diff options
author | WlodekM <[email protected]> | 2024-06-16 10:35:45 +0300 |
---|---|---|
committer | WlodekM <[email protected]> | 2024-06-16 10:35:45 +0300 |
commit | abef6da56913f1c55528103e60a50451a39628b1 (patch) | |
tree | b3c8092471ecbb73e568cd0d336efa0e7871ee8d /src/Window_PS3.c |
initial commit
Diffstat (limited to 'src/Window_PS3.c')
-rw-r--r-- | src/Window_PS3.c | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/src/Window_PS3.c b/src/Window_PS3.c new file mode 100644 index 0000000..68d64e0 --- /dev/null +++ b/src/Window_PS3.c @@ -0,0 +1,394 @@ +#include "Core.h" +#if defined CC_BUILD_PS3 +#include "Window.h" +#include "Platform.h" +#include "Input.h" +#include "Event.h" +#include "Graphics.h" +#include "String.h" +#include "Funcs.h" +#include "Bitmap.h" +#include "Errors.h" +#include "ExtMath.h" +#include "Logger.h" +#include "VirtualKeyboard.h" +#include <io/pad.h> +#include <io/kb.h> +#include <sysutil/sysutil.h> +#include <sysutil/video.h> + +static cc_bool launcherMode; +static padInfo pad_info; +static padData pad_data; +static KbInfo kb_info; +static KbData kb_data; +static KbConfig kb_config; + +struct _DisplayData DisplayInfo; +struct _WindowData WindowInfo; + +static void sysutil_callback(u64 status, u64 param, void* usrdata) { + switch (status) { + case SYSUTIL_EXIT_GAME: + Window_Main.Exists = false; + Window_RequestClose(); + break; + } +} + +void Window_PreInit(void) { + sysUtilRegisterCallback(0, sysutil_callback, NULL); +} + +void Window_Init(void) { + videoState state; + videoResolution resolution; + + videoGetState(0, 0, &state); + videoGetResolution(state.displayMode.resolution, &resolution); + + DisplayInfo.Width = resolution.width; + DisplayInfo.Height = resolution.height; + DisplayInfo.ScaleX = 1; + DisplayInfo.ScaleY = 1; + + Window_Main.Width = resolution.width; + Window_Main.Height = resolution.height; + Window_Main.Focused = true; + Window_Main.Exists = true; + + Input.Sources = INPUT_SOURCE_GAMEPAD; + DisplayInfo.ContentOffsetX = 20; + DisplayInfo.ContentOffsetY = 20; + + ioPadInit(MAX_PORT_NUM); + ioKbInit(MAX_KB_PORT_NUM); + ioKbSetCodeType(0, KB_CODETYPE_RAW); + ioKbGetConfiguration(0, &kb_config); +} + +void Window_Free(void) { } + +void Window_Create2D(int width, int height) { + launcherMode = true; + Gfx_Create(); // launcher also uses RSX to draw +} + +void Window_Create3D(int width, int height) { + launcherMode = false; +} + +void Window_SetTitle(const cc_string* title) { } +void Clipboard_GetText(cc_string* value) { } // TODO sceClipboardGetText +void Clipboard_SetText(const cc_string* value) { } // TODO sceClipboardSetText + +int Window_GetWindowState(void) { return WINDOW_STATE_FULLSCREEN; } +cc_result Window_EnterFullscreen(void) { return 0; } +cc_result Window_ExitFullscreen(void) { return 0; } +int Window_IsObscured(void) { return 0; } + +void Window_Show(void) { } +void Window_SetSize(int width, int height) { } + +void Window_RequestClose(void) { + Event_RaiseVoid(&WindowEvents.Closing); +} + + +/*########################################################################################################################* +*--------------------------------------------------Keyboard processing----------------------------------------------------* +*#########################################################################################################################*/ +#define MAX_KEYCODE_MAPPINGS 148 +static char now_pressed[MAX_KEYCODE_MAPPINGS], was_pressed[MAX_KEYCODE_MAPPINGS]; +static int MapKey(int k) { + if (k >= KB_RAWKEY_A && k <= KB_RAWKEY_Z) return 'A' + (k - KB_RAWKEY_A); + if (k >= KB_RAWKEY_1 && k <= KB_RAWKEY_9) return '1' + (k - KB_RAWKEY_1); + if (k >= KB_RAWKEY_F1 && k <= KB_RAWKEY_F12) return CCKEY_F1 + (k - KB_RAWKEY_F1); + if (k >= KB_RAWKEY_KPAD_1 && k <= KB_RAWKEY_KPAD_9) return CCKEY_KP1 + (k - KB_RAWKEY_KPAD_1); + switch (k) { + case KB_RAWKEY_PRINTSCREEN: return CCKEY_PRINTSCREEN; + case KB_RAWKEY_SCROLL_LOCK: return CCKEY_SCROLLLOCK; + case KB_RAWKEY_PAUSE: return CCKEY_PAUSE; + case KB_RAWKEY_INSERT: return CCKEY_INSERT; + case KB_RAWKEY_HOME: return CCKEY_HOME; + case KB_RAWKEY_PAGE_UP: return CCKEY_PAGEUP; + case KB_RAWKEY_DELETE: return CCKEY_DELETE; + case KB_RAWKEY_END: return CCKEY_END; + case KB_RAWKEY_PAGE_DOWN: return CCKEY_PAGEDOWN; + case KB_RAWKEY_RIGHT_ARROW: return CCKEY_RIGHT; + case KB_RAWKEY_LEFT_ARROW: return CCKEY_LEFT; + case KB_RAWKEY_DOWN_ARROW: return CCKEY_DOWN; + case KB_RAWKEY_UP_ARROW: return CCKEY_UP; + case KB_RAWKEY_0: return '0'; + case KB_RAWKEY_ENTER: return CCKEY_ENTER; + case KB_RAWKEY_ESCAPE: return CCKEY_ESCAPE; + case KB_RAWKEY_BS: return CCKEY_BACKSPACE; + case KB_RAWKEY_TAB: return CCKEY_TAB; + case KB_RAWKEY_SPACE: return CCKEY_SPACE; + case KB_RAWKEY_MINUS: return CCKEY_MINUS; + case KB_RAWKEY_EQUAL_101: return CCKEY_EQUALS; + //case KB_RAWKEY_ACCENT_CIRCONFLEX_106: return CCKEY_TILDE; + //case KB_RAWKEY_LEFT_BRACKET_101: return CCKEY_LBRACKET; + //case KB_RAWKEY_ATMARK_106 + //case KB_RAWKEY_RIGHT_BRACKET_101: return CCKEY_RBRACKET; + case KB_RAWKEY_LEFT_BRACKET_106: return CCKEY_LBRACKET; + case KB_RAWKEY_BACKSLASH_101: return CCKEY_BACKSLASH; + case KB_RAWKEY_RIGHT_BRACKET_106: return CCKEY_RBRACKET; + case KB_RAWKEY_SEMICOLON: return CCKEY_SEMICOLON; + case KB_RAWKEY_QUOTATION_101: return CCKEY_QUOTE; + //case KB_RAWKEY_COLON_106: return CCKEY_SEMICOLON; + case KB_RAWKEY_COMMA: return CCKEY_COMMA; + case KB_RAWKEY_PERIOD: return CCKEY_PERIOD; + case KB_RAWKEY_SLASH: return CCKEY_SLASH; + case KB_RAWKEY_CAPS_LOCK: return CCKEY_CAPSLOCK; + + case KB_RAWKEY_KPAD_NUMLOCK: return CCKEY_NUMLOCK; + case KB_RAWKEY_KPAD_SLASH: return CCKEY_KP_DIVIDE; + case KB_RAWKEY_KPAD_ASTERISK: return CCKEY_KP_MULTIPLY; + case KB_RAWKEY_KPAD_MINUS: return CCKEY_KP_MINUS; + case KB_RAWKEY_KPAD_PLUS: return CCKEY_KP_PLUS; + case KB_RAWKEY_KPAD_ENTER: return CCKEY_KP_ENTER; + case KB_RAWKEY_KPAD_0: return CCKEY_KP0; + case KB_RAWKEY_KPAD_PERIOD: return CCKEY_KP_DECIMAL; + case KB_RAWKEY_BACKSLASH_106: return CCKEY_BACKSLASH; + + case 147: return CCKEY_TILDE; + } + return 0; +} +static cc_bool kb_deferredClear; +static void ProcessKBButtons(void) { + // PS3 keyboard APIs only seem to return current keys pressed, + // which is a massive pain to work with + // + // The API is really strange and when pressing two keys produces e.g. + // - Event 1) pressed 82 + // - Event 2) pressed 46 + // instead of + // - Event 1) pressed 82 + // - Event 2) pressed 82 46 + // + // Additionally on real hardware, the following events when observed + // - Releasing key: [key] [0] + // - Holding key: [key] [0] [key] [0] [key] [0] + // I don't really know why this happens, so try to detect this by + // deferring resetting all keys to next Window_ProcessEvents + // TODO properly investigate this + + if (kb_deferredClear && (kb_data.nb_keycode == 0 || kb_data.keycode[0] == 0)) { + Mem_Set(now_pressed, 0, sizeof(now_pressed)); + kb_deferredClear = false; + } else { + kb_deferredClear = false; + if (!kb_data.nb_keycode) return; + } + + // possibly unpress all keys next time around + if (kb_data.keycode[0] == 0) kb_deferredClear = true; + + for (int i = 0; i < kb_data.nb_keycode; i++) + { + int rawcode = kb_data.keycode[i]; + if (rawcode > 0 && rawcode < MAX_KEYCODE_MAPPINGS) + now_pressed[rawcode] = true; + } + + for (int i = 0; i < MAX_KEYCODE_MAPPINGS; i++) + { + if (now_pressed[i] == was_pressed[i]) continue; + + int key = MapKey(i); + if (key) Input_SetNonRepeatable(key, now_pressed[i]); + //if (key) Platform_Log3("UPDATE %h: %c = %t", &i, Input_DisplayNames[key], &now_pressed[i]); + } + + Mem_Copy(was_pressed, now_pressed, sizeof(now_pressed)); +} + +static KbMkey old_mods; +#define ToggleMod(field, btn) if (diff._KbMkeyU._KbMkeyS. field) Input_Set(btn, mods->_KbMkeyU._KbMkeyS. field); + +static void ProcessKBModifiers(KbMkey* mods) { + KbMkey diff; + diff._KbMkeyU.mkeys = mods->_KbMkeyU.mkeys ^ old_mods._KbMkeyU.mkeys; + + ToggleMod(l_alt, CCKEY_LALT); + ToggleMod(r_alt, CCKEY_RALT); + ToggleMod(l_ctrl, CCKEY_LCTRL); + ToggleMod(r_ctrl, CCKEY_RCTRL); + ToggleMod(l_shift, CCKEY_LSHIFT); + ToggleMod(r_shift, CCKEY_RSHIFT); + ToggleMod(l_win, CCKEY_LWIN); + ToggleMod(r_win, CCKEY_RWIN); + + old_mods = *mods; +} + +static void ProcessKBTextInput(void) { + for (int i = 0; i < kb_data.nb_keycode; i++) + { + int rawcode = kb_data.keycode[i]; + if (!rawcode) continue; + int unicode = ioKbCnvRawCode(kb_config.mapping, kb_data.mkey, kb_data.led, rawcode); + + if (unicode && unicode <= 0xFF) + Event_RaiseInt(&InputEvents.Press, (cc_unichar)unicode); + + //char C = unicode; + //Platform_Log4("%i --> %i / %h / %r", &rawcode, &unicode, &unicode, &C); + } +} + +static void ProcessKBInput(void) { + int res = ioKbRead(0, &kb_data); + Input.Sources |= INPUT_SOURCE_NORMAL; + + if (res == 0 && kb_data.nb_keycode > 0) { + ProcessKBButtons(); + ProcessKBModifiers(&kb_data.mkey); + ProcessKBTextInput(); + } +} + + +/*########################################################################################################################* +*----------------------------------------------------Input processing-----------------------------------------------------* +*#########################################################################################################################*/ +void Window_ProcessEvents(float delta) { + ioKbGetInfo(&kb_info); + if (kb_info.status[0]) ProcessKBInput(); +} + +void Cursor_SetPosition(int x, int y) { } // Makes no sense for PS Vita + +void Window_EnableRawMouse(void) { Input.RawMode = true; } +void Window_UpdateRawMouse(void) { } +void Window_DisableRawMouse(void) { Input.RawMode = false; } + + +/*########################################################################################################################* +*-------------------------------------------------------Gamepads----------------------------------------------------------* +*#########################################################################################################################*/ +static void HandleButtons(int port, padData* data) { + //Platform_Log2("BUTTONS: %h (%h)", &data->button[2], &data->button[0]); + Gamepad_SetButton(port, CCPAD_A, data->BTN_TRIANGLE); + Gamepad_SetButton(port, CCPAD_B, data->BTN_SQUARE); + Gamepad_SetButton(port, CCPAD_X, data->BTN_CROSS); + Gamepad_SetButton(port, CCPAD_Y, data->BTN_CIRCLE); + + Gamepad_SetButton(port, CCPAD_START, data->BTN_START); + Gamepad_SetButton(port, CCPAD_SELECT, data->BTN_SELECT); + Gamepad_SetButton(port, CCPAD_LSTICK, data->BTN_L3); + Gamepad_SetButton(port, CCPAD_RSTICK, data->BTN_R3); + + Gamepad_SetButton(port, CCPAD_LEFT, data->BTN_LEFT); + Gamepad_SetButton(port, CCPAD_RIGHT, data->BTN_RIGHT); + Gamepad_SetButton(port, CCPAD_UP, data->BTN_UP); + Gamepad_SetButton(port, CCPAD_DOWN, data->BTN_DOWN); + + Gamepad_SetButton(port, CCPAD_L, data->BTN_L1); + Gamepad_SetButton(port, CCPAD_R, data->BTN_R1); + Gamepad_SetButton(port, CCPAD_ZL, data->BTN_L2); + Gamepad_SetButton(port, CCPAD_ZR, data->BTN_R2); +} + +#define AXIS_SCALE 32.0f +static void HandleJoystick(int port, int axis, int x, int y, float delta) { + if (Math_AbsI(x) <= 32) x = 0; + if (Math_AbsI(y) <= 32) y = 0; + + Gamepad_SetAxis(port, axis, x / AXIS_SCALE, y / AXIS_SCALE, delta); +} + +static void ProcessPadInput(int port, float delta, padData* pad) { + HandleButtons(port, pad); + HandleJoystick(port, PAD_AXIS_LEFT, pad->ANA_L_H - 0x80, pad->ANA_L_V - 0x80, delta); + HandleJoystick(port, PAD_AXIS_RIGHT, pad->ANA_R_H - 0x80, pad->ANA_R_V - 0x80, delta); +} + +void Window_ProcessGamepads(float delta) { + ioPadGetInfo(&pad_info); + for (int port = 0; port < INPUT_MAX_GAMEPADS; port++) + { + if (!pad_info.status[port]) continue; + + ioPadGetData(port, &pad_data); + ProcessPadInput(port, delta, &pad_data); + } +} + + +/*########################################################################################################################* +*------------------------------------------------------Framebuffer--------------------------------------------------------* +*#########################################################################################################################*/ +static u32 fb_offset; + +extern u32* Gfx_AllocImage(u32* offset, s32 w, s32 h); +extern void Gfx_TransferImage(u32 offset, s32 w, s32 h); + +void Window_AllocFramebuffer(struct Bitmap* bmp, int width, int height) { + u32* pixels = Gfx_AllocImage(&fb_offset, width, height); + bmp->scan0 = pixels; + bmp->width = width; + bmp->height = height; + + Gfx_ClearColor(PackedCol_Make(0x40, 0x60, 0x80, 0xFF)); +} + +void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) { + // TODO test + Gfx_BeginFrame(); + Gfx_ClearBuffers(GFX_BUFFER_COLOR | GFX_BUFFER_DEPTH); + // TODO: Only transfer dirty region instead of the entire bitmap + Gfx_TransferImage(fb_offset, bmp->width, bmp->height); + Gfx_EndFrame(); +} + +void Window_FreeFramebuffer(struct Bitmap* bmp) { + //Mem_Free(bmp->scan0); + /* TODO free framebuffer */ +} + + +/*########################################################################################################################* +*------------------------------------------------------Soft keyboard------------------------------------------------------* +*#########################################################################################################################*/ +void OnscreenKeyboard_Open(struct OpenKeyboardArgs* args) { + if (Input.Sources & INPUT_SOURCE_NORMAL) return; + VirtualKeyboard_Open(args, launcherMode); +} + +void OnscreenKeyboard_SetText(const cc_string* text) { + VirtualKeyboard_SetText(text); +} + +void OnscreenKeyboard_Draw2D(Rect2D* r, struct Bitmap* bmp) { + VirtualKeyboard_Display2D(r, bmp); +} + +void OnscreenKeyboard_Draw3D(void) { + VirtualKeyboard_Display3D(); +} + +void OnscreenKeyboard_Close(void) { + VirtualKeyboard_Close(); +} + + +/*########################################################################################################################* +*-------------------------------------------------------Misc/Other--------------------------------------------------------* +*#########################################################################################################################*/ +void Window_ShowDialog(const char* title, const char* msg) { + /* TODO implement */ + Platform_LogConst(title); + Platform_LogConst(msg); +} + +cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) { + return ERR_NOT_SUPPORTED; +} + +cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* args) { + return ERR_NOT_SUPPORTED; +} +#endif |