This repository has been archived on 2026-05-18. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
GCNUtilLib/gul.c

303 lines
8.3 KiB
C
Raw Normal View History

2026-05-18 12:39:29 -04:00
#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