the cutting room mirror

LEGO Star Wars III: The Clone Wars (Nintendo DS)

This article has a talk page!This article has a talk page!
view on tcrf.net

LEGO! Star Wars! III! Clone Wars.

fedora.nbfc#

The data directory contains the icon from LEGO Indiana Jones: The Original Adventures.

Unused Character#

The man behind the counter in the HUB area can be switched to by using a moon-jump cheat to get behind the counter. He's basically a Clone Trooper without a helmet, except he doesn't have a gun and uses Obi-Wan's icon. He can also use The Force, unlike the other Clone Troopers.

Uncompiled Source Code#

In the same data directory contains a file named test.txt which seems to be for a knife-throwing game for the Wii.


#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "fnaDevice.h"
#include "fnaMatrix.h"
#include "fnaPrimitive.h"
#include "fnaTexture.h"
#include "fnaDebug.h"
#include "fnaLight.h"
#include "fnaController.h"

#include "fnFont.h"
#include "fnMaths.h"
#include "fnMemory.h"
#include "fnCollision.h"
#include "fnRender.h"
#include "fnAnimBones.h"

#include "geGameobject.h"

#include "..\Games.h"
#include "..\Controls.h"
#include "..\GameLoop.h"
#include "..\Players.h"
#include "..\ViewPorts.h"
#include "..\SoundFX.h"
#include "..\GOFlasher.h"
#include "..\Hud.h"
#include "..\Gestures.h"


//-----------------------------------------------------------------------------------------------------------------------------
fnOBJECT *Game058_FindChild(fnOBJECT *parentObject, const char *ChildName);


//-----------------------------------------------------------------------------------------------------------------------------
// Constants
const u32 GAME058_DURATION = 6000000;//6000;

const u32 NUM_KNIVES = 50;
const u32 NUM_THROW_TICKS = 35;


static u8 SoundFX[] = {
    SFX_WHISTLE,
    SFX_CAMERA,
    SFX_CROWDBOO,
    SFX_CROWDOOH,
    SFX_CROWDCHEER,
    SFX_CROWDLOOP,
    SFX_COUNTDOWN,
    GESOUND_NONE
};

//-----------------------------------------------------------------------------------------------------------------------------
// Enums
enum GAME058PLAYERSTATE {
    GAME058PLAYERSTATE_PLAYING,
    GAME058PLAYERSTATE_FINISHED,
};

enum GAME058KNIFESTATE {
    GAME058KNIFESTATE_FREE,
    GAME058KNIFESTATE_THROWING,
    GAME058KNIFESTATE_FALLING,
    GAME058KNIFESTATE_ON_FLOOR,
    GAME058KNIFESTATE_STUCK,
};


//-----------------------------------------------------------------------------------------------------------------------------
// Structs and classes
class Game058 : public Game {
public:
    Game058();
    void GameLoad();
    void GameExit();
    void GameUpdate(u32 tick, u32 player, fnINPUTDEVICE *joypad);
    void GameUpdateAll(u32 tick);
    void GameRender();
};


struct GAME058KNIFE
{
    GEGAMEOBJECT        *pKnife;
    GAME058KNIFESTATE   State;
    x32mat4             KnifeMat;
    x32mat4             StartMat;
    x32mat4             TargetMat;

    u32                 StartTick;
    u32                 EndTick;
};


struct GAME058PLAYER {
    GAME058PLAYERSTATE State;
    CONTROLPOINTER* pPointer;
    x32mat4         CameraMatrix;
    x32vec2         ScreenPos;
    fnCACHEITEM     *pPointerTexture;
    GEGAMEOBJECT    *GOCharacter;
    GEUIITEM*       _clogBar;

    u32             NumLaunched;
    GAME058KNIFE    Knives[NUM_KNIVES];

    GEGAMEOBJECT    *GOKnifeThrowing;
    GEGAMEOBJECT    *GOWheel;
//  fnOBJECT        *GOWheel;
    x32             WheelAngle;
};

