diff --git a/src/render/psp/SDL_render_psp.c b/src/render/psp/SDL_render_psp.c index 6a6f58527..c1e0e6dd9 100644 --- a/src/render/psp/SDL_render_psp.c +++ b/src/render/psp/SDL_render_psp.c @@ -108,9 +108,22 @@ typedef struct { float u, v; float x, y, z; - } VertTV; +typedef struct +{ + int col; + float x, y, z; +} VertCV; + + +typedef struct +{ + float u, v; + int col; + float x, y, z; +} VertTCV; + #define PI 3.14159265358979f #define radToDeg(x) ((x)*180.f/PI) @@ -473,6 +486,94 @@ PSP_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_F return 0; } +static int +PSP_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + int i; + int count = indices ? num_indices : num_vertices; + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + if (texture == NULL) { + VertCV *verts; + verts = (VertCV *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertCV), 4, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + for (i = 0; i < count; i++) { + int j; + float *xy_; + int col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(int *)((char*)color + j * color_stride); + + verts->x = xy_[0] * scale_x; + verts->y = xy_[1] * scale_y; + verts->z = 0; + + verts->col = col_; + + verts++; + } + } else { + PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata; + VertTCV *verts; + verts = (VertTCV *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertTCV), 4, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + for (i = 0; i < count; i++) { + int j; + float *xy_; + int col_; + float *uv_; + + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(int *)((char*)color + j * color_stride); + uv_ = (float *)((char*)uv + j * uv_stride); + + verts->x = xy_[0] * scale_x; + verts->y = xy_[1] * scale_y; + verts->z = 0; + + verts->col = col_; + + verts->u = uv_[0] * psp_texture->textureWidth; + verts->v = uv_[1] * psp_texture->textureHeight; + + verts++; + } + } + + return 0; +} + static int PSP_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) { @@ -853,6 +954,25 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti break; } + case SDL_RENDERCMD_GEOMETRY: { + const size_t count = cmd->data.draw.count; + if (cmd->data.draw.texture == NULL) { + const VertCV *verts = (VertCV *) (gpumem + cmd->data.draw.first); + sceGuDisable(GU_TEXTURE_2D); + /* In GU_SMOOTH mode */ + sceGuDrawArray(GU_TRIANGLES, GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts); + sceGuEnable(GU_TEXTURE_2D); + } else { + const VertTCV *verts = (VertTCV *) (gpumem + cmd->data.draw.first); + TextureActivate(cmd->data.draw.texture); + /* Need to force refresh of blending mode, probably something to FIXME */ + PSP_SetBlendMode(renderer, SDL_BLENDMODE_INVALID); + PSP_SetBlendMode(renderer, cmd->data.draw.blend); + sceGuDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts); + } + break; + } + case SDL_RENDERCMD_NO_OP: break; } @@ -967,6 +1087,7 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->QueueSetDrawColor = PSP_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = PSP_QueueDrawPoints; renderer->QueueDrawLines = PSP_QueueDrawPoints; /* lines and points queue vertices the same way. */ + renderer->QueueGeometry = PSP_QueueGeometry; renderer->QueueFillRects = PSP_QueueFillRects; renderer->QueueCopy = PSP_QueueCopy; renderer->QueueCopyEx = PSP_QueueCopyEx; @@ -1028,8 +1149,11 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags) sceGuEnable(GU_SCISSOR_TEST); /* Backface culling */ + /* + FIXME: Culling probably un-needed ? It can conflict with SDL_RENDERCMD_GEOMETRY sceGuFrontFace(GU_CCW); sceGuEnable(GU_CULL_FACE); + */ /* Texturing */ sceGuEnable(GU_TEXTURE_2D);