From 4808701c6e4599f5aaf25e7b38d67d26054765e5 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 9 Sep 2023 22:28:53 +1000 Subject: [PATCH] PS3: More work on 3D, switch to using native FS apis --- src/Graphics_PS3.c | 85 +++++++++++++++++++++++++++++--------- src/Platform_PS3.c | 100 ++++++++++++++++++++++++--------------------- src/Window_PS3.c | 12 ++++++ 3 files changed, 132 insertions(+), 65 deletions(-) diff --git a/src/Graphics_PS3.c b/src/Graphics_PS3.c index 7ea4cacf6..555c731ae 100644 --- a/src/Graphics_PS3.c +++ b/src/Graphics_PS3.c @@ -38,9 +38,8 @@ static void VP_Load(VertexProgram* vp, const u8* source) { vp->prog = (rsxVertexProgram*)source; u32 size = 0; rsxVertexProgramGetUCode(vp->prog, &vp->ucode, &size); - vp->mvp = rsxVertexProgramGetConst(vp->prog, "mvp"); - Platform_Log1("VP shader size: %i", &size); + vp->mvp = rsxVertexProgramGetConst(vp->prog, "mvp"); } static void LoadVertexPrograms(void) { @@ -81,7 +80,6 @@ static void FP_Load(FragmentProgram* fp, const u8* source) { u32 size = 0; rsxFragmentProgramGetUCode(fp->prog, &fp->ucode, &size); - Platform_Log1("FP shader size: %i", &size); fp->buffer = (u32*)rsxMemalign(128, size); Mem_Copy(fp->buffer, fp->ucode, size); rsxAddressToOffset(fp->buffer, &fp->offset); @@ -121,7 +119,7 @@ static void Gfx_RestoreState(void) { rsxSetColorMaskMrt(context, 0); rsxSetDepthFunc(context, GCM_LEQUAL); - rsxSetClearDepthStencil(context, 0xFFFFFF); + rsxSetClearDepthStencil(context, 0xFFFFFFFF); rsxSetUserClipPlaneControl(context,GCM_USER_CLIP_PLANE_DISABLE, GCM_USER_CLIP_PLANE_DISABLE, @@ -207,6 +205,7 @@ void SetRenderTarget(u32 index) { rsxSetSurface(context,&sf); } +static GfxResourceID white_square; void Gfx_Create(void) { // TODO rethink all this @@ -231,6 +230,12 @@ void Gfx_Create(void) { LoadVertexPrograms(); LoadFragmentPrograms(); + + // 1x1 dummy white texture + struct Bitmap bmp; + BitmapCol pixels[1] = { BITMAPCOLOR_WHITE }; + Bitmap_Init(bmp, 1, 1, pixels); + white_square = Gfx_CreateTexture(&bmp, 0, false); } cc_bool Gfx_TryRestoreContext(void) { return true; } @@ -453,7 +458,7 @@ void Gfx_BindVb(GfxResourceID vb) { void Gfx_DeleteVb(GfxResourceID* vb) { GfxResourceID data = *vb;/* TODO */ - if (data) Mem_Free(data); + if (data) rsxFree(data); *vb = 0; } @@ -494,38 +499,79 @@ void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) { /*########################################################################################################################* *---------------------------------------------------------Textures--------------------------------------------------------* *#########################################################################################################################*/ +typedef struct CCTexture_ { + cc_uint32 width, height; + cc_uint32 pad[(128 - 8)/4]; // TODO better way of aligning to 128 bytes + cc_uint32 pixels[]; +} CCTexture; + +GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) { + int size = bmp->width * bmp->height * 4; + CCTexture* tex = (CCTexture*)rsxMemalign(128, 128 + size); + + tex->width = bmp->width; + tex->height = bmp->height; + Mem_Copy(tex->pixels, bmp->scan0, size); + return tex; +} + void Gfx_BindTexture(GfxResourceID texId) { + CCTexture* tex = (CCTexture*)texId; + if (!tex) tex = white_square; /* TODO */ + + u32 offset; + rsxAddressToOffset(tex->pixels, &offset); + gcmTexture texture; + + texture.format = GCM_TEXTURE_FORMAT_A8R8G8B8 | GCM_TEXTURE_FORMAT_LIN; + texture.mipmap = 1; + texture.dimension = GCM_TEXTURE_DIMS_2D; + texture.cubemap = GCM_FALSE; + texture.remap = ((GCM_TEXTURE_REMAP_TYPE_REMAP << GCM_TEXTURE_REMAP_TYPE_B_SHIFT) | + (GCM_TEXTURE_REMAP_TYPE_REMAP << GCM_TEXTURE_REMAP_TYPE_G_SHIFT) | + (GCM_TEXTURE_REMAP_TYPE_REMAP << GCM_TEXTURE_REMAP_TYPE_R_SHIFT) | + (GCM_TEXTURE_REMAP_TYPE_REMAP << GCM_TEXTURE_REMAP_TYPE_A_SHIFT) | + (GCM_TEXTURE_REMAP_COLOR_B << GCM_TEXTURE_REMAP_COLOR_B_SHIFT) | + (GCM_TEXTURE_REMAP_COLOR_G << GCM_TEXTURE_REMAP_COLOR_G_SHIFT) | + (GCM_TEXTURE_REMAP_COLOR_R << GCM_TEXTURE_REMAP_COLOR_R_SHIFT) | + (GCM_TEXTURE_REMAP_COLOR_A << GCM_TEXTURE_REMAP_COLOR_A_SHIFT)); + texture.width = tex->width; + texture.height = tex->height; + texture.depth = 1; + texture.location = GCM_LOCATION_RSX; + texture.pitch = tex->width * 4; + texture.offset = offset; + + rsxLoadTexture(context, 0, &texture); + rsxTextureControl(context, 0, GCM_TRUE,0<<8,12<<8,GCM_TEXTURE_MAX_ANISO_1); + rsxTextureFilter(context, 0, 0, GCM_TEXTURE_NEAREST, GCM_TEXTURE_NEAREST, + GCM_TEXTURE_CONVOLUTION_QUINCUNX); + rsxTextureWrapMode(context, 0, GCM_TEXTURE_REPEAT, GCM_TEXTURE_REPEAT, GCM_TEXTURE_REPEAT, 0, GCM_TEXTURE_ZFUNC_LESS, 0); } void Gfx_DeleteTexture(GfxResourceID* texId) { - /* TODO */ -} - -void Gfx_EnableMipmaps(void) { } -void Gfx_DisableMipmaps(void) { } - -GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) { - return 1;/* TODO */ + GfxResourceID data = *texId; + if (data) rsxFree(data); + *texId = NULL; } void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps) { rsxInvalidateTextureCache(context, GCM_INVALIDATE_TEXTURE); -/* TODO */ + /* TODO */ } void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, struct Bitmap* part, cc_bool mipmaps) { Gfx_UpdateTexture(texId, x, y, part, part->width, mipmaps); } +void Gfx_EnableMipmaps(void) { } +void Gfx_DisableMipmaps(void) { } + /*########################################################################################################################* *-----------------------------------------------------State management----------------------------------------------------* *#########################################################################################################################*/ -static PackedCol gfx_fogColor; -static float gfx_fogEnd = 16.0f, gfx_fogDensity = 1.0f; -static FogFunc gfx_fogMode = -1; - void Gfx_SetFog(cc_bool enabled) {/* TODO */ } @@ -552,7 +598,7 @@ void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) { *dst = *matrix; struct Matrix mvp; - Matrix_Mul(&mvp, &_view, &_proj); + Matrix_Mul(&mvp, &_proj, &_view); // TODO: dity uniforms for (int i = 0; i < Array_Elems(VP_list); i++) @@ -600,5 +646,6 @@ void Gfx_DrawVb_IndexedTris(int verticesCount) {/* TODO */ } void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) {/* TODO */ + rsxDrawVertexArray(context, GCM_TYPE_QUADS, startVertex, verticesCount); } #endif \ No newline at end of file diff --git a/src/Platform_PS3.c b/src/Platform_PS3.c index 416c16580..64f307802 100644 --- a/src/Platform_PS3.c +++ b/src/Platform_PS3.c @@ -16,14 +16,11 @@ #include #include #include -#include #include #include #include #include #include -#include -#include #include #include #include @@ -98,6 +95,7 @@ cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) { *-----------------------------------------------------Directory/File------------------------------------------------------* *#########################################################################################################################*/ static const cc_string root_path = String_FromConst("/dev_hdd0/ClassiCube/"); + static void GetNativePath(char* str, const cc_string* path) { Mem_Copy(str, root_path.buffer, root_path.length); str += root_path.length; @@ -122,74 +120,83 @@ int File_Exists(const cc_string* path) { cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCallback callback) { cc_string path; char pathBuffer[FILENAME_SIZE]; char str[NATIVE_STR_LEN]; - DIR* dirPtr; - struct dirent* entry; + sysFSDirent entry; char* src; - int len, res, is_dir; + int dir_fd, res; GetNativePath(str, dirPath); - dirPtr = opendir(str); - if (!dirPtr) return errno; + if ((res = sysLv2FsOpenDir(str, &dir_fd))) return res; - /* POSIX docs: "When the end of the directory is encountered, a null pointer is returned and errno is not changed." */ - /* errno is sometimes leftover from previous calls, so always reset it before readdir gets called */ - errno = 0; - String_InitArray(path, pathBuffer); + for (;;) + { + u64 read = 0; + if ((res = sysLv2FsReadDir(dir_fd, &entry, &read))) return res; + if (!read) break; // end of entries - while ((entry = readdir(dirPtr))) { - path.length = 0; - String_Format1(&path, "%s/", dirPath); - - /* ignore . and .. entry */ - src = entry->d_name; + // ignore . and .. entry + src = entry.d_name; if (src[0] == '.' && src[1] == '\0') continue; if (src[0] == '.' && src[1] == '.' && src[2] == '\0') continue; - - len = String_Length(src); + + String_InitArray(path, pathBuffer); + String_Format1(&path, "%s/", dirPath); + + int len = String_Length(src); String_AppendUtf8(&path, src, len); - is_dir = entry->d_type == DT_DIR; - /* TODO: fallback to stat when this fails */ - - if (is_dir) { + if (entry.d_type == DT_DIR) { res = Directory_Enum(&path, obj, callback); - if (res) { closedir(dirPtr); return res; } + if (res) break; } else { callback(&path, obj); } - errno = 0; } - res = errno; /* return code from readdir */ - closedir(dirPtr); + sysLv2FsCloseDir(dir_fd); return res; } static cc_result File_Do(cc_file* file, const cc_string* path, int mode) { char str[NATIVE_STR_LEN]; GetNativePath(str, path); - *file = open(str, mode, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - return *file == -1 ? errno : 0; + int fd = -1; + + int access = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + int res = sysLv2FsOpen(str, mode, &fd, access, NULL, 0); + + if (res) { + *file = -1; return res; + } else { + // TODO: is this actually needed? + if (mode & SYS_O_CREAT) sysLv2FsChmod(str, access); + *file = fd; return 0; + } } cc_result File_Open(cc_file* file, const cc_string* path) { - return File_Do(file, path, O_RDONLY); + return File_Do(file, path, SYS_O_RDONLY); } cc_result File_Create(cc_file* file, const cc_string* path) { - return File_Do(file, path, O_RDWR | O_CREAT | O_TRUNC); + return File_Do(file, path, SYS_O_RDWR | SYS_O_CREAT | SYS_O_TRUNC); } cc_result File_OpenOrCreate(cc_file* file, const cc_string* path) { - return File_Do(file, path, O_RDWR | O_CREAT); + return File_Do(file, path, SYS_O_RDWR | SYS_O_CREAT); } cc_result File_Read(cc_file file, void* data, cc_uint32 count, cc_uint32* bytesRead) { - *bytesRead = read(file, data, count); - return *bytesRead == -1 ? errno : 0; + u64 read = 0; + int res = sysLv2FsRead(file, data, count, &read); + + *bytesRead = read; + return res; } cc_result File_Write(cc_file file, const void* data, cc_uint32 count, cc_uint32* bytesWrote) { - *bytesWrote = write(file, data, count); - return *bytesWrote == -1 ? errno : 0; + u64 wrote = 0; + int res = sysLv2FsWrite(file, data, count, &wrote); + + *bytesWrote = wrote; + return res; } cc_result File_Close(cc_file file) { @@ -197,24 +204,25 @@ cc_result File_Close(cc_file file) { } cc_result File_Seek(cc_file file, int offset, int seekType) { - static cc_uint8 modes[3] = { SEEK_SET, SEEK_CUR, SEEK_END }; - return lseek(file, offset, modes[seekType]) == -1 ? errno : 0; + static cc_uint8 modes[] = { SEEK_SET, SEEK_CUR, SEEK_END }; + u64 position = 0; + return sysLv2FsLSeek64(file, offset, modes[seekType], &position); } cc_result File_Position(cc_file file, cc_uint32* pos) { - *pos = lseek(file, 0, SEEK_CUR); - return *pos == -1 ? errno : 0; + u64 position = 0; + int res = sysLv2FsLSeek64(file, 0, SEEK_CUR, &position); + + *pos = position; + return res; } cc_result File_Length(cc_file file, cc_uint32* len) { sysFSStat st; int res = sysLv2FsFStat(file, &st); - if (res) { - *len = -1; return res; - } else { - *len = st.st_size; return 0; - } + *len = st.st_size; + return res; } diff --git a/src/Window_PS3.c b/src/Window_PS3.c index 0e79149dc..81c644d3a 100644 --- a/src/Window_PS3.c +++ b/src/Window_PS3.c @@ -12,6 +12,7 @@ #include "ExtMath.h" #include "Logger.h" #include +#include #include static cc_bool launcherMode; static padInfo pad_info; @@ -23,7 +24,18 @@ struct _WinData WindowInfo; int Display_ScaleX(int x) { return x; } int Display_ScaleY(int y) { return y; } +static void sysutil_callback(u64 status, u64 param, void* usrdata) { + switch (status) { + case SYSUTIL_EXIT_GAME: + Event_RaiseVoid(&WindowEvents.Closing); + WindowInfo.Exists = false; + break; + } +} + void Window_Init(void) { + sysUtilRegisterCallback(0, sysutil_callback, NULL); + videoState state; videoResolution resolution;