PCem
changeset 106:af02d3d16c98
Added joystick emulation
| author | TomW |
|---|---|
| date | Sun Jun 08 13:45:26 2014 +0100 |
| parents | eb624a751863 |
| children | 0202ec1f468e |
| files | src/Makefile.mingw src/gameport.c src/gameport.h src/model.c src/pc.c src/plat-joystick.h src/win-joystick.cc |
| diffstat | 7 files changed, 293 insertions(+), 2 deletions(-) [+] |
line diff
1.1 --- a/src/Makefile.mingw Sat Jun 07 15:57:57 2014 +0100 1.2 +++ b/src/Makefile.mingw Sun Jun 08 13:45:26 2014 +0100 1.3 @@ -4,7 +4,7 @@ 1.4 WINDRES = windres.exe 1.5 CFLAGS = -O3 -march=i686 -fomit-frame-pointer 1.6 OBJ = 386.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \ 1.7 - config.o cpu.o dac.o device.o dma.o fdc.o \ 1.8 + config.o cpu.o dac.o device.o dma.o fdc.o gameport.o \ 1.9 headland.o i430vx.o ide.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \ 1.10 keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o model.o \ 1.11 mouse.o mouse_ps2.o mouse_serial.o neat.o nvr.o olivetti_m24.o \ 1.12 @@ -18,7 +18,7 @@ 1.13 vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o vid_pcjr.o vid_s3.o \ 1.14 vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o vid_svga_render.o \ 1.15 vid_tandy.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \ 1.16 - vid_voodoo.o video.o wd76c10.o win.o win-d3d.o win-d3d-fs.o win-ddraw.o win-ddraw-fs.o win-keyboard.o win-midi.o \ 1.17 + vid_voodoo.o video.o wd76c10.o win.o win-d3d.o win-d3d-fs.o win-ddraw.o win-ddraw-fs.o win-joystick.o win-keyboard.o win-midi.o \ 1.18 win-mouse.o win-timer.o win-video.o x86seg.o x87.o xtide.o pc.res 1.19 FMOBJ = dbopl.o 1.20 SIDOBJ = convolve.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/gameport.c Sun Jun 08 13:45:26 2014 +0100 2.3 @@ -0,0 +1,136 @@ 2.4 +#include <stdlib.h> 2.5 +#include "ibm.h" 2.6 +#include "device.h" 2.7 +#include "io.h" 2.8 +#include "plat-joystick.h" 2.9 +#include "timer.h" 2.10 + 2.11 +#include "gameport.h" 2.12 + 2.13 +typedef struct gameport_axis_t 2.14 +{ 2.15 + int count; 2.16 + int axis_nr; 2.17 + struct gameport_t *gameport; 2.18 +} gameport_axis_t; 2.19 + 2.20 +typedef struct gameport_t 2.21 +{ 2.22 + uint8_t state; 2.23 + 2.24 + gameport_axis_t axis[4]; 2.25 +} gameport_t; 2.26 + 2.27 +static int gameport_time(int axis) 2.28 +{ 2.29 + axis += 32768; 2.30 + axis = (axis * 100) / 65; /*Axis now in ohms*/ 2.31 + axis = (axis * 11) / 1000; 2.32 + return TIMER_USEC * (axis + 24); /*max = 11.115 ms*/ 2.33 +} 2.34 + 2.35 +void gameport_write(uint16_t addr, uint8_t val, void *p) 2.36 +{ 2.37 + gameport_t *gameport = (gameport_t *)p; 2.38 + 2.39 + gameport->state |= 0x0f; 2.40 +// pclog("gameport_write : joysticks_present=%i\n", joysticks_present); 2.41 + if (joysticks_present) 2.42 + { 2.43 + gameport->axis[0].count = gameport_time(joystick_state[0].x); 2.44 + gameport->axis[1].count = gameport_time(joystick_state[0].y); 2.45 +// pclog("gameport_write: axis[0]=%i,%i axis[1]=%i,%i\n", joystick_state[0].x, gameport->axis[0].count, joystick_state[0].y, gameport->axis[1].count); 2.46 + } 2.47 + if (joysticks_present >= 2) 2.48 + { 2.49 + gameport->axis[2].count = gameport_time(joystick_state[1].x); 2.50 + gameport->axis[3].count = gameport_time(joystick_state[1].y); 2.51 +// pclog("gameport_write: axis[2]=%i,%i axis[3]=%i,%i\n", joystick_state[1].x, gameport->axis[2].count, joystick_state[1].y, gameport->axis[3].count); 2.52 + } 2.53 +} 2.54 + 2.55 +uint8_t gameport_read(uint16_t addr, void *p) 2.56 +{ 2.57 + gameport_t *gameport = (gameport_t *)p; 2.58 + uint8_t ret; 2.59 + 2.60 + ret = gameport->state | 0xf0; 2.61 + 2.62 + if (joysticks_present) 2.63 + { 2.64 + if (joystick_state[0].b[0]) 2.65 + ret &= ~0x10; 2.66 + if (joystick_state[0].b[1]) 2.67 + ret &= ~0x20; 2.68 + if (joystick_state[0].b[2]) 2.69 + ret &= ~0x40; 2.70 + if (joystick_state[0].b[3]) 2.71 + ret &= ~0x80; 2.72 + } 2.73 + if (joysticks_present >= 2) 2.74 + { 2.75 + if (joystick_state[1].b[0]) 2.76 + ret &= ~0x40; 2.77 + if (joystick_state[1].b[1]) 2.78 + ret &= ~0x80; 2.79 + } 2.80 + 2.81 +// pclog("gameport_read: ret=%02x %08x:%08x\n", ret, cs, pc); 2.82 + return ret; 2.83 +} 2.84 + 2.85 +void gameport_timer_over(void *p) 2.86 +{ 2.87 + gameport_axis_t *axis = (gameport_axis_t *)p; 2.88 + gameport_t *gameport = axis->gameport; 2.89 + 2.90 + gameport->state &= ~(1 << axis->axis_nr); 2.91 + axis->count = 0; 2.92 + 2.93 +// pclog("gameport_timer_over : axis_nr=%i\n", axis->axis_nr); 2.94 +} 2.95 + 2.96 +void *gameport_init() 2.97 +{ 2.98 + gameport_t *gameport = malloc(sizeof(gameport_t)); 2.99 + 2.100 + memset(gameport, 0, sizeof(gameport_t)); 2.101 + 2.102 + gameport->axis[0].gameport = gameport; 2.103 + gameport->axis[1].gameport = gameport; 2.104 + gameport->axis[2].gameport = gameport; 2.105 + gameport->axis[3].gameport = gameport; 2.106 + 2.107 + gameport->axis[0].axis_nr = 0; 2.108 + gameport->axis[1].axis_nr = 1; 2.109 + gameport->axis[2].axis_nr = 2; 2.110 + gameport->axis[3].axis_nr = 3; 2.111 + 2.112 + timer_add(gameport_timer_over, &gameport->axis[0].count, &gameport->axis[0].count, &gameport->axis[0]); 2.113 + timer_add(gameport_timer_over, &gameport->axis[1].count, &gameport->axis[1].count, &gameport->axis[1]); 2.114 + timer_add(gameport_timer_over, &gameport->axis[2].count, &gameport->axis[2].count, &gameport->axis[2]); 2.115 + timer_add(gameport_timer_over, &gameport->axis[3].count, &gameport->axis[3].count, &gameport->axis[3]); 2.116 + 2.117 + io_sethandler(0x0200, 0x0008, gameport_read, NULL, NULL, gameport_write, NULL, NULL, gameport); 2.118 + 2.119 + return gameport; 2.120 +} 2.121 + 2.122 +void gameport_close(void *p) 2.123 +{ 2.124 + gameport_t *gameport = (gameport_t *)p; 2.125 + 2.126 + free(gameport); 2.127 +} 2.128 + 2.129 +device_t gameport_device = 2.130 +{ 2.131 + "Game port", 2.132 + 0, 2.133 + gameport_init, 2.134 + gameport_close, 2.135 + NULL, 2.136 + NULL, 2.137 + NULL, 2.138 + NULL 2.139 +};
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/gameport.h Sun Jun 08 13:45:26 2014 +0100 3.3 @@ -0,0 +1,1 @@ 3.4 +extern device_t gameport_device;
4.1 --- a/src/model.c Sat Jun 07 15:57:57 2014 +0100 4.2 +++ b/src/model.c Sun Jun 08 13:45:26 2014 +0100 4.3 @@ -9,6 +9,7 @@ 4.4 #include "device.h" 4.5 #include "dma.h" 4.6 #include "fdc.h" 4.7 +#include "gameport.h" 4.8 #include "headland.h" 4.9 #include "i430vx.h" 4.10 #include "ide.h" 4.11 @@ -122,6 +123,7 @@ 4.12 pit_init(); 4.13 serial1_init(0x3f8, 4); 4.14 serial2_init(0x2f8, 3); 4.15 + device_add(&gameport_device); 4.16 } 4.17 4.18 void xt_init()
5.1 --- a/src/pc.c Sat Jun 07 15:57:57 2014 +0100 5.2 +++ b/src/pc.c Sun Jun 08 13:45:26 2014 +0100 5.3 @@ -20,6 +20,7 @@ 5.4 #include "nvr.h" 5.5 #include "pic.h" 5.6 #include "pit.h" 5.7 +#include "plat-joystick.h" 5.8 #include "plat-mouse.h" 5.9 #include "serial.h" 5.10 #include "sound.h" 5.11 @@ -196,6 +197,7 @@ 5.12 5.13 keyboard_init(); 5.14 mouse_init(); 5.15 + joystick_init(); 5.16 5.17 loadconfig(); 5.18 pclog("Config loaded\n"); 5.19 @@ -326,6 +328,7 @@ 5.20 keyboard_process(); 5.21 // checkkeys(); 5.22 pollmouse(); 5.23 + poll_joystick(); 5.24 endblit(); 5.25 5.26 framecountx++;
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/plat-joystick.h Sun Jun 08 13:45:26 2014 +0100 6.3 @@ -0,0 +1,19 @@ 6.4 +#ifdef __cplusplus 6.5 +extern "C" { 6.6 +#endif 6.7 + void joystick_init(); 6.8 + void joystick_close(); 6.9 + void poll_joystick(); 6.10 + 6.11 + typedef struct joystick_t 6.12 + { 6.13 + int x, y; 6.14 + int b[4]; 6.15 + } joystick_t; 6.16 + 6.17 + extern joystick_t joystick_state[2]; 6.18 + extern int joysticks_present; 6.19 +#ifdef __cplusplus 6.20 +} 6.21 +#endif 6.22 +
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/win-joystick.cc Sun Jun 08 13:45:26 2014 +0100 7.3 @@ -0,0 +1,130 @@ 7.4 +#include <dinput.h> 7.5 +#include "plat-joystick.h" 7.6 +#include "plat-dinput.h" 7.7 +#include "win.h" 7.8 + 7.9 +extern "C" int video_fullscreen; 7.10 + 7.11 +extern "C" void fatal(const char *format, ...); 7.12 +extern "C" void pclog(const char *format, ...); 7.13 + 7.14 +extern "C" void joystick_init(); 7.15 +extern "C" void joystick_close(); 7.16 +extern "C" void poll_joystick(); 7.17 + 7.18 +joystick_t joystick_state[2]; 7.19 + 7.20 +static LPDIRECTINPUTDEVICE2 lpdi_joystick[2] = {NULL, NULL}; 7.21 + 7.22 +int joysticks_present = 0; 7.23 +static GUID joystick_guids[2]; 7.24 + 7.25 +static BOOL CALLBACK joystick_enum_callback(LPCDIDEVICEINSTANCE lpddi, LPVOID data) 7.26 +{ 7.27 + if (joysticks_present >= 2) 7.28 + return DIENUM_STOP; 7.29 + 7.30 + pclog("joystick_enum_callback : found joystick %i : %s\n", joysticks_present, lpddi->tszProductName); 7.31 + 7.32 + joystick_guids[joysticks_present++] = lpddi->guidInstance; 7.33 + 7.34 + if (joysticks_present >= 2) 7.35 + return DIENUM_STOP; 7.36 + 7.37 + return DIENUM_CONTINUE; 7.38 +} 7.39 + 7.40 +void joystick_init() 7.41 +{ 7.42 + int c; 7.43 + 7.44 + atexit(joystick_close); 7.45 + 7.46 + joysticks_present = 0; 7.47 + 7.48 + if (FAILED(lpdi->EnumDevices(DIDEVTYPE_JOYSTICK, joystick_enum_callback, NULL, DIEDFL_ATTACHEDONLY))) 7.49 + fatal("joystick_init : EnumDevices failed\n"); 7.50 + 7.51 + pclog("joystick_init: joysticks_present=%i\n", joysticks_present); 7.52 + 7.53 + for (c = 0; c < joysticks_present; c++) 7.54 + { 7.55 + LPDIRECTINPUTDEVICE lpdi_joystick_temp = NULL; 7.56 + DIPROPRANGE joy_axis_range; 7.57 + 7.58 + if (FAILED(lpdi->CreateDevice(joystick_guids[c], &lpdi_joystick_temp, NULL))) 7.59 + fatal("joystick_init : CreateDevice failed\n"); 7.60 + if (FAILED(lpdi_joystick_temp->QueryInterface(IID_IDirectInputDevice2, (void **)&lpdi_joystick[c]))) 7.61 + fatal("joystick_init : CreateDevice failed\n"); 7.62 + lpdi_joystick_temp->Release(); 7.63 + if (FAILED(lpdi_joystick[c]->SetCooperativeLevel(ghwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) 7.64 + fatal("joystick_init : SetCooperativeLevel failed\n"); 7.65 + if (FAILED(lpdi_joystick[c]->SetDataFormat(&c_dfDIJoystick))) 7.66 + fatal("joystick_init : SetDataFormat failed\n"); 7.67 + 7.68 + joy_axis_range.lMin = -32768; 7.69 + joy_axis_range.lMax = 32767; 7.70 + joy_axis_range.diph.dwSize = sizeof(DIPROPRANGE); 7.71 + joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); 7.72 + joy_axis_range.diph.dwObj = DIJOFS_X; 7.73 + joy_axis_range.diph.dwHow = DIPH_BYOFFSET; 7.74 + lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); 7.75 + 7.76 + joy_axis_range.lMin = -32768; 7.77 + joy_axis_range.lMax = 32767; 7.78 + joy_axis_range.diph.dwSize = sizeof(DIPROPRANGE); 7.79 + joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); 7.80 + joy_axis_range.diph.dwObj = DIJOFS_Y; 7.81 + joy_axis_range.diph.dwHow = DIPH_BYOFFSET; 7.82 + lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); 7.83 + 7.84 + if (FAILED(lpdi_joystick[c]->Acquire())) 7.85 + fatal("joystick_init : Acquire failed\n"); 7.86 + } 7.87 +} 7.88 + 7.89 +void joystick_close() 7.90 +{ 7.91 + if (lpdi_joystick[1]) 7.92 + { 7.93 + lpdi_joystick[1]->Release(); 7.94 + lpdi_joystick[1] = NULL; 7.95 + } 7.96 + if (lpdi_joystick[0]) 7.97 + { 7.98 + lpdi_joystick[0]->Release(); 7.99 + lpdi_joystick[0] = NULL; 7.100 + } 7.101 +} 7.102 + 7.103 +void poll_joystick() 7.104 +{ 7.105 + int c; 7.106 + 7.107 + for (c = 0; c < joysticks_present; c++) 7.108 + { 7.109 + DIJOYSTATE joystate; 7.110 + 7.111 + if (FAILED(lpdi_joystick[c]->Poll())) 7.112 + { 7.113 + lpdi_joystick[c]->Acquire(); 7.114 + lpdi_joystick[c]->Poll(); 7.115 + } 7.116 + if (FAILED(lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&joystate))) 7.117 + { 7.118 + lpdi_joystick[c]->Acquire(); 7.119 + lpdi_joystick[c]->Poll(); 7.120 + lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&joystate); 7.121 + } 7.122 + 7.123 + joystick_state[c].x = joystate.lX; 7.124 + joystick_state[c].y = joystate.lY; 7.125 + joystick_state[c].b[0] = joystate.rgbButtons[0] & 0x80; 7.126 + joystick_state[c].b[1] = joystate.rgbButtons[1] & 0x80; 7.127 + joystick_state[c].b[2] = joystate.rgbButtons[2] & 0x80; 7.128 + joystick_state[c].b[3] = joystate.rgbButtons[3] & 0x80; 7.129 + 7.130 + pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); 7.131 + } 7.132 +} 7.133 +
