Added joystick emulation

This commit is contained in:
TomW 2014-06-08 13:45:26 +01:00
commit 4cb7d58d53
7 changed files with 293 additions and 2 deletions

View file

@ -4,7 +4,7 @@ CC = gcc.exe
WINDRES = windres.exe
CFLAGS = -O3 -march=i686 -fomit-frame-pointer
OBJ = 386.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \
config.o cpu.o dac.o device.o dma.o fdc.o \
config.o cpu.o dac.o device.o dma.o fdc.o gameport.o \
headland.o i430vx.o ide.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o model.o \
mouse.o mouse_ps2.o mouse_serial.o neat.o nvr.o olivetti_m24.o \
@ -18,7 +18,7 @@ OBJ = 386.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \
vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o vid_pcjr.o vid_s3.o \
vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o vid_svga_render.o \
vid_tandy.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \
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 \
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 \
win-mouse.o win-timer.o win-video.o x86seg.o x87.o xtide.o pc.res
FMOBJ = dbopl.o
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

136
src/gameport.c Normal file
View file

@ -0,0 +1,136 @@
#include <stdlib.h>
#include "ibm.h"
#include "device.h"
#include "io.h"
#include "plat-joystick.h"
#include "timer.h"
#include "gameport.h"
typedef struct gameport_axis_t
{
int count;
int axis_nr;
struct gameport_t *gameport;
} gameport_axis_t;
typedef struct gameport_t
{
uint8_t state;
gameport_axis_t axis[4];
} gameport_t;
static int gameport_time(int axis)
{
axis += 32768;
axis = (axis * 100) / 65; /*Axis now in ohms*/
axis = (axis * 11) / 1000;
return TIMER_USEC * (axis + 24); /*max = 11.115 ms*/
}
void gameport_write(uint16_t addr, uint8_t val, void *p)
{
gameport_t *gameport = (gameport_t *)p;
gameport->state |= 0x0f;
// pclog("gameport_write : joysticks_present=%i\n", joysticks_present);
if (joysticks_present)
{
gameport->axis[0].count = gameport_time(joystick_state[0].x);
gameport->axis[1].count = gameport_time(joystick_state[0].y);
// 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);
}
if (joysticks_present >= 2)
{
gameport->axis[2].count = gameport_time(joystick_state[1].x);
gameport->axis[3].count = gameport_time(joystick_state[1].y);
// 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);
}
}
uint8_t gameport_read(uint16_t addr, void *p)
{
gameport_t *gameport = (gameport_t *)p;
uint8_t ret;
ret = gameport->state | 0xf0;
if (joysticks_present)
{
if (joystick_state[0].b[0])
ret &= ~0x10;
if (joystick_state[0].b[1])
ret &= ~0x20;
if (joystick_state[0].b[2])
ret &= ~0x40;
if (joystick_state[0].b[3])
ret &= ~0x80;
}
if (joysticks_present >= 2)
{
if (joystick_state[1].b[0])
ret &= ~0x40;
if (joystick_state[1].b[1])
ret &= ~0x80;
}
// pclog("gameport_read: ret=%02x %08x:%08x\n", ret, cs, pc);
return ret;
}
void gameport_timer_over(void *p)
{
gameport_axis_t *axis = (gameport_axis_t *)p;
gameport_t *gameport = axis->gameport;
gameport->state &= ~(1 << axis->axis_nr);
axis->count = 0;
// pclog("gameport_timer_over : axis_nr=%i\n", axis->axis_nr);
}
void *gameport_init()
{
gameport_t *gameport = malloc(sizeof(gameport_t));
memset(gameport, 0, sizeof(gameport_t));
gameport->axis[0].gameport = gameport;
gameport->axis[1].gameport = gameport;
gameport->axis[2].gameport = gameport;
gameport->axis[3].gameport = gameport;
gameport->axis[0].axis_nr = 0;
gameport->axis[1].axis_nr = 1;
gameport->axis[2].axis_nr = 2;
gameport->axis[3].axis_nr = 3;
timer_add(gameport_timer_over, &gameport->axis[0].count, &gameport->axis[0].count, &gameport->axis[0]);
timer_add(gameport_timer_over, &gameport->axis[1].count, &gameport->axis[1].count, &gameport->axis[1]);
timer_add(gameport_timer_over, &gameport->axis[2].count, &gameport->axis[2].count, &gameport->axis[2]);
timer_add(gameport_timer_over, &gameport->axis[3].count, &gameport->axis[3].count, &gameport->axis[3]);
io_sethandler(0x0200, 0x0008, gameport_read, NULL, NULL, gameport_write, NULL, NULL, gameport);
return gameport;
}
void gameport_close(void *p)
{
gameport_t *gameport = (gameport_t *)p;
free(gameport);
}
device_t gameport_device =
{
"Game port",
0,
gameport_init,
gameport_close,
NULL,
NULL,
NULL,
NULL
};

1
src/gameport.h Normal file
View file

@ -0,0 +1 @@
extern device_t gameport_device;

View file

@ -9,6 +9,7 @@
#include "device.h"
#include "dma.h"
#include "fdc.h"
#include "gameport.h"
#include "headland.h"
#include "i430vx.h"
#include "ide.h"
@ -122,6 +123,7 @@ void common_init()
pit_init();
serial1_init(0x3f8, 4);
serial2_init(0x2f8, 3);
device_add(&gameport_device);
}
void xt_init()

