Page MenuHomePhabricator (Chris)

No OneTemporary

Size
252 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/characters/Makefile.in b/data/characters/Makefile.in
index 5fcd31e..c39250c 100644
--- a/data/characters/Makefile.in
+++ b/data/characters/Makefile.in
@@ -1,209 +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@
charactersdatadir = $(pkgdatadir)/characters
charactersdata_DATA = BENCEDATA.DAT DESCANTDATA.DAT.pl STAFF.DAT ZOLIDATA.DAT BENCEDATA.DAT.pl MACIDATA.DAT ULMARDATA.DAT ZOLIDATA.DAT.pl CUMIDATA.DAT MACIDATA.DAT.pl ULMARDATA.DAT.pl CUMIDATA.DAT.pl SIRPIDATA.DAT UPIDATA.DAT DESCANTDATA.DAT SIRPIDATA.DAT.pl UPIDATA.DAT.pl GRIZLIDATA.DAT GRIZLIDATA.DAT.pl
EXTRA_DIST = $(charactersdata_DATA)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../config.h
CONFIG_CLEAN_FILES =
DATA = $(charactersdata_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 --include-deps data/characters/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu data/characters/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
install-charactersdataDATA: $(charactersdata_DATA)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(charactersdatadir)
@list='$(charactersdata_DATA)'; for p in $$list; do \
if test -f $(srcdir)/$$p; then \
echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(charactersdatadir)/$$p"; \
$(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(charactersdatadir)/$$p; \
else if test -f $$p; then \
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(charactersdatadir)/$$p"; \
$(INSTALL_DATA) $$p $(DESTDIR)$(charactersdatadir)/$$p; \
fi; fi; \
done
uninstall-charactersdataDATA:
@$(NORMAL_UNINSTALL)
list='$(charactersdata_DATA)'; for p in $$list; do \
rm -f $(DESTDIR)$(charactersdatadir)/$$p; \
done
tags: TAGS
TAGS:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = data/characters
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/characters/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-charactersdataDATA
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am: uninstall-charactersdataDATA
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)$(charactersdatadir)
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-charactersdataDATA install-charactersdataDATA 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/mkinstalldirs b/mkinstalldirs
index 8a6a317..6a05037 100755
--- a/mkinstalldirs
+++ b/mkinstalldirs
@@ -1,40 +1,40 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
-# $Id: mkinstalldirs,v 1.1 2003/09/01 19:30:18 upi Exp $
+# $Id: mkinstalldirs,v 1.2 2003/09/01 20:40:21 upi Exp $
errstatus=0
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here
diff --git a/src/Audio.cpp b/src/Audio.cpp
index 1401623..89757ec 100644
--- a/src/Audio.cpp
+++ b/src/Audio.cpp
@@ -1,256 +1,256 @@
/***************************************************************************
Audio.cpp - description
-------------------
begin : Sat Jul 26 2003
copyright : (C) 2003 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include "Audio.h"
#include "State.h"
#include "common.h"
-#include <SDL/SDL_mixer.h>
+#include "SDL_mixer.h"
#include <string>
#include <map>
typedef std::map<std::string,Mix_Chunk*> SampleMap;
typedef std::map<std::string,Mix_Music*> MusicMap;
typedef SampleMap::iterator SampleMapIterator;
typedef MusicMap::iterator MusicMapIterator;
MszAudio* Audio = NULL;
class MszAudioPriv
{
public:
bool m_bAudioOk;
int m_iNumChannels;
SampleMap m_oSamples;
MusicMap m_oMusics;
};
#define SELF (*m_poPriv)
#define CHECKOK if ( ! m_poPriv->m_bAudioOk ) return;
MszAudio::MszAudio()
{
Audio = this;
m_poPriv = new MszAudioPriv;
m_poPriv->m_bAudioOk = false;
m_poPriv->m_iNumChannels = 0;
SDL_version compile_version;
const SDL_version *link_version;
MIX_VERSION(&compile_version);
debug( "compiled with SDL_mixer version: %d.%d.%d\n",
compile_version.major, compile_version.minor, compile_version.patch);
link_version=Mix_Linked_Version();
debug("running with SDL_mixer version: %d.%d.%d\n",
link_version->major, link_version->minor, link_version->patch);
if ( Mix_OpenAudio( MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT,
2 /*stereo*/, 1024*2 /*chunksize*/ ) < 0 )
{
debug("Mix_OpenAudio: %s\n", Mix_GetError());
SELF.m_bAudioOk = false;
}
else
{
SELF.m_bAudioOk = true;
}
m_poPriv->m_iNumChannels = Mix_AllocateChannels(8);
}
MszAudio::~MszAudio()
{
delete m_poPriv;
m_poPriv = NULL;
}
void MszAudio::LoadSample( const char* a_pcFilename, const char* a_pcSampleName )
{
CHECKOK;
std::string sSampleName( a_pcSampleName ? a_pcSampleName : a_pcFilename );
std::string sSampleFile = DATADIR;
sSampleFile += "/sound/";
sSampleFile += a_pcFilename;
if ( m_poPriv->m_oSamples.count( sSampleName ) )
{
debug( "Key %s already loaded", a_pcSampleName );
return;
}
Mix_Chunk *poSample;
poSample=Mix_LoadWAV(sSampleFile.c_str());
if(!poSample)
{
debug("Mix_LoadWAV: %s\n", Mix_GetError());
return;
}
m_poPriv->m_oSamples[ sSampleName ] = poSample;
}
void MszAudio::UnloadSample( const char* a_pcSampleName )
{
SampleMapIterator it = m_poPriv->m_oSamples.find( a_pcSampleName );
if ( m_poPriv->m_oSamples.end() == it )
{
debug( "UnloadSample: sample %s not found", a_pcSampleName );
return;
}
Mix_FreeChunk( (*it).second );
m_poPriv->m_oSamples.erase( it );
}
void MszAudio::PlaySample( const char* a_pcSampleName )
{
Mix_Chunk* poSample;
SampleMapIterator it = m_poPriv->m_oSamples.find(a_pcSampleName);
if ( m_poPriv->m_oSamples.end() == it )
{
// Try to load the sample..
LoadSample( a_pcSampleName );
it = m_poPriv->m_oSamples.find(a_pcSampleName);
if ( m_poPriv->m_oSamples.end() == it )
{
debug( "PlaySample: sample %s not found", a_pcSampleName );
return;
}
}
poSample = (*it).second;
int iVolume = g_oState.m_iSoundVolume * 128 / 100;
if ( poSample->volume != iVolume )
{
Mix_VolumeChunk( poSample, iVolume );
}
if ( -1 == Mix_PlayChannel( -1, poSample, 0 ) )
{
debug( "PlaySample: Mix_PlayChannel: %s\n",Mix_GetError());
}
}
void MszAudio::PlayFile( const char* a_pcFileName )
{
Mix_Chunk *poSample;
poSample=Mix_LoadWAV("sample.wav");
if(!poSample)
{
debug("Mix_LoadWAV: %s\n", Mix_GetError());
return;
}
if ( -1 == Mix_PlayChannel( -1, poSample, 0 ) )
{
debug( "PlaySample: Mix_PlayChannel: %s\n",Mix_GetError());
}
Mix_FreeChunk( poSample );
}
void MszAudio::LoadMusic( const char* a_pcFilename, const char* a_pcMusicName )
{
CHECKOK;
std::string sMusicName( a_pcMusicName ? a_pcMusicName : a_pcFilename );
std::string sMusicFile = DATADIR;
sMusicFile += "/sound/";
sMusicFile += a_pcFilename;
if ( m_poPriv->m_oMusics.count( sMusicName ) )
{
debug( "Key %s already loaded", a_pcMusicName );
return;
}
Mix_Music *poMusic;
poMusic=Mix_LoadMUS(sMusicFile.c_str());
if(!poMusic)
{
debug("Mix_LoadMUS: %s\n", Mix_GetError());
return;
}
m_poPriv->m_oMusics[ sMusicName ] = poMusic;
}
void MszAudio::UnloadMusic( const char* a_pcMusicName )
{
MusicMapIterator it = m_poPriv->m_oMusics.find( a_pcMusicName );
if ( m_poPriv->m_oMusics.end() == it )
{
debug( "UnloadMusic: music %s not found", a_pcMusicName );
return;
}
Mix_FreeMusic( (*it).second );
m_poPriv->m_oMusics.erase( it );
}
void MszAudio::PlayMusic( const char* a_pcMusicName )
{
MusicMapIterator it = m_poPriv->m_oMusics.find( a_pcMusicName );
if ( m_poPriv->m_oMusics.end() == it )
{
debug( "PlayMusic: music %s not found", a_pcMusicName );
return;
}
SetMusicVolume( g_oState.m_iMusicVolume );
//Mix_PlayMusic( (*it).second, -1 );
Mix_FadeInMusic( (*it).second, -1, 100 );
}
void MszAudio::FadeMusic( int a_iMilliSec )
{
Mix_FadeOutMusic( a_iMilliSec );
}
void MszAudio::SetMusicVolume( int a_iVolume )
{
Mix_VolumeMusic( a_iVolume * 128 / 100 );
}
void MszAudio::StopMusic()
{
Mix_HaltMusic();
}
bool MszAudio::IsMusicPlaying()
{
return Mix_PlayingMusic();
}
diff --git a/src/FlyingChars.cpp b/src/FlyingChars.cpp
index fdfa625..194b9af 100644
--- a/src/FlyingChars.cpp
+++ b/src/FlyingChars.cpp
@@ -1,405 +1,406 @@
/***************************************************************************
FlyingChars.cpp - description
-------------------
begin : Mon Aug 12 2003
copyright : (C) 2003 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
-#include <FlyingChars.h>
+#include "FlyingChars.h"
#include "sge_surface.h"
#include "common.h"
int g_iLineTime = 100;
int g_iCharTime = 80;
FlyingChars::FlyingChars( sge_bmpFont* a_poFont, const SDL_Rect& a_roRect, int a_iFontDisplacement )
{
m_poFont = a_poFont;
m_oRect = a_roRect;
m_iFontDisplacement = a_iFontDisplacement;
m_bDone = true;
m_iTimeToNextLine = 0;
m_iDelay = 0;
m_iLastLineY = a_roRect.y;
m_pcText = NULL;
m_enAlignment = FC_AlignLeft;
m_iTextOffset = 0;
m_bScrolling = false;
m_dScrollupRate = (double)(m_poFont->CharHeight+2) / (double)g_iLineTime;
m_dScrollup = 0.0;
}
FlyingChars::~FlyingChars()
{
}
void FlyingChars::AddText( const char* a_pcText,
TextAlignment a_enAlignment, bool a_bOneByOne )
{
EnqueuedText oNewText;
oNewText.m_pcText = a_pcText;
oNewText.m_enAlignment = a_enAlignment;
m_oEnqueuedTexts.push_back( oNewText );
if ( a_bOneByOne && m_iLastLineY <= m_oRect.y )
{
m_iLastLineY = m_oRect.y + m_oRect.h - m_poFont->CharHeight;
}
else if ( 0 == m_pcText
|| m_iLastLineY <= m_oRect.y + m_oRect.h - m_poFont->CharHeight )
{
DequeueText();
}
}
bool FlyingChars::IsDone()
{
if ( m_oEnqueuedTexts.size() == 0
&& ( NULL == m_pcText || 0 == m_pcText[ m_iTextOffset] )
&& ( m_bDone ) )
{
return true;
}
return false;
}
void FlyingChars::DequeueText()
{
if ( 0 == m_oEnqueuedTexts.size() )
{
return;
}
EnqueuedText& oEnqueuedText = m_oEnqueuedTexts.front();
- m_oEnqueuedTexts.pop_front();
m_pcText = oEnqueuedText.m_pcText;
m_enAlignment = oEnqueuedText.m_enAlignment;
m_iTextOffset = 0;
while ( m_iLastLineY <= m_oRect.y + m_oRect.h - m_poFont->CharHeight )
{
AddNextLine();
m_iTimeToNextLine += g_iLineTime;
if ( 0 == m_pcText[m_iTextOffset] )
{
break;
}
}
+
+ m_oEnqueuedTexts.pop_front();
}
void FlyingChars::Advance( int a_iNumFrames )
{
if ( a_iNumFrames > 5 ) a_iNumFrames = 5;
if ( a_iNumFrames <= 0 ) a_iNumFrames = 0;
m_bDone = true;
m_iTimeToNextLine -= a_iNumFrames;
if ( m_iTimeToNextLine < 0 )
{
m_iTimeToNextLine += g_iLineTime;
m_iDelay = 0;
if ( !m_pcText
|| 0 == m_pcText[m_iTextOffset] )
{
DequeueText();
}
else
{
AddNextLine();
}
}
m_dScrollup += a_iNumFrames * m_dScrollupRate;
int iScrollup = (int) m_dScrollup;
m_dScrollup -= iScrollup;
iScrollup *= 2;
for ( FlyingLetterIterator it=m_oLetters.begin(); it!=m_oLetters.end(); ++it )
{
FlyingLetter& roLetter = *it;
if ( m_bScrolling )
{
roLetter.m_iDY -= iScrollup;
roLetter.m_iY -= iScrollup;
if ( roLetter.m_iDY < m_oRect.y * 2
&& roLetter.m_iDY >= 0 )
{
roLetter.m_iDY = -100;
roLetter.m_iTime = 40;
}
}
if (roLetter.m_iDelay > 0)
{
roLetter.m_iDelay -= a_iNumFrames;
continue;
}
if ( roLetter.m_iTime > 0 )
{
m_bDone = false;
int iEstX = roLetter.m_iSX * roLetter.m_iTime / 2 + roLetter.m_iX ;
if ( iEstX > roLetter.m_iDX )
{
roLetter.m_iSX -= a_iNumFrames;
}
else if ( iEstX < roLetter.m_iDX )
{
roLetter.m_iSX += a_iNumFrames;
}
roLetter.m_iX += roLetter.m_iSX * a_iNumFrames;
if ( roLetter.m_iSY * roLetter.m_iTime / 2 + roLetter.m_iY >= roLetter.m_iDY )
{
roLetter.m_iSY -= a_iNumFrames;
}
else
{
roLetter.m_iSY += a_iNumFrames;
}
roLetter.m_iY += roLetter.m_iSY * a_iNumFrames;
roLetter.m_iTime -= a_iNumFrames;
if ( roLetter.m_iTime <= 0 )
{
roLetter.m_iX = roLetter.m_iDX;
roLetter.m_iY = roLetter.m_iDY;
roLetter.m_iSX = roLetter.m_iSY = 0;
roLetter.m_iTime = 0;
}
}
}
}
void FlyingChars::Draw()
{
for ( FlyingLetterIterator it=m_oLetters.begin(); it!=m_oLetters.end(); ++it )
{
FlyingLetter& roLetter = *it;
int iDestX, iDestY;
if (roLetter.m_iDelay > 0)
{
continue;
}
else if ( roLetter.m_iTime > 0 )
{
iDestX = roLetter.m_iX;
iDestY = roLetter.m_iY;
}
else
{
iDestX = roLetter.m_iX;
iDestY = roLetter.m_iY;
}
int iSrcX, iSrcW;
if ( ! m_poFont->CharPos )
{
iSrcX = roLetter.m_cLetter * m_poFont->CharWidth;
iSrcW = m_poFont->CharWidth;
}
else
{
int iOfs = (roLetter.m_cLetter-33)*2 + 1;
iSrcX = m_poFont->CharPos[iOfs];
iSrcW = m_poFont->CharPos[iOfs+1] - iSrcX;
}
//debug( "Letter %c at %d,%d\n", roLetter.m_cLetter, iDestX/2, iDestY/2 );
sge_Blit( m_poFont->FontSurface, gamescreen, iSrcX, m_poFont->yoffs,
iDestX/2, iDestY/2, iSrcW, m_poFont->CharHeight );
}
}
void FlyingChars::AddNextLine()
{
if ( NULL == m_pcText )
{
return;
}
// 1. SCROLL UP EVERYTHING IF NECESSARY
if ( m_iLastLineY > m_oRect.y + m_oRect.h - m_poFont->CharHeight )
{
// scroll up every character
if ( !m_bScrolling )
{
m_bScrolling = true;
m_iTimeToNextLine = (m_iLastLineY - (m_oRect.y + m_oRect.h - m_poFont->CharHeight)) / m_dScrollupRate;
return;
}
m_iLastLineY = m_oRect.y + m_oRect.h - m_poFont->CharHeight;
}
SDL_Rect oRect;
const char* pcLineStart = m_pcText + m_iTextOffset;
if ( '\n' == *pcLineStart ) ++pcLineStart;
while (*pcLineStart == 32 || *pcLineStart == '\t' ) ++pcLineStart;
if ( 0 == *pcLineStart )
{
m_iTextOffset = pcLineStart - m_pcText;
return;
}
// 2. CALCULATE LINE WIDTH AND CONTENTS
const char* pcLineEnd = pcLineStart;
const char* pcNextWord = pcLineEnd;
int iNumWords = 0;
int iLineWidth = 0;
int iWidth = 0;
while (1)
{
++iNumWords;
if ( '\n' == *pcNextWord
|| 0 == *pcNextWord)
{
break;
}
// Skip the next 'white space' part
while (*pcNextWord == 32 || *pcNextWord == '\t' )
{
iWidth += GetCharWidth( *pcNextWord );
++pcNextWord;
}
// Skip the next 'non-whitespace' part
while (*pcNextWord != 32 && *pcNextWord != '\t'
&& *pcNextWord != '\n' && *pcNextWord != 0 )
{
iWidth += GetCharWidth( *pcNextWord );
++pcNextWord;
}
if ( iWidth > m_oRect.w )
{
// overflow
break;
}
pcLineEnd = pcNextWord;
iLineWidth = iWidth;
}
if ( pcLineEnd == pcLineStart )
{
pcLineEnd = pcNextWord;
iLineWidth = iWidth;
}
// 3. ADD LETTERS IN LINE
double dX = m_oRect.x;
double dSpaceLength = 0.0;
switch ( m_enAlignment )
{
case FC_AlignJustify:
if ( '\n' == *pcLineEnd
|| 0 == *pcLineEnd )
{
}
else
{
dSpaceLength = (m_oRect.w - iLineWidth) / double( iNumWords > 2 ? iNumWords-2 : 1 );
}
break;
case FC_AlignCenter:
dX += (m_oRect.w - iLineWidth) /2;
break;
case FC_AlignRight:
dX += (m_oRect.w - iLineWidth);
break;
default:
break;
}
FlyingLetter oLetter;
oLetter.m_iDY = m_iLastLineY * 2;
for ( const char *pcChar = pcLineStart; pcChar<pcLineEnd; ++pcChar )
{
if ( *pcChar < 33 )
{
if ( *pcChar == 32 || *pcChar == '\t' )
{
dX += dSpaceLength;
// debug( "dX = %3.2f dSpaceLength = %2.2f\n", (float)dX, (float)dSpaceLength );
}
int iWidth = GetCharWidth( *pcChar );
dX += iWidth;
//debug( "dX = %3.2f iWidth = %d\n", (float)dX, iWidth );
continue;
}
oRect = sge_BF_TextSize( m_poFont, pcLineStart, pcChar-pcLineStart );
oLetter.m_iDX = (int) dX * 2;
oLetter.m_iX = rand() % (gamescreen->w * 2);
oLetter.m_iY = gamescreen->h * 2;
oLetter.m_iSX = 0;
oLetter.m_iSY = -45 + rand() % 15 ;
oLetter.m_iDelay = m_iDelay++;
oLetter.m_iTime = g_iCharTime;
oLetter.m_cLetter = *pcChar;
m_oLetters.push_back(oLetter);
dX += GetCharWidth( *pcChar );
}
m_iTextOffset = pcLineEnd - m_pcText;
m_iLastLineY += m_poFont->CharHeight + 2;
}
int FlyingChars::GetCharWidth( char a_cChar )
{
if ( a_cChar == 0 )
{
return 0;
}
else if ( m_poFont->CharPos )
{
if ( a_cChar < 33 )
{
return m_poFont->CharPos[3] - m_poFont->CharPos[2] + 1;
}
else
{
int iOfs = (a_cChar - 33) * 2 + 1;
return m_poFont->CharPos[iOfs+1] - m_poFont->CharPos[iOfs] + m_iFontDisplacement;
}
}
return m_poFont->CharWidth;
}
diff --git a/src/Game.cpp b/src/Game.cpp
index bc874c0..6dbeb72 100644
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -1,724 +1,728 @@
/***************************************************************************
Game.cpp - description
-------------------
begin : Mon Sep 24 2001
copyright : (C) 2001 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include <string.h>
#include <stdio.h>
-#include <SDL/SDL_image.h>
+#include "SDL_image.h"
#include "sge_surface.h"
#include "sge_primitives.h"
#include "sge_bm_text.h"
-#include <SDL/SDL_events.h>
-#include <SDL/SDL_keysym.h>
+#include "SDL_events.h"
+#include "SDL_keysym.h"
#include <fstream>
#include "common.h"
#include "gfx.h"
#include "Backend.h"
#include "RlePack.h"
#include "State.h"
#include "Game.h"
#include "Audio.h"
/*
GAME PALETTE
From To Num Desc
---------------------------------------
0 .. 63 64 Background
64 .. 111 48 Doodads
112 .. 175 64 1st Fighter
176 .. 239 64 2nd Fighter
240 .. 255 16 basic colors
*/
#define MAXFRAMESKIP 5
struct SFpsCounter
{
int m_iLastCheck; // Last second then Tick() was called
int m_iFrames; // The number of frames in this second so far
int m_iFps; // The number of frames in the last second
void Reset()
{
m_iLastCheck = m_iFrames = m_iFps = 0;
}
void Tick()
{
int iSecond = SDL_GetTicks() / 1000;
if ( iSecond > m_iLastCheck )
{
m_iLastCheck = iSecond;
m_iFps = m_iFrames;
m_iFrames = 0;
fprintf( stderr, "%d ", m_iFps);
}
++m_iFrames;
}
} oFpsCounter;
/***************************************************************************
GAME PUBLIC METHODS
***************************************************************************/
Game::Game( bool a_bIsReplay, bool a_bDebug)
{
m_bIsReplay = a_bIsReplay;
m_bDebug = a_bDebug;
m_poBackground = LoadBackground( "level1.png", 64 );
m_poDoodads = LoadBackground( "Doodads.png", 48, 64 );
m_aiRoundsWonByPlayer[0] = m_aiRoundsWonByPlayer[1] = 0;
m_iNumberOfRounds = 0;
}
Game::~Game()
{
SDL_FreeSurface( m_poBackground );
m_poBackground = NULL;
SDL_FreeSurface( m_poDoodads );
m_poDoodads = NULL;
}
int Game::Run()
{
do
{
m_sReplayString.clear();
m_aReplayOffsets.clear();
DoOneRound();
if ( g_oState.m_bQuitFlag
|| SState::IN_DEMO == g_oState.m_enGameMode )
{
return -1;
}
} while ( m_aiRoundsWonByPlayer[0] < 2
&& m_aiRoundsWonByPlayer[1] < 2
&& m_iNumberOfRounds < 3 );
if ( m_aiRoundsWonByPlayer[1] > m_aiRoundsWonByPlayer[0] ) return 1;
if ( m_aiRoundsWonByPlayer[1] < m_aiRoundsWonByPlayer[0] ) return 0;
return -1;
}
std::string& Game::GetReplay()
{
return m_sReplayString;
}
/***************************************************************************
GAME DRAWING METHODS
***************************************************************************/
void Game::DrawHitPointDisplay()
{
int hp1 = g_oBackend.m_aoPlayers[0].m_iHitPoints;// * 100 / g_oState.m_iHitPoints;
int hp2 = g_oBackend.m_aoPlayers[1].m_iHitPoints;// * 100 / g_oState.m_iHitPoints;
SDL_Rect src, dst;
src.y = 154;
src.h = 20;
dst.y = 15;
// Player 1, green part.
dst.x = 40;
src.x = 0;
src.w = hp1*2;
SDL_BlitSurface( m_poDoodads, &src, gamescreen, &dst );
// Player 1, red part.
dst.x += hp1*2;
src.x = (100 + hp1)*2;
src.w = (100-hp1)*2;
SDL_BlitSurface( m_poDoodads, &src, gamescreen, &dst );
// Player 2, red part.
dst.x = 400;
src.x = 200;
src.w = (100-hp2)*2;
SDL_BlitSurface( m_poDoodads, &src, gamescreen, &dst );
// Player 2, green part.
dst.x = 400 + (100-hp2)*2;
src.x = (100-hp2)*2;
src.w = hp2*2;
SDL_BlitSurface( m_poDoodads, &src, gamescreen, &dst );
// "Won" icon for Player 1
src.x = 0; src.y = 276; src.w = 32; src.h = 32;
if ( m_aiRoundsWonByPlayer[0] > 0 )
{
dst.x = 4; dst.y = 11;
SDL_BlitSurface( m_poDoodads, &src, gamescreen, &dst );
}
if ( m_aiRoundsWonByPlayer[1] > 0 )
{
dst.x = 604; dst.y = 11;
SDL_BlitSurface( m_poDoodads, &src, gamescreen, &dst );
}
}
void Game::DrawBackground()
{
sge_Blit( m_poBackground, gamescreen,
g_oBackend.m_iBgX, g_oBackend.m_iBgY,
0, 0, SCREENWIDTH, SCREENHEIGHT );
}
void Game::DrawPoly( const char* sName, int color )
{
AV *iList;
int n;
iList = get_av( sName, FALSE );
if ( iList == NULL )
{
return;
}
n = av_len( iList ) + 1;
if ( n< 2 )
{
return;
}
for ( int i=0; i<n; i += 2 )
{
int j = (i+2) % n;
int x1 = SvIV( *av_fetch( iList, i, false) );
int y1 = SvIV( *av_fetch( iList, i+1, false) );
int x2 = SvIV( *av_fetch( iList, j, false) );
int y2 = SvIV( *av_fetch( iList, j+1, false) );
sge_Line( gamescreen, x1, y1, x2, y2, color ) ;
}
}
void Game::DrawDoodads()
{
for ( int i=0; i<g_oBackend.m_iNumDoodads; ++i )
{
Backend::SDoodad& roDoodad = g_oBackend.m_aoDoodads[i];
if ( 0 == roDoodad.m_iType )
{
// Handle text doodads
const char *s = roDoodad.m_sText.c_str();
int iWidth = sge_BF_TextSize(fastFont, s).w;
int iDoodadX = roDoodad.m_iX - iWidth/2;
if ( iDoodadX + iWidth > 640 ) iDoodadX = 640 - iWidth;
if ( iDoodadX < 0 ) iDoodadX = 0;
int iDoodadY = roDoodad.m_iY;
sge_BF_textout( gamescreen, fastFont, s, iDoodadX, iDoodadY );
continue;
}
SDL_Rect rsrc, rdst;
rdst.x = roDoodad.m_iX;
rdst.y = roDoodad.m_iY;
rsrc.x = 64 * roDoodad.m_iFrame;
rsrc.y = 0;
rsrc.w = 64;
rsrc.h = 64;
SDL_BlitSurface( m_poDoodads, &rsrc, gamescreen, &rdst );
//debug( "Doodad x: %d, y: %d, t: %d, f: %d\n", dx, dy, dt, df );
}
}
void Game::Draw()
{
DrawBackground();
for ( int i=0; i<2; ++i )
{
int iFrame = g_oBackend.m_aoPlayers[i].m_iFrame;
if ( 0 != iFrame )
{
(i ? pack2 : pack1)->draw( ABS(iFrame)-1,
g_oBackend.m_aoPlayers[i].m_iX,
g_oBackend.m_aoPlayers[i].m_iY,
iFrame<0 );
}
}
if ( m_bDebug )
{
DrawPoly( "p1head", C_LIGHTRED );
DrawPoly( "p1body", C_LIGHTGREEN );
DrawPoly( "p1legs", C_LIGHTBLUE );
DrawPoly( "p1hit", C_YELLOW );
DrawPoly( "p2head", C_LIGHTRED );
DrawPoly( "p2body", C_LIGHTGREEN );
DrawPoly( "p2legs", C_LIGHTBLUE );
DrawPoly( "p2hit", C_YELLOW );
}
DrawDoodads();
DrawHitPointDisplay();
if ( Ph_NORMAL == m_enGamePhase )
{
char s[100];
sprintf( s, "%d", g_oBackend.m_iGameTime );
DrawTextMSZ( s, inkFont, 320, 10, AlignHCenter, C_LIGHTCYAN, gamescreen );
}
else if ( Ph_START == m_enGamePhase )
{
char s[100];
sprintf( s, "Round %d", m_iNumberOfRounds+1 );
DrawTextMSZ( s, inkFont, 320, 200, AlignHCenter, C_WHITE, gamescreen );
}
else if ( Ph_REWIND == m_enGamePhase )
{
DrawTextMSZ( "REW", inkFont, 320, 10, AlignHCenter, C_WHITE, gamescreen );
}
else if ( Ph_SLOWFORWARD == m_enGamePhase )
{
DrawTextMSZ( "REPLAY", inkFont, 320, 10, AlignHCenter, C_WHITE, gamescreen );
}
else if ( Ph_REPLAY == m_enGamePhase )
{
DrawTextMSZ( "DEMO", inkFont, 320, 10, AlignHCenter, C_WHITE, gamescreen );
}
if ( oFpsCounter.m_iFps > 0 )
{
sge_BF_textoutf( gamescreen, fastFont, 2, 2, "%d fps", oFpsCounter.m_iFps );
}
SDL_Flip( gamescreen );
}
/***************************************************************************
GAME PROTECTED METHODS
***************************************************************************/
/**
This method reads and updates the game's variables. In replay mode,
this is done by parsing the replay string. Otherwise the perl
backend is advanced the given number of steps.
Whichever the case, the variables will be available in g_oBackend.
*/
void Game::Advance( int a_iNumFrames )
{
if ( m_bIsReplay )
{
// Replay mode...
m_iFrame += a_iNumFrames;
if ( m_iFrame >= ((int)m_aReplayOffsets.size())-1 ) m_iFrame = m_aReplayOffsets.size() - 2;
if ( m_iFrame <= 0 ) m_iFrame = 0;
std::string sFrameDesc = m_sReplayString.substr(
m_aReplayOffsets[m_iFrame],
m_aReplayOffsets[m_iFrame+1] - m_aReplayOffsets[m_iFrame] );
g_oBackend.ReadFromString( sFrameDesc );
return;
}
while ( a_iNumFrames > 0 )
{
-- a_iNumFrames;
std::string sFrameDesc;
g_oBackend.AdvancePerl();
g_oBackend.ReadFromPerl();
g_oBackend.PlaySounds();
g_oBackend.WriteToString( sFrameDesc );
m_sReplayString += sFrameDesc;
m_sReplayString += '\n';
m_aReplayOffsets.push_back( m_sReplayString.size() );
}
}
/** ProcessEvents reads events from the SDL event system.
Relevant key events are fed to the backend.
Esc brings up the menu.
Returns 1 on quit event, 0 otherwise.
*/
int Game::ProcessEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
g_oState.m_bQuitFlag = true;
return 1;
case SDL_KEYDOWN:
{
if ( event.key.keysym.sym == SDLK_ESCAPE )
return 1;
if ( Ph_NORMAL != m_enGamePhase )
break;
for (int i=0; i<2; i++)
{
for (int j=0; j<9; j++ )
{
if (g_oState.m_aiPlayerKeys[i][j] == event.key.keysym.sym)
{
PERLCALL( "KeyDown", i, j );
}
}
}
break;
}
case SDL_KEYUP:
{
if ( Ph_NORMAL != m_enGamePhase )
break;
for (int i=0; i<2; i++)
{
for (int j=0; j<9; j++ )
{
if (g_oState.m_aiPlayerKeys[i][j] == event.key.keysym.sym)
{
PERLCALL( "KeyUp", i, j );
}
}
}
break;
}
} // End of switch
} // End of while SDL_PollEvent;
return 0;
}
void Game::HurryUp()
{
Audio->PlaySample( "aroooga.voc" );
DrawGradientText( "HURRY UP!", titleFont, 200, gamescreen );
SDL_Delay( 1000 );
Audio->PlaySample( "machine_start.voc" );
}
void Game::TimeUp()
{
DrawGradientText( "TIME IS UP!", titleFont, 200, gamescreen );
SDL_Delay( 1000 );
}
void Game::InstantReplay( int a_iKoAt )
{
int iCurrentFrame = m_aReplayOffsets.size() - 200;
int iThisTick, iLastTick, iGameSpeed;
m_enGamePhase = Ph_REWIND;
iGameSpeed = 8;
iThisTick = SDL_GetTicks() / iGameSpeed;
iLastTick = iThisTick - 1;
while ( iCurrentFrame < (int)m_aReplayOffsets.size() - 150 )
{
// 1. Wait for the next tick (on extremely fast machines..)
while (iThisTick == iLastTick)
{
iThisTick = SDL_GetTicks() / iGameSpeed;
if ( iThisTick==iLastTick ) SDL_Delay(1);
}
// 2. Advance as many ticks as necessary..
int iNumTicks = iThisTick - iLastTick;
if ( iNumTicks > 10 ) iNumTicks = 10;
if ( iNumTicks < 0 ) iNumTicks = 0;
iCurrentFrame += ( Ph_REWIND == m_enGamePhase ) ? -iNumTicks : +iNumTicks ;
if ( Ph_REWIND == m_enGamePhase
&& ( iCurrentFrame < a_iKoAt - 200 || iCurrentFrame <= 0 )
)
{
m_enGamePhase = Ph_SLOWFORWARD;
iGameSpeed = 16;
SDL_Delay(500);
}
iLastTick = iThisTick;
if ( iCurrentFrame < 0 ) iCurrentFrame = 0;
m_iFrame = iCurrentFrame;
if ( m_iFrame >= ((int)m_aReplayOffsets.size())-1 ) m_iFrame = m_aReplayOffsets.size() - 2;
if ( m_iFrame <= 0 ) m_iFrame = 0;
std::string sFrameDesc = m_sReplayString.substr(
m_aReplayOffsets[m_iFrame],
m_aReplayOffsets[m_iFrame+1] - m_aReplayOffsets[m_iFrame] );
//debug( "PB: Frame %d ofs %d-%d; data: '%s'\n", m_iFrame,
// m_aReplayOffsets[m_iFrame], m_aReplayOffsets[m_iFrame+1], sFrameDesc.c_str() );
g_oBackend.ReadFromString( sFrameDesc );
if ( ProcessEvents() )
{
break;
}
oFpsCounter.Tick();
// 3. Draw the next game screen..
Draw();
if ( g_oState.m_bQuitFlag )
{
break;
}
}
}
void Game::DoOneRound()
{
m_enGamePhase = Ph_START;
g_oBackend.PerlEvalF( "GameStart(%d);", g_oState.m_iHitPoints );
int iKoFrame = -1;
double dGameTime = 2 * 1000;
int iThisTick, iLastTick, iGameSpeed;
bool bHurryUp = false;
iGameSpeed = 12;
iThisTick = SDL_GetTicks() / iGameSpeed;
iLastTick = iThisTick - 1;
oFpsCounter.Reset();
// 1. DO THE NORMAL GAME ROUND and HURRYUP
while ( dGameTime > 0 )
{
// 1. Wait for the next tick (on extremely fast machines..)
while (iThisTick == iLastTick)
{
iThisTick = SDL_GetTicks() / iGameSpeed;
if ( iThisTick==iLastTick ) SDL_Delay(1);
}
// 2. Advance as many ticks as necessary..
int iNumTicks = iThisTick - iLastTick;
if ( iNumTicks > MAXFRAMESKIP ) iNumTicks = MAXFRAMESKIP;
Advance( iNumTicks );
dGameTime -= iNumTicks * iGameSpeed;
if ( Ph_START == m_enGamePhase )
{
if ( dGameTime < 0 )
{
m_enGamePhase = Ph_NORMAL;
dGameTime = g_oState.m_iGameTime * 1000;
}
}
else if ( Ph_NORMAL == m_enGamePhase )
{
if ( dGameTime < 10 * 1000
&& !bHurryUp )
{
bHurryUp = true;
HurryUp();
iGameSpeed = iGameSpeed * 3 / 4;
}
if ( g_oBackend.m_bKO )
{
m_enGamePhase = Ph_KO;
dGameTime = 10 * 1000;
iKoFrame = m_aReplayOffsets.size();
}
else if ( dGameTime < 0 )
{
m_enGamePhase = Ph_TIMEUP;
TimeUp();
break;
}
}
g_oBackend.m_iGameTime = (int) ((dGameTime + 500.0) / 1000.0);
iLastTick = iThisTick;
if ( ProcessEvents() )
{
break;
}
oFpsCounter.Tick();
// 3. Draw the next game screen..
Draw();
if ( g_oBackend.m_iGameOver || g_oState.m_bQuitFlag )
{
break;
}
}
// 3. DO THE REPLAY (IF THERE WAS A KO)
if ( iKoFrame>0 )
{
InstantReplay( iKoFrame );
}
// 4. END OF ROUND
int p1h = g_oBackend.m_aoPlayers[0].m_iHitPoints;
int p2h = g_oBackend.m_aoPlayers[1].m_iHitPoints;
debug( "Game over; p1h = %d; p2h = %d\n", p1h, p2h );
if ( p1h > p2h ) ++m_aiRoundsWonByPlayer[0];
if ( p2h > p1h ) ++m_aiRoundsWonByPlayer[1];
++m_iNumberOfRounds;
}
void Game::DoReplay( const char* a_pcReplayFile )
{
std::ifstream oInput( a_pcReplayFile );
int iPlayer1, iPlayer2;
oInput >> iPlayer1 >> iPlayer2;
std::string sLine;
std::getline( oInput, sLine );
SetPlayer( 0, (FighterEnum) iPlayer1 );
SetPlayer( 1, (FighterEnum) iPlayer2 );
int iCurrentFrame = 0;
int iThisTick, iLastTick, iGameSpeed;
m_enGamePhase = Ph_REPLAY;
iGameSpeed = 12;
iThisTick = SDL_GetTicks() / iGameSpeed;
iLastTick = iThisTick - 1;
while ( !oInput.eof() )
{
// 1. Wait for the next tick (on extremely fast machines..)
while (iThisTick == iLastTick)
{
iThisTick = SDL_GetTicks() / iGameSpeed;
if ( iThisTick==iLastTick ) SDL_Delay(1);
}
// 2. Advance as many ticks as necessary..
int iNumTicks = iThisTick - iLastTick;
if ( iNumTicks > 5 ) iNumTicks = 5;
for ( int i=0; i< iNumTicks; ++i )
{
std::getline( oInput, sLine );
}
+ if ( 0 == sLine.size() )
+ {
+ break;
+ }
iLastTick = iThisTick;
g_oBackend.ReadFromString( sLine );
if ( ProcessEvents() )
{
break;
}
oFpsCounter.Tick();
// 3. Draw the next game screen..
Draw();
if ( g_oState.m_bQuitFlag )
{
break;
}
}
}
int DoGame( char* a_pcReplayFile, bool a_bIsReplay, bool a_bDebug )
{
Game oGame( a_bIsReplay, a_bDebug );
if ( a_bIsReplay )
{
if ( NULL == a_pcReplayFile )
{
return 0;
}
oGame.DoReplay( a_pcReplayFile );
return 0;
}
else
{
int iRetval = oGame.Run();
if ( NULL != a_pcReplayFile )
{
std::ofstream oOutput( a_pcReplayFile );
oOutput << Fighter1 << ' ' << Fighter2 << '\n' << oGame.GetReplay();
}
return iRetval;
}
}
diff --git a/src/PlayerSelect.cpp b/src/PlayerSelect.cpp
index 065d504..644005b 100644
--- a/src/PlayerSelect.cpp
+++ b/src/PlayerSelect.cpp
@@ -1,496 +1,497 @@
/***************************************************************************
PlayerSelect.cpp - description
-------------------
begin : Sun Dec 8 2002
copyright : (C) 2002 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include <stdio.h>
-#include <SDL/SDL.h>
-#include <SDL/SDL_video.h>
-#include <SDL/SDL_image.h>
+#include "SDL.h"
+#include "SDL_video.h"
+#include "SDL_image.h"
#include "sge_primitives.h"
#include "common.h"
#include "Audio.h"
#include "gfx.h"
#include "RlePack.h"
#include "Backend.h"
#include "State.h"
#define CHOOSERLEFT 158
#define CHOOSERTOP 98
#define CHOOSERHEIGHT 80
#define CHOOSERWIDTH 80
#define CHOOSERROWS 4
#define CHOOSERCOLS 4
#ifndef NULL
#define NULL 0
#endif
/***************************************************************************
PUBLIC EXPORTED VARIABLES
***************************************************************************/
FighterEnum Fighter1 = ZOLI;
FighterEnum Fighter2 = ZOLI;
RlePack* pack1;
RlePack* pack2;
/***************************************************************************
PRIVATE VARIABLES (perl variable space)
***************************************************************************/
int p1 = 0;
int p2 = 3;
bool done1 = false;
bool done2 = false;
FighterEnum ChooserCells[CHOOSERROWS][CHOOSERCOLS] = {
{ ZOLI, UPI, CUMI, SIRPI },
{ ULMAR, MACI, BENCE, GRIZLI },
{ AMBRUS, DESCANT, SURBA, DANI },
{ UNKNOWN, KINGA, MISI, UNKNOWN },
};
bool IsFighterAvailable( FighterEnum a_enFighter )
{
static bool g_abFighterAvailable[ LASTFIGHTER ] =
{
false,
true, true, true, true,
true, true, true, true,
true, false, false, false,
false, false
};
if ( a_enFighter < UNKNOWN
|| a_enFighter >= LASTFIGHTER )
{
return false;
}
return g_abFighterAvailable[ a_enFighter ];
}
RlePack* LoadFighter( FighterEnum fighter, int offset )
{
char filename[FILENAME_MAX+1];
const char* s;
switch (fighter)
{
case ZOLI: s = "ZOLIDATA.DAT"; break;
case UPI: s = "UPIDATA.DAT"; break;
case ULMAR: s = "ULMARDATA.DAT"; break;
case CUMI: s = "CUMIDATA.DAT"; break;
case SIRPI: s = "SIRPIDATA.DAT"; break;
case MACI: s = "MACIDATA.DAT"; break;
case BENCE: s = "BENCEDATA.DAT"; break;
case DESCANT: s = "DESCANTDATA.DAT"; break;
case GRIZLI: s = "GRIZLIDATA.DAT"; break;
default: s = "ZOLIDATA.DAT"; break;
}
strcpy( filename, DATADIR );
strcat( filename, "/characters/" );
strcat( filename, s );
RlePack* pack = new RlePack( filename );
pack->offsetSprites( offset );
SDL_SetColors( gamescreen, pack->getPalette(), offset, 64 );
return pack;
}
void TintFighter( RlePack* fighter, TintEnum tint, int offset )
{
if ( tint == RANDOM_TINT )
{
switch (rand() % 4 )
{
case 0: tint = ZOMBIE_TINT; break;
case 1: tint = GRAY_TINT; break;
case 2: tint = DARK_TINT; break;
case 3: tint = INVERTED_TINT; break;
}
}
SDL_Color palette[64];
int i;
memcpy( palette, fighter->getPalette(), sizeof(palette) );
switch( tint )
{
case ZOMBIE_TINT:
{
for ( i=0; i<64; ++i )
{
palette[i].r = 0;
palette[i].b = 0;
}
break;
}
case GRAY_TINT:
{
int j;
for ( i=0; i<64; ++i )
{
j = (palette[i].r + palette[i].g + palette[i].b)/4;
palette[i].r = j;
palette[i].g = j;
palette[i].b = j;
}
break;
}
case DARK_TINT:
{
for ( i=0; i<64; ++i )
{
palette[i].r = int(palette[i].r) * 2 / 3;
palette[i].g = int(palette[i].g) * 2 / 3;
palette[i].b = int(palette[i].b) * 2 / 3;
}
break;
}
case INVERTED_TINT:
{
for ( i=0; i<64; ++i )
{
palette[i].r = 255 - palette[i].r;
palette[i].g = 255 - palette[i].g;
palette[i].b = 255 - palette[i].b;
}
break;
}
default:
break;
}
SDL_SetColors( gamescreen, palette, offset, 64 );
}
void SetPlayer( int player, FighterEnum fighter )
{
int offset = player ? 176 : 112;
RlePack* pack = LoadFighter( fighter, offset );
if ( player )
{
delete pack2;
pack2 = pack;
}
else
{
delete pack1;
pack1 = pack;
}
PERLCALL( "SetPlayerNumber", player, fighter );
FighterEnum& thisPlayer = player ? Fighter2 : Fighter1;
thisPlayer = fighter;
if ( pack2 )
{
TintFighter( pack2, Fighter1 == Fighter2 ? RANDOM_TINT : NO_TINT, 176 );
}
}
void handleKey( int player, int key )
{
int& p = player ? p2 : p1;
int oldp = p;
bool& done = player ? done2 : done1;
if ( done )
{
return;
}
switch ( key )
{
case 0: // up
if ( p >= CHOOSERCOLS ) p -= CHOOSERCOLS;
break;
case 1: // down
if ( (p/CHOOSERCOLS) < (CHOOSERROWS-1) ) p += CHOOSERCOLS;
break;
case 2: // left
if ( (p % CHOOSERCOLS) > 0 ) p--;
break;
case 3: // right
if ( (p % CHOOSERCOLS) < (CHOOSERCOLS-1) ) p++;
break;
default:
if ( ChooserCells[p/4][p%4] )
{
done = true;
PERLCALL( "PlayerSelected", player, 0 );
Audio->PlaySample("magic.voc");
return;
}
}
if ( !IsFighterAvailable( ChooserCells[p/CHOOSERCOLS][p%CHOOSERCOLS] ) )
{
p = oldp;
}
if ( oldp != p )
{
Audio->PlaySample("strange_quack.voc");
SetPlayer( player, ChooserCells[p/CHOOSERCOLS][p%CHOOSERCOLS] );
}
}
void drawRect( int pos, int color )
{
int row = pos / CHOOSERCOLS;
int col = pos % CHOOSERCOLS;
SDL_Rect r, r1;
r.x = CHOOSERLEFT + col * CHOOSERWIDTH;
r.y = CHOOSERTOP + row * CHOOSERHEIGHT;
r.w = CHOOSERWIDTH + 5;
r.h = 5;
r1 = r;
SDL_FillRect( gamescreen, &r1, color );
r.y += CHOOSERHEIGHT;
r1 = r;
SDL_FillRect( gamescreen, &r1, color );
r.y -= CHOOSERHEIGHT;
r.w = 5;
r.h = CHOOSERHEIGHT + 5;
r1 = r;
SDL_FillRect( gamescreen, &r1, color );
r.x += CHOOSERWIDTH;
r1 = r;
SDL_FillRect( gamescreen, &r1, color );
}
void checkPlayer( SDL_Surface* background, int row, int col )
{
int x1, y1;
x1 = CHOOSERLEFT + col * CHOOSERWIDTH +5;
y1 = CHOOSERTOP + row * CHOOSERHEIGHT +5;
sge_Line(background, x1+5, y1+5, x1 + CHOOSERWIDTH-10, y1 + CHOOSERHEIGHT-10, 252);
sge_Line(background, x1 + CHOOSERWIDTH-10, y1+5, x1+5, y1 + CHOOSERHEIGHT-10, 252);
x1++;
sge_Line(background, x1+5, y1+5, x1 + CHOOSERWIDTH-10, y1 + CHOOSERHEIGHT-10, 252);
sge_Line(background, x1 + CHOOSERWIDTH-10, y1+5, x1+5, y1 + CHOOSERHEIGHT-10, 252);
y1++;
sge_Line(background, x1+5, y1+5, x1 + CHOOSERWIDTH-10, y1 + CHOOSERHEIGHT-10, 252);
sge_Line(background, x1 + CHOOSERWIDTH-10, y1+5, x1+5, y1 + CHOOSERHEIGHT-10, 252);
x1--;
sge_Line(background, x1+5, y1+5, x1 + CHOOSERWIDTH-10, y1 + CHOOSERHEIGHT-10, 252);
sge_Line(background, x1 + CHOOSERWIDTH-10, y1+5, x1+5, y1 + CHOOSERHEIGHT-10, 252);
}
void PlayerSelect()
{
SDL_FillRect( gamescreen, NULL, C_BLACK );
SDL_Flip( gamescreen );
char filename[FILENAME_MAX+1];
strcpy( filename, DATADIR );
strcat( filename, "/gfx/" );
strcat( filename, "PlayerSelect.png" );
SDL_Surface* background = IMG_Load( filename );
if (!background)
{
debug( "Can't load file: %s\n", filename );
g_oState.m_bQuitFlag = true;
return;
}
SDL_Palette* pal = background->format->palette;
if ( pal )
{
int ncolors = pal->ncolors;
if (ncolors>111) ncolors = 111;
SDL_SetColors( gamescreen, pal->colors, 0, ncolors );
}
background = SDL_DisplayFormat( background );
DrawGradientText( "Choose A Fighter Dammit", titleFont, 10, background );
-
- for ( int i=0; i<CHOOSERROWS; ++i )
+
+ int i;
+ for ( i=0; i<CHOOSERROWS; ++i )
{
for ( int j=0; j<CHOOSERCOLS; ++j )
{
if ( !IsFighterAvailable(ChooserCells[i][j]) &&
UNKNOWN != ChooserCells[i][j] )
{
checkPlayer( background, i, j );
}
}
}
if (pack1) SDL_SetColors( gamescreen, pack1->getPalette(), 112, 64 );
if (pack2) SDL_SetColors( gamescreen, pack2->getPalette(), 176, 64 );
PERLEVAL( "SelectStart();" );
done1 = done2 = false;
int thisTick, lastTick, gameSpeed;
gameSpeed = 12 ;
thisTick = SDL_GetTicks() / gameSpeed;
lastTick = thisTick - 1;
- int i = 0;
+ i = 0;
bool bDraw = true;
int over = 0;
int iCourtain = 0;
int iCourtainSpeed = 0;
int iCourtainTime = 80;
SDL_Event event;
while (1)
{
// 1. Wait for the next tick (on extremely fast machines..)
while (1)
{
thisTick = SDL_GetTicks() / gameSpeed;
if ( thisTick==lastTick )
{
SDL_Delay(1);
}
else
{
break;
}
}
// 2. Advance as many ticks as necessary..
if ( iCourtainTime > 0 )
{
int iAdvance = thisTick - lastTick;
if ( iAdvance > 5 ) iAdvance = 5;
if ( iCourtain + iCourtainSpeed * iCourtainTime /2 < 320 * 4 )
iCourtainSpeed += iAdvance;
else
iCourtainSpeed -= iAdvance;
iCourtain += iCourtainSpeed * iAdvance;
iCourtainTime -= iAdvance;
if ( iCourtainTime > 0 )
{
SDL_Rect oRect;
oRect.x = 320 - iCourtain/4; oRect.y = 0;
oRect.w = iCourtain / 2; oRect.h = gamescreen->h;
if ( oRect.x < 0 ) oRect.x = 0;
if ( oRect.w > gamescreen->w ) oRect.w = gamescreen->w;
SDL_SetClipRect( gamescreen, &oRect );
}
else
{
SDL_SetClipRect( gamescreen, NULL );
}
}
int iNumFrames = thisTick - lastTick;
if ( iNumFrames>5 ) iNumFrames = 5;
for ( int i=0; i<iNumFrames; ++i )
{
g_oBackend.AdvancePerl();
}
lastTick = thisTick;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
g_oState.m_bQuitFlag = true;
break;
case SDL_KEYDOWN:
{
if ( event.key.keysym.sym == SDLK_ESCAPE )
{
DoMenu( false );
break;
}
for (int i=0; i<2; i++)
{
for (int j=0; j<9; j++ )
{
if (g_oState.m_aiPlayerKeys[i][j] == event.key.keysym.sym)
{
drawRect( p1, 240 );
drawRect( p2, 240 );
handleKey( i, j );
}
}
}
}
break;
} // switch statement
} // Polling events
int p1x = SvIV(get_sv("p1x", FALSE));
int p1y = SvIV(get_sv("p1y", FALSE));
int p1f = SvIV(get_sv("p1f", FALSE));
int p2x = SvIV(get_sv("p2x", FALSE));
int p2y = SvIV(get_sv("p2y", FALSE));
int p2f = SvIV(get_sv("p2f", FALSE));
over = SvIV(get_sv("over", FALSE));
SDL_BlitSurface( background, NULL, gamescreen, NULL );
if (p1f) pack1->draw( ABS(p1f)-1, p1x, p1y, p1f<0 );
if (p2f) pack2->draw( ABS(p2f)-1, p2x, p2y, p2f<0 );
if ( !done1) drawRect( p1, 250 );
if ( !done2) drawRect( p2, 253 );
SDL_Flip( gamescreen );
if (over || g_oState.m_bQuitFlag || SState::IN_DEMO == g_oState.m_enGameMode) break;
}
SDL_FreeSurface( background );
SDL_SetClipRect( gamescreen, NULL );
return;
}
diff --git a/src/RlePack.cpp b/src/RlePack.cpp
index d6407b6..6e58f47 100644
--- a/src/RlePack.cpp
+++ b/src/RlePack.cpp
@@ -1,544 +1,544 @@
/***************************************************************************
RlePack.cpp - description
-------------------
begin : Mon Sep 24 2001
copyright : (C) 2001 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <SDL/SDL.h>
-#include <SDL/SDL_video.h>
+#include "SDL.h"
+#include "SDL_video.h"
#include "common.h"
#include "RlePack.h"
typedef struct RLE_SPRITE /* a RLE compressed sprite */
{
int w, h; /* width and height in pixels */
int color_depth; /* color depth of the image */
int size; /* size of sprite data in bytes */
signed char dat[0];
} RLE_SPRITE;
struct RlePack_P
{
SDL_Color palette[256];
int count, arraysize;
RLE_SPRITE** sprites;
};
RlePack::RlePack( const char* filename )
{
p = new RlePack_P;
p->count = p->arraysize = 0;
p->sprites = NULL;
//@ Load file and stuff
FILE* f;
f = fopen( filename, "rb" );
if (f==NULL)
{
debug( "Can't open file '%s'.\n", filename );
return;
}
int datacount;
#define READDW(I) { \
unsigned char data[4]; \
fread( data, 4, 1, f ); \
(I) = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3]; }
#define READW(I) { \
unsigned char data[2]; \
fread( data, 2, 1, f ); \
(I) = (data[0]<<8) + data[1]; }
#define READCH(S,C) { \
fread( S, C, 1, f ); S[C] = 0; }
fseek( f, 8, SEEK_SET ); // Skip header
READDW( datacount );
debug( "File '%s' contains %d entries.\n", filename, datacount );
if (datacount>500) datacount = 500; // Sanity
p->arraysize = datacount;
- p->sprites = new (RLE_SPRITE*)[ datacount ];
+ p->sprites = new RLE_SPRITE*[ datacount ];
while( (!feof(f)) && (!ferror(f)) && (datacount>0) )
{
char s[10];
READCH( s, 4 );
if ( !strcmp( s, "prop" )) // Found a property
{
fseek( f, 4, SEEK_CUR );
unsigned int propsize;
READDW( propsize );
fseek( f, propsize, SEEK_CUR );
}
else if (!strcmp( s, "RLE " )) // Found an RLE_SPRITE
{
datacount--;
unsigned int length, bpp, width, height, size;
READDW( length );
READDW( length );
READW( bpp );
READW( width );
READW( height );
READDW( size );
RLE_SPRITE* sprite = (RLE_SPRITE*) malloc( sizeof(RLE_SPRITE) + size );
p->sprites[ p->count ] = sprite;
(p->count)++;
sprite->w = width;
sprite->h = height;
sprite->color_depth = bpp;
sprite->size = size;
fread( sprite->dat, 1, size, f );
}
else if (!strcmp( s, "PAL ")) // Found a palette
{
datacount--;
unsigned int length, pallength;
READDW( length );
READDW( length );
pallength = length>1024 ? 1024 : length;
pallength /= 4;
- for (uint i=0; i< pallength; i++)
+ for (unsigned int i=0; i< pallength; i++)
{
char c[4];
fread( c, 4, 1, f );
p->palette[i].r = c[0]*4;
p->palette[i].g = c[1]*4;
p->palette[i].b = c[2]*4;
p->palette[i].unused = 0;
}
fseek( f, length - pallength*4, SEEK_CUR );
}
else // Found something else
{
debug( "Unknown: %s.", s );
datacount--;
unsigned int length;
READDW( length );
READDW( length );
fseek( f, length, SEEK_CUR );
}
}
fclose( f );
}
RlePack::~RlePack()
{
if (!p)
return;
if (p->sprites)
{
for ( int i=0; i<p->count; ++i )
{
delete p->sprites[i];
p->sprites[i] = NULL;
}
delete[] p->sprites;
p->sprites = NULL;
}
delete( p );
p = NULL;
}
void OffsetRLESprite( RLE_SPRITE* spr, int offset )
{
if (!spr || !offset) return;
signed char *s = spr->dat;
signed char c;
int y;
for (y=0; y<spr->h; y++)
{
c = *s++;
while (c)
{
// For positive c: solid pixels.
for ( ; c>0; c-- )
{
*s = (*s) + offset;
s++;
}
c = *s++;
}
}
}
void RlePack::offsetSprites( int offset )
{
if ( (offset<=0) || (offset>255) )
return;
int i;
// Offset every RLE_SPRITE
for ( i=0; i<p->count; ++i )
{
OffsetRLESprite( p->sprites[i], offset );
}
}
SDL_Color* RlePack::getPalette()
{
return p->palette;
}
void draw_rle_sprite_v_flip( RLE_SPRITE* src, int dx, int dy )
{
#define RLE_PTR signed char*
#define RLE_IS_EOL(c) ((c) == 0)
#define PIXEL_PTR unsigned char*
#define OFFSET_PIXEL_PTR(p,x) ((PIXEL_PTR) (p) + (x))
#define INC_PIXEL_PTR(p) ((p)++)
#define DEC_PIXEL_PTR(p) ((p)--)
#define PUT_PIXEL(p,c) (*((unsigned char *)(p)) = (c))
//#define PUT_PIXEL(p,c) bmp_write8((unsigned long) (p), (c))
int x, y, w, h; // width and height of visible area
int dxbeg, dybeg; // beginning in destination
int sxbeg, sybeg; // beginning in source
RLE_PTR s;
SDL_Surface* dst = gamescreen;
// Clip to dst->clip_rect
int dst_cl = dst->clip_rect.x;
int dst_cr = dst->clip_rect.w + dst_cl;
int dst_ct = dst->clip_rect.y;
int dst_cb = dst->clip_rect.h + dst_ct;
// if (dst->clip)
if (1)
{
int tmp;
dxbeg = dx;
if ( dst_cl > dx ) dxbeg = dst_cl;
tmp = dx + src->w - dst_cr;
sxbeg = ((tmp < 0) ? 0 : tmp);
tmp = dx + src->w;
if (tmp > dst_cr ) tmp = dst_cr;
w = tmp - dxbeg;
if (w <= 0)
return;
tmp = dst_ct - dy;
sybeg = ((tmp < 0) ? 0 : tmp);
dybeg = sybeg + dy;
tmp = dst_cb - dy;
h = ((tmp > src->h) ? src->h : tmp) - sybeg;
if (h <= 0)
return;
}
else {
w = src->w;
h = src->h;
sxbeg = 0;
sybeg = 0;
dxbeg = dx;
dybeg = dy;
}
s = (RLE_PTR) (src->dat);
dxbeg += w;
/* Clip top. */
for (y = sybeg - 1; y >= 0; y--) {
long c = *s++;
while (!RLE_IS_EOL(c)) {
if (c > 0)
s += c;
c = *s++;
}
}
//@@@ bmp_select(dst);
/* Visible part. */
for (y = 0; y < h; y++) {
//@@@ PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
PIXEL_PTR d = (PIXEL_PTR) dst->pixels;
d += (dybeg+y)*dst->pitch;
d = OFFSET_PIXEL_PTR( d, dxbeg );
long c = *s++;
/* Clip left. */
for (x = sxbeg; x > 0; ) {
if (RLE_IS_EOL(c))
goto next_line;
else if (c > 0) {
/* Run of solid pixels. */
if ((x - c) >= 0) {
/* Fully clipped. */
x -= c;
s += c;
}
else {
/* Visible on the right. */
c -= x;
s += x;
break;
}
}
else {
/* Run of transparent pixels. */
if ((x + c) >= 0) {
/* Fully clipped. */
x += c;
}
else {
/* Visible on the right. */
c += x;
break;
}
}
c = *s++;
}
/* Visible part. */
for (x = w; x > 0; ) {
if (RLE_IS_EOL(c))
goto next_line;
else if (c > 0) {
/* Run of solid pixels. */
if ((x - c) >= 0) {
/* Fully visible. */
x -= c;
for (c--; c >= 0; s++, DEC_PIXEL_PTR(d), c--) {
unsigned long col = *s;
PUT_PIXEL(d, col);
}
}
else {
/* Clipped on the right. */
c -= x;
for (x--; x >= 0; s++, DEC_PIXEL_PTR(d), x--) {
unsigned long col = *s;
PUT_PIXEL(d, col);
}
break;
}
}
else {
/* Run of transparent pixels. */
x += c;
d = OFFSET_PIXEL_PTR(d, c);
}
c = *s++;
}
/* Clip right. */
while (!RLE_IS_EOL(c)) {
if (c > 0)
s += c;
c = *s++;
}
next_line: ;
}
//@@@bmp_unwrite_line(dst);
}
void draw_rle_sprite( RLE_SPRITE* src, int dx, int dy )
{
#define RLE_PTR signed char*
#define RLE_IS_EOL(c) ((c) == 0)
#define PIXEL_PTR unsigned char*
#define OFFSET_PIXEL_PTR(p,x) ((PIXEL_PTR) (p) + (x))
#define INC_PIXEL_PTR(p) ((p)++)
#define DEC_PIXEL_PTR(p) ((p)--)
#define PUT_PIXEL(p,c) (*((unsigned char *)(p)) = (c))
//#define PUT_PIXEL(p,c) bmp_write8((unsigned long) (p), (c))
int x, y, w, h; // width and height of visible area
int dxbeg, dybeg; // beginning in destination
int sxbeg, sybeg; // beginning in source
RLE_PTR s;
SDL_Surface* dst = gamescreen;
// Clip to dst->clip_rect
int dst_cl = dst->clip_rect.x;
int dst_cr = dst->clip_rect.w + dst_cl;
int dst_ct = dst->clip_rect.y;
int dst_cb = dst->clip_rect.h + dst_ct;
// if (dst->clip)
if (1)
{
int tmp;
tmp = dst_cl - dx;
sxbeg = ((tmp < 0) ? 0 : tmp);
dxbeg = sxbeg + dx;
tmp = dst_cr - dx;
w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
if ( w<=0 ) return;
tmp = dst_ct - dy;
sybeg = ((tmp < 0) ? 0 : tmp);
dybeg = sybeg + dy;
tmp = dst_cb - dy;
h = ((tmp > src->h) ? src->h : tmp) - sybeg;
if ( h<=0 ) return;
}
else {
w = src->w;
h = src->h;
sxbeg = 0;
sybeg = 0;
dxbeg = dx;
dybeg = dy;
}
s = (RLE_PTR) (src->dat);
/* Clip top. */
for (y = sybeg - 1; y >= 0; y--) {
long c = *s++;
while (!RLE_IS_EOL(c)) {
if (c > 0)
s += c;
c = *s++;
}
}
//@@@ bmp_select(dst);
/* Visible part. */
for (y = 0; y < h; y++) {
//@@@ PIXEL_PTR d = OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y), dxbeg);
PIXEL_PTR d = (PIXEL_PTR) dst->pixels;
d += (dybeg+y)*dst->pitch;
d = OFFSET_PIXEL_PTR( d, dxbeg );
long c = *s++;
/* Clip left. */
for (x = sxbeg; x > 0; ) {
if (RLE_IS_EOL(c))
goto next_line;
else if (c > 0) {
/* Run of solid pixels. */
if ((x - c) >= 0) {
/* Fully clipped. */
x -= c;
s += c;
}
else {
/* Visible on the right. */
c -= x;
s += x;
break;
}
}
else {
/* Run of transparent pixels. */
if ((x + c) >= 0) {
/* Fully clipped. */
x += c;
}
else {
/* Visible on the right. */
c += x;
break;
}
}
c = *s++;
}
/* Visible part. */
for (x = w; x > 0; ) {
if (RLE_IS_EOL(c))
goto next_line;
else if (c > 0) {
/* Run of solid pixels. */
if ((x - c) >= 0) {
/* Fully visible. */
x -= c;
for (c--; c >= 0; s++, INC_PIXEL_PTR(d), c--) {
unsigned long col = *s;
PUT_PIXEL(d, col);
}
}
else {
/* Clipped on the right. */
c -= x;
for (x--; x >= 0; s++, INC_PIXEL_PTR(d), x--) {
unsigned long col = *s;
PUT_PIXEL(d, col);
}
break;
}
}
else {
/* Run of transparent pixels. */
x += c;
d = OFFSET_PIXEL_PTR(d, -c);
}
c = *s++;
}
/* Clip right. */
while (!RLE_IS_EOL(c)) {
if (c > 0)
s += c;
c = *s++;
}
next_line: ;
}
//@@@bmp_unwrite_line(dst);
}
void RlePack::draw( int index, int x, int y, bool flipped )
{
if ( (index<0) || (index>=p->count) )
return;
RLE_SPRITE* sprite = p->sprites[index];
if (!sprite)
return;
if ( flipped )
draw_rle_sprite_v_flip( sprite, x, y );
else
draw_rle_sprite( sprite, x, y );
}
diff --git a/src/State.h b/src/State.h
index ca26a6e..9b486e7 100644
--- a/src/State.h
+++ b/src/State.h
@@ -1,97 +1,101 @@
/***************************************************************************
State.h - description
-------------------
begin : Mon Aug 12 2003
copyright : (C) 2003 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#ifndef STATE_H
#define STATE_H
#include "SDL_mixer.h"
#include "SDL_keysym.h"
struct SState
{
enum TGameMode {
IN_DEMO,
IN_SINGLE,
IN_MULTI,
} m_enGameMode;
bool m_bQuitFlag; // true if quit event came
const char* m_pcArgv0; // Set by main to argv[0]
// VARIABLES DURING GAMEPLAY (OR REPLAY)
bool m_bGameOver; // true if the game is over
bool m_bIsReplay; // true if in replay mode
FILE* m_poReplayFile; // the file to load/save replay from/to, or NULL
// CONFIGURATION VARIABLES
int m_iGameTime; // Time of rounds in seconds.
int m_iHitPoints; // The initial number of hit points.
bool m_bFullscreen; // True in fullscreen mode.
int m_iChannels; // 1: mono, 2: stereo
int m_iMixingRate; // The mixing rate, in kHz
int m_iMixingBits; // 1: 8bit, 2: 16bit
int m_iMusicVolume; // Volume of music; 0: off, 100: max
int m_iSoundVolume; // Volume of sound effects; 0: off, 100: max
int m_aiPlayerKeys[2][9]; // Player keysyms
SState()
{
m_enGameMode = IN_DEMO;
m_bQuitFlag = false;
m_pcArgv0 = NULL;
m_bGameOver = true;
m_bIsReplay = false;
m_poReplayFile = NULL;
m_iGameTime = 60;
m_iHitPoints = 100;
#ifdef _WINDOWS
- m_bFullscreen = true;
+ #ifdef _DEBUG
+ m_bFullScreen = false;
+ #else
+ m_bFullscreen = true;
+ #endif
#else
- m_bFullscreen = false;
+ m_bFullscreen = false;
#endif
m_iChannels = 2;
m_iMixingRate = MIX_DEFAULT_FREQUENCY;
m_iMixingBits = 2;
m_iMusicVolume = 50;
m_iSoundVolume = 100;
static const int aiDefaultKeys[2][9] = {
{ SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT, SDLK_PAGEDOWN,
SDLK_DELETE, SDLK_INSERT, SDLK_END, SDLK_HOME },
{ SDLK_w, SDLK_s, SDLK_a, SDLK_d, SDLK_x,
SDLK_f, SDLK_r, SDLK_g, SDLK_t }
};
for ( int i=0; i<2; ++i )
for ( int j=0; j<9; ++j )
m_aiPlayerKeys[i][j] = aiDefaultKeys[i][j];
};
void Load();
void Save();
void ToggleFullscreen();
};
extern SState g_oState;
#endif
diff --git a/src/gfx.cpp b/src/gfx.cpp
index b008889..4b50070 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -1,274 +1,273 @@
/***************************************************************************
gfx.cpp - description
-------------------
begin : Tue Apr 10 2001
copyright : (C) 2001 by UPi
email : upi@apocalypse.rulez.org
***************************************************************************/
#include <string.h>
-#include <SDL/SDL.h>
-#include <SDL/SDL_video.h>
-#include <SDL/SDL_image.h>
-#include <SDL/SDL_ttf.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"
void sge_TTF_SizeText( _sge_TTFont*font, const char* string, int* x, int* y )
{
SDL_Rect r = sge_TTF_TextSize( font, (char*) string );
*x = r.w;
*y = r.h;
}
int DrawTextMSZ( const char* string, _sge_TTFont* font, int x, int y, int flags,
int fg, SDL_Surface* target )
{
int retval = 0;
if (!string || !*string) return retval;
if (flags & UseTilde)
{
char *str2 = strdup( string );
char onechar[2];
char *c1, *c2, *c3;
int w = 0;
int i, j;
bool notend;
if (flags & AlignHCenter)
{
// Determine width of the string without the stupid tildes
c1 = c2 = str2;
notend = true;
while (notend)
{
c2 = c1; // c1: start of this run
while (*c2 && (*c2!='~')) c2++; // c2: end of this run
notend = *c2;
*c2 = 0;
sge_TTF_SizeText( font, c1, &i, &j);
w += i;
if (notend) { *c2='~'; c1=c2+1; } // next run..
}
x -= w/2;
}
flags &= ~(UseTilde | AlignHCenter);
c1 = str2;
onechar[1]=0;
notend = true;
while (1)
{
c2 = c1;
while (*c2 && (*c2!='~')) c2++; // c2: end of this run
notend = *c2;
*c2 = 0;
sge_TTF_SizeText( font, c1, &i, &j);
DrawTextMSZ( c1, font, x, y, flags, fg, target );
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 );
x += i;
retval += i;
c1 = c2+1;
if (!*c1) break; // ~X was end of string
}
delete( str2 );
return retval;
}
SDL_Rect dest;
int w, h;
sge_TTF_SizeText( font, string, &w, &h );
dest.w = retval = w;
dest.h = h;
dest.x = flags & AlignHCenter ? x-dest.w/2 : x;
dest.y = flags & AlignVCenter ? y-dest.h/2 : y;
//debug( "X: %d, Y: %d, W: %d, H: %d\n", dest.x, dest.y, dest.w, dest.h );
if ( flags & UseShadow )
{
sge_tt_textout_UTF8( target, font, string, dest.x+2, dest.y+2+sge_TTF_FontAscent(font), C_BLACK, C_BLACK, 255 );
}
sge_TTF_AAOn();
dest = sge_tt_textout_UTF8( target, font, string, dest.x, dest.y+sge_TTF_FontAscent(font), fg, C_BLACK, 255 );
sge_TTF_AAOff();
return dest.w;
}
void DrawGradientText( const char* text, _sge_TTFont* font, int y, SDL_Surface* target )
{
int i, j;
// 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_UTF8( surface, font, text,
1, y1, 255, 0, 255);
- for ( int y=1; y<size.h-1; ++y )
+ for ( y=1; y<size.h-1; ++y )
{
int color = 254 * y / (size.h-1) + 1;
unsigned char *p0, *p1, *p2;
p1 = (unsigned char*) surface->pixels;
p1 += surface->pitch * y + 1;
p0 = p1 - surface->pitch;
p2 = p1 + surface->pitch;
for ( int x=1; x<size.w-1; ++x, ++p0, ++p1, ++p2 )
{
if ( *p1 > 2 )
{
*p1 = color;
}
else
{
if ( (*(p1-1) > 2) || (*(p1+1) > 2) || *p0 > 2 || *p2 > 2 )
{
*p1 = 1;
}
}
}
}
// 4. FINALLY
SDL_BlitSurface( surface, NULL, target, &size );
SDL_FreeSurface( surface );
SDL_UpdateRect( target, size.x, size.y, size.w, size.h );
}
SDL_Color MakeColor( Uint8 r, Uint8 g, Uint8 b )
{
SDL_Color color;
color.r = r; color.g = g; color.b = b; color.unused = 0;
return color;
}
SDLKey GetKey()
{
SDL_Event event;
while (SDL_WaitEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
g_oState.m_bQuitFlag = true;
return SDLK_ESCAPE;
case SDL_KEYDOWN:
{
return event.key.keysym.sym;
}
break;
} // switch statement
} // Polling events
return SDLK_ESCAPE;
}
SDL_Surface* LoadBackground( const char* a_pcFilename, int a_iNumColors, int a_iPaletteOffset )
{
char filepath[FILENAME_MAX+1];
strcpy( filepath, DATADIR );
strcat( filepath, "/gfx/" );
strcat( filepath, a_pcFilename );
SDL_Surface* poBackground = IMG_Load( filepath );
if (!poBackground)
{
debug( "Can't load file: %s\n", filepath );
return NULL;
}
SDL_Palette* pal = poBackground->format->palette;
if ( pal )
{
int ncolors = pal->ncolors;
if (ncolors>a_iNumColors) ncolors = a_iNumColors;
if (ncolors+a_iPaletteOffset > 255) ncolors = 255 - a_iPaletteOffset;
SDL_SetColors( gamescreen, pal->colors, a_iPaletteOffset, ncolors );
}
SDL_Surface* poRetval = SDL_DisplayFormat( poBackground );
SDL_FreeSurface( poBackground );
return poRetval;
}
diff --git a/src/main.cpp b/src/main.cpp
index 65800f7..ccd0365 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,372 +1,376 @@
/***************************************************************************
main.cpp - description
-------------------
begin : Wed Aug 22 10:18:47 CEST 2001
copyright : (C) 2001 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "FlyingChars.h"
#include "SDL_video.h"
#include "sge_tt_text.h"
#include "sge_bm_text.h"
#include "sge_surface.h"
#include "SDL.h"
#include "SDL_image.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <string>
#include "common.h"
#include "gfx.h"
#include "Audio.h"
#include "RlePack.h"
#include "Backend.h"
#include "State.h"
_sge_TTFont* inkFont;
_sge_TTFont* impactFont;
_sge_TTFont* titleFont;
sge_bmpFont* fastFont;
sge_bmpFont* creditsFont;
sge_bmpFont* storyFont;
SDL_Color Colors[] =
{
{ 0, 0, 0, 0 }, { 0, 0, 42, 0 }, { 0, 42, 0, 0 }, { 0, 42, 42, 0 },
{ 42, 0, 0, 0 }, { 42, 0, 42, 0 }, { 63, 42, 0, 0 }, { 42, 42, 42, 0 },
{ 21, 21, 21, 0 }, { 21, 21, 63, 0 }, { 21, 63, 21, 0 }, { 21, 63, 63, 0 },
{ 63, 21, 21, 0 }, { 63, 21, 63, 0 }, { 63, 63, 21, 0 }, { 63, 63, 63, 0 }
};
void Complain( const char* a_pcError )
{
+#ifdef _WINDOWS
+ ::MessageBoxA( 0, a_pcError, "OpenMortal", MB_ICONEXCLAMATION );
+#else
fprintf( stderr, "%s", a_pcError );
+#endif
}
_sge_TTFont* LoadTTF( const char* a_pcFilename, int a_iSize )
{
std::string sPath = std::string(DATADIR) + "/fonts/" + a_pcFilename;
_sge_TTFont* poFont = sge_TTF_OpenFont( sPath.c_str(), a_iSize );
if ( NULL == poFont )
{
Complain( ("Couldn't load font: " + sPath).c_str() );
}
return poFont;
}
sge_bmpFont* LoadBMPFont( const char* a_pcFilename )
{
std::string sPath = std::string(DATADIR) + "/fonts/" + a_pcFilename;
sge_bmpFont* poFont = sge_BF_OpenFont( sPath.c_str(), SGE_BFSFONT | SGE_BFTRANSP );
if ( NULL == poFont )
{
Complain( ("Couldn't load font: " + sPath).c_str() );
}
return poFont;
}
int init( int iFlags )
{
if (SDL_Init(SDL_INIT_VIDEO /*| SDL_INIT_AUDIO*/) < 0)
{
fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError());
return -1;
}
atexit(SDL_Quit);
int d = SDL_VideoModeOK(640, 480, 8, iFlags);
if (d == 0)
{
fprintf(stderr, "requested video mode not available\n");
// return -1;
}
gamescreen = SDL_SetVideoMode(640, 480, 8, iFlags);
if (gamescreen == NULL)
{
fprintf(stderr, "failed to set video mode: %s\n", SDL_GetError());
return -1;
}
SDL_WM_SetCaption( "OpenMortal", "OpenMortal" );
std::string sPath = std::string(DATADIR) + "/gfx/icon.png";
SDL_WM_SetIcon(IMG_Load(sPath.c_str()), NULL);
SDL_ShowCursor( SDL_DISABLE );
for ( int i=0; i<16; ++i ) { Colors[i].r *=4; Colors[i].g *=4; Colors[i].b *=4; }
SDL_SetColors( gamescreen, Colors, 256-16, 16 );
if ( sge_TTF_Init() )
{
fprintf(stderr, "couldn't start ttf engine: %s\n", SDL_GetError());
return -1;
}
sge_TTF_AAOff();
inkFont = LoadTTF( "aardvark.ttf", 24 );
if ( !inkFont ) return -1;
impactFont = LoadTTF( "gooddogc.ttf", 20 );
if ( !impactFont ) return -1;
titleFont = LoadTTF( "manslem.ttf", 40 );
if ( !titleFont ) return -1;
fastFont = LoadBMPFont( "impactfont2.png" );
if ( !fastFont ) return -1;
//SDL_SetColorKey( fastFont->FontSurface, SDL_SRCCOLORKEY | SDL_RLEACCEL,
// sge_GetPixel(fastFont->FontSurface,0,fastFont->FontSurface->h-1) );
creditsFont = LoadBMPFont( "fangfont.png" );
storyFont = LoadBMPFont( "glossyfont.png" );
if ( !creditsFont ) return -1;
return 0;
}
int init2()
{
if ( !g_oBackend.Construct() )
{
fprintf(stderr, "couldn't start backend.\n" );
return -1;
}
return 0;
}
int DrawMainScreen()
{
SDL_Surface* background = LoadBackground( "Mortal.png", 240 );
SDL_Rect r;
r.x = r.y = 0;
std::string sStaffFilename = DATADIR;
sStaffFilename += "/characters/STAFF.DAT";
RlePack pack( sStaffFilename.c_str() );
SDL_SetColors( gamescreen, pack.getPalette(), 0, 240 );
SDL_BlitSurface( background, NULL, gamescreen, &r );
SDL_Flip( gamescreen );
FighterEnum f[14] = {
UPI, ZOLI, SURBA, ULMAR, MISI, BENCE,
DESCANT, KINGA, GRIZLI, SIRPI, MACI, DANI, CUMI,
AMBRUS };
char* filename[14] = {
"UPi.pl", "Zoli.pl", NULL, "Ulmar.pl", NULL, "Bence.pl",
"Descant.pl", NULL, "Grizli.pl", "Sirpi.pl", "Maci.pl", NULL, "Cumi.pl",
NULL };
int x[14] = {
0, 26, 67, 125, 159, 209,
249, 289, 358, 397, 451, 489, 532, 161 };
int y[14] = {
5, 4, 5, 5, 5, 7,
4, 0, 7, 5, 5, 6, 5, 243 };
char s[100];
int i;
for ( i=0; i<14; ++i )
{
pack.draw( i, x[i], y[i], false );
SDL_Flip( gamescreen );
if ( filename[i] != NULL )
{
debug( "Loading fighter %s", filename[i] );
sprintf( s, "require '%s';", filename[i] );
PERLEVAL(s);
char *error = SvPV_nolen(get_sv("@", FALSE));
if ( error )
{
fprintf( stderr, "%s", error );
}
}
}
int retval = 0;
i = 0;
SDL_Event event;
/*
while (retval == 0)
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
SDL_FreeSurface( background );
retval = -1;
case SDL_KEYDOWN:
SDL_FreeSurface( background );
retval = -1;
}
}
SDL_Delay( 100 );
i ++;
if ( i > 30 )
break;
}
*/
SDL_FreeSurface( background );
return retval;
}
int main(int argc, char *argv[])
{
srand( (unsigned int)time(NULL) );
if ( 0 != init2() )
{
fprintf( stderr, "init2() failed." );
return -1;
}
g_oState.m_pcArgv0 = argv[0];
g_oState.Load();
bool bDebug = false;
int iFlags = SDL_SWSURFACE | SDL_HWPALETTE;
if ( g_oState.m_bFullscreen )
{
iFlags |= SDL_FULLSCREEN;
}
- for ( int i=1; i<argc; ++i )
+ int i;
+ for ( i=1; i<argc; ++i )
{
if ( !strcmp(argv[i], "-debug") )
{
bDebug = true;
}
else if ( !strcmp(argv[i], "-fullscreen") )
{
iFlags |= SDL_FULLSCREEN;
}
else if ( !strcmp(argv[i], "-hwsurface") )
{
iFlags |= SDL_HWSURFACE;
}
else if ( !strcmp(argv[i], "-doublebuf") )
{
iFlags |= SDL_DOUBLEBUF;
}
else if ( !strcmp(argv[i], "-anyformat") )
{
iFlags |= SDL_ANYFORMAT;
}
else
{
printf( "Usage: %s [-debug] [-fullscreen] [-hwsurface] [-doublebuf] [-anyformat]\n", argv[0] );
return 0;
}
}
if (init( iFlags )<0)
{
return -1;
}
new MszAudio;
Audio->LoadMusic( "Last_Ninja_-_The_Wilderness.mid", "DemoMusic" );
Audio->PlayMusic( "DemoMusic" );
Audio->LoadMusic( "2nd_pm.s3m", "GameMusic" );
DrawMainScreen();
//game.execute();
SetPlayer( 0, ZOLI );
SetPlayer( 1, SIRPI );
int nextFighter = 0;
int describeOrder[ (int)LASTFIGHTER ];
- int i;
for ( i=0; i<(int)LASTFIGHTER; ++i ) describeOrder[i] = i;
for ( i=0; i<100; ++i )
{
int j = rand() % (int)LASTFIGHTER;
int k = rand() % (int)LASTFIGHTER;
int l;
l = describeOrder[j];
describeOrder[j] = describeOrder[k];
describeOrder[k] = l;
}
/*
{
int iGameNumber=0;
char acReplayFile[1024];
for ( i=0; i<15; ++i )
{
sprintf( acReplayFile, DATADIR "/msz%i.replay", i );
DrawTextMSZ( acReplayFile, impactFont, 10, 10, 0, C_WHITE, gamescreen );
SDL_Delay(5000 );
DoGame( acReplayFile, true, bDebug );
}
}
*/
while ( 1 )
{
if ( g_oState.m_bQuitFlag ) break;
DoDemos();
if ( g_oState.m_bQuitFlag ) break;
Audio->PlaySample( "car_start.voc" );
Audio->PlayMusic( "GameMusic" );
while ( g_oState.m_enGameMode != SState::IN_DEMO
&& !g_oState.m_bQuitFlag )
{
PlayerSelect();
if ( g_oState.m_bQuitFlag || g_oState.m_enGameMode == SState::IN_DEMO ) break;
//sprintf( acReplayFile, "/tmp/msz%d.replay", ++iGameNumber );
int iGameResult = DoGame( NULL, false, bDebug );
//int iGameResult = DoGame( acReplayFile, false, bDebug );
//DoGame( acReplayFile, true, bDebug );
if ( g_oState.m_bQuitFlag || g_oState.m_enGameMode == SState::IN_DEMO ) break;
debug ( "iGameResult = %d\n", iGameResult );
if ( iGameResult >= 0 )
{
GameOver( iGameResult );
}
if ( g_oState.m_bQuitFlag || g_oState.m_enGameMode == SState::IN_DEMO ) break;
}
if ( g_oState.m_bQuitFlag ) break;
Audio->PlayMusic( "DemoMusic" );
}
g_oState.Save();
return EXIT_SUCCESS;
}
diff --git a/src/menu.cpp b/src/menu.cpp
index 8f943ee..eb23e3d 100644
--- a/src/menu.cpp
+++ b/src/menu.cpp
@@ -1,751 +1,751 @@
/***************************************************************************
menu.cpp - description
-------------------
begin : Sun Aug 3 2003
copyright : (C) 2003 by upi
email : upi@apocalypse.rulez.org
***************************************************************************/
-#include <SDL/SDL.h>
-#include <SDL/SDL_video.h>
+#include "SDL.h"
+#include "SDL_video.h"
#include "menu.h"
#include "gfx.h"
#include "State.h"
#include "common.h"
#include "Audio.h"
#include "Backend.h"
enum
{
/* Master menu structure:
MAIN MENU
*/
MENU_UNKNOWN,
MENU_SURRENDER,
MENU_SINGLE_PLAYER,
MENU_EASY,
MENU_MEDIUM,
MENU_HARD,
MENU_MULTI_PLAYER,
MENU_OPTIONS,
MENU_GAME_TIME, // ( :30 - 5:00 )
MENU_TOTAL_HIT_POINTS, // ( 25 - 1000 )
MENU_SOUND,
MENU_CHANNELS, // MONO / STEREO
MENU_MIXING_RATE, // 11kHz / 22kHz / 44.1 kHz
MENU_BITS, // 8 bit / 16 bit
MENU_MUSIC_VOLUME, // (0% - 100%)
MENU_SOUND_VOLUME, // (0% - 100%)
MENU_SOUND_OK,
MENU_FULLSCREEN,
MENU_KEYS_RIGHT,
MENU_KEYS_LEFT,
MENU_OPTIONS_OK,
MENU_INFO,
MENU_QUIT, // (confirm)
};
const char* g_ppcGameTime[] = { "0:30", "0:45", "1:00", "1:15", "1:30", "1:45", "2:00", "3:00", "5:00", NULL };
const int g_piGameTime[] = { 30, 45, 60, 75, 90, 105, 120, 180, 300 };
const char* g_ppcHitPoints[] = { "BABY", "VERY LOW", "LOW", "NORMAL", "HIGH", "VERY HIGH", "NEAR IMMORTAL", NULL };
const int g_piHitPoints[] = { 1, 10, 50, 100, 150, 200, 500 };
const char* g_ppcChannels[] = { "MONO", "STEREO", NULL };
const int g_piChannels[] = { 1, 2 };
const char* g_ppcMixingRate[] = { "LOW", "MEDIUM", "HIGH", NULL };
const int g_piMixingRate[] = { 1, 2, 3 };
const char* g_ppcMixingBits[] = { "8 bit", "16 bit", NULL };
const int g_piMixingBits[] = { 1, 2 };
const char* g_ppcVolume[] = { "OFF", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%", NULL };
const int g_piVolume[] = { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
SDL_Surface* poBackground = NULL;
void InputKeys( int a_iPlayerNumber )
{
SDL_BlitSurface( poBackground, NULL, gamescreen, NULL );
DrawGradientText( "Input keys", titleFont, 20, gamescreen );
SDL_Flip( gamescreen );
static const char* apcKeyNames[9] = { "up", "down", "left", "right", "block",
"low punch", "high punch", "low kick", "high kick" };
char acBuffer[1024];
int iY = 70;
for ( int i=0; i<9; ++i )
{
sprintf( acBuffer, "%s player-'%s'?", a_iPlayerNumber ? "Left" : "Right", apcKeyNames[i] );
DrawTextMSZ( acBuffer, inkFont, 10, iY, UseShadow, C_WHITE, gamescreen );
SDLKey enKey = GetKey();
if ( SDLK_ESCAPE == enKey )
{
SDL_BlitSurface( poBackground, NULL, gamescreen, NULL );
SDL_Flip( gamescreen );
return;
}
g_oBackend.PerlEvalF( "GetKeysym(%d);", enKey );
DrawTextMSZ( SvPV_nolen(get_sv("keysym",TRUE)), inkFont, 530, iY, UseShadow, C_WHITE, gamescreen );
g_oState.m_aiPlayerKeys[a_iPlayerNumber][i] = enKey;
iY += 35;
}
DrawTextMSZ( "Thanks!", inkFont, 320, iY + 20, UseShadow | AlignCenter, C_WHITE, gamescreen );
GetKey();
SDL_BlitSurface( poBackground, NULL, gamescreen, NULL );
SDL_Flip( gamescreen );
}
/***************************************************************************
MENUITEM DEFINITION
***************************************************************************/
MenuItem::MenuItem( Menu* a_poMenu, const char* a_pcUtf8Text, int a_iCode )
: m_sUtf8Text( a_pcUtf8Text )
{
m_poMenu = a_poMenu;
m_iCode = a_iCode;
m_oPosition.x = m_oPosition.y = 100;
m_oPosition.w = m_oPosition.h = 100;
m_bCenter = true;
m_iHighColor = C_WHITE;
m_iLowColor = C_LIGHTGRAY;
m_iInactiveColor = C_DARKGRAY;
m_iBackgroundColor = C_BLACK;
m_bActive = false;
m_bEnabled = true;
}
MenuItem::~MenuItem()
{
}
void MenuItem::Draw()
{
if ( NULL != poBackground )
{
SDL_BlitSurface( poBackground, &m_oPosition, gamescreen, &m_oPosition );
}
else
{
SDL_FillRect( gamescreen, &m_oPosition, 0 );
}
int iX = m_oPosition.x;
int iY = m_oPosition.y;
if ( m_bCenter )
{
iX += m_oPosition.w / 2;
}
DrawTextMSZ( m_sUtf8Text.c_str(), inkFont, iX, iY,
UseTilde | UseShadow | (m_bCenter ? AlignHCenter : 0),
m_bEnabled ? (m_bActive ? m_iHighColor : m_iLowColor) : m_iInactiveColor,
gamescreen );
SDL_UpdateRect( gamescreen, m_oPosition.x, m_oPosition.y, m_oPosition.w, m_oPosition.h );
}
void MenuItem::Clear()
{
// debug( "Clear: %d:%d %dx%d\n", m_oPosition.x, m_oPosition.y, m_oPosition.w, m_oPosition.h );
if (poBackground )
{
SDL_Rect oDest = m_oPosition;
SDL_BlitSurface( poBackground, &m_oPosition, gamescreen, &oDest );
}
else
{
SDL_FillRect( gamescreen, &m_oPosition, C_WHITE );
}
SDL_UpdateRect( gamescreen, m_oPosition.x, m_oPosition.y, m_oPosition.w, m_oPosition.h );
}
void MenuItem::Activate()
{
if ( m_poMenu )
{
m_poMenu->ItemActivated( m_iCode, this );
}
}
void MenuItem::SetText( const char* a_pcUtf8Text, bool a_bCenter )
{
m_sUtf8Text = a_pcUtf8Text;
m_bCenter = a_bCenter;
Draw();
}
void MenuItem::SetPosition( const SDL_Rect& a_roPosition )
{
m_oPosition = a_roPosition;
}
void MenuItem::SetActive( bool a_bActive )
{
if ( m_bActive == a_bActive )
{
return;
}
m_bActive = a_bActive;
Draw();
}
void MenuItem::SetEnabled( bool a_bEnabled )
{
if ( m_bEnabled == a_bEnabled )
{
return;
}
m_bEnabled = a_bEnabled;
Draw();
}
/***************************************************************************
ENUMMENUITEM DEFINITION
***************************************************************************/
EnumMenuItem::EnumMenuItem( Menu* a_poMenu, int a_iInitialValue, const char* a_pcUtf8Text, int a_iCode )
: MenuItem( a_poMenu, a_pcUtf8Text, a_iCode )
{
m_sUtf8Title = a_pcUtf8Text;
m_iMax = -1;
m_iValue = a_iInitialValue;
}
EnumMenuItem::~EnumMenuItem()
{
}
void EnumMenuItem::Draw()
{
m_sUtf8Text = m_sUtf8Title;
if ( m_iValue <= m_iMax )
{
m_sUtf8Text += m_ppcNames[m_iValue];
}
if ( m_iValue > 0 )
{
m_sUtf8Text = "< " + m_sUtf8Text;
}
if ( m_iValue < m_iMax )
{
m_sUtf8Text += " >";
}
MenuItem::Draw();
}
void EnumMenuItem::Increment()
{
if ( m_iValue < m_iMax )
{
++m_iValue;
Draw();
m_poMenu->ItemChanged( m_iCode, m_piValues[m_iValue], this );
Audio->PlaySample( "ding.voc" );
}
}
void EnumMenuItem::Decrement()
{
if ( m_iValue > 0 )
{
--m_iValue;
Draw();
m_poMenu->ItemChanged( m_iCode, m_piValues[m_iValue], this );
Audio->PlaySample( "ding.voc" );
}
}
void EnumMenuItem::SetEnumValues( const char ** a_ppcNames, const int * a_piValues )
{
m_ppcNames = a_ppcNames;
m_piValues = a_piValues;
int i;
bool bFoundValue = false;
for ( i=0; NULL != a_ppcNames[i]; ++i )
{
if ( !bFoundValue &&
m_iValue == a_piValues[i] )
{
bFoundValue = true;
m_iValue = i;
}
}
if ( !bFoundValue )
{
m_iValue = 0;
}
m_iMax = i-1;
}
/***************************************************************************
MENU DEFINITION
***************************************************************************/
Menu::Menu( const char* a_pcTitle )
: m_sTitle( a_pcTitle )
{
m_iCurrentItem = 0;
m_iReturnCode = -1;
m_bDone = false;
}
Menu::~Menu()
{
ItemIterator it;
for ( it = m_oItems.begin(); it != m_oItems.end(); ++it )
{
delete *it;
}
}
MenuItem* Menu::AddMenuItem( const char* a_pcUtf8Text, SDLKey a_tShortcut, int a_iCode )
{
MenuItem* poItem = new MenuItem( this, a_pcUtf8Text, a_iCode );
return AddMenuItem( poItem );
}
EnumMenuItem* Menu::AddEnumMenuItem( const char* a_pcUtf8Text, int a_iInitialValue,
const char** a_ppcNames, const int* a_piValues, int a_iCode )
{
EnumMenuItem* poItem = new EnumMenuItem( this, a_iInitialValue, a_pcUtf8Text, a_iCode );
poItem->SetEnumValues( a_ppcNames, a_piValues );
AddMenuItem( poItem );
return poItem;
}
MenuItem* Menu::AddMenuItem( MenuItem* a_poItem )
{
m_oItems.push_back( a_poItem );
SDL_Rect oRect;
oRect.x = 0; oRect.w = gamescreen->w;
oRect.y = m_oItems.size() * 45 + 100;
oRect.h = 45;
a_poItem->SetPosition( oRect );
return a_poItem;
}
void Menu::AddOkCancel( int a_iOkCode )
{
SDL_Rect oRect;
oRect.x = 0; oRect.w = 150;
oRect.y = gamescreen->h - 50; oRect.h = 30;
MenuItem* poItem = AddMenuItem( "~OK", SDLK_o, a_iOkCode );
poItem->SetPosition( oRect );
// poItem = AddMenuItem( "Cancel", SDLK_UNKNOWN, 0 );
oRect.x = gamescreen->w - 150;
poItem->SetPosition( oRect );
}
void Menu::InvokeSubmenu( Menu* a_poMenu )
{
Audio->PlaySample( "strange_button.voc" );
Clear();
m_iReturnCode = a_poMenu->Run();
if ( m_iReturnCode < 0 )
{
Audio->PlaySample( "pop.voc" );
Draw();
}
else
{
m_iReturnCode --;
m_bDone = true;
}
}
void Menu::ItemActivated( int a_iItemCode, MenuItem* a_poMenuItem )
{
debug( "Menu::ItemActivated( %d )\n", a_iItemCode );
switch ( a_iItemCode )
{
case MENU_QUIT:
m_bDone = true;
m_iReturnCode = 100;
g_oState.m_bQuitFlag = true;
break;
case MENU_SURRENDER:
m_bDone = true;
m_iReturnCode = 100;
g_oState.m_enGameMode = SState::IN_DEMO;
break;
case MENU_MULTI_PLAYER:
m_bDone = true;
m_iReturnCode = 100;
g_oState.m_enGameMode = SState::IN_MULTI;
break;
case MENU_FULLSCREEN:
Audio->PlaySample( "strange_button.voc" );
g_oState.ToggleFullscreen();
if ( NULL != poBackground )
{
SDL_BlitSurface( poBackground, NULL, gamescreen, NULL );
}
else
{
SDL_FillRect( gamescreen, NULL, 0 );
}
a_poMenuItem->SetText( g_oState.m_bFullscreen ? "~FULLSCREEN ON" : "~FULLSCREEN OFF", true );
Draw();
break;
case MENU_OPTIONS_OK:
m_bDone = true;
m_iReturnCode = -1;
break;
case MENU_OPTIONS:
{
Menu* poMenu = new Menu( "Options" );
poMenu->AddEnumMenuItem( "GAME TIME: ", g_oState.m_iGameTime, g_ppcGameTime, g_piGameTime, MENU_GAME_TIME );
poMenu->AddEnumMenuItem( "HIT POINTS: ", g_oState.m_iHitPoints, g_ppcHitPoints, g_piHitPoints, MENU_TOTAL_HIT_POINTS );
poMenu->AddMenuItem( "~SOUND", SDLK_s, MENU_SOUND );
poMenu->AddMenuItem( g_oState.m_bFullscreen ? "~FULLSCREEN ON" : "~FULLSCREEN OFF", SDLK_f, MENU_FULLSCREEN );
poMenu->AddMenuItem( "~RIGHT PLAYER KEYS", SDLK_r, MENU_KEYS_RIGHT );
poMenu->AddMenuItem( "~LEFT PLAYER KEYS", SDLK_l, MENU_KEYS_LEFT );
poMenu->AddOkCancel( MENU_OPTIONS_OK );
InvokeSubmenu( poMenu );
delete poMenu;
break;
}
case MENU_SOUND:
{
Menu* poMenu = new Menu( "Sound" );
poMenu->AddEnumMenuItem( "CHANNELS: ", 1, g_ppcChannels, g_piChannels, MENU_CHANNELS )->SetEnabled(false);
poMenu->AddEnumMenuItem( "SOUND QUALITY: ", 2, g_ppcMixingRate, g_piMixingRate, MENU_MIXING_RATE )->SetEnabled(false);
poMenu->AddEnumMenuItem( "SOUND FIDELITY: ", 2, g_ppcMixingBits, g_piMixingBits, MENU_BITS )->SetEnabled(false);
poMenu->AddEnumMenuItem( "MUSIC VOLUME: ", g_oState.m_iMusicVolume, g_ppcVolume, g_piVolume, MENU_MUSIC_VOLUME );
poMenu->AddEnumMenuItem( "EFFECTS VOLUME: ", g_oState.m_iSoundVolume, g_ppcVolume, g_piVolume, MENU_SOUND_VOLUME );
poMenu->AddOkCancel( MENU_SOUND_OK );
InvokeSubmenu( poMenu );
delete poMenu;
break;
}
case MENU_SOUND_OK:
m_bDone = true;
m_iReturnCode = -1;
break;
case MENU_KEYS_LEFT:
InputKeys(1);
Draw();
break;
case MENU_KEYS_RIGHT:
InputKeys(0);
Draw();
break;
default:
break;
}
}
void Menu::ItemChanged( int a_iItemCode, int a_iValue, MenuItem* a_poMenuItem )
{
debug( "Menu::ItemActivated( %d )\n", a_iItemCode );
switch ( a_iItemCode )
{
case MENU_MUSIC_VOLUME:
g_oState.m_iMusicVolume = a_iValue;
Audio->SetMusicVolume( a_iValue );
break;
case MENU_SOUND_VOLUME:
g_oState.m_iSoundVolume = a_iValue;
break;
case MENU_GAME_TIME:
g_oState.m_iGameTime = a_iValue;
break;
case MENU_TOTAL_HIT_POINTS:
g_oState.m_iHitPoints = a_iValue;
break;
} // end of switch a_iItemCode
}
/** Run executes the menus, maybe invoking submenus as well. The
menus modify the global game state.
Returns 0, or the number of parent menus that should be cleared. */
int Menu::Run()
{
if ( m_oItems[m_iCurrentItem]->GetEnabled() )
{
m_oItems[m_iCurrentItem]->SetActive(true);
}
else
{
FocusNext();
}
Draw();
while ( !m_bDone )
{
SDLKey enKey = GetKey();
if ( g_oState.m_bQuitFlag ||
SDLK_ESCAPE == enKey )
{
m_bDone = true;
m_iReturnCode = -1;
break;
}
switch ( enKey )
{
case SDLK_UP:
{
FocusPrev();
break;
} // end of SDLK_UP
case SDLK_DOWN:
{
FocusNext();
break;
} // end of SDLK_DOWN
case SDLK_LEFT:
{
MenuItem* poItem = m_oItems[m_iCurrentItem];
poItem->Decrement();
break;
}
case SDLK_RIGHT:
{
MenuItem* poItem = m_oItems[m_iCurrentItem];
poItem->Increment();
break;
}
case SDLK_RETURN:
{
MenuItem* poItem = m_oItems[m_iCurrentItem];
if ( poItem->GetEnabled() )
{
poItem->Activate();
}
}
default:
break;
} // end of switch
}
Clear();
return m_iReturnCode;
}
void Menu::Draw()
{
DrawGradientText( m_sTitle.c_str(), titleFont, 20, gamescreen );
for ( ItemIterator it=m_oItems.begin(); it!=m_oItems.end(); ++it )
{
(*it)->Draw();
}
SDL_Flip( gamescreen );
}
void Menu::FocusNext()
{
MenuItem* poItem = NULL;
int iNextItem;
for ( iNextItem = m_iCurrentItem+1; iNextItem < (int) m_oItems.size(); ++iNextItem )
{
poItem = m_oItems[iNextItem];
if ( poItem->GetEnabled() )
{
break;
}
poItem = NULL;
}
if ( NULL != poItem )
{
Audio->PlaySample("strange_quack.voc");
m_oItems[m_iCurrentItem]->SetActive(false);
m_oItems[iNextItem]->SetActive(true);
m_iCurrentItem = iNextItem;
}
}
void Menu::FocusPrev()
{
MenuItem* poItem = NULL;
int iPrevItem;
for ( iPrevItem = m_iCurrentItem-1; iPrevItem >= 0; --iPrevItem )
{
poItem = m_oItems[iPrevItem];
if ( poItem->GetEnabled() )
{
break;
}
poItem = NULL;
}
if ( NULL != poItem )
{
Audio->PlaySample("strange_quack.voc");
m_oItems[m_iCurrentItem]->SetActive(false);
m_oItems[iPrevItem]->SetActive(true);
m_iCurrentItem = iPrevItem;
}
}
void Menu::Clear()
{
if (poBackground)
{
SDL_BlitSurface( poBackground, 0, gamescreen, 0 );
}
else
{
SDL_FillRect( gamescreen, NULL, 0 );
}
}
void DoMenu( bool a_bDrawBackground )
{
Audio->PlaySample( "crashhh.voc" );
poBackground = SDL_ConvertSurface( gamescreen, gamescreen->format, SDL_SWSURFACE );
if ( NULL == poBackground )
{
debug( "DoMenu: Couldn't allocate background.\n" );
}
else
{
int i;
SDL_Rect oRect;
oRect.x = 0; oRect.w = poBackground->w; oRect.h = 1;
for ( i=0; i<poBackground->h; i += 2 )
{
oRect.y = i;
SDL_FillRect( poBackground, &oRect, C_BLACK );
}
oRect.w = 1; oRect.y = 0; oRect.h = poBackground->h;
for ( i=0; i<poBackground->w; i+=2 )
{
oRect.x = i;
SDL_FillRect(poBackground, &oRect, C_BLACK );
}
SDL_BlitSurface( poBackground, 0, gamescreen, 0 );
SDL_Flip( gamescreen );
}
Menu oMenu( "Main Menu" );
if ( SState::IN_DEMO == g_oState.m_enGameMode )
{
oMenu.AddMenuItem( "~SINGLE PLAYER GAME", SDLK_s, MENU_SINGLE_PLAYER )->SetEnabled(false);
oMenu.AddMenuItem( "~MULTI PLAYER GAME", SDLK_m, MENU_MULTI_PLAYER );
}
else
{
oMenu.AddMenuItem( "~SURRENDER GAME", SDLK_s, MENU_SURRENDER );
}
oMenu.AddMenuItem( "~OPTIONS", SDLK_o, MENU_OPTIONS );
oMenu.AddMenuItem( "~INFO", SDLK_i, MENU_INFO )->SetEnabled(false);
oMenu.AddMenuItem( "QUIT", SDLK_UNKNOWN, MENU_QUIT );
oMenu.Run();
Audio->PlaySample("shades_rollup.voc");
//SDL_BlitSurface( poBackground, 0, gamescreen, 0 );
//SDL_Flip( gamescreen );
SDL_FreeSurface( poBackground );
poBackground = NULL;
}
diff --git a/src/sge_bm_text.cpp b/src/sge_bm_text.cpp
index 9fca2a0..22aeed4 100644
--- a/src/sge_bm_text.cpp
+++ b/src/sge_bm_text.cpp
@@ -1,552 +1,552 @@
/*
* SDL Graphics Extension
* Text/Bitmap font functions
*
* Started 990815
*
* License: LGPL v2+ (see the file LICENSE)
* (c)1999-2001 Anders Lindstr?m
*/
/*********************************************************************
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
*********************************************************************/
/*
* Some of this is taken from SDL_DrawText by Garrett Banuk (mongoose@wpi.edu)
* http://www.wpi.edu/~mongoose/SDL_Console
* Thanks to Karl Bartel for the SFont format!
*/
-#include <SDL/SDL.h>
+#include "SDL.h"
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <new>
#include "sge_surface.h"
#include "sge_bm_text.h"
#include "sge_tt_text.h"
#ifdef _SGE_HAVE_IMG
-#include <SDL/SDL_image.h>
+#include "SDL_image.h"
#endif
using namespace std;
/* Globals used for sge_Update/sge_Lock (defined in sge_surface) */
extern Uint8 _sge_update;
extern Uint8 _sge_lock;
//==================================================================================
// Creates a new font from a surface
//==================================================================================
sge_bmpFont* sge_BF_CreateFont(SDL_Surface *surface, Uint8 flags)
{
sge_bmpFont *font;
font = new(nothrow) sge_bmpFont; if(font==NULL){SDL_SetError("SGE - Out of memory");return NULL;}
if(!(flags&SGE_BFNOCONVERT) && !(flags&SGE_BFSFONT)){ /* Get a converted copy */
font->FontSurface = SDL_DisplayFormat(surface);
if(font->FontSurface==NULL){SDL_SetError("SGE - Out of memory");return NULL;}
if(flags&SGE_BFPALETTE){ //We want an 8bit surface
SDL_Surface *tmp;
tmp = SDL_AllocSurface(SDL_SWSURFACE, surface->w, surface->h, 8, 0, 0, 0, 0);
if(tmp==NULL){SDL_SetError("SGE - Out of memory");SDL_FreeSurface(font->FontSurface);return NULL;}
//Set the palette
tmp->format->palette->colors[0].r = 0;
tmp->format->palette->colors[0].g = 0;
tmp->format->palette->colors[0].b = 0;
tmp->format->palette->colors[1].r = 255;
tmp->format->palette->colors[1].g = 255;
tmp->format->palette->colors[1].b = 255;
if (SDL_MUSTLOCK(font->FontSurface) && _sge_lock)
if (SDL_LockSurface(font->FontSurface) < 0){
SDL_SetError("SGE - Locking error");
SDL_FreeSurface(font->FontSurface);
return NULL;
}
//Copy the font to the 8bit surface
Sint16 x,y;
Uint32 bc=sge_GetPixel(font->FontSurface,0,surface->h-1);
for(y=0; y<font->FontSurface->h; y++){
for(x=0; x<font->FontSurface->w; x++){
if(sge_GetPixel(font->FontSurface,x,y)==bc)
*((Uint8 *)tmp->pixels + y * tmp->pitch + x)=0;
else
*((Uint8 *)tmp->pixels + y * tmp->pitch + x)=1;
}
}
if (SDL_MUSTLOCK(font->FontSurface) && _sge_lock) {
SDL_UnlockSurface(font->FontSurface);
}
//sge_Blit(surface, tmp, 0,0,0,0,surface->w, surface->h);
SDL_FreeSurface(font->FontSurface);
font->FontSurface=tmp;
}
if((flags&SGE_FLAG8))
SDL_FreeSurface(surface);
}
else if(flags&SGE_FLAG8) /* Use the source */
font->FontSurface = surface;
else /* Get a copy */
font->FontSurface = sge_copy_surface(surface);
if(font->FontSurface==NULL){SDL_SetError("SGE - Out of memory");return NULL;}
SDL_Surface *fnt = font->FontSurface; //Shorthand
font->Chars=0;
if(!(flags&SGE_BFSFONT)){ /* Fixed width font */
font->CharWidth = font->FontSurface->w/256;
font->CharHeight = font->FontSurface->h;
font->CharPos = NULL;
font->yoffs = 0;
font->Chars=256;
}
else{ /* Karl Bartel's sfont */
Sint16 x=0;
int i=0;
font->CharPos = new(nothrow) Sint16[512];
if(!font->CharPos){SDL_SetError("SGE - Out of memory");sge_BF_CloseFont(font);return NULL;}
Uint32 color = sge_GetPixel(fnt,0,0);
while (x<fnt->w && font->Chars<256){
if (sge_GetPixel(fnt,x,0)==color) {
font->CharPos[i++]=x;
while (x<fnt->w-1 && sge_GetPixel(fnt,x,0)==color)
x++;
font->CharPos[i++]=x;
font->Chars++;
}
x++;
}
font->CharHeight = font->FontSurface->h-1;
font->CharWidth = 0;
font->yoffs = 1;
}
/* Set font as transparent if the flag is set */
if (SDL_MUSTLOCK(font->FontSurface) && _sge_lock)
if (SDL_LockSurface(font->FontSurface) < 0){
return font;
}
font->bcolor=sge_GetPixel(font->FontSurface,0,font->FontSurface->h-1);
if (SDL_MUSTLOCK(font->FontSurface) && _sge_lock) {
SDL_UnlockSurface(font->FontSurface);
}
if(flags&SGE_BFTRANSP || flags&SGE_BFSFONT)
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >= \
SDL_VERSIONNUM(1, 1, 4)
SDL_SetColorKey(font->FontSurface,SDL_SRCCOLORKEY, font->bcolor); //Some versions of SDL have a bug with SDL_RLEACCEL
#else
SDL_SetColorKey(font->FontSurface,SDL_SRCCOLORKEY|SDL_RLEACCEL, font->bcolor);
#endif
return font;
}
//==================================================================================
// Loads the font into a new struct
//==================================================================================
sge_bmpFont* sge_BF_OpenFont(const char *file, Uint8 flags)
{
sge_bmpFont *font;
SDL_Surface *Temp;
/* load the font bitmap */
#ifdef _SGE_HAVE_IMG
if(NULL == (Temp = IMG_Load(file))) //We have SDL_Img lib!
#else
if(NULL == (Temp = SDL_LoadBMP(file))) //We can only load bmp files...
#endif
{
sge_SetError("SGE - Couldn't load font file: %s",file);
return NULL;
}
font = sge_BF_CreateFont(Temp,flags|SGE_FLAG8); //SGE_FLAG8 - no need to make a copy of the surface
return font;
}
//==================================================================================
// Draws string to surface with the selected font
// Returns pos. and size of the drawn text
//==================================================================================
SDL_Rect sge_BF_textout(SDL_Surface *surface, sge_bmpFont *font, const char *string, Sint16 x, Sint16 y, int length)
{
SDL_Rect ret; ret.x=0;ret.y=0;ret.w=0;ret.h=0;
if(font==NULL || length==0){return ret;}
int characters;
Sint16 xsrc,xdest,ofs,adv=font->CharWidth;
float diff=0;
/* Valid coords ? */
if(surface)
if(x>surface->w || y>surface->h)
return ret;
characters = strlen(string);
xdest=x;
/* Now draw it */
for(int i=0; i<characters; i++)
{
if(!font->CharPos) /* Fixed width */
xsrc = string[i] * font->CharWidth;
else{ /* Variable width */
if(string[i]==' ' || (string[i]-33)>font->Chars || string[i]<33){
xdest += font->CharPos[2]-font->CharPos[1];
continue;
}
ofs = (string[i]-33)*2+1;
xsrc = (font->CharPos[ofs]+font->CharPos[ofs-1])/2;
//font->CharWidth = (font->CharPos[ofs+2]+font->CharPos[ofs+1])/2-(font->CharPos[ofs]+font->CharPos[ofs-1])/2-1;
font->CharWidth = (font->CharPos[ofs+2]+font->CharPos[ofs+1])/2-(font->CharPos[ofs]+font->CharPos[ofs-1])/2;
adv = font->CharPos[ofs+1]-font->CharPos[ofs];
diff =(font->CharPos[ofs]-font->CharPos[ofs-1])/2.0;
}
if(surface)
sge_Blit(font->FontSurface, surface, xsrc,font->yoffs, int(xdest-diff),y, font->CharWidth,font->CharHeight);
xdest += adv;
--length;
if (0 == length)
{
break;
}
}
ret.x=x; ret.y=y; ret.w=xdest-x+font->CharWidth; ret.h=font->CharHeight;
if(surface)
sge_UpdateRect(surface, x, y, ret.w, ret.h);
return ret;
}
//==================================================================================
// Returns the size (w and h) of the string (if rendered with font)
//==================================================================================
SDL_Rect sge_BF_TextSize(sge_bmpFont *font, const char *string, int length)
{
return sge_BF_textout(NULL, font, string, 0, 0, length);
}
//==================================================================================
// Draws formated text to surface with the selected font
// Returns pos. and size of the drawn text
// * just like printf(char *format, ...) *
//==================================================================================
SDL_Rect sge_BF_textoutf(SDL_Surface *surface, sge_bmpFont *font, Sint16 x, Sint16 y ,const char *format, ...)
{
char buf[256];
va_list ap;
#ifdef __WIN32__
va_start((va_list*)ap, format); //Stupid w32 crosscompiler
#else
va_start(ap, format);
#endif
vsprintf(buf, format, ap);
va_end(ap);
return sge_BF_textout(surface, font, buf, x, y);
}
//==================================================================================
// Returns the height of the font
// Returns 0 if the struct was invalid
//==================================================================================
Sint16 sge_BF_GetHeight(sge_bmpFont *font)
{
if(font)
return font->CharHeight;
else
return 0;
}
//==================================================================================
// Returns the width of the font (only fixed width fonts)
// Returns 0 if the struct was invalid
//==================================================================================
Sint16 sge_BF_GetWidth(sge_bmpFont *font)
{
if(font)
return font->CharWidth;
else
return 0;
}
//==================================================================================
// Removes font from memory
//==================================================================================
void sge_BF_CloseFont(sge_bmpFont *font)
{
if(font){
SDL_FreeSurface(font->FontSurface);
if(font->CharPos)
delete[] font->CharPos;
delete font;
font=NULL;
}
}
//==================================================================================
// Change the font color
// Will not work on 'color' fonts!
// Doesn't like 24bpp
// slooooow!
//==================================================================================
void sge_BF_SetColor(sge_bmpFont *font, Uint8 R, Uint8 G, Uint8 B)
{
if(font==NULL){return;}
if(!font->FontSurface->format->palette){ //Slow truecolor version
Sint16 x,y;
Sint16 ypnt;
SDL_Surface *surface=font->FontSurface;
Uint32 c_keep=font->bcolor;
Uint32 color=SDL_MapRGB(font->FontSurface->format, R, G, B);
switch(surface->format->BytesPerPixel){
case 1: { /* Assuming 8-bpp */
Uint8 *pnt;
for(y=0; y<surface->h; y++){
ypnt=y*surface->pitch;
for(x=0; x<surface->w; x++){
pnt=((Uint8 *)surface->pixels + x + ypnt);
if(*pnt!=c_keep){*pnt=(Uint8)color;}
}
}
}
break;
case 2: { /* Probably 15-bpp or 16-bpp */
Uint16 *pnt;
for(y=0; y<surface->h; y++){
ypnt=y*surface->pitch/2;
for(x=0; x<surface->w; x++){
pnt=((Uint16 *)surface->pixels + x + ypnt);
if(*pnt!=c_keep){*pnt=(Uint16)color;}
}
}
}
break;
case 3: { /* Slow 24-bpp mode, usually not used */
}
break;
case 4: { /* Probably 32-bpp */
Uint32 *pnt;
for(y=0; y<surface->h; y++){
ypnt=y*surface->pitch/4;
for(x=0; x<surface->w; x++){
pnt=((Uint32 *)surface->pixels + x + ypnt);
if(*pnt!=c_keep){*pnt=(Uint32)color;}
}
}
}
break;
}
}else{ //Fast palette version
SDL_Color c[2];
c[0].r=0; c[1].r=R;
c[0].g=0; c[1].g=G;
c[0].b=0; c[1].b=B;
SDL_SetColors(font->FontSurface, c, 0, 2);
}
}
//==================================================================================
// Insert a element (latin1)
//==================================================================================
void insert_char_latin1(char *string, char ch, int pos, int max)
{
if(pos>max || pos<0){return;}
else if(pos==max){string[pos]=ch;}
else{
for(int i=max; i>=pos; i--){
string[i+1]=string[i];
}
string[pos]=ch;
}
}
//==================================================================================
// Delete a element (latin1)
//==================================================================================
void delete_char_latin1(char *string, int pos, int max)
{
if(pos>max || pos<0){return;}
else if(pos==max){string[pos]=0;}
else{
for(int i=pos; i<=max-1; i++){
string[i]=string[i+1];
}
string[max]=0;
}
}
//==================================================================================
// BitmapText input
//==================================================================================
int sge_BF_input(SDL_Surface *screen,sge_bmpFont *font,char *string, Uint8 flags, int pos,int len,Sint16 x,Sint16 y)
{
if(len<pos || pos<0 || len<0 || font==NULL){return -2;}
char cur=124;//The character for the cursor - '|'
int max; //The strings size
SDL_Rect ret,tmp;
SDL_Surface *buffer=NULL;
buffer=SDL_DisplayFormat(screen); /* Fixme: Yum! Memory! */
if(buffer==NULL){SDL_SetError("SGE - Out of memory");return -3;}
max=pos;
string[pos+1]=0;
SDL_EnableUNICODE(1);
/* Init cursor */
string[pos]=cur;
ret=sge_BF_textout(screen, font, string, x, y);
SDL_Event event;
int quit=0;
do{
/* Check events */
SDL_WaitEvent(&event);
if(event.type==SDL_QUIT){quit=-1;}
else if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_ESCAPE){quit=1;}
else if(event.type==SDL_KEYDOWN && (event.key.keysym.sym==SDLK_RETURN || event.key.keysym.sym==SDLK_KP_ENTER)){quit=1;}
else if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_BACKSPACE){
if(pos>0){
/* Delete char cursor-1 */
delete_char_latin1(string,pos-1,max); pos--; max--;
sge_Update_OFF();
sge_Blit(buffer,screen, ret.x, ret.y, x,y, ret.w, ret.h);
tmp=ret;
ret=sge_BF_textout(screen, font, string, x, y);
sge_Update_ON();
sge_UpdateRect(screen, tmp.x, tmp.y, tmp.w, tmp.h);
/* Handle keyrepeat */
if(!(flags&SGE_FLAG3))
if(keyrepeat(&event, 20)==-1){quit=-1;}
}
}
else if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_RIGHT){
if(pos!=max && pos!=len){
/* Move cursor right */
delete_char_latin1(string,pos,max);pos++;
insert_char_latin1(string,cur,pos,max);
sge_Blit(buffer,screen, ret.x, ret.y, x,y, ret.w, ret.h);
ret=sge_BF_textout(screen, font, string, x, y);
/* Handle keyrepeat */
if(!(flags&SGE_FLAG3))
if(keyrepeat(&event, 20)==-1){quit=-1;}
}
}
else if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_LEFT){
if(pos>0){
/* Move cursor left */
delete_char_latin1(string,pos,max);pos--;
insert_char_latin1(string,cur,pos,max);
sge_Blit(buffer,screen, ret.x, ret.y, x,y, ret.w, ret.h);
ret=sge_BF_textout(screen, font, string, x, y);
/* Handle keyrepeat */
if(!(flags&SGE_FLAG3))
if(keyrepeat(&event, 20)==-1){quit=-1;}
}
}
else if(event.type==SDL_KEYDOWN && event.key.keysym.sym==SDLK_DELETE){
/* Delete char cursor+1 */
if(pos!=max && pos!=len){
delete_char_latin1(string,pos+1,max);max--;
sge_Update_OFF();
sge_Blit(buffer,screen, ret.x, ret.y, x,y, ret.w, ret.h);
tmp=ret;
ret=sge_BF_textout(screen, font, string, x, y);
sge_Update_ON();
sge_UpdateRect(screen, tmp.x, tmp.y, tmp.w, tmp.h);
/* Handle keyrepeat */
if(!(flags&SGE_FLAG3))
if(keyrepeat(&event, 20)==-1){quit=-1;}
}
}
else if(event.type==SDL_KEYDOWN && event.key.keysym.unicode!=0){
/* Insert new char */
if(max!=len){
max++;
insert_char_latin1(string, (char)event.key.keysym.unicode, pos,max); pos++;
sge_Blit(buffer,screen, ret.x, ret.y, x,y, ret.w, ret.h);
ret=sge_BF_textout(screen, font, string, x, y);
/* Handle keyrepeat */
if(!(flags&SGE_FLAG3))
if(keyrepeat(&event, 40)==-1){quit=-1;}
}
}
}while(quit==0);
/* Remove the cursor from string */
delete_char_latin1(string,pos,max);
//Remove text/cursor from screen
sge_Blit(buffer,screen, ret.x, ret.y, x,y, ret.w, ret.h);
if(!(flags&SGE_FLAG2))
ret=sge_BF_textout(screen, font, string, x, y);
else
sge_UpdateRect(screen, x,y, ret.w, ret.h);
SDL_FreeSurface(buffer);
if(quit==-1){return -1;} //Waaa! The user killed me!
return max;
}
diff --git a/src/sge_bm_text.h b/src/sge_bm_text.h
index d7b7fd5..f56635b 100644
--- a/src/sge_bm_text.h
+++ b/src/sge_bm_text.h
@@ -1,66 +1,66 @@
/*
* SDL Graphics Extension
* Text/Bitmap font functions (header)
*
* Started 990815
*
* License: LGPL v2+ (see the file LICENSE)
* (c)1999-2001 Anders Lindstr?m
*/
/*********************************************************************
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
*********************************************************************/
#ifndef sge_bm_text_H
#define sge_bm_text_H
-#include <SDL/SDL.h>
+#include "SDL.h"
#include "sge_internal.h"
/* BF open flags */
#define SGE_BFTRANSP SGE_FLAG1
#define SGE_BFSFONT SGE_FLAG2
#define SGE_BFNOCONVERT SGE_FLAG3
#define SGE_BFPALETTE SGE_FLAG4
/* Text input flags */
#define SGE_IBG SGE_FLAG1
#define SGE_IDEL SGE_FLAG2
#define SGE_INOKR SGE_FLAG3
/* the bitmap font structure */
typedef struct{
SDL_Surface *FontSurface;
Sint16 CharWidth;
Sint16 CharHeight;
Sint16 *CharPos;
Sint16 yoffs;
Uint32 bcolor;
Sint16 Chars;
} sge_bmpFont;
#ifdef _SGE_C
extern "C" {
#endif
DECLSPEC sge_bmpFont* sge_BF_OpenFont(const char *file, Uint8 flags);
DECLSPEC void sge_BF_CloseFont(sge_bmpFont *font);
DECLSPEC void sge_BF_SetColor(sge_bmpFont *font, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC Sint16 sge_BF_GetHeight(sge_bmpFont *font);
DECLSPEC Sint16 sge_BF_GetWidth(sge_bmpFont *font);
DECLSPEC SDL_Rect sge_BF_TextSize(sge_bmpFont *font, const char *string, int length=-1);
DECLSPEC SDL_Rect sge_BF_textout(SDL_Surface *surface, sge_bmpFont *font, const char *string, Sint16 x, Sint16 y, int length=-1);
DECLSPEC SDL_Rect sge_BF_textoutf(SDL_Surface *surface, sge_bmpFont *font, Sint16 x, Sint16 y , const char *format, ...);
DECLSPEC int sge_BF_input(SDL_Surface *screen,sge_bmpFont *font,char *string, Uint8 flags,int pos,int len,Sint16 x,Sint16 y);
#ifdef _SGE_C
}
#endif
#endif /* sge_bm_text_H */
diff --git a/src/sge_primitives.cpp b/src/sge_primitives.cpp
index cd00843..5278ca4 100644
--- a/src/sge_primitives.cpp
+++ b/src/sge_primitives.cpp
@@ -1,1660 +1,1660 @@
/*
* SDL Graphics Extension
* Drawing primitives
*
* Started 990815 (split from sge_draw 010611)
*
* License: LGPL v2+ (see the file LICENSE)
* (c)1999-2001 Anders Lindstr?m
*/
/*********************************************************************
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
*********************************************************************/
/*
* Some of this code is taken from the "Introduction to SDL" and
* John Garrison's PowerPak
*/
-#include <SDL/SDL.h>
+#include "SDL.h"
#include <math.h>
#include <string.h>
#include <stdarg.h>
#include "sge_primitives.h"
#include "sge_surface.h"
/* Globals used for sge_Update/sge_Lock (defined in sge_surface) */
extern Uint8 _sge_update;
extern Uint8 _sge_lock;
/**********************************************************************************/
/** Line functions **/
/**********************************************************************************/
//==================================================================================
// Internal draw horizontal line
//==================================================================================
void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
{
if(x1>x2){Sint16 tmp=x1; x1=x2; x2=tmp;}
//Do the clipping
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
if(y<Surface->clip_miny || y>Surface->clip_maxy || x1>Surface->clip_maxx || x2<Surface->clip_minx)
return;
if(x1<Surface->clip_minx)
x1=Surface->clip_minx;
if(x2>Surface->clip_maxx)
x2=Surface->clip_maxx;
#endif
SDL_Rect l;
l.x=x1; l.y=y; l.w=x2-x1+1; l.h=1;
SDL_FillRect(Surface, &l, Color);
}
//==================================================================================
// Draw horizontal line
//==================================================================================
void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
{
if(x1>x2){Sint16 tmp=x1; x1=x2; x2=tmp;}
//Do the clipping
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
if(y<Surface->clip_miny || y>Surface->clip_maxy || x1>Surface->clip_maxx || x2<Surface->clip_minx)
return;
if(x1<Surface->clip_minx)
x1=Surface->clip_minx;
if(x2>Surface->clip_maxx)
x2=Surface->clip_maxx;
#endif
SDL_Rect l;
l.x=x1; l.y=y; l.w=x2-x1+1; l.h=1;
SDL_FillRect(Surface, &l, Color);
sge_UpdateRect(Surface, x1, y, x2-x1+1, 1);
}
//==================================================================================
// Draw horizontal line (RGB)
//==================================================================================
void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B)
{
sge_HLine(Surface,x1,x2,y, SDL_MapRGB(Surface->format, R, G, B));
}
//==================================================================================
// Internal draw horizontal line (alpha)
//==================================================================================
void _HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha)
{
Uint8 update = _sge_update;
Uint8 lock = _sge_lock;
_sge_update = 0;
_sge_lock = 0;
sge_FilledRectAlpha(Surface, x1,y,x2,y, Color, alpha);
_sge_update = update;
_sge_lock = lock;
}
//==================================================================================
// Draw horizontal line (alpha)
//==================================================================================
void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha)
{
sge_FilledRectAlpha(Surface, x1,y,x2,y, Color, alpha);
}
//==================================================================================
// Draw horizontal line (alpha RGB)
//==================================================================================
void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
sge_HLineAlpha(Surface,x1,x2,y, SDL_MapRGB(Surface->format, R, G, B), alpha);
}
//==================================================================================
// Internal draw vertical line
//==================================================================================
void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
{
if(y1>y2){Sint16 tmp=y1; y1=y2; y2=tmp;}
//Do the clipping
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
if(x<Surface->clip_minx || x>Surface->clip_maxx || y1>Surface->clip_maxy || y2<Surface->clip_miny)
return;
if(y1<Surface->clip_miny)
y1=Surface->clip_miny;
if(y2>Surface->clip_maxy)
y2=Surface->clip_maxy;
#endif
SDL_Rect l;
l.x=x; l.y=y1; l.w=1; l.h=y2-y1+1;
SDL_FillRect(Surface, &l, Color);
}
//==================================================================================
// Draw vertical line
//==================================================================================
void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
{
if(y1>y2){Sint16 tmp=y1; y1=y2; y2=tmp;}
//Do the clipping
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
if(x<Surface->clip_minx || x>Surface->clip_maxx || y1>Surface->clip_maxy || y2<Surface->clip_miny)
return;
if(y1<Surface->clip_miny)
y1=Surface->clip_miny;
if(y2>Surface->clip_maxy)
y2=Surface->clip_maxy;
#endif
SDL_Rect l;
l.x=x; l.y=y1; l.w=1; l.h=y2-y1+1;
SDL_FillRect(Surface, &l, Color);
sge_UpdateRect(Surface, x, y1, 1, y2-y1+1);
}
//==================================================================================
// Draw vertical line (RGB)
//==================================================================================
void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
{
sge_VLine(Surface,x,y1,y2, SDL_MapRGB(Surface->format, R, G, B));
}
//==================================================================================
// Internal draw vertical line (alpha - no update)
//==================================================================================
void _VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color, Uint8 alpha)
{
Uint8 update = _sge_update;
Uint8 lock = _sge_lock;
_sge_update = 0;
_sge_lock = 0;
sge_FilledRectAlpha(Surface, x,y1,x,y2, Color, alpha);
_sge_update = update;
_sge_lock = lock;
}
//==================================================================================
// Draw vertical line (alpha)
//==================================================================================
void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color, Uint8 alpha)
{
sge_FilledRectAlpha(Surface, x,y1,x,y2, Color, alpha);
}
//==================================================================================
// Draw vertical line (alpha RGB)
//==================================================================================
void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
sge_VLineAlpha(Surface,x,y1,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
}
//==================================================================================
// Performs Callback at each line point. (From PowerPak)
//==================================================================================
void sge_DoLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
{
Sint16 dx, dy, sdx, sdy, x, y, px, py;
dx = x2 - x1;
dy = y2 - y1;
sdx = (dx < 0) ? -1 : 1;
sdy = (dy < 0) ? -1 : 1;
dx = sdx * dx + 1;
dy = sdy * dy + 1;
x = y = 0;
px = x1;
py = y1;
if (dx >= dy){
for (x = 0; x < dx; x++){
Callback(Surface, px, py, Color);
y += dy;
if (y >= dx){
y -= dx;
py += sdy;
}
px += sdx;
}
}
else{
for (y = 0; y < dy; y++){
Callback(Surface, px, py, Color);
x += dx;
if (x >= dy){
x -= dy;
px += sdx;
}
py += sdy;
}
}
}
//==================================================================================
// Performs Callback at each line point. (RGB)
//==================================================================================
void sge_DoLine(SDL_Surface *Surface, Sint16 X1, Sint16 Y1, Sint16 X2, Sint16 Y2, Uint8 R, Uint8 G, Uint8 B, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
{
sge_DoLine(Surface,X1,Y1,X2,Y2, SDL_MapRGB(Surface->format, R, G, B),Callback);
}
//==================================================================================
// Draws a line
//==================================================================================
void _Line(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
{
/* Clipping */
if(x2<sge_clip_xmin(surface) || x1>sge_clip_xmax(surface) || y2<sge_clip_ymin(surface) || y1>sge_clip_ymax(surface))
return;
if (x1 < sge_clip_xmin(surface))
x1 = sge_clip_xmin(surface);
if (x2 > sge_clip_xmax(surface))
x2 = sge_clip_xmax(surface);
if (y1 < sge_clip_ymin(surface))
y1 = sge_clip_ymin(surface);
if (y2 > sge_clip_ymax(surface))
y2 = sge_clip_ymax(surface);
Sint16 dx, dy, sdx, sdy, x, y;
dx = x2 - x1;
dy = y2 - y1;
sdx = (dx < 0) ? -1 : 1;
sdy = (dy < 0) ? -1 : 1;
dx = sdx * dx + 1;
dy = sdy * dy + 1;
x = y = 0;
Sint16 pixx = surface->format->BytesPerPixel;
Sint16 pixy = surface->pitch;
Uint8 *pixel = (Uint8*)surface->pixels + y1*pixy + x1*pixx;
pixx *= sdx;
pixy *= sdy;
if (dx < dy) {
Sint32 tmp = dx; dx = dy; dy = Sint16(tmp);
tmp = pixx; pixx = pixy; pixy = tmp;
}
switch(surface->format->BytesPerPixel) {
case 1: {
for(x=0; x < dx; x++) {
*pixel = color;
y += dy;
if (y >= dx) {
y -= dx;
pixel += pixy;
}
pixel += pixx;
}
}
break;
case 2: {
for(x=0; x < dx; x++) {
*(Uint16*)pixel = color;
y += dy;
if (y >= dx) {
y -= dx;
pixel += pixy;
}
pixel += pixx;
}
}
break;
case 3: {
Uint8 rshift8 = surface->format->Rshift/8;
Uint8 gshift8 = surface->format->Gshift/8;
Uint8 bshift8 = surface->format->Bshift/8;
Uint8 ashift8 = surface->format->Ashift/8;
Uint8 R = (color>>surface->format->Rshift)&0xff;
Uint8 G = (color>>surface->format->Gshift)&0xff;
Uint8 B = (color>>surface->format->Bshift)&0xff;
Uint8 A = (color>>surface->format->Ashift)&0xff;
for(x=0; x < dx; x++) {
*(pixel+rshift8) = R;
*(pixel+gshift8) = G;
*(pixel+bshift8) = B;
*(pixel+ashift8) = A;
y += dy;
if (y >= dx) {
y -= dx;
pixel += pixy;
}
pixel += pixx;
}
}
break;
case 4: {
for(x=0; x < dx; x++) {
*(Uint32*)pixel = color;
y += dy;
if (y >= dx) {
y -= dx;
pixel += pixy;
}
pixel += pixx;
}
}
break;
}
}
void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color)
{
if (SDL_MUSTLOCK(Surface) && _sge_lock) {
if (SDL_LockSurface(Surface) < 0)
return;
}
/* Draw the line */
_Line(Surface, x1,y1, x2,y2, Color);
/* unlock the display */
if (SDL_MUSTLOCK(Surface) && _sge_lock) {
SDL_UnlockSurface(Surface);
}
sge_UpdateRect(Surface, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
}
//==================================================================================
// Draws a line (RGB)
//==================================================================================
void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
{
sge_Line(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B));
}
//==================================================================================
// A quick hack to get alpha working with callbacks
//==================================================================================
Uint8 _sge_alpha_hack = 0;
void callback_alpha_hack(SDL_Surface *surf, Sint16 x, Sint16 y, Uint32 color)
{
_PutPixelAlpha(surf,x,y,color,_sge_alpha_hack);
}
//==================================================================================
// Draws a line (alpha)
//==================================================================================
void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha)
{
if (SDL_MUSTLOCK(Surface) && _sge_lock)
if (SDL_LockSurface(Surface) < 0)
return;
_sge_alpha_hack = alpha;
/* Draw the line */
sge_DoLine(Surface, x1, y1, x2, y2, Color, callback_alpha_hack);
/* unlock the display */
if (SDL_MUSTLOCK(Surface) && _sge_lock) {
SDL_UnlockSurface(Surface);
}
sge_UpdateRect(Surface, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
}
//==================================================================================
// Draws a line (alpha - RGB)
//==================================================================================
void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
sge_LineAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
}
//==================================================================================
// Anti-aliased line
// From SDL_gfxPrimitives written by A. Schiffler (aschiffler@home.com)
//==================================================================================
#define AAbits 8
#define AAlevels 256 /* 2^AAbits */
void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
{
Sint32 xx0,yy0,xx1,yy1;
Uint32 intshift, erracc=0, erradj;
Uint32 erracctmp, wgt, wgtcompmask;
Sint16 dx, dy, tmp, xdir, y0p1, x0pxdir;
/* Keep on working with 32bit numbers */
xx0=x1;
yy0=y1;
xx1=x2;
yy1=y2;
/* Reorder points if required */
if (yy0 > yy1) {
tmp = yy0; yy0 = yy1; yy1 = tmp;
tmp = xx0; xx0 = xx1; xx1 = tmp;
}
/* Calculate distance */
dx = xx1 - xx0;
dy = yy1 - yy0;
/* Adjust for negative dx and set xdir */
if (dx >= 0) {
xdir=1;
} else {
xdir=-1;
dx=(-dx);
}
/* Check for special cases */
if (dx==0) {
/* Vertical line */
sge_VLineAlpha(dst, x1,y1,y2,color,alpha);
return;
} else if (dy==0) {
/* Horizontal line */
sge_HLineAlpha(dst, x1,x2,y1,color,alpha);
return;
} else if (dx==dy) {
/* Diagonal line */
if(alpha==255)
sge_Line(dst,x1,y1,x2,y2,color);
else
sge_LineAlpha(dst,x1,y1,x2,y2,color,alpha);
return;
}
Uint8 a = 255-alpha;
/* Lock surface */
if ( SDL_MUSTLOCK(dst) && _sge_lock )
if ( SDL_LockSurface(dst) < 0 )
return;
intshift = 32 - AAbits; /* # of bits by which to shift erracc to get intensity level */
wgtcompmask = AAlevels - 1; /* Mask used to flip all bits in an intensity weighting */
if(alpha==255)
_PutPixel(dst,x1,y1, color); /* Draw the initial pixel in the foreground color */
else
_PutPixelAlpha(dst,x1,y1, color, alpha);
/* x-major or y-major? */
if (dy > dx) {
/* y-major. Calculate 16-bit fixed point fractional part of a pixel that
X advances every time Y advances 1 pixel, truncating the result so that
we won't overrun the endpoint along the X axis */
erradj = ((dx << 16) / dy)<<16;
/* draw all pixels other than the first and last */
x0pxdir=xx0+xdir;
while (--dy) {
erracctmp = erracc;
erracc += erradj;
if (erracc <= erracctmp) {
/* rollover in error accumulator, x coord advances */
xx0=x0pxdir;
x0pxdir += xdir;
}
yy0++; /* y-major so always advance Y */
/* the AAbits most significant bits of erracc give us the intensity
weighting for this pixel, and the complement of the weighting for
the paired pixel. */
wgt = (erracc >> intshift) & 255;
tmp = 255-wgt-a;
if(tmp<0)
tmp=0;
_PutPixelAlpha(dst,xx0,yy0,color,Uint8(tmp));
tmp = wgt-a;
if(tmp<0)
tmp=0;
_PutPixelAlpha(dst,x0pxdir,yy0,color,Uint8(tmp));
}
} else {
/* x-major line. Calculate 16-bit fixed-point fractional part of a pixel
that Y advances each time X advances 1 pixel, truncating the result so
that we won't overrun the endpoint along the X axis. */
erradj = ((dy << 16) / dx)<<16;
/* draw all pixels other than the first and last */
y0p1=yy0+1;
while (--dx) {
erracctmp = erracc;
erracc += erradj;
if (erracc <= erracctmp) {
/* Accumulator turned over, advance y */
yy0=y0p1;
y0p1++;
}
xx0 += xdir; /* x-major so always advance X */
/* the AAbits most significant bits of erracc give us the intensity
weighting for this pixel, and the complement of the weighting for
the paired pixel. */
wgt = (erracc >> intshift) & 255;
tmp = 255-wgt-a;
if(tmp<0)
tmp=0;
_PutPixelAlpha(dst,xx0,yy0,color,tmp);
tmp = wgt-a;
if(tmp<0)
tmp=0;
_PutPixelAlpha(dst,xx0,y0p1,color,tmp);
}
}
/* Draw final pixel, always exactly intersected by the line and doesn't
need to be weighted. */
if(alpha==255)
_PutPixel(dst,x2,y2, color);
else
_PutPixelAlpha(dst,x2,y2, color, alpha);
/* unlock the display */
if (SDL_MUSTLOCK(dst) && _sge_lock) {
SDL_UnlockSurface(dst);
}
sge_UpdateRect(dst, (x1 < x2)? x1 : x2, (y1 < y2)? y1 : y2, ((x2-x1)<0)? (x1-x2+1) : (x2-x1+1), ((y2-y1)<0)? (y1-y2+1) : (y2-y1+1));
}
void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha)
{
sge_AALineAlpha(dst,x1,y1,x2,y2,SDL_MapRGB(dst->format, r, g, b),alpha);
}
void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
{
sge_AALineAlpha(dst, x1,y1, x2,y2, color, 255);
}
void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b)
{
sge_AALineAlpha(dst,x1,y1,x2,y2,SDL_MapRGB(dst->format, r, g, b),255);
}
/**********************************************************************************/
/** Figure functions **/
/**********************************************************************************/
//==================================================================================
// Draws a rectangle
//==================================================================================
void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
{
_HLine(Surface,x1,x2,y1,color);
_HLine(Surface,x1,x2,y2,color);
_VLine(Surface,x1,y1,y2,color);
_VLine(Surface,x2,y1,y2,color);
sge_UpdateRect(Surface, x1, y1, x2-x1, 1);
sge_UpdateRect(Surface, x1, y2, x2-x1+1, 1); /* Hmm? */
sge_UpdateRect(Surface, x1, y1, 1, y2-y1);
sge_UpdateRect(Surface, x2, y1, 1, y2-y1);
}
//==================================================================================
// Draws a rectangle (RGB)
//==================================================================================
void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
{
sge_Rect(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B));
}
//==================================================================================
// Draws a rectangle (alpha)
//==================================================================================
void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
{
if (SDL_MUSTLOCK(Surface) && _sge_lock)
if (SDL_LockSurface(Surface) < 0)
return;
_HLineAlpha(Surface,x1,x2,y1,color,alpha);
_HLineAlpha(Surface,x1,x2,y2,color,alpha);
_VLineAlpha(Surface,x1,y1,y2,color,alpha);
_VLineAlpha(Surface,x2,y1,y2,color,alpha);
if (SDL_MUSTLOCK(Surface) && _sge_lock) {
SDL_UnlockSurface(Surface);
}
sge_UpdateRect(Surface, x1, y1, x2-x1, 1);
sge_UpdateRect(Surface, x1, y2, x2-x1+1, 1); /* Hmm? */
sge_UpdateRect(Surface, x1, y1, 1, y2-y1);
sge_UpdateRect(Surface, x2, y1, 1, y2-y1);
}
//==================================================================================
// Draws a rectangle (RGB)
//==================================================================================
void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
sge_RectAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
}
//==================================================================================
// Draws a filled rectangle
//==================================================================================
void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
{
Sint16 tmp;
if(x1>x2){
tmp=x1; x1=x2; x2=tmp;
}
if(y1>y2){
tmp=y1; y1=y2; y2=tmp;
}
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
if(x2<Surface->clip_minx || x1>Surface->clip_maxx || y2<Surface->clip_miny || y1>Surface->clip_maxy)
return;
if (x1 < Surface->clip_minx)
x1=Surface->clip_minx;
if (x2 > Surface->clip_maxx)
x2=Surface->clip_maxx;
if (y1 < Surface->clip_miny)
y1=Surface->clip_miny;
if (y2 > Surface->clip_maxy)
y2=Surface->clip_maxy;
#endif
SDL_Rect area;
area.x=x1; area.y=y1;
area.w=x2-x1+1; area.h=y2-y1+1;
SDL_FillRect(Surface,&area,color);
sge_UpdateRect(Surface, x1, y1, x2-x1+1, y2-y1+1);
}
//==================================================================================
// Draws a filled rectangle (RGB)
//==================================================================================
void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
{
sge_FilledRect(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B));
}
//==================================================================================
// Draws a filled rectangle (alpha)
//==================================================================================
void sge_FilledRectAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
{
/*if( alpha == 255 ){
sge_FilledRect(surface,x1,y1,x2,y2,color);
return;
}*/
/* Fix coords */
Sint16 tmp;
if(x1>x2){
tmp=x1; x1=x2; x2=tmp;
}
if(y1>y2){
tmp=y1; y1=y2; y2=tmp;
}
/* Clipping */
if(x2<sge_clip_xmin(surface) || x1>sge_clip_xmax(surface) || y2<sge_clip_ymin(surface) || y1>sge_clip_ymax(surface))
return;
if (x1 < sge_clip_xmin(surface))
x1 = sge_clip_xmin(surface);
if (x2 > sge_clip_xmax(surface))
x2 = sge_clip_xmax(surface);
if (y1 < sge_clip_ymin(surface))
y1 = sge_clip_ymin(surface);
if (y2 > sge_clip_ymax(surface))
y2 = sge_clip_ymax(surface);
Uint32 Rmask = surface->format->Rmask, Gmask = surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
Uint32 R,G,B,A=0;
Sint16 x,y;
if (SDL_MUSTLOCK(surface) && _sge_lock)
if (SDL_LockSurface(surface) < 0)
return;
switch (surface->format->BytesPerPixel) {
case 1: { /* Assuming 8-bpp */
Uint8 *row, *pixel;
Uint8 dR, dG, dB;
Uint8 sR = surface->format->palette->colors[color].r;
Uint8 sG = surface->format->palette->colors[color].g;
Uint8 sB = surface->format->palette->colors[color].b;
for(y = y1; y<=y2; y++){
row = (Uint8 *)surface->pixels + y*surface->pitch;
for(x = x1; x <= x2; x++){
pixel = row + x;
dR = surface->format->palette->colors[*pixel].r;
dG = surface->format->palette->colors[*pixel].g;
dB = surface->format->palette->colors[*pixel].b;
dR = dR + ((sR-dR)*alpha >> 8);
dG = dG + ((sG-dG)*alpha >> 8);
dB = dB + ((sB-dB)*alpha >> 8);
*pixel = SDL_MapRGB(surface->format, dR, dG, dB);
}
}
}
break;
case 2: { /* Probably 15-bpp or 16-bpp */
Uint16 *row, *pixel;
Uint32 dR=(color & Rmask),dG=(color & Gmask),dB=(color & Bmask),dA=(color & Amask);
for(y = y1; y<=y2; y++){
row = (Uint16 *)surface->pixels + y*surface->pitch/2;
for(x = x1; x <= x2; x++){
pixel = row + x;
R = ((*pixel & Rmask) + (( dR - (*pixel & Rmask) ) * alpha >> 8)) & Rmask;
G = ((*pixel & Gmask) + (( dG - (*pixel & Gmask) ) * alpha >> 8)) & Gmask;
B = ((*pixel & Bmask) + (( dB - (*pixel & Bmask) ) * alpha >> 8)) & Bmask;
if( Amask )
A = ((*pixel & Amask) + (( dA - (*pixel & Amask) ) * alpha >> 8)) & Amask;
*pixel= R | G | B | A;
}
}
}
break;
case 3: { /* Slow 24-bpp mode, usually not used */
Uint8 *row,*pix;
Uint8 dR, dG, dB, dA;
Uint8 rshift8=surface->format->Rshift/8;
Uint8 gshift8=surface->format->Gshift/8;
Uint8 bshift8=surface->format->Bshift/8;
Uint8 ashift8=surface->format->Ashift/8;
Uint8 sR = (color>>surface->format->Rshift)&0xff;
Uint8 sG = (color>>surface->format->Gshift)&0xff;
Uint8 sB = (color>>surface->format->Bshift)&0xff;
Uint8 sA = (color>>surface->format->Ashift)&0xff;
for(y = y1; y<=y2; y++){
row = (Uint8 *)surface->pixels + y * surface->pitch;
for(x = x1; x <= x2; x++){
pix = row + x*3;
dR = *((pix)+rshift8);
dG = *((pix)+gshift8);
dB = *((pix)+bshift8);
dA = *((pix)+ashift8);
dR = dR + ((sR-dR)*alpha >> 8);
dG = dG + ((sG-dG)*alpha >> 8);
dB = dB + ((sB-dB)*alpha >> 8);
dA = dA + ((sA-dA)*alpha >> 8);
*((pix)+rshift8) = dR;
*((pix)+gshift8) = dG;
*((pix)+bshift8) = dB;
*((pix)+ashift8) = dA;
}
}
}
break;
case 4: { /* Probably 32-bpp */
Uint32 *row, *pixel;
Uint32 dR=(color & Rmask),dG=(color & Gmask),dB=(color & Bmask),dA=(color & Amask);
for(y = y1; y<=y2; y++){
row = (Uint32 *)surface->pixels + y*surface->pitch/4;
for(x = x1; x <= x2; x++){
pixel = row + x;
R = ((*pixel & Rmask) + (( dR - (*pixel & Rmask) ) * alpha >> 8)) & Rmask;
G = ((*pixel & Gmask) + (( dG - (*pixel & Gmask) ) * alpha >> 8)) & Gmask;
B = ((*pixel & Bmask) + (( dB - (*pixel & Bmask) ) * alpha >> 8)) & Bmask;
if( Amask )
A = ((*pixel & Amask) + (( dA - (*pixel & Amask) ) * alpha >> 8)) & Amask;
*pixel= R | G | B | A;
}
}
}
break;
}
if (SDL_MUSTLOCK(surface) && _sge_lock) {
SDL_UnlockSurface(surface);
}
sge_UpdateRect(surface, x1, y1, x2-x1+1, y2-y1+1);
}
void sge_FilledRectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
sge_FilledRectAlpha(Surface,x1,y1,x2,y2, SDL_MapRGB(Surface->format, R, G, B), alpha);
}
//==================================================================================
// Performs Callback at each ellipse point.
// (from Allegro)
//==================================================================================
void sge_DoEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color) )
{
int ix, iy;
int h, i, j, k;
int oh, oi, oj, ok;
if (rx < 1)
rx = 1;
if (ry < 1)
ry = 1;
h = i = j = k = 0xFFFF;
if (rx > ry) {
ix = 0;
iy = rx * 64;
do {
oh = h;
oi = i;
oj = j;
ok = k;
h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * ry) / rx;
k = (i * ry) / rx;
if (((h != oh) || (k != ok)) && (h < oi)) {
Callback(Surface, x+h, y+k, color);
if (h)
Callback(Surface, x-h, y+k, color);
if (k) {
Callback(Surface, x+h, y-k, color);
if (h)
Callback(Surface, x-h, y-k, color);
}
}
if (((i != oi) || (j != oj)) && (h < i)) {
Callback(Surface, x+i, y+j, color);
if (i)
Callback(Surface, x-i, y+j, color);
if (j) {
Callback(Surface, x+i, y-j, color);
if (i)
Callback(Surface, x-i, y-j, color);
}
}
ix = ix + iy / rx;
iy = iy - ix / rx;
} while (i > h);
}
else {
ix = 0;
iy = ry * 64;
do {
oh = h;
oi = i;
oj = j;
ok = k;
h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * rx) / ry;
k = (i * rx) / ry;
if (((j != oj) || (i != oi)) && (h < i)) {
Callback(Surface, x+j, y+i, color);
if (j)
Callback(Surface, x-j, y+i, color);
if (i) {
Callback(Surface, x+j, y-i, color);
if (j)
Callback(Surface, x-j, y-i, color);
}
}
if (((k != ok) || (h != oh)) && (h < oi)) {
Callback(Surface, x+k, y+h, color);
if (k)
Callback(Surface, x-k, y+h, color);
if (h) {
Callback(Surface, x+k, y-h, color);
if (k)
Callback(Surface, x-k, y-h, color);
}
}
ix = ix + iy / ry;
iy = iy - ix / ry;
} while(i > h);
}
}
//==================================================================================
// Performs Callback at each ellipse point. (RGB)
//==================================================================================
void sge_DoEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color) )
{
sge_DoEllipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),Callback);
}
//==================================================================================
// Draws an ellipse
//==================================================================================
void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
{
if (SDL_MUSTLOCK(Surface) && _sge_lock) {
if (SDL_LockSurface(Surface) < 0)
return;
}
sge_DoEllipse(Surface, x, y, rx, ry, color, _PutPixel);
if (SDL_MUSTLOCK(Surface) && _sge_lock) {
SDL_UnlockSurface(Surface);
}
sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1);
}
//==================================================================================
// Draws an ellipse (RGB)
//==================================================================================
void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
{
sge_Ellipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B));
}
//==================================================================================
// Draws an ellipse (alpha)
//==================================================================================
void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha)
{
if (SDL_MUSTLOCK(Surface) && _sge_lock)
if (SDL_LockSurface(Surface) < 0)
return;
_sge_alpha_hack = alpha;
sge_DoEllipse(Surface, x, y, rx, ry, color, callback_alpha_hack);
if (SDL_MUSTLOCK(Surface) && _sge_lock) {
SDL_UnlockSurface(Surface);
}
sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1);
}
//==================================================================================
// Draws an ellipse (alpha - RGB)
//==================================================================================
void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
sge_EllipseAlpha(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),alpha);
}
//==================================================================================
// Draws a filled ellipse
//==================================================================================
void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
{
int ix, iy;
int h, i, j, k;
int oh, oi, oj, ok;
if (rx < 1)
rx = 1;
if (ry < 1)
ry = 1;
oh = oi = oj = ok = 0xFFFF;
if (rx > ry) {
ix = 0;
iy = rx * 64;
do {
h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * ry) / rx;
k = (i * ry) / rx;
if ((k!=ok) && (k!=oj)) {
if (k){
_HLine(Surface,x-h,x+h,y-k,color);
_HLine(Surface,x-h,x+h,y+k,color);
}else
_HLine(Surface,x-h,x+h,y,color);
ok=k;
}
if ((j!=oj) && (j!=ok) && (k!=j)) {
if (j){
_HLine(Surface,x-i,x+i,y-j,color);
_HLine(Surface,x-i,x+i,y+j,color);
}else
_HLine(Surface,x-i,x+i,y,color);
oj=j;
}
ix = ix + iy / rx;
iy = iy - ix / rx;
} while (i > h);
}
else {
ix = 0;
iy = ry * 64;
do {
h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * rx) / ry;
k = (i * rx) / ry;
if ((i!=oi) && (i!=oh)) {
if (i){
_HLine(Surface,x-j,x+j,y-i,color);
_HLine(Surface,x-j,x+j,y+i,color);
}else
_HLine(Surface,x-j,x+j,y,color);
oi=i;
}
if ((h!=oh) && (h!=oi) && (i!=h)) {
if (h){
_HLine(Surface,x-k,x+k,y-h,color);
_HLine(Surface,x-k,x+k,y+h,color);
}else
_HLine(Surface,x-k,x+k,y,color);
oh=h;
}
ix = ix + iy / ry;
iy = iy - ix / ry;
} while(i > h);
}
sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1);
}
//==================================================================================
// Draws a filled ellipse (RGB)
//==================================================================================
void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B)
{
sge_FilledEllipse(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B));
}
//==================================================================================
// Draws a filled ellipse (alpha)
//==================================================================================
void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha)
{
int ix, iy;
int h, i, j, k;
int oh, oi, oj, ok;
if (SDL_MUSTLOCK(Surface) && _sge_lock)
if (SDL_LockSurface(Surface) < 0)
return;
if (rx < 1)
rx = 1;
if (ry < 1)
ry = 1;
oh = oi = oj = ok = 0xFFFF;
if (rx > ry) {
ix = 0;
iy = rx * 64;
do {
h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * ry) / rx;
k = (i * ry) / rx;
if ((k!=ok) && (k!=oj)) {
if (k){
_HLineAlpha(Surface,x-h,x+h,y-k,color,alpha);
_HLineAlpha(Surface,x-h,x+h,y+k,color,alpha);
}else
_HLineAlpha(Surface,x-h,x+h,y,color,alpha);
ok=k;
}
if ((j!=oj) && (j!=ok) && (k!=j)) {
if (j){
_HLineAlpha(Surface,x-i,x+i,y-j,color,alpha);
_HLineAlpha(Surface,x-i,x+i,y+j,color,alpha);
}else
_HLineAlpha(Surface,x-i,x+i,y,color,alpha);
oj=j;
}
ix = ix + iy / rx;
iy = iy - ix / rx;
} while (i > h);
}
else {
ix = 0;
iy = ry * 64;
do {
h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * rx) / ry;
k = (i * rx) / ry;
if ((i!=oi) && (i!=oh)) {
if (i){
_HLineAlpha(Surface,x-j,x+j,y-i,color,alpha);
_HLineAlpha(Surface,x-j,x+j,y+i,color,alpha);
}else
_HLineAlpha(Surface,x-j,x+j,y,color,alpha);
oi=i;
}
if ((h!=oh) && (h!=oi) && (i!=h)) {
if (h){
_HLineAlpha(Surface,x-k,x+k,y-h,color,alpha);
_HLineAlpha(Surface,x-k,x+k,y+h,color,alpha);
}else
_HLineAlpha(Surface,x-k,x+k,y,color,alpha);
oh=h;
}
ix = ix + iy / ry;
iy = iy - ix / ry;
} while(i > h);
}
if (SDL_MUSTLOCK(Surface) && _sge_lock) {
SDL_UnlockSurface(Surface);
}
sge_UpdateRect(Surface, x-rx, y-ry, 2*rx+1, 2*ry+1);
}
//==================================================================================
// Draws a filled ellipse (alpha - RGB)
//==================================================================================
void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
sge_FilledEllipseAlpha(Surface,x,y,rx,ry,SDL_MapRGB(Surface->format, R, G, B),alpha);
}
//==================================================================================
// Performs Callback at each circle point.
//==================================================================================
void sge_DoCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
{
Sint16 cx = 0;
Sint16 cy = r;
Sint16 df = 1 - r;
Sint16 d_e = 3;
Sint16 d_se = -2 * r + 5;
do {
Callback(Surface, x+cx, y+cy, color);
Callback(Surface, x-cx, y+cy, color);
Callback(Surface, x+cx, y-cy, color);
Callback(Surface, x-cx, y-cy, color);
Callback(Surface, x+cy, y+cx, color);
Callback(Surface, x+cy, y-cx, color);
Callback(Surface, x-cy, y+cx, color);
Callback(Surface, x-cy, y-cx, color);
if (df < 0) {
df += d_e;
d_e += 2;
d_se += 2;
}
else {
df += d_se;
d_e += 2;
d_se += 4;
cy--;
}
cx++;
}while(cx <= cy);
}
//==================================================================================
// Performs Callback at each circle point. (RGB)
//==================================================================================
void sge_DoCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color))
{
sge_DoCircle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),Callback);
}
//==================================================================================
// Draws a circle
//==================================================================================
void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
{
if (SDL_MUSTLOCK(Surface) && _sge_lock) {
if (SDL_LockSurface(Surface) < 0)
return;
}
sge_DoCircle(Surface, x, y, r, color, _PutPixel);
if (SDL_MUSTLOCK(Surface) && _sge_lock) {
SDL_UnlockSurface(Surface);
}
sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1);
}
//==================================================================================
// Draws a circle (RGB)
//==================================================================================
void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
{
sge_Circle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B));
}
//==================================================================================
// Draws a circle (alpha)
//==================================================================================
void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha)
{
if (SDL_MUSTLOCK(Surface) && _sge_lock)
if (SDL_LockSurface(Surface) < 0)
return;
_sge_alpha_hack = alpha;
sge_DoCircle(Surface, x, y, r, color, callback_alpha_hack);
if (SDL_MUSTLOCK(Surface) && _sge_lock) {
SDL_UnlockSurface(Surface);
}
sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1);
}
//==================================================================================
// Draws a circle (alpha - RGB)
//==================================================================================
void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
sge_CircleAlpha(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),alpha);
}
//==================================================================================
// Draws a filled circle
//==================================================================================
void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
{
Sint16 cx = 0;
Sint16 cy = r;
bool draw=true;
Sint16 df = 1 - r;
Sint16 d_e = 3;
Sint16 d_se = -2 * r + 5;
do {
if(draw){
_HLine(Surface,x-cx,x+cx,y+cy,color);
_HLine(Surface,x-cx,x+cx,y-cy,color);
draw=false;
}
if(cx!=cy){
if(cx){
_HLine(Surface,x-cy,x+cy,y-cx,color);
_HLine(Surface,x-cy,x+cy,y+cx,color);
}else
_HLine(Surface,x-cy,x+cy,y,color);
}
if (df < 0) {
df += d_e;
d_e += 2;
d_se += 2;
}
else {
df += d_se;
d_e += 2;
d_se += 4;
cy--;
draw=true;
}
cx++;
}while(cx <= cy);
sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1);
}
//==================================================================================
// Draws a filled circle (RGB)
//==================================================================================
void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B)
{
sge_FilledCircle(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B));
}
//==================================================================================
// Draws a filled circle (alpha)
//==================================================================================
void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha)
{
Sint16 cx = 0;
Sint16 cy = r;
bool draw=true;
Sint16 df = 1 - r;
Sint16 d_e = 3;
Sint16 d_se = -2 * r + 5;
if (SDL_MUSTLOCK(Surface) && _sge_lock)
if (SDL_LockSurface(Surface) < 0)
return;
do {
if(draw){
_HLineAlpha(Surface,x-cx,x+cx,y+cy,color,alpha);
_HLineAlpha(Surface,x-cx,x+cx,y-cy,color,alpha);
draw=false;
}
if(cx!=cy){
if(cx){
_HLineAlpha(Surface,x-cy,x+cy,y-cx,color,alpha);
_HLineAlpha(Surface,x-cy,x+cy,y+cx,color,alpha);
}else
_HLineAlpha(Surface,x-cy,x+cy,y,color,alpha);
}
if (df < 0) {
df += d_e;
d_e += 2;
d_se += 2;
}
else {
df += d_se;
d_e += 2;
d_se += 4;
cy--;
draw=true;
}
cx++;
}while(cx <= cy);
if (SDL_MUSTLOCK(Surface) && _sge_lock) {
SDL_UnlockSurface(Surface);
}
sge_UpdateRect(Surface, x-r, y-r, 2*r+1, 2*r+1);
}
//==================================================================================
// Draws a filled circle (alpha - RGB)
//==================================================================================
void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
sge_FilledCircleAlpha(Surface,x,y,r,SDL_MapRGB(Surface->format, R, G, B),alpha);
}
//==================================================================================
// Draws a bezier line
//==================================================================================
/* Macro to do the line... 'function' is the line drawing routine */
#define DO_BEZIER(function)\
/*
* Note: I don't think there is any great performance win in translating this to fixed-point integer math,
* most of the time is spent in the line drawing routine.
*/\
float x = float(x1), y = float(y1);\
float xp = x, yp = y;\
float delta;\
float dx, d2x, d3x;\
float dy, d2y, d3y;\
float a, b, c;\
int i;\
int n = 1;\
Sint16 xmax=x1, ymax=y1, xmin=x1, ymin=y1;\
\
/* compute number of iterations */\
if(level < 1)\
level=1;\
if(level >= 15)\
level=15; \
while (level-- > 0)\
n*= 2;\
delta = 1.0 / float(n);\
\
/* compute finite differences */\
/* a, b, c are the coefficient of the polynom in t defining the parametric curve */\
/* The computation is done independently for x and y */\
a = float(-x1 + 3*x2 - 3*x3 + x4);\
b = float(3*x1 - 6*x2 + 3*x3);\
c = float(-3*x1 + 3*x2);\
\
d3x = 6 * a * delta*delta*delta;\
d2x = d3x + 2 * b * delta*delta;\
dx = a * delta*delta*delta + b * delta*delta + c * delta;\
\
a = float(-y1 + 3*y2 - 3*y3 + y4);\
b = float(3*y1 - 6*y2 + 3*y3);\
c = float(-3*y1 + 3*y2);\
\
d3y = 6 * a * delta*delta*delta;\
d2y = d3y + 2 * b * delta*delta;\
dy = a * delta*delta*delta + b * delta*delta + c * delta;\
\
if (SDL_MUSTLOCK(surface) && _sge_lock) {\
if (SDL_LockSurface(surface) < 0)\
return;\
}\
\
/* iterate */\
for (i = 0; i < n; i++) {\
x += dx; dx += d2x; d2x += d3x;\
y += dy; dy += d2y; d2y += d3y;\
if(Sint16(xp) != Sint16(x) || Sint16(yp) != Sint16(y)){\
function;\
if(_sge_update==1){\
xmax= (xmax>Sint16(xp))? xmax : Sint16(xp); ymax= (ymax>Sint16(yp))? ymax : Sint16(yp);\
xmin= (xmin<Sint16(xp))? xmin : Sint16(xp); ymin= (ymin<Sint16(yp))? ymin : Sint16(yp);\
xmax= (xmax>Sint16(x))? xmax : Sint16(x); ymax= (ymax>Sint16(y))? ymax : Sint16(y);\
xmin= (xmin<Sint16(x))? xmin : Sint16(x); ymin= (ymin<Sint16(y))? ymin : Sint16(y);\
}\
}\
xp = x; yp = y;\
}\
\
/* unlock the display */\
if (SDL_MUSTLOCK(surface) && _sge_lock) {\
SDL_UnlockSurface(surface);\
}\
\
/* Update the area */\
sge_UpdateRect(surface, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
//==================================================================================
// Draws a bezier line
//==================================================================================
void sge_Bezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color)
{
DO_BEZIER(_Line(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color));
}
//==================================================================================
// Draws a bezier line (RGB)
//==================================================================================
void sge_Bezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B)
{
sge_Bezier(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B));
}
//==================================================================================
// Draws a bezier line (alpha)
//==================================================================================
void sge_BezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color, Uint8 alpha)
{
_sge_alpha_hack = alpha;
DO_BEZIER(sge_DoLine(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color, callback_alpha_hack));
}
//==================================================================================
// Draws a bezier line (alpha - RGB)
//==================================================================================
void sge_BezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
sge_BezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),alpha);
}
//==================================================================================
// Draws an AA bezier line (alpha)
//==================================================================================
void sge_AABezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color, Uint8 alpha)
{
Uint8 update = _sge_update;
Uint8 lock = _sge_lock;
_sge_update = 0;
_sge_lock = 0;
if (SDL_MUSTLOCK(surface) && lock)
if (SDL_LockSurface(surface) < 0)
return;
DO_BEZIER(sge_AALineAlpha(surface, Sint16(xp),Sint16(yp), Sint16(x),Sint16(y), color, alpha));
if (SDL_MUSTLOCK(surface) && lock) {
SDL_UnlockSurface(surface);
}
_sge_update = update;
_sge_lock = lock;
sge_UpdateRect(surface, xmin, ymin, xmax-xmin+1, ymax-ymin+1);
}
//==================================================================================
// Draws an AA bezier line (alpha - RGB)
//==================================================================================
void sge_AABezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
sge_AABezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),alpha);
}
//==================================================================================
// Draws an AA bezier line
//==================================================================================
void sge_AABezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color)
{
sge_AABezierAlpha(surface, x1,y1, x2,y2, x3,y3, x4,y4, level, color, 255);
}
//==================================================================================
// Draws an AA bezier line (RGB)
//==================================================================================
void sge_AABezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B)
{
sge_AABezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),255);
}
diff --git a/src/sge_primitives.h b/src/sge_primitives.h
index d81aa64..be0086a 100644
--- a/src/sge_primitives.h
+++ b/src/sge_primitives.h
@@ -1,92 +1,92 @@
/*
* SDL Graphics Extension
* Drawing primitives (header)
*
* Started 990815 (split from sge_draw 010611)
*
* License: LGPL v2+ (see the file LICENSE)
* (c)1999-2001 Anders Lindstr?m
*/
/*********************************************************************
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
*********************************************************************/
#ifndef sge_primitives_H
#define sge_primitives_H
-#include <SDL/SDL.h>
+#include "SDL.h"
#include "sge_internal.h"
#ifdef _SGE_C
extern "C" {
#endif
DECLSPEC void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color);
DECLSPEC void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color, Uint8 alpha);
DECLSPEC void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color);
DECLSPEC void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color, Uint8 alpha);
DECLSPEC void sge_DoLine(SDL_Surface *Surface, Sint16 X1, Sint16 Y1, Sint16 X2, Sint16 Y2, Uint32 Color, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color));
DECLSPEC void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color);
DECLSPEC void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 Color, Uint8 alpha);
DECLSPEC void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);
DECLSPEC void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha);
DECLSPEC void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);
DECLSPEC void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha);
DECLSPEC void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);
DECLSPEC void sge_FilledRectAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha);
DECLSPEC void sge_DoEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color));
DECLSPEC void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color);
DECLSPEC void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 Alpha);
DECLSPEC void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color);
DECLSPEC void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color, Uint8 alpha);
DECLSPEC void sge_DoCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color));
DECLSPEC void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color);
DECLSPEC void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha);
DECLSPEC void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color);
DECLSPEC void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint32 color, Uint8 alpha);
DECLSPEC void sge_Bezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color);
DECLSPEC void sge_BezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color, Uint8 alpha);
DECLSPEC void sge_AABezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color);
DECLSPEC void sge_AABezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint32 color, Uint8 alpha);
#ifdef _SGE_C
}
#endif
#ifndef sge_C_ONLY
DECLSPEC void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void sge_HLineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
DECLSPEC void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void sge_VLineAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
DECLSPEC void sge_DoLine(SDL_Surface *Surface, Sint16 X1, Sint16 Y1, Sint16 X2, Sint16 Y2, Uint8 R, Uint8 G, Uint8 B, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color));
DECLSPEC void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void sge_LineAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
DECLSPEC void sge_AALine(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b);
DECLSPEC void sge_AALineAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 alpha);
DECLSPEC void sge_Rect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void sge_RectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
DECLSPEC void sge_FilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void sge_FilledRectAlpha(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
DECLSPEC void sge_DoEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color));
DECLSPEC void sge_Ellipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void sge_EllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
DECLSPEC void sge_FilledEllipse(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void sge_FilledEllipseAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
DECLSPEC void sge_DoCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y, Uint32 Color));
DECLSPEC void sge_Circle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void sge_CircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
DECLSPEC void sge_FilledCircle(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void sge_FilledCircleAlpha(SDL_Surface *Surface, Sint16 x, Sint16 y, Sint16 r, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
DECLSPEC void sge_Bezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void sge_BezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
DECLSPEC void sge_AABezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void sge_AABezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
#endif /* sge_C_ONLY */
#endif /* sge_primitives_H */
diff --git a/src/sge_surface.cpp b/src/sge_surface.cpp
index 5c77090..5107226 100644
--- a/src/sge_surface.cpp
+++ b/src/sge_surface.cpp
@@ -1,883 +1,883 @@
/*
* SDL Graphics Extension
* Pixel, surface and color functions
*
* Started 990815 (split from sge_draw 010611)
*
* License: LGPL v2+ (see the file LICENSE)
* (c)1999-2001 Anders Lindstr?m
*/
/*********************************************************************
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
*********************************************************************/
/*
* Some of this code is taken from the "Introduction to SDL" and
* John Garrison's PowerPak
*/
-#include <SDL/SDL.h>
+#include "SDL.h"
#include <math.h>
#include <string.h>
#include <stdarg.h>
#include "sge_surface.h"
/* Globals used for sge_Update/sge_Lock */
Uint8 _sge_update=1;
Uint8 _sge_lock=1;
/**********************************************************************************/
/** Misc. functions **/
/**********************************************************************************/
//==================================================================================
// Turns off automatic update (to avoid tearing).
//==================================================================================
void sge_Update_OFF(void)
{
_sge_update=0;
}
//==================================================================================
// Turns on automatic update (default)
//==================================================================================
void sge_Update_ON(void)
{
_sge_update=1;
}
//==================================================================================
// Turns off automatic locking of surfaces
//==================================================================================
void sge_Lock_OFF(void)
{
_sge_lock=0;
}
//==================================================================================
// Turns on automatic locking (default)
//==================================================================================
void sge_Lock_ON(void)
{
_sge_lock=1;
}
//==================================================================================
// Returns update&locking mode (1-on and 0-off)
//==================================================================================
Uint8 sge_getUpdate(void)
{
return _sge_update;
}
Uint8 sge_getLock(void)
{
return _sge_lock;
}
//==================================================================================
// SDL_UpdateRect does nothing if any part of the rectangle is outside the surface
// --- This version always work
//==================================================================================
void sge_UpdateRect(SDL_Surface *screen, Sint16 x, Sint16 y, Uint16 w, Uint16 h)
{
if(_sge_update!=1 || screen != SDL_GetVideoSurface()){return;}
if(x>=screen->w || y>=screen->h){return;}
Sint16 a,b;
a=w; b=h;
if(x < 0){x=0;}
if(y < 0){y=0;}
if(a+x > screen->w){a=screen->w-x;}
if(b+y > screen->h){b=screen->h-y;}
SDL_UpdateRect(screen,x,y,a,b);
}
//==================================================================================
// Creates a 32bit (8/8/8/8) alpha surface
// Map colors with sge_MapAlpha() and then use the Uint32 color versions of
// SGEs routines
//==================================================================================
SDL_Surface *sge_CreateAlphaSurface(Uint32 flags, int width, int height)
{
return SDL_CreateRGBSurface(flags,width,height,32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
}
//==================================================================================
// Returns the Uint32 color value for a 32bit (8/8/8/8) alpha surface
//==================================================================================
Uint32 sge_MapAlpha(Uint8 R, Uint8 G, Uint8 B, Uint8 A)
{
Uint32 color=0;
color|=R<<24;
color|=G<<16;
color|=B<<8;
color|=A;
return color;
}
//==================================================================================
// Sets an SDL error string
// Accepts formated argument - like printf()
// SDL_SetError() also does this, but it does not use standard syntax (why?)
//==================================================================================
void sge_SetError(const char *format, ...)
{
char buf[256];
va_list ap;
#ifdef __WIN32__
va_start((va_list*)ap, format); //Stupid w32 crosscompiler
#else
va_start(ap, format);
#endif
vsprintf(buf, format, ap);
va_end(ap);
SDL_SetError(buf);
}
/**********************************************************************************/
/** Pixel functions **/
/**********************************************************************************/
//==================================================================================
// Fast put pixel
//==================================================================================
void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
if(x>=sge_clip_xmin(surface) && x<=sge_clip_xmax(surface) && y>=sge_clip_ymin(surface) && y<=sge_clip_ymax(surface)){
switch (surface->format->BytesPerPixel) {
case 1: { /* Assuming 8-bpp */
*((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
}
break;
case 2: { /* Probably 15-bpp or 16-bpp */
*((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
}
break;
case 3: { /* Slow 24-bpp mode, usually not used */
Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
/* Gack - slow, but endian correct */
*(pix+surface->format->Rshift/8) = color>>surface->format->Rshift;
*(pix+surface->format->Gshift/8) = color>>surface->format->Gshift;
*(pix+surface->format->Bshift/8) = color>>surface->format->Bshift;
*(pix+surface->format->Ashift/8) = color>>surface->format->Ashift;
}
break;
case 4: { /* Probably 32-bpp */
*((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
}
break;
}
}
}
//==================================================================================
// Fast put pixel (RGB)
//==================================================================================
void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B)
{
_PutPixel(surface,x,y, SDL_MapRGB(surface->format, R, G, B));
}
//==================================================================================
// Fastest put pixel functions (don't mess up indata, thank you)
//==================================================================================
void _PutPixel8(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
*((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
}
void _PutPixel16(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
*((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
}
void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
/* Gack - slow, but endian correct */
*(pix+surface->format->Rshift/8) = color>>surface->format->Rshift;
*(pix+surface->format->Gshift/8) = color>>surface->format->Gshift;
*(pix+surface->format->Bshift/8) = color>>surface->format->Bshift;
*(pix+surface->format->Ashift/8) = color>>surface->format->Ashift;
}
void _PutPixel32(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
*((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
}
void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color)
{
switch ( dest->format->BytesPerPixel ) {
case 1:
*((Uint8 *)dest->pixels + y*dest->pitch + x) = color;
break;
case 2:
*((Uint16 *)dest->pixels + y*dest->pitch/2 + x) = color;
break;
case 3:
_PutPixel24(dest,x,y,color);
break;
case 4:
*((Uint32 *)dest->pixels + y*dest->pitch/4 + x) = color;
break;
}
}
//==================================================================================
// Safe put pixel
//==================================================================================
void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
if ( SDL_MUSTLOCK(surface) && _sge_lock ) {
if ( SDL_LockSurface(surface) < 0 ) {
return;
}
}
_PutPixel(surface, x, y, color);
if ( SDL_MUSTLOCK(surface) && _sge_lock ) {
SDL_UnlockSurface(surface);
}
if(_sge_update!=1){return;}
sge_UpdateRect(surface, x, y, 1, 1);
}
//==================================================================================
// Safe put pixel (RGB)
//==================================================================================
void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B)
{
sge_PutPixel(surface,x,y, SDL_MapRGB(surface->format, R, G, B));
}
//==================================================================================
// Calculate y pitch offset
// (the y pitch offset is constant for the same y coord and surface)
//==================================================================================
Sint32 sge_CalcYPitch(SDL_Surface *dest,Sint16 y)
{
if(y>=sge_clip_ymin(dest) && y<=sge_clip_ymax(dest)){
switch ( dest->format->BytesPerPixel ) {
case 1:
return y*dest->pitch;
break;
case 2:
return y*dest->pitch/2;
break;
case 3:
return y*dest->pitch;
break;
case 4:
return y*dest->pitch/4;
break;
}
}
return -1;
}
//==================================================================================
// Put pixel with precalculated y pitch offset
//==================================================================================
void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color)
{
if(x>=sge_clip_xmin(surface) && x<=sge_clip_xmax(surface) && ypitch>=0){
switch (surface->format->BytesPerPixel) {
case 1: { /* Assuming 8-bpp */
*((Uint8 *)surface->pixels + ypitch + x) = color;
}
break;
case 2: { /* Probably 15-bpp or 16-bpp */
*((Uint16 *)surface->pixels + ypitch + x) = color;
}
break;
case 3: { /* Slow 24-bpp mode, usually not used */
/* Gack - slow, but endian correct */
Uint8 *pix = (Uint8 *)surface->pixels + ypitch + x*3;
*(pix+surface->format->Rshift/8) = color>>surface->format->Rshift;
*(pix+surface->format->Gshift/8) = color>>surface->format->Gshift;
*(pix+surface->format->Bshift/8) = color>>surface->format->Bshift;
*(pix+surface->format->Ashift/8) = color>>surface->format->Ashift;
}
break;
case 4: { /* Probably 32-bpp */
*((Uint32 *)surface->pixels + ypitch + x) = color;
}
break;
}
}
}
//==================================================================================
// Get pixel
//==================================================================================
Uint32 sge_GetPixel(SDL_Surface *surface, Sint16 x, Sint16 y)
{
switch (surface->format->BytesPerPixel) {
case 1: { /* Assuming 8-bpp */
return *((Uint8 *)surface->pixels + y*surface->pitch + x);
}
break;
case 2: { /* Probably 15-bpp or 16-bpp */
return *((Uint16 *)surface->pixels + y*surface->pitch/2 + x);
}
break;
case 3: { /* Slow 24-bpp mode, usually not used */
Uint8 *pix;
int shift;
Uint32 color=0;
pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
shift = surface->format->Rshift;
color = *(pix+shift/8)<<shift;
shift = surface->format->Gshift;
color|= *(pix+shift/8)<<shift;
shift = surface->format->Bshift;
color|= *(pix+shift/8)<<shift;
shift = surface->format->Ashift;
color|= *(pix+shift/8)<<shift;
return color;
}
break;
case 4: { /* Probably 32-bpp */
return *((Uint32 *)surface->pixels + y*surface->pitch/4 + x);
}
break;
}
return 0;
}
//==================================================================================
// Put pixel with alpha blending
//==================================================================================
void _PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha)
{
if(x>=sge_clip_xmin(surface) && x<=sge_clip_xmax(surface) && y>=sge_clip_ymin(surface) && y<=sge_clip_ymax(surface)){
Uint32 Rmask = surface->format->Rmask, Gmask = surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
Uint32 R,G,B,A=0;
switch (surface->format->BytesPerPixel) {
case 1: { /* Assuming 8-bpp */
if( alpha == 255 ){
*((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
}else{
Uint8 *pixel = (Uint8 *)surface->pixels + y*surface->pitch + x;
Uint8 dR = surface->format->palette->colors[*pixel].r;
Uint8 dG = surface->format->palette->colors[*pixel].g;
Uint8 dB = surface->format->palette->colors[*pixel].b;
Uint8 sR = surface->format->palette->colors[color].r;
Uint8 sG = surface->format->palette->colors[color].g;
Uint8 sB = surface->format->palette->colors[color].b;
dR = dR + ((sR-dR)*alpha >> 8);
dG = dG + ((sG-dG)*alpha >> 8);
dB = dB + ((sB-dB)*alpha >> 8);
*pixel = SDL_MapRGB(surface->format, dR, dG, dB);
}
}
break;
case 2: { /* Probably 15-bpp or 16-bpp */
if( alpha == 255 ){
*((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
}else{
Uint16 *pixel = (Uint16 *)surface->pixels + y*surface->pitch/2 + x;
Uint32 dc = *pixel;
R = ((dc & Rmask) + (( (color & Rmask) - (dc & Rmask) ) * alpha >> 8)) & Rmask;
G = ((dc & Gmask) + (( (color & Gmask) - (dc & Gmask) ) * alpha >> 8)) & Gmask;
B = ((dc & Bmask) + (( (color & Bmask) - (dc & Bmask) ) * alpha >> 8)) & Bmask;
if( Amask )
A = ((dc & Amask) + (( (color & Amask) - (dc & Amask) ) * alpha >> 8)) & Amask;
*pixel= R | G | B | A;
}
}
break;
case 3: { /* Slow 24-bpp mode, usually not used */
Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
Uint8 rshift8=surface->format->Rshift/8;
Uint8 gshift8=surface->format->Gshift/8;
Uint8 bshift8=surface->format->Bshift/8;
Uint8 ashift8=surface->format->Ashift/8;
if( alpha == 255 ){
*(pix+rshift8) = color>>surface->format->Rshift;
*(pix+gshift8) = color>>surface->format->Gshift;
*(pix+bshift8) = color>>surface->format->Bshift;
*(pix+ashift8) = color>>surface->format->Ashift;
}else{
Uint8 dR, dG, dB, dA=0;
Uint8 sR, sG, sB, sA=0;
pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
dR = *((pix)+rshift8);
dG = *((pix)+gshift8);
dB = *((pix)+bshift8);
dA = *((pix)+ashift8);
sR = (color>>surface->format->Rshift)&0xff;
sG = (color>>surface->format->Gshift)&0xff;
sB = (color>>surface->format->Bshift)&0xff;
sA = (color>>surface->format->Ashift)&0xff;
dR = dR + ((sR-dR)*alpha >> 8);
dG = dG + ((sG-dG)*alpha >> 8);
dB = dB + ((sB-dB)*alpha >> 8);
dA = dA + ((sA-dA)*alpha >> 8);
*((pix)+rshift8) = dR;
*((pix)+gshift8) = dG;
*((pix)+bshift8) = dB;
*((pix)+ashift8) = dA;
}
}
break;
case 4: { /* Probably 32-bpp */
if( alpha == 255 ){
*((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
}else{
Uint32 *pixel = (Uint32 *)surface->pixels + y*surface->pitch/4 + x;
Uint32 dc = *pixel;
R = ((dc & Rmask) + (( (color & Rmask) - (dc & Rmask) ) * alpha >> 8)) & Rmask;
G = ((dc & Gmask) + (( (color & Gmask) - (dc & Gmask) ) * alpha >> 8)) & Gmask;
B = ((dc & Bmask) + (( (color & Bmask) - (dc & Bmask) ) * alpha >> 8)) & Bmask;
if( Amask )
A = ((dc & Amask) + (( (color & Amask) - (dc & Amask) ) * alpha >> 8)) & Amask;
*pixel = R | G | B | A;
}
}
break;
}
}
}
void sge_PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha)
{
if ( SDL_MUSTLOCK(surface) && _sge_lock )
if ( SDL_LockSurface(surface) < 0 )
return;
_PutPixelAlpha(surface,x,y,color,alpha);
/* unlock the display */
if (SDL_MUSTLOCK(surface) && _sge_lock) {
SDL_UnlockSurface(surface);
}
if(_sge_update!=1){return;}
sge_UpdateRect(surface, x, y, 1, 1);
}
void _PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
_PutPixelAlpha(surface,x,y, SDL_MapRGB(surface->format, R, G, B),alpha);
}
void sge_PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
sge_PutPixelAlpha(surface,x,y, SDL_MapRGB(surface->format, R, G, B), alpha);
}
/**********************************************************************************/
/** Block functions **/
/**********************************************************************************/
//==================================================================================
// The sge_write_block* functions copies the given block (a surface line) directly
// to the surface. This is *much* faster then using the put pixel functions to
// update a line. The block consist of Surface->w (the width of the surface) numbers
// of color values. Note the difference in byte size for the block elements for
// different color dephts. 24 bpp is slow and not included!
//==================================================================================
void sge_write_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y)
{
memcpy( (Uint8 *)Surface->pixels + y*Surface->pitch, block, sizeof(Uint8)*Surface->w );
}
void sge_write_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y)
{
memcpy( (Uint16 *)Surface->pixels + y*Surface->pitch/2, block, sizeof(Uint16)*Surface->w );
}
void sge_write_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y)
{
memcpy( (Uint32 *)Surface->pixels + y*Surface->pitch/4, block, sizeof(Uint32)*Surface->w );
}
//==================================================================================
// ...and get
//==================================================================================
void sge_read_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y)
{
memcpy( block,(Uint8 *)Surface->pixels + y*Surface->pitch, sizeof(Uint8)*Surface->w );
}
void sge_read_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y)
{
memcpy( block,(Uint16 *)Surface->pixels + y*Surface->pitch/2, sizeof(Uint16)*Surface->w );
}
void sge_read_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y)
{
memcpy( block,(Uint32 *)Surface->pixels + y*Surface->pitch/4, sizeof(Uint32)*Surface->w );
}
/**********************************************************************************/
/** Blitting/surface functions **/
/**********************************************************************************/
//==================================================================================
// Clear surface to color
//==================================================================================
void sge_ClearSurface(SDL_Surface *Surface, Uint32 color)
{
SDL_FillRect(Surface,NULL, color);
if(_sge_update!=1){return;}
SDL_UpdateRect(Surface, 0,0,0,0);
}
//==================================================================================
// Clear surface to color (RGB)
//==================================================================================
void sge_ClearSurface(SDL_Surface *Surface, Uint8 R, Uint8 G, Uint8 B)
{
sge_ClearSurface(Surface,SDL_MapRGB(Surface->format, R, G, B));
}
//==================================================================================
// Blit from one surface to another
// Warning! Alpha and color key is lost (=0) on Src surface
//==================================================================================
int sge_BlitTransparent(SDL_Surface *Src, SDL_Surface *Dest, Sint16 SrcX, Sint16 SrcY, Sint16 DestX, Sint16 DestY, Sint16 W, Sint16 H, Uint32 Clear, Uint8 Alpha)
{
SDL_Rect src, dest;
int ret;
/* Dest clipping */
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
int flag=0;
if (DestX < Dest->clip_minx){
SrcX += Dest->clip_minx-DestX;
W -= Dest->clip_minx-DestX-1;
DestX=Dest->clip_minx;
}
if (DestY < Dest->clip_miny){
SrcY +=Dest->clip_miny-DestY;
H -= Dest->clip_miny-DestY-1;
DestY=Dest->clip_miny;
}
if ((DestX + W) > Dest->clip_maxx){
W = W - ((DestX + W) - Dest->clip_maxx)+1;
if(W<=0){SDL_SetError("SGE - Blit error");return -1;}
}
if ((DestY + H) > Dest->clip_maxy){
H = H - ((DestY + H) - Dest->clip_maxy)+1;
if(H<=0){SDL_SetError("SGE - Blit error");return -1;}
}
#endif
/* Initialize our rectangles */
src.x = SrcX;
src.y = SrcY;
src.w = W;
src.h = H;
dest.x = DestX;
dest.y = DestY;
dest.w = W;
dest.h = H;
/* We don't care about src clipping, only dest! */
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
if ( (Src->flags & SDL_SRCCLIPPING) == SDL_SRCCLIPPING){
Src->flags &= ~SDL_SRCCLIPPING; flag=1;
}
#endif
/* Set the color to be transparent */
SDL_SetColorKey(Src, SDL_SRCCOLORKEY, Clear);
/* Set the alpha value */
SDL_SetAlpha(Src, SDL_SRCALPHA, Alpha);
/* Blit */
ret=SDL_BlitSurface(Src, &src, Dest, &dest);
/* Set the correct flag */
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
if (flag==1){
Src->flags |= SDL_SRCCLIPPING;
}
#endif
/* Set normal levels */
SDL_SetAlpha(Src,0,0);
SDL_SetColorKey(Src,0,0);
return ret;
}
//==================================================================================
// Blit from one surface to another (not touching alpha or color key -
// use SDL_SetColorKey and SDL_SetAlpha)
//==================================================================================
int sge_Blit(SDL_Surface *Src, SDL_Surface *Dest, Sint16 SrcX, Sint16 SrcY, Sint16 DestX, Sint16 DestY, Sint16 W, Sint16 H)
{
SDL_Rect src, dest;
int ret;
/* Dest clipping */
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
int flag=0;
if (DestX < Dest->clip_minx){
SrcX += Dest->clip_minx-DestX;
W -= Dest->clip_minx-DestX -1;
DestX=Dest->clip_minx;
}
if (DestY < Dest->clip_miny){
SrcY +=Dest->clip_miny-DestY;
H -= Dest->clip_miny-DestY -1;
DestY=Dest->clip_miny;
}
if ((DestX + W) > Dest->clip_maxx){
W = W - ((DestX + W) - Dest->clip_maxx)+1;
if(W<=0){SDL_SetError("SGE - Blit error");return -1;}
}
if ((DestY + H) > Dest->clip_maxy){
H = H - ((DestY + H) - Dest->clip_maxy)+1;
if(H<=0){SDL_SetError("SGE - Blit error");return -1;}
}
#endif
/* Initialize our rectangles */
src.x = SrcX;
src.y = SrcY;
src.w = W;
src.h = H;
dest.x = DestX;
dest.y = DestY;
dest.w = W;
dest.h = H;
/* We don't care about src clipping, only dest! */
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
if ( (Src->flags & SDL_SRCCLIPPING) == SDL_SRCCLIPPING){
Src->flags &= ~SDL_SRCCLIPPING; flag=1;
}
#endif
/* Blit */
ret=SDL_BlitSurface(Src, &src, Dest, &dest);
/* Set the correct flag */
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
if (flag==1){
Src->flags |= SDL_SRCCLIPPING;
}
#endif
return ret;
}
//==================================================================================
// Copies a surface to a new...
//==================================================================================
SDL_Surface *sge_copy_surface(SDL_Surface *src)
{
return SDL_ConvertSurface(src, src->format,SDL_SWSURFACE);
}
/**********************************************************************************/
/** Palette functions **/
/**********************************************************************************/
//==================================================================================
// Fill in a palette entry with R, G, B componenets
//==================================================================================
SDL_Color sge_FillPaletteEntry(Uint8 R, Uint8 G, Uint8 B)
{
SDL_Color color;
color.r = R;
color.g = G;
color.b = B;
return color;
}
//==================================================================================
// Get the RGB of a color value
// Needed in those dark days before SDL 1.0
//==================================================================================
SDL_Color sge_GetRGB(SDL_Surface *Surface, Uint32 Color)
{
SDL_Color rgb;
SDL_GetRGB(Color, Surface->format, &(rgb.r), &(rgb.g), &(rgb.b));
return(rgb);
}
//==================================================================================
// Fades from (sR,sG,sB) to (dR,dG,dB), puts result in ctab[start] to ctab[stop]
//==================================================================================
void sge_Fader(SDL_Surface *Surface, Uint8 sR,Uint8 sG,Uint8 sB, Uint8 dR,Uint8 dG,Uint8 dB,Uint32 *ctab,int start, int stop)
{
// (sR,sG,sB) and (dR,dG,dB) are two points in space (the RGB cube).
/* The vector for the straight line */
int v[3];
v[0]=dR-sR; v[1]=dG-sG; v[2]=dB-sB;
/* Ref. point */
int x0=sR, y0=sG, z0=sB;
// The line's equation is:
// x= x0 + v[0] * t
// y= y0 + v[1] * t
// z= z0 + v[2] * t
//
// (x,y,z) will travel between the two points when t goes from 0 to 1.
int i=start;
double step=1.0/((stop+1)-start);
for(double t=0.0; t<=1.0 && i<=stop ; t+=step){
ctab[i++]=SDL_MapRGB(Surface->format, (Uint8)(x0+v[0]*t), (Uint8)(y0+v[1]*t), (Uint8)(z0+v[2]*t) );
}
}
//==================================================================================
// Fades from (sR,sG,sB,sA) to (dR,dG,dB,dA), puts result in ctab[start] to ctab[stop]
//==================================================================================
void sge_AlphaFader(Uint8 sR,Uint8 sG,Uint8 sB,Uint8 sA, Uint8 dR,Uint8 dG,Uint8 dB,Uint8 dA, Uint32 *ctab,int start, int stop)
{
// (sR,sG,sB,sA) and (dR,dG,dB,dA) are two points in hyperspace (the RGBA hypercube).
/* The vector for the straight line */
int v[4];
v[0]=dR-sR; v[1]=dG-sG; v[2]=dB-sB; v[3]=dA-sA;
/* Ref. point */
int x0=sR, y0=sG, z0=sB, w0=sA;
// The line's equation is:
// x= x0 + v[0] * t
// y= y0 + v[1] * t
// z= z0 + v[2] * t
// w= w0 + v[3] * t
//
// (x,y,z,w) will travel between the two points when t goes from 0 to 1.
int i=start;
double step=1.0/((stop+1)-start);
for(double t=0.0; t<=1.0 && i<=stop ; t+=step)
ctab[i++]=sge_MapAlpha((Uint8)(x0+v[0]*t), (Uint8)(y0+v[1]*t), (Uint8)(z0+v[2]*t), (Uint8)(w0+v[3]*t));
}
//==================================================================================
// Copies a nice rainbow palette to the color table (ctab[start] to ctab[stop]).
// You must also set the intensity of the palette (0-bright 255-dark)
//==================================================================================
void sge_SetupRainbowPalette(SDL_Surface *Surface,Uint32 *ctab,int intensity, int start, int stop)
{
int slice=(int)((stop-start)/6);
/* Red-Yellow */
sge_Fader(Surface, 255,intensity,intensity, 255,255,intensity, ctab, start,slice);
/* Yellow-Green */
sge_Fader(Surface, 255,255,intensity, intensity,255,intensity, ctab, slice+1, 2*slice);
/* Green-Turquoise blue */
sge_Fader(Surface, intensity,255,intensity, intensity,255,255, ctab, 2*slice+1, 3*slice);
/* Turquoise blue-Blue */
sge_Fader(Surface, intensity,255,255, intensity,intensity,255, ctab, 3*slice+1, 4*slice);
/* Blue-Purple */
sge_Fader(Surface, intensity,intensity,255, 255,intensity,255, ctab, 4*slice+1, 5*slice);
/* Purple-Red */
sge_Fader(Surface, 255,intensity,255, 255,intensity,intensity, ctab, 5*slice+1, stop);
}
//==================================================================================
// Copies a B&W palette to the color table (ctab[start] to ctab[stop]).
//==================================================================================
void sge_SetupBWPalette(SDL_Surface *Surface,Uint32 *ctab,int start, int stop)
{
sge_Fader(Surface, 0,0,0, 255,255,255, ctab,start,stop);
}
diff --git a/src/sge_surface.h b/src/sge_surface.h
index 4b5c9cd..36fee5e 100644
--- a/src/sge_surface.h
+++ b/src/sge_surface.h
@@ -1,97 +1,97 @@
/*
* SDL Graphics Extension
* Pixel, surface and color functions (header)
*
* Started 990815 (split from sge_draw 010611)
*
* License: LGPL v2+ (see the file LICENSE)
* (c)1999-2001 Anders Lindstr?m
*/
/*********************************************************************
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
*********************************************************************/
#ifndef sge_surface_H
#define sge_surface_H
-#include <SDL/SDL.h>
+#include "SDL.h"
#include "sge_internal.h"
/*
* Obsolete function names
*/
#define sge_copy_sblock8 sge_write_block8
#define sge_copy_sblock16 sge_write_block16
#define sge_copy_sblock32 sge_write_block32
#define sge_get_sblock8 sge_read_block8
#define sge_get_sblock16 sge_read_block16
#define sge_get_sblock32 sge_read_block32
#ifdef _SGE_C
extern "C" {
#endif
DECLSPEC void sge_Update_OFF(void);
DECLSPEC void sge_Update_ON(void);
DECLSPEC void sge_Lock_OFF(void);
DECLSPEC void sge_Lock_ON(void);
DECLSPEC Uint8 sge_getUpdate(void);
DECLSPEC Uint8 sge_getLock(void);
DECLSPEC void sge_UpdateRect(SDL_Surface *screen, Sint16 x, Sint16 y, Uint16 w, Uint16 h);
DECLSPEC SDL_Surface *sge_CreateAlphaSurface(Uint32 flags, int width, int height);
DECLSPEC Uint32 sge_MapAlpha(Uint8 R, Uint8 G, Uint8 B, Uint8 A);
DECLSPEC void sge_SetError(const char *format, ...);
DECLSPEC void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color);
DECLSPEC void _PutPixel8(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color);
DECLSPEC void _PutPixel16(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color);
DECLSPEC void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color);
DECLSPEC void _PutPixel32(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color);
DECLSPEC void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color);
DECLSPEC Sint32 sge_CalcYPitch(SDL_Surface *dest,Sint16 y);
DECLSPEC void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color);
DECLSPEC void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color);
DECLSPEC Uint32 sge_GetPixel(SDL_Surface *surface, Sint16 x, Sint16 y);
DECLSPEC void _PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha);
DECLSPEC void sge_PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha);
DECLSPEC void sge_write_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y);
DECLSPEC void sge_write_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y);
DECLSPEC void sge_write_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y);
DECLSPEC void sge_read_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y);
DECLSPEC void sge_read_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y);
DECLSPEC void sge_read_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y);
DECLSPEC void sge_ClearSurface(SDL_Surface *Surface, Uint32 color);
DECLSPEC int sge_BlitTransparent(SDL_Surface *Src, SDL_Surface *Dest, Sint16 SrcX, Sint16 SrcY, Sint16 DestX, Sint16 DestY, Sint16 W, Sint16 H, Uint32 Clear, Uint8 Alpha);
DECLSPEC int sge_Blit(SDL_Surface *Src, SDL_Surface *Dest, Sint16 SrcX, Sint16 SrcY, Sint16 DestX, Sint16 DestY, Sint16 W, Sint16 H);
DECLSPEC SDL_Surface *sge_copy_surface(SDL_Surface *src);
DECLSPEC SDL_Color sge_GetRGB(SDL_Surface *Surface, Uint32 Color);
DECLSPEC SDL_Color sge_FillPaletteEntry (Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void sge_Fader(SDL_Surface *Surface, Uint8 sR,Uint8 sG,Uint8 sB, Uint8 dR,Uint8 dG,Uint8 dB,Uint32 *ctab,int start, int stop);
DECLSPEC void sge_AlphaFader(Uint8 sR,Uint8 sG,Uint8 sB,Uint8 sA, Uint8 dR,Uint8 dG,Uint8 dB,Uint8 dA, Uint32 *ctab,int start, int stop);
DECLSPEC void sge_SetupRainbowPalette(SDL_Surface *Surface,Uint32 *ctab,int intensity, int start, int stop);
DECLSPEC void sge_SetupBWPalette(SDL_Surface *Surface,Uint32 *ctab,int start, int stop);
#ifdef _SGE_C
}
#endif
#ifndef sge_C_ONLY
DECLSPEC void _PutPixel(SDL_Surface *screen, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void sge_PutPixel(SDL_Surface *screen, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B);
DECLSPEC void _PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
DECLSPEC void sge_PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
DECLSPEC void sge_ClearSurface(SDL_Surface *Surface, Uint8 R, Uint8 G, Uint8 B);
#endif /* sge_C_ONLY */
#endif /* sge_surface_H */
diff --git a/src/sge_tt_text.cpp b/src/sge_tt_text.cpp
index 0b2ba5b..5ce1274 100644
--- a/src/sge_tt_text.cpp
+++ b/src/sge_tt_text.cpp
@@ -1,1469 +1,1469 @@
/*
* 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/SDL.h>
+#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 <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 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);
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);
/* 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;
}
//==================================================================================
// 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 b6d3150..94d7d0f 100644
--- a/src/sge_tt_text.h
+++ b/src/sge_tt_text.h
@@ -1,101 +1,101 @@
/*
* 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/SDL.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_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 */
#endif /* sge_tt_text_H */

File Metadata

Mime Type
text/x-diff
Expires
Wed, Feb 4, 2:16 PM (5 h, 15 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55658
Default Alt Text
(252 KB)

Event Timeline