Skip to content

Commit f2df1b2

Browse files
committed
Implementation looks to be almost right
1 parent 6274688 commit f2df1b2

File tree

1 file changed

+128
-3
lines changed

1 file changed

+128
-3
lines changed

src/render/psp/SDL_render_psp.c

Lines changed: 128 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,51 @@ static int calculateBestSliceSizeForTexture(SDL_Texture *texture, SliceSize *uvS
251251

252252
sliceSize->width = foundSlizeSize->width;
253253
sliceSize->height = foundSlizeSize->height;
254-
sliceDimension->width = ((texture->w % foundSlizeSize->width == 0) ? 0 : 1) + (texture->w / foundSlizeSize->width);
255-
sliceDimension->height = ((texture->h % foundSlizeSize->height == 0) ? 0 : 1) + (texture->h / foundSlizeSize->height);
254+
sliceDimension->width = ((uvSize->width % foundSlizeSize->width == 0) ? 0 : 1) + (uvSize->width / foundSlizeSize->width);
255+
sliceDimension->height = ((uvSize->height % foundSlizeSize->height == 0) ? 0 : 1) + (uvSize->height / foundSlizeSize->height);
256256

257257
return 0;
258258
}
259259

260+
static void fillSpriteVertices(VertTV *vertices, SliceSize *dimensions, SliceSize *sliceSize,
261+
const SDL_Rect *srcrect, const SDL_FRect *dstrect) {
262+
int i, j;
263+
float dstrectSlizeWidth = dstrect->w / dimensions->width;
264+
float dstrectSlizeHeight = dstrect->h / dimensions->height;
265+
int remainingWidth = srcrect->w % sliceSize->width;
266+
int remainingHeight = srcrect->h % sliceSize->height;
267+
int hasRemainingWidth = remainingWidth > 0;
268+
int hasRemainingHeight = remainingHeight > 0;
269+
270+
int verticesCount = dimensions->width * dimensions->height * 2;
271+
for (i = 0; i < dimensions->width; i++) {
272+
for (j = 0; j < dimensions->height; j++) {
273+
uint8_t currentIndex = (i * dimensions->height + j) * 2;
274+
vertices[currentIndex].u = srcrect->x + i * sliceSize->width;
275+
vertices[currentIndex].v = srcrect->y + j * sliceSize->height;
276+
vertices[currentIndex].x = dstrect->x + i * dstrectSlizeWidth;
277+
vertices[currentIndex].y = dstrect->y + j * dstrectSlizeHeight;
278+
vertices[currentIndex].z = 0;
279+
280+
if (i == dimensions->width - 1 && hasRemainingWidth) {
281+
vertices[currentIndex + 1].u = srcrect->x + i * sliceSize->width + remainingWidth;
282+
} else {
283+
vertices[currentIndex + 1].u = (srcrect->x + (i +1) * sliceSize->width);
284+
}
285+
286+
if (j == dimensions->height - 1 && hasRemainingHeight) {
287+
vertices[currentIndex + 1].v = srcrect->y + j * sliceSize->height + remainingHeight;
288+
} else {
289+
vertices[currentIndex + 1].v = (srcrect->y + (j + 1) * sliceSize->height);
290+
}
291+
292+
vertices[currentIndex + 1].x = dstrect->x + (i + 1) * dstrectSlizeWidth;
293+
vertices[currentIndex + 1].y = dstrect->y + (j + 1) * dstrectSlizeHeight;
294+
vertices[currentIndex + 1].z = 0;
295+
}
296+
}
297+
}
298+
260299
static void PSP_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event)
261300
{
262301
}
@@ -461,6 +500,60 @@ static int PSP_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
461500
return 0;
462501
}
463502

