OSDN Git Service

[VM][FMTOWNS][JOYPAD][MOUSE][WIP] Around MOUSE/Joystick.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmtowns / joypad.cpp
1 /*
2         FUJITSU FM Towns Emulator 'eFMTowns'
3
4         Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2020.00.26 -
6     History : 2020.09.26 Separate from joystick.cpp/joystick.h .
7         [ Towns PAD ]
8
9 */
10
11 #include "./joystick.h"
12 #include "./joypad.h"
13
14 namespace FMTOWNS {
15 void JOYPAD::initialize()
16 {
17         DEVICE::initialize();
18         _TCHAR tmps[128] = {0};
19         my_stprintf_s(tmps, sizeof(tmps), _T("FM-Towns JOY PAD #%d"), pad_num);
20         set_device_name(_T("%s"), tmps);
21 //      rawdata = emu->get_joy_buffer();
22         register_frame_event(this);
23         sel_line = false;
24 }
25
26 void JOYPAD::reset()
27 {
28 //      sel_line = true;
29 //      write_signals(&line_dat,   0);
30         query_joystick();
31         write_signals(&line_com,   (enabled) ? 0xffffffff : 0x00000000);
32 }
33
34
35 void JOYPAD::event_pre_frame(void)
36 {
37 }
38
39 void JOYPAD::event_frame(void)
40 {
41 }
42
43 void JOYPAD::query_joystick(void)
44 {
45         // enabled
46         rawdata = emu->get_joy_buffer();
47         uint32_t stat = 0;
48         if((rawdata != NULL) && (enabled)) {
49                 uint32_t d = rawdata[pad_num];
50 //              out_debug_log(_T("DATA: %08X"), d);
51                 if((type_6buttons) && (sel_line)) { // 6Buttons Multiplied
52                         // If COM == 1 THEN CHECK BUTTONS
53                         // 6Buttons PAD is seems to be this schematic:
54                         // http://www.awa.or.jp/home/shimojo/towpadx.htm
55                         // RIGHT <-> C  / LEFT <-> X / UP <-> Z / DOWN <->Y
56                         uint8_t buttons = (rawdata[pad_num] >> 8) & 0x0f;
57                         if((buttons & 0x01) != 0) stat |= LINE_JOYPORT_RIGHT;
58                         if((buttons & 0x02) != 0) stat |= LINE_JOYPORT_LEFT;
59                         if((buttons & 0x04) != 0) stat |= LINE_JOYPORT_DOWN;
60                         if((buttons & 0x08) != 0) stat |= LINE_JOYPORT_UP;
61                 } else {
62                         // If ((COM != 0) OR (PAD IS 2BUTTONS))  THEN CHECK AXIS
63                         uint8_t axis = rawdata[pad_num] & 0x0f;
64                         if((axis & 0x01) != 0) stat |= LINE_JOYPORT_UP;
65                         if((axis & 0x02) != 0) stat |= LINE_JOYPORT_DOWN;
66                         if((axis & 0x04) != 0) stat |= LINE_JOYPORT_LEFT;
67                         if((axis & 0x08) != 0) stat |= LINE_JOYPORT_RIGHT;
68                 }
69                 if((rawdata[pad_num] & 0x10) != 0) stat |= LINE_JOYPORT_A; 
70                 if((rawdata[pad_num] & 0x20) != 0) stat |= LINE_JOYPORT_B; 
71                 // SEL = UP + DOWN, RUN = LEFT + RIGHT 
72                 if((rawdata[pad_num] & 0x40) != 0) stat |= (LINE_JOYPORT_LEFT | LINE_JOYPORT_RIGHT);
73                 if((rawdata[pad_num] & 0x80) != 0) stat |= (LINE_JOYPORT_UP | LINE_JOYPORT_DOWN); 
74         } else {
75                 // None Connected
76                 stat = 0x00;
77         }
78         write_signals(&line_dat, stat);
79 }
80
81 void JOYPAD::write_signal(int id, uint32_t data, uint32_t mask)
82 {
83         uint32_t ndata = data & mask;
84
85         switch(id) {
86         case SIG_JOYPAD_QUERY:
87                 if(ndata == (1 << pad_num)) {
88                         if(enabled) query_joystick();
89                 }
90                 break;
91         case SIG_JOYPAD_ENABLE:
92                 if((ndata & (1 << SIG_JOYPORT_TYPE_2BUTTONS)) != 0) {
93                         //out_debug_log(_T("SELECT 2BUTTONS PAD"));
94                         enabled = true;
95                         type_6buttons = false;
96                         reset();
97                 } else if((ndata & (1 << SIG_JOYPORT_TYPE_6BUTTONS)) != 0) {
98                         //out_debug_log(_T("SELECT 6BUTTONS PAD"));
99                         enabled = true;
100                         type_6buttons = true;
101                         reset();
102                 } else {
103                         out_debug_log(_T("DISCONNECTED"));
104                         enabled = false;
105                         type_6buttons = false;
106                         sel_line = false;
107                         reset();
108                 }
109                 break;
110         case SIG_JOYPAD_SELECT_BUS:
111 //              out_debug_log(_T("SIG_JOYPAD_SELECT_BUS, VALUE=%08X"), ndata);
112                 if(enabled) {
113                         if(ndata != 0) {
114                                 sel_line = true;
115                         } else {
116                                 sel_line = false;
117                         }
118                         write_signals(&line_com, (sel_line) ? 0xffffffff : 0x00000000);
119                 }
120                 break;
121         }
122 }
123
124         
125 void JOYPAD::update_config()
126 {
127 }
128
129
130 #define STATE_VERSION 3
131         
132 bool JOYPAD::process_state(FILEIO *state_fio, bool loading)
133 {
134         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
135                 return false;
136         }
137         if(!state_fio->StateCheckInt32(this_device_id)) {
138                 return false;
139         }
140         state_fio->StateValue(sel_line);
141         state_fio->StateValue(type_6buttons);
142         state_fio->StateValue(pad_num);
143         state_fio->StateValue(enabled);
144         return true;
145 }
146 }