Code: Select all
#include <pspkernel.h>
unsigned short __attribute__((aligned(16))) pixels[SPRITE_HEIGHT*SPRITE_WIDTH];
unsigned short __attribute__((aligned(16))) swizzled_pixels[SPRITE_HEIGHT*SPRITE_WIDTH];
unsigned short *pixels2;
struct Vertex
{
unsigned short u, v;
unsigned short color;
float x, y, z;
};
void advancedBlit(float sx, float sy, int sw, int sh, float dx, float dy)
{
int start, end;
// blit maximizing the use of the texture-cache
/*
the texture cache is 8kB. It is used in the following fashions:
4-bit: 128x128
8-bit: 128x64
16-bit: 64x64
32-bit: 64x32
swizzling your input will give more than 100% increase in speed
*/
for (start = sx, end = sx+sw; start < end; start += SLICE_SIZE, dx += SLICE_SIZE)
{
struct Vertex* vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex));
int width = (start + SLICE_SIZE) < end ? SLICE_SIZE : end-start;
vertices[0].u = start; vertices[0].v = sy;
vertices[0].color = 0;
vertices[0].x = dx; vertices[0].y = dy; vertices[0].z = 0;
vertices[1].u = start + width; vertices[1].v = sy + sh;
vertices[1].color = 0;
vertices[1].x = dx + width; vertices[1].y = dy + sh; vertices[1].z = 0;
sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_COLOR_5551|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,vertices);
}
}
void swizzle_fast(u8* out, const u8* in, unsigned int width, unsigned int height)
{
unsigned int blockx, blocky;
unsigned int j;
unsigned int width_blocks = (width / 16);
unsigned int height_blocks = (height / 8);
unsigned int src_pitch = (width-16)/4;
unsigned int src_row = width * 8;
const u8* ysrc = in;
u32* dst = (u32*)out;
for (blocky = 0; blocky < height_blocks; ++blocky)
{
const u8* xsrc = ysrc;
for (blockx = 0; blockx < width_blocks; ++blockx)
{
const u32* src = (u32*)xsrc;
for (j = 0; j < 8; ++j)
{
*(dst++) = *(src++);
*(dst++) = *(src++);
*(dst++) = *(src++);
*(dst++) = *(src++);
src += src_pitch;
}
xsrc += 16;
}
ysrc += src_row;
}
}
void InitGFX()
{
sceGuInit();
// setup
sceGuStart(GU_DIRECT,list);
sceGuDrawBuffer(GU_PSM_5551,(void*)0,512);
sceGuDispBuffer(480,272,(void*)0x44000,512);
sceGuDepthBuffer((void*)0x88000,512);
sceGuOffset(2048 - (480/2),2048 - (272/2));
sceGuViewport(2048,2048,480,272);
sceGuDepthRange(0xc350,0x2710);
sceGuScissor(0,0,480,272);
sceGuEnable(GU_SCISSOR_TEST);
sceGuFrontFace(GU_CW);
sceGuEnable(GU_TEXTURE_2D);
sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
sceGuFinish();
sceGuSync(0,0);
sceDisplayWaitVblankStart();
sceGuDisplay(1);
}
int main(int argc, char* argv[])
{
float x = 0,y = 0;
int i;
pspDebugScreenInit();
SetupCallbacks();
InitGFX();
for(i=0;i<SPRITE_WIDTH*SPRITE_HEIGHT;i++){
pixels[i] = 0xFC00;
}
swizzle_fast((u8*)swizzled_pixels,(const u8*)pixels,SPRITE_WIDTH*2,SPRITE_HEIGHT);
// 512*2 because swizzle operates in bytes, and each pixel in a 16-bit texture is 2 bytes
sceGuCopyImage(GU_PSM_5551,0,0,SPRITE_WIDTH,SPRITE_HEIGHT,SPRITE_WIDTH,swizzled_pixels,0,0,SPRITE_WIDTH,(sceGeEdramGetAddr()+512*272*2*3));
pixels2 = sceGeEdramGetAddr()+512*272*2*3;
sceKernelDcacheWritebackAll();
while (!done)
{
SceCtrlData pad;
sceCtrlReadBufferPositive(&pad, 1);
if((pad.Buttons & PSP_CTRL_RIGHT) && x<479-SPRITE_WIDTH)x+=2;
if((pad.Buttons & PSP_CTRL_LEFT) && x>1)x-=2;
if((pad.Buttons & PSP_CTRL_UP) && y>1)y-=2;
if((pad.Buttons & PSP_CTRL_DOWN) && y<271-SPRITE_HEIGHT)y+=2;
sceGuStart(GU_DIRECT,list);
sceGuTexMode(GU_PSM_5551,0,0,1); // 16-bit RGBA
sceGuTexImage(0,SPRITE_WIDTH,SPRITE_HEIGHT,SPRITE_WIDTH,pixels2);
sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGBA); // don't get influenced by any vertex colors
sceGuTexFilter(GU_NEAREST,GU_NEAREST); // point-filtered sampling
sceGuClearColor(0);
sceGuClear(GU_COLOR_BUFFER_BIT | GU_STENCIL_BUFFER_BIT);
advancedBlit(0,0,SPRITE_WIDTH,SPRITE_HEIGHT,x,y);
sceGuFinish();
sceGuSync(0,0);
// sceDisplayWaitVblankStart();
sceGuSwapBuffers();
}
sceGuTerm();
sceKernelExitGame();
return 0;
}