View file

@ -20,6 +20,7 @@
#include "nvr.h"
#include "pic.h"
#include "pit.h"
#include "plat-joystick.h"
#include "plat-mouse.h"
#include "serial.h"
#include "sound.h"
@ -196,6 +197,7 @@ void initpc()
keyboard_init();
mouse_init();
joystick_init();
loadconfig();
pclog("Config loaded\n");
@ -326,6 +328,7 @@ void runpc()
keyboard_process();
// checkkeys();
pollmouse();
poll_joystick();
endblit();
framecountx++;

19
src/plat-joystick.h Normal file
View file

@ -0,0 +1,19 @@
#ifdef __cplusplus
extern "C" {
#endif
void joystick_init();
void joystick_close();
void poll_joystick();
typedef struct joystick_t
{
int x, y;
int b[4];
} joystick_t;
extern joystick_t joystick_state[2];
extern int joysticks_present;
#ifdef __cplusplus
}
#endif

130
src/win-joystick.cc Normal file
View file

@ -0,0 +1,130 @@
#include <dinput.h>
#include "plat-joystick.h"
#include "plat-dinput.h"
#include "win.h"
extern "C" int video_fullscreen;
extern "C" void fatal(const char *format, ...);
extern "C" void pclog(const char *format, ...);
extern "C" void joystick_init();
extern "C" void joystick_close();
extern "C" void poll_joystick();
joystick_t joystick_state[2];
static LPDIRECTINPUTDEVICE2 lpdi_joystick[2] = {NULL, NULL};
int joysticks_present = 0;
static GUID joystick_guids[2];
static BOOL CALLBACK joystick_enum_callback(LPCDIDEVICEINSTANCE lpddi, LPVOID data)
{
if (joysticks_present >= 2)
return DIENUM_STOP;
pclog("joystick_enum_callback : found joystick %i : %s\n", joysticks_present, lpddi->tszProductName);
joystick_guids[joysticks_present++] = lpddi->guidInstance;
if (joysticks_present >= 2)
return DIENUM_STOP;
return DIENUM_CONTINUE;
}
void joystick_init()
{
int c;
atexit(joystick_close);
joysticks_present = 0;
if (FAILED(lpdi->EnumDevices(DIDEVTYPE_JOYSTICK, joystick_enum_callback, NULL, DIEDFL_ATTACHEDONLY)))
fatal("joystick_init : EnumDevices failed\n");
pclog("joystick_init: joysticks_present=%i\n", joysticks_present);
for (c = 0; c < joysticks_present; c++)
{
LPDIRECTINPUTDEVICE lpdi_joystick_temp = NULL;
DIPROPRANGE joy_axis_range;
if (FAILED(lpdi->CreateDevice(joystick_guids[c], &lpdi_joystick_temp, NULL)))
fatal("joystick_init : CreateDevice failed\n");
if (FAILED(lpdi_joystick_temp->QueryInterface(IID_IDirectInputDevice2, (void **)&lpdi_joystick[c])))
fatal("joystick_init : CreateDevice failed\n");
lpdi_joystick_temp->Release();
if (FAILED(lpdi_joystick[c]->SetCooperativeLevel(ghwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
fatal("joystick_init : SetCooperativeLevel failed\n");
if (FAILED(lpdi_joystick[c]->SetDataFormat(&c_dfDIJoystick)))
fatal("joystick_init : SetDataFormat failed\n");
joy_axis_range.lMin = -32768;
joy_axis_range.lMax = 32767;
joy_axis_range.diph.dwSize = sizeof(DIPROPRANGE);
joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER);
joy_axis_range.diph.dwObj = DIJOFS_X;
joy_axis_range.diph.dwHow = DIPH_BYOFFSET;
lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph);
joy_axis_range.lMin = -32768;
joy_axis_range.lMax = 32767;
joy_axis_range.diph.dwSize = sizeof(DIPROPRANGE);
joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER);
joy_axis_range.diph.dwObj = DIJOFS_Y;
joy_axis_range.diph.dwHow = DIPH_BYOFFSET;
lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph);
if (FAILED(lpdi_joystick[c]->Acquire()))
fatal("joystick_init : Acquire failed\n");
}
}
void joystick_close()
{
if (lpdi_joystick[1])
{
lpdi_joystick[1]->Release();
lpdi_joystick[1] = NULL;
}
if (lpdi_joystick[0])
{
lpdi_joystick[0]->Release();
lpdi_joystick[0] = NULL;
}
}
void poll_joystick()
{
int c;
for (c = 0; c < joysticks_present; c++)
{
DIJOYSTATE joystate;
if (FAILED(lpdi_joystick[c]->Poll()))
{
lpdi_joystick[c]->Acquire();
lpdi_joystick[c]->Poll();
}
if (FAILED(lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&joystate)))
{
lpdi_joystick[c]->Acquire();
lpdi_joystick[c]->Poll();
lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&joystate);
}
joystick_state[c].x = joystate.lX;
joystick_state[c].y = joystate.lY;
joystick_state[c].b[0] = joystate.rgbButtons[0] & 0x80;
joystick_state[c].b[1] = joystate.rgbButtons[1] & 0x80;
joystick_state[c].b[2] = joystate.rgbButtons[2] & 0x80;
joystick_state[c].b[3] = joystate.rgbButtons[3] & 0x80;
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);
}
}