OSDN Git Service

[VM][FMTOWNS][JOYSTICK] Initial support of 2 buttons PAD.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 29 Jan 2020 16:14:00 +0000 (01:14 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 29 Jan 2020 16:14:00 +0000 (01:14 +0900)
source/src/vm/fmtowns/joystick.cpp [new file with mode: 0644]
source/src/vm/fmtowns/joystick.h [new file with mode: 0644]

diff --git a/source/src/vm/fmtowns/joystick.cpp b/source/src/vm/fmtowns/joystick.cpp
new file mode 100644 (file)
index 0000000..1d44f1b
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+       FUJITSU FM Towns Emulator 'eFMTowns'
+
+       Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
+       Date   : 2020.01.28 -
+    History : 2020.01.28 Initial from FM7.
+       [ Towns PAD ]
+
+*/
+
+#include "./joystick.h"
+
+namespace FMTOWNS {
+
+void JOYSTICK::reset()
+{
+       joydata[0] = joydata[1] = 0x00;
+       dx = dy = 0;
+       lx = ly = 0;
+       mouse_phase = 0;
+       mouse_strobe = false;
+       mouse_type = config.mouse_type;
+       switch(mouse_type & 0x03){
+       case 1:
+               emulate_mouse[0] = true;
+               emulate_mouse[1] = false;
+               break;
+       case 2:
+               emulate_mouse[0] = false;
+               emulate_mouse[1] = true;
+               break;
+       default:
+               emulate_mouse[0] = false;
+               emulate_mouse[1] = false;
+               break;
+       }
+       mouse_state = emu->get_mouse_buffer();
+       mask = 0xff;
+}
+
+void JOYSTICK::initialize()
+{
+       rawdata = emu->get_joy_buffer();
+       mouse_state = emu->get_mouse_buffer();
+       emulate_mouse[0] = emulate_mouse[1] = false;
+       joydata[0] = joydata[1] = 0x00;
+       dx = dy = 0;
+       lx = ly = -1;
+       mouse_button = 0x00;
+       mouse_timeout_event = -1;
+       
+       register_frame_event(this);
+}
+
+void JOYSTICK::release()
+{
+}
+       
+void JOYSTICK::event_frame()
+{
+       int ch;
+       int stat = 0x00;
+       uint32_t retval = 0x00;
+       uint32_t val;
+       mouse_state = emu->get_mouse_buffer();
+       if(mouse_state != NULL) {
+               dx += mouse_state[0];
+               dy += mouse_state[1];
+               if(dx < -127) {
+                       dx = -127;
+               } else if(dx > 127) {
+                       dx = 127;
+               }
+               if(dy < -127) {
+                       dy = -127;
+               } else if(dy > 127) {
+                       dy = 127;
+               }
+       }               
+       if(mouse_state != NULL) {
+               stat = mouse_state[2];
+               mouse_button = 0x00;
+               if((stat & 0x01) == 0) mouse_button |= 0x10; // left
+               if((stat & 0x02) == 0) mouse_button |= 0x20; // right
+       }
+       rawdata = emu->get_joy_buffer();
+       if(rawdata == NULL) return;
+   
+       for(ch = 0; ch < 2; ch++) {
+               if(!emulate_mouse[ch]) { // Joystick
+                       val = rawdata[ch];
+                       retval = 0x00;     
+                       if(val & 0x01) retval |= 0x01;
+                       if(val & 0x02) retval |= 0x02;
+                       if(val & 0x04) retval |= 0x04;
+                       if(val & 0x08) retval |= 0x08;
+                       if(val & 0x10) retval |= 0x10;
+                       if(val & 0x20) retval |= 0x20;
+                       if(val & 0x40) retval |= 0x10;  // Button A'
+                       if(val & 0x80) retval |= 0x20;  // Button B'
+                       if(val & 0x40) retval |= 0x40;  // RUN
+                       if(val & 0x80) retval |= 0x80;  // SELECT
+                       joydata[ch] = retval;
+               } else { // MOUSE
+               }
+       }
+}
+void JOYSTICK::write_io8(uint32_t address, uint32_t data)
+{
+       // ToDo: Mouse
+       if(address == 0x04d6) {
+               mask = data;
+       }
+}
+
+uint32_t JOYSTICK::read_io8(uint32_t address)
+{
+       // ToDo: Implement 6 buttons pad. & mouse
+       uint8_t retval = 0;
+       uint8_t port_num = (address & 0x02) >> 1;
+       switch(address) {
+       case 0x04d0:
+       case 0x04d2:
+               if((mask & (0x10 << port_num)) != 0) {
+                       retval = (joydata[port_num] & 0x3f) | 0x40;
+               } else {
+                       retval = (joydata[port_num] & 0x0f) | 0x30;
+               }                       
+               if((joydata[port_num] & 0x40) != 0) { // RUN = L+R
+                       retval = retval & ~0x0c;
+               }
+               if((joydata[port_num] & 0x80) != 0) { // RUN = UP+DOWN
+                       retval = retval & ~0x03;
+               }
+               if(((joydata[port_num] & 0x40) != 0) && (mask & (0x01 << (port_num * 2)) != 0)) {
+                       retval = retval & ~0x10;
+               }
+               if(((joydata[port_num] & 0x40) != 0) && (mask & (0x02 << (port_num * 2)) != 0)) {
+                       retval = retval & ~0x20;
+               }
+               return retval;
+               break;
+       default:
+               break;
+       }
+       return 0x00;
+}
+
+void JOYSTICK::event_callback(int event_id, int err)
+{
+}
+
+void JOYSTICK::write_signal(int id, uint32_t data, uint32_t mask)
+{
+}      
+
+void JOYSTICK::update_config(void)
+{
+}
+
+#define STATE_VERSION 1
+
+bool JOYSTICK::process_state(FILEIO *state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       state_fio->StateValue(mask);
+       state_fio->StateArray(joydata, sizeof(joydata), 1);
+       state_fio->StateArray(emulate_mouse, sizeof(emulate_mouse), 1);
+       state_fio->StateValue(dx);
+       state_fio->StateValue(dy);
+       state_fio->StateValue(lx);
+       state_fio->StateValue(ly);
+       state_fio->StateValue(mouse_button);
+       state_fio->StateValue(mouse_strobe);
+       state_fio->StateValue(mouse_phase);
+       state_fio->StateValue(mouse_data);
+       //state_fio->StateValue(mouse_timeout_event);
+
+       
+       return true;
+}
+
+}
diff --git a/source/src/vm/fmtowns/joystick.h b/source/src/vm/fmtowns/joystick.h
new file mode 100644 (file)
index 0000000..9902aac
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+       FUJITSU FM Towns Emulator 'eFMTowns'
+
+       Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
+       Date   : 2020.01.28 -
+    History : 2020.01.28 Initial from FM7.
+       [ Towns PAD ]
+
+*/
+
+#pragma once
+#include "../vm.h"
+#include "../../emu.h"
+#include "../device.h"
+
+namespace FMTOWNS {
+class JOYSTICK : public DEVICE
+{
+private:
+       bool emulate_mouse[2];
+       uint32_t joydata[2];
+       
+       const uint32_t *rawdata;
+       const int32_t *mouse_state;
+       int dx, dy;
+       int lx, ly;
+       uint32_t mouse_button;
+       bool mouse_strobe;
+       uint32_t mouse_data;
+       int mouse_phase;
+       int mouse_timeout_event;
+       int mouse_type;
+       uint8_t mask;
+public:
+       JOYSTICK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
+       {
+               set_device_name(_T("FM-Towns PAD and MOUSE (JIS)"));
+       }
+       ~JOYSTICK() {}
+       
+       // common functions
+       void initialize(void);
+       void event_frame(void);
+       void release();
+       void reset();
+       
+       void __FASTCALL write_io8(uint32_t addr, uint32_t data);
+       uint32_t __FASTCALL read_io8(uint32_t addr);
+       void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask);
+       void event_callback(int event_id, int err);
+       void update_config();
+       
+       bool process_state(FILEIO* state_fio, bool loading);
+       
+};
+}
+
+