262 lines
6.2 KiB
Text
262 lines
6.2 KiB
Text
// shared MADCAT framework code
|
|
|
|
// skeleton class, doesn't have much other than the bare generic essentials
|
|
Class MadcatGameState abstract ui
|
|
{
|
|
Name GameName;
|
|
|
|
abstract MadcatGameState Init();
|
|
}
|
|
|
|
// state manager static thinker, to keep progress throughout a play session
|
|
// must be created by the static handler on map load if it doesn't exist
|
|
Class MadcatGameStateManager : Thinker
|
|
{
|
|
ui Array<MadcatGameState> GameState;
|
|
|
|
// return state object for a specific game name
|
|
// returns null if no state exists (caller must add a new one)
|
|
static ui MadcatGameState GetState( Name GameName )
|
|
{
|
|
let gsm = MadcatGameStateManager(ThinkerIterator.Create("MadcatGameStateManager").Next());
|
|
if ( !gsm ) ThrowAbortException("Game State Manager not found.");
|
|
foreach ( gs:gsm.GameState )
|
|
{
|
|
if ( gs.GameName != GameName ) continue;
|
|
return gs;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// adds a new game state object to the list
|
|
// if an object for the same game already exists, destroy and replace it
|
|
static ui void AddState( MadcatGameState NewState )
|
|
{
|
|
let gsm = MadcatGameStateManager(ThinkerIterator.Create("MadcatGameStateManager").Next());
|
|
if ( !gsm ) ThrowAbortException("Game State Manager not found.");
|
|
for ( int i=0; i<gsm.GameState.Size(); i++ )
|
|
{
|
|
if ( gsm.GameState[i].GameName != NewState.GameName ) continue;
|
|
gsm.GameState[i].Destroy();
|
|
gsm.GameState[i] = NewState;
|
|
return;
|
|
}
|
|
gsm.GameState.Push(NewState);
|
|
}
|
|
}
|
|
|
|
enum EMadcatGameState
|
|
{
|
|
CAT_BOOT,
|
|
CAT_MENU,
|
|
CAT_GAME
|
|
};
|
|
|
|
// barebones "game" object, the base code just displays the boot screen, and
|
|
// then switches state to the menu
|
|
// it's up to subclasses to handle the rest
|
|
Class MadcatGame ui
|
|
{
|
|
int global_state;
|
|
TextureID boot_tileset;
|
|
int boot_state, boot_timer;
|
|
bool bClosed;
|
|
|
|
int boot_tiles[360];
|
|
|
|
String oldmus;
|
|
int oldorder;
|
|
bool oldloop;
|
|
|
|
enum EBootState
|
|
{
|
|
BS_FADEIN,
|
|
BS_FLASH,
|
|
BS_FADEOUT,
|
|
BS_IDLE
|
|
};
|
|
|
|
private void Boot_PrepareTitle()
|
|
{
|
|
static const int tiles_logo[] =
|
|
{
|
|
48,49,50,48,51,50,52,51,50,48,51,53,48,51,50,54,55,53,
|
|
56,57,56,58,59,60,56,61,56,56,61,61,58,59,60,61,56,61,
|
|
62,61,62,63,64,65,66,51,67,68,51,53,63,64,65,61,62,61
|
|
};
|
|
boot_tiles[0] = 1;
|
|
for ( int i=1; i<23; i++ ) boot_tiles[i] = 2;
|
|
boot_tiles[23] = 3;
|
|
for ( int i=1; i<14; i++ ) boot_tiles[i*24] = 4;
|
|
for ( int i=1; i<14; i++ ) boot_tiles[i*24+23] = 5;
|
|
boot_tiles[336] = 6;
|
|
for ( int i=337; i<359; i++ ) boot_tiles[i] = 7;
|
|
boot_tiles[359] = 8;
|
|
boot_tiles[165] = 9;
|
|
for ( int i=0; i<18; i++ ) boot_tiles[i+147] = tiles_logo[i];
|
|
for ( int i=0; i<18; i++ ) boot_tiles[i+171] = tiles_logo[i+18];
|
|
for ( int i=0; i<18; i++ ) boot_tiles[i+195] = tiles_logo[i+36];
|
|
}
|
|
private void Boot_FadeInTiles()
|
|
{
|
|
for ( int i=0; i<360; i++ )
|
|
{
|
|
if ( !boot_tiles[i] ) continue;
|
|
else if ( boot_tiles[i] < 48 ) boot_tiles[i] += 9;
|
|
else boot_tiles[i] += 21;
|
|
}
|
|
}
|
|
private void Boot_PreFadeOutTiles()
|
|
{
|
|
for ( int i=0; i<360; i++ )
|
|
{
|
|
if ( !boot_tiles[i] ) continue;
|
|
else if ( boot_tiles[i] < 48 ) boot_tiles[i] += 27;
|
|
else boot_tiles[i] += 63;
|
|
}
|
|
}
|
|
private void Boot_FadeOutTiles()
|
|
{
|
|
for ( int i=0; i<360; i++ )
|
|
{
|
|
if ( !boot_tiles[i] ) continue;
|
|
else if ( boot_tiles[i] < 48 ) boot_tiles[i] -= 9;
|
|
else boot_tiles[i] -= 21;
|
|
}
|
|
}
|
|
private void Boot_FlashState()
|
|
{
|
|
if ( boot_timer%2 ) return;
|
|
int timer = boot_timer/2;
|
|
for ( int j=0; j<timer; j++ )
|
|
{
|
|
if ( j >= 18 ) continue;
|
|
if ( boot_tiles[j+147] && (boot_tiles[j+147] < 195) ) boot_tiles[j+147] += 21;
|
|
}
|
|
for ( int j=-1; j<timer-1; j++ )
|
|
{
|
|
if ( j < 0 ) continue;
|
|
if ( j >= 18 ) continue;
|
|
if ( (boot_tiles[j+171] < 195) ) boot_tiles[j+171] += 21;
|
|
}
|
|
for ( int j=-2; j<timer-2; j++ )
|
|
{
|
|
if ( j < 0 ) continue;
|
|
if ( j >= 18 ) continue;
|
|
if ( (boot_tiles[j+195] < 195) ) boot_tiles[j+195] += 21;
|
|
}
|
|
}
|
|
private void Boot_ClearTiles()
|
|
{
|
|
for ( int i=0; i<360; i++ ) boot_tiles[i] = 0;
|
|
}
|
|
|
|
// game has been booted up
|
|
virtual void Init()
|
|
{
|
|
oldmus = musplaying.name;
|
|
oldorder = musplaying.baseorder;
|
|
oldloop = musplaying.loop;
|
|
S_ChangeMusic("");
|
|
bClosed = false;
|
|
global_state = CAT_BOOT;
|
|
boot_state = BS_FADEIN;
|
|
boot_timer = -16;
|
|
boot_tileset = TexMan.CheckForTexture("graphics/Games/MadcatTiles.png");
|
|
}
|
|
|
|
// game is ticking
|
|
virtual void Tick()
|
|
{
|
|
// only bootup is handled here
|
|
if ( global_state != CAT_BOOT ) return;
|
|
switch ( boot_state )
|
|
{
|
|
case BS_FADEIN:
|
|
if ( boot_timer == 0 ) Boot_PrepareTitle();
|
|
else if ( !(boot_timer%4) && (boot_timer >= 4) ) Boot_FadeInTiles();
|
|
boot_timer++;
|
|
if ( boot_timer > 12 )
|
|
{
|
|
boot_state++;
|
|
boot_timer = -16;
|
|
}
|
|
break;
|
|
case BS_FLASH:
|
|
Boot_FlashState();
|
|
boot_timer++;
|
|
if ( boot_timer > 80 )
|
|
{
|
|
boot_state++;
|
|
boot_timer = 0;
|
|
}
|
|
else if ( boot_timer == 0 ) S_StartSound("madcat/boot",CHAN_VOICE,CHANF_UI,1.,0.);
|
|
break;
|
|
case BS_FADEOUT:
|
|
if ( boot_timer == 0 )
|
|
{
|
|
Boot_PrepareTitle();
|
|
Boot_PreFadeOutTiles();
|
|
}
|
|
else if ( !(boot_timer%4) && (boot_timer >= 4) ) Boot_FadeOutTiles();
|
|
boot_timer++;
|
|
if ( boot_timer > 12 )
|
|
{
|
|
boot_state++;
|
|
boot_timer = 0;
|
|
}
|
|
break;
|
|
case BS_IDLE:
|
|
boot_timer++;
|
|
if ( boot_timer == 4 ) Boot_ClearTiles();
|
|
else if ( boot_timer >= 40 )
|
|
{
|
|
global_state = CAT_MENU;
|
|
boot_state = 0;
|
|
boot_timer = 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// draw on the virtual screen
|
|
// coordinates are absolute
|
|
virtual void Draw( Vector2 screen_pos, double screen_zoom, double fractic )
|
|
{
|
|
// only bootup is handled here
|
|
if ( global_state != CAT_BOOT ) return;
|
|
for ( int i=0; i<360; i++ )
|
|
{
|
|
int tsx = (boot_tiles[i]&0x0F)*8;
|
|
int tsy = ((boot_tiles[i]&0xF0)>>4)*8;
|
|
int fsx = (i%24)*16;
|
|
int fsy = (i/24)*16;
|
|
Screen.DrawTexture(boot_tileset,false,
|
|
screen_pos.x+fsx*screen_zoom,
|
|
screen_pos.y+fsy*screen_zoom,
|
|
DTA_ScaleX,screen_zoom,DTA_ScaleY,screen_zoom,
|
|
DTA_SrcX,tsx,DTA_SrcY,tsy,
|
|
DTA_SrcWidth,8,DTA_SrcHeight,8,
|
|
DTA_DestWidth,16,DTA_DestHeight,16);
|
|
}
|
|
}
|
|
|
|
// process keyboard input
|
|
virtual bool ProcessInput( int key, bool release )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// game has been closed
|
|
virtual void Close()
|
|
{
|
|
bClosed = true;
|
|
S_ChangeMusic(oldmus,oldorder,oldloop);
|
|
}
|
|
|
|
override void OnDestroy()
|
|
{
|
|
if ( !bClosed ) Close();
|
|
Super.OnDestroy();
|
|
}
|
|
}
|