From 7980438e1fc32ca080cff1f87dfe8d9fb321c684 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 21 Jun 2016 22:00:31 +0100 Subject: [PATCH] Reworking of joystick support : - Joystick type now selectable - Added emulation of standard joysticks with up to 8 buttons - Added emulation of Microsoft Sidewinder pads - Host->emulated joystick button & axis mapping now configurable (only on Windows atm) - Gameport registers now take 1us to access - helps Sidewinder drivers --- src/Makefile.am | 2 +- src/Makefile.mingw | 4 +- src/Makefile.mingw64 | 4 +- src/allegro-gui-configure.c | 58 ++++++++++--- src/allegro-joystick.c | 41 ++++++--- src/allegro-main.h | 2 + src/cpu.c | 3 + src/cpu.h | 4 + src/gameport.c | 131 +++++++++++++++++++++-------- src/gameport.h | 27 ++++++ src/pc.c | 52 +++++++++++- src/pc.rc | 24 ++++-- src/plat-joystick.h | 57 +++++++++++-- src/resources.h | 5 ++ src/win-config.c | 65 +++++++++++++++ src/win-joystick.cc | 161 +++++++++++++++++++++++++++++++----- src/win.h | 1 + 17 files changed, 542 insertions(+), 99 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index e84966d..cf2f63b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,7 @@ allegro-gui-configure.c allegro-gui-deviceconfig.c allegro-gui-hdconf.c allegro- allegro-midi.c allegro-mouse.c allegro-video.c amstrad.c cdrom-ioctl-linux.c cdrom-iso.c cdrom-null.c \ codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dac.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ -headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c \ +headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_standard.c joystick_sw_pad.c \ keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \ linux-time.c lpt.c mcr.c mem.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c \ olivetti_m24.c opti.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c rom.c scat.c serial.c sis496.c sound.c \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 0ee50d4..4aa3c3c 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -6,7 +6,7 @@ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o headland.o i430lx.o i430fx.o \ - i430vx.o ide.o intel.o intel_flash.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \ + i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_standard.o joystick_sw_pad.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 nmi.o nvr.o olivetti_m24.o opti.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o \ scat.o serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ @@ -19,7 +19,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad vid_pcjr.o vid_ps1_svga.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_tandysl.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-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ - win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-keyboard.o win-midi.o win-mouse.o \ + win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ win-status.o win-time.o win-video.o x86seg.o x87.o xtide.o pc.res FMOBJ = dbopl.o SIDOBJ = convolve.o convolve-sse.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 diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 493c376..14155ac 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -6,7 +6,7 @@ CFLAGS = -O3 -fomit-frame-pointer -msse2 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o headland.o i430lx.o i430fx.o \ - i430vx.o ide.o intel.o intel_flash.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \ + i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_standard.o joystick_sw_pad.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 nmi.o nvr.o olivetti_m24.o opti.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o \ scat.o serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ @@ -19,7 +19,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad vid_pcjr.o vid_ps1_svga.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_tandysl.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-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ - win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-keyboard.o win-midi.o win-mouse.o \ + win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ win-status.o win-time.o win-video.o x86seg.o x87.o xtide.o pc.res FMOBJ = dbopl.o SIDOBJ = convolve.o convolve-sse.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 diff --git a/src/allegro-gui-configure.c b/src/allegro-gui-configure.c index a5c07e4..9b22450 100644 --- a/src/allegro-gui-configure.c +++ b/src/allegro-gui-configure.c @@ -4,6 +4,7 @@ #include "allegro-gui.h" #include "cpu.h" #include "fdd.h" +#include "gameport.h" #include "model.h" #include "sound.h" #include "video.h" @@ -23,6 +24,7 @@ static allegro_list_t video_list[GFX_MAX+1]; static allegro_list_t sound_list[GFX_MAX+1]; static allegro_list_t cpumanu_list[4]; static allegro_list_t cpu_list[32]; +static allegro_list_t joystick_list[32]; static char mem_size_str[10], mem_size_units[3]; @@ -190,6 +192,22 @@ static char *list_proc_fdd(int index, int *list_size) return fdd_list[index].name; } +static char *list_proc_joystick(int index, int *list_size) +{ + if (index < 0) + { + int c = 0; + + while (joystick_list[c].name[0]) + c++; + + *list_size = c; + return NULL; + } + + return joystick_list[index].name; +} + static int voodoo_config_proc(int msg, DIALOG *d, int c) { int ret = d_button_proc(msg, d, c); @@ -210,10 +228,10 @@ static int list_proc(int msg, DIALOG *d, int c); static DIALOG configure_dialog[] = { - {d_shadow_box_proc, 0, 0, 568,332,0,0xffffff,0,0, 0,0,0,0,0}, // 0 + {d_shadow_box_proc, 0, 0, 568,352,0,0xffffff,0,0, 0,0,0,0,0}, // 0 - {d_button_proc, 226, 308, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1 - {d_button_proc, 296, 308, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2 + {d_button_proc, 226, 328, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1 + {d_button_proc, 296, 328, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2 {list_proc, 70*2, 12, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_model, 0, 0}, @@ -225,15 +243,15 @@ static DIALOG configure_dialog[] = {d_list_proc, 70*2, 132, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_vidspeed, 0, 0}, {list_proc, 70*2, 152, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_sound, 0, 0}, //9 - {d_edit_proc, 70*2, 216, 32, 14, 0, 0xffffff, 0, 0, 3, 0, mem_size_str, 0, 0}, + {d_edit_proc, 70*2, 236, 32, 14, 0, 0xffffff, 0, 0, 3, 0, mem_size_str, 0, 0}, - {d_text_proc, 98*2, 216, 40, 10, 0, 0xffffff, 0, 0, 0, 0, mem_size_units, 0, 0}, + {d_text_proc, 98*2, 236, 40, 10, 0, 0xffffff, 0, 0, 0, 0, mem_size_units, 0, 0}, - {d_check_proc, 14*2, 232, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "CMS / Game Blaster", 0, 0}, - {d_check_proc, 14*2, 248, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Gravis Ultrasound", 0, 0}, - {d_check_proc, 14*2, 264, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Innovation SSI-2001", 0, 0}, - {d_check_proc, 14*2, 280, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Composite CGA", 0, 0}, - {d_check_proc, 14*2, 296, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Voodoo Graphics", 0, 0}, + {d_check_proc, 14*2, 252, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "CMS / Game Blaster", 0, 0}, + {d_check_proc, 14*2, 268, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Gravis Ultrasound", 0, 0}, + {d_check_proc, 14*2, 284, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Innovation SSI-2001", 0, 0}, + {d_check_proc, 14*2, 300, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Composite CGA", 0, 0}, + {d_check_proc, 14*2, 316, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Voodoo Graphics", 0, 0}, {d_text_proc, 16*2, 16, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Machine :", 0, 0}, {d_text_proc, 16*2, 36, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Video :", 0, 0}, @@ -242,7 +260,7 @@ static DIALOG configure_dialog[] = {d_text_proc, 16*2, 116, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Cache :", 0, 0}, {d_text_proc, 16*2, 136, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Video speed :", 0, 0}, {d_text_proc, 16*2, 156, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Soundcard :", 0, 0}, - {d_text_proc, 16*2, 216, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Memory :", 0, 0}, + {d_text_proc, 16*2, 236, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Memory :", 0, 0}, {d_check_proc, 14*2, 92, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Dynamic Recompiler", 0, 0}, @@ -253,7 +271,10 @@ static DIALOG configure_dialog[] = {video_config_proc, 452, 32+4, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, //30 {sound_config_proc, 452, 152+4, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, - {voodoo_config_proc, 452, 296, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, + {voodoo_config_proc, 452, 316, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, + + {d_text_proc, 16*2, 216, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Joystick :", 0, 0}, + {d_list_proc, 70*2, 212, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_joystick, 0, 0}, //34 {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} }; @@ -452,6 +473,16 @@ pclog("video_card_available : %i\n", c); c++; } + c = 0; + while (joystick_get_name(c)) + { + strcpy(joystick_list[c].name, joystick_get_name(c)); + if (c == joystick_type) + configure_dialog[34].d1 = c; + + c++; + } + if (!sound_card_has_config(configure_dialog[9].d1)) configure_dialog[31].flags |= D_DISABLED; else @@ -586,6 +617,9 @@ pclog("video_card_available : %i\n", c); cache = configure_dialog[7].d1; mem_updatecache(); + joystick_type = configure_dialog[34].d1; + gameport_update_joystick_type(); + saveconfig(); speedchanged(); diff --git a/src/allegro-joystick.c b/src/allegro-joystick.c index 68bb5c9..953399a 100644 --- a/src/allegro-joystick.c +++ b/src/allegro-joystick.c @@ -1,30 +1,49 @@ #include "allegro-main.h" #include "plat-joystick.h" +#include "device.h" +#include "gameport.h" + +plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +joystick_t joystick_state[MAX_JOYSTICKS]; -joystick_t joystick_state[2]; int joysticks_present; void joystick_init() { install_joystick(JOY_TYPE_AUTODETECT); - joysticks_present = MIN(num_joysticks, 2); + joysticks_present = num_joysticks; } void joystick_close() { } void joystick_poll() { - int c; + int c, d; poll_joystick(); - for (c = 0; c < MIN(num_joysticks, 2); c++) - { - joystick_state[c].x = joy[c].stick[0].axis[0].pos * 256; - joystick_state[c].y = joy[c].stick[0].axis[1].pos * 256; - joystick_state[c].b[0] = joy[c].button[0].b; - joystick_state[c].b[1] = joy[c].button[1].b; - joystick_state[c].b[2] = joy[c].button[2].b; - joystick_state[c].b[3] = joy[c].button[3].b; + for (c = 0; c < num_joysticks; c++) + { + plat_joystick_state[c].a[0] = joy[c].stick[0].axis[0].pos * 256; + plat_joystick_state[c].a[1] = joy[c].stick[0].axis[1].pos * 256; + for (d = 0; d < MAX_JOYSTICK_BUTTONS; d++) + plat_joystick_state[c].b[d] = joy[c].button[d].b; + } + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + if (c < num_joysticks) + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = plat_joystick_state[c].a[d]; + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = plat_joystick_state[c].b[d]; + } + else + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = 0; + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = 0; + } } } diff --git a/src/allegro-main.h b/src/allegro-main.h index 0988d5f..ba96a4f 100644 --- a/src/allegro-main.h +++ b/src/allegro-main.h @@ -5,9 +5,11 @@ #define put_backslash allegro_put_backslash #define get_extension allegro_get_extension #define GFX_VGA allegro_GFX_VGA +#define MAX_JOYSTICKS allegro_MAX_JOYSTICKS #include +#undef MAX_JOYSTICKS #undef GFX_VGA #undef getr8 #undef setr8 diff --git a/src/cpu.c b/src/cpu.c index c3a6255..91e5cda 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -7,6 +7,7 @@ #include "pci.h" #include "codegen.h" +int isa_cycles; static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6; OpFn *x86_dynarec_opcodes; @@ -439,6 +440,8 @@ void cpu_set() cpu_hasMSR = 0; cpu_hasCR4 = 0; ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; + + isa_cycles = (int)(((int64_t)cpu_s->rspeed << ISA_CYCLES_SHIFT) / 8000000ll); if (cpu_s->pci_speed) { diff --git a/src/cpu.h b/src/cpu.h index b10abb7..1bfa9dd 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -121,4 +121,8 @@ extern int cpu_use_dynarec; extern int xt_cpu_multi; +#define ISA_CYCLES_SHIFT 6 +extern int isa_cycles; +#define ISA_CYCLES(x) ((x * isa_cycles) >> ISA_CYCLES_SHIFT) + #endif diff --git a/src/gameport.c b/src/gameport.c index c6cd9f3..ba6b235 100644 --- a/src/gameport.c +++ b/src/gameport.c @@ -6,6 +6,52 @@ #include "timer.h" #include "gameport.h" +#include "joystick_standard.h" +#include "joystick_sw_pad.h" + +int joystick_type; + +static joystick_if_t *joystick_list[] = +{ + &joystick_standard, + &joystick_standard_4button, + &joystick_standard_6button, + &joystick_standard_8button, + &joystick_sw_pad, + NULL +}; + +char *joystick_get_name(int joystick) +{ + if (!joystick_list[joystick]) + return NULL; + return joystick_list[joystick]->name; +} + +int joystick_get_max_joysticks(int joystick) +{ + return joystick_list[joystick]->max_joysticks; +} + +int joystick_get_axis_count(int joystick) +{ + return joystick_list[joystick]->axis_count; +} + +int joystick_get_button_count(int joystick) +{ + return joystick_list[joystick]->button_count; +} + +char *joystick_get_axis_name(int joystick, int id) +{ + return joystick_list[joystick]->axis_names[id]; +} + +char *joystick_get_button_name(int joystick, int id) +{ + return joystick_list[joystick]->button_names[id]; +} typedef struct gameport_axis_t { @@ -19,10 +65,18 @@ typedef struct gameport_t uint8_t state; gameport_axis_t axis[4]; + + joystick_if_t *joystick; + void *joystick_dat; } gameport_t; +static gameport_t *gameport_global = NULL; + static int gameport_time(int axis) { + if (axis == AXIS_NOT_PRESENT) + return 0; + axis += 32768; axis = (axis * 100) / 65; /*Axis now in ohms*/ axis = (axis * 11) / 1000; @@ -33,49 +87,35 @@ void gameport_write(uint16_t addr, uint8_t val, void *p) { gameport_t *gameport = (gameport_t *)p; + timer_clock(); 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); - } + + gameport->axis[0].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 0)); + gameport->axis[1].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 1)); + gameport->axis[2].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 2)); + gameport->axis[3].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 3)); + + gameport->joystick->write(gameport->joystick_dat); + + cycles -= ISA_CYCLES(8); } 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); + timer_clock(); +// if (joysticks_present) + ret = gameport->state | gameport->joystick->read(gameport->joystick_dat);//0xf0; +// else +// ret = 0xff; + +// pclog("gameport_read: ret=%02x %08x:%08x isa_cycles=%i %i\n", ret, cs, cpu_state.pc, isa_cycles, gameport->axis[0].count); + + cycles -= ISA_CYCLES(8); + return ret; } @@ -87,7 +127,8 @@ void gameport_timer_over(void *p) gameport->state &= ~(1 << axis->axis_nr); axis->count = 0; -// pclog("gameport_timer_over : axis_nr=%i\n", axis->axis_nr); + if (axis == &gameport->axis[0]) + gameport->joystick->a0_over(gameport->joystick_dat); } void *gameport_init_common() @@ -110,10 +151,24 @@ void *gameport_init_common() 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]); - + + gameport->joystick = joystick_list[joystick_type]; + gameport->joystick_dat = gameport->joystick->init(); + + gameport_global = gameport; + return gameport; } +void gameport_update_joystick_type() +{ + gameport_t *gameport = gameport_global; + + gameport->joystick->close(gameport->joystick_dat); + gameport->joystick = joystick_list[joystick_type]; + gameport->joystick_dat = gameport->joystick->init(); +} + void *gameport_init() { gameport_t *gameport = gameport_init_common(); @@ -135,6 +190,10 @@ void *gameport_201_init() void gameport_close(void *p) { gameport_t *gameport = (gameport_t *)p; + + gameport->joystick->close(gameport->joystick_dat); + + gameport_global = NULL; free(gameport); } diff --git a/src/gameport.h b/src/gameport.h index 71c73a7..2e604dd 100644 --- a/src/gameport.h +++ b/src/gameport.h @@ -1,2 +1,29 @@ extern device_t gameport_device; extern device_t gameport_201_device; + +typedef struct +{ + char name[80]; + void *(*init)(); + void (*close)(void *p); + uint8_t (*read)(void *p); + void (*write)(void *p); + int (*read_axis)(void *p, int axis); + void (*a0_over)(void *p); + int axis_count, button_count; + int max_joysticks; + char axis_names[8][32]; + char button_names[32][32]; +} joystick_if_t; + +extern int joystick_type; +char *joystick_get_name(int joystick); +int joystick_get_max_joysticks(int joystick); +int joystick_get_axis_count(int joystick); +int joystick_get_button_count(int joystick); +char *joystick_get_axis_name(int joystick, int id); +char *joystick_get_button_name(int joystick, int id); + +void gameport_update_joystick_type(); + +#define AXIS_NOT_PRESENT -99999 diff --git a/src/pc.c b/src/pc.c index 4b00bf2..a6c5d6c 100644 --- a/src/pc.c +++ b/src/pc.c @@ -18,6 +18,7 @@ #include "dma.h" #include "fdc.h" #include "fdd.h" +#include "gameport.h" #include "sound_gus.h" #include "ide.h" #include "keyboard.h" @@ -566,6 +567,7 @@ int cga_comp=0; void loadconfig(char *fn) { + int c, d; char s[512]; char *p; @@ -655,10 +657,34 @@ void loadconfig(char *fn) window_x = config_get_int(NULL, "window_x", 0); window_y = config_get_int(NULL, "window_y", 0); window_remember = config_get_int(NULL, "window_remember", 0); + + joystick_type = config_get_int(NULL, "joystick_type", 0); + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + sprintf(s, "joystick_%i_nr", c); + joystick_state[c].plat_joystick_nr = config_get_int("Joysticks", s, 0); + + if (joystick_state[c].plat_joystick_nr) + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_axis_%i", c, d); + joystick_state[c].axis_mapping[d] = config_get_int("Joysticks", s, d); + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_button_%i", c, d); + joystick_state[c].button_mapping[d] = config_get_int("Joysticks", s, d); + } + } + } } void saveconfig() { + int c, d; + config_set_int(NULL, "gameblaster", GAMEBLASTER); config_set_int(NULL, "gus", GUS); config_set_int(NULL, "ssi2001", SSI2001); @@ -714,6 +740,30 @@ void saveconfig() config_set_int(NULL, "window_x", window_x); config_set_int(NULL, "window_y", window_y); config_set_int(NULL, "window_remember", window_remember); - + + config_set_int(NULL, "joystick_type", joystick_type); + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + char s[80]; + + sprintf(s, "joystick_%i_nr", c); + config_set_int("Joysticks", s, joystick_state[c].plat_joystick_nr); + + if (joystick_state[c].plat_joystick_nr) + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_axis_%i", c, d); + config_set_int("Joysticks", s, joystick_state[c].axis_mapping[d]); + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_button_%i", c, d); + config_set_int("Joysticks", s, joystick_state[c].button_mapping[d]); + } + } + } + config_save(config_file_default); } diff --git a/src/pc.rc b/src/pc.rc index b83778e..e3b3c99 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -57,13 +57,13 @@ BEGIN END END -ConfigureDlg DIALOGEX 0, 0, 232+40, 292+40 +ConfigureDlg DIALOGEX 0, 0, 232+40, 292+40+40 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Configure PCem" FONT 8, "MS Sans Serif" BEGIN - DEFPUSHBUTTON "OK",IDOK,64,308,50,14, WS_TABSTOP - PUSHBUTTON "Cancel",IDCANCEL,128,308,50,14, WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,64,308+40,50,14, WS_TABSTOP + PUSHBUTTON "Cancel",IDCANCEL,128,308+40,50,14, WS_TABSTOP COMBOBOX IDC_COMBO1,62,16,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBOVID,62,36,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Configure", IDC_CONFIGUREVID, 224, 36, 40, 14, WS_TABSTOP @@ -77,12 +77,12 @@ BEGIN EDITTEXT IDC_MEMTEXT, 62, 172, 36, 14, ES_AUTOHSCROLL | ES_NUMBER CONTROL "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 172, 12, 14 LTEXT "MB", IDC_TEXT_MB, 98, 172, 40, 10 - CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,232,118,10 - CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,248,118,10 - CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,264,118,10 - CONTROL "Composite CGA",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,280,118,10 - CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,296,118,10 - PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 296, 40, 14, WS_TABSTOP + CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,272,118,10 + CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,288,118,10 + CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,304,118,10 + CONTROL "Composite CGA",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,320,118,10 + CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,336,118,10 + PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 336, 40, 14, WS_TABSTOP LTEXT "Machine :",IDC_STATIC,15,16,40,10 LTEXT "Video :",IDC_STATIC,15,36,34,10 LTEXT "CPU type :",IDC_STATIC,15,56,34,10 @@ -95,6 +95,12 @@ BEGIN LTEXT "Drive B: :",IDC_STATIC,15,216,40,10 COMBOBOX IDC_COMBODRA,62,196,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBODRB,62,216,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "Joystick :",IDC_STATIC,15,236,40,10 + COMBOBOX IDC_COMBOJOY,62,236,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,16,252,50,14, WS_TABSTOP + PUSHBUTTON "Joystick 2...",IDC_JOY2,80,252,50,14, WS_TABSTOP + DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,144,252,50,14, WS_TABSTOP + PUSHBUTTON "Joystick 4...",IDC_JOY4,208,252,50,14, WS_TABSTOP END HdConfDlg DIALOGEX 0, 0, 210, 312+4*16 diff --git a/src/plat-joystick.h b/src/plat-joystick.h index 2694bb4..efc8e96 100644 --- a/src/plat-joystick.h +++ b/src/plat-joystick.h @@ -5,14 +5,61 @@ extern "C" { void joystick_close(); void joystick_poll(); + typedef struct plat_joystick_t + { + char name[64]; + + int a[8]; + int b[32]; + int p[4]; + + struct + { + char name[32]; + int id; + } axis[8]; + + struct + { + char name[32]; + int id; + } button[32]; + + struct + { + char name[32]; + int id; + } pov[4]; + + int nr_axes; + int nr_buttons; + int nr_povs; + } plat_joystick_t; + + #define MAX_PLAT_JOYSTICKS 8 + + extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; + extern int joysticks_present; + + #define POV_X 0x80000000 + #define POV_Y 0x40000000 + typedef struct joystick_t { - int x, y; - int b[4]; + int axis[8]; + int button[32]; + int pov[4]; + + int plat_joystick_nr; + int axis_mapping[8]; + int button_mapping[32]; } joystick_t; - - extern joystick_t joystick_state[2]; - extern int joysticks_present; + + #define MAX_JOYSTICKS 4 + extern joystick_t joystick_state[MAX_JOYSTICKS]; + + #define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0) + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/src/resources.h b/src/resources.h index 2218ea0..20d314b 100644 --- a/src/resources.h +++ b/src/resources.h @@ -38,6 +38,7 @@ #define IDC_COMBOSPD 1061 #define IDC_COMBODRA 1062 #define IDC_COMBODRB 1063 +#define IDC_COMBOJOY 1064 #define IDC_CHECK1 1010 #define IDC_CHECK2 1011 #define IDC_CHECK3 1012 @@ -116,6 +117,10 @@ #define IDC_CONFIGUREVID 1200 #define IDC_CONFIGURESND 1201 #define IDC_CONFIGUREVOODOO 1202 +#define IDC_JOY1 1210 +#define IDC_JOY2 1211 +#define IDC_JOY3 1212 +#define IDC_JOY4 1213 #define IDC_CONFIG_BASE 1200 diff --git a/src/win-config.c b/src/win-config.c index c9e90d1..6072f44 100644 --- a/src/win-config.c +++ b/src/win-config.c @@ -9,6 +9,7 @@ #include "cpu.h" #include "device.h" #include "fdd.h" +#include "gameport.h" #include "model.h" #include "resources.h" #include "sound.h" @@ -31,6 +32,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR int temp_dynarec; int cpu_flags; int temp_fda_type, temp_fdb_type; + int temp_joystick_type; UDACCEL accel; // pclog("Dialog msg %i %08X\n",message,message); @@ -217,6 +219,25 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR SendMessage(h, WM_SETTEXT, 0, (LPARAM)(LPCSTR)"MB"); else SendMessage(h, WM_SETTEXT, 0, (LPARAM)(LPCSTR)"KB"); + + h = GetDlgItem(hdlg, IDC_COMBOJOY); + c = 0; + while (joystick_get_name(c)) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)joystick_get_name(c)); + c++; + } + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, joystick_type, 0); + + h = GetDlgItem(hdlg, IDC_JOY1); + EnableWindow(h, (joystick_get_max_joysticks(joystick_type) >= 1) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY2); + EnableWindow(h, (joystick_get_max_joysticks(joystick_type) >= 2) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY3); + EnableWindow(h, (joystick_get_max_joysticks(joystick_type) >= 3) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY4); + EnableWindow(h, (joystick_get_max_joysticks(joystick_type) >= 4) ? TRUE : FALSE); return TRUE; case WM_COMMAND: @@ -269,6 +290,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR temp_fda_type = SendMessage(h, CB_GETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_COMBODRB); temp_fdb_type = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); if (temp_model != model || gfx != gfxcard || mem != mem_size || fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || @@ -324,6 +348,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR speedchanged(); + joystick_type = temp_joystick_type; + gameport_update_joystick_type(); + case IDCANCEL: EndDialog(hdlg, 0); pause=0; @@ -513,6 +540,44 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR case IDC_CONFIGUREVOODOO: deviceconfig_open(hdlg, (void *)&voodoo_device); break; + + case IDC_COMBOJOY: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_JOY1); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 1) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY2); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 2) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY3); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 3) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY4); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 4) ? TRUE : FALSE); + } + break; + + case IDC_JOY1: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 0, temp_joystick_type); + break; + case IDC_JOY2: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 1, temp_joystick_type); + break; + case IDC_JOY3: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 2, temp_joystick_type); + break; + case IDC_JOY4: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 3, temp_joystick_type); + break; } break; } diff --git a/src/win-joystick.cc b/src/win-joystick.cc index ea06136..4c44bee 100644 --- a/src/win-joystick.cc +++ b/src/win-joystick.cc @@ -1,5 +1,11 @@ #define DIRECTINPUT_VERSION 0x0700 #include +#include +#include +extern "C" { +#include "device.h" +#include "gameport.h" +} #include "plat-joystick.h" #include "win.h" @@ -12,29 +18,72 @@ extern "C" void joystick_init(); extern "C" void joystick_close(); extern "C" void poll_joystick(); -joystick_t joystick_state[2]; +plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +joystick_t joystick_state[MAX_JOYSTICKS]; static LPDIRECTINPUT lpdi; static LPDIRECTINPUTDEVICE2 lpdi_joystick[2] = {NULL, NULL}; int joysticks_present = 0; -static GUID joystick_guids[2]; +static GUID joystick_guids[MAX_JOYSTICKS]; static BOOL CALLBACK joystick_enum_callback(LPCDIDEVICEINSTANCE lpddi, LPVOID data) { - if (joysticks_present >= 2) + if (joysticks_present >= MAX_JOYSTICKS) 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) + if (joysticks_present >= MAX_JOYSTICKS) return DIENUM_STOP; return DIENUM_CONTINUE; } +BOOL CALLBACK DIEnumDeviceObjectsCallback( + LPCDIDEVICEOBJECTINSTANCE lpddoi, + LPVOID pvRef) +{ + plat_joystick_t *state = (plat_joystick_t *)pvRef; + + if (lpddoi->guidType == GUID_XAxis || lpddoi->guidType == GUID_YAxis || lpddoi->guidType == GUID_ZAxis || + lpddoi->guidType == GUID_RxAxis || lpddoi->guidType == GUID_RyAxis || lpddoi->guidType == GUID_RzAxis || + lpddoi->guidType == GUID_Slider) + { + strncpy(state->axis[state->nr_axes].name, lpddoi->tszName, sizeof(state->axis[state->nr_axes].name)); + pclog("Axis %i : %s %x %x\n", state->nr_axes, state->axis[state->nr_axes].name, lpddoi->dwOfs, lpddoi->dwType); + if (lpddoi->guidType == GUID_XAxis) + state->axis[state->nr_axes].id = 0; + else if (lpddoi->guidType == GUID_YAxis) + state->axis[state->nr_axes].id = 1; + else if (lpddoi->guidType == GUID_ZAxis) + state->axis[state->nr_axes].id = 2; + else if (lpddoi->guidType == GUID_RxAxis) + state->axis[state->nr_axes].id = 3; + else if (lpddoi->guidType == GUID_RyAxis) + state->axis[state->nr_axes].id = 4; + else if (lpddoi->guidType == GUID_RzAxis) + state->axis[state->nr_axes].id = 5; + state->nr_axes++; + } + else if (lpddoi->guidType == GUID_Button) + { + strncpy(state->button[state->nr_buttons].name, lpddoi->tszName, sizeof(state->button[state->nr_buttons].name)); + pclog("Button %i : %s %x %x\n", state->nr_buttons, state->button[state->nr_buttons].name, lpddoi->dwOfs, lpddoi->dwType); + state->nr_buttons++; + } + else if (lpddoi->guidType == GUID_POV) + { + strncpy(state->pov[state->nr_povs].name, lpddoi->tszName, sizeof(state->pov[state->nr_povs].name)); + pclog("POV %i : %s %x %x\n", state->nr_povs, state->pov[state->nr_povs].name, lpddoi->dwOfs, lpddoi->dwType); + state->nr_povs++; + } + + return DIENUM_CONTINUE; +} + void joystick_init() { int c; @@ -55,12 +104,35 @@ void joystick_init() { LPDIRECTINPUTDEVICE lpdi_joystick_temp = NULL; DIPROPRANGE joy_axis_range; - + DIDEVICEINSTANCE device_instance; + DIDEVCAPS devcaps; + int d; + 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(); + + memset(&device_instance, 0, sizeof(device_instance)); + device_instance.dwSize = sizeof(device_instance); + if (FAILED(lpdi_joystick[c]->GetDeviceInfo(&device_instance))) + fatal("joystick_init : GetDeviceInfo failed\n"); + pclog("Joystick %i :\n", c); + pclog(" tszInstanceName = %s\n", device_instance.tszInstanceName); + pclog(" tszProductName = %s\n", device_instance.tszProductName); + strncpy(plat_joystick_state[c].name, device_instance.tszInstanceName, 64); + + memset(&devcaps, 0, sizeof(devcaps)); + devcaps.dwSize = sizeof(devcaps); + if (FAILED(lpdi_joystick[c]->GetCapabilities(&devcaps))) + fatal("joystick_init : GetCapabilities failed\n"); + pclog(" Axes = %i\n", devcaps.dwAxes); + pclog(" Buttons = %i\n", devcaps.dwButtons); + pclog(" POVs = %i\n", devcaps.dwPOVs); + + lpdi_joystick[c]->EnumObjects(DIEnumDeviceObjectsCallback, &plat_joystick_state[c], DIDFT_ALL); + 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))) @@ -70,16 +142,18 @@ void joystick_init() joy_axis_range.lMax = 32767; joy_axis_range.diph.dwSize = sizeof(DIPROPRANGE); joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); + joy_axis_range.diph.dwHow = DIPH_BYOFFSET; 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); + joy_axis_range.diph.dwObj = DIJOFS_Z; + lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); + joy_axis_range.diph.dwObj = DIJOFS_RX; + lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); + joy_axis_range.diph.dwObj = DIJOFS_RY; + lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); + joy_axis_range.diph.dwObj = DIJOFS_RZ; lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); if (FAILED(lpdi_joystick[c]->Acquire())) @@ -103,11 +177,12 @@ void joystick_close() void joystick_poll() { - int c; + int c, d; for (c = 0; c < joysticks_present; c++) { DIJOYSTATE joystate; + int b; if (FAILED(lpdi_joystick[c]->Poll())) { @@ -121,14 +196,60 @@ void joystick_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; + plat_joystick_state[c].a[0] = joystate.lX; + plat_joystick_state[c].a[1] = joystate.lY; + plat_joystick_state[c].a[2] = joystate.lZ; + plat_joystick_state[c].a[3] = joystate.lRx; + plat_joystick_state[c].a[4] = joystate.lRy; + plat_joystick_state[c].a[5] = joystate.lRz; + for (b = 0; b < 16; b++) + plat_joystick_state[c].b[b] = joystate.rgbButtons[b] & 0x80; + + for (b = 0; b < 4; b++) + plat_joystick_state[c].p[b] = joystate.rgdwPOV[b]; // 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); - } + } + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + if (joystick_state[c].plat_joystick_nr) + { + int joystick_nr = joystick_state[c].plat_joystick_nr - 1; + + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + { + if (joystick_state[c].axis_mapping[d] & POV_X) + { + int pov = plat_joystick_state[joystick_nr].p[joystick_state[c].axis_mapping[d] & 3]; + + if (LOWORD(pov) == 0xFFFF) + joystick_state[c].axis[d] = 0; + else + joystick_state[c].axis[d] = sin((2*M_PI * (double)pov) / 36000.0) * 32767; + } + else if (joystick_state[c].axis_mapping[d] & POV_Y) + { + int pov = plat_joystick_state[joystick_nr].p[joystick_state[c].axis_mapping[d] & 3]; + + if (LOWORD(pov) == 0xFFFF) + joystick_state[c].axis[d] = 0; + else + joystick_state[c].axis[d] = -cos((2*M_PI * (double)pov) / 36000.0) * 32767; + } + else + joystick_state[c].axis[d] = plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[joystick_state[c].axis_mapping[d]].id]; + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; + } + else + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = 0; + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = 0; + } + } } diff --git a/src/win.h b/src/win.h index bf6bbfa..ca76f58 100644 --- a/src/win.h +++ b/src/win.h @@ -25,6 +25,7 @@ void hdconf_open(HWND hwnd); void config_open(HWND hwnd); void deviceconfig_open(HWND hwnd, struct device_t *device); +void joystickconfig_open(HWND hwnd, int joy_nr, int type); extern char openfilestring[260];