struct GAME058DATA
{
    GAME058PLAYER       Players[4];
    GEGAMEOBJECT        *pKnife;
    u32                 TicksTaken;
    bool                HadGameStart;
    GESOUNDBANK         *SoundBank;

#ifdef _DEBUG
    fnFONT * pDebugFont;
    char DebugMsgBuffer[256];
#endif

};



//-----------------------------------------------------------------------------------------------------------------------------
// Globals
Game058 Game058Module;
Game *Game058Ptr = &Game058Module;
static x32vec2  UVTopLeft, UVTopRight, UVBottomRight, UVBottomLeft;
static GAME058DATA *pData;



//-----------------------------------------------------------------------------------------------------------------------------
// Functions
Game058::Game058() {
    levelname = "Game058KnifeThrowing";
    GameTextName = TXT_GAMETEXTWII_GAMENAME_026;
}

//-----------------------------------------------------------------------------------------------------------------------------
void Game058_InitPlayer(u32 playerIndex) {
    GAME058PLAYER* pPlayer  = &pData->Players[playerIndex];

    char buf[64];
    sprintf(buf, "Sprites/HandPoint%d.tga", playerIndex + 1);
    pPlayer->pPointerTexture = fnCache_Load(buf, fnCACHELOADTYPE_FOREGROUND);

    x32vec4 v4startEndPos;
    fnaMatrix_v4make(&v4startEndPos, fnFixedx32(-60.f), fnFixedx32(100.f), fnFixedx32(10.f), fnFixedx32(100.f));

    sprintf(buf, "Player%d", playerIndex+1);
    pPlayer->GOCharacter = geGameobject_FindGameobject(buf);

    pData->Players[playerIndex].pPointer = &Player_Get(playerIndex)->currentPointer;

    pPlayer->GOKnifeThrowing = geGameobject_FindGameobject("KnifeThrowing");
    fnaAssert( pPlayer->GOKnifeThrowing, "Game058_InitPlayer: Unable to find object KnifeThrowing" );

    pPlayer->GOWheel = geGameobject_FindGameobject("Wheel");
    fnaAssert( pPlayer->GOWheel, "Game058_InitPlayer: Unable to find object Wheel" );

//  pPlayer->GOWheel = Game058_FindChild(pPlayer->GOKnifeThrowing->object, "Wheel");
//  fnaAssert( pPlayer->GOWheel, "Game058_InitPlayer: Unable to find object Wheel" );

    for (u32 n=0; n<NUM_KNIVES; n++)
    {
        sprintf(buf, "Knife%02d", n + 1);
        pPlayer->Knives[n].State = GAME058KNIFESTATE_FREE;
        pPlayer->Knives[n].pKnife = (GEGAMEOBJECT*) geGameobject_FindGameobject(buf);
        fnaAssert( pPlayer->Knives[n].pKnife, fnaDebug_String("Game058_InitPlayer: Unable to find object %s", buf) );
    }
}

