Page MenuHomePhabricator (Chris)

No OneTemporary

Size
87 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/data/fonts/Makefile.am b/data/fonts/Makefile.am
index 46e7504..91f7fcd 100644
--- a/data/fonts/Makefile.am
+++ b/data/fonts/Makefile.am
@@ -1,8 +1,8 @@
## Process this file with automake to produce Makefile.in
fontsdatadir = $(pkgdatadir)/fonts
fontsdata_DATA = \
-aardvark.ttf bradybun.ttf deadgrit.ttf \
+aardvark.ttf bradybun.ttf deadgrit.ttf thin.ttf \
brandybun3.png glossyfont.png CreditsFont2.png
EXTRA_DIST = $(fontsdata_DATA)
diff --git a/data/fonts/Makefile.in b/data/fonts/Makefile.in
index f726b5b..5a6c707 100644
--- a/data/fonts/Makefile.in
+++ b/data/fonts/Makefile.in
@@ -1,214 +1,214 @@
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_alias = @build_alias@
build_triplet = @build@
host_alias = @host_alias@
host_triplet = @host@
target_alias = @target_alias@
target_triplet = @target@
AUTODIRS = @AUTODIRS@
CXX = @CXX@
FT2_CFLAGS = @FT2_CFLAGS@
FT2_CONFIG = @FT2_CONFIG@
FT2_LIBS = @FT2_LIBS@
MAKEINFO = @MAKEINFO@
PACKAGE = @PACKAGE@
PERL = @PERL@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
VERSION = @VERSION@
perl_embed_ccflags = @perl_embed_ccflags@
perl_embed_ldflags = @perl_embed_ldflags@
fontsdatadir = $(pkgdatadir)/fonts
-fontsdata_DATA = aardvark.ttf bradybun.ttf deadgrit.ttf brandybun3.png glossyfont.png CreditsFont2.png
+fontsdata_DATA = aardvark.ttf bradybun.ttf deadgrit.ttf thin.ttf brandybun3.png glossyfont.png CreditsFont2.png
EXTRA_DIST = $(fontsdata_DATA)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../config.h
CONFIG_CLEAN_FILES =
DATA = $(fontsdata_DATA)
DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = gtar
GZIP_ENV = --best
all: all-redirect
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu data/fonts/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
install-fontsdataDATA: $(fontsdata_DATA)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(fontsdatadir)
@list='$(fontsdata_DATA)'; for p in $$list; do \
if test -f $(srcdir)/$$p; then \
echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(fontsdatadir)/$$p"; \
$(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(fontsdatadir)/$$p; \
else if test -f $$p; then \
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(fontsdatadir)/$$p"; \
$(INSTALL_DATA) $$p $(DESTDIR)$(fontsdatadir)/$$p; \
fi; fi; \
done
uninstall-fontsdataDATA:
@$(NORMAL_UNINSTALL)
list='$(fontsdata_DATA)'; for p in $$list; do \
rm -f $(DESTDIR)$(fontsdatadir)/$$p; \
done
tags: TAGS
TAGS:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = data/fonts
distdir: $(DISTFILES)
here=`cd $(top_builddir) && pwd`; \
top_distdir=`cd $(top_distdir) && pwd`; \
distdir=`cd $(distdir) && pwd`; \
cd $(top_srcdir) \
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu data/fonts/Makefile
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
install-data-am: install-fontsdataDATA
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am: uninstall-fontsdataDATA
uninstall: uninstall-am
all-am: Makefile $(DATA)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
$(mkinstalldirs) $(DESTDIR)$(fontsdatadir)
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-generic clean-am
distclean: distclean-am
maintainer-clean-am: maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
.PHONY: uninstall-fontsdataDATA install-fontsdataDATA tags distdir \
info-am info dvi-am dvi check check-am installcheck-am installcheck \
install-exec-am install-exec install-data-am install-data install-am \
install uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/data/fonts/thin.ttf b/data/fonts/thin.ttf
new file mode 100644
index 0000000..70c1c53
Binary files /dev/null and b/data/fonts/thin.ttf differ
diff --git a/src/PlayerSelect.cpp b/src/PlayerSelect.cpp
index a35179f..9a99198 100644
--- a/src/PlayerSelect.cpp
+++ b/src/PlayerSelect.cpp
@@ -1,735 +1,736 @@
/***************************************************************************
PlayerSelect.cpp - description
-------------------
begin : Sun Dec 8 2002
copyright : (C) 2002 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include <stdio.h>
#include "PlayerSelect.h"
#include "SDL.h"
#include "SDL_video.h"
#include "SDL_image.h"
#include "sge_primitives.h"
#include "sge_surface.h"
#include "common.h"
#include "Audio.h"
#include "sge_bm_text.h"
#include "gfx.h"
#include "RlePack.h"
#include "Backend.h"
#include "State.h"
#include "MortalNetwork.h"
#include "Chooser.h"
#include "sge_tt_text.h"
#include "TextArea.h"
#ifndef NULL
#define NULL 0
#endif
/***************************************************************************
PUBLIC EXPORTED VARIABLES
***************************************************************************/
PlayerSelect g_oPlayerSelect;
/***************************************************************************
PRIVATE VARIABLES (perl variable space)
***************************************************************************/
FighterEnum ChooserCells[5][4] = {
{ ZOLI, UPI, CUMI, SIRPI },
{ ULMAR, MACI, GRIZLI, DESCANT },
{ DANI, AMBRUS, BENCE, SURBA },
{ (FighterEnum)100, (FighterEnum)101, (FighterEnum)102, (FighterEnum)103 },
{ (FighterEnum)104, (FighterEnum)105, KINGA, MISI }
};
FighterEnum ChooserCellsChat[4][5] = {
{ ZOLI, UPI, CUMI, SIRPI, ULMAR },
{ MACI, BENCE, GRIZLI, DESCANT, SURBA },
{ DANI, AMBRUS, (FighterEnum)100, (FighterEnum)102, KINGA },
{ (FighterEnum)104, (FighterEnum)105, (FighterEnum)103, (FighterEnum)101, MISI },
};
PlayerSelect::PlayerSelect()
{
for ( int i=0; i<2; ++i )
{
m_aoPlayers[i].m_enFighter = UNKNOWN;
m_aoPlayers[i].m_enTint = NO_TINT;
m_aoPlayers[i].m_poPack = NULL;
}
m_iP1 = 0;
m_iP2 = 3;
}
const PlayerInfo& PlayerSelect::GetPlayerInfo( int a_iPlayer )
{
return m_aoPlayers[ a_iPlayer ? 1 : 0 ];
}
const char* PlayerSelect::GetFighterName( int a_iPlayer )
{
return m_aoPlayers[ a_iPlayer ? 1 : 0 ].m_sFighterName.c_str();
}
int PlayerSelect::GetFighterNameWidth( int a_iPlayer )
{
return m_aiFighterNameWidth[ a_iPlayer ? 1 : 0 ];
}
bool PlayerSelect::IsFighterAvailable( FighterEnum a_enFighter )
{
if ( a_enFighter <= UNKNOWN )
{
return false;
}
bool bLocalAvailable = IsLocalFighterAvailable( a_enFighter );
if ( !IsNetworkGame() || !bLocalAvailable )
{
return bLocalAvailable;
}
// Check the remote site
return g_poNetwork->IsRemoteFighterAvailable( a_enFighter );
}
bool PlayerSelect::IsLocalFighterAvailable( FighterEnum a_enFighter )
{
if ( a_enFighter <= UNKNOWN )
{
return false;
}
g_oBackend.PerlEvalF("GetFighterStats(%d);", a_enFighter);
const char* pcDatafile = g_oBackend.GetPerlString("Datafile");
return pcDatafile && *pcDatafile;
}
/** LoadFighter simply looks up the filename associated with the given
fighter, loads it, and returns the RlePack.
\return The freshly loaded RlePack, or NULL if it could not be loaded.
*/
RlePack* PlayerSelect::LoadFighter( FighterEnum m_enFighter ) // static
{
char a_pcFilename[FILENAME_MAX+1];
const char* s;
g_oBackend.PerlEvalF( "GetFighterStats(%d);", m_enFighter );
s = g_oBackend.GetPerlString( "Datafile" );
strcpy( a_pcFilename, DATADIR );
strcat( a_pcFilename, "/characters/" );
strcat( a_pcFilename, s );
RlePack* pack = new RlePack( a_pcFilename, COLORSPERPLAYER );
if ( pack->Count() <= 0 )
{
debug( "Couldn't load RlePack: '%s'\n", a_pcFilename );
delete pack;
return NULL;
}
return pack;
}
/** SetPlayer loads the given fighter for the given player.
The RlePack is loaded first. If that succeeds, then the perl backend is
set too. The tint and palette of both players are set. */
void PlayerSelect::SetPlayer( int a_iPlayer, FighterEnum a_enFighter )
{
if ( a_iPlayer ) a_iPlayer = 1; // It's 0 or 1.
if ( m_aoPlayers[a_iPlayer].m_enFighter == a_enFighter )
{
if ( m_aoPlayers[a_iPlayer].m_poPack )
{
m_aoPlayers[a_iPlayer].m_poPack->ApplyPalette();
}
return;
}
if ( !IsFighterAvailable( a_enFighter ) )
{
return;
}
int iOffset = a_iPlayer ? COLOROFFSETPLAYER2 : COLOROFFSETPLAYER1;
RlePack* poPack = LoadFighter( a_enFighter );
poPack->OffsetSprites( iOffset );
if ( NULL == poPack )
{
debug( "SetPlayer(%d,%d): Couldn't load RlePack\n", a_iPlayer, a_enFighter );
return;
}
delete m_aoPlayers[a_iPlayer].m_poPack;
m_aoPlayers[a_iPlayer].m_poPack = poPack;
m_aoPlayers[a_iPlayer].m_enFighter = a_enFighter;
g_oBackend.PerlEvalF( "SetPlayerNumber(%d,%d);", a_iPlayer, a_enFighter );
m_aoPlayers[a_iPlayer].m_sFighterName = g_oBackend.GetPerlString( "PlayerName" );
m_aiFighterNameWidth[a_iPlayer] = sge_BF_TextSize( fastFont, GetFighterName(a_iPlayer) ).w;
TintEnum enTint = NO_TINT;
if ( m_aoPlayers[0].m_enFighter == m_aoPlayers[1].m_enFighter )
{
enTint = TintEnum( (rand() % 4) + 1 );
}
SetTint( 1, enTint );
m_aoPlayers[a_iPlayer].m_poPack->ApplyPalette();
}
void PlayerSelect::SetTint( int a_iPlayer, TintEnum a_enTint )
{
m_aoPlayers[a_iPlayer].m_enTint = a_enTint;
if ( m_aoPlayers[a_iPlayer].m_poPack )
{
m_aoPlayers[a_iPlayer].m_poPack->SetTint( a_enTint );
m_aoPlayers[a_iPlayer].m_poPack->ApplyPalette();
}
}
bool PlayerSelect::IsNetworkGame()
{
return SState::IN_NETWORK == g_oState.m_enGameMode;
}
FighterEnum PlayerSelect::GetFighterCell( int a_iIndex )
{
if ( IsNetworkGame() )
{
return ChooserCellsChat[a_iIndex/m_iChooserCols][a_iIndex%m_iChooserCols];
}
else
{
return ChooserCells[a_iIndex/m_iChooserCols][a_iIndex%m_iChooserCols];
}
}
void PlayerSelect::HandleKey( int a_iPlayer, int a_iKey )
{
// If we are in network mode, all keys count as the local player's...
if ( IsNetworkGame() )
{
a_iPlayer = g_poNetwork->IsMaster() ? 0 : 1;
}
int& riP = a_iPlayer ? m_iP2 : m_iP1;
int iOldP = riP;
bool& rbDone = a_iPlayer ? m_bDone2 : m_bDone1;
if ( rbDone )
{
return;
}
switch ( a_iKey )
{
case 0: // up
if ( riP >= m_iChooserCols ) riP -= m_iChooserCols;
break;
case 1: // down
if ( (riP/m_iChooserCols) < (m_iChooserRows-1) ) riP += m_iChooserCols;
break;
case 2: // left
if ( (riP % m_iChooserCols) > 0 ) riP--;
break;
case 3: // right
if ( (riP % m_iChooserCols) < (m_iChooserCols-1) ) riP++;
break;
default:
if ( IsFighterAvailable( GetFighterCell(riP) ) )
{
Audio->PlaySample("magic.voc");
rbDone = true;
g_oBackend.PerlEvalF( "PlayerSelected(%d);", a_iPlayer );
if ( IsNetworkGame() )
{
g_poNetwork->SendFighter( GetFighterCell(riP) );
g_poNetwork->SendReady();
}
return;
}
}
if ( iOldP != riP )
{
Audio->PlaySample("strange_quack.voc");
if ( IsFighterAvailable( GetFighterCell(riP) ) )
{
if ( IsNetworkGame() )
{
g_poNetwork->SendFighter( GetFighterCell(riP) );
}
SetPlayer( a_iPlayer, GetFighterCell(riP) );
}
}
}
void PlayerSelect::HandleNetwork()
{
g_poNetwork->Update();
bool bUpdateText = false;
while ( g_poNetwork->IsMsgAvailable() )
{
const char* pcMsg = g_poNetwork->GetMsg();
int iColor = C_YELLOW;
if ( pcMsg[0] == '*' && pcMsg[1] == '*' && pcMsg[2] == '*' ) iColor = C_WHITE;
m_poTextArea->AddString( pcMsg, iColor );
bUpdateText = true;
}
if ( bUpdateText )
{
Audio->PlaySample("pop.wav");
m_poTextArea->Redraw();
}
bool bMaster = g_poNetwork->IsMaster();
int iPlayer = bMaster ? 1 : 0;
int& riP = bMaster ? m_iP2 : m_iP1;
bool& rbDone = bMaster ? m_bDone2 : m_bDone1;
if ( rbDone )
{
return;
}
int iOldP = riP;
FighterEnum enOldFighter = GetFighterCell(iOldP);
FighterEnum enRemoteFighter = g_poNetwork->GetRemoteFighter();
if ( enOldFighter != enRemoteFighter
&& enRemoteFighter != UNKNOWN )
{
Audio->PlaySample("strange_quack.voc");
SetPlayer( iPlayer, enRemoteFighter );
int i, j;
for ( i=0; i<m_iChooserRows; ++i )
{
for ( int j=0; j<m_iChooserCols; ++j )
{
if ( ChooserCellsChat[i][j] == enRemoteFighter )
{
riP = i * m_iChooserCols + j;
break;
}
}
}
}
bool bDone = g_poNetwork->IsRemoteSideReady();
if ( bDone )
{
rbDone = true;
Audio->PlaySample("magic.voc");
g_oBackend.PerlEvalF( "PlayerSelected(%d);", iPlayer );
}
}
void PlayerSelect::DrawRect( int a_iPos, int a_iColor )
{
int iRow = a_iPos / m_iChooserCols;
int iCol = a_iPos % m_iChooserCols;
SDL_Rect r, r1;
r.x = m_iChooserLeft + iCol * m_iChooserWidth;
r.y = m_iChooserTop + iRow * m_iChooserHeight;
r.w = m_iChooserWidth + 5;
r.h = 5;
r1 = r;
SDL_FillRect( gamescreen, &r1, a_iColor );
r.y += m_iChooserHeight;
r1 = r;
SDL_FillRect( gamescreen, &r1, a_iColor );
r.y -= m_iChooserHeight;
r.w = 5;
r.h = m_iChooserHeight + 5;
r1 = r;
SDL_FillRect( gamescreen, &r1, a_iColor );
r.x += m_iChooserWidth;
r1 = r;
SDL_FillRect( gamescreen, &r1, a_iColor );
}
void PlayerSelect::CheckPlayer( SDL_Surface* a_poBackground, int a_iRow, int a_iCol, int a_iColor )
{
int x1, y1;
x1 = m_iChooserLeft + a_iCol * m_iChooserWidth +5;
y1 = m_iChooserTop + a_iRow * m_iChooserHeight +5;
sge_Line(a_poBackground, x1+5, y1+5, x1 + m_iChooserWidth-10, y1 + m_iChooserHeight-10, a_iColor);
sge_Line(a_poBackground, x1 + m_iChooserWidth-10, y1+5, x1+5, y1 + m_iChooserHeight-10, a_iColor);
x1++;
sge_Line(a_poBackground, x1+5, y1+5, x1 + m_iChooserWidth-10, y1 + m_iChooserHeight-10, a_iColor);
sge_Line(a_poBackground, x1 + m_iChooserWidth-10, y1+5, x1+5, y1 + m_iChooserHeight-10, a_iColor);
y1++;
sge_Line(a_poBackground, x1+5, y1+5, x1 + m_iChooserWidth-10, y1 + m_iChooserHeight-10, a_iColor);
sge_Line(a_poBackground, x1 + m_iChooserWidth-10, y1+5, x1+5, y1 + m_iChooserHeight-10, a_iColor);
x1--;
sge_Line(a_poBackground, x1+5, y1+5, x1 + m_iChooserWidth-10, y1 + m_iChooserHeight-10, a_iColor);
sge_Line(a_poBackground, x1 + m_iChooserWidth-10, y1+5, x1+5, y1 + m_iChooserHeight-10, a_iColor);
}
void PlayerSelect::DoPlayerSelect()
{
// 1. Set up: Load background, mark unavailable fighters
bool bNetworkMode = IsNetworkGame();
if ( bNetworkMode )
{
m_iChooserLeft = 158;
m_iChooserTop = 26;
m_iChooserHeight = 64;
m_iChooserWidth = 64;
m_iChooserRows = 4;
m_iChooserCols = 5;
}
else
{
m_iChooserLeft = 158;
m_iChooserTop = 74;
m_iChooserHeight = 80;
m_iChooserWidth = 80;
m_iChooserRows = 5;
m_iChooserCols = 4;
}
SDL_FillRect( gamescreen, NULL, C_BLACK );
SDL_Flip( gamescreen );
SDL_Surface* poBackground = LoadBackground( bNetworkMode ? "PlayerSelect_chat.png" : "PlayerSelect.png", 111 );
if ( !bNetworkMode )
{
DrawGradientText( "Choose A Fighter Dammit", titleFont, 10, poBackground );
}
//g_oChooser.Draw( poBackground );
int i, j;
for ( i=0; i<m_iChooserRows; ++i )
{
for ( int j=0; j<m_iChooserCols; ++j )
{
if ( bNetworkMode )
{
if ( !IsLocalFighterAvailable(ChooserCellsChat[i][j]) &&
UNKNOWN != ChooserCellsChat[i][j] )
{
CheckPlayer( poBackground, i, j, C_LIGHTRED );
}
else if ( !IsFighterAvailable(ChooserCellsChat[i][j]) &&
UNKNOWN != ChooserCellsChat[i][j] )
{
CheckPlayer( poBackground, i, j, C_LIGHTBLUE );
}
}
else
{
if ( !IsFighterAvailable(ChooserCells[i][j]) &&
UNKNOWN != ChooserCells[i][j] )
{
CheckPlayer( poBackground, i, j, C_LIGHTRED );
}
}
}
}
for ( i=0; i<2; ++i )
{
if ( m_aoPlayers[i].m_poPack ) m_aoPlayers[i].m_poPack->ApplyPalette();
}
SetPlayer( 0, GetFighterCell(m_iP1) );
SetPlayer( 1, GetFighterCell(m_iP2) );
if ( bNetworkMode && g_poNetwork->IsMaster() )
{
g_poNetwork->SendGameParams( g_oState.m_iGameSpeed, g_oState.m_iGameTime, g_oState.m_iHitPoints );
}
// 2. Run selection screen
g_oBackend.PerlEvalF( "SelectStart();" );
m_bDone1 = m_bDone2 = false;
int thisTick, lastTick, gameSpeed;
gameSpeed = 12 ;
thisTick = SDL_GetTicks() / gameSpeed;
lastTick = thisTick - 1;
i = 0;
int over = 0;
int iCourtain = 0;
int iCourtainSpeed = 0;
int iCourtainTime = 80;
SDL_Event event;
// Chat is 165:318 - 470:470
char acMsg[256];
sprintf( acMsg, "Press Enter to chat, Page Up/Page Down to scroll..." );
bool bDoingChat = false;
if ( bNetworkMode )
{
- m_poReadline = new CReadline( IsNetworkGame() ? poBackground : NULL, impactFont,
+ m_poReadline = new CReadline( IsNetworkGame() ? poBackground : NULL, chatFont,
acMsg, strlen(acMsg), 256, 15, 465, 610, C_LIGHTCYAN, C_BLACK, 255 );
- m_poTextArea = new CTextArea( poBackground, impactFont, 15, 313, 610, 32*4 );
+ m_poTextArea = new CTextArea( poBackground, chatFont, 15, 313, 610, 32*4 );
}
else
{
m_poReadline = NULL;
m_poTextArea = NULL;
}
while (1)
{
// 1. Wait for the next tick (on extremely fast machines..)
while (1)
{
thisTick = SDL_GetTicks() / gameSpeed;
if ( thisTick==lastTick )
{
SDL_Delay(1);
}
else
{
break;
}
}
// 2. Advance as many ticks as necessary..
if ( iCourtainTime > 0 )
{
int iAdvance = thisTick - lastTick;
if ( iAdvance > 5 ) iAdvance = 5;
if ( iCourtain + iCourtainSpeed * iCourtainTime /2 < 320 * 4 )
iCourtainSpeed += iAdvance;
else
iCourtainSpeed -= iAdvance;
iCourtain += iCourtainSpeed * iAdvance;
iCourtainTime -= iAdvance;
if ( iCourtainTime > 0 )
{
SDL_Rect oRect;
oRect.x = 320 - iCourtain/4; oRect.y = 0;
oRect.w = iCourtain / 2; oRect.h = gamescreen->h;
if ( oRect.x < 0 ) oRect.x = 0;
if ( oRect.w > gamescreen->w ) oRect.w = gamescreen->w;
SDL_SetClipRect( gamescreen, &oRect );
}
else
{
SDL_SetClipRect( gamescreen, NULL );
}
}
int iNumFrames = thisTick - lastTick;
if ( iNumFrames>5 ) iNumFrames = 5;
for ( i=0; i<iNumFrames; ++i )
{
g_oBackend.AdvancePerl();
}
lastTick = thisTick;
while (SDL_PollEvent(&event))
{
if ( SDL_QUIT == event.type )
{
g_oState.m_bQuitFlag = true;
break;
}
// HANDLE SCROLLING THE TEXT AREA
if ( event.type == SDL_KEYDOWN )
{
SDLKey enKey = event.key.keysym.sym;
if ( IsNetworkGame() )
{
if ( enKey == SDLK_PAGEUP || enKey == SDLK_KP9 )
{
m_poTextArea->ScrollUp();
continue;
}
if ( enKey == SDLK_PAGEDOWN || enKey == SDLK_KP3 )
{
m_poTextArea->ScrollDown();
continue;
}
}
}
// HANDLE CHATTING
if ( bDoingChat )
{
// The chat thingy will handle this event.
m_poReadline->HandleKeyEvent( event );
int iResult = m_poReadline->GetResult();
if ( iResult < 0 )
{
// Escape was pressed?
m_poReadline->Clear();
bDoingChat = false;
}
if ( iResult > 0 )
{
if ( strlen( acMsg ) )
{
g_poNetwork->SendMsg( acMsg );
- m_poTextArea->AddString( acMsg, C_LIGHTCYAN );
+ std::string sMsg = std::string("<") + g_oState.m_acNick + "> " + acMsg;
+ m_poTextArea->AddString( sMsg.c_str(), C_LIGHTCYAN );
m_poTextArea->Redraw();
m_poReadline->Clear();
acMsg[0] = 0;
m_poReadline->Restart( acMsg, strlen(acMsg), 256, C_LIGHTCYAN, C_BLACK, 255 );
}
else
{
m_poReadline->Clear();
bDoingChat = false;
}
}
continue;
}
// HANDLE OTHER TYPES OF KEYBOARD EVENTS
if ( event.type == SDL_KEYDOWN )
{
SDLKey enKey = event.key.keysym.sym;
if ( enKey == SDLK_ESCAPE )
{
- DoMenu( false );
+ DoMenu();
if ( IsNetworkGame() && g_poNetwork->IsMaster() )
{
g_poNetwork->SendGameParams( g_oState.m_iGameSpeed, g_oState.m_iGameTime, g_oState.m_iHitPoints );
}
break;
}
if ( IsNetworkGame() && bDoingChat == false &&
(event.key.keysym.sym == SDLK_RETURN
|| event.key.keysym.sym==SDLK_KP_ENTER) )
{
bDoingChat = true;
acMsg[0] = 0;
m_poReadline->Clear();
m_poReadline->Restart( acMsg, strlen(acMsg), 256, C_LIGHTCYAN, C_BLACK, 255 );
break;
}
for ( i=0; i<2; i++ )
{
for ( j=0; j<9; j++ )
{
if (g_oState.m_aiPlayerKeys[i][j] == event.key.keysym.sym)
{
DrawRect( m_iP1, 240 );
DrawRect( m_iP2, 240 );
HandleKey( i, j );
}
}
}
}
} // Polling events
if ( IsNetworkGame() )
{
HandleNetwork();
}
g_oBackend.ReadFromPerl();
over = g_oBackend.m_iGameOver;
SDL_BlitSurface( poBackground, NULL, gamescreen, NULL );
if ( !m_bDone1) DrawRect( m_iP1, 250 );
if ( !m_bDone2) DrawRect( m_iP2, 253 );
for ( i=0; i<2; ++i )
{
int iYOffset = bNetworkMode ? -130 : 0;
if ( g_oBackend.m_aoPlayers[i].m_iFrame )
{
m_aoPlayers[i].m_poPack->Draw(
ABS(g_oBackend.m_aoPlayers[i].m_iFrame)-1,
g_oBackend.m_aoPlayers[i].m_iX, g_oBackend.m_aoPlayers[i].m_iY + iYOffset,
g_oBackend.m_aoPlayers[i].m_iFrame < 0 );
}
int x = ( m_iChooserLeft - m_aiFighterNameWidth[i] ) / 2;
if ( x<10 ) x = 10;
if ( i ) x = gamescreen->w - x - m_aiFighterNameWidth[i];
sge_BF_textout( gamescreen, fastFont, GetFighterName(i),
x, gamescreen->h - 30 + iYOffset - (bNetworkMode ? 40 : 0) );
}
SDL_Flip( gamescreen );
if (over || g_oState.m_bQuitFlag || SState::IN_DEMO == g_oState.m_enGameMode) break;
}
delete m_poReadline;
delete m_poTextArea;
SDL_FreeSurface( poBackground );
SDL_SetClipRect( gamescreen, NULL );
return;
}
diff --git a/src/TextArea.cpp b/src/TextArea.cpp
index a440bd3..379cf1b 100644
--- a/src/TextArea.cpp
+++ b/src/TextArea.cpp
@@ -1,110 +1,166 @@
/***************************************************************************
TextArea.cpp - description
-------------------
begin : Wed Jan 28 2004
copyright : (C) 2004 by upi
email : upi@feel
***************************************************************************/
#include "TextArea.h"
#include "sge_surface.h"
#include "sge_tt_text.h"
+#include "sge_primitives.h"
#include "gfx.h"
#include "common.h"
+#include <ctype.h>
+
CTextArea::CTextArea( SDL_Surface* a_poScreen, _sge_TTFont* a_poFont, int a_x, int a_y, int a_w, int a_h )
{
m_poScreen = a_poScreen;
m_poFont = a_poFont;
m_iScrollOffset = 0;
m_oClipRect.x = x = a_x;
m_oClipRect.y = y = a_y;
m_oClipRect.w = w = a_w;
m_oClipRect.h = h = a_h;
m_poBackground = sge_copy_surface( a_poScreen, x, y, w, h );
}
CTextArea::~CTextArea()
{
SDL_FreeSurface( m_poBackground );
m_poBackground = NULL;
}
void CTextArea::Clear()
{
m_aiRowColors.clear();
m_asRowTexts.clear();
m_iScrollOffset = 0;
}
-void CTextArea::AddString( const char* a_poText, int a_iColor )
+void CTextArea::TintBackground( int a_iColor, int a_iAlpha )
{
- m_asRowTexts.push_front( a_poText );
- m_aiRowColors.push_front( a_iColor );
+ if ( NULL == m_poBackground )
+ {
+ return;
+ }
+ sge_FilledRectAlpha( m_poBackground, 0, 0, m_poBackground->w, m_poBackground->h, a_iColor, a_iAlpha );
+}
- debug( "Added '%s', number of texts is %d\n", a_poText, m_asRowTexts.size() );
+
+void CTextArea::AddString( const char* a_poText, int a_iColor )
+{
+ while ( a_poText && *a_poText )
+ {
+ // 1. FORMAT THE TEXT SO IT FITS US NICELY
+
+ SDL_Rect oRect;
+ int i, j;
+
+ for ( i=0; a_poText[i]; ++i )
+ {
+ oRect = sge_TTF_TextSize( m_poFont, a_poText, i );
+ if ( oRect.w > m_oClipRect.w )
+ {
+ break;
+ }
+ }
+
+ // i now points to the character AFTER the last good character.
+ //if ( a_poText[i] && i>1 ) --i;
+
+ // Trace back to the first space BEFORE i
+ if ( a_poText[i] )
+ {
+ for ( j = i; j>0; --j )
+ {
+ if ( isspace( a_poText[j] ) )
+ {
+ break;
+ }
+ }
+ if ( j>0 )
+ {
+ i = j;
+ }
+ }
+
+ // 2. ADD IT.
+
+ m_asRowTexts.push_front( std::string(a_poText,i) );
+ m_aiRowColors.push_front( a_iColor );
+
+ a_poText += i;
+
+ debug( "Added '%s', number of texts is %d\n", a_poText, m_asRowTexts.size() );
+ }
}
void CTextArea::ScrollUp()
{
- if ( m_iScrollOffset < (int) m_asRowTexts.size() - 1 )
+ if ( m_iScrollOffset < (int) m_asRowTexts.size() - h / sge_TTF_FontHeight(m_poFont) )
{
++m_iScrollOffset;
Redraw();
}
}
void CTextArea::ScrollDown()
{
if ( m_iScrollOffset > 0 )
{
--m_iScrollOffset;
Redraw();
}
}
void CTextArea::Redraw()
{
TStringList::const_iterator itString = m_asRowTexts.begin();
TIntList::const_iterator itColors = m_aiRowColors.begin();
for ( int i=0; i<m_iScrollOffset; ++i )
{
++itString;
++itColors;
}
SDL_Rect oOldClipRect;
SDL_GetClipRect( m_poScreen, &oOldClipRect );
SDL_SetClipRect( m_poScreen, &m_oClipRect );
+ sge_TTF_AAOn();
sge_Blit( m_poBackground, m_poScreen, 0, 0, x, y, w, h );
+
+ int iRows = h / sge_TTF_FontHeight( m_poFont );
+ int yPos = y + (iRows-1) * sge_TTF_FontHeight( m_poFont );
- for ( int yPos = y + h - sge_TTF_FontHeight( m_poFont );
- yPos >= y /*+ sge_TTF_FontAscent( m_poFont )*/;
- yPos -= sge_TTF_FontHeight( m_poFont ) )
+ for ( ; yPos >= y; yPos -= sge_TTF_FontHeight( m_poFont ) )
{
if ( itColors == m_aiRowColors.end() )
{
break;
}
// Print the current text
sge_tt_textout( m_poScreen, m_poFont, itString->c_str(), x, yPos + sge_TTF_FontAscent(m_poFont), *itColors, C_BLACK, 255 );
++itString;
++itColors;
}
-
+
sge_UpdateRect( m_poScreen, x, y, w, h );
SDL_SetClipRect( m_poScreen, &oOldClipRect );
+ sge_TTF_AAOff();
}
diff --git a/src/TextArea.h b/src/TextArea.h
index ffcdba4..e6c64d5 100644
--- a/src/TextArea.h
+++ b/src/TextArea.h
@@ -1,50 +1,51 @@
/***************************************************************************
TextArea.h - description
-------------------
begin : Wed Jan 28 2004
copyright : (C) 2004 by upi
email : upi@feel
***************************************************************************/
#ifndef TEXTAREA_H
#define TEXTAREA_H
#include "SDL_video.h"
struct SDL_Surface;
struct _sge_TTFont;
#include <string>
#include <list>
typedef std::list<std::string> TStringList;
typedef std::list<int> TIntList;
class CTextArea
{
public:
CTextArea( SDL_Surface* a_poScreen, _sge_TTFont* a_poFont, int a_x, int a_y, int a_w, int a_h );
~CTextArea();
-
+
+ void TintBackground( int a_iColor, int a_iAlpha );
void AddString( const char* a_poText, int a_iColor );
void Redraw();
void Clear();
void ScrollUp();
void ScrollDown();
protected:
SDL_Surface* m_poScreen;
SDL_Surface* m_poBackground;
_sge_TTFont* m_poFont;
SDL_Rect m_oClipRect;
int x, y, w, h;
int m_iScrollOffset;
TStringList m_asRowTexts;
TIntList m_aiRowColors;
};
#endif // TEXTAREA_H
diff --git a/src/gfx.h b/src/gfx.h
index bbe2eae..60d768d 100644
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -1,50 +1,51 @@
/***************************************************************************
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, 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
+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
diff --git a/src/sge_tt_text.cpp b/src/sge_tt_text.cpp
index 61dce6a..e2f6748 100644
--- a/src/sge_tt_text.cpp
+++ b/src/sge_tt_text.cpp
@@ -1,1760 +1,1777 @@
/*
* SDL Graphics Extension
* Text/TrueType font functions
*
* Started 990815
*
* License: LGPL v2+ (see the file LICENSE)
* (c)1999-2001 Anders Lindstr?m
*
* Uses the excellent FreeType 2 library, available at:
* http://www.freetype.org/
*/
/*********************************************************************
* 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. *
*********************************************************************/
/*
* Most of this code is taken from the SDL ttf lib by Sam Lantinga
* <slouken@devolution.com>
*/
#include "SDL.h"
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
#include "sge_surface.h"
#include "sge_primitives.h"
#include "sge_tt_text.h"
#ifndef _SGE_NOTTF
#include <ft2build.h>
#include <freetype/freetype.h>
#include <freetype/ftoutln.h>
#include <freetype/ttnameid.h>
/* The structure used to hold glyph information (cached) */
struct glyph {
int stored;
FT_UInt index;
//FT_Bitmap bitmap;
FT_Bitmap pixmap;
int minx;
int maxx;
int miny;
int maxy;
int yoffset;
int advance;
Uint16 cached;
};
/* the truetype font structure */
struct _sge_TTFont{
FT_Face face;
/* Font metrics */
int height;
int ascent;
int descent;
int lineskip;
/* The font style */
Uint8 style;
/* Extra width in glyph bounds for text styles */
int glyph_overhang;
float glyph_italics;
/* Information in the font for underlining */
int underline_offset;
int underline_height;
/* For now, support Latin-1 character set caching */
glyph *current;
glyph cache[256];
glyph scratch;
};
/* Macro to convert a character to a Unicode value -- assume already Unicode */
//Should really make a proper convert algorithm someday
#define UNICODE(c) c
/* FIXME: Right now we assume the gray-scale renderer Freetype is using
supports 256 shades of gray, but we should instead key off of num_grays
in the result FT_Bitmap after the FT_Render_Glyph() call. */
#define NUM_GRAYS 256
/* Handy routines for converting from fixed point */
#define FT_FLOOR(X) ((X & -64) / 64)
#define FT_CEIL(X) (((X + 63) & -64) / 64)
#define CACHED_METRICS 0x10
#define CACHED_BITMAP 0x01
#define CACHED_PIXMAP 0x02
/* The FreeType font engine/library */
static FT_Library _sge_library;
static int _sge_TTF_initialized = 0;
Uint8 _sge_TTF_AA=1; //Rendering mode: 0-OFF, 1-AA, 2-Alpha
/**********************************************************************************/
/** Open/misc font functions **/
/**********************************************************************************/
//==================================================================================
// Turns TTF AntiAliasing On/Off or alpha (nice but slow) (Default: On)
//==================================================================================
void sge_TTF_AAOff(void)
{
_sge_TTF_AA=0;
}
void sge_TTF_AAOn(void)
{
_sge_TTF_AA=1;
}
void sge_TTF_AA_Alpha(void)
{
_sge_TTF_AA=2;
}
//==================================================================================
// Closes the ttf engine, done by exit
//==================================================================================
void sge_TTF_Quit(void)
{
if ( _sge_TTF_initialized ) {
FT_Done_FreeType( _sge_library );
}
_sge_TTF_initialized = 0;
}
//==================================================================================
// Starts the ttf engine, must be called first
//==================================================================================
int sge_TTF_Init(void)
{
FT_Error error;
error = FT_Init_FreeType( &_sge_library );
if ( error ) {
SDL_SetError("SGE - Couldn't init FreeType engine");
return(-1);
} else {
_sge_TTF_initialized = 1;
}
atexit(sge_TTF_Quit); //dont't trust the user...
return(0);
}
//==================================================================================
// Some helper functions
//==================================================================================
void Flush_Glyph(glyph *glyph)
{
glyph->stored = 0;
glyph->index = 0;
//if( glyph->bitmap.buffer ) {
// free( glyph->bitmap.buffer );
// glyph->bitmap.buffer = 0;
//}
if( glyph->pixmap.buffer ) {
free( glyph->pixmap.buffer );
glyph->pixmap.buffer = 0;
}
glyph->cached = 0;
}
void Flush_Cache(sge_TTFont *font)
{
int i;
int size = sizeof( font->cache ) / sizeof( font->cache[0] );
for( i = 0; i < size; ++i ) {
if( font->cache[i].cached ) {
Flush_Glyph( &font->cache[i] );
}
}
if( font->scratch.cached ) {
Flush_Glyph( &font->scratch );
}
}
//==================================================================================
// Remove font from memory
//==================================================================================
void sge_TTF_CloseFont(sge_TTFont *font)
{
Flush_Cache( font );
FT_Done_Face( font->face );
free( font );
}
//==================================================================================
// Open the TT font file and returns the font with pt size
//==================================================================================
sge_TTFont *sge_TTF_OpenFont(const char *file, int ptsize)
{
sge_TTFont *font;
FT_Error error;
FT_Face face;
FT_Fixed scale;
font = (sge_TTFont *)malloc(sizeof(*font));
if ( font == NULL ) {
SDL_SetError("SGE - Out of memory");
return(NULL);
}
memset(font, 0, sizeof(*font));
/* Open the font and create ancillary data */
error = FT_New_Face( _sge_library, file, 0, &font->face );
if ( error ) {
sge_SetError("SGE - Couldn't load font file: %s",file);
free(font);
return(NULL);
}
face = font->face;
/* Make sure that our font face is scalable (global metrics) */
if ( ! FT_IS_SCALABLE(face) ) {
sge_SetError("SGE - Font face is not scalable: %s",file);
sge_TTF_CloseFont( font );
return NULL;
}
/* Set the character size and use 96 DPI */
error = FT_Set_Char_Size( font->face, 0, ptsize * 64, 96, 96 );
//error = FT_Set_Pixel_Sizes( font->face, 0, ptsize );
if( error ) {
sge_SetError("SGE - Couldn't set font size: %s",file);
sge_TTF_CloseFont( font );
return NULL;
}
/* Get the scalable font metrics for this font */
scale = face->size->metrics.y_scale;
font->ascent = FT_CEIL(FT_MulFix(face->bbox.yMax, scale));
font->descent = FT_CEIL(FT_MulFix(face->bbox.yMin, scale));
font->height = font->ascent - font->descent + /* baseline */ 1;
font->lineskip = FT_CEIL(FT_MulFix(face->height, scale));
font->underline_offset = FT_FLOOR(FT_MulFix(face->underline_position, scale));
font->underline_height = FT_FLOOR(FT_MulFix(face->underline_thickness, scale));
if ( font->underline_height < 1 ) {
font->underline_height = 1;
}
/* Set the default font style */
font->style = SGE_TTF_NORMAL;
font->glyph_overhang = face->size->metrics.y_ppem / 10;
/* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */
font->glyph_italics = 0.207f;
font->glyph_italics *= font->height;
return font;
}
//==================================================================================
// Load a glyph
//==================================================================================
FT_Error Load_Glyph(sge_TTFont *font, Uint16 ch, glyph *cached, int want )
{
FT_Face face;
FT_Error error;
FT_GlyphSlot glyph;
FT_Glyph_Metrics* metrics;
FT_Outline* outline;
//assert( font );
//assert( font->face );
face = font->face;
/* Load the glyph */
if ( ! cached->index ) {
cached->index = FT_Get_Char_Index( face, ch );
}
error = FT_Load_Glyph( face, cached->index, FT_LOAD_DEFAULT );
if( error ) {
return error;
}
/* Get our glyph shortcuts */
glyph = face->glyph;
metrics = &glyph->metrics;
outline = &glyph->outline;
/* Get the glyph metrics if desired */
if ( (want & CACHED_METRICS) && !(cached->stored & CACHED_METRICS) ) {
/* Get the bounding box */
cached->minx = FT_FLOOR(metrics->horiBearingX);
cached->maxx = cached->minx + FT_CEIL(metrics->width);
cached->maxy = FT_FLOOR(metrics->horiBearingY);
cached->miny = cached->maxy - FT_CEIL(metrics->height);
cached->yoffset = font->ascent - cached->maxy;
cached->advance = FT_CEIL(metrics->horiAdvance);
/* Adjust for bold and italic text */
if ( font->style & SGE_TTF_BOLD ) {
cached->maxx += font->glyph_overhang;
}
if ( font->style & SGE_TTF_ITALIC ) {
cached->maxx += (int)ceil(font->glyph_italics);
}
cached->stored |= CACHED_METRICS;
}
if ( ((want & CACHED_BITMAP) && !(cached->stored & CACHED_BITMAP)) ||
((want & CACHED_PIXMAP) && !(cached->stored & CACHED_PIXMAP)) ) {
//int mono = (want & CACHED_BITMAP);
int i;
FT_Bitmap* src;
FT_Bitmap* dst;
/* Handle the italic style */
if( font->style & SGE_TTF_ITALIC ) {
FT_Matrix shear;
shear.xx = 1 << 16;
shear.xy = (int) ( font->glyph_italics * ( 1 << 16 ) ) / font->height;
shear.yx = 0;
shear.yy = 1 << 16;
FT_Outline_Transform( outline, &shear );
}
/* Render the glyph */
//if ( mono ) {
// error = FT_Render_Glyph( glyph, ft_render_mode_mono );
//} else {
error = FT_Render_Glyph( glyph, ft_render_mode_normal );
//}
if( error ) {
return error;
}
/* Copy over information to cache */
src = &glyph->bitmap;
//if ( mono ) {
// dst = &cached->bitmap;
//} else {
dst = &cached->pixmap;
//}
memcpy( dst, src, sizeof( *dst ) );
//if ( mono ) {
// dst->pitch *= 8;
//}
/* Adjust for bold and italic text */
if( font->style & SGE_TTF_BOLD ) {
int bump = font->glyph_overhang;
dst->pitch += bump;
dst->width += bump;
}
if( font->style & SGE_TTF_ITALIC ) {
int bump = (int)ceil(font->glyph_italics);
dst->pitch += bump;
dst->width += bump;
}
dst->buffer = (unsigned char *)malloc( dst->pitch * dst->rows );
if( !dst->buffer ) {
return FT_Err_Out_Of_Memory;
}
memset( dst->buffer, 0, dst->pitch * dst->rows );
for( i = 0; i < src->rows; i++ ) {
int soffset = i * src->pitch;
int doffset = i * dst->pitch;
/*if ( mono ) {
unsigned char *srcp = src->buffer + soffset;
unsigned char *dstp = dst->buffer + doffset;
int j;
for ( j = 0; j < src->width; j += 8 ) {
unsigned char ch = *srcp++;
*dstp++ = (ch&0x80) >> 7;
ch <<= 1;
*dstp++ = (ch&0x80) >> 7;
ch <<= 1;
*dstp++ = (ch&0x80) >> 7;
ch <<= 1;
*dstp++ = (ch&0x80) >> 7;
ch <<= 1;
*dstp++ = (ch&0x80) >> 7;
ch <<= 1;
*dstp++ = (ch&0x80) >> 7;
ch <<= 1;
*dstp++ = (ch&0x80) >> 7;
ch <<= 1;
*dstp++ = (ch&0x80) >> 7;
}
} else {*/
memcpy(dst->buffer+doffset,
src->buffer+soffset, src->pitch);
//}
}
/* Handle the bold style */
if ( font->style & SGE_TTF_BOLD ) {
int row;
int col;
int offset;
int pixel;
Uint8* pixmap;
/* The pixmap is a little hard, we have to add and clamp */
for( row = dst->rows - 1; row >= 0; --row ) {
pixmap = (Uint8*) dst->buffer + row * dst->pitch;
for( offset=1; offset <= font->glyph_overhang; ++offset ) {
for( col = dst->width - 1; col > 0; --col ) {
pixel = (pixmap[col] + pixmap[col-1]);
if( pixel > NUM_GRAYS - 1 ) {
pixel = NUM_GRAYS - 1;
}
pixmap[col] = (Uint8) pixel;
}
}
}
}
/* Mark that we rendered this format */
//if ( mono ) {
// cached->stored |= CACHED_BITMAP;
//} else {
cached->stored |= CACHED_PIXMAP;
//}
}
/* We're done, mark this glyph cached */
cached->cached = ch;
return 0;
}
//==================================================================================
// Find glyph
//==================================================================================
FT_Error Find_Glyph(sge_TTFont *font, Uint16 ch, int want)
{
int retval = 0;
if( ch < 256 ) {
font->current = &font->cache[ch];
} else {
if ( font->scratch.cached != ch ) {
Flush_Glyph( &font->scratch );
}
font->current = &font->scratch;
}
if ( (font->current->stored & want) != want ) {
retval = Load_Glyph( font, ch, font->current, want );
}
return retval;
}
//==================================================================================
// Change the size of font
//==================================================================================
int sge_TTF_SetFontSize(sge_TTFont *font, int ptsize)
{
FT_Error error;
FT_Fixed scale;
FT_Face face;
/* Set the character size and use 96 DPI */
error = FT_Set_Char_Size( font->face, 0, ptsize * 64, 96, 96 );
//error = FT_Set_Pixel_Sizes( font->face, 0, ptsize );
if( error ) {
sge_SetError("SGE - Couldn't set font size");
sge_TTF_CloseFont( font );
return -1;
}
Flush_Cache(font);
face = font->face;
/* Get the scalable font metrics for this font */
scale = face->size->metrics.y_scale;
font->ascent = FT_CEIL(FT_MulFix(face->bbox.yMax, scale));
font->descent = FT_CEIL(FT_MulFix(face->bbox.yMin, scale));
font->height = font->ascent - font->descent + /* baseline */ 1;
font->lineskip = FT_CEIL(FT_MulFix(face->height, scale));
font->underline_offset = FT_FLOOR(FT_MulFix(face->underline_position, scale));
font->underline_height = FT_FLOOR(FT_MulFix(face->underline_thickness, scale));
if ( font->underline_height < 1 ) {
font->underline_height = 1;
}
/* Set the default font style */
//font->style = SGE_TTF_NORMAL;
font->glyph_overhang = face->size->metrics.y_ppem / 10;
/* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */
font->glyph_italics = 0.207f;
font->glyph_italics *= font->height;
return 0;
}
//==================================================================================
// Get font geometrics
//==================================================================================
int sge_TTF_FontHeight(sge_TTFont *font)
{
return(font->height);
}
int sge_TTF_FontAscent(sge_TTFont *font)
{
return(font->ascent);
}
int sge_TTF_FontDescent(sge_TTFont *font)
{
return(font->descent);
}
int sge_TTF_FontLineSkip(sge_TTFont *font)
{
return(font->lineskip);
}
int sge_TTF_GlyphMetrics(sge_TTFont *font, Uint16 ch, int* minx, int* maxx, int* miny, int* maxy, int* advance)
{
FT_Error error;
error = Find_Glyph(font, ch, CACHED_METRICS);
if ( error ) {
return -1;
}
if ( minx ) {
*minx = font->current->minx;
}
if ( maxx ) {
*maxx = font->current->maxx;
}
if ( miny ) {
*miny = font->current->miny;
}
if ( maxy ) {
*maxy = font->current->maxy;
}
if ( advance ) {
*advance = font->current->advance;
}
return 0;
}
//==================================================================================
// Set font style
//==================================================================================
void sge_TTF_SetFontStyle(sge_TTFont *font, Uint8 style)
{
font->style = style;
Flush_Cache(font);
}
//==================================================================================
// Get font style
//==================================================================================
Uint8 sge_TTF_GetFontStyle(sge_TTFont *font)
{
return(font->style);
}
#endif /* _SGE_NOTTF */
//==================================================================================
// Convert the Latin-1 text to UNICODE
//==================================================================================
Uint16 *ASCII_to_UNICODE(Uint16 *unicode, const char *text, int len)
{
int i;
for ( i=0; i < len; ++i ) {
unicode[i] = ((const unsigned char *)text)[i];
}
unicode[i] = 0;
return unicode;
}
Uint16 *sge_Latin1_Uni(const char *text)
{
Uint16 *unicode_text;
int i, unicode_len;
/* Copy the Latin-1 text to a UNICODE text buffer */
unicode_len = strlen(text);
unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text));
if ( unicode_text == NULL ) {
SDL_SetError("SGE - Out of memory");
return(NULL);
}
for ( i=0; i < unicode_len; ++i ) {
unicode_text[i] = ((const unsigned char *)text)[i];
}
unicode_text[i] = 0;
return(unicode_text);
}
//==================================================================================
// Convert the UTF-8 text to UNICODE
//==================================================================================
Uint16 *UTF8_to_UNICODE(Uint16 *unicode, const char *utf8, int len)
{
int i, j;
Uint16 ch;
for ( i=0, j=0; i < len; ++i, ++j ) {
ch = ((const unsigned char *)utf8)[i];
if ( ch >= 0xF0 ) {
ch = (Uint16)(utf8[i]&0x07) << 18;
ch |= (Uint16)(utf8[++i]&0x3F) << 12;
ch |= (Uint16)(utf8[++i]&0x3F) << 6;
ch |= (Uint16)(utf8[++i]&0x3F);
} else
if ( ch >= 0xE0 ) {
ch = (Uint16)(utf8[i]&0x3F) << 12;
ch |= (Uint16)(utf8[++i]&0x3F) << 6;
ch |= (Uint16)(utf8[++i]&0x3F);
} else
if ( ch >= 0xC0 ) {
ch = (Uint16)(utf8[i]&0x3F) << 6;
ch |= (Uint16)(utf8[++i]&0x3F);
}
unicode[j] = ch;
}
unicode[j] = 0;
return unicode;
}
Uint16 *sge_UTF8_Uni(const char *text)
{
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 *unicode_text));
if ( unicode_text == NULL ) {
SDL_SetError("SGE - Out of memory");
return(NULL);
}
return UTF8_to_UNICODE(unicode_text, text, unicode_len);
}
#ifndef _SGE_NOTTF
//==================================================================================
// Get the width of the text with the given font
//==================================================================================
SDL_Rect sge_TTF_TextSizeUNI(sge_TTFont *font, const Uint16 *text)
{
SDL_Rect ret; ret.x=0; ret.y=0, ret.w=0, ret.h=0;
const Uint16 *ch;
int x, z;
int minx, maxx;
int miny, maxy;
glyph *glyph;
FT_Error error;
/* Initialize everything to 0 */
if ( ! _sge_TTF_initialized ) {
return ret;
}
minx = miny = 0;
maxx = maxy = 0;
/* Load each character and sum it's bounding box */
x= 0;
for ( ch=text; *ch; ++ch ) {
error = Find_Glyph(font, *ch, CACHED_METRICS);
if ( error ) {
return ret;
}
glyph = font->current;
z = x + glyph->minx;
if ( minx > z ) {
minx = z;
}
if ( font->style & SGE_TTF_BOLD ) {
x += font->glyph_overhang;
}
if ( glyph->advance > glyph->maxx ) {
z = x + glyph->advance;
} else {
z = x + glyph->maxx;
}
if ( maxx < z ) {
maxx = z;
}
x += glyph->advance;
if ( glyph->miny < miny ) {
miny = glyph->miny;
}
if ( glyph->maxy > maxy ) {
maxy = glyph->maxy;
}
}
/* Fill the bounds rectangle */
ret.w = (maxx - minx);
//ret.h = (maxy - miny); /* This is correct, but breaks many applications */
ret.h = font->height;
return ret;
}
-SDL_Rect sge_TTF_TextSize(sge_TTFont *font, const char *text)
+SDL_Rect sge_TTF_TextSize(sge_TTFont *font, const char *text, int a_iMaxLength)
{
SDL_Rect ret; ret.x=ret.y=ret.w=ret.y=0;
Uint16 *unicode_text;
int unicode_len;
/* Copy the Latin-1 text to a UNICODE text buffer */
unicode_len = strlen(text);
+ if ( unicode_len > a_iMaxLength
+ && a_iMaxLength>=0 )
+ {
+ unicode_len = a_iMaxLength;
+ }
unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text));
if ( unicode_text == NULL ) {
SDL_SetError("SGE - Out of memory");
return ret;
}
- ASCII_to_UNICODE(unicode_text, text, unicode_len);
-
+ ASCII_to_UNICODE( unicode_text, text, unicode_len );
+
/* Render the new text */
ret = sge_TTF_TextSizeUNI(font, unicode_text);
/* Free the text buffer and return */
free(unicode_text);
return ret;
}
/**********************************************************************************/
/** TTF output functions **/
/**********************************************************************************/
//==================================================================================
// TT Render (unicode)
// Returns an 8bit or 32bit(8/8/8/8-alpha) surface with TT text
//==================================================================================
SDL_Surface *sge_TTF_RenderUNICODE(sge_TTFont *font,const Uint16 *text, SDL_Color fg, SDL_Color bg)
{
int xstart, width;
int w, h;
SDL_Surface *textbuf;
SDL_Palette *palette;
int index;
int rdiff, gdiff, bdiff;
const Uint16 *ch;
Uint8 *src, *dst;
Uint32 *dst32;
Uint32 alpha=0;
Uint32 pixel=0;
Uint32 Rmask=0, Gmask=0, Bmask=0, Amask=0;
int row, col;
FT_Error error;
/* Get the dimensions of the text surface */
SDL_Rect ret=sge_TTF_TextSizeUNI(font, text);
w=ret.w; h=ret.h;
if ( !w ) {
SDL_SetError("SGE - Text has zero width");
return(NULL);
}
/* Create the target surface */
width = w;
if(_sge_TTF_AA!=2) /* Allocate an 8-bit pixmap */
textbuf = SDL_AllocSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0);
else{ /* Allocate an 32-bit alpha pixmap */
if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {
Rmask = 0x000000FF;
Gmask = 0x0000FF00;
Bmask = 0x00FF0000;
Amask = 0xFF000000;
} else {
Rmask = 0xFF000000;
Gmask = 0x00FF0000;
Bmask = 0x0000FF00;
Amask = 0x000000FF;
}
textbuf = SDL_AllocSurface(SDL_SWSURFACE, w, h, 32, Rmask, Gmask, Bmask, Amask);
}
if ( textbuf == NULL ) {
SDL_SetError("SGE - Out of memory");
return(NULL);
}
/* Setup our colors */
switch(_sge_TTF_AA){
case 0:{ /* No fancy antialiasing or alpha component */
palette = textbuf->format->palette;
palette->colors[0].r = bg.r;
palette->colors[0].g = bg.g;
palette->colors[0].b = bg.b;
palette->colors[1].r = fg.r;
palette->colors[1].g = fg.g;
palette->colors[1].b = fg.b;
}
break;
case 1:{ /* Fill the palette with NUM_GRAYS levels of shading from bg to fg */
palette = textbuf->format->palette;
rdiff = fg.r - bg.r;
gdiff = fg.g - bg.g;
bdiff = fg.b - bg.b;
for ( index=0; index< NUM_GRAYS; ++index ) {
palette->colors[index].r = bg.r + (index*rdiff)/(NUM_GRAYS-1);
palette->colors[index].g = bg.g + (index*gdiff)/(NUM_GRAYS-1);
palette->colors[index].b = bg.b + (index*bdiff)/(NUM_GRAYS-1);
}
}
break;
case 2:{ /* Alpha component magic */
sge_ClearSurface(textbuf, SDL_MapRGBA(textbuf->format, bg.r,bg.g,bg.b,SDL_ALPHA_TRANSPARENT));
//pixel = (fg.r<<16)|(fg.g<<8)|fg.b;
pixel = (fg.b<<16)|(fg.g<<8)|fg.r;
}
break;
}
/* Load and render each character */
xstart = 0;
for ( ch=text; *ch; ++ch ) {
error = Find_Glyph(font, *ch, CACHED_METRICS|CACHED_PIXMAP);
if ( ! error ) {
w = font->current->pixmap.width;
src = (Uint8 *)font->current->pixmap.buffer;
for ( row = 0; row < font->current->pixmap.rows; ++row ) {
dst = (Uint8 *)textbuf->pixels + (row + font->current->yoffset)* textbuf->pitch + xstart + font->current->minx;
switch(_sge_TTF_AA){
case 0:{ /* Normal */
src = font->current->pixmap.buffer + row * font->current->pixmap.pitch;
for ( col=w; col>0; --col ) {
*dst++ |= (*src++<NUM_GRAYS/2)? 0:1;
}
}
break;
case 1:{ /* Antialiasing */
src = font->current->pixmap.buffer + row * font->current->pixmap.pitch;
for ( col=w; col>0; --col ) {
*dst++ |= *src++;
}
}
break;
case 2:{ /* Alpha */
dst32 = (Uint32 *)textbuf->pixels + (row + font->current->yoffset)* textbuf->pitch/4 + xstart + font->current->minx;
for ( col=w; col>0; --col ) {
alpha = *src++;
*dst32++ |= pixel | (alpha << 24);
}
}
break;
}
}
xstart += font->current->advance;
if ( font->style & SGE_TTF_BOLD ) {
xstart += font->glyph_overhang;
}
}
}
/* Handle the underline style */
if ( font->style & SGE_TTF_UNDERLINE ) {
int row_offset;
row_offset = font->ascent - font->underline_offset - 1;
if ( row_offset > textbuf->h ) {
row_offset = (textbuf->h-1) - font->underline_height;
}
if(_sge_TTF_AA==0){
dst = (Uint8 *)textbuf->pixels + row_offset * textbuf->pitch;
for ( row=font->underline_height; row>0; --row ) {
memset(dst, 1, textbuf->w );
dst += textbuf->pitch;
}
}else if(_sge_TTF_AA==1){
dst = (Uint8 *)textbuf->pixels + row_offset * textbuf->pitch;
for ( row=font->underline_height; row>0; --row ) {
memset(dst, NUM_GRAYS - 1, textbuf->w );
dst += textbuf->pitch;
}
}else{
pixel |= Amask;
dst32 = (Uint32 *)textbuf->pixels+row_offset*textbuf->pitch/4;
for ( row=font->underline_height; row>0; --row ) {
for ( col=0; col < textbuf->w; ++col ) {
dst32[col] = pixel;
}
dst32 += textbuf->pitch/4;
}
}
}
return(textbuf);
}
//==================================================================================
// Renders the Unicode string to TrueType on surface, with the color fcolor.
// bcolor is the target color for the antialiasing.
// Alpha sets the transparency of the text (255-solid, 0-max).
//==================================================================================
SDL_Rect sge_tt_textout_UNI(SDL_Surface *Surface, sge_TTFont *font, const Uint16 *uni, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha)
{
SDL_Rect ret; ret.x=0; ret.y=0; ret.w=0; ret.h=0;
SDL_Color temp;
SDL_Surface *text;
text=sge_TTF_RenderUNICODE(font,uni,sge_GetRGB(Surface,fcolor),sge_GetRGB(Surface,bcolor));
if(text==NULL){return ret;}
/* Align the surface text to the baseline */
Uint16 ascent=font->ascent;
temp=sge_GetRGB(Surface,bcolor);
sge_BlitTransparent(text,Surface,0,0,x,y-ascent,text->w,text->h,SDL_MapRGB(text->format,temp.r,temp.g,temp.b),Alpha);
sge_UpdateRect(Surface,x,y-ascent,text->w,text->h);
ret.x=x; ret.y=y-ascent; ret.w=text->w; ret.h=text->h;
SDL_FreeSurface(text);
return ret;
}
//==================================================================================
// Renders the Unicode string to TrueType on surface, with the color fcolor.
// bcolor is the target color for the antialiasing.
// Alpha sets the transparency of the text (0-solid, 255-max). (RGB)
//==================================================================================
SDL_Rect sge_tt_textout_UNI(SDL_Surface *Surface, sge_TTFont *font, const Uint16 *uni, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha)
{
SDL_Rect ret; ret.x=0; ret.y=0; ret.w=0; ret.h=0;
SDL_Surface *text;
text=sge_TTF_RenderUNICODE(font,uni,sge_FillPaletteEntry(fR,fG,fB),sge_FillPaletteEntry(bR,bG,bB));
if(text==NULL){return ret;}
/* Align the surface text to the baseline */
Uint16 ascent=font->ascent;
sge_BlitTransparent(text,Surface,0,0,x,y-ascent,text->w,text->h,SDL_MapRGB(text->format,bR,bG,bB),Alpha);
sge_UpdateRect(Surface,x,y-ascent,text->w,text->h);
ret.x=x; ret.y=y-ascent; ret.w=text->w; ret.h=text->h;
SDL_FreeSurface(text);
return ret;
}
//==================================================================================
// Renders the Latin-1 string to TrueType on surface, with the color fcolor.
// bcolor is the target color for the antialiasing.
// Alpha sets the transparency of the text (0-solid, 255-max).
//==================================================================================
SDL_Rect sge_tt_textout(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha)
{
SDL_Rect ret;
Uint16 *uni;
uni=sge_Latin1_Uni(string);
ret=sge_tt_textout_UNI(Surface,font,uni,x,y,fcolor,bcolor,Alpha);
free(uni);
return ret;
}
//==================================================================================
// Renders the Latin-1 string to TrueType on surface, with the color fcolor.
// bcolor is the target color for the antialiasing.
// Alpha sets the transparency of the text (0-solid, 255-max). (RGB)
//==================================================================================
SDL_Rect sge_tt_textout(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha)
{
SDL_Rect ret;
Uint16 *uni;
uni=sge_Latin1_Uni(string);
ret=sge_tt_textout_UNI(Surface,font,uni,x,y, fR,fG,fB, bR,bG,bB, Alpha);
free(uni);
return ret;
}
//==================================================================================
// Renders the UTF-8 string to TrueType on surface, with the color fcolor.
// bcolor is the target color for the antialiasing.
// Alpha sets the transparency of the text (0-solid, 255-max).
//==================================================================================
SDL_Rect sge_tt_textout_UTF8(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha)
{
SDL_Rect ret;
Uint16 *uni;
uni=sge_UTF8_Uni(string);
ret=sge_tt_textout_UNI(Surface,font,uni,x,y,fcolor,bcolor,Alpha);
free(uni);
return ret;
}
//==================================================================================
// Renders the UTF-8 string to TrueType on surface, with the color fcolor.
// bcolor is the target color for the antialiasing.
// Alpha sets the transparency of the text (0-solid, 255-max). (RGB)
//==================================================================================
SDL_Rect sge_tt_textout_UTF8(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha)
{
SDL_Rect ret;
Uint16 *uni;
uni=sge_UTF8_Uni(string);
ret=sge_tt_textout_UNI(Surface,font,uni,x,y, fR,fG,fB, bR,bG,bB, Alpha);
free(uni);
return ret;
}
//==================================================================================
// Renders the formatet Latin-1 string to TrueType on surface, with the color fcolor.
// bcolor is the target color for the antialiasing.
// Alpha sets the transparency of the text (0-solid, 255-max). (RGB ONLY)
// * just like printf(char *format,...) *
//==================================================================================
SDL_Rect sge_tt_textoutf(SDL_Surface *Surface, sge_TTFont *font, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha ,const char *format,...)
{
char buf[256];
va_list ap;
#ifdef __WIN32__
va_start((va_list*)ap, format); //Stupid win32 crosscompiler
#else
va_start(ap, format);
#endif
vsprintf(buf, format, ap);
va_end(ap);
return sge_tt_textout(Surface, font, buf, x,y, fR,fG,fB, bR,bG,bB, Alpha);
}
/**********************************************************************************/
/** TTF 'input' functions **/
/**********************************************************************************/
// First some internel functions for TTF input
//==================================================================================
// Fast update function for TTF input
//
// type=0 - in ret smaller then out ret
// type=1 - in ret bigger then out ret
// type=3 - safe
//==================================================================================
SDL_Rect fast_update(SDL_Surface *Surface,SDL_Surface *buffer,SDL_Rect ret, int type,sge_TTFont *font,Uint16 *string, Sint16 x,Sint16 y, Uint32 fcol, Uint32 bcol,int Alpha)
{
if(type==0){
sge_Update_OFF();
sge_FilledRect(Surface, ret.x, ret.y, ret.x+ret.w, ret.y+ret.h, bcol);
ret=sge_tt_textout_UNI(Surface,font,string, x,y, fcol, bcol, 0);
sge_Update_ON();
sge_UpdateRect(Surface, ret.x, ret.y, ret.w, ret.h);
}
else if(type==1){
SDL_Rect temp;
sge_Update_OFF();
sge_FilledRect(Surface, ret.x, ret.y, ret.x+ret.w, ret.y+ret.h, bcol);
temp=sge_tt_textout_UNI(Surface,font,string, x,y, fcol, bcol, 0);
sge_Update_ON();
sge_UpdateRect(Surface, ret.x, ret.y, ret.w, ret.h);
ret=temp;
}
else{
SDL_Rect temp;
sge_Update_OFF();
sge_FilledRect(Surface, ret.x, ret.y, ret.x+ret.w, ret.y+ret.h, bcol);
temp=sge_tt_textout_UNI(Surface,font,string, x,y, fcol, bcol, 0);
sge_Update_ON();
if(ret.w>=temp.w){
sge_UpdateRect(Surface, ret.x, ret.y, ret.w, ret.h);
}
else{
sge_UpdateRect(Surface, temp.x, temp.y, temp.w, temp.h);
}
ret=temp;
}
return ret;
}
//==================================================================================
// Update function for TTF input that preserve background
//
// type=0 - in ret smaller then out ret
// type=1 - in ret bigger then out ret
// type=3 - safe
//==================================================================================
SDL_Rect nice_update(SDL_Surface *Surface,SDL_Surface *buffer,SDL_Rect ret, int type,sge_TTFont *font,Uint16 *string, Sint16 x,Sint16 y, Uint32 fcol, Uint32 bcol, int Alpha)
{
if(type==0){
sge_Update_OFF();
sge_Blit(buffer,Surface, ret.x, ret.y, ret.x, ret.y, ret.w, ret.h);
ret=sge_tt_textout_UNI(Surface,font,string, x,y, fcol, bcol, Alpha);
sge_Update_ON();
sge_UpdateRect(Surface, ret.x, ret.y, ret.w, ret.h);
}
else if(type==1){
SDL_Rect temp;
sge_Update_OFF();
sge_Blit(buffer,Surface, ret.x, ret.y, ret.x, ret.y, ret.w, ret.h);
temp=sge_tt_textout_UNI(Surface,font,string, x,y, fcol, bcol, Alpha);
sge_Update_ON();
sge_UpdateRect(Surface, ret.x, ret.y, ret.w, ret.h);
ret=temp;
}
else{
SDL_Rect temp;
sge_Update_OFF();
sge_Blit(buffer,Surface, ret.x, ret.y, ret.x, ret.y, ret.w, ret.h);
temp=sge_tt_textout_UNI(Surface,font,string, x,y, fcol, bcol, Alpha);
sge_Update_ON();
if(ret.w>=temp.w){
sge_UpdateRect(Surface, ret.x, ret.y, ret.w, ret.h);
}
else{
sge_UpdateRect(Surface, temp.x, temp.y, temp.w, temp.h);
}
ret=temp;
}
return ret;
}
#endif /* _SGE_NOTTF */
//==================================================================================
// Handle keyrepeats
//==================================================================================
int keyrepeat(SDL_Event *event, int wait)
{
int keydown=1,c=0,ret=0;
SDL_Event ev;
do{
if(SDL_PollEvent(&ev)==1){
if(ev.type==SDL_QUIT){ret=-1;keydown=0;}
if(ev.type==SDL_KEYUP || ev.type==SDL_KEYDOWN){ //Keyrepeat cancelled
keydown=0;
if(ev.type==SDL_KEYDOWN){
SDL_PeepEvents(&ev,1, SDL_ADDEVENT, 0); //Return the newly pressed key to the event queue
}
}
}
SDL_Delay(10);
c++;
if(c>wait && keydown==1){ //trigers keyrepeat
ret=1;
SDL_PeepEvents(event,1, SDL_ADDEVENT, 0); //Return the old key to the event queue
keydown=0;
}
}while(keydown==1);
return ret;
}
//==================================================================================
// Insert a element
//==================================================================================
void insert_char(Uint16 *string, Uint16 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
//==================================================================================
void delete_char(Uint16 *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;
}
}
#ifndef _SGE_NOTTF
// These functions handle keyboard input and shows the result on screen. The text
// can be edited with [Backspace], [Delete], [Left arrow] and [Right arrow].
// Text input is terminated when [Return] or [Enter] is pressed, or if a quit event
// is recived.
// The sge_tt_input functions puts the result in 'string'.
//
// Flags: SGE_IBG - Keeps background, else bye bye background
// SGE_IDEL - Delete text on exit
// SGE_INOKR - No keyrepeat
// (use OR | to give more than one)
//
// If you want a 'default' text you can copy it to string before call and set pos to
// the first empty element in string - ex. "Hello" => pos=5. If not - zero.
// len is the max numbers of chars editable - ex. if you set the default text to "100"
// and only want 3 digits out, set len to 3. string should have atleast len+1 elements
// allocated
// This is *not* a fast, optimized function - but it gets the job done...
// Return:
// Zero or above - the lenght of the string
// -1 recieved a quit event (the lenght is lost)
// -2 invalid indata
// -3 out of memory
//==================================================================================
// Text input UNICODE (the core)
//==================================================================================
int sge_tt_input_UNI(SDL_Surface *screen,sge_TTFont *font,Uint16 *string, Uint8 flags, int pos,int len,Sint16 x,Sint16 y, Uint32 fcol, Uint32 bcol, int Alpha)
{
if(len<pos || pos<0 || len<0){return -2;}
Uint16 cur=124;//The charactar for the cursor - '|'
int max; //The strings size
/* Set update function */
SDL_Rect (*_update)(SDL_Surface *screen,SDL_Surface *buffer,SDL_Rect ret, int type,sge_TTFont *font,Uint16 *string, Sint16 x,Sint16 y, Uint32 fcol, Uint32 bcol, int Alpha);
SDL_Surface *buffer;
if(flags&SGE_FLAG1){ /* Keep background? */
_update=nice_update;
buffer=SDL_DisplayFormat(screen); /* Fixme: Yum! Memory! */
if(buffer==NULL){SDL_SetError("SGE - Out of memory");return -3;}
}
else{ /* nope */
_update=fast_update;
buffer=NULL;
Alpha=0;
}
SDL_Rect ret;
max=pos;
string[pos+1]=0;
SDL_EnableUNICODE(1);
/* Init cursor */
string[pos]=cur;
ret=sge_tt_textout_UNI(screen,font,string, x,y, fcol, bcol, Alpha);
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(string,pos-1,max); pos--; max--;
ret=_update(screen,buffer,ret,1,font,string, x,y, fcol, bcol, Alpha);
/* 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(string,pos,max);pos++;
insert_char(string,cur,pos,max);
ret=_update(screen,buffer,ret,3,font,string, x,y, fcol, bcol, Alpha);
/* 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(string,pos,max);pos--;
insert_char(string,cur,pos,max);
ret=_update(screen,buffer,ret,3,font,string, x,y, fcol, bcol, Alpha);
/* 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(string,pos+1,max);max--;
ret=_update(screen,buffer,ret,1,font,string, x,y, fcol, bcol, Alpha);
/* 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(string, event.key.keysym.unicode, pos,max); pos++;
ret=_update(screen,buffer,ret,0,font,string, x,y, fcol, bcol, Alpha);
/* Handle keyrepeat */
if(!(flags&SGE_FLAG3))
if(keyrepeat(&event, 40)==-1){quit=-1;}
}
}
}while(quit==0);
/* Remove the cursor from string */
delete_char(string,pos,max);
if(flags&SGE_FLAG2){ //Remove the text
if(flags&SGE_FLAG1){
sge_Blit(buffer,screen, ret.x, ret.y, ret.x, ret.y, ret.w, ret.h);
sge_UpdateRect(screen, ret.x, ret.y, ret.w, ret.h);
}
else{
sge_FilledRect(screen,ret.x, ret.y, ret.x+ret.w, ret.y+ret.h,bcol);
}
}
else{ //Draw text without cursor
ret=_update(screen,buffer,ret,1,font,string, x,y, fcol, bcol, Alpha);
}
if(flags&SGE_FLAG1){SDL_FreeSurface(buffer);}
if(quit==-1){return -1;} //Waaa! The user killed me!
return max;
}
CReadline::CReadline( SDL_Surface *a_poScreen, sge_TTFont *a_poFont,
char *a_pcString, int a_iPos, int a_iLen,
int a_x, int a_y, int a_w, Uint32 a_iFCol, Uint32 a_iBCol, int a_iAlpha )
{
m_iResult = 0;
m_poScreen = a_poScreen;
m_poFont = a_poFont;
m_piString = 0;
m_iLen = -1;
w = a_w;
x = a_x;
y = a_y;
SDL_EnableUNICODE(1);
// Create background copy.
m_oWorkArea.x = x;
m_oWorkArea.y = y - sge_TTF_FontAscent(m_poFont);
m_oWorkArea.w = w;
m_oWorkArea.h = sge_TTF_FontHeight(a_poFont);
m_poBackground = sge_copy_surface( a_poScreen, m_oWorkArea.x, m_oWorkArea.y, m_oWorkArea.w, m_oWorkArea.h );
Restart( a_pcString, a_iPos, a_iLen, a_iFCol, a_iBCol, a_iAlpha );
}
void CReadline::Restart( char *a_pcString, int a_iPos, int a_iLen,
Uint32 a_iFCol, Uint32 a_iBCol, int a_iAlpha )
{
if ( NULL == m_piString
|| m_iLen <= a_iLen )
{
if ( m_piString ) delete[] m_piString;
m_iLen = a_iLen;
m_piString = new Uint16[a_iLen+2];
}
m_iResult = 0;
m_pcLatin1String = a_pcString;
m_iPos = a_iPos;
m_iFCol = a_iFCol;
m_iBCol = a_iBCol;
m_iAlpha = a_iAlpha;
// Convert the original string into an unicode string
int i;
for(i=0; i<m_iPos; i++)
{
m_piString[i]=(unsigned char)m_pcLatin1String[i];
}
m_piString[m_iPos]=0;
// Insert the cursor at the end
m_iCursor = 124; // '|' character
m_iMax=m_iPos;
m_piString[m_iPos+1]=0;
m_piString[m_iPos]=m_iCursor;
- m_oUpdateRect = sge_tt_textout_UNI( m_poScreen, m_poFont, m_piString, x, y, m_iFCol, m_iBCol, m_iAlpha );
+ Redraw();
+ SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
}
CReadline::~CReadline()
{
delete[] m_piString;
SDL_EnableUNICODE(0);
SDL_FreeSurface( m_poBackground );
m_poBackground = NULL;
+
+ SDL_EnableKeyRepeat( 0, 0 );
}
/** Returns the current state of the line input.
\retval -1 A quit event was encountered.
\retval -2 Escape was pressed
\retval 0 Input is in progress.
\retval 1 Input has finished.
*/
int CReadline::GetResult()
{
if ( m_iResult == 0 )
{
return m_iResult;
}
+
+ SDL_EnableKeyRepeat( 0, 0 );
sge_Blit( m_poBackground, m_poScreen, m_oUpdateRect.x, m_oUpdateRect.y,
m_oUpdateRect.x, m_oUpdateRect.y, m_oUpdateRect.w, m_oUpdateRect.h);
sge_UpdateRect(m_poScreen, m_oUpdateRect.x, m_oUpdateRect.y, m_oUpdateRect.w, m_oUpdateRect.h);
if ( m_iResult < 0 )
{
return m_iResult;
}
delete_char( m_piString, m_iPos, m_iMax );
memset( m_pcLatin1String, 0, sizeof(char)*(m_iPos+1) );
for( int i=0; i<=m_iMax; i++)
{
m_pcLatin1String[i] = (char)m_piString[i];
}
insert_char( m_piString, m_iCursor, m_iPos, m_iMax );
return 1;
}
/** Internal method for redrawing the string. */
void CReadline::Update( int a_iCode )
{
//m_oUpdateRect = nice_update( m_poScreen, m_poBackground, m_oUpdateRect, a_iCode, m_poFont, m_piString,
// x, y, m_iFCol, m_iBCol, m_iAlpha );
SDL_Rect oOldClipRect;
SDL_GetClipRect( m_poScreen, &oOldClipRect );
SDL_SetClipRect( m_poScreen, &m_oWorkArea );
sge_Blit( m_poBackground, m_poScreen, 0, 0, m_oWorkArea.x, m_oWorkArea.y, m_oWorkArea.w, m_oWorkArea.h );
sge_tt_textout_UNI( m_poScreen, m_poFont, m_piString, x, y, m_iFCol, m_iBCol, m_iAlpha );
sge_UpdateRect( m_poScreen, m_oWorkArea.x, m_oWorkArea.y, m_oWorkArea.w, m_oWorkArea.h );
SDL_SetClipRect( m_poScreen, &oOldClipRect );
}
+void CReadline::Redraw()
+{
+ m_oUpdateRect = sge_tt_textout_UNI( m_poScreen, m_poFont, m_piString, x, y, m_iFCol, m_iBCol, m_iAlpha );
+ sge_UpdateRect( m_poScreen, m_oWorkArea.x, m_oWorkArea.y, m_oWorkArea.w, m_oWorkArea.h );
+}
+
+
void CReadline::Clear()
{
sge_Blit( m_poBackground, m_poScreen, 0, 0, m_oWorkArea.x, m_oWorkArea.y, m_oWorkArea.w, m_oWorkArea.h );
}
/** Runs the event queue until the input is finished.
\see GetResult
*/
int CReadline::Execute()
{
int iRetval;
SDL_Event e;
while ( 1 )
{
SDL_WaitEvent( &e );
HandleKeyEvent( e );
iRetval = GetResult();
if ( iRetval )
break;
}
return iRetval;
}
void CReadline::HandleKeyEvent( SDL_Event& a_roEvent )
{
if(a_roEvent.type==SDL_QUIT)
{
m_iResult = -1;
return;
}
if ( a_roEvent.type != SDL_KEYDOWN )
{
return;
}
if( a_roEvent.key.keysym.sym==SDLK_ESCAPE )
{
m_iResult = -2;
return;
}
if ( a_roEvent.key.keysym.sym==SDLK_RETURN
|| a_roEvent.key.keysym.sym==SDLK_KP_ENTER )
{
m_iResult = 1;
return;
}
if( a_roEvent.key.keysym.sym==SDLK_BACKSPACE )
{
if ( m_iPos == 0 )
{
return;
}
/* Delete char cursor-1 */
delete_char(m_piString,m_iPos-1,m_iMax);
m_iPos--;
m_iMax--;
Update( 1 );
return;
}
if( a_roEvent.key.keysym.sym==SDLK_RIGHT
&& m_iPos!=m_iMax && m_iPos!=m_iLen )
{
/* Move cursor right */
delete_char(m_piString,m_iPos,m_iMax);
m_iPos++;
insert_char(m_piString,m_iCursor,m_iPos,m_iMax);
Update( 3 );
return;
}
if ( a_roEvent.key.keysym.sym==SDLK_LEFT
&& m_iPos>0 )
{
/* Move cursor left */
delete_char(m_piString,m_iPos,m_iMax);
m_iPos--;
insert_char(m_piString,m_iCursor,m_iPos,m_iMax);
Update( 3 );
return;
}
if( a_roEvent.key.keysym.sym==SDLK_DELETE )
{
if ( m_iPos!=m_iMax && m_iPos!=m_iLen )
{
delete_char(m_piString,m_iPos+1,m_iMax);
m_iMax--;
Update( 1 );
}
return;
}
if( a_roEvent.key.keysym.unicode!=0
&& m_iMax != m_iLen )
{
m_iMax++;
insert_char(m_piString, a_roEvent.key.keysym.unicode, m_iPos, m_iMax);
m_iPos++;
Update( 0 );
}
}
/*
SDL_Rect CReadline::NiceUpdate( SDL_Surface *Surface,SDL_Surface *buffer,
SDL_Rect ret, int type,sge_TTFont *font,Uint16 *string, Sint16 x,Sint16 y,
Uint32 fcol, Uint32 bcol, int Alpha )
{
if(type==0){
sge_Update_OFF();
sge_Blit(buffer,Surface, ret.x, ret.y, ret.x, ret.y, ret.w, ret.h);
ret=sge_tt_textout_UNI(Surface,font,string, x,y, fcol, bcol, Alpha);
sge_Update_ON();
sge_UpdateRect(Surface, ret.x, ret.y, ret.w, ret.h);
}
else if(type==1){
SDL_Rect temp;
sge_Update_OFF();
sge_Blit(buffer,Surface, ret.x, ret.y, ret.x, ret.y, ret.w, ret.h);
temp=sge_tt_textout_UNI(Surface,font,string, x,y, fcol, bcol, Alpha);
sge_Update_ON();
sge_UpdateRect(Surface, ret.x, ret.y, ret.w, ret.h);
ret=temp;
}
else{
SDL_Rect temp;
sge_Update_OFF();
sge_Blit(buffer,Surface, ret.x, ret.y, ret.x, ret.y, ret.w, ret.h);
temp=sge_tt_textout_UNI(Surface,font,string, x,y, fcol, bcol, Alpha);
sge_Update_ON();
if(ret.w>=temp.w){
sge_UpdateRect(Surface, ret.x, ret.y, ret.w, ret.h);
}
else{
sge_UpdateRect(Surface, temp.x, temp.y, temp.w, temp.h);
}
ret=temp;
}
return ret;
}
*/
//==================================================================================
// Text input UNICODE (RGB)
//==================================================================================
int sge_tt_input_UNI(SDL_Surface *screen,sge_TTFont *font,Uint16 *string,Uint8 flags, int pos,int len,Sint16 x,Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR,Uint8 bG,Uint8 bB, int Alpha)
{
return sge_tt_input_UNI(screen,font,string,flags,pos,len,x,y,SDL_MapRGB(screen->format, fR,fG,fB),SDL_MapRGB(screen->format, bR,bG,bB),Alpha);
}
//==================================================================================
// Text input Latin1
//
// Will fail miserable if ret<0!
//==================================================================================
int sge_tt_input(SDL_Surface *screen,sge_TTFont *font,char *string,Uint8 flags, int pos,int len,Sint16 x,Sint16 y, Uint32 fcol, Uint32 bcol, int Alpha)
{
if(len<pos || pos<0 || len<0){return -2;}
#ifndef __GNUC__
Uint16 *uni=new Uint16[len+2]; //ANSI C++
#else
Uint16 uni[len+2];
#endif
int ret;
int i;
if(pos!=0){
for(i=0; i<pos; i++){ //Convert Latin1 => Uni
uni[i]=(unsigned char)string[i];
}
}
uni[pos]=0;
ret=sge_tt_input_UNI(screen,font,uni,flags,pos,len,x,y,fcol,bcol,Alpha);
memset(string,0,sizeof(char)*(pos+1));
if(ret>0){
for( i=0; i<=ret; i++){ //Convert Uni => Latin1
string[i] = (char)uni[i];
}
}
#ifndef __GNUC__
delete[] uni;
#endif
return ret;
}
//==================================================================================
// Text input Latin1 (RGB)
//==================================================================================
int sge_tt_input(SDL_Surface *screen,sge_TTFont *font,char *string,Uint8 flags, int pos,int len,Sint16 x,Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR,Uint8 bG,Uint8 bB, int Alpha)
{
return sge_tt_input(screen,font,string,flags,pos,len,x,y,SDL_MapRGB(screen->format, fR,fG,fB),SDL_MapRGB(screen->format, bR,bG,bB),Alpha);
}
#endif /* _SGE_NOTTF */
diff --git a/src/sge_tt_text.h b/src/sge_tt_text.h
index 7658fb3..b55d6be 100644
--- a/src/sge_tt_text.h
+++ b/src/sge_tt_text.h
@@ -1,145 +1,146 @@
/*
* SDL Graphics Extension
* Text/TrueType functions (header)
*
* Started 990815
*
* License: LGPL v2+ (see the file LICENSE)
* (c)1999-2001 Anders Lindstr?m
*
* Uses the excellent FreeType 2 library, available at:
* http://www.freetype.org/
*/
/*********************************************************************
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
*********************************************************************/
#ifndef sge_tt_text_H
#define sge_tt_text_H
#include "SDL.h"
#include "sge_internal.h"
/* Text input flags */
#define SGE_IBG SGE_FLAG1
#define SGE_IDEL SGE_FLAG2
#define SGE_INOKR SGE_FLAG3
#ifndef _SGE_NOTTF
/* the truetype font structure */
typedef struct _sge_TTFont sge_TTFont;
/* Font style */
#define SGE_TTF_NORMAL SGE_FLAG0
#define SGE_TTF_BOLD SGE_FLAG1
#define SGE_TTF_ITALIC SGE_FLAG2
#define SGE_TTF_UNDERLINE SGE_FLAG3
#endif /* _SGE_NOTTF */
#ifdef _SGE_C
extern "C" {
#endif
#ifndef _SGE_NOTTF
DECLSPEC void sge_TTF_AAOff(void);
DECLSPEC void sge_TTF_AAOn(void);
DECLSPEC void sge_TTF_AA_Alpha(void);
DECLSPEC int sge_TTF_Init(void);
DECLSPEC sge_TTFont *sge_TTF_OpenFont(const char *file, int ptsize);
DECLSPEC int sge_TTF_SetFontSize(sge_TTFont *font, int ptsize);
DECLSPEC int sge_TTF_FontHeight(sge_TTFont *font);
DECLSPEC int sge_TTF_FontAscent(sge_TTFont *font);
DECLSPEC int sge_TTF_FontDescent(sge_TTFont *font);
DECLSPEC int sge_TTF_FontLineSkip(sge_TTFont *font);
DECLSPEC void sge_TTF_SetFontStyle(sge_TTFont *font, Uint8 style);
DECLSPEC Uint8 sge_TTF_GetFontStyle(sge_TTFont *font);
DECLSPEC void sge_TTF_CloseFont(sge_TTFont *font);
DECLSPEC SDL_Rect sge_TTF_TextSizeUNI(sge_TTFont *font, const Uint16 *text);
-DECLSPEC SDL_Rect sge_TTF_TextSize(sge_TTFont *Font, const char *Text);
+DECLSPEC SDL_Rect sge_TTF_TextSize(sge_TTFont *Font, const char *Text, int a_iMaxLength=-1);
DECLSPEC SDL_Rect sge_tt_textout(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha);
DECLSPEC SDL_Rect sge_tt_textout_UTF8(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha);
DECLSPEC SDL_Rect sge_tt_textout_UNI(SDL_Surface *Surface, sge_TTFont *font, const Uint16 *uni, Sint16 x, Sint16 y, Uint32 fcolor, Uint32 bcolor, int Alpha);
DECLSPEC SDL_Rect sge_tt_textoutf(SDL_Surface *Surface, sge_TTFont *font, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha , const char *format,...);
DECLSPEC int sge_tt_input_UNI(SDL_Surface *screen,sge_TTFont *font,Uint16 *string,Uint8 flags, int pos,int len,Sint16 x,Sint16 y, Uint32 fcol, Uint32 bcol, int Alpha);
DECLSPEC int sge_tt_input(SDL_Surface *screen,sge_TTFont *font,char *string,Uint8 flags, int pos,int len,Sint16 x,Sint16 y, Uint32 fcol, Uint32 bcol, int Alpha);
DECLSPEC SDL_Surface *sge_TTF_RenderUNICODE(sge_TTFont *font,const Uint16 *text, SDL_Color fg, SDL_Color bg);
DECLSPEC SDL_Rect fast_update(SDL_Surface *Surface,SDL_Surface *buffer,SDL_Rect ret, int type,sge_TTFont *font,Uint16 *string, Sint16 x,Sint16 y, Uint32 fcol, Uint32 bcol,int Alpha);
DECLSPEC SDL_Rect nice_update(SDL_Surface *Surface,SDL_Surface *buffer,SDL_Rect ret, int type,sge_TTFont *font,Uint16 *string, Sint16 x,Sint16 y, Uint32 fcol, Uint32 bcol, int Alpha);
#endif /* _SGE_NOTTF */
DECLSPEC int keyrepeat(SDL_Event *event, int wait);
DECLSPEC void insert_char(Uint16 *string, Uint16 ch, int pos, int max);
DECLSPEC void delete_char(Uint16 *string, int pos, int max);
DECLSPEC Uint16 *sge_Latin1_Uni(const char *text);
#ifdef _SGE_C
}
#endif
#ifndef sge_C_ONLY
#ifndef _SGE_NOTTF
DECLSPEC SDL_Rect sge_tt_textout(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha);
DECLSPEC SDL_Rect sge_tt_textout_UTF8(SDL_Surface *Surface, sge_TTFont *font, const char *string, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha);
DECLSPEC SDL_Rect sge_tt_textout_UNI(SDL_Surface *Surface, sge_TTFont *font, const Uint16 *uni, Sint16 x, Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR, Uint8 bG, Uint8 bB, int Alpha);
DECLSPEC int sge_tt_input_UNI(SDL_Surface *screen,sge_TTFont *font,Uint16 *string,Uint8 flags, int pos,int len,Sint16 x,Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR,Uint8 bG,Uint8 bB, int Alpha);
DECLSPEC int sge_tt_input(SDL_Surface *screen,sge_TTFont *font,char *string,Uint8 flags, int pos,int len,Sint16 x,Sint16 y, Uint8 fR, Uint8 fG, Uint8 fB, Uint8 bR,Uint8 bG,Uint8 bB, int Alpha);
#endif /* _SGE_NOTTF */
#endif /* sge_C_ONLY */
class CReadline
{
public:
CReadline( SDL_Surface *a_poScreen, _sge_TTFont *a_poFont,
char *a_pcString, int a_iPos, int a_iLen,
int a_x, int a_y, int a_w, Uint32 a_iFCol, Uint32 a_iBCol, int a_iAlpha );
~CReadline();
void Restart( char *a_pcString, int a_iPos, int a_iLen,
Uint32 a_iFCol, Uint32 a_iBCol, int a_iAlpha );
int GetResult();
void HandleKeyEvent( SDL_Event& a_roEvent );
+ void Redraw();
void Clear();
int Execute();
protected:
void Update( int a_iCode );
void NiceUpdate( int a_iCode );
protected:
SDL_Surface* m_poScreen;
SDL_Surface* m_poBackground;
SDL_Rect m_oWorkArea;
_sge_TTFont* m_poFont;
char* m_pcLatin1String;
Uint16* m_piString;
int m_iPos;
int m_iLen;
int x, y, w;
Uint32 m_iFCol;
Uint32 m_iBCol;
int m_iAlpha;
SDL_Rect m_oUpdateRect;
char m_iCursor;
int m_iMax;
int m_iResult;
};
#endif /* sge_tt_text_H */

File Metadata

Mime Type
text/x-diff
Expires
Mon, Feb 2, 8:53 PM (2 d, 6 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55526
Default Alt Text
(87 KB)

Event Timeline