Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F132275
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
29 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
R76 OpenMortal
Attached
Detach File
Event Timeline