//-----------------------------------------------------------------------------------------------------------------------------
void Game058::GameLoad() {
    pData = (GAME058DATA*) fnMem_Alloc(sizeof(GAME058DATA));

    pData->pKnife = (GEGAMEOBJECT*) geGameobject_FindGameobject("Knife");

    pData->TicksTaken           = 0;
    pData->HadGameStart         = false;


    x32vec2 range = {fnFixedx32(0), fnFixedx32(115)};
    x32vec4 StartEndPos;
    switch(Player_Count)
    {
    case 1:
        fnaMatrix_v4make(&StartEndPos, -fnFixedx32(10), fnFixedx32(160), fnFixedx32(10), fnFixedx32(160));
        pData->Players[0]._clogBar = Hud_PercentCreate("sprites/EggandSpoonBar.tga", NULL, "sprites/EggandSpoonBarBit.tga", &range, &StartEndPos);
        break;
    case 2:
        fnaMatrix_v4make(&StartEndPos, -fnFixedx32(10), fnFixedx32(70), fnFixedx32(10), fnFixedx32(70));
        pData->Players[0]._clogBar = Hud_PercentCreate("sprites/EggandSpoonBar.tga", NULL, "sprites/EggandSpoonBarBit.tga", &range, &StartEndPos);

        fnaMatrix_v4make(&StartEndPos, fnFixedx32(660) * Hud_WideScreenScale, fnFixedx32(70), fnFixedx32(590) * Hud_WideScreenScale, fnFixedx32(70));
        pData->Players[1]._clogBar = Hud_PercentCreate("sprites/EggandSpoonBar.tga", NULL, "sprites/EggandSpoonBarBit.tga", &range, &StartEndPos);
        break;
    case 3:
        fnaMatrix_v4make(&StartEndPos, -fnFixedx32(10), fnFixedx32(70), fnFixedx32(10), fnFixedx32(70));
        pData->Players[0]._clogBar = Hud_PercentCreate("sprites/EggandSpoonBar.tga", NULL, "sprites/EggandSpoonBarBit.tga", &range, &StartEndPos);

        fnaMatrix_v4make(&StartEndPos, fnFixedx32(660) * Hud_WideScreenScale, fnFixedx32(70), fnFixedx32(590) * Hud_WideScreenScale, fnFixedx32(70));
        pData->Players[1]._clogBar = Hud_PercentCreate("sprites/EggandSpoonBar.tga", NULL, "sprites/EggandSpoonBarBit.tga", &range, &StartEndPos);

        fnaMatrix_v4make(&StartEndPos, -fnFixedx32(10), fnFixedx32(300), fnFixedx32(10), fnFixedx32(300));
        pData->Players[2]._clogBar = Hud_PercentCreate("sprites/EggandSpoonBar.tga", NULL, "sprites/EggandSpoonBarBit.tga", &range, &StartEndPos);
        break;
    case 4:
        fnaMatrix_v4make(&StartEndPos, -fnFixedx32(10), fnFixedx32(70), fnFixedx32(10), fnFixedx32(70));
        pData->Players[0]._clogBar = Hud_PercentCreate("sprites/EggandSpoonBar.tga", NULL, "sprites/EggandSpoonBarBit.tga", &range, &StartEndPos);

        fnaMatrix_v4make(&StartEndPos, fnFixedx32(660) * Hud_WideScreenScale, fnFixedx32(70), fnFixedx32(590) * Hud_WideScreenScale, fnFixedx32(70));
        pData->Players[1]._clogBar = Hud_PercentCreate("sprites/EggandSpoonBar.tga", NULL, "sprites/EggandSpoonBarBit.tga", &range, &StartEndPos);

        fnaMatrix_v4make(&StartEndPos, -fnFixedx32(10), fnFixedx32(300), fnFixedx32(10), fnFixedx32(300));
        pData->Players[2]._clogBar = Hud_PercentCreate("sprites/EggandSpoonBar.tga", NULL, "sprites/EggandSpoonBarBit.tga", &range, &StartEndPos);

        fnaMatrix_v4make(&StartEndPos, fnFixedx32(660) * Hud_WideScreenScale, fnFixedx32(300), fnFixedx32(590) * Hud_WideScreenScale, fnFixedx32(300));
        pData->Players[3]._clogBar = Hud_PercentCreate("sprites/EggandSpoonBar.tga", NULL, "sprites/EggandSpoonBarBit.tga", &range, &StartEndPos);
        break;
    }

    // The intro/countdown stages trash the camera1 settings, so save them for later
    fnaMatrix_v2make(&UVBottomRight,    fnFixedx32_Zero,    fnFixedx32_Zero);
    fnaMatrix_v2make(&UVBottomLeft, fnFixedx32_One,     fnFixedx32_Zero);
    fnaMatrix_v2make(&UVTopLeft,        fnFixedx32_One,     fnFixedx32_One);
    fnaMatrix_v2make(&UVTopRight,       fnFixedx32_Zero,    fnFixedx32_One);

    pData->SoundBank = geSoundBank_Load(SoundFX_Files, SoundFX);

#ifndef FNTARGET_PC
    //geSound_PlaySound(pGameData->SoundBank, SFX_CROWDLOOP, 0);
#endif
    fnaFile_SetDirectory("models/textures/");
    
    ViewPorts_Set(VIEWPORT_FULL, VIEWPORT_FULL, VIEWPORT_FULL, VIEWPORTFLAG_COUNTER);

    for (u32 playerIndex = 0; playerIndex < Player_Count; ++playerIndex)
    {
        Game058_InitPlayer(playerIndex);

        fnaMatrix_m4copy( &pData->Players[playerIndex].CameraMatrix, fnObject_GetMatrixPtr( geGameobject_FindGameobject( "Camera1" )->object ) );
    }

#ifdef _DEBUG
    pData->pDebugFont   = fnFont_Load( "Fonts/Tahoma10", FNFONTTYPE_3D );
    fnFont_SetColour( pData->pDebugFont, 0xffffffff);
    fnFont_SetAlphaBlend( pData->pDebugFont, FNALPHABLEND_SRCALPHA, FNALPHABLEND_INVSRCALPHA );
    fnFont_SetFormat( pData->pDebugFont, FNFONTPRINT_XJUSTLEFT, FNFONTPRINT_YJUSTTOP, false, false );
    fnFont_SetFont( pData->pDebugFont );
#endif // _DEBUG

}

