Page 1 of 1

Is there anyway to program for the PSP using Java?

Posted: Mon Jul 18, 2005 5:10 am
by RATiX
I haven't seen any way to do this, but seeing as how Java is the only language I know, is there away to do this?

I don't want to go installing cygwin and the PSP toolchain and all that if it's not going to help me in the end, so an answer would be appreciated.

If Java is not an option, how different is Java compared to C, or C++? If I wasn't focusing on graphics/computations would it be easy enough to switch over? And what're the differences between C and C++, and which is better for the PSP?

Thanks in advance.

Posted: Mon Jul 18, 2005 5:13 am
by mrbrown
There is no homebrew Java support for the PSP.

If you need to know the differences between Java, C, and C++ then you'd best start Googling.

Posted: Mon Jul 18, 2005 5:16 am
by Lollerskates
Until someone ports a Java run time compiler to the PSP, your only option is using the PSPSDK...

take a look at this sample game (Snake by Shine) to determine if you think you could work in this language...
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;
}


Posted: Mon Jul 18, 2005 5:28 am
by Shine
Lollerskates wrote:Until someone ports a Java run time compiler to the PSP, your only option is using the PSPSDK...
There is always another option :-) Take a look at my Lua implementation and the source of Snake there, to see if you like Lua. The size of the Lua source for Snake is less than half the size of the C program and it requires no compilation at all.

Posted: Mon Jul 18, 2005 5:40 am
by RATiX
Hmm.. I don't get the #define parts, but I can see how some of the program works.

Lua sounds interesting as well; I want to work with something that gives me UMD access - I'm sure all languages can do this, but people alreasy have it figured out for some.

I also see that C(++) has no Objects... I guess I'll just wait till PSPJRE comes out....