flycast/core/hw/maple/maple_devs.h

308 lines
8.2 KiB
C++
Executable File

#pragma once
#include <memory>
#include "types.h"
#include "maple_cfg.h"
#include "maple_helper.h"
#include <cmath>
#include "input/gamepad.h"
enum MapleFunctionID
{
MFID_0_Input = 0x01000000, //DC Controller, Lightgun buttons, arcade stick .. stuff like that
MFID_1_Storage = 0x02000000, //VMU , VMS
MFID_2_LCD = 0x04000000, //VMU
MFID_3_Clock = 0x08000000, //VMU
MFID_4_Mic = 0x10000000, //DC Mic (, dreameye too ?)
MFID_5_ARGun = 0x20000000, //Artificial Retina gun ? seems like this one was never developed or smth -- I only remember of lightguns
MFID_6_Keyboard = 0x40000000, //DC Keyboard
MFID_7_LightGun = 0x80000000, //DC Lightgun
MFID_8_Vibration = 0x00010000, //Puru Puru Puur~~~
MFID_9_Mouse = 0x00020000, //DC Mouse
MFID_10_StorageExt = 0x00040000, //Storage ? probably never used
MFID_11_Camera = 0x00080000, //DreamEye
};
enum MapleDeviceCommand
{
MDC_DeviceRequest = 0x01, //7 words.Note : Initialises device
MDC_AllStatusReq = 0x02, //7 words + device dependent ( seems to be 8 words)
MDC_DeviceReset = 0x03, //0 words
MDC_DeviceKill = 0x04, //0 words
MDC_DeviceStatus = 0x05, //Same as MDC_DeviceRequest ?
MDC_DeviceAllStatus = 0x06, //Same as MDC_AllStatusReq ?
//Various Functions
MDCF_GetCondition = 0x09, //FT
MDCF_GetMediaInfo = 0x0A, //FT,PT,3 pad
MDCF_BlockRead = 0x0B, //FT,PT,Phase,Block #
MDCF_BlockWrite = 0x0C, //FT,PT,Phase,Block #,data ...
MDCF_GetLastError = 0x0D, //FT,PT,Phase,Block #
MDCF_SetCondition = 0x0E, //FT,data ...
MDCF_MICControl = 0x0F, //FT,MIC data ...
MDCF_ARGunControl = 0x10, //FT,AR-Gun data ...
MDC_JVSUploadFirmware = 0x80, // JVS bridge firmware
MDC_JVSGetId = 0x82,
MDC_JVSSelfTest = 0x84, // JVS Self Test
MDC_JVSCommand = 0x86, // JVS I/O
};
enum MapleDeviceRV
{
MDRS_JVSNone = 0x00, // No reply, used for multiple JVS I/O boards
MDRS_DeviceStatus = 0x05, //28 words
MDRS_DeviceStatusAll = 0x06, //28 words + device dependent data
MDRS_DeviceReply = 0x07, //0 words
MDRS_DataTransfer = 0x08, //FT,depends on the command
MDRE_UnknownFunction = 0xFE, //0 words
MDRE_UnknownCmd = 0xFD, //0 words
MDRE_TransmitAgain = 0xFC, //0 words
MDRE_FileError = 0xFB, //1 word, bitfield
MDRE_LCDError = 0xFA, //1 word, bitfield
MDRE_ARGunError = 0xF9, //1 word, bitfield
MDRS_JVSSelfTestReply= 0x85, // JVS I/O SelfTest
MDRS_JVSReply = 0x87, // JVS I/O
};
enum NAOMI_KEYS
{
NAOMI_START_KEY = 1 << 15,
NAOMI_SERVICE_KEY = 1 << 14,
NAOMI_UP_KEY = 1 << 13,
NAOMI_DOWN_KEY = 1 << 12,
NAOMI_LEFT_KEY = 1 << 11,
NAOMI_RIGHT_KEY = 1 << 10,
NAOMI_BTN0_KEY = 1 << 9,
NAOMI_BTN1_KEY = 1 << 8,
NAOMI_BTN2_KEY = 1 << 7,
NAOMI_BTN3_KEY = 1 << 6,
NAOMI_BTN4_KEY = 1 << 5,
NAOMI_BTN5_KEY = 1 << 4,
NAOMI_BTN6_KEY = 1 << 3,
NAOMI_BTN7_KEY = 1 << 2,
NAOMI_BTN8_KEY = 1 << 16,
NAOMI_TEST_KEY = 1 << 1,
// Not an actual button
NAOMI_COIN_KEY = 1 << 0,
};
enum AWAVE_KEYS
{
AWAVE_START_KEY = 1 << 3,
AWAVE_BTN0_KEY = 1 << 2,
AWAVE_BTN1_KEY = 1 << 1,
AWAVE_BTN2_KEY = 1 << 0,
AWAVE_BTN3_KEY = 1 << 10,
AWAVE_BTN4_KEY = 1 << 9,
AWAVE_UP_KEY = 1 << 4,
AWAVE_DOWN_KEY = 1 << 5,
AWAVE_LEFT_KEY = 1 << 6,
AWAVE_RIGHT_KEY = 1 << 7,
AWAVE_SERVICE_KEY = 1 << 13,
AWAVE_TEST_KEY = 1 << 14,
// Not an actual button
AWAVE_COIN_KEY = 1 << 15,
AWAVE_TRIGGER_KEY = 1 << 12,
};
struct IMapleConfigMap;
struct maple_device
{
u8 maple_port; //raw maple port
u8 bus_port; //0 .. 5
u8 bus_id; //0 .. 3
u8 player_num; // for Atomiswave
char logical_port[3]; //A0, etc
MapleConfigMap* config;
//fill in the info
void Setup(u32 port, int playerNum = -1);
virtual void OnSetup() {};
virtual ~maple_device();
virtual u32 RawDma(u32* buffer_in, u32 buffer_in_len, u32* buffer_out) = 0;
virtual bool serialize(void **data, unsigned int *total_size) {
REICAST_S(player_num);
return true;
}
virtual bool unserialize(void **data, unsigned int *total_size, serialize_version_enum version) {
if (version >= V14)
REICAST_US(player_num);
return true;
}
virtual MapleDeviceType get_device_type() = 0;
virtual bool get_lightgun_pos() { return false; }
};
maple_device* maple_Create(MapleDeviceType type);
#define MAPLE_PORTS 4
template<int Magnitude>
void limit_joystick_magnitude(s8& joyx, s8& joyy)
{
float mag = joyx * joyx + joyy * joyy;
if (mag > (float)Magnitude * Magnitude)
{
mag = sqrtf(mag) / (float)Magnitude;
joyx = (s8)lroundf(joyx / mag);
joyy = (s8)lroundf(joyy / mag);
}
}
extern u8 EEPROM[0x100];
void load_naomi_eeprom();
// Mouse position and buttons
extern u32 mo_buttons[4];
extern s32 mo_x_abs[4];
extern s32 mo_y_abs[4];
extern f32 mo_x_delta[4];
extern f32 mo_y_delta[4];
extern f32 mo_wheel_delta[4];
extern s32 mo_x_phy;
extern s32 mo_y_phy;
extern s32 mo_x_prev[4];
extern s32 mo_y_prev[4];
void SetMousePosition(int x, int y, int width, int height, u32 mouseId = 0);
void SetRelativeMousePosition(int xrel, int yrel, u32 mouseId = 0);
#define SWAP32(a) ((((a) & 0xff) << 24) | (((a) & 0xff00) << 8) | (((a) >> 8) & 0xff00) | (((a) >> 24) & 0xff))
const char *GetCurrentGameButtonName(DreamcastKey key);
const char *GetCurrentGameAxisName(DreamcastKey axis);
/*
Base class with dma helpers and stuff
*/
struct maple_base: maple_device
{
u8* dma_buffer_out;
u32* dma_count_out;
u8* dma_buffer_in;
u32 dma_count_in;
void w8(u8 data) { *(u8*)dma_buffer_out = data; dma_buffer_out += 1; dma_count_out[0] += 1; }
void w16(u16 data) { *(u16*)dma_buffer_out = data; dma_buffer_out += 2; dma_count_out[0] += 2; }
void w32(u32 data) { *(u32*)dma_buffer_out = data; dma_buffer_out += 4; dma_count_out[0] += 4; }
void wptr(const void* src, u32 len)
{
u8* src8 = (u8*)src;
while (len--)
w8(*src8++);
}
void wstr(const char* str, u32 len)
{
size_t ln = strlen(str);
verify(len >= ln);
len -= ln;
while (ln--)
w8(*str++);
while (len--)
w8(' ');
}
u8 r8() { u8 rv = *(u8*)dma_buffer_in; dma_buffer_in += 1; dma_count_in -= 1; return rv; }
u16 r16() { u16 rv = *(u16*)dma_buffer_in; dma_buffer_in += 2; dma_count_in -= 2; return rv; }
u32 r32() { u32 rv = *(u32*)dma_buffer_in; dma_buffer_in += 4; dma_count_in -= 4; return rv; }
void rptr(void* dst, u32 len)
{
u8* dst8 = (u8*)dst;
while (len--)
*dst8++ = r8();
}
u32 r_count() { return dma_count_in; }
u32 Dma(u32 Command, u32* buffer_in, u32 buffer_in_len, u32* buffer_out, u32& buffer_out_len)
{
dma_buffer_out = (u8*)buffer_out;
dma_count_out = &buffer_out_len;
dma_buffer_in = (u8*)buffer_in;
dma_count_in = buffer_in_len;
return dma(Command);
}
virtual u32 dma(u32 cmd) = 0;
u32 RawDma(u32* buffer_in, u32 buffer_in_len, u32* buffer_out) override
{
u32 command=buffer_in[0] &0xFF;
//Recipient address
u32 reci = (buffer_in[0] >> 8) & 0xFF;
//Sender address
u32 send = (buffer_in[0] >> 16) & 0xFF;
u32 outlen = 0;
u32 resp = Dma(command, &buffer_in[1], buffer_in_len - 4, &buffer_out[1], outlen);
if (reci & 0x20)
reci |= maple_GetAttachedDevices(maple_GetBusId(reci));
verify(u8(outlen / 4) * 4 == outlen);
buffer_out[0] = (resp << 0 ) | (send << 8) | (reci << 16) | ((outlen / 4) << 24);
return outlen + 4;
}
};
class jvs_io_board;
struct maple_naomi_jamma : maple_base
{
const u8 ALL_NODES = 0xff;
std::vector<std::unique_ptr<jvs_io_board>> io_boards;
bool crazy_mode = false;
u8 jvs_repeat_request[32][256];
u8 jvs_receive_buffer[32][258];
u32 jvs_receive_length[32] = { 0 };
maple_naomi_jamma();
~maple_naomi_jamma() override;
MapleDeviceType get_device_type() override
{
return MDT_NaomiJamma;
}
u8 sense_line(u32 node_id)
{
bool last_node = node_id == io_boards.size();
return last_node ? 0x8E : 0x8F;
}
void send_jvs_message(u32 node_id, u32 channel, u32 length, u8 *data);
void send_jvs_messages(u32 node_id, u32 channel, bool use_repeat, u32 length, u8 *data, bool repeat_first);
bool receive_jvs_messages(u32 channel);
void handle_86_subcommand();
u32 RawDma(u32* buffer_in, u32 buffer_in_len, u32* buffer_out) override;
u32 dma(u32 cmd) override { return 0; }
bool serialize(void **data, unsigned int *total_size) override;
bool unserialize(void **data, unsigned int *total_size, serialize_version_enum version) override;
};