//-----------------------------------------------------------------------------------------------------------------------------

void Game058::GameExit()
{
    geSoundBank_Destroy(pData->SoundBank);

    for (u8 playerIndex = 0; playerIndex < Player_Count; ++playerIndex) {
        GAME058PLAYER* pPlayer = &pData->Players[playerIndex];

        fnCache_Unload(pPlayer->pPointerTexture);

        if(pPlayer->_clogBar) {
            Hud_DestroyItem(pPlayer->_clogBar);
        }
    }

#ifdef _DEBUG
    fnFont_Destroy( pData->pDebugFont );
#endif

    fnMem_Free(pData);
}

//-----------------------------------------------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------------------------------------------------


fnOBJECT *Game058_FindChild(fnOBJECT *parentObject, const char *ChildName)
{

    fnOBJECT * pChildObj    = NULL;
    fnOBJECT * pRoot        = NULL;

    pRoot = fnObject_Find( parentObject, "root" );

    fnaAssert( pRoot, "Game058_FindChild: Unable to find object root" );

    for ( pChildObj = pRoot->firstchild; pChildObj != NULL; pChildObj = pChildObj->nextchild )
    {
        if ( strncmp( pChildObj->name, ChildName, strlen(ChildName) ) == 0 )
        {
            return pChildObj;
        }
    }

    return NULL;
}



x32mat4 *game058_CalcKnifePos(u32 player)
{
    GAME058PLAYER * pPlayer = &pData->Players[player];

    x32vec2 pointer = { pPlayer->ScreenPos.x, pPlayer->ScreenPos.y };

    x32vec3 rayEnd;
    fnCamera_ScreenToWorld(GameLoop_Camera[player], &pointer, 900.0f, &rayEnd);

    x32mat4 *pKnifeMat;
    pKnifeMat = fnObject_GetMatrixPtr(pData->pKnife->object);

    pKnifeMat->loc.x = rayEnd.x;
    pKnifeMat->loc.y = rayEnd.y;
    pKnifeMat->loc.z = rayEnd.z;

    fnObject_SetMatrix(pData->pKnife->object, pKnifeMat);

    return pKnifeMat;
}

GAME058KNIFE *Game058_FindFreeKnife(u32 player)
{
    GAME058PLAYER * pPlayer = &pData->Players[player];
    GAME058KNIFE *knife = NULL;

    for (u32 n=0; n<NUM_KNIVES; n++)
    {
        if (knife == NULL && pPlayer->Knives[n].State == GAME058KNIFESTATE_FREE)
            knife = &pPlayer->Knives[n];
    }

    return knife;
}

