Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
29 KB
Referenced Files
None
Subscribers
None
diff --git a/src/PlayerSelectView.cpp b/src/PlayerSelectView.cpp
index c16cbe9..574b136 100644
--- a/src/PlayerSelectView.cpp
+++ b/src/PlayerSelectView.cpp
@@ -1,598 +1,598 @@
#include "sge_tt_text.h"
#include "sge_bm_text.h"
#include "sge_primitives.h"
#include "RlePack.h"
#include "PlayerSelectView.h"
#include "PlayerSelect.h"
#include "Chooser.h"
#include "TextArea.h"
#include "Backend.h"
#include "State.h"
#include "gfx.h"
#include "common.h"
/**
Displays teams in the player selection screen for CPlayerSelectView.
\ingroup PlayerSelect
*/
class CTeamDisplay
{
public:
CTeamDisplay( int a_iPlayer, SDL_Surface* a_poScreen, const SDL_Rect& a_roRect );
~CTeamDisplay();
void DrawTitle( Uint32 a_iColor );
void DrawQuestionMark( Uint32 a_iColor, int a_iNumber=-1 );
void AddFighter( FighterEnum a_enFighter );
void DrawFighter( FighterEnum a_enFighter, int a_iNumber );
SDL_Rect GetRect( int a_iNumber=-1 );
int GetCount() { return m_iCount; }
protected:
int m_iPlayer;
SDL_Surface* m_poScreen;
SDL_Rect m_oRect;
int m_iTitleX;
int m_iCount;
int m_iMax;
};
CTeamDisplay::CTeamDisplay( int a_iPlayer, SDL_Surface* a_poScreen, const SDL_Rect& a_roRect )
{
m_iPlayer = a_iPlayer;
m_poScreen = a_poScreen;
m_oRect = a_roRect;
m_iCount = 0;
m_iMax = g_oState.m_iTeamSize;
m_iTitleX = m_oRect.x;
const char* pcFormat = Translate("Team %d");
SDL_Rect oTextSize = sge_TTF_TextSize( impactFont, pcFormat );
int w = oTextSize.w;
m_oRect.w -= w;
m_oRect.x += w;
DrawTitle( C_WHITE );
for ( int i=0; i< m_iMax; ++i )
{
DrawQuestionMark( C_WHITE, i );
}
}
CTeamDisplay::~CTeamDisplay() {}
void CTeamDisplay::DrawTitle( Uint32 a_iColor )
{
char acBuffer[128];
const char* pcFormat = Translate("Team %d");
sprintf( acBuffer, pcFormat, m_iPlayer+1 );
DrawTextMSZ( acBuffer, impactFont, m_iTitleX, m_oRect.y+m_oRect.h/2,
AlignVCenter|UseShadow, a_iColor, m_poScreen, false );
}
void CTeamDisplay::DrawQuestionMark( Uint32 a_iColor, int a_iNumber )
{
if ( a_iNumber < 0 ) a_iNumber = m_iCount;
if ( a_iNumber >= m_iMax ) return;
SDL_Rect oRect = GetRect( a_iNumber );
sge_Rect( m_poScreen, oRect.x, oRect.y, oRect.x+oRect.w, oRect.y+oRect.h, C_WHITE );
DrawTextMSZ( "?", impactFont, oRect.x+oRect.w/2, oRect.y+oRect.h/2, AlignCenter, a_iColor, m_poScreen, false );
}
void CTeamDisplay::AddFighter( FighterEnum a_enFighter )
{
DrawQuestionMark( C_WHITE );
++m_iCount;
}
void CTeamDisplay::DrawFighter( FighterEnum a_enFighter, int a_iNumber )
{
SDL_Rect oRect = GetRect( a_iNumber );
g_oChooser.DrawPortrait( a_enFighter, m_poScreen, oRect );
sge_Rect( m_poScreen, oRect.x, oRect.y, oRect.x+oRect.w, oRect.y+oRect.h, C_WHITE );
}
SDL_Rect CTeamDisplay::GetRect( int a_iNumber )
{
if ( a_iNumber < 0 ) a_iNumber = m_iCount;
if ( m_oRect.h > 75 )
{
m_oRect.y += (m_oRect.h - 75) / 2;
m_oRect.h = 75;
}
int iGap = 5;
int iWidth = m_oRect.w / m_iMax;
if ( iWidth > m_oRect.h + iGap ) iWidth = m_oRect.h + iGap;
SDL_Rect oRect;
oRect.y = m_oRect.y;
oRect.h = m_oRect.h;
oRect.x = m_oRect.x + iWidth * a_iNumber;
oRect.w = iWidth - iGap;
return oRect;
}
IViewElement::IViewElement( CPlayerSelectView* a_poView, int a_iPriority )
{
m_poView = a_poView;
m_iPriority = a_iPriority;
m_poView->AddViewElement( this, m_iPriority );
}
IViewElement::~IViewElement()
{
}
int IViewElement::GetPriority() const
{
return m_iPriority;
}
/**
Flying portrait element for CPlayerSelectView.
The portrait of a given fighter will gracefully fly from the chooser
to a team display. The view element will delete itself afterwards.
\ingroup PlayerSelect
*/
class CFlyingPortraitViewElement: public IViewElement
{
public:
CFlyingPortraitViewElement( CPlayerSelectView* a_poView, CTeamDisplay* a_poTeamDisplay,
FighterEnum a_enFighter, const SDL_Rect& a_oSrcRect, const SDL_Rect& a_oDstRect )
: IViewElement( a_poView, 0 )
{
m_poTeamDisplay = a_poTeamDisplay;
m_iTeamNumber = m_poTeamDisplay->GetCount();
m_enFighter = a_enFighter;
m_oRect = a_oSrcRect;
m_oDstRect = a_oDstRect;
m_dX = m_oRect.x + m_oRect.w / 2;
m_dY = m_oRect.y + m_oRect.h / 2;
m_dSize = MIN( m_oRect.w, m_oRect.h );
m_dSpeedX = 0.0;
m_dSpeedY = - m_dY / 15;
m_dSpeedSize= 0.0;
m_dTargetX = m_oDstRect.x + m_oDstRect.w / 2;
m_dTargetY = m_oDstRect.y + m_oDstRect.h / 2;
m_dTargetSize = MIN( m_oDstRect.w, m_oDstRect.h);
m_iTotalTime = 70 + m_dY / 7.5;
m_iTime = m_iTotalTime;
}
~CFlyingPortraitViewElement() {}
void Advance( int a_iNumFrames )
{
if ( m_dX + m_dSpeedX * 0.5 * m_iTime > m_dTargetX ) m_dSpeedX -= a_iNumFrames * 0.5; else m_dSpeedX += a_iNumFrames * 0.5;
if ( m_dY + m_dSpeedY * 0.5 * m_iTime > m_dTargetY ) m_dSpeedY -= a_iNumFrames * 0.5; else m_dSpeedY += a_iNumFrames * 0.5;
m_dX += m_dSpeedX * a_iNumFrames;
m_dY += m_dSpeedY * a_iNumFrames;
double dTargetSize = (m_iTime > m_iTotalTime/2) ? 75.0 : m_dTargetSize;
int iTargetTime = (m_iTime > m_iTotalTime/2) ? m_iTime : ( m_iTotalTime/2-m_iTime );
if ( m_dSize + m_dSpeedSize * iTargetTime > dTargetSize ) m_dSpeedSize -= a_iNumFrames * 0.3; else m_dSpeedSize += a_iNumFrames * 0.3;
m_dSize += m_dSpeedSize * a_iNumFrames;
m_oRect.x = int( m_dX - m_dSize / 2 );
m_oRect.y = int( m_dY - m_dSize / 2 );
m_oRect.w = m_oRect.h = (int)m_dSize;
m_iTime -= a_iNumFrames;
if ( m_iTime < 0 )
{
m_poTeamDisplay->DrawFighter( m_enFighter, m_iTeamNumber );
m_poView->RemoveViewElement( this );
delete( this );
}
}
void Draw()
{
g_oChooser.DrawPortrait( m_enFighter, gamescreen, m_oRect );
}
protected:
CTeamDisplay* m_poTeamDisplay;
int m_iTeamNumber;
FighterEnum m_enFighter;
double m_dX, m_dY, m_dSize;
double m_dSpeedX, m_dSpeedY, m_dSpeedSize;
double m_dTargetX, m_dTargetY, m_dTargetSize;
int m_iTotalTime;
int m_iTime;
SDL_Rect m_oDstRect;
SDL_Rect m_oRect;
int m_iNumber;
};
/**
This view element implements the "opening courtain" effect at the start
of the player selection routine.
It removes itself when the effect is
finished.
\ingroup PlayerSelect
*/
class CCourtainViewElement: public IViewElement
{
public:
CCourtainViewElement( CPlayerSelectView* a_poView ) : IViewElement( a_poView, 0 )
{
m_iCourtain = 0;
m_iCourtainSpeed = 0;
m_iCourtainTime = 80;
}
~CCourtainViewElement() {}
void Advance( int a_iNumFrames )
{
if ( a_iNumFrames > 5 ) a_iNumFrames = 5;
if ( m_iCourtainTime <= 0 )
{
SDL_SetClipRect( gamescreen, NULL );
m_poView->RemoveViewElement( this );
delete( this );
}
if ( m_iCourtain + m_iCourtainSpeed * m_iCourtainTime /2 < 320 * 4 )
m_iCourtainSpeed += a_iNumFrames;
else
m_iCourtainSpeed -= a_iNumFrames;
m_iCourtain += m_iCourtainSpeed * a_iNumFrames;
m_iCourtainTime -= a_iNumFrames;
if ( m_iCourtainTime > 0 )
{
SDL_Rect oRect;
oRect.x = 320 - m_iCourtain/4; oRect.y = 0;
oRect.w = m_iCourtain / 2; oRect.h = gamescreen->h;
if ( oRect.x < 0 ) oRect.x = 0;
if ( oRect.w > gamescreen->w ) oRect.w = gamescreen->w;
SDL_SetClipRect( gamescreen, &oRect );
}
}
void Draw()
{
}
protected:
int m_iCourtain;
int m_iCourtainSpeed;
int m_iCourtainTime;
};
/**
This view element flashes the title and '?' mark of active teams.
\ingroup PlayerSelect
*/
class CTeamFlashViewElement: public IViewElement
{
public:
CTeamFlashViewElement( CPlayerSelectView* a_poView, int a_iPriority )
: IViewElement( a_poView, a_iPriority )
{
for ( int i=0; i<MAXPLAYERS; ++i )
{
m_bActive[i] = false;
}
}
~CTeamFlashViewElement() {}
void Advance( int a_iNumFrames )
{
m_iCycle = (m_iCycle + a_iNumFrames*10) % 512;
}
void Draw()
{
int iLum = m_iCycle < 256 ? m_iCycle : 511-m_iCycle;
for ( int i=0; i<g_oState.m_iNumPlayers; ++i )
{
if ( g_oChooser.IsRectangleVisible( i ) )
{
SDL_Color oColor;
switch (i)
{
case 0: oColor.r = 85; oColor.g = 255; oColor.b = 85; break;
case 1: oColor.r = 255; oColor.g = 85; oColor.b = 255; break;
case 2: oColor.r = 255; oColor.g = 255; oColor.b = 85; break;
default: oColor.r = 85; oColor.g = 85; oColor.b = 255; break;
}
Uint32 iColor = SDL_MapRGB( gamescreen->format, oColor.r*iLum/256, oColor.g*iLum/256, oColor.b*iLum/256 );
m_poView->GetTeamDisplay(i)->DrawTitle( iColor );
m_poView->GetTeamDisplay(i)->DrawQuestionMark( iColor );
m_bActive[i] = true;
}
else if ( m_bActive[i] )
{
m_poView->GetTeamDisplay(i)->DrawTitle( C_WHITE );
m_bActive[i] = false;
}
}
}
protected:
int m_iCycle;
bool m_bActive[MAXPLAYERS];
};
/*************************************************************************
CPLAYERSELECTVIEW CLASS
*************************************************************************/
CPlayerSelectView::CPlayerSelectView( bool a_bNetworkGame, bool a_bTeamMode )
{
m_bOver = false;
m_bNetworkGame = a_bNetworkGame;
m_bTeamMode = a_bTeamMode;
- m_bTeamMultiselect = g_oState.m_bTeamMultiselect;
+ m_bTeamMultiselect = g_oState.m_bTeamMultiselect > 0;
m_poReadline = NULL;
m_poTextArea = NULL;
m_iTime = 0;
int i;
for ( i=0; i<MAXPLAYERS; ++i ) m_apoTeamDisplays[i] = NULL;
SDL_FillRect( gamescreen, NULL, C_BLACK );
SDL_Flip( gamescreen );
m_poBackground = LoadBackground( "FighterStats.jpg", 64 ); //m_bNetworkGame ? "PlayerSelect_chat.png" : "PlayerSelect.png", 111 );
if ( m_poBackground ) SDL_SetColorKey( m_poBackground, 0, 0 );
new CCourtainViewElement(this);
if ( m_bTeamMode )
{
new CTeamFlashViewElement(this, 0);
SDL_Rect oRect;
oRect.x = 10; oRect.w = 620;
oRect.y = 380; oRect.h = 40;
m_apoTeamDisplays[0] = new CTeamDisplay( 0, m_poBackground, oRect );
oRect.y = 430; oRect.h = 40;
m_apoTeamDisplays[1] = new CTeamDisplay( 1, m_poBackground, oRect );
if ( g_oState.m_iNumPlayers >= 3 )
{
oRect.y = 330;
m_apoTeamDisplays[2] = new CTeamDisplay( 2, m_poBackground, oRect );
}
if ( g_oState.m_iNumPlayers >= 4 )
{
oRect.y = 280;
m_apoTeamDisplays[3] = new CTeamDisplay( 3, m_poBackground, oRect );
}
if ( m_bTeamMultiselect )
{
m_iChooserTop = 25;
m_iChooserHeight = 80 * 4;
m_iChooserLeft = 158;
m_iChooserWidth = 64*5;
}
else
{
DrawGradientText( "Choose A Fighter Dammit", titleFont, 10, m_poBackground );
m_iChooserTop = 75;
m_iChooserHeight = 80 * 4 - 50;
m_iChooserLeft = 180;
m_iChooserWidth = 430;
}
m_iFighterYOffset = -100;
m_iFighterNameYOffset = -95;
}
else if ( m_bNetworkGame )
{
m_iChooserLeft = 158;
m_iChooserTop = 26;
m_iChooserWidth = 64 * 5;
m_iChooserHeight = 64 * 4;
m_iFighterYOffset = -130;
m_iFighterNameYOffset = -170;
}
else
{
m_iChooserLeft = 158;
m_iChooserTop = 74;
m_iChooserWidth = 80*4;
m_iChooserHeight = 80*5;
m_iFighterYOffset = 0;
m_iFighterNameYOffset = 0;
}
g_oChooser.Start( m_poBackground );
g_oChooser.Resize( m_iChooserLeft, m_iChooserTop, m_iChooserLeft+m_iChooserWidth, m_iChooserTop+m_iChooserHeight );
g_oChooser.Draw();
if ( !m_bNetworkGame && !m_bTeamMode )
{
DrawGradientText( "Choose A Fighter Dammit", titleFont, 10, m_poBackground );
}
if ( m_bNetworkGame )
{
char acMsg[256];
sprintf( acMsg, "Press Enter to chat, Page Up/Page Down to scroll..." );
if ( m_bNetworkGame )
{
m_poReadline = new CReadline( m_bNetworkGame ? m_poBackground : NULL, chatFont,
acMsg, strlen(acMsg), 256, 15, 465, 610, C_LIGHTCYAN, C_BLACK, 255 );
m_poTextArea = new CTextArea( m_poBackground, chatFont, 15, 313, 610, 32*4 );
}
}
}
CPlayerSelectView::~CPlayerSelectView()
{
delete m_apoTeamDisplays[0]; m_apoTeamDisplays[0] = NULL;
delete m_apoTeamDisplays[1]; m_apoTeamDisplays[1] = NULL;
TViewElements::iterator it;
for ( it=m_apoElements.begin(); it!= m_apoElements.end(); ++it )
{
delete *it;
}
m_apoElements.clear();
delete m_poTextArea;
delete m_poReadline;
SDL_FreeSurface( m_poBackground );
}
void CPlayerSelectView::Advance( int a_iNumFrames )
{
m_iTime += a_iNumFrames;
for ( int i=0; i<a_iNumFrames; ++i )
{
g_oBackend.AdvancePerl();
TViewElements::iterator it;
}
TViewElements::iterator it;
TViewElements::iterator itNext;
for ( it = m_apoElements.begin(); it != m_apoElements.end(); )
{
itNext = it;
++itNext;
(*it)->Advance( a_iNumFrames );
it = itNext;
}
}
void CPlayerSelectView::Draw()
{
TViewElements::iterator it;
g_oBackend.ReadFromPerl();
- m_bOver = g_oBackend.m_iGameOver;
+ m_bOver = g_oBackend.m_iGameOver > 0;
g_oChooser.DrawRectangles(m_iTime);
SDL_BlitSurface( m_poBackground, NULL, gamescreen, NULL );
for ( it = m_apoElements.begin(); it != m_apoElements.end(); ++it )
{
(*it)->Draw();
}
for ( int i=0; i<g_oState.m_iNumPlayers; ++i )
{
if ( m_bTeamMode && 1==i && !m_bTeamMultiselect ) continue;
const SPlayerInfo& roPlayerInfo = g_oPlayerSelect.GetPlayerInfo( i );
int iPlayerNameWidth = g_oPlayerSelect.GetFighterNameWidth( i );
if ( g_oBackend.m_aoPlayers[i].m_iFrame )
{
roPlayerInfo.m_poPack->Draw(
ABS(g_oBackend.m_aoPlayers[i].m_iFrame)-1,
g_oBackend.m_aoPlayers[i].m_iX, g_oBackend.m_aoPlayers[i].m_iY + m_iFighterYOffset,
g_oBackend.m_aoPlayers[i].m_iFrame < 0 );
}
int x = ( m_iChooserLeft - iPlayerNameWidth ) / 2;
if ( x<10 ) x = 10;
if ( i ) x = gamescreen->w - x - iPlayerNameWidth;
sge_BF_textout( gamescreen, fastFont, g_oPlayerSelect.GetFighterName(i),
x, gamescreen->h - 40 + m_iFighterNameYOffset );
}
SDL_Flip( gamescreen );
}
CReadline* CPlayerSelectView::GetReadline()
{
return m_poReadline;
}
CTextArea* CPlayerSelectView::GetTextArea()
{
return m_poTextArea;
}
void CPlayerSelectView::AddViewElement( IViewElement* a_poElement, int a_iPriority )
{
m_apoElements.push_back( a_poElement );
}
void CPlayerSelectView::RemoveViewElement( IViewElement* a_poElement )
{
m_apoElements.remove( a_poElement );
}
void CPlayerSelectView::AddFighterToTeam( int a_iPlayer, FighterEnum a_enFighter )
{
new CFlyingPortraitViewElement( this, m_apoTeamDisplays[a_iPlayer], a_enFighter,
g_oChooser.GetFighterRect( a_enFighter ),
m_apoTeamDisplays[a_iPlayer]->GetRect() );
m_apoTeamDisplays[a_iPlayer]->AddFighter( a_enFighter );
}
bool CPlayerSelectView::IsOver()
{
return m_bOver;
}
CTeamDisplay* CPlayerSelectView::GetTeamDisplay( int a_iPlayer )
{
return m_apoTeamDisplays[a_iPlayer];
}
diff --git a/src/gfx.cpp b/src/gfx.cpp
index ee54575..2de9103 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -1,458 +1,466 @@
/***************************************************************************
gfx.cpp - description
-------------------
begin : Tue Apr 10 2001
copyright : (C) 2001 by UPi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include <string.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 "Event.h"
int CSurfaceLocker::m_giLockCount = 0;
Uint16 *UTF8_to_UNICODE(Uint16 *unicode, const char *utf8, int len);
void sge_TTF_SizeText( _sge_TTFont*font, const char* text, int* x, int* y )
{
#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 = new Uint16[unicode_len+1]; // (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 */
delete[] unicode_text; //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, 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;
+ char *c1, *c2;
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;
+ notend = *c2 != 0;
*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;
+ notend = *c2 != 0;
*c2 = 0;
sge_TTF_SizeText( font, c1, &i, &j);
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, 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 );
CSurfaceLocker oLock;
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, bool a_bTranslate )
{
- int i, j;
+ int i;
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];
// 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( surface, font, text,
1, y1, 255, 0, 255);
if ( SDL_MUSTLOCK(surface) ) SDL_LockSurface(surface);
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;
}
}
}
}
if ( SDL_MUSTLOCK(surface) ) SDL_UnlockSurface(surface);
// 4. FINALLY
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;
}
/**
Waits for a key event and returns it.
\param a_bTranslate If this is true, then keypad events will also be
read and processed info keys (cursor, return and escape).
*/
SDLKey GetKey( bool a_bTranslate )
{
SDL_Event oSdlEvent;
SMortalEvent oEvent;
while (SDL_WaitEvent(&oSdlEvent))
{
if ( SDL_KEYDOWN == oSdlEvent.type )
{
return oSdlEvent.key.keysym.sym;
}
if ( SDL_QUIT == oSdlEvent.type )
{
g_oState.m_bQuitFlag = true;
return SDLK_ESCAPE;
}
if ( ! a_bTranslate )
{
continue;
}
// Handle gamepad and others
TranslateEvent( &oSdlEvent, &oEvent );
switch (oEvent.m_enType)
{
case Me_QUIT:
g_oState.m_bQuitFlag = true;
return SDLK_ESCAPE;
case Me_PLAYERKEYDOWN:
switch ( oEvent.m_iKey ) {
case Mk_UP: return SDLK_UP;
case Mk_DOWN: return SDLK_DOWN;
case Mk_LEFT: return SDLK_LEFT;
case Mk_RIGHT: return SDLK_RIGHT;
default: return SDLK_RETURN;
}
break;
case Me_MENU:
return SDLK_ESCAPE;
default:
break;
} // switch statement
} // Polling events
// Code will never reach this point, unless there's an error.
return SDLK_ESCAPE;
}
-
+/**
+\TODO Remove a_iNumcolors, a_iPaletteOffset
+*/
SDL_Surface* LoadBackground( const char* a_pcFilename, int a_iNumColors, int a_iPaletteOffset, bool a_bTransparent )
{
char acFilepath[FILENAME_MAX+1];
strcpy( acFilepath, DATADIR );
strcat( acFilepath, "/gfx/" );
strcat( acFilepath, a_pcFilename );
SDL_Surface* poBackground = IMG_Load( acFilepath );
if (!poBackground)
{
debug( "Can't load file: %s\n", acFilepath );
return NULL;
}
SDL_Palette* pal = poBackground->format->palette;
if ( pal && gamescreen->format->palette )
{
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 );
// 2. TRY TO LOAD AN IMAGE MASK
// This means trying to load a .png file which acts as a mask for the
// original [jpg] image.
// If the original file is <Basename>.jpg, the mask is <Basename>.mask.png
int iLength = strlen( acFilepath );
char acMaskFilename[FILENAME_MAX+1];
strncpy( acMaskFilename, acFilepath, iLength-4 );
acMaskFilename[iLength-4] = 0;
strcat( acMaskFilename, ".mask.png" );
SDL_Surface* poMask = IMG_Load( acMaskFilename );
if ( !poMask )
{
// No mask.
return poRetval;
}
if ( poMask->w < poRetval->w
|| poMask->h < poRetval->h )
{
debug( "Error loading mask for %s: mask is too small.\n", acFilepath );
SDL_FreeSurface( poMask );
return poRetval;
}
debug( "Loading mask for %s.\n", acFilepath );
Uint32 iTransparent = SDL_MapRGB( gamescreen->format, 255, 217, 0 ); // an unlikely color in openmortal..
Uint32 iMask = sge_GetPixel( poMask, 0, 0 );
Uint32 iPixel;
for ( int y = 0; y < poRetval->h; ++y ) {
for ( int x=0; x< poRetval->w; ++x ) {
iPixel = sge_GetPixel( poMask, x, y );
// debug( "%d ", iPixel );
if ( iPixel == iMask ) {
sge_PutPixel( poRetval, x, y, iTransparent );
}
}
// debug( "\n" );
}
SDL_FreeSurface( poMask );
SDL_SetColorKey( poRetval, SDL_SRCCOLORKEY, iTransparent );
return poRetval;
}
+SDL_Surface *LoadImage( const char* a_pcFilename )
+{
+ return LoadBackground(a_pcFilename, 0, 0);
+}
+
+
bool SetVideoMode( bool a_bLarge, bool a_bFullScreen, int a_iAdditionalFlags )
{
// SET THE PARAMETERS FOR THE VIDEO MODE
int iBpp = 16; // Try the display's BPP first.
if ( NULL != gamescreen )
{
iBpp = gamescreen->format->BitsPerPixel;
}
int iFlags = a_iAdditionalFlags;
if ( a_bFullScreen )
{
iFlags |= SDL_FULLSCREEN;
}
// CALL SDL_SetVideoMode
int iWidth = a_bLarge ? 800 : 640;
int iHeight = a_bLarge ? 600 : 480;
// if ( !a_bFullScreen ) iHeight = 480;
gamescreen = SDL_SetVideoMode( iWidth, iHeight, iBpp, iFlags );
if ( NULL == gamescreen )
{
debug( "SDL_SetVideoMode( %d, %d, %d, %d ) failed.\n", iWidth, iHeight, iBpp, iFlags );
return false;
}
// IF THE DISPLAY IS 24BPP OR 8 BPP OR LESS, EMULATE 16 BPP INSTEAD
// (because we are lazy and won't write 8bpp and 24bpp code anymore)
if ( gamescreen->format->BytesPerPixel != 2
&& gamescreen->format->BytesPerPixel != 4 )
{
gamescreen = SDL_SetVideoMode( iWidth, iHeight, 16, iFlags );
if ( NULL == gamescreen )
{
debug( "SDL_SetVideoMode( %d, %d, %d, %d ) failed.\n", iWidth, iHeight, 16, iFlags );
return false;
}
}
return true;
}
diff --git a/src/gfx.h b/src/gfx.h
index e508baf..733fcab 100644
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -1,94 +1,95 @@
/***************************************************************************
gfx.h - description
-------------------
begin : Tue Apr 10 2001
copyright : (C) 2001 by UPi
email : upi@apocalypse.rulez.org
***************************************************************************/
#ifndef _GFX_H
#define _GFX_H
/**
\defgroup Media Sound and graphics
Classes that deal with sound, graphics, input, etc.
*/
struct _sge_TTFont;
#include "SDL.h"
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( bool a_bTranslate );
SDL_Surface* LoadBackground( const char* a_pcFilename, int a_iNumColors, int a_iPaletteOffset=0, bool a_bTransparent = false );
+SDL_Surface* LoadImage( const char* a_pcFilename );
bool SetVideoMode( bool a_bLarge, bool a_bFullscreen, int a_iAdditionalFlags=0 );
extern SDL_Surface* gamescreen;
/**
\ingroup Media
*/
class CSurfaceLocker
{
public:
inline CSurfaceLocker()
{
if ( 0 == m_giLockCount )
{
if (SDL_MUSTLOCK(gamescreen)) {
SDL_LockSurface( gamescreen );
}
}
++m_giLockCount;
}
inline ~CSurfaceLocker()
{
--m_giLockCount;
if ( 0 == m_giLockCount )
{
if (SDL_MUSTLOCK(gamescreen)) {
SDL_UnlockSurface( gamescreen );
}
}
}
protected:
static int m_giLockCount;
};
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
extern _sge_TTFont* chatFont; // small but legible.
#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

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jun 16, 12:40 AM (2 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
72427
Default Alt Text
(29 KB)

Event Timeline