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_PS2.c |
initial commit
Diffstat (limited to 'src/Window_PS2.c')
-rw-r--r-- | src/Window_PS2.c | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/src/Window_PS2.c b/src/Window_PS2.c new file mode 100644 index 0000000..3e626d5 --- /dev/null +++ b/src/Window_PS2.c @@ -0,0 +1,301 @@ +#include "Core.h" +#if defined CC_BUILD_PS2 +#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 <libpad.h> +#include <packet.h> +#include <dma_tags.h> +#include <gif_tags.h> +#include <gs_psm.h> +#include <dma.h> +#include <graph.h> +#include <draw.h> +#include <kernel.h> +#include <libmouse.h> + +static cc_bool launcherMode, mouseSupported; +static char padBuf0[256] __attribute__((aligned(64))); +static char padBuf1[256] __attribute__((aligned(64))); + +struct _DisplayData DisplayInfo; +struct _WindowData WindowInfo; +framebuffer_t fb_colors[2]; +zbuffer_t fb_depth; + +void Window_PreInit(void) { + dma_channel_initialize(DMA_CHANNEL_GIF, NULL, 0); + dma_channel_fast_waits(DMA_CHANNEL_GIF); +} + +void Window_Init(void) { + DisplayInfo.Width = 640; + DisplayInfo.Height = graph_get_region() == GRAPH_MODE_PAL ? 512 : 448; + DisplayInfo.ScaleX = 1; + DisplayInfo.ScaleY = 1; + + Window_Main.Width = DisplayInfo.Width; + Window_Main.Height = DisplayInfo.Height; + Window_Main.Focused = true; + Window_Main.Exists = true; + + Input.Sources = INPUT_SOURCE_GAMEPAD; + DisplayInfo.ContentOffsetX = 10; + DisplayInfo.ContentOffsetY = 10; + + padInit(0); + padPortOpen(0, 0, padBuf0); + padPortOpen(1, 0, padBuf1); + + if (PS2MouseInit() >= 0) { + PS2MouseSetReadMode(PS2MOUSE_READMODE_DIFF); + mouseSupported = true; + } +} + +void Window_Free(void) { } + +static void ResetGfxState(void) { + graph_shutdown(); + graph_vram_clear(); + + fb_colors[0].width = DisplayInfo.Width; + fb_colors[0].height = DisplayInfo.Height; + fb_colors[0].mask = 0; + fb_colors[0].psm = GS_PSM_32; + fb_colors[0].address = graph_vram_allocate(fb_colors[0].width, fb_colors[0].height, fb_colors[1].psm, GRAPH_ALIGN_PAGE); + + fb_colors[1].width = DisplayInfo.Width; + fb_colors[1].height = DisplayInfo.Height; + fb_colors[1].mask = 0; + fb_colors[1].psm = GS_PSM_32; + fb_colors[1].address = graph_vram_allocate(fb_colors[1].width, fb_colors[1].height, fb_colors[1].psm, GRAPH_ALIGN_PAGE); + + fb_depth.enable = 1; + fb_depth.method = ZTEST_METHOD_ALLPASS; + fb_depth.mask = 0; + fb_depth.zsm = GS_ZBUF_32; + fb_depth.address = graph_vram_allocate(fb_colors[0].width, fb_colors[0].height, fb_depth.zsm, GRAPH_ALIGN_PAGE); + + graph_initialize(fb_colors[1].address, fb_colors[1].width, fb_colors[1].height, fb_colors[1].psm, 0, 0); +} + +void Window_Create2D(int width, int height) { + ResetGfxState(); + launcherMode = true; +} + +void Window_Create3D(int width, int height) { + ResetGfxState(); + launcherMode = false; +} + +void Window_SetTitle(const cc_string* title) { } +void Clipboard_GetText(cc_string* value) { } +void Clipboard_SetText(const cc_string* value) { } + +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); +} + + +/*########################################################################################################################* +*----------------------------------------------------Input processing-----------------------------------------------------* +*#########################################################################################################################*/ +static void ProcessMouseInput(float delta) { + if (!mouseSupported) return; + if (PS2MouseEnum() == 0) return; + + mouse_data mData = { 0 }; + if (PS2MouseRead(&mData) < 0) return; + + Input_SetNonRepeatable(CCMOUSE_L, mData.buttons & PS2MOUSE_BTN1); + Input_SetNonRepeatable(CCMOUSE_R, mData.buttons & PS2MOUSE_BTN2); + Input_SetNonRepeatable(CCMOUSE_M, mData.buttons & PS2MOUSE_BTN3); + Mouse_ScrollVWheel(mData.wheel); + + if (!Input.RawMode) return; + float scale = (delta * 60.0) / 2.0f; + Event_RaiseRawMove(&PointerEvents.RawMoved, + mData.x * scale, mData.y * scale); +} + +void Window_ProcessEvents(float delta) { + ProcessMouseInput(delta); +} + +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, int buttons) { + // Confusingly, it seems that when a bit is on, it means the button is NOT pressed + // So just flip the bits to make more sense + buttons = buttons ^ 0xFFFF; + //Platform_Log1("BUTTONS: %h", &buttons); + + Gamepad_SetButton(port, CCPAD_A, buttons & PAD_TRIANGLE); + Gamepad_SetButton(port, CCPAD_B, buttons & PAD_SQUARE); + Gamepad_SetButton(port, CCPAD_X, buttons & PAD_CROSS); + Gamepad_SetButton(port, CCPAD_Y, buttons & PAD_CIRCLE); + + Gamepad_SetButton(port, CCPAD_START, buttons & PAD_START); + Gamepad_SetButton(port, CCPAD_SELECT, buttons & PAD_SELECT); + Gamepad_SetButton(port, CCPAD_LSTICK, buttons & PAD_L3); + Gamepad_SetButton(port, CCPAD_RSTICK, buttons & PAD_L3); + + Gamepad_SetButton(port, CCPAD_LEFT, buttons & PAD_LEFT); + Gamepad_SetButton(port, CCPAD_RIGHT, buttons & PAD_RIGHT); + Gamepad_SetButton(port, CCPAD_UP, buttons & PAD_UP); + Gamepad_SetButton(port, CCPAD_DOWN, buttons & PAD_DOWN); + + Gamepad_SetButton(port, CCPAD_L, buttons & PAD_L1); + Gamepad_SetButton(port, CCPAD_R, buttons & PAD_R1); + Gamepad_SetButton(port, CCPAD_ZL, buttons & PAD_L2); + Gamepad_SetButton(port, CCPAD_ZR, buttons & PAD_R2); +} + +#define AXIS_SCALE 16.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, struct padButtonStatus* pad) { + HandleButtons(port, pad->btns); + HandleJoystick(port, PAD_AXIS_LEFT, pad->ljoy_h - 0x80, pad->ljoy_v - 0x80, delta); + HandleJoystick(port, PAD_AXIS_RIGHT, pad->rjoy_h - 0x80, pad->rjoy_v - 0x80, delta); +} + +static cc_bool setMode[INPUT_MAX_GAMEPADS]; +static void ProcessPad(int port, float delta) { + struct padButtonStatus pad; + int state = padGetState(port, 0); + if (state != PAD_STATE_STABLE) return; + + // Change to DUALSHOCK mode so analog joysticks return values + if (!setMode[port]) { + padSetMainMode(port, 0, PAD_MMODE_DUALSHOCK, PAD_MMODE_LOCK); + setMode[port] = true; + } + + int ret = padRead(port, 0, &pad); + if (ret != 0) ProcessPadInput(port, delta, &pad); +} + +void Window_ProcessGamepads(float delta) { + ProcessPad(0, delta); + ProcessPad(1, delta); +} + + +/*########################################################################################################################* +*------------------------------------------------------Framebuffer--------------------------------------------------------* +*#########################################################################################################################*/ +void Window_AllocFramebuffer(struct Bitmap* bmp, int width, int height) { + bmp->scan0 = (BitmapCol*)Mem_Alloc(width * height, 4, "window pixels"); + bmp->width = width; + bmp->height = height; + + packet_t* packet = packet_init(100, PACKET_NORMAL); + qword_t* q = packet->data; + + q = draw_setup_environment(q, 0, &fb_colors[1], &fb_depth); + q = draw_clear(q, 0, 0, 0, + fb_colors[1].width, fb_colors[1].height, 170, 170, 170); + q = draw_finish(q); + + dma_channel_send_normal(DMA_CHANNEL_GIF, packet->data, q - packet->data, 0, 0); + dma_wait_fast(); + packet_free(packet); +} + +void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) { + // FlushCache bios call https://psi-rockin.github.io/ps2tek/ + // mode=0: Flush data cache (invalidate+writeback dirty contents to memory) + FlushCache(0); + + packet_t* packet = packet_init(200, PACKET_NORMAL); + qword_t* q = packet->data; + + q = draw_texture_transfer(q, bmp->scan0, bmp->width, bmp->height, GS_PSM_32, + fb_colors[1].address, fb_colors[1].width); + q = draw_texture_flush(q); + + dma_channel_send_chain(DMA_CHANNEL_GIF, packet->data, q - packet->data, 0, 0); + dma_wait_fast(); + packet_free(packet); +} + +void Window_FreeFramebuffer(struct Bitmap* bmp) { + Mem_Free(bmp->scan0); +} + + +/*########################################################################################################################* +*------------------------------------------------------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 |