void Game058_ThrowKnife(u32 player, u32 tick)
{
    GAME058PLAYER * pPlayer = &pData->Players[player];

    GAME058KNIFE *knife = Game058_FindFreeKnife(player);
    if (knife)
    {
        knife->State = GAME058KNIFESTATE_THROWING;
        pPlayer->NumLaunched++;
        knife->StartTick = tick;
        knife->EndTick = tick + NUM_THROW_TICKS;

        fnaAssert( knife, "No free knives!" );

        x32mat4 *pPlayerMat;
        pPlayerMat = fnObject_GetMatrixPtr(pPlayer->GOCharacter->object);




        // need to get a proper launch point here
//      fnObject_SetMatrix(knife->pKnife->object, pPlayerMat);


        if ((pPlayer->NumLaunched&1)==0)
            knife->StartMat.loc.x = pPlayerMat->loc.x + fnFixedx32(36.0f) /* + fnFixedx32(pPlayer->NumLaunched * 2)*/;
        else
            knife->StartMat.loc.x = pPlayerMat->loc.x - fnFixedx32(36.0f) /* + fnFixedx32(pPlayer->NumLaunched * 2)*/;

        knife->StartMat.loc.y = pPlayerMat->loc.y + fnFixedx32(70.0f) /* + fnFixedx32(pPlayer->NumLaunched * 2)*/;
        knife->StartMat.loc.z = fnFixedx32(250.0f);

        fnaMatrix_m4copy(&knife->KnifeMat, pPlayerMat);

        sprintf( pData->DebugMsgBuffer, "num: %d  x: %f  y: %f  z: %f",pPlayer->NumLaunched, knife->StartMat.loc.x, knife->StartMat.loc.y, knife->StartMat.loc.z  );


        x32mat4 *pTargetMat;
        pTargetMat = game058_CalcKnifePos(player);
        fnaMatrix_m4copy(&knife->TargetMat, pTargetMat);

    }
}


void Game058_UpdateKnives(u32 player, u32 tick)
{
    GAME058PLAYER * pPlayer = &pData->Players[player];
    GAME058KNIFE *knife = NULL;
    u32 currtime;
    x32 lerp;

    for (u32 n=0; n<NUM_KNIVES; n++)
    {
        knife = &pPlayer->Knives[n];
        if (knife)
        {
            switch (knife->State)
            {
                case GAME058KNIFESTATE_THROWING:
                    currtime = tick-knife->StartTick;
                    lerp = fnFixedx32(currtime) / fnFixedx32(NUM_THROW_TICKS);

                    if (lerp >= fnFixedx32(1.0f))
                    {
                        lerp = fnFixedx32(1.0f);
                        knife->State = GAME058KNIFESTATE_STUCK;
                        fnObject_Unlink(knife->pKnife->object->parent, knife->pKnife->object);
                        fnObject_Attach( pPlayer->GOWheel->object, knife->pKnife->object );
                    }

                    x32mat4 posMatrix;
                    fnaMatrix_m4unit(&posMatrix);
                    fnaMatrix_v3lerpd(&posMatrix.loc.vec3, &knife->StartMat.loc.vec3, &knife->TargetMat.loc.vec3, lerp);

                    x32mat4 cameraMatrix;
                    fnaMatrix_m4unit( &cameraMatrix );
                    fnaMatrix_m3vec_to_matrix( &cameraMatrix, &knife->StartMat.loc.vec3, &knife->TargetMat.loc.vec3, fnFixedx32_Zero );

                    x32mat4 tmpMatrix;
                    fnaMatrix_m4prodd(&tmpMatrix, &cameraMatrix, &posMatrix);
                    fnaMatrix_m4copy(&knife->KnifeMat, &tmpMatrix);
                    fnObject_SetMatrix(knife->pKnife->object, &knife->KnifeMat);
                    break;

                case GAME058KNIFESTATE_STUCK:
                    break;
            }
        }
    }
}

void Game058_RotateWheel(u32 player)
{
    GAME058PLAYER * pPlayer = &pData->Players[player];
    pPlayer->WheelAngle += fnFixedx32(2.0f);
    GEGAMEOBJECT *wheel = pPlayer->GOWheel;

    x32mat4 rotZ;
    fnaMatrix_m4unit(&rotZ);
    fnaMatrix_m3rotz(&rotZ, fnMaths_DegreeToRad(pPlayer->WheelAngle));

    x32mat4 *pWheelMat = fnObject_GetMatrixPtr(wheel->object);
    fnaMatrix_m3copy(pWheelMat, &rotZ);
    fnObject_SetMatrix(wheel->object, pWheelMat);

}


