@@ -82,6 +82,20 @@ typedef struct
8282
8383typedef  struct 
8484{
85+     SDL_Rect  viewport ;
86+     bool  viewport_dirty ;
87+     bool  viewport_is_set ;
88+ 
89+     bool  cliprect_enabled_dirty ;
90+     bool  cliprect_enabled ;
91+     bool  cliprect_dirty ;
92+     SDL_Rect  cliprect ;
93+ 
94+     float  draw_offset_x ;
95+     float  draw_offset_y ;
96+ 
97+     int  drawablew ;
98+     int  drawableh ;
8599    unsigned int   color ;
86100} PSP_DrawStateCache ;
87101
@@ -100,6 +114,7 @@ typedef struct
100114    PSP_TextureData  * most_recent_target ;  /**< start of render target LRU double linked list */ 
101115    PSP_TextureData  * least_recent_target ; /**< end of the LRU list */ 
102116
117+     PSP_DrawStateCache  drawstate ;
103118    bool  vblank_not_reached ; /**< whether vblank wasn't reached */ 
104119} PSP_RenderData ;
105120
@@ -1074,13 +1089,104 @@ static void PSP_InvalidateCachedState(SDL_Renderer *renderer)
10741089    // currently this doesn't do anything. If this needs to do something (and someone is mixing their own rendering calls in!), update this. 
10751090}
10761091
1092+ static  void  ClampCliprectToViewport (SDL_Rect  * clip , const  SDL_Rect  * viewport )
1093+ {
1094+     int  max_x_v , max_y_v , max_x_c , max_y_c ;
1095+ 
1096+     if  (clip -> x  <  0 ) {
1097+         clip -> w  +=  clip -> x ;
1098+         clip -> x  =  0 ;
1099+     }
1100+ 
1101+     if  (clip -> y  <  0 ) {
1102+         clip -> h  +=  clip -> y ;
1103+         clip -> y  =  0 ;
1104+     }
1105+ 
1106+     max_x_c  =  clip -> x  +  clip -> w ;
1107+     max_y_c  =  clip -> y  +  clip -> h ;
1108+ 
1109+     max_x_v  =  viewport -> x  +  viewport -> w ;
1110+     max_y_v  =  viewport -> y  +  viewport -> h ;
1111+ 
1112+     if  (max_x_c  >  max_x_v ) {
1113+         clip -> w  -=  (max_x_v  -  max_x_c );
1114+     }
1115+ 
1116+     if  (max_y_c  >  max_y_v ) {
1117+         clip -> h  -=  (max_y_v  -  max_y_c );
1118+     }
1119+ }
1120+ 
1121+ static  void  SetDrawState (PSP_RenderData  * data )
1122+ {
1123+     if  (data -> drawstate .viewport_dirty ) {
1124+         SDL_Rect  * viewport  =  & data -> drawstate .viewport ;
1125+         /* FIXME: Find a genuine way to make viewport work (right now calling these functions here give no effect) */ 
1126+         /* 
1127+         sceGuOffset(2048 - (480 >> 1) + viewport->x, 2048 - (272 >> 1) + viewport->y); 
1128+         sceGuViewport(2048, 2048, viewport->w, viewport->h); 
1129+         */ 
1130+         data -> drawstate .draw_offset_x  =  viewport -> x ;
1131+         data -> drawstate .draw_offset_y  =  viewport -> y ;
1132+         data -> drawstate .viewport_dirty  =  false;
1133+     }
1134+ 
1135+     if  (data -> drawstate .cliprect_enabled_dirty ) {
1136+         if  (!data -> drawstate .cliprect_enabled  &&  !data -> drawstate .viewport_is_set ) {
1137+             sceGuScissor (0 , 0 , data -> drawstate .drawablew , data -> drawstate .drawableh );
1138+             sceGuEnable (GU_SCISSOR_TEST );
1139+         }
1140+         data -> drawstate .cliprect_enabled_dirty  =  false;
1141+     }
1142+ 
1143+     if  ((data -> drawstate .cliprect_enabled  ||  data -> drawstate .viewport_is_set ) &&  data -> drawstate .cliprect_dirty ) {
1144+         SDL_Rect  rect ;
1145+         SDL_Rect  * viewport  =  & data -> drawstate .viewport ;
1146+         SDL_copyp (& rect , & data -> drawstate .cliprect );
1147+         if  (data -> drawstate .viewport_is_set ) {
1148+             ClampCliprectToViewport (& rect , viewport );
1149+             rect .x  +=  viewport -> x ;
1150+             rect .y  +=  viewport -> y ;
1151+         }
1152+         sceGuEnable (GU_SCISSOR_TEST );
1153+         sceGuScissor (rect .x , rect .y , rect .w , rect .h );
1154+         data -> drawstate .cliprect_dirty  =  false;
1155+     }
1156+ }
1157+ 
1158+ #define  PSP_VERTICES_FUNK (FunkName , Type ) \
1159+ static const Type *FunkName(const PSP_DrawStateCache *drawstate, Uint8 *gpumem, SDL_RenderCommand *cmd, size_t count) \
1160+ { \
1161+     size_t i; \
1162+     float off_x, off_y; \
1163+     Type *verts = (Type *)(gpumem + cmd->data.draw.first); \
1164+ \
1165+     if (!drawstate->viewport_is_set) { \
1166+         return verts; \
1167+     } \
1168+  \
1169+     off_x = drawstate->draw_offset_x; \
1170+     off_y = drawstate->draw_offset_y; \
1171+  \
1172+     for (i = 0; i < count; ++i) { \
1173+         verts[i].x += off_x; \
1174+         verts[i].y += off_y; \
1175+     } \
1176+ \
1177+     return verts;\
1178+ }
1179+ 
1180+ PSP_VERTICES_FUNK (PSP_GetVertV , VertV )
1181+ PSP_VERTICES_FUNK (PSP_GetVertTV , VertTV )
1182+ PSP_VERTICES_FUNK (PSP_GetVertCV , VertCV )
1183+ PSP_VERTICES_FUNK (PSP_GetVertTCV , VertTCV )
1184+ 
10771185static  bool  PSP_RunCommandQueue (SDL_Renderer  * renderer , SDL_RenderCommand  * cmd , void  * vertices , size_t  vertsize )
10781186{
10791187    PSP_RenderData  * data  =  (PSP_RenderData  * )renderer -> internal ;
10801188    Uint8  * gpumem  =  NULL ;
1081-     PSP_DrawStateCache  drawstate ;
1082- 
1083-     drawstate .color  =  0 ;
1189+     int  w  =  0 , h  =  0 ;
10841190
10851191    StartDrawing (renderer );
10861192
@@ -1096,6 +1202,21 @@ static bool PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
10961202    }
10971203    SDL_memcpy (gpumem , vertices , vertsize );
10981204
1205+     if  (!data -> boundTarget ) {
1206+         SDL_GetWindowSizeInPixels (renderer -> window , & w , & h );
1207+     } else  {
1208+         PSP_TextureData  * psp_texture  =  (PSP_TextureData  * )data -> boundTarget -> internal ;
1209+         w  =  psp_texture -> width ;
1210+         h  =  psp_texture -> height ;
1211+     }
1212+ 
1213+     if  ((w  !=  data -> drawstate .drawablew ) ||  (h  !=  data -> drawstate .drawableh )) {
1214+         data -> drawstate .viewport_dirty  =  true; // if the window dimensions changed, invalidate the current viewport, etc. 
1215+         data -> drawstate .cliprect_dirty  =  true;
1216+         data -> drawstate .drawablew  =  w ;
1217+         data -> drawstate .drawableh  =  h ;
1218+     }
1219+ 
10991220    while  (cmd ) {
11001221        switch  (cmd -> command ) {
11011222        case  SDL_RENDERCMD_SETDRAWCOLOR :
@@ -1104,28 +1225,48 @@ static bool PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
11041225            const  Uint8  g  =  (Uint8 )SDL_roundf (SDL_clamp (cmd -> data .color .color .g  *  cmd -> data .color .color_scale , 0.0f , 1.0f ) *  255.0f );
11051226            const  Uint8  b  =  (Uint8 )SDL_roundf (SDL_clamp (cmd -> data .color .color .b  *  cmd -> data .color .color_scale , 0.0f , 1.0f ) *  255.0f );
11061227            const  Uint8  a  =  (Uint8 )SDL_roundf (SDL_clamp (cmd -> data .color .color .a , 0.0f , 1.0f ) *  255.0f );
1107-             drawstate .color  =  GU_RGBA (r , g , b , a );
1228+             data -> drawstate .color  =  GU_RGBA (r , g , b , a );
11081229            break ;
11091230        }
11101231
11111232        case  SDL_RENDERCMD_SETVIEWPORT :
11121233        {
1113-             SDL_Rect  * viewport  =  & cmd -> data .viewport .rect ;
1114-             sceGuOffset (2048  -  (viewport -> w  >> 1 ), 2048  -  (viewport -> h  >> 1 ));
1115-             sceGuViewport (2048 , 2048 , viewport -> w , viewport -> h );
1116-             sceGuScissor (viewport -> x , viewport -> y , viewport -> w , viewport -> h );
1117-             // FIXME: We need to update the clip rect too, see https://github.com/libsdl-org/SDL/issues/9094 
1234+             SDL_Rect  * viewport  =  & data -> drawstate .viewport ;
1235+             if  (SDL_memcmp (viewport , & cmd -> data .viewport .rect , sizeof (cmd -> data .viewport .rect )) !=  0 ) {
1236+                 SDL_copyp (viewport , & cmd -> data .viewport .rect );
1237+                 data -> drawstate .viewport_dirty  =  true;
1238+                 data -> drawstate .cliprect_dirty  =  true;
1239+                 data -> drawstate .viewport_is_set  =  viewport -> x  !=  0  ||  viewport -> y  !=  0  ||  viewport -> w  !=  data -> drawstate .drawablew  ||  viewport -> h  !=  data -> drawstate .drawableh ;
1240+                 if  (!data -> drawstate .cliprect_enabled ) {
1241+                     if  (data -> drawstate .viewport_is_set ) {
1242+                         SDL_copyp (& data -> drawstate .cliprect , viewport );
1243+                         data -> drawstate .cliprect .x  =  0 ;
1244+                         data -> drawstate .cliprect .y  =  0 ;
1245+                     } else  {
1246+                         data -> drawstate .cliprect_enabled_dirty  =  true;
1247+                     }
1248+                 }
1249+             }
11181250            break ;
11191251        }
11201252
11211253        case  SDL_RENDERCMD_SETCLIPRECT :
11221254        {
11231255            const  SDL_Rect  * rect  =  & cmd -> data .cliprect .rect ;
1124-             if  (cmd -> data .cliprect .enabled ) {
1125-                 sceGuEnable (GU_SCISSOR_TEST );
1126-                 sceGuScissor (rect -> x , rect -> y , rect -> w , rect -> h );
1127-             } else  {
1128-                 sceGuDisable (GU_SCISSOR_TEST );
1256+             const  SDL_Rect  * viewport  =  & data -> drawstate .viewport ;
1257+             if  (data -> drawstate .cliprect_enabled  !=  cmd -> data .cliprect .enabled ) {
1258+                 data -> drawstate .cliprect_enabled  =  cmd -> data .cliprect .enabled ;
1259+                 data -> drawstate .cliprect_enabled_dirty  =  true;
1260+                 if  (!data -> drawstate .cliprect_enabled  &&  data -> drawstate .viewport_is_set ) {
1261+                     SDL_copyp (& data -> drawstate .cliprect , viewport );
1262+                     data -> drawstate .cliprect .x  =  0 ;
1263+                     data -> drawstate .cliprect .y  =  0 ;
1264+                 }
1265+             }
1266+ 
1267+             if  (SDL_memcmp (& data -> drawstate .cliprect , rect , sizeof (* rect )) !=  0 ) {
1268+                 SDL_copyp (& data -> drawstate .cliprect , rect );
1269+                 data -> drawstate .cliprect_dirty  =  true;
11291270            }
11301271            break ;
11311272        }
@@ -1145,16 +1286,18 @@ static bool PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
11451286        case  SDL_RENDERCMD_DRAW_POINTS :
11461287        {
11471288            const  size_t  count  =  cmd -> data .draw .count ;
1148-             const  VertV  * verts  =  (VertV  * )(gpumem  +  cmd -> data .draw .first );
1289+             const  VertV  * verts ;  //  = (VertV *)(gpumem + cmd->data.draw.first);
11491290            PSP_BlendState  state  =  {
1150-                 .color  =  drawstate .color ,
1291+                 .color  =  data -> drawstate .color ,
11511292                .texture  =  NULL ,
11521293                .texture_scale_mode  =  SDL_SCALEMODE_INVALID ,
11531294                .texture_address_mode_u  =  SDL_TEXTURE_ADDRESS_INVALID ,
11541295                .texture_address_mode_v  =  SDL_TEXTURE_ADDRESS_INVALID ,
11551296                .mode  =  cmd -> data .draw .blend ,
11561297                .shadeModel  =  GU_FLAT 
11571298            };
1299+             SetDrawState (data );
1300+             verts  =  PSP_GetVertV (& data -> drawstate , gpumem , cmd , count );
11581301            PSP_SetBlendState (data , & state );
11591302            sceGuDrawArray (GU_POINTS , GU_VERTEX_32BITF  | GU_TRANSFORM_2D , count , 0 , verts );
11601303            break ;
@@ -1163,16 +1306,18 @@ static bool PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
11631306        case  SDL_RENDERCMD_DRAW_LINES :
11641307        {
11651308            const  size_t  count  =  cmd -> data .draw .count ;
1166-             const  VertV  * verts  =  (VertV  * )(gpumem  +  cmd -> data .draw .first );
1309+             const  VertV  * verts ;  //  = (VertV *)(gpumem + cmd->data.draw.first);
11671310            PSP_BlendState  state  =  {
1168-                 .color  =  drawstate .color ,
1311+                 .color  =  data -> drawstate .color ,
11691312                .texture  =  NULL ,
11701313                .texture_scale_mode  =  SDL_SCALEMODE_INVALID ,
11711314                .texture_address_mode_u  =  SDL_TEXTURE_ADDRESS_INVALID ,
11721315                .texture_address_mode_v  =  SDL_TEXTURE_ADDRESS_INVALID ,
11731316                .mode  =  cmd -> data .draw .blend ,
11741317                .shadeModel  =  GU_FLAT 
11751318            };
1319+             SetDrawState (data );
1320+             verts  =  PSP_GetVertV (& data -> drawstate , gpumem , cmd , count );
11761321            PSP_SetBlendState (data , & state );
11771322            sceGuDrawArray (GU_LINE_STRIP , GU_VERTEX_32BITF  | GU_TRANSFORM_2D , count , 0 , verts );
11781323            break ;
@@ -1181,16 +1326,18 @@ static bool PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
11811326        case  SDL_RENDERCMD_FILL_RECTS :
11821327        {
11831328            const  size_t  count  =  cmd -> data .draw .count ;
1184-             const  VertV  * verts  =  (VertV  * )(gpumem  +  cmd -> data .draw .first );
1329+             const  VertV  * verts ;  //  = (VertV *)(gpumem + cmd->data.draw.first);
11851330            PSP_BlendState  state  =  {
1186-                 .color  =  drawstate .color ,
1331+                 .color  =  data -> drawstate .color ,
11871332                .texture  =  NULL ,
11881333                .texture_scale_mode  =  SDL_SCALEMODE_INVALID ,
11891334                .texture_address_mode_u  =  SDL_TEXTURE_ADDRESS_INVALID ,
11901335                .texture_address_mode_v  =  SDL_TEXTURE_ADDRESS_INVALID ,
11911336                .mode  =  cmd -> data .draw .blend ,
11921337                .shadeModel  =  GU_FLAT 
11931338            };
1339+             SetDrawState (data );
1340+             verts  =  PSP_GetVertV (& data -> drawstate , gpumem , cmd , 2  *  count );
11941341            PSP_SetBlendState (data , & state );
11951342            sceGuDrawArray (GU_SPRITES , GU_VERTEX_32BITF  | GU_TRANSFORM_2D , 2  *  count , 0 , verts );
11961343            break ;
@@ -1199,33 +1346,37 @@ static bool PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
11991346        case  SDL_RENDERCMD_COPY :
12001347        {
12011348            const  size_t  count  =  cmd -> data .draw .count ;
1202-             const  VertTV  * verts  =  (VertTV  * )(gpumem  +  cmd -> data .draw .first );
1349+             const  VertTV  * verts ;  //  = (VertTV *)(gpumem + cmd->data.draw.first);
12031350            PSP_BlendState  state  =  {
1204-                 .color  =  drawstate .color ,
1351+                 .color  =  data -> drawstate .color ,
12051352                .texture  =  cmd -> data .draw .texture ,
12061353                .texture_scale_mode  =  cmd -> data .draw .texture_scale_mode ,
12071354                .texture_address_mode_u  =  cmd -> data .draw .texture_address_mode_u ,
12081355                .texture_address_mode_v  =  cmd -> data .draw .texture_address_mode_v ,
12091356                .mode  =  cmd -> data .draw .blend ,
12101357                .shadeModel  =  GU_SMOOTH 
12111358            };
1359+             SetDrawState (data );
1360+             verts  =  PSP_GetVertTV (& data -> drawstate , gpumem , cmd , 2  *  count );
12121361            PSP_SetBlendState (data , & state );
12131362            sceGuDrawArray (GU_SPRITES , GU_TEXTURE_32BITF  | GU_VERTEX_32BITF  | GU_TRANSFORM_2D , 2  *  count , 0 , verts );
12141363            break ;
12151364        }
12161365
12171366        case  SDL_RENDERCMD_COPY_EX :
12181367        {
1219-             const  VertTV  * verts  =  (VertTV  * )(gpumem  +  cmd -> data .draw .first );
1368+             const  VertTV  * verts ;  //  = (VertTV *)(gpumem + cmd->data.draw.first);
12201369            PSP_BlendState  state  =  {
1221-                 .color  =  drawstate .color ,
1370+                 .color  =  data -> drawstate .color ,
12221371                .texture  =  cmd -> data .draw .texture ,
12231372                .texture_scale_mode  =  cmd -> data .draw .texture_scale_mode ,
12241373                .texture_address_mode_u  =  cmd -> data .draw .texture_address_mode_u ,
12251374                .texture_address_mode_v  =  cmd -> data .draw .texture_address_mode_v ,
12261375                .mode  =  cmd -> data .draw .blend ,
12271376                .shadeModel  =  GU_SMOOTH 
12281377            };
1378+             SetDrawState (data );
1379+             verts  =  PSP_GetVertTV (& data -> drawstate , gpumem , cmd , 4 );
12291380            PSP_SetBlendState (data , & state );
12301381            sceGuDrawArray (GU_TRIANGLE_FAN , GU_TEXTURE_32BITF  | GU_VERTEX_32BITF  | GU_TRANSFORM_2D , 4 , 0 , verts );
12311382            break ;
@@ -1234,23 +1385,25 @@ static bool PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
12341385        case  SDL_RENDERCMD_GEOMETRY :
12351386        {
12361387            const  size_t  count  =  cmd -> data .draw .count ;
1388+             SetDrawState (data );
12371389            if  (!cmd -> data .draw .texture ) {
1238-                 const  VertCV  * verts  =  ( VertCV   * )( gpumem   +   cmd -> data . draw . first );
1390+                 const  VertCV  * verts  =  PSP_GetVertCV ( & data -> drawstate ,  gpumem ,  cmd ,  count );
12391391                sceGuDisable (GU_TEXTURE_2D );
12401392                // In GU_SMOOTH mode 
12411393                sceGuDrawArray (GU_TRIANGLES , GU_COLOR_8888  | GU_VERTEX_32BITF  | GU_TRANSFORM_2D , count , 0 , verts );
12421394                sceGuEnable (GU_TEXTURE_2D );
12431395            } else  {
1244-                 const  VertTCV  * verts  =  (VertTCV  * )(gpumem  +  cmd -> data .draw .first );
1396+                 const  VertTCV  * verts ;  //  = (VertTCV *)(gpumem + cmd->data.draw.first);
12451397                PSP_BlendState  state  =  {
1246-                     .color  =  drawstate .color ,
1398+                     .color  =  data -> drawstate .color ,
12471399                    .texture  =  cmd -> data .draw .texture ,
12481400                    .texture_scale_mode  =  cmd -> data .draw .texture_scale_mode ,
12491401                    .texture_address_mode_u  =  cmd -> data .draw .texture_address_mode_u ,
12501402                    .texture_address_mode_v  =  cmd -> data .draw .texture_address_mode_v ,
12511403                    .mode  =  cmd -> data .draw .blend ,
12521404                    .shadeModel  =  GU_SMOOTH 
12531405                };
1406+                 verts  =  PSP_GetVertTCV (& data -> drawstate , gpumem , cmd , count );
12541407                PSP_SetBlendState (data , & state );
12551408                sceGuDrawArray (GU_TRIANGLES , GU_TEXTURE_32BITF  | GU_COLOR_8888  | GU_VERTEX_32BITF  | GU_TRANSFORM_2D , count , 0 , verts );
12561409            }
0 commit comments