diff --git a/core/hw/maple/maple_cfg.cpp b/core/hw/maple/maple_cfg.cpp index 820d68de3..a705fd639 100644 --- a/core/hw/maple/maple_cfg.cpp +++ b/core/hw/maple/maple_cfg.cpp @@ -22,6 +22,7 @@ Plugins: ImageUpdate(data); */ void UpdateInputState(u32 port); +void UpdateVibration(u32 port, u32 value); extern u16 kcode[4]; extern u32 vks[4]; @@ -42,6 +43,11 @@ struct MapleConfigMap : IMapleConfigMap this->dev=dev; } + void SetVibration(u32 value) + { + UpdateVibration(dev->bus_id, value); + } + void GetInput(PlainJoystickState* pjs) { UpdateInputState(dev->bus_id); 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/linux-dist/main.cpp b/core/linux-dist/main.cpp index 5862aeef6..6ba6a9c56 100755 --- a/core/linux-dist/main.cpp +++ b/core/linux-dist/main.cpp @@ -191,6 +191,11 @@ void UpdateInputState(u32 port) #endif } +void UpdateVibration(u32 port, u32 value) +{ + +} + void os_DoEvents() { #if defined(SUPPORT_X11) diff --git a/core/nacl/nacl.cpp b/core/nacl/nacl.cpp index b7fa39d1e..d9bc137db 100644 --- a/core/nacl/nacl.cpp +++ b/core/nacl/nacl.cpp @@ -257,6 +257,10 @@ void UpdateInputState(u32 port) { } +void UpdateVibration(u32 port, u32 value) { + +} + void os_CreateWindow() { } diff --git a/core/windows/winmain.cpp b/core/windows/winmain.cpp index 7fac9f59d..bba32de7e 100644 --- a/core/windows/winmain.cpp +++ b/core/windows/winmain.cpp @@ -5,6 +5,8 @@ #define _WIN32_WINNT 0x0500 #include +#include +#pragma comment(lib, "XInput9_1_0.lib") PCHAR* CommandLineToArgvA( @@ -105,7 +107,7 @@ PCHAR* bool VramLockedWrite(u8* address); bool ngen_Rewrite(unat& addr,unat retadr,unat acc); bool BM_LockedWrite(u8* address); - +void UpdateController(u32 port); LONG ExeptionHandler(EXCEPTION_POINTERS *ExceptionInfo) { @@ -235,6 +237,8 @@ void UpdateInputState(u32 port) if (GetAsyncKeyState(VK_RIGHT)) kcode[port]&=~key_CONT_DPAD_RIGHT; + UpdateController(port); + if (GetAsyncKeyState(VK_F1)) settings.pvr.ta_skip = 100; @@ -245,7 +249,63 @@ void UpdateInputState(u32 port) DiscSwap(); } +void UpdateController(u32 port) + { + XINPUT_STATE state; + + if (XInputGetState(port, &state) == 0) + { + WORD xbutton = state.Gamepad.wButtons; + if (xbutton & XINPUT_GAMEPAD_A) + kcode[port] &= ~key_CONT_A; + if (xbutton & XINPUT_GAMEPAD_B) + kcode[port] &= ~key_CONT_B; + if (xbutton & XINPUT_GAMEPAD_Y) + kcode[port] &= ~key_CONT_Y; + if (xbutton & XINPUT_GAMEPAD_X) + kcode[port] &= ~key_CONT_X; + + if (xbutton & XINPUT_GAMEPAD_START) + kcode[port] &= ~key_CONT_START; + + if (xbutton & XINPUT_GAMEPAD_DPAD_UP) + kcode[port] &= ~key_CONT_DPAD_UP; + if (xbutton & XINPUT_GAMEPAD_DPAD_DOWN) + kcode[port] &= ~key_CONT_DPAD_DOWN; + if (xbutton & XINPUT_GAMEPAD_DPAD_LEFT) + kcode[port] &= ~key_CONT_DPAD_LEFT; + if (xbutton & XINPUT_GAMEPAD_DPAD_RIGHT) + kcode[port] &= ~key_CONT_DPAD_RIGHT; + + lt[port] |= state.Gamepad.bLeftTrigger; + rt[port] |= state.Gamepad.bRightTrigger; + + joyx[port] |= state.Gamepad.sThumbLX / 257; + joyy[port] |= -state.Gamepad.sThumbLY / 257; + } + } + +void UpdateVibration(u32 port, u32 value) +{ + 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 - 0x07) / 15.0; + + 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) { diff --git a/shell/android/jni/src/Android.cpp b/shell/android/jni/src/Android.cpp index f50a17b9d..0bbd75d0d 100644 --- a/shell/android/jni/src/Android.cpp +++ b/shell/android/jni/src/Android.cpp @@ -231,6 +231,11 @@ void UpdateInputState(u32 Port) // @@@ Nothing here yet } +void UpdateVibration(u32 port, u32 value) +{ + +} + void *libPvr_GetRenderTarget() { // No X11 window in Android diff --git a/shell/apple/emulator-ios/emulator/ios_main.mm b/shell/apple/emulator-ios/emulator/ios_main.mm index 304bd069e..efd613b36 100644 --- a/shell/apple/emulator-ios/emulator/ios_main.mm +++ b/shell/apple/emulator-ios/emulator/ios_main.mm @@ -106,6 +106,10 @@ void UpdateInputState(u32 port) { } +void UpdateVibration(u32 port, u32 value) { + +} + void get_mic_data(u8* ) { } diff --git a/shell/apple/emulator-osx/emulator-osx/osx-main.mm b/shell/apple/emulator-osx/emulator-osx/osx-main.mm index db3586891..8dccbf7db 100644 --- a/shell/apple/emulator-osx/emulator-osx/osx-main.mm +++ b/shell/apple/emulator-osx/emulator-osx/osx-main.mm @@ -59,6 +59,10 @@ void UpdateInputState(u32 port) { } +void UpdateVibration(u32 port, u32 value) { + +} + void os_CreateWindow() { }