diff --git a/.gitignore b/.gitignore index e78cff7f4..fe5b37da8 100644 --- a/.gitignore +++ b/.gitignore @@ -72,6 +72,10 @@ ClassiCube* screenshots fontscache.txt +# CMake files +CMakeFiles/ +CMakeCache.txt + #GCC object files *.o diff --git a/Makefile b/Makefile index 6211a11b9..497cd7e8d 100644 --- a/Makefile +++ b/Makefile @@ -138,6 +138,9 @@ vita: $(MAKE) -f misc/vita/Makefile PLAT=vita ps3: $(MAKE) -f misc/ps3/Makefile PLAT=ps3 +ps1: + cmake --preset default misc/ps1 + cmake --build misc/ps1/build ps2: $(MAKE) -f misc/ps2/Makefile PLAT=ps2 xbox: diff --git a/misc/ps1/CMakeLists.txt b/misc/ps1/CMakeLists.txt new file mode 100644 index 000000000..1f78b62a4 --- /dev/null +++ b/misc/ps1/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.21) + +project( + ClassiCube + LANGUAGES C ASM + VERSION 1.0.0 + DESCRIPTION "ClassiCube PS1 port" + HOMEPAGE_URL "https://classicube.net" +) + +add_definitions(-DPLAT_PS1) +file(GLOB _sources ../../src/*.c) + +psn00bsdk_add_executable(template GPREL ${_sources}) + +psn00bsdk_add_cd_image( + iso # Target name + template # Output file name (= template.bin + template.cue) + iso.xml # Path to config file + DEPENDS template system.cnf +) diff --git a/misc/ps1/CMakePresets.json b/misc/ps1/CMakePresets.json new file mode 100644 index 000000000..97d842820 --- /dev/null +++ b/misc/ps1/CMakePresets.json @@ -0,0 +1,26 @@ +{ + "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 21, + "patch": 0 + }, + "configurePresets": [ + { + "name": "default", + "displayName": "Default configuration", + "description": "Use this preset to build the project using PSn00bSDK.", + "generator": "Ninja", + "toolchainFile": "$env{PSN00BSDK_LIBS}/cmake/sdk.cmake", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "PSN00BSDK_TC": "", + "PSN00BSDK_TARGET": "mipsel-none-elf" + }, + "warnings": { + "dev": false + } + } + ] +} diff --git a/misc/ps1/iso.xml b/misc/ps1/iso.xml new file mode 100644 index 000000000..96ea23a8c --- /dev/null +++ b/misc/ps1/iso.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/misc/ps1/system.cnf b/misc/ps1/system.cnf new file mode 100644 index 000000000..e22172615 --- /dev/null +++ b/misc/ps1/system.cnf @@ -0,0 +1,4 @@ +BOOT=cdrom:\template.exe;1 +TCB=4 +EVENT=10 +STACK=801FFFF0 diff --git a/src/Core.h b/src/Core.h index 2474e51f5..d7fac6699 100644 --- a/src/Core.h +++ b/src/Core.h @@ -368,6 +368,14 @@ typedef cc_uint8 cc_bool; #define CC_BUILD_GLES #define CC_BUILD_EGL #undef CC_BUILD_FREETYPE +#elif defined PLAT_PS1 + #define CC_BUILD_PS1 + #define CC_BUILD_OPENAL + #define CC_BUILD_HTTPCLIENT + #define CC_BUILD_COOPTHREADED + #define CC_BUILD_LOWMEM + #define CC_BUILD_CONSOLE + #undef CC_BUILD_FREETYPE #endif #endif diff --git a/src/ExtMath.c b/src/ExtMath.c index 5081d706f..51f938677 100644 --- a/src/ExtMath.c +++ b/src/ExtMath.c @@ -4,8 +4,15 @@ /* For abs(x) function */ #include -#ifndef __GNUC__ +#if defined PLAT_PS1 +float Math_AbsF(float x) { return __builtin_fabsf(x); } +float Math_SqrtF(float x) { return 0; } /* TODO broken */ + +#elif defined __GNUC__ +/* Defined in .h using builtins */ +#else #include + float Math_AbsF(float x) { return fabsf(x); /* MSVC intrinsic */ } float Math_SqrtF(float x) { return sqrtf(x); /* MSVC intrinsic */ } #endif diff --git a/src/ExtMath.h b/src/ExtMath.h index a176d5551..4907a416f 100644 --- a/src/ExtMath.h +++ b/src/ExtMath.h @@ -14,7 +14,7 @@ #define Math_Deg2Packed(x) ((cc_uint8)((x) * 256.0f / 360.0f)) #define Math_Packed2Deg(x) ((x) * 360.0f / 256.0f) -#ifdef __GNUC__ +#if defined __GNUC__ && !defined CC_PLAT_PS1 /* fabsf/sqrtf are single intrinsic instructions in gcc/clang */ /* (sqrtf is only when -fno-math-errno though) */ #define Math_AbsF(x) __builtin_fabsf(x) diff --git a/src/Graphics_PS1.c b/src/Graphics_PS1.c new file mode 100644 index 000000000..d05b9837c --- /dev/null +++ b/src/Graphics_PS1.c @@ -0,0 +1,272 @@ +#include "Core.h" +#if defined CC_BUILD_PS1 +#include "_GraphicsBase.h" +#include "Errors.h" +#include "Window.h" + +void Gfx_RestoreState(void) { + InitDefaultResources(); +} + +void Gfx_FreeState(void) { + FreeDefaultResources(); +} + +void Gfx_Create(void) { + Gfx.MaxTexWidth = 128; + Gfx.MaxTexHeight = 128; + Gfx.Created = true; + + Gfx_RestoreState(); +} + +void Gfx_Free(void) { + Gfx_FreeState(); +} + + +/*########################################################################################################################* +*---------------------------------------------------------Textures--------------------------------------------------------* +*#########################################################################################################################*/ +static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) { + return NULL; +} + +void Gfx_BindTexture(GfxResourceID texId) { +} + +void Gfx_DeleteTexture(GfxResourceID* texId) { + GfxResourceID data = *texId; + if (data) Mem_Free(data); + *texId = NULL; +} + +void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps) { + // TODO +} + +void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, struct Bitmap* part, cc_bool mipmaps) { + // TODO +} + +void Gfx_EnableMipmaps(void) { } +void Gfx_DisableMipmaps(void) { } + + +/*########################################################################################################################* +*------------------------------------------------------State management---------------------------------------------------* +*#########################################################################################################################*/ +void Gfx_SetFog(cc_bool enabled) { } +void Gfx_SetFogCol(PackedCol col) { } +void Gfx_SetFogDensity(float value) { } +void Gfx_SetFogEnd(float value) { } +void Gfx_SetFogMode(FogFunc func) { } + +void Gfx_SetFaceCulling(cc_bool enabled) { + // TODO +} + +void Gfx_SetAlphaTest(cc_bool enabled) { +} + +void Gfx_SetAlphaBlending(cc_bool enabled) { +} + +void Gfx_SetAlphaArgBlend(cc_bool enabled) { } + +void Gfx_ClearBuffers(GfxBuffers buffers) { +} + +void Gfx_ClearColor(PackedCol color) { +} + +void Gfx_SetDepthTest(cc_bool enabled) { +} + +void Gfx_SetDepthWrite(cc_bool enabled) { + // TODO +} + +static void SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a) { + // TODO +} + +void Gfx_DepthOnlyRendering(cc_bool depthOnly) { + cc_bool enabled = !depthOnly; + SetColorWrite(enabled & gfx_colorMask[0], enabled & gfx_colorMask[1], + enabled & gfx_colorMask[2], enabled & gfx_colorMask[3]); +} + + +/*########################################################################################################################* +*-------------------------------------------------------Index buffers-----------------------------------------------------* +*#########################################################################################################################*/ +GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { + return (void*)1; +} + +void Gfx_BindIb(GfxResourceID ib) { } +void Gfx_DeleteIb(GfxResourceID* ib) { } + + +/*########################################################################################################################* +*-------------------------------------------------------Vertex buffers----------------------------------------------------* +*#########################################################################################################################*/ +static void* gfx_vertices; + +static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) { + return Mem_TryAlloc(count, strideSizes[fmt]); +} + +void Gfx_BindVb(GfxResourceID vb) { gfx_vertices = vb; } + +void Gfx_DeleteVb(GfxResourceID* vb) { + GfxResourceID data = *vb; + if (data) Mem_Free(data); + *vb = 0; +} + +void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) { + return vb; +} + +void Gfx_UnlockVb(GfxResourceID vb) { + gfx_vertices = vb; +} + + +static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) { + return Mem_TryAlloc(maxVertices, strideSizes[fmt]); +} + +void Gfx_BindDynamicVb(GfxResourceID vb) { Gfx_BindVb(vb); } + +void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) { + return vb; +} + +void Gfx_UnlockDynamicVb(GfxResourceID vb) { + gfx_vertices = vb; +} + +void Gfx_DeleteDynamicVb(GfxResourceID* vb) { Gfx_DeleteVb(vb); } + + +/*########################################################################################################################* +*---------------------------------------------------------Matrices--------------------------------------------------------* +*#########################################################################################################################*/ +static struct Matrix _view, _proj, mvp; + +void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) { + if (type == MATRIX_VIEW) _view = *matrix; + if (type == MATRIX_PROJECTION) _proj = *matrix; + + Matrix_Mul(&mvp, &_view, &_proj); + // TODO +} + +void Gfx_LoadIdentityMatrix(MatrixType type) { + Gfx_LoadMatrix(type, &Matrix_Identity); + // TODO +} + +void Gfx_EnableTextureOffset(float x, float y) { + // TODO +} + +void Gfx_DisableTextureOffset(void) { + // TODO +} + +void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float zNear, float zFar) { + /* Transposed, source https://learn.microsoft.com/en-us/windows/win32/opengl/glortho */ + /* The simplified calculation below uses: L = 0, R = width, T = 0, B = height */ + *matrix = Matrix_Identity; + + matrix->row1.x = 2.0f / width; + matrix->row2.y = -2.0f / height; + matrix->row3.z = -2.0f / (zFar - zNear); + + matrix->row4.x = -1.0f; + matrix->row4.y = 1.0f; + matrix->row4.z = -(zFar + zNear) / (zFar - zNear); +} + +static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { + float zNear_ = zFar; + float zFar_ = 0.1f; + float c = (float)Cotangent(0.5f * fov); + + /* Transposed, source https://learn.microsoft.com/en-us/windows/win32/opengl/glfrustum */ + /* For pos FOV based perspective matrix, left/right/top/bottom are calculated as: */ + /* left = -c * aspect, right = c * aspect, bottom = -c, top = c */ + /* Calculations are simplified because of left/right and top/bottom symmetry */ + *matrix = Matrix_Identity; + // TODO: Check is Frustum culling needs changing for this + + matrix->row1.x = c / aspect; + matrix->row2.y = c; + matrix->row3.z = -(zFar_ + zNear_) / (zFar_ - zNear_); + matrix->row3.w = -1.0f; + matrix->row4.z = -(2.0f * zFar_ * zNear_) / (zFar_ - zNear_); + matrix->row4.w = 0.0f; +} + + +/*########################################################################################################################* +*---------------------------------------------------------Rendering-------------------------------------------------------* +*#########################################################################################################################*/ +void Gfx_SetVertexFormat(VertexFormat fmt) { + gfx_format = fmt; + gfx_stride = strideSizes[fmt]; +} + +void Gfx_DrawVb_Lines(int verticesCount) { + +} + +void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) { +} + +void Gfx_DrawVb_IndexedTris(int verticesCount) { +} + +void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) { +} + + +/*########################################################################################################################* +*---------------------------------------------------------Other/Misc------------------------------------------------------* +*#########################################################################################################################*/ +cc_result Gfx_TakeScreenshot(struct Stream* output) { + return ERR_NOT_SUPPORTED; +} + +cc_bool Gfx_WarnIfNecessary(void) { + return false; +} + +void Gfx_BeginFrame(void) { +} + +void Gfx_EndFrame(void) { + if (gfx_minFrameMs) LimitFPS(); +} + +void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMs) { + gfx_minFrameMs = minFrameMs; + gfx_vsync = vsync; +} + +void Gfx_OnWindowResize(void) { + // TODO +} + +void Gfx_GetApiInfo(cc_string* info) { + String_AppendConst(info, "-- Using PS1 --\n"); + PrintMaxTextureInfo(info); +} + +cc_bool Gfx_TryRestoreContext(void) { return true; } +#endif diff --git a/src/Platform_PS1.c b/src/Platform_PS1.c new file mode 100644 index 000000000..dfd452dca --- /dev/null +++ b/src/Platform_PS1.c @@ -0,0 +1,229 @@ +#include "Core.h" +#if defined PLAT_PS1 + +#include "_PlatformBase.h" +#include "Stream.h" +#include "ExtMath.h" +#include "Funcs.h" +#include "Window.h" +#include "Utils.h" +#include "Errors.h" +#include "PackedCol.h" +#include +#include +#include +#include +#include +#include +#include +#include "_PlatformConsole.h" + +const cc_result ReturnCode_FileShareViolation = 1000000000; // not used +const cc_result ReturnCode_FileNotFound = 99999; +const cc_result ReturnCode_DirectoryExists = 99999; + +const cc_result ReturnCode_SocketInProgess = -1; +const cc_result ReturnCode_SocketWouldBlock = -1; +const char* Platform_AppNameSuffix = " PS1"; +void exit(int code) { } // TODO how to fix + + +/*########################################################################################################################* +*------------------------------------------------------Logging/Time-------------------------------------------------------* +*#########################################################################################################################*/ +void Platform_Log(const char* msg, int len) { + char tmp[2048 + 1]; + len = min(len, 2048); + Mem_Copy(tmp, msg, len); tmp[len] = '\0'; + + printf("%s\n", tmp); +} + +#define UnixTime_TotalMS(time) ((cc_uint64)time.tv_sec * 1000 + UNIX_EPOCH + (time.tv_usec / 1000)) +TimeMS DateTime_CurrentUTC_MS(void) { + return 0; +} + +void DateTime_CurrentLocal(struct DateTime* t) { + Mem_Set(t, 0, sizeof(struct DateTime)); +} + + +/*########################################################################################################################* +*--------------------------------------------------------Stopwatch--------------------------------------------------------* +*#########################################################################################################################*/ +static volatile cc_uint32 irq_count; + +cc_uint64 Stopwatch_Measure(void) { + return irq_count; +} + +cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) { + if (end < beg) return 0; + return (end - beg); // TODO calculate ??? +} + +static void timer2_handler(void) { + irq_count++; +} + +static void Stopwatch_Init(void) { + TIMER_CTRL(2) = 0x0260; // CLK/8 input, repeated IRQ on overflow + + EnterCriticalSection(); + InterruptCallback(IRQ_TIMER2, &timer2_handler); + ExitCriticalSection(); +} + + +/*########################################################################################################################* +*-----------------------------------------------------Directory/File------------------------------------------------------* +*#########################################################################################################################*/ +cc_result Directory_Create(const cc_string* path) { + return ERR_NOT_SUPPORTED; +} + +int File_Exists(const cc_string* path) { + return 0; +} + +cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCallback callback) { + return ERR_NOT_SUPPORTED; +} + +cc_result File_Open(cc_file* file, const cc_string* path) { + return ERR_NOT_SUPPORTED; +} +cc_result File_Create(cc_file* file, const cc_string* path) { + return ERR_NOT_SUPPORTED; +} +cc_result File_OpenOrCreate(cc_file* file, const cc_string* path) { + return ERR_NOT_SUPPORTED; +} + +cc_result File_Read(cc_file file, void* data, cc_uint32 count, cc_uint32* bytesRead) { + return ERR_NOT_SUPPORTED; +} + +cc_result File_Write(cc_file file, const void* data, cc_uint32 count, cc_uint32* bytesWrote) { + return ERR_NOT_SUPPORTED; +} + +cc_result File_Close(cc_file file) { + return 0; +} + +cc_result File_Seek(cc_file file, int offset, int seekType) { + return ERR_NOT_SUPPORTED; +} + +cc_result File_Position(cc_file file, cc_uint32* pos) { + return ERR_NOT_SUPPORTED; +} + +cc_result File_Length(cc_file file, cc_uint32* len) { + return ERR_NOT_SUPPORTED; +} + + +/*########################################################################################################################* +*--------------------------------------------------------Threading--------------------------------------------------------* +*#########################################################################################################################*/ +void Thread_Sleep(cc_uint32 milliseconds) { + // TODO sleep a bit + VSync(0); +} + +void Thread_Run(void** handle, Thread_StartFunc func, int stackSize, const char* name) { + *handle = NULL; +} + +void Thread_Detach(void* handle) { +} + +void Thread_Join(void* handle) { +} + +void* Mutex_Create(void) { + return NULL; +} + +void Mutex_Free(void* handle) { +} + +void Mutex_Lock(void* handle) { +} + +void Mutex_Unlock(void* handle) { +} + +void* Waitable_Create(void) { + return NULL; +} + +void Waitable_Free(void* handle) { +} + +void Waitable_Signal(void* handle) { +} + +void Waitable_Wait(void* handle) { +} + +void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) { +} + + +/*########################################################################################################################* +*---------------------------------------------------------Socket----------------------------------------------------------* +*#########################################################################################################################*/ +cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) { + return ERR_NOT_SUPPORTED; +} + +cc_result Socket_Connect(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) { + return ERR_NOT_SUPPORTED; +} + +cc_result Socket_Read(cc_socket s, cc_uint8* data, cc_uint32 count, cc_uint32* modified) { + return ERR_NOT_SUPPORTED; +} + +cc_result Socket_Write(cc_socket s, const cc_uint8* data, cc_uint32 count, cc_uint32* modified) { + return ERR_NOT_SUPPORTED; +} + +void Socket_Close(cc_socket s) { +} + +cc_result Socket_CheckReadable(cc_socket s, cc_bool* readable) { + return ERR_NOT_SUPPORTED; +} + +cc_result Socket_CheckWritable(cc_socket s, cc_bool* writable) { + return ERR_NOT_SUPPORTED; +} + + +/*########################################################################################################################* +*--------------------------------------------------------Platform---------------------------------------------------------* +*#########################################################################################################################*/ +void Platform_Init(void) { + ResetGraph( 0 ); + Stopwatch_Init(); +} + +void Platform_Free(void) { } + +cc_bool Platform_DescribeError(cc_result res, cc_string* dst) { + return false; +} + + +/*########################################################################################################################* +*-------------------------------------------------------Encryption--------------------------------------------------------* +*#########################################################################################################################*/ +static cc_result GetMachineID(cc_uint32* key) { + return ERR_NOT_SUPPORTED; +} +#endif diff --git a/src/Window_PS1.c b/src/Window_PS1.c new file mode 100644 index 000000000..833224fd3 --- /dev/null +++ b/src/Window_PS1.c @@ -0,0 +1,206 @@ +#include "Core.h" +#if defined CC_BUILD_PS1 +#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 +#include +#include +#include +#include +#include +#include +#include + +#define SCREEN_XRES 320 +#define SCREEN_YRES 240 + +static cc_bool launcherMode; +static char pad_buff[2][34]; + +struct _DisplayData DisplayInfo; +struct _WindowData WindowInfo; + +void Window_Init(void) { + DisplayInfo.Width = SCREEN_XRES; + DisplayInfo.Height = SCREEN_YRES; + DisplayInfo.Depth = 4; // 32 bit + 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; + +// http://lameguy64.net/tutorials/pstutorials/chapter1/4-controllers.html + InitPAD(&pad_buff[0][0], 34, &pad_buff[1][0], 34); + pad_buff[0][0] = pad_buff[0][1] = 0xff; + pad_buff[1][0] = pad_buff[1][1] = 0xff; + StartPAD(); + ChangeClearPAD(0); +} + +void Window_Free(void) { } + +void Window_Create3D(int width, int height) { + 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 HandleButtons(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; + + Input_SetNonRepeatable(CCPAD_A, buttons & PAD_TRIANGLE); + Input_SetNonRepeatable(CCPAD_B, buttons & PAD_SQUARE); + Input_SetNonRepeatable(CCPAD_X, buttons & PAD_CROSS); + Input_SetNonRepeatable(CCPAD_Y, buttons & PAD_CIRCLE); + + Input_SetNonRepeatable(CCPAD_START, buttons & PAD_START); + Input_SetNonRepeatable(CCPAD_SELECT, buttons & PAD_SELECT); + + Input_SetNonRepeatable(CCPAD_LEFT, buttons & PAD_LEFT); + Input_SetNonRepeatable(CCPAD_RIGHT, buttons & PAD_RIGHT); + Input_SetNonRepeatable(CCPAD_UP, buttons & PAD_UP); + Input_SetNonRepeatable(CCPAD_DOWN, buttons & PAD_DOWN); + + Input_SetNonRepeatable(CCPAD_L, buttons & PAD_L1); + Input_SetNonRepeatable(CCPAD_R, buttons & PAD_R1); + Input_SetNonRepeatable(CCPAD_ZL, buttons & PAD_L2); + Input_SetNonRepeatable(CCPAD_ZR, buttons & PAD_R2); +} + +static void ProcessPadInput(PADTYPE* pad, double delta) { + HandleButtons(pad->btn); +} + +void Window_ProcessEvents(double delta) { + PADTYPE* pad = (PADTYPE*)&pad_buff[0][0]; + if (pad->stat == 0) ProcessPadInput(pad, 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; } + + +/*########################################################################################################################* +*------------------------------------------------------Framebuffer--------------------------------------------------------* +*#########################################################################################################################*/ +void Window_Create2D(int width, int height) { + launcherMode = true; +} + +static DISPENV disp; +static cc_uint16* fb; + +void Window_AllocFramebuffer(struct Bitmap* bmp) { + SetDefDispEnv(&disp, 0, 0, SCREEN_XRES, SCREEN_YRES); + disp.isinter = 1; + + PutDispEnv(&disp); + SetDispMask(1); + + bmp->scan0 = (BitmapCol*)Mem_Alloc(bmp->width * bmp->height, 4, "window pixels"); + fb = Mem_Alloc(bmp->width * bmp->height, 2, "real surface"); +} + +#define BGRA8_to_PS1(src) \ + ((src[2] & 0xF8) >> 3) | ((src[1] & 0xF8) << 2) | ((src[0] & 0xF8) << 7) | 0x8000 + +void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) { + RECT rect; + rect.x = 0; + rect.y = 0; + rect.w = SCREEN_XRES; + rect.h = SCREEN_YRES; + + HeapUsage usage; + GetHeapUsage(&usage); + + Platform_Log4("%i / %i / %i / %i", &usage.total, &usage.heap, &usage.stack, &usage.alloc); + + + for (int y = 0; y < bmp->height; y++) + { + cc_uint32* src = bmp->scan0 + y * bmp->width; + cc_uint16* dst = fb + y * bmp->width; + + for (int x = 0; x < bmp->width; x++) { + cc_uint8* color = (cc_uint8*)&src[x]; + dst[x] = BGRA8_to_PS1(0); + } + } + + Platform_Log4("%i / %i / %i / %i", &usage.total, &usage.heap, &usage.stack, &usage.alloc); + + LoadImage(&rect, bmp->scan0); + DrawSync(0); +} + +void Window_FreeFramebuffer(struct Bitmap* bmp) { + Mem_Free(bmp->scan0); + Mem_Free(fb); +} + + +/*########################################################################################################################* +*------------------------------------------------------Soft keyboard------------------------------------------------------* +*#########################################################################################################################*/ +void Window_OpenKeyboard(struct OpenKeyboardArgs* args) { /* TODO implement */ } +void Window_SetKeyboardText(const cc_string* text) { } +void Window_CloseKeyboard(void) { /* TODO implement */ } + + +/*########################################################################################################################* +*-------------------------------------------------------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 diff --git a/src/_PlatformConsole.h b/src/_PlatformConsole.h index 9845244ae..65a4c2dab 100644 --- a/src/_PlatformConsole.h +++ b/src/_PlatformConsole.h @@ -70,6 +70,11 @@ int Platform_GetCommandLineArgs(int argc, STRING_REF char** argv, cc_string* arg // Consoles *sometimes* doesn't use argv[0] for program name and so argc will be 0 // (e.g. when running via some emulators) if (!argc) return 0; + +#ifdef CC_BUILD_PS1 + // When running in DuckStation at least, argv was a five element array of empty strings ??? + return 0; +#endif argc--; argv++; // skip executable path argument @@ -215,4 +220,4 @@ cc_result Platform_Decrypt(const void* data, int len, cc_string* dst) { String_AppendAll(dst, header, min(dataLen, ENC_SIZE)); } return 0; -} \ No newline at end of file +}