swwmgz_m/zscript/games/swwm_madcat.zsc

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();
}
}