//-----------------------------------------------------------------------------------------------------------------------------
void Game058_UpdatePlaying(u32 tick, u32 player, fnINPUTDEVICE* joypad) {
//  GAME058PLAYER * pPlayer = &pData->Players[player];


#ifdef FNTARGET_PC
    if (Controls_Mouse->buttons[FNINPUTMOUSE_BUTTON1].clicked)
#else
    if (joypad->buttons[CONTROLS_A].clicked)
//  if (Game054_UpdateNunchuck(player, joypad) > 2.0f)
#endif
    {
        Game058_ThrowKnife(player, tick);
    }

    Game058_RotateWheel(player);
    Game058_UpdateKnives(player, tick);
    game058_CalcKnifePos(player);

//  sprintf( pData->DebugMsgBuffer, "Num: %d", pPlayer->NumLaunched  );

}

//-----------------------------------------------------------------------------------------------------------------------------
void Game058_UpdateFinished(u32 tick, u32 player, fnINPUTDEVICE * joypad) {
    fnaController_StopMotor(joypad, 0);
}

//-----------------------------------------------------------------------------------------------------------------------------
void Game058_UpdateCursor(u32 player) { 
    GAME058PLAYER * pPlayer = &pData->Players[player];
//#ifdef FNTARGET_PC
//  pPlayer->pPointer->screenloc.x = Controls_Mouse->buttons[FNINPUTMOUSE_MOUSEX].value;
//  pPlayer->pPointer->screenloc.y = Controls_Mouse->buttons[FNINPUTMOUSE_MOUSEY].value;
//#endif
    pPlayer->ScreenPos.x = pPlayer->pPointer->screenloc.x;
    pPlayer->ScreenPos.y = pPlayer->pPointer->screenloc.y;

    if (pPlayer->ScreenPos.x < 0) 
        pPlayer->ScreenPos.x = 0;
    else if (pPlayer->ScreenPos.x > fusionInit.width) 
        pPlayer->ScreenPos.x = fusionInit.width;

    if (pPlayer->ScreenPos.y < 0) 
        pPlayer->ScreenPos.y = 0;
    else if (pPlayer->ScreenPos.y > fusionInit.height) 
        pPlayer->ScreenPos.y = fusionInit.height;   
}

//-----------------------------------------------------------------------------------------------------------------------------

void Game058::GameUpdate(u32 tick, u32 player, fnINPUTDEVICE *joypad) {
    Game058_UpdateCursor(player);

    switch (pData->Players[player].State)
    {
    case GAME058PLAYERSTATE_PLAYING:
        Game058_UpdatePlaying(tick, player, joypad);
        break;

    case GAME058PLAYERSTATE_FINISHED:
        Game058_UpdateFinished(tick, player, joypad);
        break;
    }
    pData->TicksTaken++;
}

