commit fcb7f3c172f689e431bf9f5fe3749a57c33de5c0 Author: Andrew Kesterson Date: Mon May 18 12:39:29 2026 -0400 Initial add, circa 2007 diff --git a/gul.c b/gul.c new file mode 100755 index 0000000..37cce3b --- /dev/null +++ b/gul.c @@ -0,0 +1,302 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// -------------- 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 diff --git a/gul.h b/gul.h new file mode 100755 index 0000000..3ae9f05 --- /dev/null +++ b/gul.h @@ -0,0 +1,100 @@ +/* This is just a library of functions I wrote to make my life + * as a gamecube programmer easier. It sets up GX, Video, + * the console, and the BBA at current. It sets system state + * flags, provides default FIFO and Framebuffers, and generally + * lets you focus more on your demo and less on getting the + * gamecube running. Thanks to Shagkur for writing libOGC. + + * Things you should know if you compile with gcc and not g++ + - This stuff uses alot of default arguments, which technically aren't + a part of C99, so GCC *shouldn't* let you use them when compiling + with GCC (my copy won't). So I have included a few workarounds + if you compile with GCC. If using GCC and you don't want to supply + all the arguments to GXSetup and similar functions that have + default args, you can pass 0 to most integer values and NULL to most others. + The functions will work out the rest themselves. + + NOTE: This is how this *SHOULD* work. The console and video stuff works + just fine, but for some reason the GXSetup() function craps out + when compiled in C and not C++ (tho I have no idea why). If someone + knows why, corrections are welcome. + + * Revision history: + + Aug 30, 2005: Renamed the library to GUL (Gamecube Utility Lib). + Separated it into code/headers properly. + Jan 30, 2005: Added autodetect code to VideoSetup() and renamed + the functions to all have a common 'gul' preface, + and left behind function pointers for backwards compatibility. + Added a couple functions + + + Copyright (C) 2005 Andrew Kesterson andrew@aklabs.net + + This program is free software; you can redistribute it and/or + modify it under the terms of the AKLabs Standard License, + included with this distribution. + + */ + +#ifndef _GUL_H_ +#define _GUL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SYSSTATE_GX_INIT 1 +#define SYSSTATE_VIDEO_INIT 2 +#define SYSSTATE_CONSOLE_INIT 3 +#define SYSSTATE_NET_INIT 4 + +#define FIFO_SIZE (256*1024) + +// ------------- External function defs --------------- + +extern Mtx *gulDefaultViewMatrix(); +extern Mtx *gulDefaultProjectionMatrix(); +extern void *gulUserFrameBuffer(); +extern GXFifoObj *gulDefaultFifo(); +extern GXRModeObj *gulGXRMode(); + +/* copies the userland FB to the XFB */ +extern void gulCopyXFB(u32 count); + +/* thisIP is the gamecube's IP, the gateway is the gateway to the world, and the + netmask is of course the netmask. To get DHCP, just use + gulSetupNetwork(true, NULL, NULL, NULL). */ +extern u32 gulSetupNetwork(bool dhcp, char *thisIP, char *gateway, char *netmask); + +/* sets up video - call with -> + VideoSetup(false, NULL, false) to setup xfb->efb copying on retrace + or use VideoSetup(true, NULL, false) to setup direct XFB access + (the XFB won't be cleared after each retrace) */ +extern u32 gulVideoSetup(bool XFBdirect, VIRetraceCallback callback, bool blackout); + +/* setup the console */ +extern void gulConsoleSetup(); + +/* sets up GX with a g_gxDefaultProjectionMatrix matrix + * also sets up the vertex format for direct vertex data + * (so you can just start throwing polys at it) */ +extern void gulGXSetup(u8 cullMode, Vector *camVector, Vector *upVector, + Vector *lookVector, f32 nearClip, f32 farClip); + +/* sets the framebuffer copy ready flag to true */ +extern void gulGXCopyReady(); + +/* 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?..." */ +extern void gulReloadFromPSO(); + +/* checks for a given system init state */ +extern bool gulWasInit(u32 subsys); +#endif // _GUL_H diff --git a/test.c b/test.c new file mode 100755 index 0000000..db46d4a --- /dev/null +++ b/test.c @@ -0,0 +1,10 @@ +#include "gul.h" + +int main(void) +{ + gulConsoleSetup(); + printf("Hello, world!"); + while ( 1 ) { + } + return 0; +}