diff --git a/src/Makefile.am b/src/Makefile.am index ace5bf2..ce767fa 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 joystick_standard.c joystick_sw_pad.c \ +headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.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 \ 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 rtc.c scat.c serial.c sis496.c sound.c \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 2343b7a..6cbdeeb 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 joystick_standard.o joystick_sw_pad.o keyboard.o keyboard_amstrad.o keyboard_at.o \ + i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.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 rtc.o \ scat.o serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 34d039b..fae6315 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 joystick_standard.o joystick_sw_pad.o keyboard.o keyboard_amstrad.o keyboard_at.o \ + i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.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 rtc.o \ scat.o serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ diff --git a/src/gameport.c b/src/gameport.c index ba6b235..ba249bb 100644 --- a/src/gameport.c +++ b/src/gameport.c @@ -6,6 +6,7 @@ #include "timer.h" #include "gameport.h" +#include "joystick_ch_flightstick_pro.h" #include "joystick_standard.h" #include "joystick_sw_pad.h" @@ -17,6 +18,7 @@ static joystick_if_t *joystick_list[] = &joystick_standard_4button, &joystick_standard_6button, &joystick_standard_8button, + &joystick_ch_flightstick_pro, &joystick_sw_pad, NULL }; @@ -43,6 +45,11 @@ int joystick_get_button_count(int joystick) return joystick_list[joystick]->button_count; } +int joystick_get_pov_count(int joystick) +{ + return joystick_list[joystick]->pov_count; +} + char *joystick_get_axis_name(int joystick, int id) { return joystick_list[joystick]->axis_names[id]; @@ -53,6 +60,11 @@ char *joystick_get_button_name(int joystick, int id) return joystick_list[joystick]->button_names[id]; } +char *joystick_get_pov_name(int joystick, int id) +{ + return joystick_list[joystick]->pov_names[id]; +} + typedef struct gameport_axis_t { int count; diff --git a/src/gameport.h b/src/gameport.h index 2e604dd..aac97d8 100644 --- a/src/gameport.h +++ b/src/gameport.h @@ -10,10 +10,11 @@ typedef struct void (*write)(void *p); int (*read_axis)(void *p, int axis); void (*a0_over)(void *p); - int axis_count, button_count; + int axis_count, button_count, pov_count; int max_joysticks; char axis_names[8][32]; char button_names[32][32]; + char pov_names[4][32]; } joystick_if_t; extern int joystick_type; @@ -21,8 +22,10 @@ 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); +int joystick_get_pov_count(int joystick); char *joystick_get_axis_name(int joystick, int id); char *joystick_get_button_name(int joystick, int id); +char *joystick_get_pov_name(int joystick, int id); void gameport_update_joystick_type(); diff --git a/src/joystick_ch_flightstick_pro.c b/src/joystick_ch_flightstick_pro.c new file mode 100644 index 0000000..451643c --- /dev/null +++ b/src/joystick_ch_flightstick_pro.c @@ -0,0 +1,89 @@ +#include +#include "ibm.h" +#include "device.h" +#include "timer.h" +#include "gameport.h" +#include "joystick_standard.h" +#include "plat-joystick.h" + +static void *ch_flightstick_pro_init() +{ +} + +static void ch_flightstick_pro_close(void *p) +{ +} + +static uint8_t ch_flightstick_pro_read(void *p) +{ + uint8_t ret = 0xf0; + + if (JOYSTICK_PRESENT(0)) + { + if (joystick_state[0].button[0]) + ret &= ~0x10; + if (joystick_state[0].button[1]) + ret &= ~0x20; + if (joystick_state[0].button[2]) + ret &= ~0x40; + if (joystick_state[0].button[3]) + ret &= ~0x80; + if (joystick_state[0].pov[0] != -1) + { + if (joystick_state[0].pov[0] > 315 || joystick_state[0].pov[0] < 45) + ret &= ~0xf0; + else if (joystick_state[0].pov[0] >= 45 && joystick_state[0].pov[0] < 135) + ret &= ~0xb0; + else if (joystick_state[0].pov[0] >= 135 && joystick_state[0].pov[0] < 225) + ret &= ~0x70; + else if (joystick_state[0].pov[0] >= 225 && joystick_state[0].pov[0] < 315) + ret &= ~0x30; + } + } + + return ret; +} + +static void ch_flightstick_pro_write(void *p) +{ +} + +static int ch_flightstick_pro_read_axis(void *p, int axis) +{ + if (!JOYSTICK_PRESENT(0)) + return AXIS_NOT_PRESENT; + + switch (axis) + { + case 0: + return joystick_state[0].axis[0]; + case 1: + return joystick_state[0].axis[1]; + case 2: + return 0; + case 3: + return joystick_state[0].axis[2]; + } +} + +static void ch_flightstick_pro_a0_over(void *p) +{ +} + +joystick_if_t joystick_ch_flightstick_pro = +{ + .name = "CH Flightstick Pro", + .init = ch_flightstick_pro_init, + .close = ch_flightstick_pro_close, + .read = ch_flightstick_pro_read, + .write = ch_flightstick_pro_write, + .read_axis = ch_flightstick_pro_read_axis, + .a0_over = ch_flightstick_pro_a0_over, + .max_joysticks = 1, + .axis_count = 3, + .button_count = 4, + .pov_count = 1, + .axis_names = {"X axis", "Y axis", "Throttle"}, + .button_names = {"Button 1", "Button 2", "Button 3", "Button 4"}, + .pov_names = {"POV"} +}; diff --git a/src/joystick_ch_flightstick_pro.h b/src/joystick_ch_flightstick_pro.h new file mode 100644 index 0000000..6f40c29 --- /dev/null +++ b/src/joystick_ch_flightstick_pro.h @@ -0,0 +1 @@ +extern joystick_if_t joystick_ch_flightstick_pro; diff --git a/src/pc.c b/src/pc.c index 5829c1b..381366c 100644 --- a/src/pc.c +++ b/src/pc.c @@ -678,6 +678,13 @@ void loadconfig(char *fn) sprintf(s, "joystick_%i_button_%i", c, d); joystick_state[c].button_mapping[d] = config_get_int("Joysticks", s, d); } + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_pov_%i_x", c, d); + joystick_state[c].pov_mapping[d][0] = config_get_int("Joysticks", s, d); + sprintf(s, "joystick_%i_pov_%i_y", c, d); + joystick_state[c].pov_mapping[d][1] = config_get_int("Joysticks", s, d); + } } } @@ -765,6 +772,13 @@ void saveconfig() sprintf(s, "joystick_%i_button_%i", c, d); config_set_int("Joysticks", s, joystick_state[c].button_mapping[d]); } + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_pov_%i_x", c, d); + config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][0]); + sprintf(s, "joystick_%i_pov_%i_y", c, d); + config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][1]); + } } } diff --git a/src/plat-joystick.h b/src/plat-joystick.h index efc8e96..667732c 100644 --- a/src/plat-joystick.h +++ b/src/plat-joystick.h @@ -53,6 +53,7 @@ extern "C" { int plat_joystick_nr; int axis_mapping[8]; int button_mapping[32]; + int pov_mapping[4][2]; } joystick_t; #define MAX_JOYSTICKS 4 @@ -62,4 +63,4 @@ extern "C" { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/src/win-joystick.cc b/src/win-joystick.cc index 4c44bee..dbe5db2 100644 --- a/src/win-joystick.cc +++ b/src/win-joystick.cc @@ -175,6 +175,30 @@ void joystick_close() } } +static int joystick_get_axis(int joystick_nr, int mapping) +{ + if (mapping & POV_X) + { + int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + + if (LOWORD(pov) == 0xFFFF) + return 0; + else + return sin((2*M_PI * (double)pov) / 36000.0) * 32767; + } + else if (mapping & POV_Y) + { + int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + + if (LOWORD(pov) == 0xFFFF) + return 0; + else + return -cos((2*M_PI * (double)pov) / 36000.0) * 32767; + } + else + return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; +} + void joystick_poll() { int c, d; @@ -218,30 +242,25 @@ void joystick_poll() 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]; - } + joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); 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]]; + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + int x, y; + double angle, magnitude; + + x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); + y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); + + angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI); + magnitude = sqrt((double)x*(double)x + (double)y*(double)y); + + if (magnitude < 16384) + joystick_state[c].pov[d] = -1; + else + joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360; + } } else { @@ -249,6 +268,8 @@ void joystick_poll() joystick_state[c].axis[d] = 0; for (d = 0; d < joystick_get_button_count(joystick_type); d++) joystick_state[c].button[d] = 0; + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + joystick_state[c].pov[d] = -1; } } } diff --git a/src/win-joystickconfig.c b/src/win-joystickconfig.c index b2aa4c0..b5371de 100644 --- a/src/win-joystickconfig.c +++ b/src/win-joystickconfig.c @@ -79,6 +79,38 @@ static void rebuild_axis_button_selections(HWND hdlg) id += 2; } + + for (c = 0; c < joystick_get_pov_count(joystick_config_type)*2; c++) + { + int sel = c; + + h = GetDlgItem(hdlg, id); + SendMessage(h, CB_RESETCONTENT, 0, 0); + + if (joystick) + { + for (d = 0; d < plat_joystick_state[joystick-1].nr_povs; d++) + { + char s[80]; + + sprintf(s, "%s (X axis)", plat_joystick_state[joystick-1].pov[d].name); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + } + for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].axis[d].name); + } + SendMessage(h, CB_SETCURSEL, sel, 0); + EnableWindow(h, TRUE); + } + else + EnableWindow(h, FALSE); + + id += 2; + } + } static int get_axis(HWND hdlg, int id) @@ -97,6 +129,23 @@ static int get_axis(HWND hdlg, int id) return POV_X | (axis_sel >> 1); } +static int get_pov(HWND hdlg, int id) +{ + HWND h = GetDlgItem(hdlg, id); + int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0); + int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_povs*2; + + if (axis_sel < nr_povs) + { + if (axis_sel & 1) + return POV_Y | (axis_sel >> 1); + else + return POV_X | (axis_sel >> 1); + } + + return axis_sel - nr_povs; +} + static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) @@ -120,6 +169,7 @@ static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wPar if (joystick_state[joystick_nr].plat_joystick_nr) { int nr_axes = plat_joystick_state[joystick-1].nr_axes; + int nr_povs = plat_joystick_state[joystick-1].nr_povs; for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { int mapping = joystick_state[joystick_nr].axis_mapping[c]; @@ -139,6 +189,29 @@ static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wPar SendMessage(h, CB_SETCURSEL, joystick_state[joystick_nr].button_mapping[c], 0); id += 2; } + for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) + { + int mapping; + + h = GetDlgItem(hdlg, id); + mapping = joystick_state[joystick_nr].pov_mapping[c][0]; + if (mapping & POV_X) + SendMessage(h, CB_SETCURSEL, (mapping & 3)*2, 0); + else if (mapping & POV_Y) + SendMessage(h, CB_SETCURSEL, (mapping & 3)*2 + 1, 0); + else + SendMessage(h, CB_SETCURSEL, mapping + nr_povs*2, 0); + id += 2; + h = GetDlgItem(hdlg, id); + mapping = joystick_state[joystick_nr].pov_mapping[c][1]; + if (mapping & POV_X) + SendMessage(h, CB_SETCURSEL, (mapping & 3)*2, 0); + else if (mapping & POV_Y) + SendMessage(h, CB_SETCURSEL, (mapping & 3)*2 + 1, 0); + else + SendMessage(h, CB_SETCURSEL, mapping + nr_povs*2, 0); + id += 2; + } } } return TRUE; @@ -174,6 +247,15 @@ static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wPar joystick_state[joystick_nr].button_mapping[c] = SendMessage(h, CB_GETCURSEL, 0, 0); id += 2; } + for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) + { + h = GetDlgItem(hdlg, id); + joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id); + id += 2; + h = GetDlgItem(hdlg, id); + joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(hdlg, id); + id += 2; + } } } case IDCANCEL: @@ -359,6 +441,59 @@ void joystickconfig_open(HWND hwnd, int joy_nr, int type) y += 20; } + for (c = 0; c < joystick_get_pov_count(type)*2; c++) + { + char s[80]; + + /*Combo box*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 70; + item->y = y; + item->id = id++; + + item->cx = 140; + item->cy = 150; + + item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0085; // combo box class + + if (c & 1) + sprintf(s, "%s (Y axis)", joystick_get_pov_name(type, c/2)); + else + sprintf(s, "%s (X axis)", joystick_get_pov_name(type, c/2)); + data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256); + *data++ = 0; // no creation data + + if (((unsigned long)data) & 2) + data++; + + /*Static text*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 10; + item->y = y; + item->id = id++; + + item->cx = 60; + item->cy = 15; + + item->style = WS_CHILD | WS_VISIBLE; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0082; // static class + + data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256); + *data++ = 0; // no creation data + + if (((unsigned long)data) & 2) + data++; + + y += 20; + } + dlg->cdit = (id - IDC_CONFIG_BASE) + 2; // DEFPUSHBUTTON "OK",IDOK,64,232,50,14, WS_TABSTOP