ref: 6d53668beda9b8e88ee6c74230e1e70a2cc0061b
parent: bcbb06f092ff9a2c5441de91d60de1cc81e4d036
author: Clownacy <[email protected]>
date: Mon Apr 13 20:31:13 EDT 2020
Add Wii U platform backend With this backend, CSE2 can run on the Wii U. It's not ideal - it doesn't have its own renderer yet, so it just uses the software renderer, and it only displays on the gamepad, because drawing to the TV as well makes the game lag. Also there's no sound. Also the lack of input rebinding is annoying.
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,7 +19,7 @@
set(BACKEND_RENDERER "SDLTexture" CACHE STRING "Which renderer the game should use: 'OpenGL3' for an OpenGL 3.2 renderer, 'OpenGLES2' for an OpenGL ES 2.0 renderer, 'SDLTexture' for SDL2's hardware-accelerated Texture API, 'SDLSurface' for SDL2's software-rendered Surface API, or 'Software' for a handwritten software renderer")
set(BACKEND_AUDIO "SDL2" CACHE STRING "Which audio backend the game should use: 'SDL2', 'miniaudio', or 'Null'")
-set(BACKEND_PLATFORM "SDL2" CACHE STRING "Which platform backend the game should use: 'SDL2', 'GLFW3', or 'Null'")
+set(BACKEND_PLATFORM "SDL2" CACHE STRING "Which platform backend the game should use: 'SDL2', 'GLFW3', 'WiiU', or 'Null'")
option(LTO "Enable link-time optimisation" OFF)
option(PKG_CONFIG_STATIC_LIBS "On platforms with pkg-config, static-link the dependencies (good for Windows builds, so you don't need to bundle DLL files)" OFF)
@@ -351,6 +351,11 @@
"src/Backends/GLFW3/Misc.cpp"
"src/Backends/GLFW3/Window.h"
)
+elseif(BACKEND_PLATFORM MATCHES "WiiU")
+ target_sources(CSE2 PRIVATE
+ "src/Backends/WiiU/Controller.cpp"
+ "src/Backends/WiiU/Misc.cpp"
+ )
elseif(BACKEND_PLATFORM MATCHES "Null")
target_sources(CSE2 PRIVATE
"src/Backends/Null/Controller.cpp"
@@ -372,6 +377,8 @@
target_sources(CSE2 PRIVATE "src/Backends/GLFW3/Window-OpenGLES2.cpp")
elseif(BACKEND_PLATFORM MATCHES "GLFW3" AND BACKEND_RENDERER MATCHES "Software")
target_sources(CSE2 PRIVATE "src/Backends/GLFW3/Window-Software.cpp")
+elseif(BACKEND_PLATFORM MATCHES "WiiU" AND BACKEND_RENDERER MATCHES "Software")
+ target_sources(CSE2 PRIVATE "src/Backends/WiiU/Window-Software.cpp")
elseif(BACKEND_PLATFORM MATCHES "Null" AND BACKEND_RENDERER MATCHES "Software")
target_sources(CSE2 PRIVATE "src/Backends/Null/Window-Software.cpp")
else()
--- /dev/null
+++ b/src/Backends/WiiU/Controller.cpp
@@ -1,0 +1,77 @@
+#include "../Controller.h"
+
+#include <vpad/input.h>
+
+#define DEADZONE (10000.0f / 32767.0f)
+
+bool ControllerBackend_Init(void)
+{
+ VPADInit();
+
+ return true;
+}
+
+void ControllerBackend_Deinit(void)
+{
+ VPADShutdown();
+}
+
+bool ControllerBackend_GetJoystickStatus(bool **buttons, unsigned int *button_count, short **axes, unsigned int *axis_count)
+{
+ VPADReadError vpad_error;
+ VPADStatus vpad_status;
+ VPADRead(VPAD_CHAN_0, &vpad_status, 1, &vpad_error);
+
+ static bool button_buffer[27];
+ static short axis_buffer[4];
+
+ *button_count = sizeof(button_buffer) / sizeof(button_buffer[0]);
+ *axis_count = sizeof(axis_buffer) / sizeof(axis_buffer[0]);
+
+ //////////////////////////
+ // Handle button inputs //
+ //////////////////////////
+
+ button_buffer[0] = vpad_status.hold & VPAD_BUTTON_Y; // Shoot
+ button_buffer[1] = vpad_status.hold & VPAD_BUTTON_B; // Jump
+ button_buffer[2] = vpad_status.hold & VPAD_BUTTON_X; // Map
+ button_buffer[3] = vpad_status.hold & VPAD_BUTTON_L; // Weapon left
+ button_buffer[4] = vpad_status.hold & VPAD_BUTTON_R; // Weapon right
+ button_buffer[5] = vpad_status.hold & VPAD_BUTTON_A; // Inventory
+ button_buffer[6] = vpad_status.hold & VPAD_BUTTON_ZL; // Weapon left
+ button_buffer[7] = vpad_status.hold & VPAD_BUTTON_ZR; // Weapon right
+ button_buffer[8] = vpad_status.hold & VPAD_BUTTON_LEFT;
+ button_buffer[9] = vpad_status.hold & VPAD_BUTTON_RIGHT;
+ button_buffer[10] = vpad_status.hold & VPAD_BUTTON_UP;
+ button_buffer[11] = vpad_status.hold & VPAD_BUTTON_DOWN;
+ button_buffer[12] = vpad_status.hold & VPAD_BUTTON_PLUS;
+ button_buffer[13] = vpad_status.hold & VPAD_BUTTON_MINUS;
+ button_buffer[14] = vpad_status.hold & VPAD_BUTTON_HOME;
+ button_buffer[15] = vpad_status.hold & VPAD_BUTTON_SYNC;
+ button_buffer[16] = vpad_status.hold & VPAD_BUTTON_STICK_R;
+ button_buffer[17] = vpad_status.hold & VPAD_BUTTON_STICK_L;
+ button_buffer[18] = vpad_status.hold & VPAD_BUTTON_TV;
+ button_buffer[19] = vpad_status.hold & VPAD_STICK_R_EMULATION_LEFT;
+ button_buffer[20] = vpad_status.hold & VPAD_STICK_R_EMULATION_RIGHT;
+ button_buffer[21] = vpad_status.hold & VPAD_STICK_R_EMULATION_UP;
+ button_buffer[22] = vpad_status.hold & VPAD_STICK_R_EMULATION_DOWN;
+ button_buffer[23] = vpad_status.hold & VPAD_STICK_L_EMULATION_LEFT;
+ button_buffer[24] = vpad_status.hold & VPAD_STICK_L_EMULATION_RIGHT;
+ button_buffer[25] = vpad_status.hold & VPAD_STICK_L_EMULATION_UP;
+ button_buffer[26] = vpad_status.hold & VPAD_STICK_L_EMULATION_DOWN;
+
+ *buttons = button_buffer;
+
+ ////////////////////////
+ // Handle axis inputs //
+ ////////////////////////
+
+ axis_buffer[0] = (short)(vpad_status.leftStick.x * 0x7FFF);
+ axis_buffer[1] = (short)(vpad_status.leftStick.y * -0x7FFF);
+ axis_buffer[2] = (short)(vpad_status.rightStick.x * 0x7FFF);
+ axis_buffer[3] = (short)(vpad_status.rightStick.y * -0x7FFF);
+
+ *axes = axis_buffer;
+
+ return true;
+}
--- /dev/null
+++ b/src/Backends/WiiU/Misc.cpp
@@ -1,0 +1,114 @@
+#include "../Misc.h"
+
+#include <string.h>
+
+#include <coreinit/thread.h>
+
+#include <whb/proc.h>
+#include <whb/sdcard.h>
+
+static unsigned long tick_delta;
+
+bool Backend_Init(void)
+{
+ WHBProcInit();
+
+ if (!WHBMountSdCard())
+ return FALSE;
+
+ tick_delta = OSGetSystemInfo()->busClockSpeed / 4;
+
+ return true;
+}
+
+void Backend_Deinit(void)
+{
+ WHBUnmountSdCard();
+
+ WHBProcShutdown();
+}
+
+void Backend_PostWindowCreation(void)
+{
+
+}
+
+bool Backend_GetBasePath(char *string_buffer)
+{
+ strcpy(string_buffer, WHBGetSdCardMountPath());
+ strcat(string_buffer, "/CSE2");
+
+ return true;
+}
+
+void Backend_HideMouse(void)
+{
+
+}
+
+void Backend_SetWindowIcon(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
+{
+ (void)rgb_pixels;
+ (void)width;
+ (void)height;
+}
+
+void Backend_SetCursor(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
+{
+ (void)rgb_pixels;
+ (void)width;
+ (void)height;
+}
+
+void PlaybackBackend_EnableDragAndDrop(void)
+{
+
+}
+
+bool Backend_SystemTask(bool active)
+{
+ (void)active;
+
+ return WHBProcIsRunning();
+}
+
+void Backend_GetKeyboardState(bool *keyboard_state)
+{
+ memset(keyboard_state, 0, sizeof(bool) * BACKEND_KEYBOARD_TOTAL);
+}
+
+void Backend_ShowMessageBox(const char *title, const char *message)
+{
+ (void)title;
+ (void)message;
+}
+
+ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintError(const char *format, ...)
+{
+ (void)format;
+}
+
+ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintInfo(const char *format, ...)
+{
+ (void)format;
+}
+
+unsigned long Backend_GetTicks(void)
+{
+ static uint64_t accumulator;
+
+ static unsigned long last_tick;
+
+ unsigned long current_tick = OSGetTick();
+
+ accumulator += current_tick - last_tick;
+
+ last_tick = current_tick;
+
+ return (accumulator * 1000) / tick_delta;
+}
+
+void Backend_Delay(unsigned int ticks)
+{
+ OSSleepTicks((ticks * tick_delta) / 1000);
+}
--- /dev/null
+++ b/src/Backends/WiiU/Window-Software.cpp
@@ -1,0 +1,107 @@
+#include "../Window-Software.h"
+
+#include <stdlib.h>
+
+#include <coreinit/cache.h>
+#include <coreinit/screen.h>
+
+static unsigned char *fake_framebuffer;
+
+//static unsigned char *tv_framebuffer;
+static unsigned char *drc_framebuffer;
+
+static size_t framebuffer_width;
+static size_t framebuffer_height;
+
+//static uint32_t tv_buffer_size;
+static uint32_t drc_buffer_size;
+
+unsigned char* WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, bool fullscreen, size_t *pitch)
+{
+ (void)window_title;
+ (void)fullscreen;
+
+ framebuffer_width = screen_width;
+ framebuffer_height = screen_height;
+
+ OSScreenInit();
+
+ OSScreenEnableEx(SCREEN_TV, FALSE);
+ OSScreenEnableEx(SCREEN_DRC, TRUE);
+
+// tv_buffer_size = OSScreenGetBufferSizeEx(SCREEN_TV);
+ drc_buffer_size = OSScreenGetBufferSizeEx(SCREEN_DRC);
+
+// tv_framebuffer = (unsigned char*)aligned_alloc(0x100, tv_buffer_size); // C11 fun
+ drc_framebuffer = (unsigned char*)aligned_alloc(0x100, drc_buffer_size); // C11 fun
+
+// OSScreenSetBufferEx(SCREEN_TV, tv_framebuffer);
+ OSScreenSetBufferEx(SCREEN_DRC, drc_framebuffer);
+
+ fake_framebuffer = (unsigned char*)malloc(screen_width * screen_height * 3);
+
+ *pitch = screen_width * 3;
+
+ return fake_framebuffer;
+}
+
+void WindowBackend_Software_DestroyWindow(void)
+{
+ free(fake_framebuffer);
+ free(drc_framebuffer);
+// free(tv_framebuffer);
+ OSScreenShutdown();
+}
+
+void WindowBackend_Software_Display(void)
+{
+ const size_t line_size = (drc_buffer_size / 480) / 2;
+
+ static bool flipflop;
+
+ unsigned char *in_pointer = fake_framebuffer;
+
+ for (size_t y = 0; y < framebuffer_height; ++y)
+ {
+ unsigned char *out_pointer = &drc_framebuffer[line_size * y];
+
+ if (!flipflop)
+ out_pointer += drc_buffer_size / 2;
+
+ out_pointer += ((854 - framebuffer_width) * 4) / 2;
+
+ for (size_t x = 0; x < framebuffer_width; ++x)
+ {
+ *out_pointer++ = *in_pointer++;
+ *out_pointer++ = *in_pointer++;
+ *out_pointer++ = *in_pointer++;
+ *out_pointer++ = 0;
+/* uint32_t colour = 0;
+ colour |= *in_pointer++ << 24;
+ colour |= *in_pointer++ << 16;
+ colour |= *in_pointer++ << 8;
+ OSScreenPutPixelEx(SCREEN_DRC, x, y, colour);
+ */ }
+ }
+
+ flipflop = !flipflop;
+
+// static unsigned char accumulator = 0;
+
+// accumulator += 0x10;
+
+// for (size_t i = 0; i < buffer_size; ++i)
+// real_framebuffer[i] = accumulator;
+
+// DCFlushRange(tv_framebuffer, tv_buffer_size);
+// DCFlushRange(drc_framebuffer, drc_buffer_size);
+
+// OSScreenFlipBuffersEx(SCREEN_TV);
+ OSScreenFlipBuffersEx(SCREEN_DRC);
+}
+
+void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height)
+{
+ (void)width;
+ (void)height;
+}