diff --git a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp index 8e682550b..472d70be4 100644 --- a/core/hw/maple/maple_cfg.cpp +++ b/core/hw/maple/maple_cfg.cpp @@ -21,6 +21,7 @@ Plugins: ImageUpdate(data); */ void UpdateInputState(u32 port); +void UpdateVibration(u32 port, u32 value); extern u16 kcode[4]; extern u32 vks[4]; @@ -41,6 +42,11 @@ struct MapleConfigMap : IMapleConfigMap this->dev=dev; } + void SetVibration(u32 value) + { + UpdateVibration(dev->bus_id, value); + } + void GetInput(PlainJoystickState* pjs) { UpdateInputState(dev->bus_id); @@ -72,7 +78,7 @@ void mcfg_CreateDevices() mcfg_Create(MDT_SegaController,0,5); mcfg_Create(MDT_SegaVMU,0,0); - mcfg_Create(MDT_SegaVMU,0,1); + mcfg_Create(MDT_PurupuruPack,0,1); #else mcfg_Create(MDT_NaomiJamma, 0, 5); #endif diff --git a/core/hw/maple/maple_cfg.h b/core/hw/maple/maple_cfg.h index de724a0f8..6b7d9efb6 100644 --- a/core/hw/maple/maple_cfg.h +++ b/core/hw/maple/maple_cfg.h @@ -57,6 +57,7 @@ struct PlainJoystickState struct IMapleConfigMap { + virtual void SetVibration(u32 value) = 0; virtual void GetInput(PlainJoystickState* pjs)=0; virtual void SetImage(void* img)=0; virtual ~IMapleConfigMap() {} diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index 227099847..c07b5dac7 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -22,6 +22,7 @@ const char* maple_sega_mouse_name = "Emulated Dreamcast Mouse"; const char* maple_sega_dreameye_name_1 = "Dreamcast Camera Flash Devic"; const char* maple_sega_dreameye_name_2 = "Dreamcast Camera Flash LDevic"; const char* maple_sega_mic_name = "MicDevice for Dreameye"; +const char* maple_sega_purupuru_name = "Puru Puru Pack"; const char* maple_sega_brand = "Produced By or Under License From SEGA ENTERPRISES,LTD."; @@ -844,6 +845,98 @@ struct maple_microphone: maple_base } }; + +struct maple_sega_purupuru : maple_base +{ + u16 AST, AST_ms; + u32 VIBSET; + + virtual u32 dma(u32 cmd) + { + switch (cmd) + { + case MDC_DeviceRequest: + //caps + //4 + w32(MFID_8_Vibration); + + //struct data + //3*4 + w32(0x00000101); + w32(0); + w32(0); + + //1 area code + w8(0xFF); + + //1 direction + w8(0); + + //30 + wstr(maple_sega_purupuru_name, 30); + + //60 + wstr(maple_sega_brand, 60); + + //2 + w16(0x00C8); + + //2 + w16(0x0640); + + return MDRS_DeviceStatus; + + //get last vibration + case MDCF_GetCondition: + + w32(MFID_8_Vibration); + + w32(VIBSET); + + return MDRS_DataTransfer; + + case MDCF_GetMediaInfo: + + w32(MFID_8_Vibration); + + // PuruPuru vib specs + w32(0x3B07E010); + + return MDRS_DataTransfer; + + case MDCF_BlockRead: + + w32(MFID_8_Vibration); + w32(0); + + w16(2); + w16(AST); + + return MDRS_DataTransfer; + + case MDCF_BlockWrite: + + //Auto-stop time + AST = dma_buffer_in[10]; + AST_ms = AST * 250 + 250; + + return MDRS_DeviceReply; + + case MDCF_SetCondition: + + VIBSET = *(u32*)&dma_buffer_in[4]; + //Do the rumble thing! + config->SetVibration(VIBSET); + + return MDRS_DeviceReply; + + default: + //printf("UNKOWN MAPLE COMMAND %d\n",cmd); + return MDRE_UnknownFunction; + } + } +}; + char EEPROM[0x100]; bool EEPROM_loaded = false; @@ -1300,6 +1393,11 @@ maple_device* maple_Create(MapleDeviceType type) rv = new maple_sega_vmu(); break; + case MDT_PurupuruPack: + rv = new maple_sega_purupuru(); + break; + + case MDT_NaomiJamma: rv = new maple_naomi_jamma(); diff --git a/core/hw/maple/maple_devs.h b/core/hw/maple/maple_devs.h index 3d7aeee56..91140822d 100755 --- a/core/hw/maple/maple_devs.h +++ b/core/hw/maple/maple_devs.h @@ -6,6 +6,7 @@ enum MapleDeviceType MDT_SegaController, MDT_SegaVMU, MDT_Microphone, + MDT_PurupuruPack, MDT_NaomiJamma, diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index f1c6214fe..d0d1c8beb 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -286,7 +286,29 @@ void UpdateController(u32 port) } } +void UpdateVibration(u32 port, u32 value) +{ + const u8 freq_l = 0x16; + //const u8 freq_h = 0x31; + u8 POW_POS = (value >> 8) & 0x3; + u8 POW_NEG = (value >> 12) & 0x3; + u8 FREQ = (value >> 16) & 0xFF; + + XINPUT_VIBRATION vib; + + double pow = (POW_POS + POW_NEG) / 7.0; + double pow_l = pow * (0x3B - FREQ) / 17.0; + double pow_r = pow * (FREQ / (double)freq_l); + + if (pow_l > 1.0) pow_l = 1.0; + if (pow_r > 1.0) pow_r = 1.0; + + vib.wLeftMotorSpeed = (u16)(65535 * pow_l); + vib.wRightMotorSpeed = (u16)(65535 * pow_r); + + XInputSetState(port, &vib); +} LRESULT CALLBACK WndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {