Last active
December 20, 2015 01:29
-
-
Save Orphis/6048978 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* PSP Software Development Kit - http://www.pspdev.org | |
* ----------------------------------------------------------------------- | |
* Licensed under the BSD license, see LICENSE in PSPSDK root for details. | |
* | |
* Copyright (c) 2005 Jesper Svennevid | |
*/ | |
#include <pspkernel.h> | |
#include <pspdisplay.h> | |
#include <pspdebug.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <math.h> | |
#include <string.h> | |
#include <time.h> | |
#include <pspgu.h> | |
PSP_MODULE_INFO("Clut Sample", 0, 1, 1); | |
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER); | |
static unsigned int __attribute__((aligned(16))) list[262144]; | |
struct Vertex | |
{ | |
float u,v; | |
float x,y,z; | |
}; | |
int SetupCallbacks(); | |
#define BUF_WIDTH (512) | |
#define SCR_WIDTH (480) | |
#define SCR_HEIGHT (272) | |
#define PIXEL_SIZE (4) /* change this if you change to another screenmode */ | |
#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE) | |
#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */ | |
#define PAD1 0, | |
#define PAD2 PAD1 PAD1 | |
#define PAD4 PAD2 PAD2 | |
#define PAD8 PAD4 PAD4 | |
#define PAD12 PAD8 PAD4 | |
#define PAD14 PAD8 PAD4 PAD2 | |
#define PAD15 PAD8 PAD4 PAD2 PAD1 | |
#define PAD16 PAD8 PAD8 | |
#define PAD24 PAD16 PAD8 | |
unsigned char __attribute__((aligned(16))) tex5650[] = { | |
0x1F, 0x00, 0xE0, 0x07, PAD12 | |
0x00, 0xF8, 0xFF, 0xFF, PAD12 | |
}; | |
unsigned char __attribute__((aligned(16))) tex5551[] = { | |
0x1F, 0x80, 0xE0, 0x83, PAD12 | |
0x00, 0xFC, 0xFF, 0xFF, PAD12 | |
}; | |
unsigned char __attribute__((aligned(16))) tex4444[] = { | |
0x0F, 0xF0, 0xF0, 0xF0, PAD12 | |
0x00, 0xFF, 0xFF, 0xFF, PAD12 | |
}; | |
unsigned char __attribute__((aligned(16))) tex8888[] = { | |
0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, PAD8 | |
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PAD8 | |
}; | |
unsigned char __attribute__((aligned(16))) texclut4[] = { | |
0x10, PAD15 | |
0x32, PAD15 | |
}; | |
unsigned char __attribute__((aligned(16))) texclut8[] = { | |
0x00, 0x01, PAD14 | |
0x02, 0x03, PAD14 | |
}; | |
unsigned char __attribute__((aligned(16))) texclut16[] = { | |
0x00, 0x00, 0x01, 0x00, PAD12 | |
0x02, 0x00, 0x03, 0x00, PAD12 | |
}; | |
unsigned char __attribute__((aligned(16))) texclut32[] = { | |
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, PAD8 | |
0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, PAD8 | |
}; | |
unsigned char __attribute__((aligned(16))) clut5650[] = { | |
0x1F, 0x00, 0xE0, 0x07, 0x00, 0xF8, 0xFF, 0xFF, PAD24 | |
}; | |
unsigned char __attribute__((aligned(16))) clut5551[] = { | |
0x1F, 0x80, 0xE0, 0x83, 0x00, 0xFC, 0xFF, 0xFF, PAD24 | |
}; | |
unsigned char __attribute__((aligned(16))) clut4444[] = { | |
0x0F, 0xF0, 0xF0, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, PAD24 | |
}; | |
unsigned char __attribute__((aligned(16))) clut8888[] = { | |
0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PAD16 | |
}; | |
void drawsprite(int texfmt, int tbw, int clutfmt, unsigned char* tex, unsigned char* clut, int n) { | |
int i = n % 4; | |
int j = n / 4; | |
int sh = SCR_HEIGHT / 5; | |
int sw = SCR_WIDTH / 4; | |
if(clutfmt != -1) { | |
sceGuClutMode(clutfmt,0,0xff,0); | |
sceKernelDcacheWritebackAll(); | |
sceGuClutLoad(1,clut); // upload 32*8 entries (256) | |
} | |
sceGuTexMode(texfmt,0,0,0); | |
sceGuTexImage(0,2,2,tbw,tex); | |
sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGB); | |
sceGuTexFilter(GU_NEAREST,GU_NEAREST); | |
sceGuTexScale(1.0f,1.0f); | |
sceGuTexOffset(0.0f,0.0f); | |
sceGuAmbientColor(0xffffffff); | |
sceGuColor(0xffffffff); | |
struct Vertex* vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex)); | |
vertices[0].u = 0; vertices[0].v = 0; | |
vertices[0].x = sw * i; vertices[0].y = sh * j; vertices[0].z = 0; | |
vertices[1].u = 2; vertices[1].v = 2; | |
vertices[1].x = sw * (i + 1); vertices[1].y = sh * (j + 1); vertices[1].z = 0; | |
sceGuDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,vertices); | |
} | |
int main(int argc, char* argv[]) | |
{ | |
SetupCallbacks(); | |
sceKernelDcacheWritebackAll(); | |
// setup GU | |
sceGuInit(); | |
sceGuStart(GU_DIRECT,list); | |
sceGuDrawBuffer(GU_PSM_8888,(void*)0,BUF_WIDTH); | |
sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)FRAME_SIZE,BUF_WIDTH); | |
sceGuDepthBuffer((void*)(FRAME_SIZE*2),BUF_WIDTH); | |
sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); | |
sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); | |
sceGuDepthRange(0xc350,0x2710); | |
sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); | |
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(GU_TRUE); | |
// run sample | |
int offset = 0; | |
for(;;) | |
{ | |
sceGuStart(GU_DIRECT,list); | |
// clear screen | |
sceGuClearColor(0x808080); | |
sceGuClear(GU_COLOR_BUFFER_BIT); | |
// render sprite | |
int n = 0; | |
drawsprite(GU_PSM_5650, 8, -1, tex5650, NULL, n++); | |
drawsprite(GU_PSM_5551, 8, -1, tex5551, NULL, n++); | |
drawsprite(GU_PSM_4444, 8, -1, tex4444, NULL, n++); | |
drawsprite(GU_PSM_8888, 4, -1, tex8888, NULL, n++); | |
drawsprite(GU_PSM_T4, 32, GU_PSM_5650, texclut4, clut5650, n++); | |
drawsprite(GU_PSM_T4, 32, GU_PSM_5551, texclut4, clut5551, n++); | |
drawsprite(GU_PSM_T4, 32, GU_PSM_4444, texclut4, clut4444, n++); | |
drawsprite(GU_PSM_T4, 32, GU_PSM_8888, texclut4, clut8888, n++); | |
drawsprite(GU_PSM_T8, 16, GU_PSM_5650, texclut8, clut5650, n++); | |
drawsprite(GU_PSM_T8, 16, GU_PSM_5551, texclut8, clut5551, n++); | |
drawsprite(GU_PSM_T8, 16, GU_PSM_4444, texclut8, clut4444, n++); | |
drawsprite(GU_PSM_T8, 16, GU_PSM_8888, texclut8, clut8888, n++); | |
drawsprite(GU_PSM_T16, 8, GU_PSM_5650, texclut16, clut5650, n++); | |
drawsprite(GU_PSM_T16, 8, GU_PSM_5551, texclut16, clut5551, n++); | |
drawsprite(GU_PSM_T16, 8, GU_PSM_4444, texclut16, clut4444, n++); | |
drawsprite(GU_PSM_T16, 8, GU_PSM_8888, texclut16, clut8888, n++); | |
drawsprite(GU_PSM_T32, 4, GU_PSM_5650, texclut32, clut5650, n++); | |
drawsprite(GU_PSM_T32, 4, GU_PSM_5551, texclut32, clut5551, n++); | |
drawsprite(GU_PSM_T32, 4, GU_PSM_4444, texclut32, clut4444, n++); | |
drawsprite(GU_PSM_T32, 4, GU_PSM_8888, texclut32, clut8888, n++); | |
// wait for next frame | |
sceGuFinish(); | |
sceGuSync(0,0); | |
sceDisplayWaitVblankStart(); | |
sceGuSwapBuffers(); | |
offset++; | |
} | |
sceGuTerm(); | |
sceKernelExitGame(); | |
return 0; | |
} | |
/* Exit callback */ | |
int exit_callback(int arg1, int arg2, void *common) | |
{ | |
sceKernelExitGame(); | |
return 0; | |
} | |
/* Callback thread */ | |
int CallbackThread(SceSize args, void *argp) | |
{ | |
int cbid; | |
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL); | |
sceKernelRegisterExitCallback(cbid); | |
sceKernelSleepThreadCB(); | |
return 0; | |
} | |
/* Sets up the callback thread and returns its thread id */ | |
int SetupCallbacks(void) | |
{ | |
int thid = 0; | |
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0); | |
if(thid >= 0) | |
{ | |
sceKernelStartThread(thid, 0, 0); | |
} | |
return thid; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment