21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_RENDER_PSP
27 #include "../SDL_sysrender.h"
29 #include <pspkernel.h>
30 #include <pspdisplay.h>
46 #define PSP_SCREEN_WIDTH 480
47 #define PSP_SCREEN_HEIGHT 272
49 #define PSP_FRAME_BUFFER_WIDTH 512
50 #define PSP_FRAME_BUFFER_SIZE (PSP_FRAME_BUFFER_WIDTH*PSP_SCREEN_HEIGHT)
52 static unsigned int __attribute__((aligned(16))) DisplayList[262144];
55 #define COL5650(r,g,b,a) ((r>>3) | ((g>>2)<<5) | ((b>>3)<<11))
56 #define COL5551(r,g,b,a) ((r>>3) | ((g>>3)<<5) | ((b>>3)<<10) | (a>0?0x7000:0))
57 #define COL4444(r,g,b,a) ((r>>4) | ((g>>4)<<4) | ((b>>4)<<8) | ((a>>4)<<12))
58 #define COL8888(r,g,b,a) ((r) | ((g)<<8) | ((b)<<16) | ((a)<<24))
71 unsigned int currentColor;
83 unsigned int textureWidth;
84 unsigned int textureHeight;
105 #define PI 3.14159265358979f
107 #define radToDeg(x) ((x)*180.f/PI)
108 #define degToRad(x) ((x)*PI/180.f)
110 float MathAbs(
float x)
116 "vabs.s S000, S000\n"
123 void MathSincos(
float r,
float *
s,
float *
c)
127 "vcst.s S003, VFPU_2_PI\n"
128 "vmul.s S002, S002, S003\n"
129 "vrot.p C000, S002, [s, c]\n"
132 :
"=r"(*s),
"=r"(*c):
"r"(
r));
135 void Swap(
float *
a,
float *
b)
144 TextureNextPow2(
unsigned int w)
179 if(
data->displayListAvail)
182 sceGuStart(GU_DIRECT, DisplayList);
188 TextureSwizzle(PSP_TextureData *psp_texture)
190 if(psp_texture->swizzled)
193 int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
194 int height = psp_texture->size / bytewidth;
196 int rowblocks = (bytewidth>>4);
197 int rowblocksadd = (rowblocks-1)<<7;
198 unsigned int blockaddress = 0;
199 unsigned int *
src = (
unsigned int*) psp_texture->data;
206 for(
j = 0;
j <
height;
j++, blockaddress += 16)
210 block = (
unsigned int*)&
data[blockaddress];
214 for(
i = 0;
i < rowblocks;
i++)
224 blockaddress += rowblocksadd;
227 free(psp_texture->data);
228 psp_texture->data =
data;
233 int TextureUnswizzle(PSP_TextureData *psp_texture)
235 if(!psp_texture->swizzled)
240 int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
241 int height = psp_texture->size / bytewidth;
243 int widthblocks = bytewidth/16;
244 int heightblocks =
height/8;
246 int dstpitch = (bytewidth - 16)/4;
247 int dstrow = bytewidth * 8;
249 unsigned int *
src = (
unsigned int*) psp_texture->data;
258 sceKernelDcacheWritebackAll();
262 unsigned char *ydst = (
unsigned char *)
data;
264 for(blocky = 0; blocky < heightblocks; ++blocky)
266 unsigned char *xdst = ydst;
268 for(blockx = 0; blockx < widthblocks; ++blockx)
272 block = (
unsigned int*)xdst;
274 for(
j = 0;
j < 8; ++
j)
276 *(block++) = *(
src++);
277 *(block++) = *(
src++);
278 *(block++) = *(
src++);
279 *(block++) = *(
src++);
289 free(psp_texture->data);
291 psp_texture->data =
data;
308 PSP_TextureData* psp_texture = (PSP_TextureData*)
SDL_calloc(1,
sizeof(*psp_texture));
314 psp_texture->width =
texture->w;
315 psp_texture->height =
texture->h;
316 psp_texture->textureHeight = TextureNextPow2(
texture->h);
317 psp_texture->textureWidth = TextureNextPow2(
texture->w);
318 psp_texture->format = PixelFormatToPSPFMT(
texture->format);
320 switch(psp_texture->format)
325 psp_texture->bits = 16;
329 psp_texture->bits = 32;
337 psp_texture->size = psp_texture->textureHeight*psp_texture->pitch;
338 psp_texture->data =
SDL_calloc(1, psp_texture->size);
340 if(!psp_texture->data)
345 texture->driverdata = psp_texture;
359 PSP_TextureData *psp_texture = (PSP_TextureData *)
texture->driverdata;
365 TextureSwizzle(psp_texture);
368 sceGuEnable(GU_TEXTURE_2D);
369 sceGuTexWrap(GU_REPEAT, GU_REPEAT);
370 sceGuTexMode(psp_texture->format, 0, 0, psp_texture->swizzled);
371 sceGuTexFilter(scaleMode, scaleMode);
373 sceGuTexImage(0, psp_texture->textureWidth, psp_texture->textureHeight, psp_texture->textureWidth, psp_texture->data);
374 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
400 sceKernelDcacheWritebackAll();
408 PSP_TextureData *psp_texture = (PSP_TextureData *)
texture->driverdata;
411 (
void *) ((
Uint8 *) psp_texture->data +
rect->
y * psp_texture->pitch +
413 *pitch = psp_texture->pitch;
420 PSP_TextureData *psp_texture = (PSP_TextureData *)
texture->driverdata;
502 const float x = dstrect->
x;
503 const float y = dstrect->
y;
504 const float width = dstrect->
w;
505 const float height = dstrect->
h;
507 const float u0 = srcrect->
x;
508 const float v0 = srcrect->
y;
509 const float u1 = srcrect->
x + srcrect->
w;
510 const float v1 = srcrect->
y + srcrect->
h;
512 if((MathAbs(
u1) - MathAbs(u0)) < 64.0
f)
540 const float endX =
x +
width;
541 const float slice = 64.0f;
544 float ustep = (
u1 - u0)/
width * slice;
559 const float polyWidth = ((curX + slice) > endX) ? (endX - curX) : slice;
560 const float sourceWidth = ((curU + ustep) >
u1) ? (
u1 - curU) : ustep;
590 const float centerx = center->
x;
591 const float centery = center->
y;
592 const float x = dstrect->
x + centerx;
593 const float y = dstrect->
y + centery;
594 const float width = dstrect->
w - centerx;
595 const float height = dstrect->
h - centery;
598 float u0 = srcrect->
x;
599 float v0 = srcrect->
y;
600 float u1 = srcrect->
x + srcrect->
w;
601 float v1 = srcrect->
y + srcrect->
h;
610 MathSincos(degToRad(
angle), &
s, &
c);
612 const float cw =
c *
width;
613 const float sw =
s *
width;
627 verts->x =
x - cw + sh;
628 verts->y =
y - sw - ch;
634 verts->x =
x - cw - sh;
635 verts->y =
y - sw + ch;
641 verts->x =
x + cw - sh;
642 verts->y =
y + sw + ch;
648 verts->x =
x + cw + sh;
649 verts->y =
y + sw - ch;
663 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
664 sceGuDisable(GU_BLEND);
667 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
668 sceGuEnable(GU_BLEND);
669 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );
672 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
673 sceGuEnable(GU_BLEND);
674 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF );
677 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
678 sceGuEnable(GU_BLEND);
679 sceGuBlendFunc(GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
682 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
683 sceGuEnable(GU_BLEND);
684 sceGuBlendFunc(GU_ADD, GU_DST_COLOR, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
705 Uint8 *gpumem = (
Uint8 *) sceGuGetMemory(vertsize);
707 return SDL_SetError(
"Couldn't obtain a %d-byte vertex buffer!", (
int) vertsize);
746 sceGuClearColor(
color);
748 sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT|GU_FAST_CLEAR_BIT);
754 const VertV *verts = (VertV *) (gpumem + cmd->
data.
draw.first);
762 sceGuDisable(GU_TEXTURE_2D);
763 sceGuShadeModel(GU_FLAT);
764 sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF|GU_TRANSFORM_2D,
count, 0, verts);
765 sceGuShadeModel(GU_SMOOTH);
766 sceGuEnable(GU_TEXTURE_2D);
772 const VertV *verts = (VertV *) (gpumem + cmd->
data.
draw.first);
780 sceGuDisable(GU_TEXTURE_2D);
781 sceGuShadeModel(GU_FLAT);
782 sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF|GU_TRANSFORM_2D,
count, 0, verts);
783 sceGuShadeModel(GU_SMOOTH);
784 sceGuEnable(GU_TEXTURE_2D);
790 const VertV *verts = (VertV *) (gpumem + cmd->
data.
draw.first);
798 sceGuDisable(GU_TEXTURE_2D);
799 sceGuShadeModel(GU_FLAT);
800 sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2 *
count, 0, verts);
801 sceGuShadeModel(GU_SMOOTH);
802 sceGuEnable(GU_TEXTURE_2D);
808 const VertTV *verts = (VertTV *) (gpumem + cmd->
data.
draw.first);
810 TextureActivate(cmd->
data.
draw.texture);
814 sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
815 sceGuColor(GU_RGBA(255, 255, 255,
alpha));
817 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
818 sceGuColor(0xFFFFFFFF);
821 sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2 *
count, 0, verts);
824 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
830 const VertTV *verts = (VertTV *) (gpumem + cmd->
data.
draw.first);
832 TextureActivate(cmd->
data.
draw.texture);
836 sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
837 sceGuColor(GU_RGBA(255, 255, 255,
alpha));
839 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
840 sceGuColor(0xFFFFFFFF);
843 sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, verts);
846 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
872 if(!
data->displayListAvail)
880 sceDisplayWaitVblankStart();
882 data->backbuffer =
data->frontbuffer;
883 data->frontbuffer = vabsptr(sceGuSwapBuffers());
891 PSP_TextureData *psp_texture = (PSP_TextureData *)
texture->driverdata;
909 if (!
data->initialized)
930 PSP_RenderData *
data;
948 renderer->SetTextureColorMod = PSP_SetTextureColorMod;
987 data->frontbuffer = (
unsigned int *)(PSP_FRAME_BUFFER_SIZE<<1);
988 data->backbuffer = (
unsigned int *)(0);
990 data->psm = pixelformat;
993 data->frontbuffer = (
unsigned int *)(PSP_FRAME_BUFFER_SIZE<<2);
994 data->backbuffer = (
unsigned int *)(0);
996 data->psm = GU_PSM_8888;
1002 sceGuStart(GU_DIRECT, DisplayList);
1003 sceGuDrawBuffer(
data->psm,
data->frontbuffer, PSP_FRAME_BUFFER_WIDTH);
1004 sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT,
data->backbuffer, PSP_FRAME_BUFFER_WIDTH);
1007 sceGuOffset(2048 - (PSP_SCREEN_WIDTH>>1), 2048 - (PSP_SCREEN_HEIGHT>>1));
1008 sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
1010 data->frontbuffer = vabsptr(
data->frontbuffer);
1011 data->backbuffer = vabsptr(
data->backbuffer);
1014 sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
1015 sceGuEnable(GU_SCISSOR_TEST);
1018 sceGuFrontFace(GU_CCW);
1019 sceGuEnable(GU_CULL_FACE);
1022 sceGuEnable(GU_TEXTURE_2D);
1023 sceGuShadeModel(GU_SMOOTH);
1024 sceGuTexWrap(GU_REPEAT, GU_REPEAT);
1027 sceGuEnable(GU_BLEND);
1028 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
1030 sceGuTexFilter(GU_LINEAR,GU_LINEAR);
1034 sceDisplayWaitVblankStartCB();
1035 sceGuDisplay(GU_TRUE);
1045 .num_texture_formats = 4,
1051 .max_texture_width = 512,
1052 .max_texture_height = 512,