@@ -251,12 +251,51 @@ static int calculateBestSliceSizeForTexture(SDL_Texture *texture, SliceSize *uvS
251
251
252
252
sliceSize -> width = foundSlizeSize -> width ;
253
253
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 );
256
256
257
257
return 0 ;
258
258
}
259
259
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
+
260
299
static void PSP_WindowEvent (SDL_Renderer * renderer , const SDL_WindowEvent * event )
261
300
{
262
301
}
@@ -461,6 +500,60 @@ static int PSP_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
461
500
return 0 ;
462
501
}
463
502
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
+
464
557
static int PSP_RenderSetViewPort (SDL_Renderer * renderer , SDL_RenderCommand * cmd )
465
558
{
466
559
PSP_RenderData * data = (PSP_RenderData * )renderer -> driverdata ;
@@ -636,6 +729,34 @@ int PSP_RenderPoints(SDL_Renderer *renderer, void *vertices, SDL_RenderCommand *
636
729
return 0 ;
637
730
}
638
731
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
+
639
760
static int PSP_RunCommandQueue (SDL_Renderer * renderer , SDL_RenderCommand * cmd , void * vertices , size_t vertsize )
640
761
{
641
762
/* 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
685
806
}
686
807
case SDL_RENDERCMD_FILL_RECTS : /* unused */
687
808
break ;
688
- case SDL_RENDERCMD_COPY : /* unused */
809
+ case SDL_RENDERCMD_COPY :
810
+ {
811
+ PSP_RenderCopy (renderer , gpumem , cmd );
689
812
break ;
813
+ }
690
814
case SDL_RENDERCMD_COPY_EX : /* unused */
691
815
break ;
692
816
case SDL_RENDERCMD_GEOMETRY :
@@ -845,6 +969,7 @@ static int PSP_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, Uint32
845
969
renderer -> QueueDrawPoints = PSP_QueueDrawPoints ;
846
970
renderer -> QueueDrawLines = PSP_QueueDrawPoints ;
847
971
renderer -> QueueGeometry = PSP_QueueGeometry ;
972
+ renderer -> QueueCopy = PSP_QueueCopy ;
848
973
renderer -> RunCommandQueue = PSP_RunCommandQueue ;
849
974
renderer -> RenderReadPixels = PSP_RenderReadPixels ;
850
975
renderer -> RenderPresent = PSP_RenderPresent ;
0 commit comments