503+
static int PSP_QueueCopy(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
504+
const SDL_Rect *srcrect, const SDL_FRect *dstrect)
505+
{
506+
VertTV *verts;
507+
uint8_t verticesCount;
508+
const float x = dstrect->x;
509+
const float y = dstrect->y;
510+
const float width = dstrect->w;
511+
const float height = dstrect->h;
512+
513+
const float u0 = srcrect->x;
514+
const float v0 = srcrect->y;
515+
const float u1 = srcrect->x + srcrect->w;
516+
const float v1 = srcrect->y + srcrect->h;
517+
518+
// We need to split in slices because we have a texture bigger than 64 pixel width
519+
if (texture) {
520+
SliceSize sliceSize, sliceDimension, uvSize;
521+
uvSize.width = abs(u1) - abs(u0);
522+
uvSize.height = abs(v1) - abs(v0);
523+
if (calculateBestSliceSizeForTexture(texture, &uvSize, &sliceSize, &sliceDimension))
524+
return -1;
525+
526+
verticesCount = sliceDimension.width * sliceDimension.height * 2;
527+
verts = (VertTV *)SDL_AllocateRenderVertices(renderer, verticesCount * sizeof(VertTV), 4, &cmd->data.draw.first);
528+
if (verts == NULL)
529+
return -1;
530+
531+
fillSpriteVertices(verts, &sliceDimension, &sliceSize, srcrect, dstrect);
532+
} else {
533+
// We don't need to split in slices because we don't have a texture
534+
verticesCount = 2;
535+
verts = (VertTV *)SDL_AllocateRenderVertices(renderer, verticesCount * sizeof(VertTV), 4, &cmd->data.draw.first);
536+
if (verts == NULL)
537+
return -1;
538+
539+
verts[0].u = u0;
540+
verts[0].v = v0;
541+
verts[0].x = x;
542+
verts[0].y = y;
543+
verts[0].z = 0;
544+
545+
verts[1].u = u1;
546+
verts[1].v = v1;
547+
verts[1].x = x + width;
548+
verts[1].y = y + height;
549+
verts[1].z = 0;
550+
}
551+
552+
cmd->data.draw.count = verticesCount;
553+
554+
return 0;
555+
}
556+
464557
static int PSP_RenderSetViewPort(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
465558
{
466559
PSP_RenderData *data = (PSP_RenderData *)renderer->driverdata;
@@ -636,6 +729,34 @@ int PSP_RenderPoints(SDL_Renderer *renderer, void *vertices, SDL_RenderCommand *
636729
return 0;
637730
}
638731

732+
int PSP_RenderCopy(SDL_Renderer *renderer, void *vertices, SDL_RenderCommand *cmd)
733+
{
734+
PSP_RenderData *data = (PSP_RenderData *)renderer->driverdata;
735+
const size_t count = cmd->data.draw.count;
736+
const VertTV *verts = (VertTV *)(vertices + cmd->data.draw.first);
737+
PSP_BlendInfo blendInfo = {
738+
.mode = cmd->data.draw.blend,
739+
.shade = GU_FLAT
740+
};
741+
742+
PSP_SetBlendMode(data, blendInfo);
743+
744+
if (cmd->data.draw.texture) {
745+
PSP_Texture *psp_tex = (PSP_Texture *)cmd->data.draw.texture->driverdata;
746+
747+
sceGuTexMode(psp_tex->format, 0, 0, GU_FALSE);
748+
sceGuTexImage(0, psp_tex->textureWidth, psp_tex->textureHeight, psp_tex->width, psp_tex->data);
749+
sceGuTexFilter(psp_tex->filter, psp_tex->filter);
750+
sceGuEnable(GU_TEXTURE_2D);
751+
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts);
752+
sceGuDisable(GU_TEXTURE_2D);
753+
} else {
754+
sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts);
755+
}
756+
757+
return 0;
758+
}
759+
639760
static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
640761
{
641762
/* note that before the renderer interface change, this would do extrememly small
@@ -685,8 +806,11 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
685806
}
686807
case SDL_RENDERCMD_FILL_RECTS: /* unused */
687808
break;
688-
case SDL_RENDERCMD_COPY: /* unused */
809+
case SDL_RENDERCMD_COPY:
810+
{
811+
PSP_RenderCopy(renderer, gpumem, cmd);
689812
break;
813+
}
690814
case SDL_RENDERCMD_COPY_EX: /* unused */
691815
break;
692816
case SDL_RENDERCMD_GEOMETRY:
@@ -845,6 +969,7 @@ static int PSP_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, Uint32
845969
renderer->QueueDrawPoints = PSP_QueueDrawPoints;
846970
renderer->QueueDrawLines = PSP_QueueDrawPoints;
847971
renderer->QueueGeometry = PSP_QueueGeometry;
972+
renderer->QueueCopy = PSP_QueueCopy;
848973
renderer->RunCommandQueue = PSP_RunCommandQueue;
849974
renderer->RenderReadPixels = PSP_RenderReadPixels;
850975
renderer->RenderPresent = PSP_RenderPresent;

0 commit comments

Comments
 (0)