21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_RENDER_PSP
26 #include "../SDL_sysrender.h"
28 #include <pspkernel.h>
29 #include <pspdisplay.h>
102 .num_texture_formats = 4,
108 .max_texture_width = 512,
109 .max_texture_height = 512,
113 #define PSP_SCREEN_WIDTH 480
114 #define PSP_SCREEN_HEIGHT 272
116 #define PSP_FRAME_BUFFER_WIDTH 512
117 #define PSP_FRAME_BUFFER_SIZE (PSP_FRAME_BUFFER_WIDTH*PSP_SCREEN_HEIGHT)
119 static unsigned int __attribute__((aligned(16))) DisplayList[262144];
122 #define COL5650(r,g,b,a) ((r>>3) | ((g>>2)<<5) | ((b>>3)<<11))
123 #define COL5551(r,g,b,a) ((r>>3) | ((g>>3)<<5) | ((b>>3)<<10) | (a>0?0x7000:0))
124 #define COL4444(r,g,b,a) ((r>>4) | ((g>>4)<<4) | ((b>>4)<<8) | ((a>>4)<<12))
125 #define COL8888(r,g,b,a) ((r) | ((g)<<8) | ((b)<<16) | ((a)<<24))
138 unsigned int currentColor;
139 int currentBlendMode;
150 unsigned int textureWidth;
151 unsigned int textureHeight;
175 TextureNextPow2(
unsigned int w)
210 if(
data->displayListAvail)
213 sceGuStart(GU_DIRECT, DisplayList);
219 TextureSwizzle(PSP_TextureData *psp_texture)
221 if(psp_texture->swizzled)
224 int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
225 int height = psp_texture->size / bytewidth;
227 int rowblocks = (bytewidth>>4);
228 int rowblocksadd = (rowblocks-1)<<7;
229 unsigned int blockaddress = 0;
230 unsigned int *
src = (
unsigned int*) psp_texture->data;
237 for(
j = 0;
j <
height;
j++, blockaddress += 16)
241 block = (
unsigned int*)&
data[blockaddress];
245 for(
i = 0;
i < rowblocks;
i++)
255 blockaddress += rowblocksadd;
258 free(psp_texture->data);
259 psp_texture->data =
data;
264 int TextureUnswizzle(PSP_TextureData *psp_texture)
266 if(!psp_texture->swizzled)
271 int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
272 int height = psp_texture->size / bytewidth;
274 int widthblocks = bytewidth/16;
275 int heightblocks =
height/8;
277 int dstpitch = (bytewidth - 16)/4;
278 int dstrow = bytewidth * 8;
280 unsigned int *
src = (
unsigned int*) psp_texture->data;
289 sceKernelDcacheWritebackAll();
293 unsigned char *ydst = (
unsigned char *)
data;
295 for(blocky = 0; blocky < heightblocks; ++blocky)
297 unsigned char *xdst = ydst;
299 for(blockx = 0; blockx < widthblocks; ++blockx)
303 block = (
unsigned int*)xdst;
305 for(
j = 0;
j < 8; ++
j)
307 *(block++) = *(
src++);
308 *(block++) = *(
src++);
309 *(block++) = *(
src++);
310 *(block++) = *(
src++);
320 free(psp_texture->data);
322 psp_texture->data =
data;
334 PSP_RenderData *
data;
389 data->frontbuffer = (
unsigned int *)(PSP_FRAME_BUFFER_SIZE<<1);
390 data->backbuffer = (
unsigned int *)(0);
392 data->psm = pixelformat;
395 data->frontbuffer = (
unsigned int *)(PSP_FRAME_BUFFER_SIZE<<2);
396 data->backbuffer = (
unsigned int *)(0);
398 data->psm = GU_PSM_8888;
404 sceGuStart(GU_DIRECT, DisplayList);
405 sceGuDrawBuffer(
data->psm,
data->frontbuffer, PSP_FRAME_BUFFER_WIDTH);
406 sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT,
data->backbuffer, PSP_FRAME_BUFFER_WIDTH);
409 sceGuOffset(2048 - (PSP_SCREEN_WIDTH>>1), 2048 - (PSP_SCREEN_HEIGHT>>1));
410 sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
412 data->frontbuffer = vabsptr(
data->frontbuffer);
413 data->backbuffer = vabsptr(
data->backbuffer);
416 sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
417 sceGuEnable(GU_SCISSOR_TEST);
420 sceGuFrontFace(GU_CCW);
421 sceGuEnable(GU_CULL_FACE);
424 sceGuEnable(GU_TEXTURE_2D);
425 sceGuShadeModel(GU_SMOOTH);
426 sceGuTexWrap(GU_REPEAT, GU_REPEAT);
429 sceGuEnable(GU_BLEND);
430 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
432 sceGuTexFilter(GU_LINEAR,GU_LINEAR);
436 sceDisplayWaitVblankStartCB();
437 sceGuDisplay(GU_TRUE);
453 PSP_TextureData* psp_texture = (PSP_TextureData*)
SDL_calloc(1,
sizeof(*psp_texture));
459 psp_texture->width =
texture->w;
460 psp_texture->height =
texture->h;
461 psp_texture->textureHeight = TextureNextPow2(
texture->h);
462 psp_texture->textureWidth = TextureNextPow2(
texture->w);
463 psp_texture->format = PixelFormatToPSPFMT(
texture->format);
465 switch(psp_texture->format)
470 psp_texture->bits = 16;
474 psp_texture->bits = 32;
482 psp_texture->size = psp_texture->textureHeight*psp_texture->pitch;
483 psp_texture->data =
SDL_calloc(1, psp_texture->size);
485 if(!psp_texture->data)
490 texture->driverdata = psp_texture;
504 PSP_TextureData *psp_texture = (PSP_TextureData *)
texture->driverdata;
510 TextureSwizzle(psp_texture);
513 sceGuEnable(GU_TEXTURE_2D);
514 sceGuTexWrap(GU_REPEAT, GU_REPEAT);
515 sceGuTexMode(psp_texture->format, 0, 0, psp_texture->swizzled);
516 sceGuTexFilter(scaleMode, scaleMode);
518 sceGuTexImage(0, psp_texture->textureWidth, psp_texture->textureHeight, psp_texture->textureWidth, psp_texture->data);
519 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
545 sceKernelDcacheWritebackAll();
553 PSP_TextureData *psp_texture = (PSP_TextureData *)
texture->driverdata;
556 (
void *) ((
Uint8 *) psp_texture->data +
rect->
y * psp_texture->pitch +
558 *pitch = psp_texture->pitch;
565 PSP_TextureData *psp_texture = (PSP_TextureData *)
texture->driverdata;
598 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
599 sceGuDisable(GU_BLEND);
602 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
603 sceGuEnable(GU_BLEND);
604 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );
607 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
608 sceGuEnable(GU_BLEND);
609 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF );
612 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
613 sceGuEnable(GU_BLEND);
614 sceGuBlendFunc( GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
629 sceGuClearColor(
color);
631 sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT|GU_FAST_CLEAR_BIT);
643 VertV* vertices = (VertV*)sceGuGetMemory(
count*
sizeof(VertV));
648 vertices[
i].z = 0.0f;
650 sceGuDisable(GU_TEXTURE_2D);
652 sceGuShadeModel(GU_FLAT);
653 sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF|GU_TRANSFORM_2D,
count, 0, vertices);
654 sceGuShadeModel(GU_SMOOTH);
655 sceGuEnable(GU_TEXTURE_2D);
667 VertV* vertices = (VertV*)sceGuGetMemory(
count*
sizeof(VertV));
672 vertices[
i].z = 0.0f;
675 sceGuDisable(GU_TEXTURE_2D);
677 sceGuShadeModel(GU_FLAT);
678 sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF|GU_TRANSFORM_2D,
count, 0, vertices);
679 sceGuShadeModel(GU_SMOOTH);
680 sceGuEnable(GU_TEXTURE_2D);
695 VertV* vertices = (VertV*)sceGuGetMemory((
sizeof(VertV)<<1));
697 vertices[0].y =
rect->
y;
698 vertices[0].z = 0.0f;
702 vertices[1].z = 0.0f;
704 sceGuDisable(GU_TEXTURE_2D);
706 sceGuShadeModel(GU_FLAT);
707 sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
708 sceGuShadeModel(GU_SMOOTH);
709 sceGuEnable(GU_TEXTURE_2D);
716 #define PI 3.14159265358979f
718 #define radToDeg(x) ((x)*180.f/PI)
719 #define degToRad(x) ((x)*PI/180.f)
721 float MathAbs(
float x)
727 "vabs.s S000, S000\n"
734 void MathSincos(
float r,
float *
s,
float *
c)
738 "vcst.s S003, VFPU_2_PI\n"
739 "vmul.s S002, S002, S003\n"
740 "vrot.p C000, S002, [s, c]\n"
743 :
"=r"(*s),
"=r"(*c):
"r"(
r));
746 void Swap(
float *
a,
float *
b)
768 u1 = srcrect->
x + srcrect->
w;
769 v1 = srcrect->
y + srcrect->
h;
779 sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
780 sceGuColor(GU_RGBA(255, 255, 255,
alpha));
782 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
783 sceGuColor(0xFFFFFFFF);
786 if((MathAbs(
u1) - MathAbs(u0)) < 64.0
f)
788 VertTV* vertices = (VertTV*)sceGuGetMemory((
sizeof(VertTV))<<1);
798 vertices[1].x =
x +
width;
802 sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
811 float ustep = (
u1 - u0)/
width * slice;
818 VertTV* vertices = (VertTV*)sceGuGetMemory((
sizeof(VertTV))<<1);
820 float polyWidth = ((curX + slice) > endX) ? (endX - curX) : slice;
821 float sourceWidth = ((curU + ustep) >
u1) ? (
u1 - curU) : ustep;
823 vertices[0].u = curU;
825 vertices[0].x = curX;
832 vertices[1].u = curU;
834 vertices[1].x = curX;
838 sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
843 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
864 float centerx, centery;
873 u1 = srcrect->
x + srcrect->
w;
874 v1 = srcrect->
y + srcrect->
h;
887 sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
888 sceGuColor(GU_RGBA(255, 255, 255,
alpha));
890 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
891 sceGuColor(0xFFFFFFFF);
901 MathSincos(degToRad(
angle), &
s, &
c);
914 VertTV* vertices = (VertTV*)sceGuGetMemory(
sizeof(VertTV)<<2);
918 vertices[0].x =
x - cw + sh;
919 vertices[0].y =
y - sw - ch;
924 vertices[1].x =
x - cw - sh;
925 vertices[1].y =
y - sw + ch;
930 vertices[2].x =
x + cw - sh;
931 vertices[2].y =
y + sw + ch;
936 vertices[3].x =
x + cw + sh;
937 vertices[3].y =
y + sw - ch;
941 Swap(&vertices[0].
v, &vertices[2].
v);
942 Swap(&vertices[1].
v, &vertices[3].
v);
945 Swap(&vertices[0].u, &vertices[2].u);
946 Swap(&vertices[1].u, &vertices[3].u);
949 sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices);
952 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
960 if(!
data->displayListAvail)
968 sceDisplayWaitVblankStart();
970 data->backbuffer =
data->frontbuffer;
971 data->frontbuffer = vabsptr(sceGuSwapBuffers());
979 PSP_TextureData *psp_texture = (PSP_TextureData *)
texture->driverdata;
997 if (!
data->initialized)