Skip to content

Commit

Permalink
dreamconn: detect dreamconn+ with VID/PID. Send maple data as text.
Browse files Browse the repository at this point in the history
Create DreamConn gamepad when detected.
Send/receive maple data in ascii dump form.
Simplify maple device creation.

Issue #1305
  • Loading branch information
flyinghead committed Dec 20, 2024
1 parent 6c3d77b commit b9fdd50
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 115 deletions.
5 changes: 1 addition & 4 deletions core/hw/maple/maple_cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,7 @@ static void mcfg_Create(MapleDeviceType type, u32 bus, u32 port, s32 player_num
{
delete MapleDevices[bus][port];
maple_device* dev = maple_Create(type);
dev->Setup(maple_GetAddress(bus, port), player_num);
dev->config = new MapleConfigMap(dev);
dev->OnSetup();
MapleDevices[bus][port] = dev;
dev->Setup(bus, port, player_num);
}

static void createNaomiDevices()
Expand Down
97 changes: 66 additions & 31 deletions core/hw/maple/maple_devs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,19 @@ const char* maple_densha_controller_name = "TAITO 001 Controller";
const char* maple_sega_brand = "Produced By or Under License From SEGA ENTERPRISES,LTD.";

//fill in the info
void maple_device::Setup(u32 port, int playerNum)
void maple_device::Setup(u32 bus, u32 port, int playerNum)
{
maple_port = port;
bus_port = maple_GetPort(port);
bus_id = maple_GetBusId(port);
maple_port = (bus << 6) | (1 << port);
bus_port = port;
bus_id = bus;
logical_port[0] = 'A' + bus_id;
logical_port[1] = bus_port == 5 ? 'x' : '1' + bus_port;
logical_port[2] = 0;
player_num = playerNum == -1 ? bus_id : playerNum;

config = new MapleConfigMap(this);
OnSetup();
MapleDevices[bus][port] = this;
}
maple_device::~maple_device()
{
Expand Down Expand Up @@ -683,7 +687,7 @@ struct maple_sega_vmu: maple_base
case MFID_2_LCD:
{
DEBUG_LOG(MAPLE, "VMU %s LCD write", logical_port);
r32();
r32(); // PT, phase, block#
rptr(lcd_data,192);

u8 white=0xff,black=0x00;
Expand Down Expand Up @@ -1719,7 +1723,7 @@ struct RFIDReaderWriter : maple_base
u32 resp = Dma(command, &buffer_in[1], buffer_in_len - 4, &buffer_out[1], outlen);

if (reci & 0x20)
reci |= maple_GetAttachedDevices(maple_GetBusId(reci));
reci |= maple_GetAttachedDevices(bus_id);

verify(u8(outlen / 4) * 4 == outlen);
buffer_out[0] = (resp << 0 ) | (reci << 8) | (send << 16) | ((outlen / 4) << 24);
Expand Down Expand Up @@ -2107,63 +2111,94 @@ maple_device* maple_Create(MapleDeviceType type)

struct DreamConnVmu : public maple_sega_vmu
{
DreamConn& dreamconn;
std::shared_ptr<DreamConn> dreamconn;

DreamConnVmu(DreamConn& dreamconn) : dreamconn(dreamconn) {
DreamConnVmu(std::shared_ptr<DreamConn> dreamconn) : dreamconn(dreamconn) {
}

u32 dma(u32 cmd) override
{
if (cmd == MDCF_BlockWrite && *(u32 *)dma_buffer_in == MFID_2_LCD)
{
// send the raw maple msg
dreamconn.send(dma_buffer_in - 4, dma_count_in + 4);
const MapleMsg *msg = reinterpret_cast<const MapleMsg*>(dma_buffer_in - 4);
dreamconn->send(*msg);
}
return maple_sega_vmu::dma(cmd);
}

void copy(maple_sega_vmu *other)
{
memcpy(flash_data, other->flash_data, sizeof(flash_data));
memcpy(lcd_data, other->lcd_data, sizeof(lcd_data));
memcpy(lcd_data_decoded, other->lcd_data_decoded, sizeof(lcd_data_decoded));
fullSaveNeeded = other->fullSaveNeeded;
}

void updateScreen()
{
MapleMsg msg;
msg.command = MDCF_BlockWrite;
msg.destAP = maple_port;
msg.originAP = bus_id << 6;
msg.size = 2 + sizeof(lcd_data) / 4;
*(u32 *)&msg.data[0] = MFID_2_LCD;
*(u32 *)&msg.data[4] = 0; // PT, phase, block#
memcpy(&msg.data[8], lcd_data, sizeof(lcd_data));
dreamconn->send(msg);
}
};

struct DreamConnPurupuru : public maple_sega_purupuru
{
DreamConn& dreamconn;
std::shared_ptr<DreamConn> dreamconn;

DreamConnPurupuru(DreamConn& dreamconn) : dreamconn(dreamconn) {
DreamConnPurupuru(std::shared_ptr<DreamConn> dreamconn) : dreamconn(dreamconn) {
}

u32 dma(u32 cmd) override
{
const MapleMsg *msg = reinterpret_cast<const MapleMsg*>(dma_buffer_in - 4);
switch (cmd)
{
case MDCF_BlockWrite:
dreamconn.send(dma_buffer_in - 4, dma_count_in + 4);
dreamconn->send(*msg);
break;

case MDCF_SetCondition:
dreamconn.send(dma_buffer_in - 4, dma_count_in + 4);
dreamconn->send(*msg);
break;
}
return maple_sega_purupuru::dma(cmd);
}
};

void createDreamConnDevices(DreamConn& dreamconn)
void createDreamConnDevices(std::shared_ptr<DreamConn> dreamconn, bool gameStart)
{
const int bus = dreamconn.getBus();
if (dreamconn.hasVmu() && dynamic_cast<DreamConnVmu*>(MapleDevices[bus][0]) == nullptr)
const int bus = dreamconn->getBus();
if (dreamconn->hasVmu())
{
delete MapleDevices[bus][0];
DreamConnVmu *dev = new DreamConnVmu(dreamconn);
dev->Setup((bus << 6) | 1);
dev->config = new MapleConfigMap(dev);
dev->OnSetup();
MapleDevices[bus][0] = dev;
}
if (dreamconn.hasRumble() && dynamic_cast<DreamConnPurupuru*>(MapleDevices[bus][1]) == nullptr)
maple_device *dev = MapleDevices[bus][0];
if (gameStart || (dev != nullptr && dev->get_device_type() == MDT_SegaVMU))
{
DreamConnVmu *vmu = new DreamConnVmu(dreamconn);
vmu->Setup(bus, 0);
if (!gameStart) {
// if loading a state, copy data from the regular vmu and send a screen update
vmu->copy(static_cast<maple_sega_vmu*>(dev));
vmu->updateScreen();
}
delete dev;
}
}
if (dreamconn->hasRumble())
{
delete MapleDevices[bus][1];
DreamConnPurupuru *dev = new DreamConnPurupuru(dreamconn);
dev->Setup((bus << 6) | 2);
dev->config = new MapleConfigMap(dev);
dev->OnSetup();
MapleDevices[bus][1] = dev;
maple_device *dev = MapleDevices[bus][1];
if (gameStart || (dev != nullptr && dev->get_device_type() == MDT_PurupuruPack))
{
delete dev;
DreamConnPurupuru *rumble = new DreamConnPurupuru(dreamconn);
rumble->Setup(bus, 1);
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions core/hw/maple/maple_devs.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ struct maple_device
MapleConfigMap* config;

//fill in the info
void Setup(u32 port, int playerNum = -1);
void Setup(u32 bus, u32 port = 5, int playerNum = -1);

virtual void OnSetup() {};
virtual ~maple_device();
Expand Down Expand Up @@ -246,7 +246,7 @@ struct maple_base: maple_device
u32 resp = Dma(command, &buffer_in[1], buffer_in_len - 4, &buffer_out[1], outlen);

if (reci & 0x20)
reci |= maple_GetAttachedDevices(maple_GetBusId(reci));
reci |= maple_GetAttachedDevices(bus_id);

verify(u8(outlen / 4) * 4 == outlen);
buffer_out[0] = (resp << 0 ) | (send << 8) | (reci << 16) | ((outlen / 4) << 24);
Expand Down
9 changes: 0 additions & 9 deletions core/hw/maple/maple_helper.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
#include "maple_helper.h"
#include "maple_if.h"

u32 maple_GetPort(u32 addr)
{
for (int i=0;i<6;i++)
{
if ((1<<i)&addr)
return i;
}
return 5;
}
u32 maple_GetAttachedDevices(u32 bus)
{
verify(MapleDevices[bus][5]!=0);
Expand Down
15 changes: 0 additions & 15 deletions core/hw/maple/maple_helper.h
Original file line number Diff line number Diff line change
@@ -1,19 +1,4 @@
#pragma once
#include "types.h"

static inline u32 maple_GetBusId(u32 addr)
{
return addr >> 6;
}

u32 maple_GetPort(u32 addr);
u32 maple_GetAttachedDevices(u32 bus);

//device : 0 .. 4 -> subdevice , 5 -> main device :)
static inline u32 maple_GetAddress(u32 bus, u32 port)
{
u32 rv = bus << 6;
rv |= 1 << port;

return rv;
}
12 changes: 10 additions & 2 deletions core/hw/maple/maple_if.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ static void maple_SB_MDSTAR_Write(u32 addr, u32 data)
}
#endif

static u32 getPort(u32 addr)
{
for (int i = 0; i < 6; i++)
if ((1 << i) & addr)
return i;
return 5;
}

static void maple_DoDma()
{
verify(SB_MDEN & 1);
Expand Down Expand Up @@ -202,8 +210,8 @@ static void maple_DoDma()
//Number of additional words in frame
u32 inlen = (frame_header >> 24) & 0xFF;

u32 port = maple_GetPort(reci);
u32 bus = maple_GetBusId(reci);
u32 port = getPort(reci);
u32 bus = reci >> 6;

if (MapleDevices[bus][5] && MapleDevices[bus][port])
{
Expand Down
Loading

0 comments on commit b9fdd50

Please sign in to comment.