diff --git a/src/platforms/rcore_playstation2.c b/src/platforms/rcore_playstation2.c index 87fe9ddf6c46..7bc89e901935 100644 --- a/src/platforms/rcore_playstation2.c +++ b/src/platforms/rcore_playstation2.c @@ -63,6 +63,8 @@ #include /* ps2gl */ +#include "GL/glut.h" +#include "GL/ps2gl.h" #include #include #include @@ -107,9 +109,19 @@ static const struct // Types and Structures Definition //---------------------------------------------------------------------------------- + +#define PS2GL_MAX_TEXTURE_LIMIT 10 //You can change this limit +typedef struct { + GLuint id; + int width, height; +} ps2gl_surface_t; + + typedef struct { // TODO: Define the platform specific variables required int version; + ps2gl_surface_t surfaces[PS2GL_MAX_TEXTURE_LIMIT]; + unsigned int surface_index; } PlatformData; //---------------------------------------------------------------------------------- @@ -376,16 +388,44 @@ void DisableCursor(void) CORE.Input.Mouse.cursorHidden = true; } +int gVBlankDivisor = 1; // 1=~60 (NTSC), 2=~30, 3=~20, 4=~15 ... +double gRefreshHz = 59.94; // overwritten to 50.0 on PAL + +static inline void Ps2SetRefreshHz(bool pal) { gRefreshHz = pal ? 50.0 : 59.94; } + +void SetTargetFPSPS2(int fps) +{ + if (fps <= 0 || fps >= (int)(gRefreshHz - 0.5)) + { + gVBlankDivisor = 1; + } + else + { + int div = (int)lround(gRefreshHz / (double)fps); + if (div < 1) div = 1; + gVBlankDivisor = div; + } + TRACELOG(LOG_INFO, + "PS2: vblank pacing refresh=%.2f Hz, target=%d fps -> divisor=%d (actual ~%.2f fps)", + gRefreshHz, fps, gVBlankDivisor, gRefreshHz / gVBlankDivisor); +} + // Swap back buffer with front buffer (screen drawing) void SwapScreenBuffer(void) { pglEndGeometry(); if (!firstTime) + { pglFinishRenderingGeometry(PGL_DONT_FORCE_IMMEDIATE_STOP); + } else + { firstTime = false; - pglWaitForVSync(); + } + for (int i = 0; i < gVBlankDivisor; ++i) { + pglWaitForVSync(); + } pglSwapBuffers(); pglRenderGeometry(); } @@ -903,6 +943,23 @@ int initializePad(int port, int slot) return 1; } + +void rlLoadTexturePS2(unsigned int id, const void *data, int width, int height) +{ + const size_t imageSize = (size_t)width * (size_t)height * 4u; + uint8_t *texels = (uint8_t*)pglutAllocDmaMem(imageSize); + memcpy(texels, data, imageSize); + + glBindTexture(GL_TEXTURE_2D, id); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texels); + glBindTexture(GL_TEXTURE_2D, 0); +} // Initialize platform: graphics, inputs and more int InitPlatform(void) { @@ -968,13 +1025,13 @@ int InitPlatform(void) } // does gs memory need to be initialized? - + bool pal = false; if (!pglHasGsMemBeenInitted()) { TRACELOG(LOG_INFO,"GS memory has not been allocated by the user; using default values."); //pal true ntsc false - initGsMemoryForRaylib(false); + initGsMemoryForRaylib(pal); } - + Ps2SetRefreshHz(pal); diff --git a/src/rcore.c b/src/rcore.c index f95646f47011..0c09eb9b52ea 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -977,6 +977,9 @@ void BeginDrawing(void) //rlTranslatef(0.375, 0.375, 0); // HACK to have 2D pixel-perfect drawing on OpenGL 1.1 // NOTE: Not required with OpenGL 3.3+ +#if defined(PLATFORM_PLAYSTATION2) + rlTranslatef(0.375, 0.375, 0); +#endif } // End canvas drawing and swap buffers (double buffering) @@ -1040,6 +1043,7 @@ void EndDrawing(void) CORE.Time.frame = CORE.Time.update + CORE.Time.draw; // Wait for some milliseconds... +#if !defined(PLATFORM_PLAYSTATION2) if (CORE.Time.frame < CORE.Time.target) { WaitTime(CORE.Time.target - CORE.Time.frame); @@ -1050,7 +1054,7 @@ void EndDrawing(void) CORE.Time.frame += waitTime; // Total frame time: update + draw + wait } - +#endif PollInputEvents(); // Poll user events (before next frame update) #endif @@ -1744,10 +1748,15 @@ Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera) // Set target FPS (maximum) void SetTargetFPS(int fps) { +#if defined(PLATFORM_PLAYSTATION2) + SetTargetFPSPS2(fps); + return; +#endif if (fps < 1) CORE.Time.target = 0.0; else CORE.Time.target = 1.0/(double)fps; TRACELOG(LOG_INFO, "TIMER: Target time per frame: %02.03f milliseconds", (float)CORE.Time.target*1000.0f); + } // Get current FPS diff --git a/src/rlgl.h b/src/rlgl.h index 25bfefe11f70..7602f6e438d7 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -770,6 +770,9 @@ RLAPI void rlDrawVertexArrayElementsInstanced(int offset, int count, const void #if defined(PLATFORM_NINTENDO64) void rlLoadTextureN64(const void *data, int width, int height, int format, int mipmapCount); #endif +#if defined(PLATFORM_PLAYSTATION2) +void rlLoadTexturePS2(unsigned int id, const void *data, int width, int height); +#endif RLAPI unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount); // Load texture data RLAPI unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo) RLAPI unsigned int rlLoadTextureCubemap(const void *data, int size, int format, int mipmapCount); // Load texture cubemap data @@ -3471,6 +3474,10 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format, #if defined(PLATFORM_NINTENDO64) //glTextParameter must be set before upload to gpu rlLoadTextureN64(data,width,height,format,mipmapCount); +#endif +#if defined(PLATFORM_PLAYSTATION2) + rlLoadTexturePS2(id, data, width, height); + TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %u] PS2 upload %dx%d RGBA8", id, width, height); #endif // At this point we have the texture loaded in GPU and texture parameters configured diff --git a/src/rmodels.c b/src/rmodels.c index e598bebd7ff1..338aa37cea2c 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -1479,7 +1479,7 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform) #define GL_COLOR_ARRAY 0x8076 #define GL_TEXTURE_COORD_ARRAY 0x8078 - rlEnableTexture(material.maps[MATERIAL_MAP_DIFFUSE].texture.id); + if (mesh.texcoords && material.maps[MATERIAL_MAP_DIFFUSE].texture.id > 0) rlEnableTexture(material.maps[MATERIAL_MAP_DIFFUSE].texture.id); if (mesh.animVertices) rlEnableStatePointer(GL_VERTEX_ARRAY, mesh.animVertices); else rlEnableStatePointer(GL_VERTEX_ARRAY, mesh.vertices); @@ -4485,10 +4485,12 @@ static Model LoadOBJ(const char *fileName) model.meshes[i].vertices = (float *)MemAlloc(sizeof(float)*vertexCount*3); model.meshes[i].normals = (float *)MemAlloc(sizeof(float)*vertexCount*3); - model.meshes[i].texcoords = (float *)MemAlloc(sizeof(float)*vertexCount*2); #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + model.meshes[i].texcoords = (float *)MemAlloc(sizeof(float)*vertexCount*2); model.meshes[i].colors = (unsigned char *)MemAlloc(sizeof(unsigned char)*vertexCount*4); #else + if (objAttributes.texcoords != NULL && objAttributes.num_texcoords > 0) model.meshes[i].texcoords = (float *)MemAlloc(sizeof(float)*vertexCount*2); + else model.meshes[i].texcoords = NULL; model.meshes[i].colors = NULL; #endif } @@ -4544,16 +4546,11 @@ static Model LoadOBJ(const char *fileName) for (int i = 0; i < 3; i++) model.meshes[meshIndex].vertices[localMeshVertexCount*3 + i] = objAttributes.vertices[vertIndex*3 + i]; - if ((objAttributes.texcoords != NULL) && (texcordIndex != TINYOBJ_INVALID_INDEX) && (texcordIndex >= 0)) + if ((objAttributes.texcoords != NULL) && (texcordIndex != TINYOBJ_INVALID_INDEX) && (texcordIndex >= 0) && (model.meshes[meshIndex].texcoords)) { for (int i = 0; i < 2; i++) model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + i] = objAttributes.texcoords[texcordIndex*2 + i]; model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + 1] = 1.0f - model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + 1]; } - else - { - model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + 0] = 0.0f; - model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + 1] = 0.0f; - } if ((objAttributes.normals != NULL) && (normalIndex != TINYOBJ_INVALID_INDEX) && (normalIndex >= 0)) {