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 +