Snake psp source wrote:
// Shine's Snake
//
// artworks by Gundrosen
// coding by Shine
//
// Credits:
// based on Hello World for PSP by nem
// Exit Game test by TyRaNiD
// function stubs: PSPDev - Browser Api (by djhuevo & neofar,
http://pspdev.ofcode.com/api.php)
// controller function usage based on a program by skippy911
// and many hints from people at
http://forums.ps2dev.org
#include "pg.h"
#include "background.c"
#include "headR.c"
#include "headT.c"
#include "headL.c"
#include "headB.c"
#include "tailR.c"
#include "tailT.c"
#include "tailL.c"
#include "tailB.c"
#include "bodyLT.c"
#include "bodyLB.c"
#include "bodyRT.c"
#include "bodyRB.c"
#include "bodyLR.c"
#include "bodyTB.c"
#include "apple.c"
#include "fly.c"
unsigned short* tails[] = { tailRData, tailTData, tailLData, tailBData };
unsigned short* heads[] = { headRData, headTData, headLData, headBData };
unsigned short* bodies[] = { bodyLRData, bodyTBData, bodyLRData, bodyTBData };
#define RIGHT 0
#define TOP 1
#define LEFT 2
#define BOTTOM 3
#define O_RDONLY 0x0001
#define O_WRONLY 0x0002
#define O_RDWR 0x0003
#define O_NBLOCK 0x0010
#define O_APPEND 0x0100
#define O_CREAT 0x0200
#define O_TRUNC 0x0400
#define O_NOWAIT 0x8000
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
/* Button bit masks */
#define CTRL_SQUARE 0x8000
#define CTRL_TRIANGLE 0x1000
#define CTRL_CIRCLE 0x2000
#define CTRL_CROSS 0x4000
#define CTRL_UP 0x0010
#define CTRL_DOWN 0x0040
#define CTRL_LEFT 0x0080
#define CTRL_RIGHT 0x0020
#define CTRL_START 0x0008
#define CTRL_SELECT 0x0001
#define CTRL_LTRIGGER 0x0100
#define CTRL_RTRIGGER 0x0200
/* Returned control data */
typedef struct _ctrl_data
{
int frame;
int buttons;
unsigned char analog[4];
int unused;
} ctrl_data_t;
/* game structs and variables */
typedef struct
{
int x;
int y;
int direction;
} Cell;
#define RGB(r, g, b) ((r)|((g)<<5)|((b)<<10))
#define TEXT_COLOR RGB(0, 0, 0)
Cell* cells = (Cell*)0x9300000;
Cell target;
unsigned short* targetImage;
int dx;
int dy;
int x;
int y;
int cellStart;
int cellEnd;
int maxCells = 60*34;
int score;
int high = 0;
static unsigned seed1;
static unsigned seed2;
void initSeeds()
{
seed1 = sceKernelLibcTime((void *) 0);
seed2 = sceKernelLibcTime((void *) 0);
}
unsigned int myRand()
{
seed1 = (seed1 + 46906481) ^ seed2;
seed2 = seed1 ^ ( ((seed2<<3) | (seed2 >> 29)) + 103995407);
return seed1 - seed2;
}
int exit_callback(void)
{
sceKernelExitGame();
return 0;
}
int CallbackThread(void *arg)
{
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
int SetupCallbacks(void)
{
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0)
{
sceKernelStartThread(thid, 0, 0);
}
return thid;
}
const char digitFont[] = {
1,1,1,1,
1,0,0,1,
1,0,0,1,
1,0,0,1,
1,1,1,1,
0,0,0,1,
0,0,0,1,
0,0,0,1,
0,0,0,1,
0,0,0,1,
1,1,1,1,
0,0,0,1,
1,1,1,1,
1,0,0,0,
1,1,1,1,
1,1,1,1,
0,0,0,1,
1,1,1,1,
0,0,0,1,
1,1,1,1,
1,0,0,1,
1,0,0,1,
1,1,1,1,
0,0,0,1,
0,0,0,1,
1,1,1,1,
1,0,0,0,
1,1,1,1,
0,0,0,1,
1,1,1,1,
1,1,1,1,
1,0,0,0,
1,1,1,1,
1,0,0,1,
1,1,1,1,
1,1,1,1,
0,0,0,1,
0,0,0,1,
0,0,0,1,
0,0,0,1,
1,1,1,1,
1,0,0,1,
1,1,1,1,
1,0,0,1,
1,1,1,1,
1,1,1,1,
1,0,0,1,
1,1,1,1,
0,0,0,1,
1,1,1,1};
void print7Segment(int x, int y, int digit)
{
unsigned short* vram = (unsigned short*) pgGetVramAddr(x, y);
int xo, yo;
int i = digit * 5*4;
for (yo = 0; yo < 5; yo++) {
for (xo = 0; xo < 4; xo++) {
if (digitFont
) {
vram[xo + yo * 512] = TEXT_COLOR;
} else {
vram[xo + yo * 512] = backgroundData[x + xo + (y + yo) * backgroundWidth];
}
i++;
}
}
}
void printDecimal(int x, int y, int color, int value)
{
int i;
int zero = 1;
int digits[6];
for (i = 5; i >= 0; i--) {
digits = value%10;
value /= 10;
}
i = 0;
while (i < 5 && digits == 0) digits[i++] = -1;
for (i = 0; i < 6; i++) {
if (digits >= 0) {
print7Segment(x, y, digits);
x += 6;
}
}
}
void fillCell(int x, int y)
{
unsigned short* vram = (unsigned short*) pgGetVramAddr(x * 16, y * 16);
int xo, yo;
for (yo = 0; yo < 16; yo++) {
for (xo = 0; xo < 16; xo++) {
vram[xo + yo * 512] = backgroundData[16*x + xo + (16*y + yo) * backgroundWidth];
}
}
}
void plotCellImage(int x, int y, unsigned short* image)
{
unsigned short* vram = (unsigned short*) pgGetVramAddr(x * 16, y * 16);
int xo, yo;
for (yo = 0; yo < 16; yo++) {
for (xo = 0; xo < 16; xo++) {
if (*image != 0x8000) {
vram[xo + yo * 512] = *image;
} else vram[xo + yo * 512] = backgroundData[16*x + xo + (16*y + yo) * backgroundWidth];
image++;
}
}
}
void createRandomTarget()
{
target.x = (myRand() % 21) + 1;
target.y = (myRand() % 15) + 1;
if (myRand() % 2) {
targetImage = appleData;
} else {
targetImage = flyData;
}
}
void writeByte(int fd, unsigned char data)
{
sceIoWrite(fd, &data, 1);
}
const char tgaHeader[] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0};
/*
void screenshot()
{
const int width = 480;
const int lineWidth = 512;
const int height = 272;
unsigned short lineBuffer[width];
unsigned short* vram = (unsigned short*) pgGetVramAddr(0, 0);
int x, y;
int fd = sceIoOpen("ms0:/screenshot.tga", O_CREAT | O_TRUNC | O_WRONLY, 0777);
if (!fd) return;
sceIoWrite(fd, tgaHeader, sizeof(tgaHeader));
writeByte(fd, width & 0xff);
writeByte(fd, width >> 8);
writeByte(fd, height & 0xff);
writeByte(fd, height >> 8);
writeByte(fd, 16);
writeByte(fd, 0);
for (y = height - 1; y >= 0; y--) {
for (x = 0; x < width; x++) {
unsigned short color = vram[y * lineWidth + x];
unsigned char red = color & 0x1f;
unsigned char green = (color >> 5) & 0x1f;
unsigned char blue = (color >> 10) & 0x1f;
lineBuffer[x] = blue | (green<<5) | (red<<10);
}
sceIoWrite(fd, lineBuffer, width * 2);
}
sceIoClose(fd);
}
*/
void newGame()
{
pgFlipDrawFrame();
unsigned short* vram = (unsigned short*) pgGetVramAddr(0, 0);
int xo, yo;
unsigned short* image = backgroundData;
for (yo = 0; yo < backgroundHeight; yo++) {
for (xo = 0; xo < backgroundWidth; xo++) {
if (*image != 0x8000) vram[xo + yo * 512] = *image;
image++;
}
}
dx = 0;
dy = 0;
x = 12;
y = 8;
cellStart = 0;
cellEnd = 1;
cells[cellStart].x = x;
cells[cellStart].y = y;
cells[cellStart].direction = RIGHT;
cells[cellEnd].x = ++x;
cells[cellEnd].y = y;
cells[cellEnd].direction = RIGHT;
createRandomTarget();
plotCellImage(cells[cellStart].x, cells[cellStart].y, tailRData);
plotCellImage(cells[cellEnd].x, cells[cellEnd].y, headRData);
score = 0;
pgFlipShowFrameV();
}
void keyboardControl()
{
ctrl_data_t ctrl;
sceDisplayWaitVblankStart();
sceCtrlReadBufferPositive(&ctrl, 1);
if (ctrl.buttons & CTRL_UP) {
dx = 0;
dy = -1;
} else if (ctrl.buttons & CTRL_DOWN) {
dx = 0;
dy = 1;
} else if (ctrl.buttons & CTRL_LEFT) {
dx = -1;
dy = 0;
} else if (ctrl.buttons & CTRL_RIGHT) {
dx = 1;
dy = 0;
}/* else if (ctrl.buttons & CTRL_CIRCLE) {
screenshot();
}*/
}
void move()
{
if (dx == 0 && dy == 0) return;
int lastDirection = cells[cellEnd].direction;
int lastX = cells[cellEnd].x;
int lastY = cells[cellEnd].y;
x += dx;
y += dy;
cellEnd++;
if (cellEnd == maxCells) cellEnd = 0;
cells[cellEnd].x = x;
cells[cellEnd].y = y;
if (dx == 1) {
cells[cellEnd].direction = RIGHT;
} else if (dy == -1) {
cells[cellEnd].direction = TOP;
} else if (dx == -1) {
cells[cellEnd].direction = LEFT;
} else if (dy == 1) {
cells[cellEnd].direction = BOTTOM;
}
int direction = cells[cellEnd].direction;
if (lastDirection == RIGHT && direction == TOP) {
plotCellImage(lastX, lastY, bodyLTData);
} else if (lastDirection == TOP && direction == LEFT) {
plotCellImage(lastX, lastY, bodyLBData);
} else if (lastDirection == LEFT && direction == BOTTOM) {
plotCellImage(lastX, lastY, bodyRBData);
} else if (lastDirection == BOTTOM && direction == RIGHT) {
plotCellImage(lastX, lastY, bodyRTData);
} else if (lastDirection == RIGHT && direction == BOTTOM) {
plotCellImage(lastX, lastY, bodyLBData);
} else if (lastDirection == TOP && direction == RIGHT) {
plotCellImage(lastX, lastY, bodyRBData);
} else if (lastDirection == LEFT && direction == TOP) {
plotCellImage(lastX, lastY, bodyRTData);
} else if (lastDirection == BOTTOM && direction == LEFT) {
plotCellImage(lastX, lastY, bodyLTData);
} else {
plotCellImage(lastX, lastY, bodies[direction]);
}
plotCellImage(cells[cellEnd].x, cells[cellEnd].y, heads[cells[cellEnd].direction]);
if (x == target.x && y == target.y) {
createRandomTarget();
score++;
} else {
fillCell(cells[cellStart].x, cells[cellStart].y);
cellStart++;
if (cellStart == maxCells) cellStart = 0;
int start = cellStart;
if (start != cellEnd) {
start++;
if (start == maxCells) start = 0;
}
plotCellImage(cells[cellStart].x, cells[cellStart].y, tails[cells[start].direction]);
}
}
int isGameOver()
{
int lastX = cells[cellEnd].x;
int lastY = cells[cellEnd].y;
int gameOver = 0;
if (lastX >= 22) gameOver = 1;
if (lastX < 1) gameOver = 1;
if (lastY >= 16) gameOver = 1;
if (lastY < 1) gameOver = 1;
int start = cellStart;
while (start != cellEnd) {
if (cells[start].x == lastX && cells[start].y == lastY) {
gameOver = 1;
break;
}
start++;
if (start == maxCells) start = 0;
}
return gameOver;
}
int xmain(int ra)
{
initSeeds();
SetupCallbacks();
pgInit();
pgScreenFrame(1, 1);
newGame();
while (1) {
int i = 0;
for (i = 0; i < 5; i++) keyboardControl();
move();
plotCellImage(target.x, target.y, targetImage);
if (score > high) high = score;
if (isGameOver()) {
pgWaitVn(50);
newGame();
}
printDecimal(410, 81, TEXT_COLOR, score);
printDecimal(429, 129, TEXT_COLOR, high);
}
return 0;
}