//-----------------------------------------------------------------------------------------------------------------------------
void Game058::GameUpdateAll(u32 tick) {
    switch(GameLoop_CurrentStage)
    {
    case GAMELOOPSTAGE_INTRO:
        break;

    case GAMELOOPSTAGE_COUNTDOWN:
        if (GameLoop_CountDownTimer == 400) {
//          fnCamera_SetParallel(GameLoop_Camera[0], 100.0f);
//          x32vec3 org = geGameobject_FindGameobject("fleeceOrigin")->object->worldmatrix.loc.vec3;
//          fnCamera_WorldToScreen(GameLoop_Camera[0], &org, &pData->_fleeceOrigin);
        }

        for (u8 i = 0; i < Player_Count; ++i) {
            geUIItem_Show(pData->Players[i]._clogBar, 0);
        }

        if (GameLoop_CountDownTimer == geMain_UpdateFPS * 2)
            ViewPorts_ShowHud();

        if(!((GameLoop_CountDownTimer+1) % geMain_UpdateFPS))
            geSound_PlaySound(pData->SoundBank, SFX_COUNTDOWN, 0);

        if(GameLoop_CountDownTimer == geMain_UpdateFPS)
        {
            geSound_PlaySound(pData->SoundBank, SFX_WHISTLE, 0);
            geSound_PlaySound(pData->SoundBank, SFX_CROWDCHEER, 0);
            GOFlasher_RateIncrease();
        }

        for (u32 playerIndex = 0; playerIndex < Player_Count; ++playerIndex)
        {
            Game058_UpdateCursor(playerIndex);
        }

        if (!pData->HadGameStart)
        {
            GEGAMEOBJECT * cam = geGameobject_FindGameobject("Camera1");
            fnObject_SetMatrix(GameLoop_Camera[0], &cam->object->worldmatrix);
        }
        pData->HadGameStart = true;
        break;


    case GAMELOOPSTAGE_GAME:
        if (pData->TicksTaken >= GAME058_DURATION) {
            for (u8 player = 0; player < Player_Count; ++player) {
                pData->Players[player].State = GAME058PLAYERSTATE_FINISHED;
                fnaController_StopMotor(&Player_Get(player)->currentInput, 0);
            }
            
            GameLoop_CurrentStage = GAMELOOPSTAGE_OUTRO;
        }
        break;

    case GAMELOOPSTAGE_OUTRO:
        break;

    case GAMELOOPSTAGE_OUTRORECORDS:
        break;

    default:
        fnaFail("Game058::GameUpdateAll: Hit default case.");
        break;
    }
}

//-----------------------------------------------------------------------------------------------------------------------------
void Game058::GameRender() {
    fnaLight_ResetAll();

    for (u32 i = 0; i < Player_Count; ++i)
    {
        ViewPorts_Render(i, fnFixedx32(pData->TicksTaken) / fnFixedx32(geMain_UpdateFPS));

        GAME058PLAYER* pPlayer = &pData->Players[i];

        if (GameLoop_CurrentStage == GAMELOOPSTAGE_GAME || GameLoop_CurrentStage == GAMELOOPSTAGE_COUNTDOWN)
        {
            x32vec3 v3ScreenPos;

            v3ScreenPos.x = pPlayer->ScreenPos.x - 32;
            v3ScreenPos.y = pPlayer->ScreenPos.y - 32;
            v3ScreenPos.z = 0.f;

            u32 colour;
            switch (i)
            {
                case 0: colour = 0xffffffff; break;
                case 1: colour = 0xffff0000; break;
                case 2: colour = 0xff00ff00; break;
                case 3: colour = 0xff00ffff; break;
                default: colour = 0xffffffff; break;
            }

            geUISprite_Render(pPlayer->pPointerTexture, &v3ScreenPos, colour, true);
        }

//      Hud_SetPercentBar(pPlayer->_clogBar, displayedClipClog);
    }

#ifdef _DEBUG
    fnFont_SetFont( pData->pDebugFont );
    fnFont_SetLocation( 20, 5);
    fnFont_PrintString( pData->DebugMsgBuffer );
#endif // _DEBUG

}

There are six cheats that can be used in the main menu of the game, that are all applied to whichever save file is loaded afterwards. When a code is entered successfully an explosion sound can be heard. For some reason, the two cheats that give you studs only work on a new game and don't have any effect if you try to apply them to an existing save file.

Input

Description

Down, Up, Left, Left, Right, Right, Right, Down, L, R, L, R, Up, Up, Select

Give 1 million studs

Up, Down, Right, Right, Up, Up, L, R, L, R, L, L, R, R, Select

Give 3 million studs

Down, Down, Left, Right, L, L, R, R, Down, Down, R, R, L, L, Select

Unlock all Characters

L, R, L, L, Right, Right, Left, Left, Up, Down, R, L, L, R, Select

Unlock all Levels

Down, Up, Up, Up, Down, Up, L, R, R, L, Down, Down, Left, Right, Select

Unlock all Extras

Up, Down, Up, Up, Down, Down, L, L, L, L, Right, Right, Left, Right, Select

Unlock all Minikits

(Source: SporyTike (RetroAchievements.org))