303 lines
8.3 KiB
C
Executable File
303 lines
8.3 KiB
C
Executable File
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <malloc.h>
|
|
#include <math.h>
|
|
#include <gccore.h>
|
|
#include <network.h>
|
|
#include <ogcsys.h>
|
|
#include <stdio.h>
|
|
|
|
// -------------- Constants -------------------
|
|
|
|
#define SYSSTATE_GX_INIT 2
|
|
#define SYSSTATE_VIDEO_INIT 4
|
|
#define SYSSTATE_CONSOLE_INIT 8
|
|
#define SYSSTATE_NET_INIT 16
|
|
|
|
// I forget why I set the FIFO to this size initially...?
|
|
#define FIFO_SIZE (256*1024)
|
|
|
|
//--------------- Variables ------------------
|
|
|
|
u32 systemState;
|
|
|
|
// VIDEO variables
|
|
void *gul_viDefaultUserFrameBuff = NULL;
|
|
GXRModeObj *gul_gxDefaultGXRenderMode;
|
|
|
|
// GX specific system-level stuff
|
|
void *gul_gxDefaultFIFOBuffer = NULL;
|
|
GXFifoObj *gul_gxDefaultFIFOObj = NULL;
|
|
|
|
// matrix stuff (gul_gxDefaultViewMatrixmatrix mostly)
|
|
Mtx gul_gxDefaultViewMatrix;
|
|
Mtx gul_gxDefaultProjectionMatrix;
|
|
Vector gul_gxDefaultCameraPosition = {0.0F, 0.0F, 0.0F};
|
|
Vector gul_gxDefaultCameraUp = {0.0F, 1.0F, 0.0F};
|
|
Vector gul_gxDefaultCameraLook = {0.0F, 0.0F, -1.0F};
|
|
|
|
// misc
|
|
GXColor gul_gxDefaultBackgroundColor = {0, 0, 0, 255};
|
|
bool gul_gxXFBCopyReady = GX_FALSE;
|
|
|
|
// ---------------- Functions ---------------
|
|
|
|
// shamelessly stolen from the various tkcne demos
|
|
// copies the XFB to the screen when gul_gxXFBCopyReady is true
|
|
// I dun remember what the 'count' was for?
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
static void gulCopyXFB(u32 count)
|
|
{
|
|
if(gul_gxXFBCopyReady==GX_TRUE) {
|
|
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
|
|
GX_SetColorUpdate(GX_TRUE);
|
|
GX_CopyDisp(gul_viDefaultUserFrameBuff,GX_TRUE);
|
|
GX_Flush();
|
|
gul_gxXFBCopyReady = GX_FALSE;
|
|
}
|
|
}
|
|
#ifdef __cplusplus
|
|
} // extern C
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
u32 gulSetupNetwork(bool dhcp, char *thisIP, char *gateway, char *netmask)
|
|
{
|
|
u32 retval;
|
|
|
|
retval = net_init();
|
|
|
|
#ifdef DEBUG
|
|
printf("Initing network...\n");
|
|
printf("net_init returned: %d\n", retval);
|
|
#endif
|
|
|
|
if ( retval ) {
|
|
return retval;
|
|
}
|
|
|
|
retval = if_config(thisIP, gateway, netmask, dhcp );
|
|
|
|
#ifdef DEBUG
|
|
printf("if_config returned: %d\n", retval);
|
|
#endif
|
|
|
|
systemState |= SYSSTATE_NET_INIT;
|
|
return retval;
|
|
}
|
|
#ifdef __cplusplus
|
|
} // extern C
|
|
#endif
|
|
|
|
|
|
#ifdef __cplusplus
|
|
u32 gulVideoSetup(bool XFBdirect=true, VIRetraceCallback callback=NULL, bool blackout=true)
|
|
extern "C" {
|
|
#else
|
|
u32 gulVideoSetup(bool XFBdirect, VIRetraceCallback callback, bool blackout)
|
|
#endif
|
|
{
|
|
if ( callback == NULL ) {
|
|
callback = gulCopyXFB;
|
|
}
|
|
|
|
VIDEO_Init();
|
|
|
|
switch ( VIDEO_GetCurrentTvMode() ) {
|
|
case VI_NTSC:
|
|
gul_gxDefaultGXRenderMode = &TVNtsc480IntAa;
|
|
break;
|
|
case VI_PAL:
|
|
gul_gxDefaultGXRenderMode = &TVPal524IntAa;
|
|
break;
|
|
case VI_EURGB60:
|
|
gul_gxDefaultGXRenderMode = &TVPal524IntAa; // this may cause problems.... No EURGB60 modes tho?
|
|
break;
|
|
case VI_MPAL:
|
|
gul_gxDefaultGXRenderMode = &TVMpal480IntDf;
|
|
}
|
|
|
|
VIDEO_Configure(gul_gxDefaultGXRenderMode);
|
|
|
|
gul_viDefaultUserFrameBuff = MEM_K0_TO_K1(memalign(VIDEO_PadFramebufferWidth(gul_gxDefaultGXRenderMode->fbWidth)*gul_gxDefaultGXRenderMode->xfbHeight*VI_DISPLAY_PIX_SZ, 32));
|
|
|
|
VIDEO_SetNextFramebuffer((void *)MEM_VIRTUAL_TO_PHYSICAL(gul_viDefaultUserFrameBuff));
|
|
if ( XFBdirect == false) {
|
|
VIDEO_SetPostRetraceCallback(callback);
|
|
}
|
|
VIDEO_SetBlack(blackout);
|
|
VIDEO_Flush();
|
|
VIDEO_WaitVSync();
|
|
VIDEO_WaitVSync();
|
|
|
|
systemState |= SYSSTATE_VIDEO_INIT;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
void gulConsoleSetup()
|
|
{
|
|
// the console will occupy a small area of the screen that should fit
|
|
// mostly within the screen. Sometimes the console will overlap if we don't
|
|
// give it a little border. If you're using the console in GX, though,
|
|
// it will occupy the whole screen.
|
|
if ( !(systemState & SYSSTATE_VIDEO_INIT) ) {
|
|
#ifdef __cplusplus
|
|
gulVideoSetup();
|
|
#else
|
|
gulVideoSetup(false, gulCopyXFB, false);
|
|
#endif
|
|
}
|
|
console_init(gul_viDefaultUserFrameBuff,
|
|
20,
|
|
100,
|
|
gul_gxDefaultGXRenderMode->viWidth,
|
|
gul_gxDefaultGXRenderMode->viHeight,
|
|
gul_gxDefaultGXRenderMode->viWidth*VI_DISPLAY_PIX_SZ);
|
|
systemState |= SYSSTATE_CONSOLE_INIT;
|
|
}
|
|
#ifdef __cplusplus
|
|
} // extern C
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
void gulGXSetup(u8 cullMode=0, Vector *camVector=NULL, Vector *upVector=NULL,
|
|
Vector *lookVector=NULL, f32 nearClip=NULL, f32 farClip=NULL)
|
|
#else
|
|
void gulGXSetup(u8 cullMode, Vector *camVector, Vector *upVector,
|
|
Vector *lookVector, f32 nearClip, f32 farClip)
|
|
#endif
|
|
{
|
|
#ifndef __cplusplus
|
|
if ( nearClip == 0 ) {
|
|
nearClip = 1.0F;
|
|
}
|
|
if ( farClip == 0 ) {
|
|
farClip = 300.0F;
|
|
}
|
|
if ( lookVector == NULL ) {
|
|
lookVector = &gul_gxDefaultCameraLook;
|
|
}
|
|
if ( upVector == NULL ) {
|
|
upVector = &gul_gxDefaultCameraUp;
|
|
}
|
|
if ( camVector == NULL ) {
|
|
camVector = &gul_gxDefaultCameraPosition;
|
|
}
|
|
if ( cullMode == 0 ) {
|
|
cullMode = GX_CULL_NONE;
|
|
}
|
|
#endif // __cplusplus
|
|
|
|
if ( !(systemState & SYSSTATE_VIDEO_INIT) ) {
|
|
#ifndef __cplusplus
|
|
gulVideoSetup(false, NULL, false);
|
|
#else
|
|
gulVideoSetup();
|
|
#endif // __cplusplus
|
|
}
|
|
|
|
gul_gxDefaultFIFOBuffer = MEM_K0_TO_K1( memalign(FIFO_SIZE,32) );
|
|
memset(gul_gxDefaultFIFOBuffer, 0, FIFO_SIZE);
|
|
|
|
gul_gxDefaultFIFOObj = GX_Init(gul_gxDefaultFIFOBuffer, FIFO_SIZE);
|
|
GX_SetCopyClear(gul_gxDefaultBackgroundColor, 0x00ffffff);
|
|
GX_SetViewport(0,0,gul_gxDefaultGXRenderMode->fbWidth,gul_gxDefaultGXRenderMode->efbHeight,0,1);
|
|
GX_SetDispCopyYScale((f32)gul_gxDefaultGXRenderMode->xfbHeight/(f32)gul_gxDefaultGXRenderMode->efbHeight);
|
|
GX_SetScissor(0,0,gul_gxDefaultGXRenderMode->fbWidth,gul_gxDefaultGXRenderMode->efbHeight);
|
|
GX_SetDispCopySrc(0,0,gul_gxDefaultGXRenderMode->fbWidth,gul_gxDefaultGXRenderMode->efbHeight);
|
|
GX_SetDispCopyDst(gul_gxDefaultGXRenderMode->fbWidth,gul_gxDefaultGXRenderMode->xfbHeight);
|
|
GX_SetCopyFilter(gul_gxDefaultGXRenderMode->aa,gul_gxDefaultGXRenderMode->sample_pattern,
|
|
GX_TRUE,gul_gxDefaultGXRenderMode->vfilter);
|
|
GX_SetFieldMode(gul_gxDefaultGXRenderMode->field_rendering,
|
|
((gul_gxDefaultGXRenderMode->viHeight==2*gul_gxDefaultGXRenderMode->xfbHeight)?GX_ENABLE:GX_DISABLE));
|
|
|
|
GX_SetCullMode(GX_CULL_NONE);
|
|
GX_CopyDisp(gul_viDefaultUserFrameBuff,GX_TRUE);
|
|
GX_SetDispCopyGamma(GX_GM_1_0);
|
|
|
|
guLookAt(gul_gxDefaultViewMatrix, camVector, upVector, lookVector);
|
|
guPerspective(gul_gxDefaultProjectionMatrix, 60, 1.33F, nearClip, farClip);
|
|
GX_LoadProjectionMtx(gul_gxDefaultProjectionMatrix, GX_PERSPECTIVE);
|
|
|
|
GX_ClearVtxDesc();
|
|
|
|
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
|
|
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
|
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
|
|
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
|
|
|
GX_SetNumChans(1);
|
|
GX_SetNumTexGens(0);
|
|
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0);
|
|
GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
|
|
|
|
systemState |= SYSSTATE_GX_INIT;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
// sets gul_gxXFBCopyReady to true
|
|
|
|
inline void gulGXCopyReady()
|
|
{
|
|
gul_gxXFBCopyReady = true;
|
|
}
|
|
|
|
// hits up the PSO reload vector
|
|
// included so you don't ever have to worry again about
|
|
// "have I got that reload vector set right?..." */
|
|
|
|
inline void gulReloadFromPSO()
|
|
{
|
|
void (*psoreload)() = (void(*)())0x80001800;
|
|
psoreload();
|
|
}
|
|
|
|
// checks for a given system init state
|
|
|
|
inline bool gulWasInit(u32 subsys)
|
|
{
|
|
return (systemState & subsys);
|
|
}
|
|
|
|
// some functions to return pointers to the various gul guts.
|
|
// I prefer doing it this way, having all the constants exported
|
|
// in the .h looks ugly.
|
|
|
|
inline Mtx *gulDefaultViewMatrix()
|
|
{
|
|
return &gul_gxDefaultViewMatrix;
|
|
}
|
|
|
|
inline Mtx *gulDefaultProjectionMatrix()
|
|
{
|
|
return &gul_gxDefaultProjectionMatrix;
|
|
}
|
|
|
|
inline void *gulUserFrameBuffer()
|
|
{
|
|
return gul_viDefaultUserFrameBuff;
|
|
}
|
|
|
|
inline GXFifoObj *gulDefaultFifo()
|
|
{
|
|
return gul_gxDefaultFIFOObj;
|
|
}
|
|
|
|
inline GXRModeObj *gulGXRMode()
|
|
{
|
|
return gul_gxDefaultGXRenderMode;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
} // extern C
|
|
#endif
|