Code: Select all
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <gccore.h>
#include <wiiuse/wpad.h>
/* Small class for patching the game into the Wii System */
class WiiManager
{
private:
// VIDEO framebuffer
void *m_frameBuffer[2];
// Video mode
GXRModeObj *m_rmode;
// Init functions
void initVideoSystem();
public:
WiiManager();
virtual ~WiiManager();
// Break execution
void breakExec();
};
WiiManager::WiiManager()
{
// Initialise Wii VIDEO system
initVideoSystem();
}
void WiiManager::initVideoSystem()
{
u32 fb = 0; // initial framebuffer index
Mtx44 perspective; // Projection matrix
// Initialise the video system
VIDEO_Init();
// This function initialises the attached controllers
WPAD_Init();
// Obtain the preferred video mode from the system
// This will correspond to the settings in the Wii menu
m_rmode = VIDEO_GetPreferredMode(NULL);
// Allocate memory for the display in the uncached region
// for double buffering
m_frameBuffer[0] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(m_rmode)); //frames to draw on
m_frameBuffer[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(m_rmode)); //...
// Initialise the console, required for printf
//CON_InitEx(m_rmode, 20, 30, m_rmode->fbWidth - 40, m_rmode->xfbHeight - 60);
// Set up the video registers with the chosen mode
VIDEO_Configure(m_rmode);
// Tell the video hardware where our display memory is
VIDEO_SetNextFramebuffer(m_frameBuffer[fb]);
// Make the display visible
VIDEO_SetBlack(FALSE);
// Flush the video register changes to the hardware
VIDEO_Flush();
// Wait for Video setup to complete
VIDEO_WaitVSync();
if(m_rmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
// ##########################
// Setup the GX FIFO
// ##########################
//pointer to the buffer
void *fifo = NULL;
//Make a buffer to hold GX instructions, 32bit aligned
fifo = memalign(32,DEFAULT_FIFO_SIZE);
//Make sure it is all empty (fill it with 0's)
memset(fifo,0,DEFAULT_FIFO_SIZE); //Make sure it is all empty (fill it with 0's)
//Call GX_Init to set defaults for everything and extra setup stuff
GX_Init(fifo,DEFAULT_FIFO_SIZE);
// ##########################
// Set initial background color
// ##########################
//a color for the background (solid black with full alpha (can't see through it)
GXColor background = {0, 0, 0, 0xff};
//every copy to the screen, set color to 'background' and zbuffer to 0x00ffffff
GX_SetCopyClear(background, 0x00ffffff);
// ##########################
// Setting viewport and other stuff
// ##########################
//What area should GX be writing to on it's canvas?
GX_SetViewport(0,0,m_rmode->fbWidth,m_rmode->efbHeight,0,1);
//if the GX canvas is different in height than what you are rendering to the TV
int yscale = GX_GetYScaleFactor(m_rmode->efbHeight,m_rmode->xfbHeight);
//make is so that the TV looks like the canvas (useful if not 480p or anything)
int xfbHeight = GX_SetDispCopyYScale(yscale);
//What area should be rendered to on the frame? You can use this to do some tricks, like split screen and such
GX_SetScissor(0,0,m_rmode->fbWidth,m_rmode->efbHeight);
// ##########################
// Set the way that you copy from the GX canvas to
// the frame buffer for drawing
// ##########################
GX_SetDispCopySrc(0,0,m_rmode->fbWidth,m_rmode->efbHeight);
GX_SetDispCopyDst(m_rmode->fbWidth,xfbHeight);
GX_SetCopyFilter(m_rmode->aa,m_rmode->sample_pattern,GX_TRUE,m_rmode->vfilter);
GX_SetFieldMode(m_rmode->field_rendering,((m_rmode->viHeight==2*m_rmode->xfbHeight)?GX_ENABLE:GX_DISABLE));
// ##########################
// Set cull mode, copy display and gamma
// ##########################
//Which polygons should be removed?
GX_SetCullMode(GX_CULL_NONE);
//Draw the first frame from efb->xfb,clearing efb
GX_CopyDisp(m_frameBuffer[fb],GX_TRUE);
//How much gamma should be done?
GX_SetDispCopyGamma(GX_GM_1_0);
// ##########################
// Final tweaks, perspective and loading projection matrix
// ##########################
f32 w = m_rmode->viWidth;
f32 h = m_rmode->viHeight;
guPerspective(perspective, 45, (f32)w/h, 0.1F, 300.0F); // crash
GX_LoadProjectionMtx(perspective, GX_PERSPECTIVE);
}
WiiManager::~WiiManager(){}
int main (int argc, char *argv)
{
WiiManager *wii_manager= new WiiManager();
delete wii_manager;
}