Page MenuHomePhabricator (Chris)

No OneTemporary

Size
102 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 be12cbc..852c450 100644
--- a/src/Backend.cpp
+++ b/src/Backend.cpp
@@ -1,396 +1,446 @@
/***************************************************************************
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 "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;
+ *perl_sound, *perl_Translated;
+/***************************************************************************
+ TRANSLATION SERVICES
+***************************************************************************/
+
+const char* Translate( const char* a_pcText )
+{
+ dSP ;
+
+ ENTER ;
+ SAVETMPS ;
+
+ PUSHMARK(SP) ;
+ XPUSHs(sv_2mortal(newSVpv(a_pcText, 0)));
+ PUTBACK ;
+
+ call_pv("Translate", G_DISCARD);
+ FREETMPS ;
+ LEAVE ;
+
+ if ( NULL == perl_Translated )
+ {
+ perl_Translated = get_sv("Translated", TRUE);
+ }
+ return SvPV_nolen( perl_Translated );
+}
+
+
+const char* TranslateUTF8( const char* a_pcText )
+{
+ dSP ;
+
+ ENTER ;
+ SAVETMPS ;
+
+ PUSHMARK(SP) ;
+ XPUSHs(sv_2mortal(newSVpv(a_pcText, 0)));
+ PUTBACK ;
+
+ call_pv("Translate", G_DISCARD);
+ FREETMPS ;
+ LEAVE ;
+
+ if ( NULL == perl_Translated )
+ {
+ perl_Translated = get_sv("Translated", TRUE);
+ }
+ return SvPVutf8_nolen( perl_Translated );
+}
+
+
/***************************************************************************
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 = "";
}
}
// 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 )
{
if ( a_rsString.length() < 10 )
{
m_iNumDoodads = m_iNumSounds = 0;
return;
}
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 761a67d..19270d2 100644
--- a/src/Demo.cpp
+++ b/src/Demo.cpp
@@ -1,400 +1,435 @@
/***************************************************************************
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"
+#include "RlePack.h"
+#include "FighterStats.h" // #includes 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 != 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_sText1 = Translate( "CreditsText1" );
+ m_sText2 = Translate( "CreditsText2" );
+ m_sText3 = Translate( "CreditsText3" );
+
+ m_poFlyingChars->AddText( m_sText1.c_str(), FlyingChars::FC_AlignCenter, true );
+ m_poFlyingChars->AddText( m_sText2.c_str(), FlyingChars::FC_AlignJustify, true );
+ m_poFlyingChars->AddText( m_sText3.c_str(), FlyingChars::FC_AlignCenter, true );
m_poFlyingChars->AddText( "\n\n\n\n\n\n:)", FlyingChars::FC_AlignRight, true );
}
+protected:
+ std::string m_sText1;
+ std::string m_sText2;
+ std::string m_sText3;
};
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 );
+ m_sText1 = Translate( "Story1Text" );
+ m_poFlyingChars->AddText( m_sText1.c_str(), FlyingChars::FC_AlignJustify, true );
}
+protected:
+ std::string m_sText1;
};
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 );
+ m_sText1 = Translate( "Story2Text" );
+ m_poFlyingChars->AddText( m_sText1.c_str(), FlyingChars::FC_AlignJustify, true );
}
+protected:
+ std::string m_sText1;
};
class MainScreenDemo: public Demo
{
public:
MainScreenDemo()
{
- m_iTimeLeft = 100;
-
+ i = 0;
+ m_iTimeLeft = 50;
m_poBackground = LoadBackground( "Mortal.png", 240 );
+ std::string sStaffFilename = DATADIR;
+ sStaffFilename += "/characters/STAFF.DAT";
+ m_poPack = new RlePack( sStaffFilename.c_str(), 240 );
+ m_poPack->ApplyPalette();
+ SDL_BlitSurface( m_poBackground, NULL, gamescreen, NULL );
+ SDL_Flip( gamescreen );
+
+ int j, k, l;
+ for ( j=0; j<14; ++j )
+ {
+ m_aiOrder[j] = j;
+ m_bShown[j] = false;
+ }
+ for ( j=0; j<14; ++j )
+ {
+ k = rand() % 14;
+ l = m_aiOrder[j]; m_aiOrder[j] = m_aiOrder[k]; m_aiOrder[k] = l;
+ }
+ }
+
+ ~MainScreenDemo()
+ {
+ delete m_poPack;
+ m_poPack = NULL;
}
int Advance( int a_iNumFrames, bool a_bFlip )
{
+ static int x[14] = {
+ 0, 26, 67, 125, 159, 209,
+ 249, 289, 358, 397, 451, 489, 532, 161 };
+ static int y[14] = {
+ 5, 4, 5, 5, 5, 7,
+ 4, 0, 7, 5, 5, 6, 5, 243 };
+
m_iTimeLeft -= a_iNumFrames;
- Demo::Advance( a_iNumFrames, true );
- return ( m_iTimeLeft <= 0 ) ? 1 : 0;
+
+ if ( m_iTimeLeft <= 0
+ && i >= 14 )
+ {
+ return 1;
+ }
+
+ if ( m_iTimeLeft <= 0 )
+ {
+ m_bShown[ m_aiOrder[i] ] = true;
+ for ( int j=0; j<=14; ++j )
+ {
+ if ( m_bShown[j] )
+ {
+ m_poPack->Draw( j, x[j], y[j], false );
+ }
+ }
+ SDL_Flip( gamescreen );
+ ++i;
+ m_iTimeLeft += 20;
+ if ( i >= 14 )
+ {
+ m_iTimeLeft += 50;
+ }
+ }
+
+ return 0;
}
protected:
+ RlePack* m_poPack;
int m_iTimeLeft;
+ int i;
+ int m_aiOrder[14];
+ bool m_bShown[14];
};
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;
}
+static bool g_bFirstTime = true;
+
+
void DoDemos()
{
#define DoDemos_BREAKONEND \
if ( g_oState.m_enGameMode != SState::IN_DEMO \
|| g_oState.m_bQuitFlag ) \
return;
+
+ if ( g_bFirstTime )
+ {
+ g_bFirstTime = false;
+ }
+ else
+ {
+ MainScreenDemo oDemo;
+ oDemo.Run();
+ }
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;
+ {
+ MainScreenDemo oDemo;
+ oDemo.Run();
+ }
+ DoDemos_BREAKONEND;
}
}
diff --git a/src/Demo.h b/src/Demo.h
index 35d4ef1..80bfe94 100644
--- a/src/Demo.h
+++ b/src/Demo.h
@@ -1,59 +1,44 @@
/***************************************************************************
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( 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/FighterEnum.h b/src/FighterEnum.h
index 1536492..c676cbf 100644
--- a/src/FighterEnum.h
+++ b/src/FighterEnum.h
@@ -1,62 +1,62 @@
/***************************************************************************
FighterEnum.h - description
-------------------
begin : 2003-09-03
copyright : (C) 2003 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#ifndef FIGHTERENUM_H
#define FIGHTERENUM_H
/// FIGHTER ENUMERABLE
enum FighterEnum {
UNKNOWN = 0, ///< Must be the first element, must be 0 (used by iterations)
ULMAR,
UPI,
ZOLI,
CUMI,
SIRPI,
MACI,
BENCE,
GRIZLI,
DESCANT,
SURBA,
AMBRUS,
DANI,
KINGA,
MISI,
LASTFIGHTER, ///< This must terminate the list, iterations use it.
};
/** The TintEnum contains values that can be passed to RlePack::SetTint.
The tint is some modification of the original palette of an RlePack. This
is used for two things:
\li In case both players choose the same fighter, player 2's fighter is
tinted so they won't get confused.
-\li Some special effects (e.g. frozen) make the figther tinted as well.
+\li Some special effects (e.g. frozen) make the fighter tinted as well.
The Tint of players is stored by PlayerSelect and applied by RlePack::SetTint().
*/
enum TintEnum {
NO_TINT = 0,
ZOMBIE_TINT,
GRAY_TINT,
DARK_TINT,
INVERTED_TINT,
FROZEN_TINT,
};
#endif // FIGHTERENUM_H
diff --git a/src/FighterStats.cpp b/src/FighterStats.cpp
index dd9fb24..3ea9ec9 100644
--- a/src/FighterStats.cpp
+++ b/src/FighterStats.cpp
@@ -1,248 +1,255 @@
/***************************************************************************
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 "State.h"
+#include "FighterStats.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( FighterEnum a_iFighter )
{
m_iTimeLeft = 500;
m_poStaff = NULL;
m_poBackground = LoadBackground( "FighterStats.png", 64 );
- DrawGradientText( "Figher Stats", titleFont, 10, m_poBackground );
+ DrawGradientText( "Fighter 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.
+ // First run; create shuffled array of fighters.
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;
}
}
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 );
+ DrawTextMSZ( s, font, LEFTMARGIN+i, y, 0, C_ORANGE, m_poBackground, false );
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 );
+ DrawTextMSZ( s, font, LEFTMARGIN2+i, y, 0, C_ORANGE, m_poBackground, false );
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 );
+ DrawTextMSZ( s, font, LEFTMARGIN+i, y, 0, C_ORANGE, m_poBackground, false );
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 );
+ DrawTextMSZ( s, font, LEFTMARGIN2+i, y, 0, C_ORANGE, m_poBackground, false );
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 );
+ DrawTextMSZ( s, font, LEFTMARGIN+i, y, 0, C_ORANGE, m_poBackground, false );
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 );
+ DrawTextMSZ( s, font, LEFTMARGIN2+i, y, 0, C_ORANGE, m_poBackground, false );
- s = SvPV_nolen(get_sv("Story", FALSE ));
+ m_sStory = 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 );
+ m_poFlyingChars->AddText( m_sStory.c_str(), FlyingChars::FC_AlignJustify, false );
if ( g_oPlayerSelect.IsFighterAvailable( m_enFighter ) )
{
- s = SvPV_nolen(get_sv("Keys", TRUE ));
+ m_sKeys = SvPV_nolen(get_sv("Keys", TRUE ));
m_poFlyingChars->AddText( "\nKEYS\n", FlyingChars::FC_AlignCenter, true );
- m_poFlyingChars->AddText( s, FlyingChars::FC_AlignCenter, true );
+ m_poFlyingChars->AddText( m_sKeys.c_str(), FlyingChars::FC_AlignCenter, true );
}
else
{
- m_poFlyingChars->AddText( "Unfortunately this figther is not yet playable.",
- FlyingChars::FC_AlignLeft, true );
+ m_sKeys = Translate("Unfortunately this fighter is not yet playable.");
+ m_poFlyingChars->AddText( m_sKeys.c_str(), 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;
}
}
}
+
+ if ( SState::IN_DEMO != g_oState.m_enGameMode )
+ {
+ sge_BF_textout( gamescreen, fastFont, Translate("Press F1 to skip..."), 230, 450 );
+ }
+
SDL_Flip( gamescreen );
return (m_iTimeLeft > 0) ? 0 : 1;
}
diff --git a/src/FlyingChars.cpp b/src/FlyingChars.cpp
index 194b9af..70de9fd 100644
--- a/src/FlyingChars.cpp
+++ b/src/FlyingChars.cpp
@@ -1,406 +1,406 @@
/***************************************************************************
FlyingChars.cpp - description
-------------------
begin : Mon Aug 12 2003
copyright : (C) 2003 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include "FlyingChars.h"
#include "sge_surface.h"
#include "common.h"
int g_iLineTime = 100;
int g_iCharTime = 80;
FlyingChars::FlyingChars( sge_bmpFont* a_poFont, const SDL_Rect& a_roRect, int a_iFontDisplacement )
{
m_poFont = a_poFont;
m_oRect = a_roRect;
m_iFontDisplacement = a_iFontDisplacement;
m_bDone = true;
m_iTimeToNextLine = 0;
m_iDelay = 0;
m_iLastLineY = a_roRect.y;
m_pcText = NULL;
m_enAlignment = FC_AlignLeft;
m_iTextOffset = 0;
m_bScrolling = false;
m_dScrollupRate = (double)(m_poFont->CharHeight+2) / (double)g_iLineTime;
m_dScrollup = 0.0;
}
FlyingChars::~FlyingChars()
{
}
void FlyingChars::AddText( const char* a_pcText,
TextAlignment a_enAlignment, bool a_bOneByOne )
{
EnqueuedText oNewText;
oNewText.m_pcText = a_pcText;
oNewText.m_enAlignment = a_enAlignment;
m_oEnqueuedTexts.push_back( oNewText );
if ( a_bOneByOne && m_iLastLineY <= m_oRect.y )
{
m_iLastLineY = m_oRect.y + m_oRect.h - m_poFont->CharHeight;
}
else if ( 0 == m_pcText
|| m_iLastLineY <= m_oRect.y + m_oRect.h - m_poFont->CharHeight )
{
DequeueText();
}
}
bool FlyingChars::IsDone()
{
if ( m_oEnqueuedTexts.size() == 0
&& ( NULL == m_pcText || 0 == m_pcText[ m_iTextOffset] )
&& ( m_bDone ) )
{
return true;
}
return false;
}
void FlyingChars::DequeueText()
{
if ( 0 == m_oEnqueuedTexts.size() )
{
return;
}
EnqueuedText& oEnqueuedText = m_oEnqueuedTexts.front();
- m_pcText = oEnqueuedText.m_pcText;
+ m_pcText = (unsigned char*) oEnqueuedText.m_pcText;
m_enAlignment = oEnqueuedText.m_enAlignment;
m_iTextOffset = 0;
while ( m_iLastLineY <= m_oRect.y + m_oRect.h - m_poFont->CharHeight )
{
AddNextLine();
m_iTimeToNextLine += g_iLineTime;
if ( 0 == m_pcText[m_iTextOffset] )
{
break;
}
}
m_oEnqueuedTexts.pop_front();
}
void FlyingChars::Advance( int a_iNumFrames )
{
if ( a_iNumFrames > 5 ) a_iNumFrames = 5;
if ( a_iNumFrames <= 0 ) a_iNumFrames = 0;
m_bDone = true;
m_iTimeToNextLine -= a_iNumFrames;
if ( m_iTimeToNextLine < 0 )
{
- m_iTimeToNextLine += g_iLineTime;
m_iDelay = 0;
if ( !m_pcText
|| 0 == m_pcText[m_iTextOffset] )
{
DequeueText();
}
else
{
+ m_iTimeToNextLine += g_iLineTime;
AddNextLine();
}
}
m_dScrollup += a_iNumFrames * m_dScrollupRate;
int iScrollup = (int) m_dScrollup;
m_dScrollup -= iScrollup;
iScrollup *= 2;
for ( FlyingLetterIterator it=m_oLetters.begin(); it!=m_oLetters.end(); ++it )
{
FlyingLetter& roLetter = *it;
if ( m_bScrolling )
{
roLetter.m_iDY -= iScrollup;
roLetter.m_iY -= iScrollup;
if ( roLetter.m_iDY < m_oRect.y * 2
&& roLetter.m_iDY >= 0 )
{
roLetter.m_iDY = -100;
roLetter.m_iTime = 40;
}
}
if (roLetter.m_iDelay > 0)
{
roLetter.m_iDelay -= a_iNumFrames;
continue;
}
if ( roLetter.m_iTime > 0 )
{
m_bDone = false;
int iEstX = roLetter.m_iSX * roLetter.m_iTime / 2 + roLetter.m_iX ;
if ( iEstX > roLetter.m_iDX )
{
roLetter.m_iSX -= a_iNumFrames;
}
else if ( iEstX < roLetter.m_iDX )
{
roLetter.m_iSX += a_iNumFrames;
}
roLetter.m_iX += roLetter.m_iSX * a_iNumFrames;
if ( roLetter.m_iSY * roLetter.m_iTime / 2 + roLetter.m_iY >= roLetter.m_iDY )
{
roLetter.m_iSY -= a_iNumFrames;
}
else
{
roLetter.m_iSY += a_iNumFrames;
}
roLetter.m_iY += roLetter.m_iSY * a_iNumFrames;
roLetter.m_iTime -= a_iNumFrames;
if ( roLetter.m_iTime <= 0 )
{
roLetter.m_iX = roLetter.m_iDX;
roLetter.m_iY = roLetter.m_iDY;
roLetter.m_iSX = roLetter.m_iSY = 0;
roLetter.m_iTime = 0;
}
}
}
}
void FlyingChars::Draw()
{
for ( FlyingLetterIterator it=m_oLetters.begin(); it!=m_oLetters.end(); ++it )
{
FlyingLetter& roLetter = *it;
int iDestX, iDestY;
if (roLetter.m_iDelay > 0)
{
continue;
}
else if ( roLetter.m_iTime > 0 )
{
iDestX = roLetter.m_iX;
iDestY = roLetter.m_iY;
}
else
{
iDestX = roLetter.m_iX;
iDestY = roLetter.m_iY;
}
int iSrcX, iSrcW;
if ( ! m_poFont->CharPos )
{
iSrcX = roLetter.m_cLetter * m_poFont->CharWidth;
iSrcW = m_poFont->CharWidth;
}
else
{
- int iOfs = (roLetter.m_cLetter-33)*2 + 1;
+ int iOfs = ( ((unsigned int)roLetter.m_cLetter)-33)*2 + 1;
iSrcX = m_poFont->CharPos[iOfs];
iSrcW = m_poFont->CharPos[iOfs+1] - iSrcX;
}
//debug( "Letter %c at %d,%d\n", roLetter.m_cLetter, iDestX/2, iDestY/2 );
sge_Blit( m_poFont->FontSurface, gamescreen, iSrcX, m_poFont->yoffs,
iDestX/2, iDestY/2, iSrcW, m_poFont->CharHeight );
}
}
void FlyingChars::AddNextLine()
{
if ( NULL == m_pcText )
{
return;
}
// 1. SCROLL UP EVERYTHING IF NECESSARY
if ( m_iLastLineY > m_oRect.y + m_oRect.h - m_poFont->CharHeight )
{
// scroll up every character
if ( !m_bScrolling )
{
m_bScrolling = true;
m_iTimeToNextLine = (m_iLastLineY - (m_oRect.y + m_oRect.h - m_poFont->CharHeight)) / m_dScrollupRate;
return;
}
m_iLastLineY = m_oRect.y + m_oRect.h - m_poFont->CharHeight;
}
SDL_Rect oRect;
- const char* pcLineStart = m_pcText + m_iTextOffset;
+ const unsigned char* pcLineStart = m_pcText + m_iTextOffset;
if ( '\n' == *pcLineStart ) ++pcLineStart;
while (*pcLineStart == 32 || *pcLineStart == '\t' ) ++pcLineStart;
if ( 0 == *pcLineStart )
{
m_iTextOffset = pcLineStart - m_pcText;
return;
}
// 2. CALCULATE LINE WIDTH AND CONTENTS
- const char* pcLineEnd = pcLineStart;
- const char* pcNextWord = pcLineEnd;
+ const unsigned char* pcLineEnd = pcLineStart;
+ const unsigned char* pcNextWord = pcLineEnd;
int iNumWords = 0;
int iLineWidth = 0;
int iWidth = 0;
while (1)
{
++iNumWords;
if ( '\n' == *pcNextWord
|| 0 == *pcNextWord)
{
break;
}
// Skip the next 'white space' part
while (*pcNextWord == 32 || *pcNextWord == '\t' )
{
iWidth += GetCharWidth( *pcNextWord );
++pcNextWord;
}
// Skip the next 'non-whitespace' part
while (*pcNextWord != 32 && *pcNextWord != '\t'
&& *pcNextWord != '\n' && *pcNextWord != 0 )
{
iWidth += GetCharWidth( *pcNextWord );
++pcNextWord;
}
if ( iWidth > m_oRect.w )
{
// overflow
break;
}
pcLineEnd = pcNextWord;
iLineWidth = iWidth;
}
if ( pcLineEnd == pcLineStart )
{
pcLineEnd = pcNextWord;
iLineWidth = iWidth;
}
// 3. ADD LETTERS IN LINE
double dX = m_oRect.x;
double dSpaceLength = 0.0;
switch ( m_enAlignment )
{
case FC_AlignJustify:
if ( '\n' == *pcLineEnd
|| 0 == *pcLineEnd )
{
}
else
{
dSpaceLength = (m_oRect.w - iLineWidth) / double( iNumWords > 2 ? iNumWords-2 : 1 );
}
break;
case FC_AlignCenter:
dX += (m_oRect.w - iLineWidth) /2;
break;
case FC_AlignRight:
dX += (m_oRect.w - iLineWidth);
break;
default:
break;
}
FlyingLetter oLetter;
oLetter.m_iDY = m_iLastLineY * 2;
- for ( const char *pcChar = pcLineStart; pcChar<pcLineEnd; ++pcChar )
+ for ( const unsigned char *pcChar = pcLineStart; pcChar<pcLineEnd; ++pcChar )
{
if ( *pcChar < 33 )
{
if ( *pcChar == 32 || *pcChar == '\t' )
{
dX += dSpaceLength;
// debug( "dX = %3.2f dSpaceLength = %2.2f\n", (float)dX, (float)dSpaceLength );
}
int iWidth = GetCharWidth( *pcChar );
dX += iWidth;
//debug( "dX = %3.2f iWidth = %d\n", (float)dX, iWidth );
continue;
}
- oRect = sge_BF_TextSize( m_poFont, pcLineStart, pcChar-pcLineStart );
+ oRect = sge_BF_TextSize( m_poFont, (char*) pcLineStart, pcChar-pcLineStart );
oLetter.m_iDX = (int) dX * 2;
oLetter.m_iX = rand() % (gamescreen->w * 2);
oLetter.m_iY = gamescreen->h * 2;
oLetter.m_iSX = 0;
oLetter.m_iSY = -45 + rand() % 15 ;
oLetter.m_iDelay = m_iDelay++;
oLetter.m_iTime = g_iCharTime;
oLetter.m_cLetter = *pcChar;
m_oLetters.push_back(oLetter);
dX += GetCharWidth( *pcChar );
}
m_iTextOffset = pcLineEnd - m_pcText;
m_iLastLineY += m_poFont->CharHeight + 2;
}
-int FlyingChars::GetCharWidth( char a_cChar )
+int FlyingChars::GetCharWidth( unsigned char a_cChar )
{
if ( a_cChar == 0 )
{
return 0;
}
else if ( m_poFont->CharPos )
{
if ( a_cChar < 33 )
{
return m_poFont->CharPos[3] - m_poFont->CharPos[2] + 1;
}
else
{
- int iOfs = (a_cChar - 33) * 2 + 1;
+ int iOfs = ( ((unsigned int)a_cChar) - 33) * 2 + 1;
return m_poFont->CharPos[iOfs+1] - m_poFont->CharPos[iOfs] + m_iFontDisplacement;
}
}
return m_poFont->CharWidth;
}
diff --git a/src/FlyingChars.h b/src/FlyingChars.h
index 0d819b6..e470054 100644
--- a/src/FlyingChars.h
+++ b/src/FlyingChars.h
@@ -1,89 +1,89 @@
/***************************************************************************
FlyingChars.h - description
-------------------
begin : Mon Aug 12 2003
copyright : (C) 2003 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#ifndef FLYINGCHARS_H
#define FLYINGCHARS_H
#include "sge_bm_text.h"
#include <vector>
#include <list>
struct FlyingLetter
{
int m_iX, m_iY;
int m_iSX, m_iSY;
int m_iDX, m_iDY;
int m_iDelay;
int m_iTime;
- char m_cLetter;
+ unsigned char m_cLetter;
};
class FlyingChars
{
public:
enum TextAlignment {
FC_AlignLeft,
FC_AlignRight,
FC_AlignCenter,
FC_AlignJustify,
};
public:
FlyingChars( sge_bmpFont* a_poFont, const SDL_Rect& a_roRect, int a_iFontDisplacement = 0 );
~FlyingChars();
void AddText( const char* a_pcText, TextAlignment a_enAlignment, bool bOneByOne );
void Advance( int a_iNumFrames );
void Draw();
bool IsDone();
int GetCount();
protected:
void AddNextLine();
- int GetCharWidth( char a_cChar );
+ int GetCharWidth( unsigned char a_cChar );
void DequeueText();
protected:
struct EnqueuedText
{
const char* m_pcText;
TextAlignment m_enAlignment;
};
std::list<EnqueuedText> m_oEnqueuedTexts;
bool m_bDone;
bool m_bScrolling;
double m_dScrollupRate;
double m_dScrollup;
typedef std::vector<FlyingLetter> FlyingLetterList;
typedef FlyingLetterList::iterator FlyingLetterIterator;
sge_bmpFont* m_poFont;
int m_iFontDisplacement;
FlyingLetterList m_oLetters;
int m_iTimeToNextLine;
SDL_Rect m_oRect;
- const char* m_pcText;
+ const unsigned char* m_pcText;
TextAlignment m_enAlignment;
int m_iTextOffset;
int m_iLastLineY;
int m_iDelay;
};
#endif // FLYINGCHARS_H
diff --git a/src/Game.cpp b/src/Game.cpp
index 6c2655a..f83fdfb 100644
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -1,797 +1,801 @@
/***************************************************************************
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 "Background.h"
#include "common.h"
#include "gfx.h"
#include "Backend.h"
#include "RlePack.h"
#include "State.h"
#include "Game.h"
#include "Audio.h"
+#include "MortalNetwork.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_poBackground = new Background();
m_poBackground->Load(mg_iBackgroundNumber++);
if ( !m_poBackground->IsOK() )
{
m_poBackground->Load(1);
mg_iBackgroundNumber = 1;
}
m_poDoodads = LoadBackground( "Doodads.png", 48, 64 );
m_aiRoundsWonByPlayer[0] = m_aiRoundsWonByPlayer[1] = 0;
m_iNumberOfRounds = 0;
}
Game::~Game()
{
delete m_poBackground;
m_poBackground = NULL;
SDL_FreeSurface( m_poDoodads );
m_poDoodads = NULL;
}
int Game::Run()
{
do
{
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()
{
m_poBackground->Draw( g_oBackend.m_iBgX, g_oBackend.m_iBgY );
/*
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 );
+ DrawTextMSZ( s, inkFont, 320, 10, AlignHCenter, C_LIGHTCYAN, gamescreen, false );
}
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 );
+ const char* format = TranslateUTF8( "Round %d" );
+ sprintf( s, format, m_iNumberOfRounds+1 );
+ DrawTextMSZ( s, inkFont, 320, 200, AlignHCenter, C_WHITE, gamescreen, false );
}
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 );
+ sge_BF_textout( gamescreen, fastFont, Translate("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 );
+ sge_BF_textout( gamescreen, fastFont, Translate("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
***************************************************************************/
+bool Game::IsNetworkGame()
+{
+ return SState::IN_NETWORK == g_oState.m_enGameMode;
+}
+
+
/**
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;
}
+
+ if ( IsNetworkGame() )
+ {
+ bool bMaster = g_poNetwork->IsMaster();
+
+ }
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/Game.h b/src/Game.h
index 46c1c5a..1580bf3 100644
--- a/src/Game.h
+++ b/src/Game.h
@@ -1,73 +1,75 @@
/***************************************************************************
Game.h - description
-------------------
begin : Mon Aug 27 2003
copyright : (C) 2003 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#ifndef GAME_H
#define GAME_H
#include <string>
#include <vector>
struct SDL_Surface;
class Background;
class Game
{
public:
Game( bool a_bIsReplay, bool a_bDebug );
~Game();
int Run();
std::string& GetReplay();
void DoReplay( const char* a_pcReplayFile );
protected:
void Draw();
void DrawHitPointDisplay();
void DrawBackground();
void DrawDoodads();
void DrawPoly( const char* a_pcName, int a_iColor );
void DoOneRound();
void Advance( int a_iNumFrames );
int ProcessEvents();
void HurryUp();
void TimeUp();
void InstantReplay( int a_iKoAt );
+
+ bool IsNetworkGame();
protected:
static int mg_iBackgroundNumber;
bool m_bIsReplay;
bool m_bDebug;
Background* m_poBackground;
SDL_Surface* m_poDoodads;
int m_aiRoundsWonByPlayer[2];
int m_iNumberOfRounds;
int m_iFrame;
std::string m_sReplayString;
std::vector<int> m_aReplayOffsets;
enum // This enum assumes its values during DoOneRound
{
Ph_START, // "Round X" displayed, fighters getting ready
Ph_NORMAL, // During the fight
Ph_TIMEUP, // Time is up, no KO, no replay.
Ph_KO, // There is a KO, forward until the guy is down
Ph_REWIND, // There was a KO, rewinding until before the KO
Ph_SLOWFORWARD, // Playing back the KO
Ph_REPLAY, // Replay mode
} m_enGamePhase;
};
#endif
diff --git a/src/State.cpp b/src/State.cpp
index 30bbf4c..e0ecebb 100644
--- a/src/State.cpp
+++ b/src/State.cpp
@@ -1,143 +1,255 @@
/***************************************************************************
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 "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
}
+
+
+
+SState::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;
+ #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];
+
+ // Read the locale from the operating system
+ char* pcLocale = setlocale( LC_CTYPE, NULL );
+ debug( "The locale returned by the operating system is '%s'\n", pcLocale ? pcLocale : "NULL" );
+
+ if ( NULL == pcLocale
+ || strcmp( pcLocale, "C") == 0 )
+ {
+ // Try the 'GETENV' method
+ pcLocale = getenv( "LANG" );
+ debug( "The LANG envvar is '%s'\n", pcLocale ? pcLocale : "NULL" );
+ }
+
+ if ( NULL != pcLocale )
+ {
+ strncpy( m_acLanguage, pcLocale, 2 );
+ m_acLanguage[2] = 0;
+ }
+ else
+ {
+ strcpy( m_acLanguage, "en" );
+ }
+
+ strcpy( m_acLatestServer, "apocalypse.rulez.org" );
+ m_bServer = false;
+};
+
+
+
+
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,
+ gamescreen->format->BitsPerPixel,
m_bFullscreen ? SDL_FULLSCREEN : SDL_SWSURFACE );
-
+
if ( bPaletted )
{
SDL_SetPalette( gamescreen, SDL_LOGPAL | SDL_PHYSPAL, aoPalette, 0, iNumColors );
}
}
+void SState::SetLanguage( const char* a_pcLanguage )
+{
+ if ( m_acLanguage != a_pcLanguage )
+ {
+ strncpy( m_acLanguage, a_pcLanguage, 9 );
+ m_acLanguage[9] = 0;
+ }
+ g_oBackend.PerlEvalF( "SetLanguage('%s');", m_acLanguage );
+ SV* poSv = get_sv("LanguageNumber", FALSE);
+ if (poSv)
+ {
+ m_iLanguageCode = SvIV( poSv );
+ }
+ else
+ {
+ m_iLanguageCode = 0;
+ }
+}
+
+
+
+void SState::SetServer( const char* a_pcServer )
+{
+ if ( a_pcServer )
+ {
+ strncpy( m_acLatestServer, a_pcServer, 255 );
+ m_acLatestServer[255] = 0;
+ m_bServer = false;
+ }
+ else
+ {
+ m_bServer = true;
+ }
+}
+
+
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 );
+ poSv = get_sv("LANGUAGE", FALSE); if (poSv) { strncpy( m_acLanguage, SvPV_nolen( poSv ), 9 ); m_acLanguage[9] = 0; }
+ poSv = get_sv("LATESTSERVER", FALSE); if (poSv) { strncpy( m_acLatestServer, SvPV_nolen( poSv ), 255 ); m_acLanguage[255] = 0; }
+ poSv = get_sv("SERVER", FALSE); if (poSv) m_bServer = 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';
+ oStream << "LANGUAGE=" << m_acLanguage << '\n';
+ oStream << "LATESTSERVER=" << m_acLatestServer << '\n';
+ oStream << "SERVER=" << m_bServer << '\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 e700b12..48a6cd9 100644
--- a/src/State.h
+++ b/src/State.h
@@ -1,93 +1,62 @@
/***************************************************************************
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_NETWORK,
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
+ char m_acLanguage[10]; // Language ID (en,hu,fr,es,..)
+ int m_iLanguageCode; // Non-persistend language code (set by backend based on the language)
- 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;
- #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];
-
- };
+ char m_acLatestServer[256];
+ bool m_bServer;
+
+ SState();
void Load();
void Save();
void ToggleFullscreen();
+ void SetLanguage( const char* a_pcLanguage );
+ void SetServer( const char* a_pcServer );
};
extern SState g_oState;
#endif
diff --git a/src/common.h b/src/common.h
index 9341380..6698452 100644
--- a/src/common.h
+++ b/src/common.h
@@ -1,57 +1,59 @@
/***************************************************************************
common.h - description
-------------------
begin : Fri Aug 24 2001
copyright : (C) 2001 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#ifndef __COMMON_H
#define __COMMON_H
struct SDL_Surface;
#define SCREENWIDTH 640
#define SCREENHEIGHT 480
#define GAMEBITS 3
#define GAMEBITS2 (1<<GAMEBITS)
void debug( const char* format, ... );
#define ABS(A) ( (A>=0) ? (A) : -(A) )
#ifdef _SDL_video_h
extern SDL_Surface* gamescreen;
-
-
-void DoMenu( bool a_bDrawBackground );
-void GameOver( int a_iPlayerWon );
-void DoDemos();
-
-
+
+
+void DoMenu( bool a_bDrawBackground );
+void GameOver( int a_iPlayerWon );
+void DoDemos();
+
+const char* Translate( const char* a_pcText );
+const char* TranslateUTF8( const char* a_pcText );
+
#define C_BLACK 240
#define C_BLUE 241
#define C_GREEN 242
#define C_CYAN 243
#define C_RED 244
#define C_MAGENTA 245
#define C_ORANGE 246
#define C_LIGHTGRAY 247
#define C_DARKGRAY 248
#define C_LIGHTBLUE 249
#define C_LIGHTGREEN 250
#define C_LIGHTCYAN 251
#define C_LIGHTRED 252
#define C_LIGHTMAGENTA 253
#define C_YELLOW 254
#define C_WHITE 255
#endif
#endif
diff --git a/src/gfx.cpp b/src/gfx.cpp
index 4b50070..b3f538f 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -1,273 +1,323 @@
/***************************************************************************
gfx.cpp - description
-------------------
begin : Tue Apr 10 2001
copyright : (C) 2001 by UPi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include <string.h>
+#include <malloc.h>
-#include "SDL.h"
-#include "SDL_video.h"
-#include "SDL_image.h"
-#include "sge_tt_text.h"
-#include "sge_surface.h"
+
+#include "SDL.h"
+#include "SDL_video.h"
+#include "SDL_image.h"
+
+
+
+#include "sge_tt_text.h"
+#include "sge_surface.h"
#ifndef __COMMON_H
#include "common.h"
#endif
#ifndef _GFX_H
#include "gfx.h"
#endif
-#include "State.h"
+#include "State.h"
+
+Uint16 *UTF8_to_UNICODE(Uint16 *unicode, const char *utf8, int len);
-void sge_TTF_SizeText( _sge_TTFont*font, const char* string, int* x, int* y )
+
+void sge_TTF_SizeText( _sge_TTFont*font, const char* text, int* x, int* y )
{
- SDL_Rect r = sge_TTF_TextSize( font, (char*) string );
+#ifdef MSZ_USES_UTF8
+ Uint16 *unicode_text;
+ int unicode_len;
+
+ /* Copy the UTF-8 text to a UNICODE text buffer */
+ unicode_len = strlen(text);
+ unicode_text = (Uint16 *)malloc( (unicode_len+1) * sizeof (Uint16) );
+ if ( unicode_text == NULL )
+ {
+ SDL_SetError("SGE - Out of memory");
+ *x = *y = 0;
+ return;
+ }
+ UTF8_to_UNICODE(unicode_text, text, unicode_len);
+
+ /* Render the new text */
+ SDL_Rect r = sge_TTF_TextSizeUNI(font, unicode_text);
+
+ /* Free the text buffer and return */
+ free(unicode_text);
+#else
+ SDL_Rect r = sge_TTF_TextSize( font, text );
+#endif
*x = r.w;
*y = r.h;
}
int DrawTextMSZ( const char* string, _sge_TTFont* font, int x, int y, int flags,
- int fg, SDL_Surface* target )
+ int fg, SDL_Surface* target, bool a_bTranslate )
{
int retval = 0;
if (!string || !*string) return retval;
+ if ( a_bTranslate )
+ {
+ string = Translate( string );
+ }
+
if (flags & UseTilde)
{
char *str2 = strdup( string );
char onechar[2];
char *c1, *c2, *c3;
int w = 0;
int i, j;
bool notend;
if (flags & AlignHCenter)
{
// Determine width of the string without the stupid tildes
c1 = c2 = str2;
notend = true;
while (notend)
{
c2 = c1; // c1: start of this run
while (*c2 && (*c2!='~')) c2++; // c2: end of this run
notend = *c2;
*c2 = 0;
sge_TTF_SizeText( font, c1, &i, &j);
w += i;
if (notend) { *c2='~'; c1=c2+1; } // next run..
}
x -= w/2;
}
flags &= ~(UseTilde | AlignHCenter);
c1 = str2;
onechar[1]=0;
notend = true;
while (1)
{
c2 = c1;
while (*c2 && (*c2!='~')) c2++; // c2: end of this run
notend = *c2;
*c2 = 0;
sge_TTF_SizeText( font, c1, &i, &j);
- DrawTextMSZ( c1, font, x, y, flags, fg, target );
+ DrawTextMSZ( c1, font, x, y, flags, fg, target, false );
x += i;
// At this point, we're either at a ~ or end of the text (notend)
if (!notend) break;
onechar[0]= *++c2; // Could be 0, if ~ at end.
if (!onechar[0]) break;
sge_TTF_SizeText( font, onechar, &i, &j);
- DrawTextMSZ( onechar, font, x, y, flags, C_LIGHTCYAN, target );
+ DrawTextMSZ( onechar, font, x, y, flags, C_LIGHTCYAN, target, false );
x += i;
retval += i;
c1 = c2+1;
if (!*c1) break; // ~X was end of string
}
delete( str2 );
return retval;
}
SDL_Rect dest;
int w, h;
sge_TTF_SizeText( font, string, &w, &h );
dest.w = retval = w;
dest.h = h;
dest.x = flags & AlignHCenter ? x-dest.w/2 : x;
dest.y = flags & AlignVCenter ? y-dest.h/2 : y;
//debug( "X: %d, Y: %d, W: %d, H: %d\n", dest.x, dest.y, dest.w, dest.h );
if ( flags & UseShadow )
{
+#ifdef MSZ_USES_UTF8
sge_tt_textout_UTF8( target, font, string, dest.x+2, dest.y+2+sge_TTF_FontAscent(font), C_BLACK, C_BLACK, 255 );
+#else
+ sge_tt_textout( target, font, string, dest.x+2, dest.y+2+sge_TTF_FontAscent(font), C_BLACK, C_BLACK, 255 );
+#endif
}
sge_TTF_AAOn();
+#ifdef MSZ_USES_UTF8
dest = sge_tt_textout_UTF8( target, font, string, dest.x, dest.y+sge_TTF_FontAscent(font), fg, C_BLACK, 255 );
+#else
+ dest = sge_tt_textout( target, font, string, dest.x, dest.y+sge_TTF_FontAscent(font), fg, C_BLACK, 255 );
+#endif
sge_TTF_AAOff();
return dest.w;
}
-void DrawGradientText( const char* text, _sge_TTFont* font, int y, SDL_Surface* target )
+void DrawGradientText( const char* text, _sge_TTFont* font, int y, SDL_Surface* target, bool a_bTranslate )
{
int i, j;
+ if ( a_bTranslate )
+ {
+ text = Translate( text );
+ }
+
// 1. CREATE OFFSCREEN SURFACE
SDL_Rect size = sge_TTF_TextSize( font, (char*)text );
size.w += 2;
size.h += 2;
size.x = 320 - size.w / 2;
if ( size.x < 0 ) size.x = 0;
size.y = y;
SDL_Surface* surface = SDL_CreateRGBSurface( SDL_SRCCOLORKEY, size.w, size.h, 8, 0,0,0,0 );
if ( NULL == surface )
{
debug( "DrawGradientText: Couldn't allocate %d by %d surface!\n", size.w, size.h );
return;
}
// 2. SET OFFSCREEN SURFACE COLORS
SDL_SetColorKey( surface, SDL_SRCCOLORKEY, 0 );
SDL_Color colors[256];
colors[0].r = colors[0].g = colors[0].b = 0;
- colors[1] = colors[0];
+ colors[1] = colors[0];
// The rest is red->yellow gradient.
for ( i=2; i<255; ++i )
{
int j = i > 25 ? i-25 : 0;
colors[i].r = 255;
colors[i].g = 255-j;
colors[i].b = 0;
}
SDL_SetColors( surface, colors, 0, 256 );
// 3. DRAW TEXT, APPLY BORDER, APPLY GRADIENT.
int y1 = sge_TTF_FontAscent(font);
- sge_tt_textout_UTF8( surface, font, text,
- 1, y1, 255, 0, 255);
+ sge_tt_textout( surface, font, text,
+ 1, y1, 255, 0, 255);
+
for ( y=1; y<size.h-1; ++y )
{
int color = 254 * y / (size.h-1) + 1;
unsigned char *p0, *p1, *p2;
p1 = (unsigned char*) surface->pixels;
p1 += surface->pitch * y + 1;
p0 = p1 - surface->pitch;
p2 = p1 + surface->pitch;
for ( int x=1; x<size.w-1; ++x, ++p0, ++p1, ++p2 )
{
if ( *p1 > 2 )
{
*p1 = color;
}
else
{
if ( (*(p1-1) > 2) || (*(p1+1) > 2) || *p0 > 2 || *p2 > 2 )
{
*p1 = 1;
}
}
}
}
// 4. FINALLY
- SDL_BlitSurface( surface, NULL, target, &size );
- SDL_FreeSurface( surface );
- SDL_UpdateRect( target, size.x, size.y, size.w, size.h );
+ SDL_BlitSurface( surface, NULL, target, &size );
+ SDL_FreeSurface( surface );
+ SDL_UpdateRect( target, size.x, size.y, size.w, size.h );
}
SDL_Color MakeColor( Uint8 r, Uint8 g, Uint8 b )
{
SDL_Color color;
color.r = r; color.g = g; color.b = b; color.unused = 0;
return color;
}
SDLKey GetKey()
{
SDL_Event event;
+
while (SDL_WaitEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
g_oState.m_bQuitFlag = true;
return SDLK_ESCAPE;
case SDL_KEYDOWN:
{
return event.key.keysym.sym;
}
break;
} // switch statement
} // Polling events
return SDLK_ESCAPE;
}
-SDL_Surface* LoadBackground( const char* a_pcFilename, int a_iNumColors, int a_iPaletteOffset )
-{
- char filepath[FILENAME_MAX+1];
- strcpy( filepath, DATADIR );
- strcat( filepath, "/gfx/" );
- strcat( filepath, a_pcFilename );
-
- SDL_Surface* poBackground = IMG_Load( filepath );
- if (!poBackground)
- {
- debug( "Can't load file: %s\n", filepath );
- return NULL;
- }
-
- SDL_Palette* pal = poBackground->format->palette;
- if ( pal )
- {
- int ncolors = pal->ncolors;
- if (ncolors>a_iNumColors) ncolors = a_iNumColors;
- if (ncolors+a_iPaletteOffset > 255) ncolors = 255 - a_iPaletteOffset;
- SDL_SetColors( gamescreen, pal->colors, a_iPaletteOffset, ncolors );
- }
-
- SDL_Surface* poRetval = SDL_DisplayFormat( poBackground );
- SDL_FreeSurface( poBackground );
-
- return poRetval;
-}
-
-
+SDL_Surface* LoadBackground( const char* a_pcFilename, int a_iNumColors, int a_iPaletteOffset )
+{
+ char filepath[FILENAME_MAX+1];
+ strcpy( filepath, DATADIR );
+ strcat( filepath, "/gfx/" );
+ strcat( filepath, a_pcFilename );
+
+ SDL_Surface* poBackground = IMG_Load( filepath );
+ if (!poBackground)
+ {
+ debug( "Can't load file: %s\n", filepath );
+ return NULL;
+ }
+
+ SDL_Palette* pal = poBackground->format->palette;
+ if ( pal )
+ {
+ int ncolors = pal->ncolors;
+ if (ncolors>a_iNumColors) ncolors = a_iNumColors;
+ if (ncolors+a_iPaletteOffset > 255) ncolors = 255 - a_iPaletteOffset;
+ SDL_SetColors( gamescreen, pal->colors, a_iPaletteOffset, ncolors );
+ }
+
+ SDL_Surface* poRetval = SDL_DisplayFormat( poBackground );
+ SDL_FreeSurface( poBackground );
+
+ return poRetval;
+}
+
+
diff --git a/src/gfx.h b/src/gfx.h
index a150ac5..a2493c6 100644
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -1,45 +1,45 @@
/***************************************************************************
gfx.h - description
-------------------
begin : Tue Apr 10 2001
copyright : (C) 2001 by UPi
email : upi@apocalypse.rulez.org
***************************************************************************/
-
-
-#ifndef _GFX_H
-#define _GFX_H
-
-
-struct _sge_TTFont;
-
-enum GFX_Constants {
- AlignHCenter = 1,
- AlignVCenter = 2,
- AlignCenter = 3,
- UseTilde = 4,
- UseShadow = 8,
-};
-
-int DrawTextMSZ( const char* text, _sge_TTFont* font, int x, int y,
- int flags, int fg, SDL_Surface* target );
-
-void DrawGradientText( const char* text, _sge_TTFont* font, int y,
- SDL_Surface* target );
-
-SDL_Color MakeColor( Uint8 r, Uint8 g, Uint8 b );
-
-SDLKey GetKey();
-SDL_Surface* LoadBackground( const char* a_pcFilename, int a_iNumColors, int a_iPaletteOffset=0 );
-
-extern _sge_TTFont* titleFont; // Largest font, for titles
-extern _sge_TTFont* inkFont; // Medium-size front, headings
-extern _sge_TTFont* impactFont; // Smallest font, for long descriptions
-
-#ifdef sge_bm_text_H
-extern sge_bmpFont* fastFont; // In-game text, e.g. combo text
-extern sge_bmpFont* creditsFont;
-extern sge_bmpFont* storyFont;
-#endif
-
-#endif
+
+
+#ifndef _GFX_H
+#define _GFX_H
+
+
+struct _sge_TTFont;
+
+enum GFX_Constants {
+ AlignHCenter = 1,
+ AlignVCenter = 2,
+ AlignCenter = 3,
+ UseTilde = 4,
+ UseShadow = 8,
+};
+
+int DrawTextMSZ( const char* text, _sge_TTFont* font, int x, int y,
+ int flags, int fg, SDL_Surface* target, bool a_bTranslate = true );
+
+void DrawGradientText( const char* text, _sge_TTFont* font, int y,
+ SDL_Surface* target, bool a_bTranslate = true );
+
+SDL_Color MakeColor( Uint8 r, Uint8 g, Uint8 b );
+
+SDLKey GetKey();
+SDL_Surface* LoadBackground( const char* a_pcFilename, int a_iNumColors, int a_iPaletteOffset=0 );
+
+extern _sge_TTFont* titleFont; // Largest font, for titles
+extern _sge_TTFont* inkFont; // Medium-size front, headings
+extern _sge_TTFont* impactFont; // Smallest font, for long descriptions
+
+#ifdef sge_bm_text_H
+extern sge_bmpFont* fastFont; // In-game text, e.g. combo text
+extern sge_bmpFont* creditsFont;
+extern sge_bmpFont* storyFont;
+#endif
+
+#endif
diff --git a/src/sge_bm_text.cpp b/src/sge_bm_text.cpp
index d553c98..5495dec 100644
--- a/src/sge_bm_text.cpp
+++ b/src/sge_bm_text.cpp
@@ -1,552 +1,556 @@
/*
* 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, 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){
+ unsigned char c = string[i];
+
+ if(c==' ' || (c-33)>font->Chars || c<33){
xdest += font->CharPos[2]-font->CharPos[1];
continue;
- }
- ofs = (string[i]-33)*2+1;
+ }
+
+ ofs = ( ((unsigned int)c)-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;
+ //ret.x=x; ret.y=y; ret.w=xdest-x+font->CharWidth; ret.h=font->CharHeight;
+ ret.x=x; ret.y=y; ret.w=xdest-x+adv; ret.h=font->CharHeight;
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;
}

File Metadata

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

Event Timeline