Well I've tried just about everything, even copied over the ps2snd make file word for word to mine in case it was a makefile issue.
Here's my full source, it's all single source and everything runs perfectly except the four calls to the sound lib to set the volume, which do not link.(And when i say everything elses runs perfectly i of course mean when i cut the four offending lines)
Code: Select all
#include "gsKit.h"
#include "dmaKit.h"
#include "malloc.h"
#include "libpad.h"
#include "kernel.h"
#include "stdio.h"
#include "loadfile.h"
#include <sifrpc.h>
#include <ps2snd.h>
typedef char int8;
typedef short int16;
typedef int int32;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long uint64;
typedef long int64;
typedef struct int128
{
int64 lo, hi;
} int128 __attribute__((aligned(16)));
typedef struct uint128
{
uint64 lo, hi;
} uint128 __attribute__((aligned(16)));
uint64 MakeRgb(int r,int g,int b)
{
return ((uint64)(r) <<0) | ((uint64)(g) << 8) | ((uint64)(b) << 16);
}
uint64 MakeRgba(int r,int g,int b,int a)
{
return ((uint64)(r) <<0) | ((uint64)(g) << 8) | ((uint64)(b) << 16) | ((uint64)(a) << 32);
}
template <class T>
class ListNode
{
public:
T &get()
{
return object;
};
void set(T &object)
{
this->object = object;
};
ListNode<T> *getNext()
{
return nextNode;
};
void setNext(ListNode<T> *nextNode)
{
this->nextNode = nextNode;
};
private:
T object;
ListNode<T> *nextNode;
};
template <class T>
class List
{
public:
// Constructor
List()
{
headNode = new ListNode<T>;
headNode->setNext(NULL);
currentNode = NULL;
size = 0;
};
// Destructor
~List()
{
ListNode<T> *pointerToDelete, *pointer = headNode;
while (pointer != NULL)
{
pointerToDelete = pointer;
pointer = pointer->getNext();
delete pointerToDelete;
}
};
T &get()
{
if (currentNode == NULL)
start();
return currentNode->get()
;
};
void add(T &addObject)
{
ListNode<T> *newNode = new ListNode<T>;
newNode->set(addObject)
;
newNode->setNext(headNode->getNext());
headNode->setNext(newNode);
size++;
};
void remove()
{
lastCurrentNode->setNext(currentNode->getNext());
delete currentNode;
currentNode = lastCurrentNode;
size--;
};
void start()
{
lastCurrentNode = headNode;
currentNode = headNode;
};
bool next()
{
// If the currentNode now points at nothing, we've reached the end
if (currentNode == NULL)
return false;
// Update the last node and current node
lastCurrentNode = currentNode;
currentNode = currentNode->getNext();
// If currentNode points at nothing or there is nothing added, we can immediately return false
if (currentNode == NULL || size == 0)
return false;
else
return true;
};
int getSize()
{
return size;
};
private:
int size;
ListNode<T> *headNode;
ListNode<T> *currentNode, *lastCurrentNode;
};
extern "C"
{
void UpdatePad()
{
int i=0;
int ret=0;
int port=0,slot=0;
ret=padGetState(port, slot);
while((ret != PAD_STATE_STABLE) && (ret != PAD_STATE_FINDCTP1)) {
if(ret==PAD_STATE_DISCONN) {
printf("Pad(%d, %d) is disconnected\n", port, slot);
}
ret=padGetState(port, slot);
}
if(i==1) {
printf("Pad: OK!\n");
}
}
struct padButtonStatus buttons;
u32 paddata;
u32 old_pad = 0;
u32 new_pad;
int but_select,but_start;
int but_cross,but_circle,but_square,but_triangle;
float but_crossp,but_circlep,but_squarep,but_trianglep;
int but_l1,but_l2,but_r1,but_r2;
int but_l3,but_r3;
float but_l1p,but_l2p,but_r1p,but_r2p;
float joy_lx,joy_ly;
float joy_rx,joy_ry;
float joy_hx,joy_hy;
void ReadPad()
{
int ret;
int port = 0,slot =0;
but_square=0;
but_triangle=0;
but_circle=0;
but_cross=0;
but_l1=0;
but_l2=0;
but_r1=0;
but_r2=0;
but_select=0;
but_start=0;
but_l3=0;
but_r3=0;
ret = padRead(port, slot, &buttons);
if (ret != 0) {
paddata = 0xffff ^ buttons.btns;
new_pad = paddata;//'paddata & ~old_pad;
old_pad = paddata;
// Directions
if(new_pad & PAD_LEFT) {
joy_hx = -1;
}
if(new_pad & PAD_DOWN) {
joy_hy = 1;
}
if(new_pad & PAD_RIGHT) {
joy_hx = 1;
}
if(new_pad & PAD_UP) {
joy_hy = 1;
}
if(new_pad & PAD_START) {
but_start = 1;
}
if(new_pad & PAD_R3) {
but_r3 = 1;
}
if(new_pad & PAD_L3) {
but_l3 = 1;
}
if(new_pad & PAD_SELECT) {
but_select = 1;
}
if(new_pad & PAD_SQUARE) {
but_square = 1;
}
if(new_pad & PAD_CROSS) {
but_cross = 1;
}
if(new_pad & PAD_CIRCLE) {
but_circle = 1;
}
if(new_pad & PAD_TRIANGLE) {
but_triangle = 1;
}
if(new_pad & PAD_R1) {
but_r1 = 1;
}
if(new_pad & PAD_L1) {
but_l1 = 1;
}
if(new_pad & PAD_R2) {
but_r2 = 1;
}
if(new_pad & PAD_L2) {
but_l2 = 1;
}
but_crossp = buttons.cross_p;
but_squarep = buttons.square_p;
but_circlep = buttons.circle_p;
but_trianglep = buttons.triangle_p;
but_l1p = buttons.l1_p;
but_r1p = buttons.r1_p;
but_l2p = buttons.l2_p;
but_r2p = buttons.r2_p;
joy_hx -= buttons.left_p;
joy_hx += buttons.right_p;
joy_hy -= buttons.up_p;
joy_hy += buttons.down_p;
}
}
int waitPadReady(int port, int slot)
{
int state;
int lastState;
char stateString[16];
state = padGetState(port, slot);
lastState = -1;
while((state != PAD_STATE_STABLE) && (state != PAD_STATE_FINDCTP1)) {
if (state != lastState) {
padStateInt2String(state, stateString);
printf("Please wait, pad(%d,%d) is in state %s\n",
port, slot, stateString);
}
lastState = state;
state=padGetState(port, slot);
}
// Were the pad ever 'out of sync'?
if (lastState != -1) {
printf("Pad OK!\n");
}
return 0;
}
}
u64 cur_col;
GSGLOBAL *gs_Global;
inline void SetColor(int r,int g,int b,int a=255)
{
cur_col = MakeRgba(r,g,b,a); ;//GS_SETREG_RGBAQ(r,g,b,a,0);
}
inline void DrawRect(float x,float y,float w,float h,int z)
{
gsKit_prim_sprite(gs_Global, x,y, x+w,y+h, z, cur_col );
}
//consts instead of enum 'cos they wern't compiling for some reason.
const int Control_Pad = 1,Control_AI = 2;
class Bat
{
public:
Bat(float x,float y,int control)
{
_x=x;
_y=y;
_yi=0;
_len=90;
_cpu = control;
_lenInc=0;
}
~Bat()
{
}
void Render()
{
_len +=_lenInc;
DrawRect(_x,_y-(_len/2),20,_len,5);
_len -=_lenInc;
}
void Update()
{
switch(_cpu)
{
case Control_Pad:
_lenInc = but_crossp * 0.2;
//print'f("LenInc: %f \n",_lenInc);
if(abs(joy_hy)>30)
_yi += joy_hy *0.02;
break;
case Control_AI:
break;
}
_y += _yi;
if(_y<( (_len/2)+(_lenInc/2)) ) _y=( (_len/2)+(_lenInc/2));
if(_y>(gs_Global->Height-( (_len/2)+(_lenInc/2) ) ))
_y = (gs_Global->Height-( (_len/2)+(_lenInc/2) ) );
_yi *= 0.95;
};
float _lenInc;
float _x,_y;
float _yi,_len;
int _cpu;
};
class Star
{
public:
Star(float x,float y,float z)
{
_x = x;
_y = y;
_z = z;
_lx = x;
}
void Move(float x)
{
_x +=(x/(255-_z));
if( _x<-10 )
{
_x=gs_Global->Width+10;
_y=rand()%gs_Global->Height;
_z=rand()%255;
_lx = _x;
}
}
float _x,_y,_z;
float _lx;
};
class Ball
{
public:
Ball(float x,float y)
{
_x = x;
_y = y;
}
void Update()
{
_x+=_xi;
_y+=_yi;
}
void Render()
{
SetColor(255,255,255,255);
DrawRect(_x-8,_y-8,16,16,1 );
}
float _x,_y;
float _xi,_yi;
};
Ball *ball;
void UpdateAndRenderBall()
{
ball->Update();
ball->Render();
}
List<Star *>stars;
List<Bat *>bats;
void AddStar(float x,float y,float z)
{
Star *star = new Star(x,y,z);
stars.add( star );
}
void StarsUpdateAndRender()
{
stars.start();
while( stars.next() )
{
Star * star = stars.get();
star->_lx = star->_x+2;
star->Move( -50 );
//SetColor( star->_z,star->_z,star->_z,255 );
//DrawRect( star->_x-2,star->_y-2,4,4,(int)(255-star->_z) );
float xd;
xd = star->_lx - star->_x;
xd = xd *2;
gsKit_prim_line( gs_Global, star->_x,star->_y,star->_x+xd,star->_y,(255-star->_z),MakeRgb(star->_z,star->_z,star->_z) );
}
}
void AddBat(float x,int control)
{
Bat *bat = new Bat(x,gs_Global->Height/2.0,control);
bats.add( bat );
}
void RenderBats()
{
bats.start();
SetColor(255,255,255,255);
while( bats.next() )
{
Bat *bat = bats.get();
bat->Render();
}
}
void UpdateBats()
{
bats.start();
while( bats.next() )
{
Bat *bat = bats.get();
bat->Update();
}
}
extern "C" {
int main(int argc, char ** argv) {
u64 White, Black, Red, Green, Blue, BlueTrans, RedTrans, GreenTrans, WhiteTrans;
// GSGLOBAL *gsGlobal = gsKit_init_global(GS_MODE_VGA_640_60); // VGA 640x480@60Hz
// GSGLOBAL *gsGlobal = gsKit_init_global(GS_MODE_DTV_480P); // HTDV 480P
// GSGLOBAL *gsGlobal = gsKit_init_global(GS_MODE_DTV_720P); // HTDV 720P
// GSGLOBAL *gsGlobal = gsKit_init_global(GS_MODE_DTV_1080I); // HDTV 1080I Full Buffers
// GSGLOBAL *gsGlobal = gsKit_init_global(GS_MODE_DTV_1080I_I); // HDTV 1080I Half Buffers
SifInitRpc(0);
SifLoadModule("rom0:SIO2MAN", 0, NULL);
SifLoadModule("rom0:PADMAN", 0, NULL);
int ret;
/* Load LibSD (freesd will work too one day, I promise ;) */
ret = SifLoadModule("rom0:LIBSD", 0, NULL);
if (ret<0)
{
printf("XXXXX failed to load host:LIBSD.IRX (%d)\n", ret);
return 0;
}
/* Load ps2snd */
ret = SifLoadModule("host:ps2snd.irx", 0, NULL);
if (ret<0)
{
printf("XXXXX failed to load host:ps2snd.irx (%d)\n", ret);
return 0;
}
SdSetParam(0 | SD_PARAM_MVOLL, 0x3fff);
SdSetParam(0 | SD_PARAM_MVOLR, 0x3fff);
SdSetParam(1 | SD_PARAM_MVOLL, 0x3fff);
SdSetParam(1 | SD_PARAM_MVOLR, 0x3fff);
printf("About to init pad. \n");
static char padBuf[256] __attribute__((aligned(64)));
printf("Created structure \n");
padInit(0);
printf("Called padinit.\n");
if((padPortOpen(0, 0, padBuf)) == 0) {
printf("padOpenPort failed");
return 0;
}
printf("Joypad Initialized");
waitPadReady(0,0);
padSetMainMode(0,0, PAD_MMODE_DUALSHOCK, PAD_MMODE_LOCK);
waitPadReady(0,0);
padEnterPressMode(0,0);
waitPadReady(0,0);
gs_Global = gsKit_init_global(GS_MODE_PAL); // Full Buffers
// GSGLOBAL *gsGlobal = gsKit_init_global(GS_MODE_PAL_I); // NTSC Half Buffers
// GSGLOBAL *gsGlobal = gsKit_init_global(GS_MODE_NTSC); // NTSC Full Buffers
// GSGLOBAL *gsGlobal = gsKit_init_global(GS_MODE_NTSC_I); // NTSC Half Buffers
// You can use these to turn off Z/Double Buffering. They are on by default.
// gsGlobal->DoubleBuffering = GS_SETTING_OFF;
// gsGlobal->ZBuffering = GS_SETTING_OFF;
// This makes things look marginally better in half-buffer mode...
// however on some CRT and all LCD, it makes a really horrible screen shake.
// Uncomment this to disable it. (It is on by default)
// gsGlobal->DoSubOffset = GS_SETTING_OFF;
gs_Global->PrimAlphaEnable = GS_SETTING_ON;
float x = 10;
float y = 10;
float width = 150;
float height = 150;
float VHeight;
VHeight = gs_Global->Height;
float *LineStrip;
float *LineStripPtr;
float *TriStrip;
float *TriStripPtr;
float *TriFanPtr;
float *TriFan;
dmaKit_init(D_CTRL_RELE_OFF, D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC,
D_CTRL_STD_OFF, D_CTRL_RCYC_8);
// Initialize the DMAC
dmaKit_chan_init(DMA_CHANNEL_GIF);
dmaKit_chan_init(DMA_CHANNEL_FROMSPR);
dmaKit_chan_init(DMA_CHANNEL_TOSPR);
White = GS_SETREG_RGBAQ(0xFF,0xFF,0xFF,0x00,0x00);
gsKit_init_screen(gs_Global);
gsKit_clear(gs_Global, White);
gsKit_set_test(gs_Global, GS_ZTEST_OFF);
gsKit_mode_switch(gs_Global, GS_ONESHOT);
//Init paddles
AddBat( 20,Control_Pad );
AddBat( gs_Global->Width-40,Control_AI );
SetColor(255,255,255,255);
for(int i=0;i<500;i++)
{
AddStar( rand()%gs_Global->Width,rand()%gs_Global->Height,rand()%255);
}
ball = new Ball( gs_Global->Width/2,gs_Global->Height/2 );
while(1)
{
gsKit_clear(gs_Global,MakeRgb(0,0,0));
UpdatePad();
ReadPad();
UpdateBats();
StarsUpdateAndRender();
RenderBats();
UpdateAndRenderBall();
if( y <= 10 && (x + width) < (gs_Global->Width - 10))
x+=1;
else if( (y + height) < (VHeight - 10) && (x + width) >= (gs_Global->Width - 10) )
y+=1;
else if( (y + height) >= (VHeight - 10) && x > 10 )
x-=1;
else if( y > 10 && x <= 10 )
y-=1;
// gsKit_prim_sprite(gsGlobal, x, y, x + width, y + height, 4, MakeRgb(255,0,0));
//gsKit_prim_sprite(gsGlobal,20,20,140,140,4,MakeRgba(255,255,128,255));
// RedTrans must be a oneshot for proper blending!
//gsKit_prim_sprite(gsGlobal, 100.0f, 100.0f, 200.0f, 200.0f, 5, MakeRgba(128,128,128,128));
gsKit_queue_exec(gs_Global);
// Flip before exec to take advantage of DMA execution double buffering.
gsKit_sync_flip(gs_Global);
}
return 0;
}
}