Page MenuHomePhabricator (Chris)

No OneTemporary

Size
129 KB
Referenced Files
None
Subscribers
None
This document is not UTF8. It was detected as JIS and converted to UTF8 for display.
diff --git a/src/Backend.cpp b/src/Backend.cpp
index 7738a33..3a5de60 100644
--- a/src/Backend.cpp
+++ b/src/Backend.cpp
@@ -1,389 +1,390 @@
/***************************************************************************
Backend.cpp - description
-------------------
begin : Mon Dec 9 2002
copyright : (C) 2002 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include "common.h"
#include "Backend.h"
#include "Audio.h"
#include <string>
#include <stdarg.h>
-#include <EXTERN.h>
-#include <perl.h>
+#include "MszPerl.h"
/***************************************************************************
PUBLIC EXPORTED VARIABLES
***************************************************************************/
PerlInterpreter* my_perl;
Backend g_oBackend;
/***************************************************************************
PRIVATE VARIABLES (perl variable space)
***************************************************************************/
SV
*perl_bgx, *perl_bgy,
*perl_p1x, *perl_p1y, *perl_p1f, *perl_p1h,
*perl_p2x, *perl_p2y, *perl_p2f, *perl_p2h,
*perl_time, *perl_over, *perl_ko;
SV
*perl_doodad_x, *perl_doodad_y,
*perl_doodad_t, *perl_doodad_f,
*perl_doodad_dir, *perl_doodad_gfxowner,
*perl_doodad_text;
SV
*perl_sound;
/***************************************************************************
BACKEND CLASS IMPLEMENTATION
***************************************************************************/
#define PERLEVAL(A) eval_pv(A, TRUE);
#define PERLCALL(PROC,A,B) { \
dSP; \
ENTER; \
SAVETMPS; \
PUSHMARK(SP); \
XPUSHs(sv_2mortal(newSViv(A))); \
XPUSHs(sv_2mortal(newSViv(B))); \
PUTBACK ; \
\
call_pv( (PROC), G_DISCARD ); \
\
FREETMPS; \
LEAVE; \
}
Backend::Backend()
{
m_iBgX = m_iBgY = 0;
m_iNumDoodads = m_iNumSounds = 0;
for ( int i=0; i<2; ++i )
{
m_aoPlayers[i].m_iX = m_aoPlayers[i].m_iY = 0;
m_aoPlayers[i].m_iFrame = 0;
m_aoPlayers[i].m_iHitPoints = 0;
}
}
Backend::~Backend()
{
if ( NULL != my_perl )
{
perl_destruct( my_perl );
perl_free( my_perl );
my_perl = NULL;
}
}
bool Backend::Construct()
{
if ( my_perl != NULL )
{
// Already inited
return false;
}
perl_bgx = NULL;
perl_doodad_x = NULL;
std::string sFileName = DATADIR;
sFileName += "/script";
-
+
+#ifndef _WINDOWS
chdir( sFileName.c_str() );
+#endif
char *perl_argv[] = {"", "Backend.pl"};
my_perl = perl_alloc();
if ( my_perl == NULL )
{
return false;
}
perl_construct( my_perl );
if ( perl_parse( my_perl, NULL, 2, perl_argv, (char**)NULL ) )
{
char *error = SvPV_nolen(get_sv("@", FALSE));
fprintf( stderr, "%s", error );
return false;
}
if ( perl_run( my_perl ) )
{
char *error = SvPV_nolen(get_sv("@", FALSE));
fprintf( stderr, "%s", error );
return false;
}
return true;
}
const char* Backend::PerlEvalF( const char* a_pcFormat, ... )
{
va_list ap;
va_start( ap, a_pcFormat );
char acBuffer[1024];
vsnprintf( acBuffer, 1023, a_pcFormat, ap );
acBuffer[1023] = 0;
PERLEVAL(acBuffer);
const char *pcError = SvPV_nolen(get_sv("@", FALSE));
if ( pcError )
{
fprintf( stderr, "%s", pcError );
}
va_end( ap );
return pcError;
}
const char* Backend::GetPerlString( const char* acScalarName )
{
SV* poScalar = get_sv( acScalarName, FALSE );
if ( NULL == poScalar )
{
return "";
}
return SvPV_nolen( poScalar );
}
int Backend::GetPerlInt( const char* acScalarName )
{
SV* poScalar = get_sv( acScalarName, FALSE );
if ( NULL == poScalar )
{
return 0;
}
return SvIV( poScalar );
}
void Backend::AdvancePerl()
{
PERLEVAL("GameAdvance();");
}
void Backend::ReadFromPerl()
{
if ( perl_bgx == NULL )
{
perl_bgx = get_sv("bgx", TRUE);
perl_bgy = get_sv("bgy", TRUE);
perl_p1x = get_sv("p1x", TRUE);
perl_p1y = get_sv("p1y", TRUE);
perl_p1f = get_sv("p1f", TRUE);
perl_p1h = get_sv("p1h", TRUE);
perl_p2x = get_sv("p2x", TRUE);
perl_p2y = get_sv("p2y", TRUE);
perl_p2f = get_sv("p2f", TRUE);
perl_p2h = get_sv("p2h", TRUE);
perl_time= get_sv("time", TRUE);
perl_over= get_sv("over", TRUE);
perl_ko = get_sv("ko", TRUE);
}
m_iBgX = SvIV( perl_bgx );
m_iBgY = SvIV( perl_bgy );
m_aoPlayers[0].m_iX = SvIV( perl_p1x );
m_aoPlayers[0].m_iY = SvIV( perl_p1y );
m_aoPlayers[0].m_iFrame = SvIV( perl_p1f );
m_aoPlayers[0].m_iHitPoints = SvIV( perl_p1h ) / 10;
m_aoPlayers[1].m_iX = SvIV( perl_p2x );
m_aoPlayers[1].m_iY = SvIV( perl_p2y );
m_aoPlayers[1].m_iFrame = SvIV( perl_p2f );
m_aoPlayers[1].m_iHitPoints = SvIV( perl_p2h ) / 10;
m_iGameTime = SvIV( perl_time );
m_iGameOver = SvIV( perl_over );
m_bKO = SvIV( perl_ko );
// READ DOODAD DATA
if ( perl_doodad_x == NULL )
{
perl_doodad_x = get_sv("doodad_x", TRUE);
perl_doodad_y = get_sv("doodad_y", TRUE);
perl_doodad_t = get_sv("doodad_t", TRUE);
perl_doodad_f = get_sv("doodad_f", TRUE);
perl_doodad_dir = get_sv("doodad_dir", TRUE);
perl_doodad_gfxowner = get_sv("doodad_gfxowner", TRUE);
perl_doodad_text = get_sv("doodad_text", TRUE);
}
for ( m_iNumDoodads=0; m_iNumDoodads<MAXDOODADS; ++m_iNumDoodads )
{
PERLEVAL("GetNextDoodadData();");
SDoodad& oDoodad = m_aoDoodads[m_iNumDoodads];
oDoodad.m_iType = SvIV(perl_doodad_t);
if ( oDoodad.m_iType < 0 )
{
break;
}
oDoodad.m_iX = SvIV(perl_doodad_x);
oDoodad.m_iY = SvIV(perl_doodad_y);
oDoodad.m_iFrame = SvIV(perl_doodad_f);
oDoodad.m_iDir = SvIV(perl_doodad_dir);
oDoodad.m_iGfxOwner = SvIV(perl_doodad_gfxowner);
if ( oDoodad.m_iType == 0 )
{
oDoodad.m_sText = SvPV_nolen(perl_doodad_text);
}
else
{
- oDoodad.m_sText.clear();
+ oDoodad.m_sText = "";
}
}
// READ SOUND DATA
if ( perl_sound == NULL )
{
perl_sound = get_sv("sound", TRUE);
}
for ( m_iNumSounds=0; m_iNumSounds<MAXSOUNDS; ++m_iNumSounds )
{
PERLEVAL("GetNextSoundData();");
const char* pcSound = SvPV_nolen(perl_sound);
if ( NULL == pcSound
|| 0 == *pcSound )
{
break;
}
m_asSounds[ m_iNumSounds ] = pcSound;
//Audio->PlaySample( pcSound );
}
}
void Backend::PlaySounds()
{
for ( int i=0; i<m_iNumSounds; ++i )
{
Audio->PlaySample( m_asSounds[i].c_str() );
}
}
/***************************************************************************
PLAYBACK STRING CONVERSION ROUTINES
***************************************************************************/
void Backend::WriteToString( std::string& a_rsOutString )
{
char acBuffer[2048];
int iNumChars = sprintf( acBuffer, "%d %d %d %d %d %d %d %d %d %d %d ",
m_iBgX, m_iBgY,
m_aoPlayers[0].m_iX, m_aoPlayers[0].m_iY, m_aoPlayers[0].m_iFrame, m_aoPlayers[0].m_iHitPoints,
m_aoPlayers[1].m_iX, m_aoPlayers[1].m_iY, m_aoPlayers[1].m_iFrame, m_aoPlayers[1].m_iHitPoints,
m_iNumDoodads );
int i;
for ( i = 0; i<m_iNumDoodads; ++i )
{
SDoodad& roDoodad = m_aoDoodads[i];
iNumChars += sprintf( acBuffer+iNumChars, "%d %d %d %d %d %d %d %s ",
roDoodad.m_iX, roDoodad.m_iY, roDoodad.m_iType, roDoodad.m_iFrame,
roDoodad.m_iDir, roDoodad.m_iGfxOwner,
roDoodad.m_sText.size(), roDoodad.m_sText.c_str() );
}
iNumChars += sprintf( acBuffer+iNumChars, "%d ", m_iNumSounds );
for ( i = 0; i<m_iNumSounds; ++i )
{
iNumChars += sprintf( acBuffer+iNumChars, " %d %s",
m_asSounds[i].size(), m_asSounds[i].c_str() );
}
// debug( "Frame: '%s'\n", acBuffer );
a_rsOutString = acBuffer;
}
void Backend::ReadFromString( const std::string& a_rsString )
{
const char* pcBuffer = a_rsString.c_str();
int iNumMatches;
int iOffset, iTotal;
iNumMatches = sscanf( pcBuffer, "%d %d %d %d %d %d %d %d %d %d %d%n",
&m_iBgX, &m_iBgY,
&m_aoPlayers[0].m_iX, &m_aoPlayers[0].m_iY, &m_aoPlayers[0].m_iFrame, &m_aoPlayers[0].m_iHitPoints,
&m_aoPlayers[1].m_iX, &m_aoPlayers[1].m_iY, &m_aoPlayers[1].m_iFrame, &m_aoPlayers[1].m_iHitPoints,
&m_iNumDoodads, &iTotal );
if ( m_iNumDoodads > MAXDOODADS )
{
m_iNumDoodads = m_iNumSounds = 0;
return;
}
int i, j;
for ( i=0; i<m_iNumDoodads; ++i )
{
SDoodad& roDoodad = m_aoDoodads[i];
iNumMatches += sscanf( pcBuffer+iTotal, "%d %d %d %d %d %d %d %n",
&roDoodad.m_iX, &roDoodad.m_iY, &roDoodad.m_iType, &roDoodad.m_iFrame,
&roDoodad.m_iDir, &roDoodad.m_iGfxOwner,
&j, &iOffset );
iTotal += iOffset;
roDoodad.m_sText.assign( pcBuffer + iTotal, j );
iTotal += j;
}
iNumMatches += sscanf( pcBuffer + iTotal, "%d%n",
&m_iNumSounds, &iOffset );
if ( m_iNumSounds > MAXSOUNDS )
{
m_iNumSounds = 0;
return;
}
iTotal += iOffset;
for ( i=0; i<m_iNumSounds; ++i )
{
iNumMatches += sscanf( pcBuffer+iTotal, "%d %n",
&j, &iOffset );
iTotal += iOffset;
m_asSounds[i].assign( pcBuffer + iTotal, j );
iTotal += j;
}
}
diff --git a/src/Demo.cpp b/src/Demo.cpp
index 465fa99..761a67d 100644
--- a/src/Demo.cpp
+++ b/src/Demo.cpp
@@ -1,358 +1,400 @@
/***************************************************************************
Demo.cpp - description
-------------------
begin : Wed Aug 16 22:18:47 CEST 2003
copyright : (C) 2003 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include "FlyingChars.h"
#include "SDL.h"
#include "State.h"
#include "gfx.h"
#include "common.h"
#include "Backend.h"
#include "Demo.h"
Demo::Demo()
{
m_poFlyingChars = NULL;
m_bAdvanceGame = false;
}
Demo::~Demo()
{
delete m_poFlyingChars;
m_poFlyingChars = NULL;
}
int Demo::Advance( int a_iNumFrames, bool a_bFlip )
{
int iRetVal = 1;
if ( a_iNumFrames > 5 )
a_iNumFrames = 5;
if ( m_poBackground )
{
SDL_BlitSurface( m_poBackground, NULL, gamescreen, NULL );
}
if ( m_poFlyingChars )
{
iRetVal &= AdvanceFlyingChars( a_iNumFrames );
m_poFlyingChars->Draw();
}
if ( m_bAdvanceGame )
{
iRetVal &= AdvanceGame( a_iNumFrames );
//@ DRAW GAME?
}
if ( a_bFlip )
{
SDL_Flip( gamescreen );
}
return iRetVal;
}
int Demo::AdvanceFlyingChars( int a_iNumFrames )
{
m_poFlyingChars->Advance( a_iNumFrames );
return ( m_poFlyingChars->IsDone() ? 1 : 0 );
}
int Demo::AdvanceGame( int a_iNumFrames )
{
for ( int i=0; i<a_iNumFrames; ++i )
{
g_oBackend.AdvancePerl();
}
return 0;
}
int Demo::Run()
{
+ SState::TGameMode enOriginalGameMode = g_oState.m_enGameMode;
+
int thisTick, lastTick, firstTick, gameSpeed;
SDL_Event event;
gameSpeed = 12;
thisTick = SDL_GetTicks() / gameSpeed;
lastTick = thisTick - 1;
firstTick = SDL_GetTicks() / gameSpeed;
while ( 1 )
{
// 1. Wait for the next tick (on extremely fast machines..)
while (1)
{
thisTick = SDL_GetTicks() / gameSpeed;
if ( thisTick==lastTick )
{
SDL_Delay(1);
}
else
{
break;
}
}
// 2. Call ADVANCE.
int iRetVal = Advance(thisTick-lastTick, true);
lastTick = thisTick;
if ( iRetVal )
{
return 0;
}
// 3. Handle events.
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
g_oState.m_bQuitFlag = true;
break;
case SDL_KEYDOWN:
if ( event.key.keysym.sym == SDLK_ESCAPE )
{
OnMenu();
break;
}
+ if ( event.key.keysym.sym == SDLK_F1 )
+ {
+ return 0;
+ }
for ( int i=0; i<2; ++i )
{
for ( int j=0; j<9; ++j )
{
if ( g_oState.m_aiPlayerKeys[i][j] == event.key.keysym.sym)
{
g_oState.m_enGameMode = SState::IN_MULTI;
}
}
}
break;
} // switch
} // while SDL_PollEvent
- if ( g_oState.m_enGameMode != SState::IN_DEMO
+ if ( g_oState.m_enGameMode != enOriginalGameMode
|| g_oState.m_bQuitFlag )
{
return 1;
}
} // while 1;
}
void DoMenu( bool a_bDrawBackground );
void Demo::OnMenu()
{
::DoMenu( true );
}
class CreditsDemo: public Demo
{
public:
CreditsDemo()
{
m_poBackground = LoadBackground( "Credits.png", 240 );
SDL_UnlockSurface( m_poBackground );
DrawGradientText( "Credits", titleFont, 20, m_poBackground );
SDL_Flip( m_poBackground );
SDL_Rect oRect;
oRect.x = 110; oRect.w = gamescreen->w - 220;
oRect.y = 100; oRect.h = 350;
m_poFlyingChars = new FlyingChars( creditsFont, oRect );
m_poFlyingChars->AddText( "OPENMORTAL CREDITS\n\n\n"
"-- THE OPENMORTAL TEAM ARE --\n\n"
"CODING - UPi\n"
"MUSIC - Oedipus\n"
"GRAPHICS - UPi\n"
"\n-- CAST --\n\n"
"Boxer - Zoli\n"
"Cumi - As himself\n"
"Descant - As himself\n"
"Fureszes Orult - Ambrus\n"
"Grizli - As himself\n"
"Kinga - As herself\n"
"Macy - As herself\n"
"Misi - As himself\n"
"Rising-san - Surba\n"
"Sirpi - As himself\n"
"Taka Ito - Bence\n"
"Tokeletlen Katona - Dani\n"
"Watasiwa Baka Janajo - Ulmar\n"
"Black Dark Evil Mage - UPi\n"
"\n-- HOSTING --\n\n"
"sourceforge.net\n"
"apocalypse.rulez.org\n"
"freshmeat.net\n"
"\nOpenMortal is Copyright 2003 of the OpenMortal Team\n"
"Distributed under the GNU General Public Licence Version 2\n\n",
FlyingChars::FC_AlignCenter, true );
m_poFlyingChars->AddText( "Thanks to Midway for not harrassing us with legal stuff so far, "
"even though we must surely violate at least 50 of their patents, international "
"copyrights and registered trademarks.\n\n"
"OpenMortal needs your help! If you can contribute music, graphics, improved code, "
"additional characters, cash, beer, pizza or any other consumable, please mail us "
"at upi@apocalypse.rulez.org! The same address is currently accepting comments and "
"fanmail too (hint, hint!).\n\n",
FlyingChars::FC_AlignJustify, true );
m_poFlyingChars->AddText( "Be sure to check out other stuff from\n"
"Apocalypse Production\n"
"and\n"
"Degec Entertainment\n\n",
FlyingChars::FC_AlignCenter, true );
m_poFlyingChars->AddText( "\n\n\n\n\n\n:)", FlyingChars::FC_AlignRight, true );
}
};
class Story1Demo: public Demo
{
public:
Story1Demo()
{
m_poBackground = LoadBackground( "Story1.png", 240 );
SDL_UnlockSurface( m_poBackground );
SDL_Rect oRect;
oRect.x = 50; oRect.w = gamescreen->w - 100;
oRect.y = 50; oRect.h = gamescreen->h - 100;
m_poFlyingChars = new FlyingChars( storyFont, oRect, -1 );
m_poFlyingChars->AddText(
"We, the Gods of the Evil Killer Black Antipathic Dim (witted) Fire Mages "
"no longer tolerate the lack of evildoing.\n\n"
"We send them out on a "
"mission so diabolical, so evil that the world will never be the same "
"again!\n\n"
"We order our unworthy followers to "
"\nDESTROY THE SATURDAY\n"
"and plunge humanity into a dark age of 5 working days and 1 holiday "
"per week... FOREVER!\n\n\n\n\n\n\n\n\n",
FlyingChars::FC_AlignJustify, true );
}
};
+class Story2Demo: public Demo
+{
+public:
+ Story2Demo()
+ {
+ m_poBackground = LoadBackground( "Story2.png", 240 );
+ SDL_UnlockSurface( m_poBackground );
+
+ SDL_Rect oRect;
+ oRect.x = 50; oRect.w = gamescreen->w - 100;
+ oRect.y = 50; oRect.h = gamescreen->h - 100;
+
+ m_poFlyingChars = new FlyingChars( storyFont, oRect, -1 );
+ m_poFlyingChars->AddText(
+"Whenever EVIL looms on the horizon, the good guys are there to "
+"save the day. Son Goku, the protector of Earth and Humanity "
+"went to the rescue...\n\n"
+
+"Only to become ROADKILL on his way to the Mortal Szombat "
+"tournament! It was Cumi's first time behind the wheel, after all...\n\n\n\n\n\n\n\n\n",
+ FlyingChars::FC_AlignJustify, true );
+ }
+};
+
class MainScreenDemo: public Demo
{
public:
MainScreenDemo()
{
m_iTimeLeft = 100;
m_poBackground = LoadBackground( "Mortal.png", 240 );
}
int Advance( int a_iNumFrames, bool a_bFlip )
{
m_iTimeLeft -= a_iNumFrames;
Demo::Advance( a_iNumFrames, true );
return ( m_iTimeLeft <= 0 ) ? 1 : 0;
}
protected:
int m_iTimeLeft;
};
void DoReplayDemo()
{
static int aiOrder[6] = {-1, -1, -1, -1, -1, -1};
static int iNext = 0;
if ( aiOrder[0]<0 )
{
// shuffle
int i, j, k;
for ( i=0; i<6; ++i ) aiOrder[i]=i;
for ( i=0; i<6; ++i )
{
j = rand() % 6;
k = aiOrder[i];
aiOrder[i] = aiOrder[j];
aiOrder[j] = k;
}
iNext = 0;
}
char acFilename[1024];
sprintf( acFilename, DATADIR "/demo%d.om", aiOrder[iNext] );
// DoGame( acFilename, true, false );
iNext = ( iNext + 1 ) % 6;
}
void DoDemos()
{
#define DoDemos_BREAKONEND \
if ( g_oState.m_enGameMode != SState::IN_DEMO \
|| g_oState.m_bQuitFlag ) \
return;
while (1)
{
DoDemos_BREAKONEND;
{
MainScreenDemo oDemo;
oDemo.Run();
}
DoDemos_BREAKONEND;
DoReplayDemo();
DoDemos_BREAKONEND;
{
Story1Demo oDemo;
oDemo.Run();
}
DoDemos_BREAKONEND;
DoReplayDemo();
DoDemos_BREAKONEND;
{
FighterStatsDemo oDemo;
oDemo.Run();
}
DoDemos_BREAKONEND;
DoReplayDemo();
DoDemos_BREAKONEND;
+ {
+ Story2Demo oDemo;
+ oDemo.Run();
+ }
+ DoDemos_BREAKONEND;
+ {
+ FighterStatsDemo oDemo;
+ oDemo.Run();
+ }
+ DoDemos_BREAKONEND;
+ DoReplayDemo();
+ DoDemos_BREAKONEND;
{
CreditsDemo oDemo;
oDemo.Run();
}
DoDemos_BREAKONEND;
}
}
diff --git a/src/Demo.h b/src/Demo.h
index 0d54f23..35d4ef1 100644
--- a/src/Demo.h
+++ b/src/Demo.h
@@ -1,59 +1,59 @@
/***************************************************************************
Demo.h - description
-------------------
begin : Wed Aug 16 22:18:47 CEST 2003
copyright : (C) 2003 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#ifndef DEMO_H
#define DEMO_H
class FlyingChars;
struct SDL_Surface;
class Demo
{
public:
Demo();
virtual ~Demo();
virtual int Run();
protected:
virtual int Advance( int a_iNumFrames, bool a_bFlip );
virtual int AdvanceFlyingChars( int a_iNumFrames );
virtual int AdvanceGame( int a_iNumFrames );
virtual void OnMenu();
protected:
FlyingChars* m_poFlyingChars;
bool m_bAdvanceGame;
SDL_Surface* m_poBackground;
};
class FighterStatsDemo: public Demo
{
public:
- FighterStatsDemo();
+ FighterStatsDemo( FighterEnum a_iFighter = UNKNOWN );
virtual ~FighterStatsDemo();
int Advance( int a_iNumFrames, bool a_bFlip );
protected:
int m_iTimeLeft;
FighterEnum m_enFighter;
RlePack* m_poStaff;
static int mg_iLastFighter; // index of the last fighter in the fighter order
static FighterEnum mg_aenFighterOrder[LASTFIGHTER-1];
};
#endif // DEMO_H
diff --git a/src/FighterStats.cpp b/src/FighterStats.cpp
index 61c2f11..dd9fb24 100644
--- a/src/FighterStats.cpp
+++ b/src/FighterStats.cpp
@@ -1,242 +1,248 @@
/***************************************************************************
FighterStats.cpp - description
-------------------
begin : Tue Dec 10 2002
copyright : (C) 2002 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include <stdio.h>
#include <string>
#include "PlayerSelect.h"
#include "FlyingChars.h"
#include "SDL.h"
#include "SDL_video.h"
#include "SDL_image.h"
#include "sge_tt_text.h"
#include "common.h"
#include "gfx.h"
#include "RlePack.h"
#include "Backend.h"
#include "Demo.h"
-#include <EXTERN.h>
-#include <perl.h>
+#include "MszPerl.h"
extern PerlInterpreter* my_perl;
#define LEFTMARGIN 160
#define TOPMARGIN 70
#define RIGHTMARGIN 630
#define LINEHEIGHT 35
#define GAPWIDTH 20
#define DESCMARGIN 50
#define LEFTMARGIN2 ((LEFTMARGIN+RIGHTMARGIN+GAPWIDTH)/2)
/*
void DrawMultiLineText( const char* text, _sge_TTFont* font, int x, int y,
int fg, SDL_Surface* target )
{
const char* s1, * s2;
char line[1024];
s1 = s2 = text;
while (1)
{
while ( isspace(*s2) ) s2++;
if ( !*s2 )
break;
s1 = s2; // s1: start of line.
while ( (*s2 != '\n') && *s2 ) s2++;
strncpy( line, s1, s2-s1 );
line[s2-s1] = 0;
DrawTextMSZ( line, font, x, y, 0, fg, target );
y += sge_TTF_FontLineSkip( font );
}
}
*/
int FighterStatsDemo::mg_iLastFighter = -1;
FighterEnum FighterStatsDemo::mg_aenFighterOrder[LASTFIGHTER-1];
-FighterStatsDemo::FighterStatsDemo()
+FighterStatsDemo::FighterStatsDemo( FighterEnum a_iFighter )
{
m_iTimeLeft = 500;
m_poStaff = NULL;
m_poBackground = LoadBackground( "FighterStats.png", 64 );
DrawGradientText( "Figher Stats", titleFont, 10, m_poBackground );
SDL_BlitSurface( m_poBackground, NULL, gamescreen, NULL );
SDL_Flip( gamescreen );
if ( mg_iLastFighter < 0 )
{
// First run; create shuffled array of figthers.
mg_iLastFighter = 0;
int i, j;
FighterEnum k;
for ( i=0; i<LASTFIGHTER-1; ++i )
{
mg_aenFighterOrder[i] = (FighterEnum)(i+1);
}
for ( i=0; i<LASTFIGHTER-1; ++i )
{
j = rand() % (LASTFIGHTER-1);
k = mg_aenFighterOrder[i];
mg_aenFighterOrder[i] = mg_aenFighterOrder[j];
mg_aenFighterOrder[j] = k;
}
}
- mg_iLastFighter = (mg_iLastFighter+1) % (LASTFIGHTER-1);
- m_enFighter = mg_aenFighterOrder[mg_iLastFighter];
+ if ( a_iFighter <= UNKNOWN )
+ {
+ mg_iLastFighter = (mg_iLastFighter+1) % (LASTFIGHTER-1);
+ m_enFighter = mg_aenFighterOrder[mg_iLastFighter];
+ }
+ else
+ {
+ m_enFighter = a_iFighter;
+ }
if ( g_oPlayerSelect.IsFighterAvailable( m_enFighter ) )
{
g_oPlayerSelect.SetPlayer( 0, m_enFighter );
g_oBackend.PerlEvalF( "SelectStart();" );
}
else
{
std::string sStaffFilename = DATADIR;
sStaffFilename += "/characters/STAFF.DAT";
m_poStaff = new RlePack( sStaffFilename.c_str(), 240 );
}
g_oBackend.PerlEvalF("GetFighterStats(%d);", m_enFighter );
_sge_TTFont* font = impactFont;
int y = TOPMARGIN;
AV *StatTags = get_av( "StatTags", FALSE );
char *s, *sTag;
s = SvPV_nolen(get_sv("Name", FALSE));
DrawTextMSZ( s, inkFont, (LEFTMARGIN + RIGHTMARGIN)/2, y, AlignHCenter, C_WHITE, m_poBackground );
y+= 10;
s = SvPV_nolen(get_sv("Team", FALSE ));
sTag = SvPV_nolen( *av_fetch( StatTags, 1, false ) );
int i = DrawTextMSZ( sTag, font, LEFTMARGIN, y+=LINEHEIGHT, 0, C_YELLOW, m_poBackground );
DrawTextMSZ( s, font, LEFTMARGIN+i, y, 0, C_ORANGE, m_poBackground );
s = SvPV_nolen(get_sv("Style", FALSE ));
sTag = SvPV_nolen( *av_fetch( StatTags, 2, false ) );
i = DrawTextMSZ( sTag, font, LEFTMARGIN2, y, 0, C_YELLOW, m_poBackground );
DrawTextMSZ( s, font, LEFTMARGIN2+i, y, 0, C_ORANGE, m_poBackground );
s = SvPV_nolen(get_sv("Age", FALSE ));
sTag = SvPV_nolen( *av_fetch( StatTags, 3, false ) );
i = DrawTextMSZ( sTag, font, LEFTMARGIN, y+=LINEHEIGHT, 0, C_YELLOW, m_poBackground );
DrawTextMSZ( s, font, LEFTMARGIN+i, y, 0, C_ORANGE, m_poBackground );
s = SvPV_nolen(get_sv("Weight", FALSE ));
sTag = SvPV_nolen( *av_fetch( StatTags, 4, false ) );
i = DrawTextMSZ( sTag, font, LEFTMARGIN2, y, 0, C_YELLOW, m_poBackground );
DrawTextMSZ( s, font, LEFTMARGIN2+i, y, 0, C_ORANGE, m_poBackground );
s = SvPV_nolen(get_sv("Height", FALSE ));
sTag = SvPV_nolen( *av_fetch( StatTags, 5, false ) );
i = DrawTextMSZ( sTag, font, LEFTMARGIN, y+=LINEHEIGHT, 0, C_YELLOW, m_poBackground );
DrawTextMSZ( s, font, LEFTMARGIN+i, y, 0, C_ORANGE, m_poBackground );
s = SvPV_nolen(get_sv("Shoe", FALSE ));
sTag = SvPV_nolen( *av_fetch( StatTags, 6, false ) );
i = DrawTextMSZ( sTag, font, LEFTMARGIN2, y, 0, C_YELLOW, m_poBackground );
DrawTextMSZ( s, font, LEFTMARGIN2+i, y, 0, C_ORANGE, m_poBackground );
s = SvPV_nolen(get_sv("Story", FALSE ));
SDL_Rect oFlyingRect;
oFlyingRect.x = LEFTMARGIN;
oFlyingRect.y = y+DESCMARGIN;
oFlyingRect.w = gamescreen->w - oFlyingRect.x - 20;
oFlyingRect.h = gamescreen->h - oFlyingRect.y - 10;
m_poFlyingChars = new FlyingChars( creditsFont, oFlyingRect );
m_poFlyingChars->AddText( s, FlyingChars::FC_AlignJustify, false );
if ( g_oPlayerSelect.IsFighterAvailable( m_enFighter ) )
{
s = SvPV_nolen(get_sv("Keys", TRUE ));
m_poFlyingChars->AddText( "\nKEYS\n", FlyingChars::FC_AlignCenter, true );
m_poFlyingChars->AddText( s, FlyingChars::FC_AlignCenter, true );
}
else
{
m_poFlyingChars->AddText( "Unfortunately this figther is not yet playable.",
FlyingChars::FC_AlignLeft, true );
}
}
FighterStatsDemo::~FighterStatsDemo()
{
delete m_poStaff;
}
int FighterStatsDemo::Advance( int a_iNumFrames, bool a_bFlip )
{
if ( a_iNumFrames > 5 ) a_iNumFrames = 5;
if ( m_poFlyingChars->IsDone() )
{
m_iTimeLeft -= a_iNumFrames;
}
AdvanceFlyingChars( a_iNumFrames );
SDL_BlitSurface( m_poBackground, NULL, gamescreen, NULL );
m_poFlyingChars->Draw();
// 2. Advance as many ticks as necessary..
if ( g_oPlayerSelect.IsFighterAvailable( m_enFighter ) )
{
for (int i=0; i<a_iNumFrames; ++i )
{
g_oBackend.AdvancePerl();
}
int p1x = SvIV(get_sv("p1x", TRUE));
int p1y = SvIV(get_sv("p1y", TRUE));
int p1f = SvIV(get_sv("p1f", TRUE));
if (p1f) g_oPlayerSelect.GetPlayerInfo(0).m_poPack->Draw( ABS(p1f)-1, p1x, p1y, p1f<0 );
}
else
{
static FighterEnum f[14] = {
UPI, ZOLI, SURBA, ULMAR, MISI, BENCE,
DESCANT, KINGA, GRIZLI, SIRPI, MACI, DANI, CUMI,
AMBRUS };
for ( int i=0; i<14; ++i )
{
if ( m_enFighter == f[i] )
{
//m_poStaff->draw( i, 10, 120 );
break;
}
}
}
SDL_Flip( gamescreen );
return (m_iTimeLeft > 0) ? 0 : 1;
}
diff --git a/src/Game.cpp b/src/Game.cpp
index 8c2346d..5aa0a46 100644
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -1,785 +1,784 @@
/***************************************************************************
Game.cpp - description
-------------------
begin : Mon Sep 24 2001
copyright : (C) 2001 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include <string.h>
#include <stdio.h>
#include "SDL_image.h"
#include "sge_surface.h"
#include "sge_primitives.h"
#include "sge_bm_text.h"
#include "SDL_events.h"
#include "SDL_keysym.h"
#include <fstream>
#include "PlayerSelect.h"
#include "common.h"
#include "gfx.h"
#include "Backend.h"
#include "RlePack.h"
#include "State.h"
#include "Game.h"
#include "Audio.h"
-#include <EXTERN.h>
-#include <perl.h>
+#include "MszPerl.h"
extern PerlInterpreter* my_perl;
int Game::mg_iBackgroundNumber = 1;
/*
GAME PALETTE
From To Num Desc
---------------------------------------
0 .. 63 64 Background
64 .. 111 48 Doodads
112 .. 175 64 1st Fighter
176 .. 239 64 2nd Fighter
240 .. 255 16 basic colors
*/
#define MAXFRAMESKIP 5
struct SFpsCounter
{
int m_iLastCheck; // Last second then Tick() was called
int m_iFrames; // The number of frames in this second so far
int m_iFps; // The number of frames in the last second
void Reset()
{
m_iLastCheck = m_iFrames = m_iFps = 0;
}
void Tick()
{
int iSecond = SDL_GetTicks() / 1000;
if ( iSecond > m_iLastCheck )
{
m_iLastCheck = iSecond;
m_iFps = m_iFrames;
m_iFrames = 0;
fprintf( stderr, "%d ", m_iFps);
}
++m_iFrames;
}
} oFpsCounter;
/***************************************************************************
GAME PUBLIC METHODS
***************************************************************************/
Game::Game( bool a_bIsReplay, bool a_bDebug)
{
m_bIsReplay = a_bIsReplay;
m_bDebug = a_bDebug;
char acFilename[1024];
sprintf( acFilename, "level%d.png", mg_iBackgroundNumber++ );
m_poBackground = LoadBackground( acFilename, 64 );
if ( NULL == m_poBackground )
{
mg_iBackgroundNumber = 1;
m_poBackground = LoadBackground( "level1.png", 64 );
}
m_poDoodads = LoadBackground( "Doodads.png", 48, 64 );
m_aiRoundsWonByPlayer[0] = m_aiRoundsWonByPlayer[1] = 0;
m_iNumberOfRounds = 0;
}
Game::~Game()
{
SDL_FreeSurface( m_poBackground );
m_poBackground = NULL;
SDL_FreeSurface( m_poDoodads );
m_poDoodads = NULL;
}
int Game::Run()
{
do
{
- m_sReplayString.clear();
+ m_sReplayString = "";
m_aReplayOffsets.clear();
DoOneRound();
if ( g_oState.m_bQuitFlag
|| SState::IN_DEMO == g_oState.m_enGameMode )
{
return -1;
}
} while ( m_aiRoundsWonByPlayer[0] < 2
&& m_aiRoundsWonByPlayer[1] < 2
&& m_iNumberOfRounds < 3 );
if ( m_aiRoundsWonByPlayer[1] > m_aiRoundsWonByPlayer[0] ) return 1;
if ( m_aiRoundsWonByPlayer[1] < m_aiRoundsWonByPlayer[0] ) return 0;
return -1;
}
std::string& Game::GetReplay()
{
return m_sReplayString;
}
/***************************************************************************
GAME DRAWING METHODS
***************************************************************************/
void Game::DrawHitPointDisplay()
{
int hp1 = g_oBackend.m_aoPlayers[0].m_iHitPoints;// * 100 / g_oState.m_iHitPoints;
int hp2 = g_oBackend.m_aoPlayers[1].m_iHitPoints;// * 100 / g_oState.m_iHitPoints;
SDL_Rect src, dst;
src.y = 154;
src.h = 20;
dst.y = 15;
// Player 1, green part.
dst.x = 40;
src.x = 0;
src.w = hp1*2;
SDL_BlitSurface( m_poDoodads, &src, gamescreen, &dst );
// Player 1, red part.
dst.x += hp1*2;
src.x = (100 + hp1)*2;
src.w = (100-hp1)*2;
SDL_BlitSurface( m_poDoodads, &src, gamescreen, &dst );
// Player 2, red part.
dst.x = 400;
src.x = 200;
src.w = (100-hp2)*2;
SDL_BlitSurface( m_poDoodads, &src, gamescreen, &dst );
// Player 2, green part.
dst.x = 400 + (100-hp2)*2;
src.x = (100-hp2)*2;
src.w = hp2*2;
SDL_BlitSurface( m_poDoodads, &src, gamescreen, &dst );
// "Won" icon for Player 1
src.x = 0; src.y = 276; src.w = 32; src.h = 32;
if ( m_aiRoundsWonByPlayer[0] > 0 )
{
dst.x = 4; dst.y = 11;
SDL_BlitSurface( m_poDoodads, &src, gamescreen, &dst );
}
if ( m_aiRoundsWonByPlayer[1] > 0 )
{
dst.x = 604; dst.y = 11;
SDL_BlitSurface( m_poDoodads, &src, gamescreen, &dst );
}
sge_BF_textout( gamescreen, fastFont, g_oPlayerSelect.GetFighterName(0),
230 - g_oPlayerSelect.GetFighterNameWidth(0), 38 );
sge_BF_textout( gamescreen, fastFont, g_oPlayerSelect.GetFighterName(1),
410, 38 );
}
void Game::DrawBackground()
{
sge_Blit( m_poBackground, gamescreen,
g_oBackend.m_iBgX, g_oBackend.m_iBgY,
0, 0, SCREENWIDTH, SCREENHEIGHT );
}
void Game::DrawPoly( const char* sName, int color )
{
AV *iList;
int n;
iList = get_av( sName, FALSE );
if ( iList == NULL )
{
return;
}
n = av_len( iList ) + 1;
if ( n< 2 )
{
return;
}
for ( int i=0; i<n; i += 2 )
{
int j = (i+2) % n;
int x1 = SvIV( *av_fetch( iList, i, false) );
int y1 = SvIV( *av_fetch( iList, i+1, false) );
int x2 = SvIV( *av_fetch( iList, j, false) );
int y2 = SvIV( *av_fetch( iList, j+1, false) );
sge_Line( gamescreen, x1, y1, x2, y2, color ) ;
}
}
void Game::DrawDoodads()
{
for ( int i=0; i<g_oBackend.m_iNumDoodads; ++i )
{
Backend::SDoodad& roDoodad = g_oBackend.m_aoDoodads[i];
if ( 0 == roDoodad.m_iType )
{
// Handle text doodads
const char *s = roDoodad.m_sText.c_str();
int iWidth = sge_BF_TextSize(fastFont, s).w;
int iDoodadX = roDoodad.m_iX - iWidth/2;
if ( iDoodadX + iWidth > 640 ) iDoodadX = 640 - iWidth;
if ( iDoodadX < 0 ) iDoodadX = 0;
int iDoodadY = roDoodad.m_iY;
sge_BF_textout( gamescreen, fastFont, s, iDoodadX, iDoodadY );
continue;
}
if ( roDoodad.m_iGfxOwner < 2 )
{
g_oPlayerSelect.GetPlayerInfo(roDoodad.m_iGfxOwner).m_poPack->Draw(
roDoodad.m_iFrame, roDoodad.m_iX, roDoodad.m_iY, roDoodad.m_iDir < 1 );
continue;
}
SDL_Rect rsrc, rdst;
rdst.x = roDoodad.m_iX;
rdst.y = roDoodad.m_iY;
rsrc.x = 64 * roDoodad.m_iFrame;
rsrc.y = 0;
rsrc.w = 64;
rsrc.h = 64;
SDL_BlitSurface( m_poDoodads, &rsrc, gamescreen, &rdst );
//debug( "Doodad x: %d, y: %d, t: %d, f: %d\n", dx, dy, dt, df );
}
}
void Game::Draw()
{
DrawBackground();
for ( int i=0; i<2; ++i )
{
int iFrame = g_oBackend.m_aoPlayers[i].m_iFrame;
if ( 0 != iFrame )
{
g_oPlayerSelect.GetPlayerInfo(i).m_poPack->Draw(
ABS(iFrame)-1,
g_oBackend.m_aoPlayers[i].m_iX,
g_oBackend.m_aoPlayers[i].m_iY,
iFrame<0 );
}
}
if ( m_bDebug )
{
DrawPoly( "p1head", C_LIGHTRED );
DrawPoly( "p1body", C_LIGHTGREEN );
DrawPoly( "p1legs", C_LIGHTBLUE );
DrawPoly( "p1hit", C_YELLOW );
DrawPoly( "p2head", C_LIGHTRED );
DrawPoly( "p2body", C_LIGHTGREEN );
DrawPoly( "p2legs", C_LIGHTBLUE );
DrawPoly( "p2hit", C_YELLOW );
}
DrawDoodads();
DrawHitPointDisplay();
if ( Ph_NORMAL == m_enGamePhase )
{
char s[100];
sprintf( s, "%d", g_oBackend.m_iGameTime );
DrawTextMSZ( s, inkFont, 320, 10, AlignHCenter, C_LIGHTCYAN, gamescreen );
}
else if ( Ph_START == m_enGamePhase )
{
char s[100];
sprintf( s, "Round %d", m_iNumberOfRounds+1 );
DrawTextMSZ( s, inkFont, 320, 200, AlignHCenter, C_WHITE, gamescreen );
}
else if ( Ph_REWIND == m_enGamePhase )
{
DrawTextMSZ( "REW", inkFont, 320, 10, AlignHCenter, C_WHITE, gamescreen );
sge_BF_textout( gamescreen, fastFont, "Press F1 to skip...", 230, 450 );
}
else if ( Ph_SLOWFORWARD == m_enGamePhase )
{
DrawTextMSZ( "REPLAY", inkFont, 320, 10, AlignHCenter, C_WHITE, gamescreen );
sge_BF_textout( gamescreen, fastFont, "Press F1 to skip...", 230, 450 );
}
else if ( Ph_REPLAY == m_enGamePhase )
{
DrawTextMSZ( "DEMO", inkFont, 320, 10, AlignHCenter, C_WHITE, gamescreen );
}
if ( oFpsCounter.m_iFps > 0 )
{
sge_BF_textoutf( gamescreen, fastFont, 2, 2, "%d fps", oFpsCounter.m_iFps );
}
SDL_Flip( gamescreen );
}
/***************************************************************************
GAME PROTECTED METHODS
***************************************************************************/
/**
This method reads and updates the game's variables. In replay mode,
this is done by parsing the replay string. Otherwise the perl
backend is advanced the given number of steps.
Whichever the case, the variables will be available in g_oBackend.
*/
void Game::Advance( int a_iNumFrames )
{
if ( m_bIsReplay )
{
// Replay mode...
m_iFrame += a_iNumFrames;
if ( m_iFrame >= ((int)m_aReplayOffsets.size())-1 ) m_iFrame = m_aReplayOffsets.size() - 2;
if ( m_iFrame <= 0 ) m_iFrame = 0;
std::string sFrameDesc = m_sReplayString.substr(
m_aReplayOffsets[m_iFrame],
m_aReplayOffsets[m_iFrame+1] - m_aReplayOffsets[m_iFrame] );
g_oBackend.ReadFromString( sFrameDesc );
return;
}
while ( a_iNumFrames > 0 )
{
-- a_iNumFrames;
std::string sFrameDesc;
g_oBackend.AdvancePerl();
g_oBackend.ReadFromPerl();
g_oBackend.PlaySounds();
g_oBackend.WriteToString( sFrameDesc );
m_sReplayString += sFrameDesc;
m_sReplayString += '\n';
m_aReplayOffsets.push_back( m_sReplayString.size() );
}
}
/** ProcessEvents reads events from the SDL event system.
Relevant key events are fed to the backend.
Esc brings up the menu.
Returns 1 on quit event (e.g. if the current game or replay should be aborted), 0 otherwise.
*/
int Game::ProcessEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
g_oState.m_bQuitFlag = true;
return 1;
case SDL_KEYDOWN:
{
if ( event.key.keysym.sym == SDLK_ESCAPE )
{
SState::TGameMode enMode = g_oState.m_enGameMode;
::DoMenu( true );
return g_oState.m_enGameMode == enMode ? 0 : 1;
}
if ( event.key.keysym.sym == SDLK_F1 )
{
// shortcut: abort the current round. This shall is here
// to ease testing, and will be removed from the final
// version.
return 1;
}
if ( Ph_NORMAL != m_enGamePhase &&
Ph_REPLAY != m_enGamePhase )
break;
for (int i=0; i<2; i++)
{
for (int j=0; j<9; j++ )
{
if (g_oState.m_aiPlayerKeys[i][j] == event.key.keysym.sym)
{
if (g_oState.m_enGameMode == SState::IN_DEMO)
{
g_oState.m_enGameMode = SState::IN_MULTI;
return 1;
}
g_oBackend.PerlEvalF( "KeyDown(%d,%d);", i, j );
return 0;
}
}
}
break;
}
case SDL_KEYUP:
{
if ( Ph_NORMAL != m_enGamePhase )
break;
for (int i=0; i<2; i++)
{
for (int j=0; j<9; j++ )
{
if (g_oState.m_aiPlayerKeys[i][j] == event.key.keysym.sym)
{
g_oBackend.PerlEvalF( "KeyUp(%d,%d);", i, j );
return 0;
}
}
}
break;
}
} // End of switch
} // End of while SDL_PollEvent;
return 0;
}
void Game::HurryUp()
{
Audio->PlaySample( "aroooga.voc" );
DrawGradientText( "HURRY UP!", titleFont, 200, gamescreen );
SDL_Delay( 1000 );
Audio->PlaySample( "machine_start.voc" );
}
void Game::TimeUp()
{
DrawGradientText( "TIME IS UP!", titleFont, 200, gamescreen );
SDL_Delay( 1000 );
}
void Game::InstantReplay( int a_iKoAt )
{
int iCurrentFrame = m_aReplayOffsets.size() - 200;
int iThisTick, iLastTick, iGameSpeed;
m_enGamePhase = Ph_REWIND;
iGameSpeed = 8;
iThisTick = SDL_GetTicks() / iGameSpeed;
iLastTick = iThisTick - 1;
while ( iCurrentFrame < (int)m_aReplayOffsets.size() - 150 )
{
// 1. Wait for the next tick (on extremely fast machines..)
while (iThisTick == iLastTick)
{
iThisTick = SDL_GetTicks() / iGameSpeed;
if ( iThisTick==iLastTick ) SDL_Delay(1);
}
// 2. Advance as many ticks as necessary..
int iNumTicks = iThisTick - iLastTick;
if ( iNumTicks > 10 ) iNumTicks = 10;
if ( iNumTicks < 0 ) iNumTicks = 0;
iCurrentFrame += ( Ph_REWIND == m_enGamePhase ) ? -iNumTicks : +iNumTicks ;
if ( Ph_REWIND == m_enGamePhase
&& ( iCurrentFrame < a_iKoAt - 200 || iCurrentFrame <= 0 )
)
{
m_enGamePhase = Ph_SLOWFORWARD;
iGameSpeed = 16;
SDL_Delay(500);
}
iLastTick = iThisTick;
if ( iCurrentFrame < 0 ) iCurrentFrame = 0;
m_iFrame = iCurrentFrame;
if ( m_iFrame >= ((int)m_aReplayOffsets.size())-1 ) m_iFrame = m_aReplayOffsets.size() - 2;
if ( m_iFrame <= 0 ) m_iFrame = 0;
std::string sFrameDesc = m_sReplayString.substr(
m_aReplayOffsets[m_iFrame],
m_aReplayOffsets[m_iFrame+1] - m_aReplayOffsets[m_iFrame] );
//debug( "PB: Frame %d ofs %d-%d; data: '%s'\n", m_iFrame,
// m_aReplayOffsets[m_iFrame], m_aReplayOffsets[m_iFrame+1], sFrameDesc.c_str() );
g_oBackend.ReadFromString( sFrameDesc );
if ( ProcessEvents() )
{
break;
}
oFpsCounter.Tick();
// 3. Draw the next game screen..
Draw();
if ( g_oState.m_bQuitFlag
|| SState::IN_DEMO == g_oState.m_enGameMode )
{
break;
}
}
}
void Game::DoOneRound()
{
m_enGamePhase = Ph_START;
g_oBackend.PerlEvalF( "GameStart(%d,%d);", g_oState.m_iHitPoints, m_bDebug );
int iKoFrame = -1;
double dGameTime = 2 * 1000; // Only for the "greeting phase", the real gametime will be set after.
int iThisTick, iLastTick, iGameSpeed;
bool bHurryUp = false;
bool bReplayAfter = true;
iGameSpeed = g_oState.m_iGameSpeed;
iThisTick = SDL_GetTicks() / iGameSpeed;
iLastTick = iThisTick - 1;
oFpsCounter.Reset();
// 1. DO THE NORMAL GAME ROUND and HURRYUP
while ( dGameTime >= 0 )
{
// 1. Wait for the next tick (on extremely fast machines..)
while (iThisTick == iLastTick)
{
iThisTick = SDL_GetTicks() / iGameSpeed;
if ( iThisTick==iLastTick ) SDL_Delay(1);
}
// 2. Advance as many ticks as necessary..
int iNumTicks = iThisTick - iLastTick;
if ( iNumTicks > MAXFRAMESKIP ) iNumTicks = MAXFRAMESKIP;
Advance( iNumTicks );
dGameTime -= iNumTicks * iGameSpeed;
if ( Ph_START == m_enGamePhase )
{
if ( dGameTime <= 0 )
{
m_enGamePhase = Ph_NORMAL;
dGameTime = g_oState.m_iGameTime * 1000;
}
}
else if ( Ph_NORMAL == m_enGamePhase )
{
if ( dGameTime < 10 * 1000
&& !bHurryUp )
{
bHurryUp = true;
HurryUp();
iGameSpeed = iGameSpeed * 3 / 4;
}
if ( g_oBackend.m_bKO )
{
m_enGamePhase = Ph_KO;
dGameTime = 10 * 1000;
iKoFrame = m_aReplayOffsets.size();
}
else if ( dGameTime <= 0 )
{
m_enGamePhase = Ph_TIMEUP;
TimeUp();
break;
}
}
g_oBackend.m_iGameTime = (int) ((dGameTime + 500.0) / 1000.0);
iLastTick = iThisTick;
if ( ProcessEvents() || g_oState.m_bQuitFlag )
{
bReplayAfter = false;
break;
}
oFpsCounter.Tick();
// 3. Draw the next game screen..
Draw();
if ( g_oBackend.m_iGameOver )
{
break;
}
}
// 3. DO THE REPLAY (IF THERE WAS A KO)
if ( iKoFrame>0 && bReplayAfter )
{
InstantReplay( iKoFrame );
}
// 4. END OF ROUND
int p1h = g_oBackend.m_aoPlayers[0].m_iHitPoints;
int p2h = g_oBackend.m_aoPlayers[1].m_iHitPoints;
debug( "Game over; p1h = %d; p2h = %d\n", p1h, p2h );
if ( p1h > p2h ) ++m_aiRoundsWonByPlayer[0];
if ( p2h > p1h ) ++m_aiRoundsWonByPlayer[1];
++m_iNumberOfRounds;
}
void Game::DoReplay( const char* a_pcReplayFile )
{
std::ifstream oInput( a_pcReplayFile );
int iPlayer1, iPlayer2;
oInput >> iPlayer1 >> iPlayer2;
std::string sLine;
std::getline( oInput, sLine );
g_oPlayerSelect.SetPlayer( 0, (FighterEnum) iPlayer1 );
g_oPlayerSelect.SetPlayer( 1, (FighterEnum) iPlayer2 );
int iThisTick, iLastTick, iGameSpeed;
m_enGamePhase = Ph_REPLAY;
iGameSpeed = 12;
iThisTick = SDL_GetTicks() / iGameSpeed;
iLastTick = iThisTick - 1;
while ( !oInput.eof() )
{
// 1. Wait for the next tick (on extremely fast machines..)
while (iThisTick == iLastTick)
{
iThisTick = SDL_GetTicks() / iGameSpeed;
if ( iThisTick==iLastTick ) SDL_Delay(1);
}
// 2. Advance as many ticks as necessary..
int iNumTicks = iThisTick - iLastTick;
if ( iNumTicks > 5 ) iNumTicks = 5;
for ( int i=0; i< iNumTicks; ++i )
{
std::getline( oInput, sLine );
}
if ( 0 == sLine.size() )
{
break;
}
iLastTick = iThisTick;
g_oBackend.ReadFromString( sLine );
if ( ProcessEvents() )
{
break;
}
oFpsCounter.Tick();
// 3. Draw the next game screen..
Draw();
if ( g_oState.m_bQuitFlag )
{
break;
}
}
}
int DoGame( char* a_pcReplayFile, bool a_bIsReplay, bool a_bDebug )
{
Game oGame( a_bIsReplay, a_bDebug );
if ( a_bIsReplay )
{
if ( NULL == a_pcReplayFile )
{
return 0;
}
oGame.DoReplay( a_pcReplayFile );
return 0;
}
else
{
int iRetval = oGame.Run();
if ( NULL != a_pcReplayFile )
{
std::ofstream oOutput( a_pcReplayFile );
oOutput <<
g_oPlayerSelect.GetPlayerInfo(0).m_enFighter << ' ' <<
g_oPlayerSelect.GetPlayerInfo(1).m_enFighter << '\n' << oGame.GetReplay();
}
return iRetval;
}
}
diff --git a/src/Makefile.am b/src/Makefile.am
index 2e68a36..95c6fe8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,27 +1,27 @@
## Process this file with automake to produce Makefile.in
bin_PROGRAMS = openmortal
openmortal_SOURCES = Audio.cpp Backend.cpp common.cpp \
Demo.cpp FighterStats.cpp FlyingChars.cpp Game.cpp gfx.cpp main.cpp \
menu.cpp PlayerSelect.cpp RlePack.cpp sge_bm_text.cpp \
sge_primitives.cpp sge_surface.cpp sge_tt_text.cpp State.cpp \
GameOver.cpp
EXTRA_DIST = Audio.h Backend.h common.h Demo.h FlyingChars.h gfx.h \
menu.h RlePack.h sge_bm_text.h sge_config.h sge_internal.h \
sge_primitives.h sge_surface.h sge_tt_text.h State.h \
- Game.h FighterEnum.h PlayerSelect.h\
+ Game.h FighterEnum.h PlayerSelect.h MszPerl.h \
Audio.cpp Backend.cpp common.cpp \
Demo.cpp FighterStats.cpp FlyingChars.cpp Game.cpp gfx.cpp main.cpp \
menu.cpp PlayerSelect.cpp RlePack.cpp sge_bm_text.cpp \
sge_primitives.cpp sge_surface.cpp sge_tt_text.cpp State.cpp \
GameOver.cpp
CXXFLAGS= @CXXFLAGS@ -DDATADIR=\"${pkgdatadir}\" -Wall
# set the include path found by configure
#INCLUDES= $(all_includes)
# the library search path.
#msz_LDFLAGS = $(all_libraries)
diff --git a/src/Makefile.in b/src/Makefile.in
index 0f3a000..f91dde9 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,303 +1,363 @@
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_alias = @build_alias@
build_triplet = @build@
host_alias = @host_alias@
host_triplet = @host@
target_alias = @target_alias@
target_triplet = @target@
AUTODIRS = @AUTODIRS@
CXX = @CXX@
FT2_CFLAGS = @FT2_CFLAGS@
FT2_CONFIG = @FT2_CONFIG@
FT2_LIBS = @FT2_LIBS@
MAKEINFO = @MAKEINFO@
PACKAGE = @PACKAGE@
PERL = @PERL@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
VERSION = @VERSION@
perl_embed_ccflags = @perl_embed_ccflags@
perl_embed_ldflags = @perl_embed_ldflags@
bin_PROGRAMS = openmortal
openmortal_SOURCES = Audio.cpp Backend.cpp common.cpp Demo.cpp FighterStats.cpp FlyingChars.cpp Game.cpp gfx.cpp main.cpp menu.cpp PlayerSelect.cpp RlePack.cpp sge_bm_text.cpp sge_primitives.cpp sge_surface.cpp sge_tt_text.cpp State.cpp GameOver.cpp
-EXTRA_DIST = Audio.h Backend.h common.h Demo.h FlyingChars.h gfx.h menu.h RlePack.h sge_bm_text.h sge_config.h sge_internal.h sge_primitives.h sge_surface.h sge_tt_text.h State.h Game.h FighterEnum.h PlayerSelect.h Audio.cpp Backend.cpp common.cpp Demo.cpp FighterStats.cpp FlyingChars.cpp Game.cpp gfx.cpp main.cpp menu.cpp PlayerSelect.cpp RlePack.cpp sge_bm_text.cpp sge_primitives.cpp sge_surface.cpp sge_tt_text.cpp State.cpp GameOver.cpp
+EXTRA_DIST = Audio.h Backend.h common.h Demo.h FlyingChars.h gfx.h menu.h RlePack.h sge_bm_text.h sge_config.h sge_internal.h sge_primitives.h sge_surface.h sge_tt_text.h State.h Game.h FighterEnum.h PlayerSelect.h MszPerl.h Audio.cpp Backend.cpp common.cpp Demo.cpp FighterStats.cpp FlyingChars.cpp Game.cpp gfx.cpp main.cpp menu.cpp PlayerSelect.cpp RlePack.cpp sge_bm_text.cpp sge_primitives.cpp sge_surface.cpp sge_tt_text.cpp State.cpp GameOver.cpp
CXXFLAGS = @CXXFLAGS@ -DDATADIR=\"${pkgdatadir}\" -Wall
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
PROGRAMS = $(bin_PROGRAMS)
DEFS = @DEFS@ -I. -I$(srcdir) -I..
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
openmortal_OBJECTS = Audio.o Backend.o common.o Demo.o FighterStats.o \
FlyingChars.o Game.o gfx.o main.o menu.o PlayerSelect.o RlePack.o \
sge_bm_text.o sge_primitives.o sge_surface.o sge_tt_text.o State.o \
GameOver.o
openmortal_LDADD = $(LDADD)
openmortal_DEPENDENCIES =
openmortal_LDFLAGS =
CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/Audio.P .deps/Backend.P .deps/Demo.P \
+.deps/FighterStats.P .deps/FlyingChars.P .deps/Game.P .deps/GameOver.P \
+.deps/PlayerSelect.P .deps/RlePack.P .deps/State.P .deps/common.P \
+.deps/gfx.P .deps/main.P .deps/menu.P .deps/sge_bm_text.P \
+.deps/sge_primitives.P .deps/sge_surface.P .deps/sge_tt_text.P
SOURCES = $(openmortal_SOURCES)
OBJECTS = $(openmortal_OBJECTS)
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .cpp .o .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
- cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
mostlyclean-binPROGRAMS:
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
distclean-binPROGRAMS:
maintainer-clean-binPROGRAMS:
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
if test -f $$p; then \
echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
list='$(bin_PROGRAMS)'; for p in $$list; do \
rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
openmortal: $(openmortal_OBJECTS) $(openmortal_DEPENDENCIES)
@rm -f openmortal
$(CXXLINK) $(openmortal_LDFLAGS) $(openmortal_OBJECTS) $(openmortal_LDADD) $(LIBS)
.cpp.o:
$(CXXCOMPILE) -c $<
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = src
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu src/Makefile
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cpp
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cpp
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am: install-binPROGRAMS
install-exec: install-exec-am
install-data-am:
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am: uninstall-binPROGRAMS
uninstall: uninstall-am
all-am: Makefile $(PROGRAMS)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
$(mkinstalldirs) $(DESTDIR)$(bindir)
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \
- mostlyclean-tags mostlyclean-generic
+ mostlyclean-tags mostlyclean-depend mostlyclean-generic
mostlyclean: mostlyclean-am
-clean-am: clean-binPROGRAMS clean-compile clean-tags clean-generic \
- mostlyclean-am
+clean-am: clean-binPROGRAMS clean-compile clean-tags clean-depend \
+ clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-binPROGRAMS distclean-compile distclean-tags \
- distclean-generic clean-am
+ distclean-depend distclean-generic clean-am
distclean: distclean-am
maintainer-clean-am: maintainer-clean-binPROGRAMS \
maintainer-clean-compile maintainer-clean-tags \
- maintainer-clean-generic distclean-am
+ maintainer-clean-depend maintainer-clean-generic \
+ distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile tags mostlyclean-tags distclean-tags \
-clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
-check-am installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \
+distclean-depend clean-depend maintainer-clean-depend info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
# set the include path found by configure
#INCLUDES= $(all_includes)
# the library search path.
#msz_LDFLAGS = $(all_libraries)
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/src/MszPerl.h b/src/MszPerl.h
new file mode 100644
index 0000000..95d245f
--- /dev/null
+++ b/src/MszPerl.h
@@ -0,0 +1,29 @@
+/***************************************************************************
+ MszPerl.h - description
+ -------------------
+ begin : Mon Jan 5 2004
+ copyright : (C) 2004 by upi
+ email : upi@feel
+ ***************************************************************************/
+
+/**
+This file helps include perl.h
+The windows version of perl.h contains a lot of stupid #defines, this
+file helps undefine them.
+*/
+
+#ifndef __MSZPERL_H
+#define __MSZPERL_H
+
+#include <EXTERN.h>
+#include <perl.h>
+
+#ifdef _WINDOWS
+#undef bool
+#undef chdir
+#undef close
+#undef eof
+#define vsnprintf _vsnprintf
+#endif
+
+#endif // __MSZPERL_H
diff --git a/src/PlayerSelect.cpp b/src/PlayerSelect.cpp
index 9457067..dbf876c 100644
--- a/src/PlayerSelect.cpp
+++ b/src/PlayerSelect.cpp
@@ -1,502 +1,498 @@
/***************************************************************************
PlayerSelect.cpp - description
-------------------
begin : Sun Dec 8 2002
copyright : (C) 2002 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include <stdio.h>
#include "PlayerSelect.h"
#include "SDL.h"
#include "SDL_video.h"
#include "SDL_image.h"
#include "sge_primitives.h"
#include "common.h"
#include "Audio.h"
#include "sge_bm_text.h"
#include "gfx.h"
#include "RlePack.h"
#include "Backend.h"
#include "State.h"
#define CHOOSERLEFT 158
-#define CHOOSERTOP 98
+#define CHOOSERTOP 74
#define CHOOSERHEIGHT 80
#define CHOOSERWIDTH 80
-#define CHOOSERROWS 4
+#define CHOOSERROWS 5
#define CHOOSERCOLS 4
#ifndef NULL
#define NULL 0
#endif
/***************************************************************************
PUBLIC EXPORTED VARIABLES
***************************************************************************/
PlayerSelect g_oPlayerSelect;
/***************************************************************************
PRIVATE VARIABLES (perl variable space)
***************************************************************************/
/*
int p1 = 0;
int p2 = 3;
bool done1 = false;
bool done2 = false;
*/
+/*
FighterEnum ChooserCells[CHOOSERROWS][CHOOSERCOLS] = {
{ ZOLI, UPI, CUMI, SIRPI },
{ ULMAR, MACI, BENCE, GRIZLI },
{ AMBRUS, DESCANT, SURBA, DANI },
{ UNKNOWN, KINGA, MISI, UNKNOWN },
};
+*/
+
+FighterEnum ChooserCells[CHOOSERROWS][CHOOSERCOLS] = {
+ { ZOLI, UPI, CUMI, SIRPI },
+ { ULMAR, MACI, GRIZLI, DESCANT },
+ { DANI, AMBRUS, BENCE, SURBA },
+ { (FighterEnum)100, (FighterEnum)101, (FighterEnum)102, (FighterEnum)103 },
+ { (FighterEnum)104, (FighterEnum)105, KINGA, MISI }
+};
PlayerSelect::PlayerSelect()
{
for ( int i=0; i<2; ++i )
{
m_aoPlayers[i].m_enFighter = UNKNOWN;
m_aoPlayers[i].m_enTint = NO_TINT;
m_aoPlayers[i].m_poPack = NULL;
}
m_iP1 = 0;
m_iP2 = CHOOSERCOLS-1;
}
const PlayerInfo& PlayerSelect::GetPlayerInfo( int a_iPlayer )
{
return m_aoPlayers[ a_iPlayer ? 1 : 0 ];
}
const char* PlayerSelect::GetFighterName( int a_iPlayer )
{
return m_aoPlayers[ a_iPlayer ? 1 : 0 ].m_sFighterName.c_str();
}
int PlayerSelect::GetFighterNameWidth( int a_iPlayer )
{
return m_aiFighterNameWidth[ a_iPlayer ? 1 : 0 ];
}
bool PlayerSelect::IsFighterAvailable( FighterEnum a_enFighter )
{
/*
static bool g_abFighterAvailable[ LASTFIGHTER ] =
{
false,
true, true, true, true,
true, true, true, true,
true, false, false, false,
false, false
};
*/
- if ( a_enFighter < UNKNOWN
- || a_enFighter >= LASTFIGHTER )
+ if ( a_enFighter <= UNKNOWN )
{
return false;
}
g_oBackend.PerlEvalF("GetFighterStats(%d);", a_enFighter);
const char* pcDatafile = g_oBackend.GetPerlString("Datafile");
return ( pcDatafile && *pcDatafile );
}
/** LoadFighter simply looks up the filename associated with the given
fighter, loads it, and returns the RlePack.
\return The freshly loaded RlePack, or NULL if it could not be loaded.
*/
RlePack* PlayerSelect::LoadFighter( FighterEnum m_enFighter ) // static
{
char a_pcFilename[FILENAME_MAX+1];
const char* s;
-
- /*
- switch (m_enFighter)
- {
- case ZOLI: s = "ZOLIDATA.DAT"; break;
- case UPI: s = "UPIDATA.DAT"; break;
- case ULMAR: s = "ULMARDATA.DAT"; break;
- case CUMI: s = "CUMIDATA.DAT"; break;
- case SIRPI: s = "SIRPIDATA.DAT"; break;
- case MACI: s = "MACIDATA.DAT"; break;
- case BENCE: s = "BENCEDATA.DAT"; break;
- case DESCANT: s = "DESCANTDATA.DAT"; break;
- case GRIZLI: s = "GRIZLIDATA.DAT"; break;
- default: return NULL; break;
- }
- */
+
g_oBackend.PerlEvalF( "GetFighterStats(%d);", m_enFighter );
s = g_oBackend.GetPerlString( "Datafile" );
strcpy( a_pcFilename, DATADIR );
strcat( a_pcFilename, "/characters/" );
strcat( a_pcFilename, s );
RlePack* pack = new RlePack( a_pcFilename, COLORSPERPLAYER );
if ( pack->Count() <= 0 )
{
debug( "Couldn't load RlePack: '%s'\n", a_pcFilename );
delete pack;
return NULL;
}
return pack;
}
/** SetPlayer loads the given fighter for the given player.
The RlePack is loaded first. If that succeeds, then the perl backend is
set too. The tint and palette of both players are set. */
void PlayerSelect::SetPlayer( int a_iPlayer, FighterEnum a_enFighter )
{
if ( a_iPlayer ) a_iPlayer = 1; // It's 0 or 1.
if ( m_aoPlayers[a_iPlayer].m_enFighter == a_enFighter )
{
return;
}
+ if ( !IsFighterAvailable( a_enFighter ) )
+ {
+ return;
+ }
int iOffset = a_iPlayer ? COLOROFFSETPLAYER2 : COLOROFFSETPLAYER1;
RlePack* poPack = LoadFighter( a_enFighter );
poPack->OffsetSprites( iOffset );
if ( NULL == poPack )
{
debug( "SetPlayer(%d,%d): Couldn't load RlePack\n", a_iPlayer, a_enFighter );
return;
}
delete m_aoPlayers[a_iPlayer].m_poPack;
m_aoPlayers[a_iPlayer].m_poPack = poPack;
m_aoPlayers[a_iPlayer].m_enFighter = a_enFighter;
g_oBackend.PerlEvalF( "SetPlayerNumber(%d,%d);", a_iPlayer, a_enFighter );
m_aoPlayers[a_iPlayer].m_sFighterName = g_oBackend.GetPerlString( "PlayerName" );
m_aiFighterNameWidth[a_iPlayer] = sge_BF_TextSize( fastFont, GetFighterName(a_iPlayer) ).w;
TintEnum enTint = NO_TINT;
if ( m_aoPlayers[0].m_enFighter == m_aoPlayers[1].m_enFighter )
{
enTint = TintEnum( (rand() % 4) + 1 );
}
SetTint( 1, enTint );
m_aoPlayers[a_iPlayer].m_poPack->ApplyPalette();
}
void PlayerSelect::SetTint( int a_iPlayer, TintEnum a_enTint )
{
m_aoPlayers[a_iPlayer].m_enTint = a_enTint;
if ( m_aoPlayers[a_iPlayer].m_poPack )
{
m_aoPlayers[a_iPlayer].m_poPack->SetTint( a_enTint );
m_aoPlayers[a_iPlayer].m_poPack->ApplyPalette();
}
}
void PlayerSelect::HandleKey( int a_iPlayer, int a_iKey )
{
int& riP = a_iPlayer ? m_iP2 : m_iP1;
int iOldP = riP;
bool& rbDone = a_iPlayer ? m_bDone2 : m_bDone1;
if ( rbDone )
{
return;
}
switch ( a_iKey )
{
case 0: // up
if ( riP >= CHOOSERCOLS ) riP -= CHOOSERCOLS;
break;
case 1: // down
if ( (riP/CHOOSERCOLS) < (CHOOSERROWS-1) ) riP += CHOOSERCOLS;
break;
case 2: // left
if ( (riP % CHOOSERCOLS) > 0 ) riP--;
break;
case 3: // right
if ( (riP % CHOOSERCOLS) < (CHOOSERCOLS-1) ) riP++;
break;
default:
- if ( ChooserCells[riP/4][riP%4] )
+ if ( IsFighterAvailable( ChooserCells[riP/CHOOSERCOLS][riP%CHOOSERCOLS] ) )
{
rbDone = true;
g_oBackend.PerlEvalF( "PlayerSelected(%d);", a_iPlayer );
Audio->PlaySample("magic.voc");
return;
}
}
- if ( !IsFighterAvailable( ChooserCells[riP/CHOOSERCOLS][riP%CHOOSERCOLS] ) )
- {
- riP = iOldP;
- }
-
if ( iOldP != riP )
{
Audio->PlaySample("strange_quack.voc");
- SetPlayer( a_iPlayer, ChooserCells[riP/CHOOSERCOLS][riP%CHOOSERCOLS] );
+ if ( IsFighterAvailable( ChooserCells[riP/CHOOSERCOLS][riP%CHOOSERCOLS] ) )
+ {
+ SetPlayer( a_iPlayer, ChooserCells[riP/CHOOSERCOLS][riP%CHOOSERCOLS] );
+ }
}
}
void PlayerSelect::DrawRect( int a_iPos, int a_iColor )
{
int iRow = a_iPos / CHOOSERCOLS;
int iCol = a_iPos % CHOOSERCOLS;
SDL_Rect r, r1;
r.x = CHOOSERLEFT + iCol * CHOOSERWIDTH;
r.y = CHOOSERTOP + iRow * CHOOSERHEIGHT;
r.w = CHOOSERWIDTH + 5;
r.h = 5;
r1 = r;
SDL_FillRect( gamescreen, &r1, a_iColor );
r.y += CHOOSERHEIGHT;
r1 = r;
SDL_FillRect( gamescreen, &r1, a_iColor );
r.y -= CHOOSERHEIGHT;
r.w = 5;
r.h = CHOOSERHEIGHT + 5;
r1 = r;
SDL_FillRect( gamescreen, &r1, a_iColor );
r.x += CHOOSERWIDTH;
r1 = r;
SDL_FillRect( gamescreen, &r1, a_iColor );
}
void PlayerSelect::CheckPlayer( SDL_Surface* a_poBackground, int a_iRow, int a_iCol )
{
int x1, y1;
x1 = CHOOSERLEFT + a_iCol * CHOOSERWIDTH +5;
y1 = CHOOSERTOP + a_iRow * CHOOSERHEIGHT +5;
sge_Line(a_poBackground, x1+5, y1+5, x1 + CHOOSERWIDTH-10, y1 + CHOOSERHEIGHT-10, 252);
sge_Line(a_poBackground, x1 + CHOOSERWIDTH-10, y1+5, x1+5, y1 + CHOOSERHEIGHT-10, 252);
x1++;
sge_Line(a_poBackground, x1+5, y1+5, x1 + CHOOSERWIDTH-10, y1 + CHOOSERHEIGHT-10, 252);
sge_Line(a_poBackground, x1 + CHOOSERWIDTH-10, y1+5, x1+5, y1 + CHOOSERHEIGHT-10, 252);
y1++;
sge_Line(a_poBackground, x1+5, y1+5, x1 + CHOOSERWIDTH-10, y1 + CHOOSERHEIGHT-10, 252);
sge_Line(a_poBackground, x1 + CHOOSERWIDTH-10, y1+5, x1+5, y1 + CHOOSERHEIGHT-10, 252);
x1--;
sge_Line(a_poBackground, x1+5, y1+5, x1 + CHOOSERWIDTH-10, y1 + CHOOSERHEIGHT-10, 252);
sge_Line(a_poBackground, x1 + CHOOSERWIDTH-10, y1+5, x1+5, y1 + CHOOSERHEIGHT-10, 252);
}
void PlayerSelect::DoPlayerSelect()
{
// 1. Set up: Load background, mark unavailable fighters
SDL_FillRect( gamescreen, NULL, C_BLACK );
SDL_Flip( gamescreen );
SDL_Surface* poBackground = LoadBackground( "PlayerSelect.png", 111 );
DrawGradientText( "Choose A Fighter Dammit", titleFont, 10, poBackground );
int i, j;
for ( i=0; i<CHOOSERROWS; ++i )
{
for ( int j=0; j<CHOOSERCOLS; ++j )
{
if ( !IsFighterAvailable(ChooserCells[i][j]) &&
UNKNOWN != ChooserCells[i][j] )
{
CheckPlayer( poBackground, i, j );
}
}
}
for ( i=0; i<2; ++i )
{
if ( m_aoPlayers[i].m_poPack ) m_aoPlayers[i].m_poPack->ApplyPalette();
}
SetPlayer( 0, ChooserCells[m_iP1/CHOOSERCOLS][m_iP1%CHOOSERCOLS] );
SetPlayer( 1, ChooserCells[m_iP2/CHOOSERCOLS][m_iP2%CHOOSERCOLS] );
// 2. Run selection screen
g_oBackend.PerlEvalF( "SelectStart();" );
m_bDone1 = m_bDone2 = false;
int thisTick, lastTick, gameSpeed;
gameSpeed = 12 ;
thisTick = SDL_GetTicks() / gameSpeed;
lastTick = thisTick - 1;
i = 0;
int over = 0;
int iCourtain = 0;
int iCourtainSpeed = 0;
int iCourtainTime = 80;
SDL_Event event;
while (1)
{
// 1. Wait for the next tick (on extremely fast machines..)
while (1)
{
thisTick = SDL_GetTicks() / gameSpeed;
if ( thisTick==lastTick )
{
SDL_Delay(1);
}
else
{
break;
}
}
// 2. Advance as many ticks as necessary..
if ( iCourtainTime > 0 )
{
int iAdvance = thisTick - lastTick;
if ( iAdvance > 5 ) iAdvance = 5;
if ( iCourtain + iCourtainSpeed * iCourtainTime /2 < 320 * 4 )
iCourtainSpeed += iAdvance;
else
iCourtainSpeed -= iAdvance;
iCourtain += iCourtainSpeed * iAdvance;
iCourtainTime -= iAdvance;
if ( iCourtainTime > 0 )
{
SDL_Rect oRect;
oRect.x = 320 - iCourtain/4; oRect.y = 0;
oRect.w = iCourtain / 2; oRect.h = gamescreen->h;
if ( oRect.x < 0 ) oRect.x = 0;
if ( oRect.w > gamescreen->w ) oRect.w = gamescreen->w;
SDL_SetClipRect( gamescreen, &oRect );
}
else
{
SDL_SetClipRect( gamescreen, NULL );
}
}
int iNumFrames = thisTick - lastTick;
if ( iNumFrames>5 ) iNumFrames = 5;
for ( i=0; i<iNumFrames; ++i )
{
g_oBackend.AdvancePerl();
}
lastTick = thisTick;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
g_oState.m_bQuitFlag = true;
break;
case SDL_KEYDOWN:
{
if ( event.key.keysym.sym == SDLK_ESCAPE )
{
DoMenu( false );
break;
}
for ( i=0; i<2; i++ )
{
for ( j=0; j<9; j++ )
{
if (g_oState.m_aiPlayerKeys[i][j] == event.key.keysym.sym)
{
DrawRect( m_iP1, 240 );
DrawRect( m_iP2, 240 );
HandleKey( i, j );
}
}
}
}
break;
} // switch statement
} // Polling events
g_oBackend.ReadFromPerl();
over = g_oBackend.m_iGameOver;
SDL_BlitSurface( poBackground, NULL, gamescreen, NULL );
+ if ( !m_bDone1) DrawRect( m_iP1, 250 );
+ if ( !m_bDone2) DrawRect( m_iP2, 253 );
for ( i=0; i<2; ++i )
{
if ( g_oBackend.m_aoPlayers[i].m_iFrame )
{
m_aoPlayers[i].m_poPack->Draw(
ABS(g_oBackend.m_aoPlayers[i].m_iFrame)-1,
g_oBackend.m_aoPlayers[i].m_iX, g_oBackend.m_aoPlayers[i].m_iY,
g_oBackend.m_aoPlayers[i].m_iFrame < 0 );
}
int x = ( CHOOSERLEFT - m_aiFighterNameWidth[i] ) / 2;
if ( x<10 ) x = 10;
if ( i ) x = gamescreen->w - x - m_aiFighterNameWidth[i];
sge_BF_textout( gamescreen, fastFont, GetFighterName(i),
x, gamescreen->h - 30 );
}
- if ( !m_bDone1) DrawRect( m_iP1, 250 );
- if ( !m_bDone2) DrawRect( m_iP2, 253 );
SDL_Flip( gamescreen );
if (over || g_oState.m_bQuitFlag || SState::IN_DEMO == g_oState.m_enGameMode) break;
}
SDL_FreeSurface( poBackground );
SDL_SetClipRect( gamescreen, NULL );
return;
}
diff --git a/src/RlePack.cpp b/src/RlePack.cpp
index b4f55d9..2ea3d61 100644
--- a/src/RlePack.cpp
+++ b/src/RlePack.cpp
@@ -1,809 +1,809 @@
/***************************************************************************
RlePack.cpp - description
-------------------
begin : Mon Sep 24 2001
copyright : (C) 2001 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include "RlePack.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
#include "common.h"
/// Sanity: This is the maximal number of entries in a .DAT file.
#define MAXDATACOUNT 65530
inline void ChangeEndian32( Uint32& a_riArg )
{
char* pcArg = (char*)&a_riArg;
char cTemp;
cTemp = pcArg[0]; pcArg[0] = pcArg[3]; pcArg[3] = cTemp;
cTemp = pcArg[1]; pcArg[1] = pcArg[2]; pcArg[2] = cTemp;
}
inline void ChangeEndian16( Uint16& a_riArg )
{
char* pcArg = (char*)&a_riArg;
char cTemp;
cTemp = pcArg[0]; pcArg[0] = pcArg[1]; pcArg[1] = cTemp;
}
inline Uint32 ConvertEndian32( Uint32 a_iArg )
{
char* pcArg = (char*)&a_iArg;
char cTemp;
cTemp = pcArg[0]; pcArg[0] = pcArg[3]; pcArg[3] = cTemp;
cTemp = pcArg[1]; pcArg[1] = pcArg[2]; pcArg[2] = cTemp;
return a_iArg;
}
inline Uint16 ConvertEndian16( Uint16 a_iArg )
{
char* pcArg = (char*)&a_iArg;
char cTemp;
cTemp = pcArg[0]; pcArg[0] = pcArg[1]; pcArg[1] = cTemp;
return a_iArg;
}
typedef struct RLE_SPRITE /* a RLE compressed sprite */
{
Uint16 dummy; // For better alignment... NASTY NASTY HACK!!
Uint16 color_depth; /* color depth of the image */
Uint16 w, h; /* width and height in pixels */
Uint32 size;
signed char dat[0];
} RLE_SPRITE;
struct RlePack_P
{
SDL_Color m_aoPalette[256];
SDL_Color m_aoTintedPalette[256];
TintEnum m_enTint;
int m_iCount;
int m_iArraysize;
RLE_SPRITE** m_pSprites;
void* m_pData;
int m_iColorCount;
int m_iColorOffset;
};
RlePack::RlePack( const char* a_pcFilename, int a_iNumColors )
{
p = new RlePack_P;
p->m_enTint = NO_TINT;
p->m_iCount = 0;
p->m_iArraysize = 0;
p->m_pSprites = NULL;
p->m_pData = NULL;
p->m_iColorCount = 0;
p->m_iColorOffset = 0;
// Load file and stuff
LoadFile( a_pcFilename, a_iNumColors );
}
RlePack::~RlePack()
{
if (!p)
return;
if (p->m_pSprites)
{
delete[] p->m_pSprites;
p->m_pSprites = NULL;
}
free( p->m_pData );
delete( p );
p = NULL;
}
void RlePack::Clear()
{
if ( p && p->m_pSprites )
{
delete[] p->m_pSprites;
p->m_pSprites = NULL;
}
}
int RlePack::LoadFile( const char* a_pcFilename, int a_iNumColors )
{
FILE* f;
f = fopen( a_pcFilename, "rb" );
if (f==NULL)
{
debug( "Can't open file '%s'.\n", a_pcFilename );
return -1;
}
fseek( f, 0, SEEK_END );
long iFileSize = ftell ( f );
p->m_pData = malloc( iFileSize );
if ( NULL == p->m_pData )
{
fclose( f );
return -1;
}
fseek( f, 0, SEEK_SET );
int iRead = fread( p->m_pData, 1, iFileSize, f );
fclose( f );
p->m_iColorCount = a_iNumColors;
if ( iFileSize != iRead )
{
debug( "Warning RlePack(): iFileSize=%d, iRead=%d\n", iFileSize, iRead );
}
struct SHeader
{
char acDummy[8];
Uint32 iDatacount;
} *poHeader = (SHeader*) p->m_pData;
ChangeEndian32( poHeader->iDatacount );
debug( "File '%s' contains %d entries.\n", a_pcFilename, poHeader->iDatacount );
if (poHeader->iDatacount>MAXDATACOUNT) poHeader->iDatacount = MAXDATACOUNT; // Sanity
p->m_iArraysize = poHeader->iDatacount;
p->m_pSprites = new RLE_SPRITE*[ poHeader->iDatacount ];
char* pcNext = ((char*)p->m_pData) + sizeof(SHeader);
char* pcEnd = ((char*)p->m_pData) + iFileSize;
- while ( pcNext < pcEnd )
+ while ( pcNext < pcEnd - 4 )
{
if ( 0 == strncmp( pcNext, "prop", 4 ) )
{
struct SProperty
{
char acName[4];
Uint32 iSize;
} *poProperty = (SProperty*) (pcNext+4);
ChangeEndian32( poProperty->iSize );
pcNext += 4 + sizeof(SProperty) + poProperty->iSize;
}
else if ( 0 == strncmp( pcNext, "RLE ", 4 ) )
{
struct SRLE
{
RLE_SPRITE oSprite;
} *poRle = (SRLE*) (pcNext+10);
poRle->oSprite.color_depth = ConvertEndian16(poRle->oSprite.color_depth);
poRle->oSprite.w = ConvertEndian16(poRle->oSprite.w);
poRle->oSprite.h = ConvertEndian16(poRle->oSprite.h);
poRle->oSprite.size = ConvertEndian32(poRle->oSprite.size);
p->m_pSprites[p->m_iCount] = &(poRle->oSprite);
p->m_iCount++;
pcNext += 10 + sizeof( SRLE ) + poRle->oSprite.size;
}
else if ( 0 == strncmp( pcNext, "PAL ", 4 ) )
{
struct SPAL
{
Uint32 iLength1;
Uint32 iLength;
SDL_Color aoColors[256];
} *poPal = (SPAL*) (pcNext+4);
ChangeEndian32( poPal->iLength );
int iNumColors = poPal->iLength>1024 ? 1024 : poPal->iLength;
iNumColors /= 4;
for (int i=0; i< iNumColors; i++)
{
p->m_aoPalette[i].r = poPal->aoColors[i].r*4;
p->m_aoPalette[i].g = poPal->aoColors[i].g*4;
p->m_aoPalette[i].b = poPal->aoColors[i].b*4;
p->m_aoPalette[i].unused = 0;
p->m_aoTintedPalette[i] = p->m_aoPalette[i];
}
pcNext += 4 + 8 + poPal->iLength;
}
else
{
struct SUnknown
{
Uint32 iSize;
} *poUnknown = (SUnknown*) (pcNext+4);
ChangeEndian32( poUnknown->iSize );
debug( "Unknown: '%4s', size: %d\n", pcNext, poUnknown->iSize );
pcNext += 4 + sizeof(SUnknown) + poUnknown->iSize;
}
}
return p->m_iCount;
#if 0
int datacount;
#define READDW(I) { \
unsigned char data[4]; \
fread( data, 4, 1, f ); \
(I) = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3]; }
#define READW(I) { \
unsigned char data[2]; \
fread( data, 2, 1, f ); \
(I) = (data[0]<<8) + data[1]; }
#define READCH(S,C) { \
fread( S, C, 1, f ); S[C] = 0; }
fseek( f, 8, SEEK_SET ); // Skip header
READDW( datacount );
debug( "File '%s' contains %d entries.\n", filename, datacount );
if (datacount>500) datacount = 500; // Sanity
p->arraysize = datacount;
p->sprites = new RLE_SPRITE*[ datacount ];
while( (!feof(f)) && (!ferror(f)) && (datacount>0) )
{
char s[10];
READCH( s, 4 );
if ( !strcmp( s, "prop" )) // Found a property
{
fseek( f, 4, SEEK_CUR );
unsigned int propsize;
READDW( propsize );
fseek( f, propsize, SEEK_CUR );
}
else if (!strcmp( s, "RLE " )) // Found an RLE_SPRITE
{
datacount--;
unsigned int length, bpp, width, height, size;
READDW( length );
READDW( length );
READW( bpp );
READW( width );
READW( height );
READDW( size );
RLE_SPRITE* sprite = (RLE_SPRITE*) malloc( sizeof(RLE_SPRITE) + size );
p->sprites[ p->count ] = sprite;
(p->count)++;
sprite->w = width;
sprite->h = height;
sprite->color_depth = bpp;
sprite->size = size;
fread( sprite->dat, 1, size, f );
}
else if (!strcmp( s, "PAL ")) // Found a palette
{
datacount--;
unsigned int length, pallength;
READDW( length );
READDW( length );
pallength = length>1024 ? 1024 : length;
pallength /= 4;
for (unsigned int i=0; i< pallength; i++)
{
char c[4];
fread( c, 4, 1, f );
p->palette[i].r = c[0]*4;
p->palette[i].g = c[1]*4;
p->palette[i].b = c[2]*4;
p->palette[i].unused = 0;
}
fseek( f, length - pallength*4, SEEK_CUR );
}
else // Found something else
{
debug( "Unknown: %s.", s );
datacount--;
unsigned int length;
READDW( length );
READDW( length );
fseek( f, length, SEEK_CUR );
}
}
fclose( f );
#endif
}
int RlePack::Count()
{
return p->m_iCount;
}
void OffsetRLESprite( RLE_SPRITE* spr, int offset ) // Static method
{
if (!spr || !offset) return;
signed char *s = spr->dat;
signed char c;
int y;
for (y=0; y<spr->h; y++)
{
c = *s++;
while (c)
{
// For positive c: solid pixels.
for ( ; c>0; c-- )
{
*s = (*s) + offset;
s++;
}
c = *s++;
}
}
}
void RlePack::OffsetSprites( int a_iOffset )
{
if ( (a_iOffset<=0) || (a_iOffset>255) )
return;
p->m_iColorOffset = a_iOffset;
int i;
// Offset every RLE_SPRITE
for ( i=0; i<p->m_iCount; ++i )
{
OffsetRLESprite( p->m_pSprites[i], a_iOffset );
}
}
void RlePack::SetTint( TintEnum a_enTint )
{
int i;
switch( a_enTint )
{
case ZOMBIE_TINT:
{
for ( i=0; i<p->m_iColorCount; ++i )
{
p->m_aoTintedPalette[i].r = 0;
p->m_aoTintedPalette[i].g = p->m_aoPalette[i].g;
p->m_aoTintedPalette[i].b = 0;
}
break;
}
case GRAY_TINT:
{
int j;
for ( i=0; i<p->m_iColorCount; ++i )
{
j = (p->m_aoPalette[i].r + p->m_aoPalette[i].g + p->m_aoPalette[i].b)/4;
p->m_aoTintedPalette[i].r = j;
p->m_aoTintedPalette[i].g = j;
p->m_aoTintedPalette[i].b = j;
}
break;
}
case DARK_TINT:
{
for ( i=0; i<p->m_iColorCount; ++i )
{
p->m_aoTintedPalette[i].r = int(p->m_aoPalette[i].r) * 2 / 3;
p->m_aoTintedPalette[i].g = int(p->m_aoPalette[i].g) * 2 / 3;
p->m_aoTintedPalette[i].b = int(p->m_aoPalette[i].b) * 2 / 3;
}
break;
}
case INVERTED_TINT:
{
for ( i=0; i<p->m_iColorCount; ++i )
{
p->m_aoTintedPalette[i].r = 255 - p->m_aoPalette[i].r;
p->m_aoTintedPalette[i].g = 255 - p->m_aoPalette[i].g;
p->m_aoTintedPalette[i].b = 255 - p->m_aoPalette[i].b;
}
break;
}
case NO_TINT:
default:
{
for ( i=0; i<p->m_iColorCount; ++i )
{
p->m_aoTintedPalette[i] = p->m_aoPalette[i];
}
break;
}
} // end of switch( a_enTint )
}
void RlePack::ApplyPalette()
{
SDL_SetColors( gamescreen, p->m_aoTintedPalette, p->m_iColorOffset, p->m_iColorCount );
}
/*
SDL_Color* RlePack::getPalette()
{
return p->palette;
}
*/
void draw_rle_sprite_v_flip( RLE_SPRITE* src, int dx, int dy ) // static method
{
#define RLE_PTR signed char*
#define RLE_IS_EOL(c) ((c) == 0)
#define PIXEL_PTR unsigned char*
#define OFFSET_PIXEL_PTR(p,x) ((PIXEL_PTR) (p) + (x))
#define INC_PIXEL_PTR(p) ((p)++)
#define DEC_PIXEL_PTR(p) ((p)--)
#define PUT_PIXEL(p,c) (*((unsigned char *)(p)) = (c))
//#define PUT_PIXEL(p,c) bmp_write8((unsigned long) (p), (c))
int x, y, w, h; // width and height of visible area
int dxbeg, dybeg; // beginning in destination
int sxbeg, sybeg; // beginning in source
RLE_PTR s;
SDL_Surface* dst = gamescreen;
// Clip to dst->clip_rect
int dst_cl = dst->clip_rect.x;
int dst_cr = dst->clip_rect.w + dst_cl - 1;
int dst_ct = dst->clip_rect.y;
int dst_cb = dst->clip_rect.h + dst_ct;
// if (dst->clip)
if (1)
{
int tmp;
dxbeg = dx;
if ( dst_cl > dx ) dxbeg = dst_cl;
tmp = dx + src->w - dst_cr;
sxbeg = ((tmp < 0) ? 0 : tmp);
tmp = dx + src->w;
if (tmp > dst_cr ) tmp = dst_cr;
w = tmp - dxbeg;
if (w <= 0)
return;
tmp = dst_ct - dy;
sybeg = ((tmp < 0) ? 0 : tmp);
dybeg = sybeg + dy;
tmp = dst_cb - dy;
h = ((tmp > src->h) ? src->h : tmp) - sybeg;
if (h <= 0)
return;
}
else {
w = src->w;
h = src->h;
sxbeg = 0;
sybeg = 0;
dxbeg = dx;
dybeg = dy;
}
s = (RLE_PTR) (src->dat);
dxbeg += w;
/* Clip top. */
for (y = sybeg - 1; y >= 0; y--) {
long c = *s++;
while (!RLE_IS_EOL(c)) {
if (c > 0)
s += c;
c = *s++;
}
}
//@@@ bmp_select(dst);
/* Visible part. */
for (y = 0; y < h; y++) {
//@@@ PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
PIXEL_PTR d = (PIXEL_PTR) dst->pixels;
d += (dybeg+y)*dst->pitch;
d = OFFSET_PIXEL_PTR( d, dxbeg );
long c = *s++;
/* Clip left. */
for (x = sxbeg; x > 0; ) {
if (RLE_IS_EOL(c))
goto next_line;
else if (c > 0) {
/* Run of solid pixels. */
if ((x - c) >= 0) {
/* Fully clipped. */
x -= c;
s += c;
}
else {
/* Visible on the right. */
c -= x;
s += x;
break;
}
}
else {
/* Run of transparent pixels. */
if ((x + c) >= 0) {
/* Fully clipped. */
x += c;
}
else {
/* Visible on the right. */
c += x;
break;
}
}
c = *s++;
}
/* Visible part. */
for (x = w; x > 0; ) {
if (RLE_IS_EOL(c))
goto next_line;
else if (c > 0) {
/* Run of solid pixels. */
if ((x - c) >= 0) {
/* Fully visible. */
x -= c;
for (c--; c >= 0; s++, DEC_PIXEL_PTR(d), c--) {
unsigned long col = *s;
PUT_PIXEL(d, col);
}
}
else {
/* Clipped on the right. */
c -= x;
for (x--; x >= 0; s++, DEC_PIXEL_PTR(d), x--) {
unsigned long col = *s;
PUT_PIXEL(d, col);
}
break;
}
}
else {
/* Run of transparent pixels. */
x += c;
d = OFFSET_PIXEL_PTR(d, c);
}
c = *s++;
}
/* Clip right. */
while (!RLE_IS_EOL(c)) {
if (c > 0)
s += c;
c = *s++;
}
next_line: ;
}
//@@@bmp_unwrite_line(dst);
}
void draw_rle_sprite( RLE_SPRITE* src, int dx, int dy ) // static method
{
#define RLE_PTR signed char*
#define RLE_IS_EOL(c) ((c) == 0)
#define PIXEL_PTR unsigned char*
#define OFFSET_PIXEL_PTR(p,x) ((PIXEL_PTR) (p) + (x))
#define INC_PIXEL_PTR(p) ((p)++)
#define DEC_PIXEL_PTR(p) ((p)--)
#define PUT_PIXEL(p,c) (*((unsigned char *)(p)) = (c))
//#define PUT_PIXEL(p,c) bmp_write8((unsigned long) (p), (c))
int x, y, w, h; // width and height of visible area
int dxbeg, dybeg; // beginning in destination
int sxbeg, sybeg; // beginning in source
RLE_PTR s;
SDL_Surface* dst = gamescreen;
// Clip to dst->clip_rect
int dst_cl = dst->clip_rect.x;
int dst_cr = dst->clip_rect.w + dst_cl;
int dst_ct = dst->clip_rect.y;
int dst_cb = dst->clip_rect.h + dst_ct;
// if (dst->clip)
if (1)
{
int tmp;
tmp = dst_cl - dx;
sxbeg = ((tmp < 0) ? 0 : tmp);
dxbeg = sxbeg + dx;
tmp = dst_cr - dx;
w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
if ( w<=0 ) return;
tmp = dst_ct - dy;
sybeg = ((tmp < 0) ? 0 : tmp);
dybeg = sybeg + dy;
tmp = dst_cb - dy;
h = ((tmp > src->h) ? src->h : tmp) - sybeg;
if ( h<=0 ) return;
}
else {
w = src->w;
h = src->h;
sxbeg = 0;
sybeg = 0;
dxbeg = dx;
dybeg = dy;
}
s = (RLE_PTR) (src->dat);
/* Clip top. */
for (y = sybeg - 1; y >= 0; y--) {
long c = *s++;
while (!RLE_IS_EOL(c)) {
if (c > 0)
s += c;
c = *s++;
}
}
//@@@ bmp_select(dst);
/* Visible part. */
for (y = 0; y < h; y++) {
//@@@ PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
PIXEL_PTR d = (PIXEL_PTR) dst->pixels;
d += (dybeg+y)*dst->pitch;
d = OFFSET_PIXEL_PTR( d, dxbeg );
long c = *s++;
/* Clip left. */
for (x = sxbeg; x > 0; ) {
if (RLE_IS_EOL(c))
goto next_line;
else if (c > 0) {
/* Run of solid pixels. */
if ((x - c) >= 0) {
/* Fully clipped. */
x -= c;
s += c;
}
else {
/* Visible on the right. */
c -= x;
s += x;
break;
}
}
else {
/* Run of transparent pixels. */
if ((x + c) >= 0) {
/* Fully clipped. */
x += c;
}
else {
/* Visible on the right. */
c += x;
break;
}
}
c = *s++;
}
/* Visible part. */
for (x = w; x > 0; ) {
if (RLE_IS_EOL(c))
goto next_line;
else if (c > 0) {
/* Run of solid pixels. */
if ((x - c) >= 0) {
/* Fully visible. */
x -= c;
for (c--; c >= 0; s++, INC_PIXEL_PTR(d), c--) {
unsigned long col = *s;
PUT_PIXEL(d, col);
}
}
else {
/* Clipped on the right. */
c -= x;
for (x--; x >= 0; s++, INC_PIXEL_PTR(d), x--) {
unsigned long col = *s;
PUT_PIXEL(d, col);
}
break;
}
}
else {
/* Run of transparent pixels. */
x += c;
d = OFFSET_PIXEL_PTR(d, -c);
}
c = *s++;
}
/* Clip right. */
while (!RLE_IS_EOL(c)) {
if (c > 0)
s += c;
c = *s++;
}
next_line: ;
}
//@@@bmp_unwrite_line(dst);
}
void RlePack::Draw( int a_iIndex, int a_iX, int a_iY, bool a_bFlipped )
{
if ( (a_iIndex<0) || (a_iIndex>=p->m_iCount) )
return;
RLE_SPRITE* poSprite = p->m_pSprites[a_iIndex];
if (!poSprite)
return;
if ( a_bFlipped )
draw_rle_sprite_v_flip( poSprite, a_iX, a_iY );
else
draw_rle_sprite( poSprite, a_iX, a_iY );
}
diff --git a/src/State.cpp b/src/State.cpp
index 1dbf4b8..30bbf4c 100644
--- a/src/State.cpp
+++ b/src/State.cpp
@@ -1,145 +1,143 @@
/***************************************************************************
State.cpp - description
-------------------
begin : Mon Aug 12 2003
copyright : (C) 2003 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include "../config.h"
#include "SDL.h"
#include "common.h"
#include "State.h"
#include <string>
#include <fstream>
#include "Backend.h"
-
-#include <EXTERN.h>
-#include <perl.h>
+#include "MszPerl.h"
extern PerlInterpreter* my_perl;
SState g_oState;
std::string GetConfigHeader()
{
std::string sHeader( "Simple config file " );
sHeader += PACKAGE " " VERSION;
return sHeader;
}
std::string GetConfigFilename()
{
#ifdef _WINDOWS
if ( NULL != g_oState.m_pcArgv0 )
{
return std::string(g_oState.m_pcArgv0) + ".ini";
}
return "c:\\openmortal.ini";
#else
return std::string(getenv("HOME")) + "/.openmortalrc";
#endif
}
void SState::ToggleFullscreen()
{
m_bFullscreen = !m_bFullscreen;
bool bPaletted = ( gamescreen->format->BitsPerPixel <= 8 );
SDL_Color aoPalette[256];
int iNumColors = 0;
if ( bPaletted )
{
iNumColors = gamescreen->format->palette->ncolors;
if ( iNumColors > 256 ) iNumColors = 256;
for ( int i=0; i<iNumColors; ++i )
{
aoPalette[i].r = gamescreen->format->palette->colors[i].r;
aoPalette[i].g = gamescreen->format->palette->colors[i].g;
aoPalette[i].b = gamescreen->format->palette->colors[i].b;
aoPalette[i].unused = 0;
}
}
gamescreen = SDL_SetVideoMode( gamescreen->w, gamescreen->h,
gamescreen->format->BitsPerPixel,
m_bFullscreen ? SDL_FULLSCREEN : SDL_SWSURFACE );
if ( bPaletted )
{
SDL_SetPalette( gamescreen, SDL_LOGPAL | SDL_PHYSPAL, aoPalette, 0, iNumColors );
}
}
void SState::Load()
{
std::string sFilename = GetConfigFilename();
g_oBackend.PerlEvalF( "ParseConfig('%s');", sFilename.c_str() );
SV* poSv;
poSv = get_sv("GAMETIME", FALSE); if (poSv) m_iGameTime = SvIV( poSv );
poSv = get_sv("HITPOINTS", FALSE); if (poSv) m_iHitPoints = SvIV( poSv );
poSv = get_sv("GAMESPEED", FALSE); if (poSv) m_iGameSpeed = SvIV( poSv );
poSv = get_sv("FULLSCREEN", FALSE); if (poSv) m_bFullscreen = SvIV( poSv );
poSv = get_sv("CHANNELS", FALSE); if (poSv) m_iChannels = SvIV( poSv );
poSv = get_sv("MIXINGRATE", FALSE); if (poSv) m_iMixingRate = SvIV( poSv );
poSv = get_sv("MIXINGBITS", FALSE); if (poSv) m_iMixingBits = SvIV( poSv );
poSv = get_sv("MUSICVOLUME", FALSE); if (poSv) m_iMusicVolume = SvIV( poSv );
poSv = get_sv("SOUNDVOLUME", FALSE); if (poSv) m_iSoundVolume = SvIV( poSv );
char pcBuffer[1024];
for ( int i=0; i<2; ++i )
{
for ( int j=0; j<9; ++j )
{
sprintf( pcBuffer, "PLAYER%dKEY%d", i, j );
poSv = get_sv(pcBuffer, FALSE); if (poSv) m_aiPlayerKeys[i][j] = SvIV( poSv );
}
}
}
void SState::Save()
{
std::string sFilename = GetConfigFilename();
std::ofstream oStream( sFilename.c_str(), std::ios_base::out | std::ios_base::trunc );
if ( oStream.rdstate() & std::ios::failbit )
{
debug( "Unable to open config file: %s\n", sFilename.c_str() );
return;
}
oStream << GetConfigHeader() << '\n';
oStream << "GAMETIME=" << m_iGameTime << '\n';
oStream << "HITPOINTS=" << m_iHitPoints << '\n';
oStream << "GAMESPEED=" << m_iGameSpeed << '\n';
oStream << "FULLSCREEN=" << m_bFullscreen << '\n';
oStream << "CHANNELS=" << m_iChannels << '\n';
oStream << "MIXINGRATE=" << m_iMixingRate << '\n';
oStream << "MIXINGBITS=" << m_iMixingBits << '\n';
oStream << "MUSICVOLUME=" << m_iMusicVolume << '\n';
oStream << "SOUNDVOLUME=" << m_iSoundVolume << '\n';
for ( int i=0; i<2; ++i )
{
for ( int j=0; j<9; ++j )
{
oStream << "PLAYER" <<i<< "KEY" <<j<< '=' << m_aiPlayerKeys[i][j] << '\n';
}
}
oStream.flush();
oStream.close();
}
diff --git a/src/State.h b/src/State.h
index 67c8150..e700b12 100644
--- a/src/State.h
+++ b/src/State.h
@@ -1,93 +1,93 @@
/***************************************************************************
State.h - description
-------------------
begin : Mon Aug 12 2003
copyright : (C) 2003 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#ifndef STATE_H
#define STATE_H
#include "SDL_mixer.h"
#include "SDL_keysym.h"
struct SState
{
enum TGameMode {
IN_DEMO,
IN_SINGLE,
IN_MULTI,
} m_enGameMode;
bool m_bQuitFlag; // true if quit event came
const char* m_pcArgv0; // Set by main to argv[0]
// CONFIGURATION VARIABLES
int m_iGameTime; // Time of rounds in seconds.
int m_iHitPoints; // The initial number of hit points.
int m_iGameSpeed; // The speed of the game (fps = 1000/GameSpeed)
bool m_bFullscreen; // True in fullscreen mode.
int m_iChannels; // 1: mono, 2: stereo
int m_iMixingRate; // The mixing rate, in kHz
int m_iMixingBits; // 1: 8bit, 2: 16bit
int m_iMusicVolume; // Volume of music; 0: off, 100: max
int m_iSoundVolume; // Volume of sound effects; 0: off, 100: max
int m_aiPlayerKeys[2][9]; // Player keysyms
SState()
{
m_enGameMode = IN_DEMO;
m_bQuitFlag = false;
m_pcArgv0 = NULL;
m_iGameTime = 60;
m_iHitPoints = 100;
m_iGameSpeed = 12;
#ifdef _WINDOWS
#ifdef _DEBUG
- m_bFullScreen = false;
+ m_bFullscreen = false;
#else
m_bFullscreen = true;
#endif
#else
m_bFullscreen = false;
#endif
m_iChannels = 2;
m_iMixingRate = MIX_DEFAULT_FREQUENCY;
m_iMixingBits = 2;
m_iMusicVolume = 50;
m_iSoundVolume = 100;
static const int aiDefaultKeys[2][9] = {
{ SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT, SDLK_PAGEDOWN,
SDLK_DELETE, SDLK_INSERT, SDLK_END, SDLK_HOME },
{ SDLK_w, SDLK_s, SDLK_a, SDLK_d, SDLK_x,
SDLK_f, SDLK_r, SDLK_g, SDLK_t }
};
for ( int i=0; i<2; ++i )
for ( int j=0; j<9; ++j )
m_aiPlayerKeys[i][j] = aiDefaultKeys[i][j];
};
void Load();
void Save();
void ToggleFullscreen();
};
extern SState g_oState;
#endif
diff --git a/src/main.cpp b/src/main.cpp
index 4a0b2ec..afafe4b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,346 +1,361 @@
/***************************************************************************
main.cpp - description
-------------------
begin : Wed Aug 22 10:18:47 CEST 2001
copyright : (C) 2001 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "PlayerSelect.h"
-
-#include "SDL_video.h"
-#include "sge_tt_text.h"
-#include "sge_bm_text.h"
-#include "sge_surface.h"
-#include "SDL.h"
-#include "SDL_image.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <string>
-
-#include "common.h"
-#include "gfx.h"
-#include "Audio.h"
-#include "RlePack.h"
-#include "Backend.h"
-#include "State.h"
-
-
-_sge_TTFont* inkFont;
-_sge_TTFont* impactFont;
-_sge_TTFont* titleFont;
-sge_bmpFont* fastFont;
-sge_bmpFont* creditsFont;
-sge_bmpFont* storyFont;
-
-SDL_Color Colors[] =
-{
- { 0, 0, 0, 0 }, { 0, 0, 42, 0 }, { 0, 42, 0, 0 }, { 0, 42, 42, 0 },
- { 42, 0, 0, 0 }, { 42, 0, 42, 0 }, { 63, 42, 0, 0 }, { 42, 42, 42, 0 },
- { 21, 21, 21, 0 }, { 21, 21, 63, 0 }, { 21, 63, 21, 0 }, { 21, 63, 63, 0 },
- { 63, 21, 21, 0 }, { 63, 21, 63, 0 }, { 63, 63, 21, 0 }, { 63, 63, 63, 0 }
-};
-
-
-void Complain( const char* a_pcError )
-{
-#ifdef _WINDOWS
- ::MessageBoxA( 0, a_pcError, "OpenMortal", MB_ICONEXCLAMATION );
-#else
- fprintf( stderr, "%s", a_pcError );
-#endif
-}
-
-
-_sge_TTFont* LoadTTF( const char* a_pcFilename, int a_iSize )
-{
- std::string sPath = std::string(DATADIR) + "/fonts/" + a_pcFilename;
- _sge_TTFont* poFont = sge_TTF_OpenFont( sPath.c_str(), a_iSize );
-
- if ( NULL == poFont )
- {
- Complain( ("Couldn't load font: " + sPath).c_str() );
- }
-
- return poFont;
-}
-
-
-sge_bmpFont* LoadBMPFont( const char* a_pcFilename )
-{
- std::string sPath = std::string(DATADIR) + "/fonts/" + a_pcFilename;
- sge_bmpFont* poFont = sge_BF_OpenFont( sPath.c_str(), SGE_BFSFONT | SGE_BFTRANSP );
- if ( NULL == poFont )
- {
- Complain( ("Couldn't load font: " + sPath).c_str() );
- }
- return poFont;
-}
-
-
-int init( int iFlags )
-{
- if (SDL_Init(SDL_INIT_VIDEO /*| SDL_INIT_AUDIO*/) < 0)
- {
- fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError());
- return -1;
- }
- atexit(SDL_Quit);
-
- int d = SDL_VideoModeOK(640, 480, 8, iFlags);
- if (d == 0)
- {
- fprintf(stderr, "requested video mode not available\n");
-// return -1;
- }
-
- gamescreen = SDL_SetVideoMode(640, 480, 8, iFlags);
- if (gamescreen == NULL)
- {
- fprintf(stderr, "failed to set video mode: %s\n", SDL_GetError());
- return -1;
- }
-
- SDL_WM_SetCaption( "OpenMortal", "OpenMortal" );
- std::string sPath = std::string(DATADIR) + "/gfx/icon.png";
- SDL_WM_SetIcon(IMG_Load(sPath.c_str()), NULL);
- SDL_ShowCursor( SDL_DISABLE );
-
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "PlayerSelect.h"
+
+#include "SDL_video.h"
+#include "sge_tt_text.h"
+#include "sge_bm_text.h"
+#include "sge_surface.h"
+#include "SDL.h"
+#include "SDL_image.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <string>
+
+#include "common.h"
+#include "gfx.h"
+#include "Audio.h"
+#include "RlePack.h"
+#include "Backend.h"
+#include "State.h"
+#include "Demo.h"
+
+
+#ifdef _WINDOWS
+
+#undef DATADIR // GRRR.. windows keyword...
+#include <windows.h>
+#define DATADIR "../data"
+
+#endif
+
+_sge_TTFont* inkFont;
+_sge_TTFont* impactFont;
+_sge_TTFont* titleFont;
+sge_bmpFont* fastFont;
+sge_bmpFont* creditsFont;
+sge_bmpFont* storyFont;
+
+SDL_Color Colors[] =
+{
+ { 0, 0, 0, 0 }, { 0, 0, 42, 0 }, { 0, 42, 0, 0 }, { 0, 42, 42, 0 },
+ { 42, 0, 0, 0 }, { 42, 0, 42, 0 }, { 63, 42, 0, 0 }, { 42, 42, 42, 0 },
+ { 21, 21, 21, 0 }, { 21, 21, 63, 0 }, { 21, 63, 21, 0 }, { 21, 63, 63, 0 },
+ { 63, 21, 21, 0 }, { 63, 21, 63, 0 }, { 63, 63, 21, 0 }, { 63, 63, 63, 0 }
+};
+
+
+void Complain( const char* a_pcError )
+{
+#ifdef _WINDOWS
+ ::MessageBoxA( 0, a_pcError, "OpenMortal", MB_ICONEXCLAMATION );
+#else
+ fprintf( stderr, "%s", a_pcError );
+#endif
+}
+
+
+_sge_TTFont* LoadTTF( const char* a_pcFilename, int a_iSize )
+{
+ std::string sPath = std::string(DATADIR) + "/fonts/" + a_pcFilename;
+ _sge_TTFont* poFont = sge_TTF_OpenFont( sPath.c_str(), a_iSize );
+
+ if ( NULL == poFont )
+ {
+ Complain( ("Couldn't load font: " + sPath).c_str() );
+ }
+
+
+ return poFont;
+}
+
+
+sge_bmpFont* LoadBMPFont( const char* a_pcFilename )
+{
+ std::string sPath = std::string(DATADIR) + "/fonts/" + a_pcFilename;
+ sge_bmpFont* poFont = sge_BF_OpenFont( sPath.c_str(), SGE_BFSFONT | SGE_BFTRANSP );
+ if ( NULL == poFont )
+ {
+ Complain( ("Couldn't load font: " + sPath).c_str() );
+ }
+ return poFont;
+}
+
+
+int init( int iFlags )
+{
+ if (SDL_Init(SDL_INIT_VIDEO /*| SDL_INIT_AUDIO*/) < 0)
+ {
+ fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError());
+ return -1;
+ }
+ atexit(SDL_Quit);
+
+ int d = SDL_VideoModeOK(640, 480, 8, iFlags);
+ if (d == 0)
+ {
+ fprintf(stderr, "requested video mode not available\n");
+// return -1;
+ }
+
+ gamescreen = SDL_SetVideoMode(640, 480, 8, iFlags);
+ if (gamescreen == NULL)
+ {
+ fprintf(stderr, "failed to set video mode: %s\n", SDL_GetError());
+ return -1;
+ }
+
+ SDL_WM_SetCaption( "OpenMortal", "OpenMortal" );
+ std::string sPath = std::string(DATADIR) + "/gfx/icon.png";
+ SDL_WM_SetIcon(IMG_Load(sPath.c_str()), NULL);
+ SDL_ShowCursor( SDL_DISABLE );
+
for ( int i=0; i<16; ++i ) { Colors[i].r *=4; Colors[i].g *=4; Colors[i].b *=4; }
SDL_SetColors( gamescreen, Colors, 256-16, 16 );
if ( sge_TTF_Init() )
{
fprintf(stderr, "couldn't start ttf engine: %s\n", SDL_GetError());
return -1;
}
- sge_TTF_AAOff();
-
- inkFont = LoadTTF( "aardvark.ttf", 24 );
- if ( !inkFont ) return -1;
- impactFont = LoadTTF( "gooddogc.ttf", 20 );
- if ( !impactFont ) return -1;
- titleFont = LoadTTF( "manslem.ttf", 40 );
- if ( !titleFont ) return -1;
-
- fastFont = LoadBMPFont( "impactfont2.png" );
- if ( !fastFont ) return -1;
+ sge_TTF_AAOff();
+
+ inkFont = LoadTTF( "aardvark.ttf", 24 );
+ if ( !inkFont ) return -1;
+ impactFont = LoadTTF( "gooddogc.ttf", 20 );
+ if ( !impactFont ) return -1;
+ titleFont = LoadTTF( "manslem.ttf", 40 );
+ if ( !titleFont ) return -1;
+
+ fastFont = LoadBMPFont( "impactfont2.png" );
+ if ( !fastFont ) return -1;
//SDL_SetColorKey( fastFont->FontSurface, SDL_SRCCOLORKEY | SDL_RLEACCEL,
// sge_GetPixel(fastFont->FontSurface,0,fastFont->FontSurface->h-1) );
- creditsFont = LoadBMPFont( "fangfont.png" );
- storyFont = LoadBMPFont( "glossyfont.png" );
- if ( !creditsFont ) return -1;
-
- return 0;
-}
-
-
-int init2()
-{
- if ( !g_oBackend.Construct() )
- {
- fprintf(stderr, "couldn't start backend.\n" );
- return -1;
- }
- return 0;
-}
-
-
-
-
-
-int DrawMainScreen()
-{
- SDL_Surface* background = LoadBackground( "Mortal.png", 240 );
- SDL_Rect r;
- r.x = r.y = 0;
-
- std::string sStaffFilename = DATADIR;
- sStaffFilename += "/characters/STAFF.DAT";
- RlePack pack( sStaffFilename.c_str(), 240 );
- pack.ApplyPalette();
- //SDL_SetColors( gamescreen, pack.getPalette(), 0, 240 );
- SDL_BlitSurface( background, NULL, gamescreen, &r );
+ creditsFont = LoadBMPFont( "fangfont.png" );
+ storyFont = LoadBMPFont( "glossyfont.png" );
+ if ( !creditsFont ) return -1;
+
+ return 0;
+}
+
+
+int init2()
+{
+ if ( !g_oBackend.Construct() )
+ {
+ fprintf(stderr, "couldn't start backend.\n" );
+ return -1;
+ }
+ return 0;
+}
+
+
+
+
+
+int DrawMainScreen()
+{
+ SDL_Surface* background = LoadBackground( "Mortal.png", 240 );
+ SDL_Rect r;
+ r.x = r.y = 0;
+
+ std::string sStaffFilename = DATADIR;
+ sStaffFilename += "/characters/STAFF.DAT";
+ RlePack pack( sStaffFilename.c_str(), 240 );
+ pack.ApplyPalette();
+ //SDL_SetColors( gamescreen, pack.getPalette(), 0, 240 );
+ SDL_BlitSurface( background, NULL, gamescreen, &r );
SDL_Flip( gamescreen );
-
- FighterEnum f[14] = {
- UPI, ZOLI, SURBA, ULMAR, MISI, BENCE,
- DESCANT, KINGA, GRIZLI, SIRPI, MACI, DANI, CUMI,
- AMBRUS };
- char* filename[14] = {
- "UPi.pl", "Zoli.pl", NULL, "Ulmar.pl", NULL, "Bence.pl",
- "Descant.pl", NULL, "Grizli.pl", "Sirpi.pl", "Maci.pl", NULL, "Cumi.pl",
- NULL };
- int x[14] = {
- 0, 26, 67, 125, 159, 209,
- 249, 289, 358, 397, 451, 489, 532, 161 };
- int y[14] = {
- 5, 4, 5, 5, 5, 7,
- 4, 0, 7, 5, 5, 6, 5, 243 };
-
+
+ char* filename[15] = {
+ "Jacint.pl", "Jozsi.pl", "Agent.pl", "Mrsmith.pl",
+ "Sleepy.pl", "Tejszin.pl",
+ "UPi.pl", "Zoli.pl", "Ulmar.pl", "Bence.pl",
+ "Descant.pl", "Grizli.pl", "Sirpi.pl", "Macy.pl", "Cumi.pl" };
+ int x[14] = {
+ 0, 26, 67, 125, 159, 209,
+ 249, 289, 358, 397, 451, 489, 532, 161 };
+ int y[14] = {
+ 5, 4, 5, 5, 5, 7,
+ 4, 0, 7, 5, 5, 6, 5, 243 };
+
int i;
-
- for ( i=0; i<14; ++i )
- {
- pack.Draw( i, x[i], y[i], false );
- SDL_Flip( gamescreen );
- if ( filename[i] != NULL )
- {
- debug( "Loading fighter %s", filename[i] );
- g_oBackend.PerlEvalF( "require '%s';", filename[i] );
- }
- }
-
+
+ g_oBackend.PerlEvalF( "eval( \"require '%s/characters/Ambrus.pl';\" )", DATADIR );
+ g_oBackend.PerlEvalF( "eval( \"require '%s/characters/Dani.pl';\" )", DATADIR );
+
+ for ( i=0; i<15; ++i )
+ {
+ pack.Draw( i, x[i], y[i], false );
+ SDL_Flip( gamescreen );
+ if ( filename[i] != NULL )
+ {
+ debug( "Loading fighter %s", filename[i] );
+ g_oBackend.PerlEvalF( "eval( \"require '%s/characters/%s';\" )", DATADIR, filename[i] );
+ }
+ }
+
int retval = 0;
i = 0;
SDL_Event event;
-
- SDL_FreeSurface( background );
- return retval;
-
-}
-
-
-
-int main(int argc, char *argv[])
-{
- srand( (unsigned int)time(NULL) );
- if ( 0 != init2() )
- {
- fprintf( stderr, "init2() failed." );
- return -1;
- }
-
- g_oState.m_pcArgv0 = argv[0];
- g_oState.Load();
-
+
+ SDL_FreeSurface( background );
+ return retval;
+
+}
+
+
+
+int main(int argc, char *argv[])
+{
+ srand( (unsigned int)time(NULL) );
+ if ( 0 != init2() )
+ {
+ fprintf( stderr, "init2() failed." );
+ return -1;
+ }
+
+ g_oState.m_pcArgv0 = argv[0];
+ g_oState.Load();
+
bool bDebug = false;
-
- int iFlags = SDL_SWSURFACE | SDL_HWPALETTE;
- if ( g_oState.m_bFullscreen )
- {
- iFlags |= SDL_FULLSCREEN;
- }
-
- int i;
- for ( i=1; i<argc; ++i )
- {
- if ( !strcmp(argv[i], "-debug") )
- {
- bDebug = true;
- }
- else if ( !strcmp(argv[i], "-fullscreen") )
- {
- iFlags |= SDL_FULLSCREEN;
- }
- else if ( !strcmp(argv[i], "-hwsurface") )
- {
- iFlags |= SDL_HWSURFACE;
- }
- else if ( !strcmp(argv[i], "-doublebuf") )
- {
- iFlags |= SDL_DOUBLEBUF;
- }
- else if ( !strcmp(argv[i], "-anyformat") )
- {
- iFlags |= SDL_ANYFORMAT;
- }
- else
- {
- printf( "Usage: %s [-debug] [-fullscreen] [-hwsurface] [-doublebuf] [-anyformat]\n", argv[0] );
- return 0;
- }
- }
-
- if (init( iFlags )<0)
- {
- return -1;
- }
-
- new MszAudio;
- Audio->LoadMusic( "Last_Ninja_-_The_Wilderness.mid", "DemoMusic" );
- Audio->PlayMusic( "DemoMusic" );
- Audio->LoadMusic( "2nd_pm.s3m", "GameMusic" );
-
- DrawMainScreen();
-
- g_oPlayerSelect.SetPlayer( 0, ZOLI );
- g_oPlayerSelect.SetPlayer( 1, SIRPI );
-
- int nextFighter = 0;
- int describeOrder[ (int)LASTFIGHTER ];
-
- for ( i=0; i<(int)LASTFIGHTER; ++i ) describeOrder[i] = i;
- for ( i=0; i<100; ++i )
- {
- int j = rand() % (int)LASTFIGHTER;
- int k = rand() % (int)LASTFIGHTER;
- int l;
- l = describeOrder[j];
- describeOrder[j] = describeOrder[k];
- describeOrder[k] = l;
- }
-
- /*
- {
- int iGameNumber=0;
- char acReplayFile[1024];
-
- for ( i=0; i<15; ++i )
- {
- sprintf( acReplayFile, DATADIR "/msz%i.replay", i );
- DrawTextMSZ( acReplayFile, impactFont, 10, 10, 0, C_WHITE, gamescreen );
- SDL_Delay(5000 );
-
- DoGame( acReplayFile, true, bDebug );
- }
- }
- */
-
- while ( 1 )
- {
- if ( g_oState.m_bQuitFlag ) break;
- DoDemos();
- if ( g_oState.m_bQuitFlag ) break;
-
- Audio->PlaySample( "car_start.voc" );
- Audio->PlayMusic( "GameMusic" );
-
- while ( g_oState.m_enGameMode != SState::IN_DEMO
- && !g_oState.m_bQuitFlag )
- {
- g_oPlayerSelect.DoPlayerSelect();
- if ( g_oState.m_bQuitFlag || g_oState.m_enGameMode == SState::IN_DEMO ) break;
-
- //sprintf( acReplayFile, "/tmp/msz%d.replay", ++iGameNumber );
-
- int iGameResult = DoGame( NULL, false, bDebug );
- //int iGameResult = DoGame( acReplayFile, false, bDebug );
- //DoGame( acReplayFile, true, bDebug );
- if ( g_oState.m_bQuitFlag || g_oState.m_enGameMode == SState::IN_DEMO ) break;
-
- debug ( "iGameResult = %d\n", iGameResult );
-
- if ( iGameResult >= 0 )
- {
- GameOver( iGameResult );
- }
- if ( g_oState.m_bQuitFlag || g_oState.m_enGameMode == SState::IN_DEMO ) break;
- }
-
- if ( g_oState.m_bQuitFlag ) break;
- Audio->PlayMusic( "DemoMusic" );
- }
-
- g_oState.Save();
- return EXIT_SUCCESS;
-}
+
+ int iFlags = SDL_SWSURFACE | SDL_HWPALETTE;
+ if ( g_oState.m_bFullscreen )
+ {
+ iFlags |= SDL_FULLSCREEN;
+ }
+
+ int i;
+ for ( i=1; i<argc; ++i )
+ {
+ if ( !strcmp(argv[i], "-debug") )
+ {
+ bDebug = true;
+ }
+ else if ( !strcmp(argv[i], "-fullscreen") )
+ {
+ iFlags |= SDL_FULLSCREEN;
+ }
+ else if ( !strcmp(argv[i], "-hwsurface") )
+ {
+ iFlags |= SDL_HWSURFACE;
+ }
+ else if ( !strcmp(argv[i], "-doublebuf") )
+ {
+ iFlags |= SDL_DOUBLEBUF;
+ }
+ else if ( !strcmp(argv[i], "-anyformat") )
+ {
+ iFlags |= SDL_ANYFORMAT;
+ }
+ else
+ {
+ printf( "Usage: %s [-debug] [-fullscreen] [-hwsurface] [-doublebuf] [-anyformat]\n", argv[0] );
+ return 0;
+ }
+ }
+
+ if (init( iFlags )<0)
+ {
+ return -1;
+ }
+
+ new MszAudio;
+ Audio->LoadMusic( "Last_Ninja_-_The_Wilderness.mid", "DemoMusic" );
+ Audio->PlayMusic( "DemoMusic" );
+ Audio->LoadMusic( "2nd_pm.s3m", "GameMusic" );
+
+ DrawMainScreen();
+
+ g_oPlayerSelect.SetPlayer( 0, ZOLI );
+ g_oPlayerSelect.SetPlayer( 1, SIRPI );
+
+ int nextFighter = 0;
+ int describeOrder[ (int)LASTFIGHTER ];
+
+ for ( i=0; i<(int)LASTFIGHTER; ++i ) describeOrder[i] = i;
+ for ( i=0; i<100; ++i )
+ {
+ int j = rand() % (int)LASTFIGHTER;
+ int k = rand() % (int)LASTFIGHTER;
+ int l;
+ l = describeOrder[j];
+ describeOrder[j] = describeOrder[k];
+ describeOrder[k] = l;
+ }
+
+ /*
+ {
+ int iGameNumber=0;
+ char acReplayFile[1024];
+
+ for ( i=0; i<15; ++i )
+ {
+ sprintf( acReplayFile, DATADIR "/msz%i.replay", i );
+ DrawTextMSZ( acReplayFile, impactFont, 10, 10, 0, C_WHITE, gamescreen );
+ SDL_Delay(5000 );
+
+ DoGame( acReplayFile, true, bDebug );
+ }
+ }
+ */
+
+ while ( 1 )
+ {
+ if ( g_oState.m_bQuitFlag ) break;
+ DoDemos();
+ if ( g_oState.m_bQuitFlag ) break;
+
+ Audio->PlaySample( "car_start.voc" );
+ Audio->PlayMusic( "GameMusic" );
+
+ while ( g_oState.m_enGameMode != SState::IN_DEMO
+ && !g_oState.m_bQuitFlag )
+ {
+ g_oPlayerSelect.DoPlayerSelect();
+ if ( g_oState.m_bQuitFlag || g_oState.m_enGameMode == SState::IN_DEMO ) break;
+
+ //sprintf( acReplayFile, "/tmp/msz%d.replay", ++iGameNumber );
+
+ int iGameResult = DoGame( NULL, false, bDebug );
+ //int iGameResult = DoGame( acReplayFile, false, bDebug );
+ //DoGame( acReplayFile, true, bDebug );
+ if ( g_oState.m_bQuitFlag || g_oState.m_enGameMode == SState::IN_DEMO ) break;
+
+ debug ( "iGameResult = %d\n", iGameResult );
+
+ if ( iGameResult >= 0 )
+ {
+ GameOver( iGameResult );
+ FighterStatsDemo oDemo( g_oPlayerSelect.GetPlayerInfo( iGameResult ).m_enFighter );
+ oDemo.Run();
+ }
+ if ( g_oState.m_bQuitFlag || g_oState.m_enGameMode == SState::IN_DEMO ) break;
+ }
+
+ if ( g_oState.m_bQuitFlag ) break;
+ Audio->PlayMusic( "DemoMusic" );
+ }
+
+ g_oState.Save();
+
+ SDL_Quit();
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/sge_bm_text.cpp b/src/sge_bm_text.cpp
index 22aeed4..d553c98 100644
--- a/src/sge_bm_text.cpp
+++ b/src/sge_bm_text.cpp
@@ -1,552 +1,552 @@
/*
* SDL Graphics Extension
* Text/Bitmap font functions
*
* Started 990815
*
* License: LGPL v2+ (see the file LICENSE)
* (c)1999-2001 Anders Lindstr?m
*/
/*********************************************************************
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
*********************************************************************/
/*
* Some of this is taken from SDL_DrawText by Garrett Banuk (mongoose@wpi.edu)
* http://www.wpi.edu/~mongoose/SDL_Console
* Thanks to Karl Bartel for the SFont format!
*/
#include "SDL.h"
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <new>
#include "sge_surface.h"
#include "sge_bm_text.h"
#include "sge_tt_text.h"
#ifdef _SGE_HAVE_IMG
#include "SDL_image.h"
#endif
using namespace std;
/* Globals used for sge_Update/sge_Lock (defined in sge_surface) */
extern Uint8 _sge_update;
extern Uint8 _sge_lock;
//==================================================================================
// Creates a new font from a surface
//==================================================================================
sge_bmpFont* sge_BF_CreateFont(SDL_Surface *surface, Uint8 flags)
{
sge_bmpFont *font;
font = new(nothrow) sge_bmpFont; if(font==NULL){SDL_SetError("SGE - Out of memory");return NULL;}
if(!(flags&SGE_BFNOCONVERT) && !(flags&SGE_BFSFONT)){ /* Get a converted copy */
font->FontSurface = SDL_DisplayFormat(surface);
if(font->FontSurface==NULL){SDL_SetError("SGE - Out of memory");return NULL;}
if(flags&SGE_BFPALETTE){ //We want an 8bit surface
SDL_Surface *tmp;
tmp = SDL_AllocSurface(SDL_SWSURFACE, surface->w, surface->h, 8, 0, 0, 0, 0);
if(tmp==NULL){SDL_SetError("SGE - Out of memory");SDL_FreeSurface(font->FontSurface);return NULL;}
//Set the palette
tmp->format->palette->colors[0].r = 0;
tmp->format->palette->colors[0].g = 0;
tmp->format->palette->colors[0].b = 0;
tmp->format->palette->colors[1].r = 255;
tmp->format->palette->colors[1].g = 255;
tmp->format->palette->colors[1].b = 255;
if (SDL_MUSTLOCK(font->FontSurface) && _sge_lock)
if (SDL_LockSurface(font->FontSurface) < 0){
SDL_SetError("SGE - Locking error");
SDL_FreeSurface(font->FontSurface);
return NULL;
}
//Copy the font to the 8bit surface
Sint16 x,y;
Uint32 bc=sge_GetPixel(font->FontSurface,0,surface->h-1);
for(y=0; y<font->FontSurface->h; y++){
for(x=0; x<font->FontSurface->w; x++){
if(sge_GetPixel(font->FontSurface,x,y)==bc)
*((Uint8 *)tmp->pixels + y * tmp->pitch + x)=0;
else
*((Uint8 *)tmp->pixels + y * tmp->pitch + x)=1;
}
}
if (SDL_MUSTLOCK(font->FontSurface) && _sge_lock) {
SDL_UnlockSurface(font->FontSurface);
}
//sge_Blit(surface, tmp, 0,0,0,0,surface->w, surface->h);
SDL_FreeSurface(font->FontSurface);
font->FontSurface=tmp;
}
if((flags&SGE_FLAG8))
SDL_FreeSurface(surface);
}
else if(flags&SGE_FLAG8) /* Use the source */
font->FontSurface = surface;
else /* Get a copy */
font->FontSurface = sge_copy_surface(surface);
if(font->FontSurface==NULL){SDL_SetError("SGE - Out of memory");return NULL;}
SDL_Surface *fnt = font->FontSurface; //Shorthand
font->Chars=0;
if(!(flags&SGE_BFSFONT)){ /* Fixed width font */
font->CharWidth = font->FontSurface->w/256;
font->CharHeight = font->FontSurface->h;
font->CharPos = NULL;
font->yoffs = 0;
font->Chars=256;
}
else{ /* Karl Bartel's sfont */
Sint16 x=0;
int i=0;
font->CharPos = new(nothrow) Sint16[512];
if(!font->CharPos){SDL_SetError("SGE - Out of memory");sge_BF_CloseFont(font);return NULL;}
Uint32 color = sge_GetPixel(fnt,0,0);
while (x<fnt->w && font->Chars<256){
if (sge_GetPixel(fnt,x,0)==color) {
font->CharPos[i++]=x;
while (x<fnt->w-1 && sge_GetPixel(fnt,x,0)==color)
x++;
font->CharPos[i++]=x;
font->Chars++;
}
x++;
}
font->CharHeight = font->FontSurface->h-1;
font->CharWidth = 0;
font->yoffs = 1;
}
/* Set font as transparent if the flag is set */
if (SDL_MUSTLOCK(font->FontSurface) && _sge_lock)
if (SDL_LockSurface(font->FontSurface) < 0){
return font;
}
font->bcolor=sge_GetPixel(font->FontSurface,0,font->FontSurface->h-1);
if (SDL_MUSTLOCK(font->FontSurface) && _sge_lock) {
SDL_UnlockSurface(font->FontSurface);
}
if(flags&SGE_BFTRANSP || flags&SGE_BFSFONT)
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >= \
SDL_VERSIONNUM(1, 1, 4)
SDL_SetColorKey(font->FontSurface,SDL_SRCCOLORKEY, font->bcolor); //Some versions of SDL have a bug with SDL_RLEACCEL
#else
SDL_SetColorKey(font->FontSurface,SDL_SRCCOLORKEY|SDL_RLEACCEL, font->bcolor);
#endif
return font;
}
//==================================================================================
// Loads the font into a new struct
//==================================================================================
sge_bmpFont* sge_BF_OpenFont(const char *file, Uint8 flags)
{
sge_bmpFont *font;
SDL_Surface *Temp;
/* load the font bitmap */
#ifdef _SGE_HAVE_IMG
if(NULL == (Temp = IMG_Load(file))) //We have SDL_Img lib!
#else
if(NULL == (Temp = SDL_LoadBMP(file))) //We can only load bmp files...
#endif
{
sge_SetError("SGE - Couldn't load font file: %s",file);
return NULL;
}
font = sge_BF_CreateFont(Temp,flags|SGE_FLAG8); //SGE_FLAG8 - no need to make a copy of the surface
return font;
}
//==================================================================================
// Draws string to surface with the selected font
// Returns pos. and size of the drawn text
//==================================================================================
-SDL_Rect sge_BF_textout(SDL_Surface *surface, sge_bmpFont *font, const char *string, Sint16 x, Sint16 y, int length)
+SDL_Rect sge_BF_textout(SDL_Surface *surface, sge_bmpFont *font, const char *string, Sint16 x, Sint16 y, int length, bool doupdate)
{
SDL_Rect ret; ret.x=0;ret.y=0;ret.w=0;ret.h=0;
if(font==NULL || length==0){return ret;}
int characters;
Sint16 xsrc,xdest,ofs,adv=font->CharWidth;
float diff=0;
/* Valid coords ? */
if(surface)
if(x>surface->w || y>surface->h)
return ret;
characters = strlen(string);
xdest=x;
/* Now draw it */
for(int i=0; i<characters; i++)
{
if(!font->CharPos) /* Fixed width */
xsrc = string[i] * font->CharWidth;
else{ /* Variable width */
if(string[i]==' ' || (string[i]-33)>font->Chars || string[i]<33){
xdest += font->CharPos[2]-font->CharPos[1];
continue;
}
ofs = (string[i]-33)*2+1;
xsrc = (font->CharPos[ofs]+font->CharPos[ofs-1])/2;
//font->CharWidth = (font->CharPos[ofs+2]+font->CharPos[ofs+1])/2-(font->CharPos[ofs]+font->CharPos[ofs-1])/2-1;
font->CharWidth = (font->CharPos[ofs+2]+font->CharPos[ofs+1])/2-(font->CharPos[ofs]+font->CharPos[ofs-1])/2;
adv = font->CharPos[ofs+1]-font->CharPos[ofs];
diff =(font->CharPos[ofs]-font->CharPos[ofs-1])/2.0;
}
if(surface)
sge_Blit(font->FontSurface, surface, xsrc,font->yoffs, int(xdest-diff),y, font->CharWidth,font->CharHeight);
xdest += adv;
--length;
if (0 == length)
{
break;
}
}
ret.x=x; ret.y=y; ret.w=xdest-x+font->CharWidth; ret.h=font->CharHeight;
- if(surface)
+ if(surface && doupdate)
sge_UpdateRect(surface, x, y, ret.w, ret.h);
return ret;
}
//==================================================================================
// Returns the size (w and h) of the string (if rendered with font)
//==================================================================================
SDL_Rect sge_BF_TextSize(sge_bmpFont *font, const char *string, int length)
{
return sge_BF_textout(NULL, font, string, 0, 0, length);
}
//==================================================================================
// Draws formated text to surface with the selected font
// Returns pos. and size of the drawn text
// * just like printf(char *format, ...) *
//==================================================================================
SDL_Rect sge_BF_textoutf(SDL_Surface *surface, sge_bmpFont *font, Sint16 x, Sint16 y ,const char *format, ...)
{
char buf[256];
va_list ap;
#ifdef __WIN32__
va_start((va_list*)ap, format); //Stupid w32 crosscompiler
#else
va_start(ap, format);
#endif
vsprintf(buf, format, ap);
va_end(ap);
return sge_BF_textout(surface, font, buf, x, y);
}
//==================================================================================
// Returns the height of the font
// Returns 0 if the struct was invalid
//==================================================================================
Sint16 sge_BF_GetHeight(sge_bmpFont *font)
{
if(font)
return font->CharHeight;
else
return 0;
}
//==================================================================================
// Returns the width of the font (only fixed width fonts)
// Returns 0 if the struct was invalid
//==================================================================================
Sint16 sge_BF_GetWidth(sge_bmpFont *font)
{
if(font)
return font->CharWidth;
else
return 0;
}
//==================================================================================
// Removes font from memory
//==================================================================================
void sge_BF_CloseFont(sge_bmpFont *font)
{
if(font){
SDL_FreeSurface(font->FontSurface);
if(font->CharPos)
delete[] font->CharPos;
delete font;
font=NULL;
}
}
//==================================================================================
// Change the font color
// Will not work on 'color' fonts!
// Doesn't like 24bpp
// slooooow!
//==================================================================================
void sge_BF_SetColor(sge_bmpFont *font, Uint8 R, Uint8 G, Uint8 B)
{
if(font==NULL){return;}
if(!font->FontSurface->format->palette){ //Slow truecolor version
Sint16 x,y;
Sint16 ypnt;
SDL_Surface *surface=font->FontSurface;
Uint32 c_keep=font->bcolor;
Uint32 color=SDL_MapRGB(font->FontSurface->format, R, G, B);
switch(surface->format->BytesPerPixel){
case 1: { /* Assuming 8-bpp */
Uint8 *pnt;
for(y=0; y<surface->h; y++){
ypnt=y*surface->pitch;
for(x=0; x<surface->w; x++){
pnt=((Uint8 *)surface->pixels + x + ypnt);
if(*pnt!=c_keep){*pnt=(Uint8)color;}
}
}
}
break;
case 2: { /* Probably 15-bpp or 16-bpp */
Uint16 *pnt;
for(y=0; y<surface->h; y++){
ypnt=y*surface->pitch/2;
for(x=0; x<surface->w; x++){
pnt=((Uint16 *)surface->pixels + x + ypnt);
if(*pnt!=c_keep){*pnt=(Uint16)color;}
}
}
}
break;
case 3: { /* Slow 24-bpp mode, usually not used */
}
break;
case 4: { /* Probably 32-bpp */
Uint32 *pnt;
for(y=0; y<surface->h; y++){
ypnt=y*surface->pitch/4;
for(x=0; x<surface->w; x++){
pnt=((Uint32 *)surface->pixels + x + ypnt);
if(*pnt!=c_keep){*pnt=(Uint32)color;}
}
}
}
break;
}
}else{ //Fast palette version
SDL_Color c[2];
c[0].r=0; c[1].r=R;
c[0].g=0; c[1].g=G;
c[0].b=0; c[1].b=B;
SDL_SetColors(font->FontSurface, c, 0, 2);
}
}
//==================================================================================
// Insert a element (latin1)
//==================================================================================
void insert_char_latin1(char *string, char ch, int pos, int max)
{
if(pos>max || pos<0){return;}
else if(pos==max){string[pos]=ch;}
else{
for(int i=max; i>=pos; i--){
string[i+1]=string[i];
}
string[pos]=ch;
}
}
//==================================================================================
// Delete a element (latin1)
//==================================================================================
void delete_char_latin1(char *string, int pos, int max)
{
if(pos>max || pos<0){return;}
else if(pos==max){string[pos]=0;}
else{
for(int i=pos; i<=max-1; i++){
string[i]=string[i+1];
}
string[max]=0;
}
}
//==================================================================================
// BitmapText input
//==================================================================================
int sge_BF_input(SDL_Surface *screen,sge_bmpFont *font,char *string, Uint8 flags, int pos,int len,Sint16 x,Sint16 y)
{
if(len<pos || pos<0 || len<0 || font==NULL){return -2;}
char cur=124;//The character for the cursor - '|'
int max; //The strings size
SDL_Rect ret,tmp;
SDL_Surface *buffer=NULL;
buffer=SDL_DisplayFormat(screen); /* Fixme: Yum! Memory! */
if(buffer==NULL){SDL_SetError("SGE - Out of memory");return -3;}
max=pos;
string[pos+1]=0;
SDL_EnableUNICODE(1);
/* Init cursor */
string[pos]=cur;
ret=sge_BF_textout(screen, font, string, x, y);
SDL_Event event;
int quit=0;
do{
/* Check events */
SDL_WaitEvent(&event);
if(event.type==SDL_QUIT){quit=-1;}
else if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){quit=1;}
else if(event.type==SDL_KEYDOWN && (event.key.keysym.sym==SDLK_RETURN || event.key.keysym.sym==SDLK_KP_ENTER)){quit=1;}
else if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_BACKSPACE){
if(pos>0){
/* Delete char cursor-1 */
delete_char_latin1(string,pos-1,max); pos--; max--;
sge_Update_OFF();
sge_Blit(buffer,screen, ret.x, ret.y, x,y, ret.w, ret.h);
tmp=ret;
ret=sge_BF_textout(screen, font, string, x, y);
sge_Update_ON();
sge_UpdateRect(screen, tmp.x, tmp.y, tmp.w, tmp.h);
/* Handle keyrepeat */
if(!(flags&SGE_FLAG3))
if(keyrepeat(&event, 20)==-1){quit=-1;}
}
}
else if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_RIGHT){
if(pos!=max && pos!=len){
/* Move cursor right */
delete_char_latin1(string,pos,max);pos++;
insert_char_latin1(string,cur,pos,max);
sge_Blit(buffer,screen, ret.x, ret.y, x,y, ret.w, ret.h);
ret=sge_BF_textout(screen, font, string, x, y);
/* Handle keyrepeat */
if(!(flags&SGE_FLAG3))
if(keyrepeat(&event, 20)==-1){quit=-1;}
}
}
else if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_LEFT){
if(pos>0){
/* Move cursor left */
delete_char_latin1(string,pos,max);pos--;
insert_char_latin1(string,cur,pos,max);
sge_Blit(buffer,screen, ret.x, ret.y, x,y, ret.w, ret.h);
ret=sge_BF_textout(screen, font, string, x, y);
/* Handle keyrepeat */
if(!(flags&SGE_FLAG3))
if(keyrepeat(&event, 20)==-1){quit=-1;}
}
}
else if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_DELETE){
/* Delete char cursor+1 */
if(pos!=max && pos!=len){
delete_char_latin1(string,pos+1,max);max--;
sge_Update_OFF();
sge_Blit(buffer,screen, ret.x, ret.y, x,y, ret.w, ret.h);
tmp=ret;
ret=sge_BF_textout(screen, font, string, x, y);
sge_Update_ON();
sge_UpdateRect(screen, tmp.x, tmp.y, tmp.w, tmp.h);
/* Handle keyrepeat */
if(!(flags&SGE_FLAG3))
if(keyrepeat(&event, 20)==-1){quit=-1;}
}
}
else if(event.type==SDL_KEYDOWN && event.key.keysym.unicode!=0){
/* Insert new char */
if(max!=len){
max++;
insert_char_latin1(string, (char)event.key.keysym.unicode, pos,max); pos++;
sge_Blit(buffer,screen, ret.x, ret.y, x,y, ret.w, ret.h);
ret=sge_BF_textout(screen, font, string, x, y);
/* Handle keyrepeat */
if(!(flags&SGE_FLAG3))
if(keyrepeat(&event, 40)==-1){quit=-1;}
}
}
}while(quit==0);
/* Remove the cursor from string */
delete_char_latin1(string,pos,max);
//Remove text/cursor from screen
sge_Blit(buffer,screen, ret.x, ret.y, x,y, ret.w, ret.h);
if(!(flags&SGE_FLAG2))
ret=sge_BF_textout(screen, font, string, x, y);
else
sge_UpdateRect(screen, x,y, ret.w, ret.h);
SDL_FreeSurface(buffer);
if(quit==-1){return -1;} //Waaa! The user killed me!
return max;
}
diff --git a/src/sge_bm_text.h b/src/sge_bm_text.h
index f56635b..82e14f2 100644
--- a/src/sge_bm_text.h
+++ b/src/sge_bm_text.h
@@ -1,66 +1,66 @@
/*
* SDL Graphics Extension
* Text/Bitmap font functions (header)
*
* Started 990815
*
* License: LGPL v2+ (see the file LICENSE)
* (c)1999-2001 Anders Lindstr?m
*/
/*********************************************************************
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
*********************************************************************/
#ifndef sge_bm_text_H
#define sge_bm_text_H
#include "SDL.h"
#include "sge_internal.h"
/* BF open flags */
#define SGE_BFTRANSP SGE_FLAG1
#define SGE_BFSFONT SGE_FLAG2
#define SGE_BFNOCONVERT SGE_FLAG3
#define SGE_BFPALETTE SGE_FLAG4
/* Text input flags */
#define SGE_IBG SGE_FLAG1
#define SGE_IDEL SGE_FLAG2
#define SGE_INOKR SGE_FLAG3
/* the bitmap font structure */
typedef struct{
SDL_Surface *FontSurface;
Sint16 CharWidth;
Sint16 CharHeight;
Sint16 *CharPos;
Sint16 yoffs;
Uint32 bcolor;
Sint16 Chars;
} sge_bmpFont;
#ifdef _SGE_C
extern "C" {
#endif
DECLSPEC sge_bmpFont* sge_BF_OpenFont(const char *file, Uint8 flags);
DECLSPEC void sge_BF_CloseFont(sge_bmpFont *font);
DECLSPEC void sge_BF_SetColor(sge_bmpFont *font, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC Sint16 sge_BF_GetHeight(sge_bmpFont *font);
DECLSPEC Sint16 sge_BF_GetWidth(sge_bmpFont *font);
DECLSPEC SDL_Rect sge_BF_TextSize(sge_bmpFont *font, const char *string, int length=-1);
-DECLSPEC SDL_Rect sge_BF_textout(SDL_Surface *surface, sge_bmpFont *font, const char *string, Sint16 x, Sint16 y, int length=-1);
+DECLSPEC SDL_Rect sge_BF_textout(SDL_Surface *surface, sge_bmpFont *font, const char *string, Sint16 x, Sint16 y, int length=-1, bool doupdate=false);
DECLSPEC SDL_Rect sge_BF_textoutf(SDL_Surface *surface, sge_bmpFont *font, Sint16 x, Sint16 y , const char *format, ...);
DECLSPEC int sge_BF_input(SDL_Surface *screen,sge_bmpFont *font,char *string, Uint8 flags,int pos,int len,Sint16 x,Sint16 y);
#ifdef _SGE_C
}
#endif
#endif /* sge_bm_text_H */

File Metadata

Mime Type
text/x-diff
Expires
Wed, Feb 4, 2:13 PM (12 h, 59 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55640
Default Alt Text
(129 KB)

Event Timeline