diff options
-rw-r--r-- | .SRCINFO | 28 | ||||
-rw-r--r-- | CASE.COOP | bin | 0 -> 13440 bytes | |||
-rw-r--r-- | CAT.COOP | bin | 0 -> 13440 bytes | |||
-rw-r--r-- | CLAASSYM.DUEL | bin | 0 -> 13440 bytes | |||
-rw-r--r-- | PACMAN.DUEL | bin | 0 -> 13440 bytes | |||
-rw-r--r-- | PKGBUILD | 45 | ||||
-rw-r--r-- | ROOMS.COOP | bin | 0 -> 13440 bytes | |||
-rw-r--r-- | RUN.COOP | bin | 0 -> 13440 bytes | |||
-rw-r--r-- | SNERTGAME.DUEL | bin | 0 -> 13440 bytes | |||
-rw-r--r-- | TIME.COOP | bin | 0 -> 13440 bytes | |||
-rw-r--r-- | TOTALY_IMPOSSIBLE.COOP | bin | 0 -> 13440 bytes | |||
-rw-r--r-- | WEISSBIER.COOP | bin | 0 -> 13440 bytes | |||
-rw-r--r-- | njam-1.25-debian-src.patch | 2306 |
13 files changed, 2373 insertions, 6 deletions
@@ -1,7 +1,7 @@ pkgbase = njam pkgdesc = Full-featured cross-platform pacman-like game pkgver = 1.25 - pkgrel = 8 + pkgrel = 9 url = http://njam.sourceforge.net/ arch = i686 arch = x86_64 @@ -9,11 +9,33 @@ pkgbase = njam depends = sdl_image depends = sdl_mixer depends = sdl_net - source = http://downloads.sourceforge.net/njam/njam-1.25-src.tar.gz + source = http://deb.debian.org/debian/pool/main/n/njam/njam_1.25.orig.tar.gz source = njam.desktop + source = njam-1.25-debian-src.patch + source = CASE.COOP + source = CAT.COOP + source = CLAASSYM.DUEL + source = PACMAN.DUEL + source = ROOMS.COOP + source = RUN.COOP + source = SNERTGAME.DUEL + source = TIME.COOP + source = TOTALY_IMPOSSIBLE.COOP + source = WEISSBIER.COOP source = njam-1.25-gcc45-archlinux.patch - md5sums = b49f65a0c5df83de85df4f985337e2eb + md5sums = 231fda022d309e1ef4a0d993ca693462 md5sums = a2e8f7e419de1b864c31342003ebcd4d + md5sums = 615b4c5395d31ec09b2459843a3f1311 + md5sums = f4b8a42967b34ec920b87f8ee1e6790a + md5sums = 1bd67a5d315a4691220389f10fd90f27 + md5sums = 1b5bb57d1b39586a633c7dc932cb4795 + md5sums = 38b5ed7dc76bc36fd7c14ef5985e1e30 + md5sums = f2a91508a47c3d13f11deb3aab02ecdb + md5sums = 66225a96c323211e68c93dbe3f46fa18 + md5sums = 0fd169ed7d7a57c12f835249525898df + md5sums = 22418c9860f08e479238a8fa6aa59525 + md5sums = 1d1af2b2a1d0a2c0c7f840a697f26ebb + md5sums = 2fe5b30304cec91849bb8c784a41130a md5sums = 0add7095857fe517d35abdbd79e25259 pkgname = njam diff --git a/CASE.COOP b/CASE.COOP Binary files differnew file mode 100644 index 000000000000..76713c0a84af --- /dev/null +++ b/CASE.COOP diff --git a/CAT.COOP b/CAT.COOP Binary files differnew file mode 100644 index 000000000000..cdae932fc307 --- /dev/null +++ b/CAT.COOP diff --git a/CLAASSYM.DUEL b/CLAASSYM.DUEL Binary files differnew file mode 100644 index 000000000000..893868d76685 --- /dev/null +++ b/CLAASSYM.DUEL diff --git a/PACMAN.DUEL b/PACMAN.DUEL Binary files differnew file mode 100644 index 000000000000..3fc7c923cc53 --- /dev/null +++ b/PACMAN.DUEL @@ -3,17 +3,56 @@ pkgname=njam pkgver=1.25 -pkgrel=8 +pkgrel=9 pkgdesc="Full-featured cross-platform pacman-like game" arch=('i686' 'x86_64') url="http://njam.sourceforge.net/" license=('GPL') depends=('sdl_image' 'sdl_mixer' 'sdl_net') -source=(http://downloads.sourceforge.net/$pkgname/$pkgname-$pkgver-src.tar.gz njam.desktop njam-1.25-gcc45-archlinux.patch) -md5sums=('b49f65a0c5df83de85df4f985337e2eb' 'a2e8f7e419de1b864c31342003ebcd4d' '0add7095857fe517d35abdbd79e25259') +source=(http://deb.debian.org/debian/pool/main/n/$pkgname/${pkgname}_$pkgver.orig.tar.gz + njam.desktop + njam-1.25-debian-src.patch + CASE.COOP + CAT.COOP + CLAASSYM.DUEL + PACMAN.DUEL + ROOMS.COOP + RUN.COOP + SNERTGAME.DUEL + TIME.COOP + TOTALY_IMPOSSIBLE.COOP + WEISSBIER.COOP + njam-1.25-gcc45-archlinux.patch) +md5sums=('231fda022d309e1ef4a0d993ca693462' + 'a2e8f7e419de1b864c31342003ebcd4d' + '615b4c5395d31ec09b2459843a3f1311' + 'f4b8a42967b34ec920b87f8ee1e6790a' + '1bd67a5d315a4691220389f10fd90f27' + '1b5bb57d1b39586a633c7dc932cb4795' + '38b5ed7dc76bc36fd7c14ef5985e1e30' + 'f2a91508a47c3d13f11deb3aab02ecdb' + '66225a96c323211e68c93dbe3f46fa18' + '0fd169ed7d7a57c12f835249525898df' + '22418c9860f08e479238a8fa6aa59525' + '1d1af2b2a1d0a2c0c7f840a697f26ebb' + '2fe5b30304cec91849bb8c784a41130a' + '0add7095857fe517d35abdbd79e25259') prepare() { cd "$srcdir/$pkgname-$pkgver-src" + patch -p1 < "$srcdir/njam-1.25-debian-src.patch" + cp \ + "$srcdir/CASE.COOP" \ + "$srcdir/CAT.COOP" \ + "$srcdir/CLAASSYM.DUEL" \ + "$srcdir/PACMAN.DUEL" \ + "$srcdir/ROOMS.COOP" \ + "$srcdir/RUN.COOP" \ + "$srcdir/SNERTGAME.DUEL" \ + "$srcdir/TIME.COOP" \ + "$srcdir/TOTALY_IMPOSSIBLE.COOP" \ + "$srcdir/WEISSBIER.COOP" \ + "levels/" patch -p0 < "$srcdir/njam-1.25-gcc45-archlinux.patch" } diff --git a/ROOMS.COOP b/ROOMS.COOP Binary files differnew file mode 100644 index 000000000000..79e871a45373 --- /dev/null +++ b/ROOMS.COOP diff --git a/RUN.COOP b/RUN.COOP Binary files differnew file mode 100644 index 000000000000..e31e5f4c63a7 --- /dev/null +++ b/RUN.COOP diff --git a/SNERTGAME.DUEL b/SNERTGAME.DUEL Binary files differnew file mode 100644 index 000000000000..8b7071fd2bc1 --- /dev/null +++ b/SNERTGAME.DUEL diff --git a/TIME.COOP b/TIME.COOP Binary files differnew file mode 100644 index 000000000000..f72a186b75a1 --- /dev/null +++ b/TIME.COOP diff --git a/TOTALY_IMPOSSIBLE.COOP b/TOTALY_IMPOSSIBLE.COOP Binary files differnew file mode 100644 index 000000000000..77d86ec14f5f --- /dev/null +++ b/TOTALY_IMPOSSIBLE.COOP diff --git a/WEISSBIER.COOP b/WEISSBIER.COOP Binary files differnew file mode 100644 index 000000000000..35a1660c5f84 --- /dev/null +++ b/WEISSBIER.COOP diff --git a/njam-1.25-debian-src.patch b/njam-1.25-debian-src.patch new file mode 100644 index 000000000000..ac27fe346d05 --- /dev/null +++ b/njam-1.25-debian-src.patch @@ -0,0 +1,2306 @@ +Differences from Debian's njam_1.25.orig.tar.gz to the originally used njam-1.25-src.tar.gz + +The following differences have been removed from this patch: + +# diff --git a/MacOSX/.DS_Store b/MacOSX/.DS_Store +# deleted file mode 100644 +# index 5008ddf..0000000 +# Binary files a/MacOSX/.DS_Store and /dev/null differ +# +# diff --git a/MacOSX/English.lproj/.DS_Store b/MacOSX/English.lproj/.DS_Store +# deleted file mode 100644 +# index 5008ddf..0000000 +# Binary files a/MacOSX/English.lproj/.DS_Store and /dev/null differ +# +# diff --git a/contrib/njam.sh b/contrib/njam.sh +# old mode 100644 +# new mode 100755 +# +# diff --git a/levels/CASE.COOP b/levels/CASE.COOP +# new file mode 100644 +# index 0000000..76713c0 +# Binary files /dev/null and b/levels/CASE.COOP differ +# +# diff --git a/levels/CAT.COOP b/levels/CAT.COOP +# new file mode 100644 +# index 0000000..cdae932 +# Binary files /dev/null and b/levels/CAT.COOP differ +# +# diff --git a/levels/CLAASSYM.DUEL b/levels/CLAASSYM.DUEL +# new file mode 100644 +# index 0000000..893868d +# Binary files /dev/null and b/levels/CLAASSYM.DUEL differ +# +# diff --git a/levels/PACMAN.DUEL b/levels/PACMAN.DUEL +# new file mode 100644 +# index 0000000..3fc7c92 +# Binary files /dev/null and b/levels/PACMAN.DUEL differ +# +# diff --git a/levels/ROOMS.COOP b/levels/ROOMS.COOP +# new file mode 100644 +# index 0000000..79e871a +# Binary files /dev/null and b/levels/ROOMS.COOP differ +# +# diff --git a/levels/RUN.COOP b/levels/RUN.COOP +# new file mode 100644 +# index 0000000..e31e5f4 +# Binary files /dev/null and b/levels/RUN.COOP differ +# +# diff --git a/levels/SNERTGAME.DUEL b/levels/SNERTGAME.DUEL +# new file mode 100644 +# index 0000000..8b7071f +# Binary files /dev/null and b/levels/SNERTGAME.DUEL differ +# +# diff --git a/levels/TIME.COOP b/levels/TIME.COOP +# new file mode 100644 +# index 0000000..f72a186 +# Binary files /dev/null and b/levels/TIME.COOP differ +# +# diff --git a/levels/TOTALY_IMPOSSIBLE.COOP b/levels/TOTALY_IMPOSSIBLE.COOP +# new file mode 100644 +# index 0000000..77d86ec +# Binary files /dev/null and b/levels/TOTALY_IMPOSSIBLE.COOP differ +# +# diff --git a/levels/WEISSBIER.COOP b/levels/WEISSBIER.COOP +# new file mode 100644 +# index 0000000..35a1660 +# Binary files /dev/null and b/levels/WEISSBIER.COOP differ +# +# diff --git a/missing b/missing +# old mode 100644 +# new mode 100755 +# +# diff --git a/src/njam.o b/src/njam.o +# new file mode 100644 +# index 0000000..272501f +# Binary files /dev/null and b/src/njam.o differ +# +# diff --git a/src/njamedit.o b/src/njamedit.o +# new file mode 100644 +# index 0000000..73ff5dd +# Binary files /dev/null and b/src/njamedit.o differ +# +# diff --git a/src/njamfont.o b/src/njamfont.o +# new file mode 100644 +# index 0000000..3267281 +# Binary files /dev/null and b/src/njamfont.o differ +# +# diff --git a/src/njamgame.o b/src/njamgame.o +# new file mode 100644 +# index 0000000..11a4c80 +# Binary files /dev/null and b/src/njamgame.o differ +# +# diff --git a/src/njammap.o b/src/njammap.o +# new file mode 100644 +# index 0000000..b7b6a74 +# Binary files /dev/null and b/src/njammap.o differ +# +# diff --git a/src/njamnet.o b/src/njamnet.o +# new file mode 100644 +# index 0000000..0465d70 +# Binary files /dev/null and b/src/njamnet.o differ +# +# diff --git a/src/njamutils.o b/src/njamutils.o +# new file mode 100644 +# index 0000000..53c5654 +# Binary files /dev/null and b/src/njamutils.o differ + +diff --git a/html/doc-editor.html b/html/doc-editor.html +index 9f4b16b..e13565c 100644 +--- a/html/doc-editor.html ++++ b/html/doc-editor.html +@@ -30,7 +30,8 @@ documentation</font></big></big></b><br> + <td valign="top"><b><font face="Helvetica, Arial, sans-serif" + color="#ffffff"> Njam is a full-featured cross-platform pacman-like game + written in C++ using SDL library</font></b></td> +- <td valign="top" align="right"><small><a href="index.html"><b><small><font ++ <td valign="top" align="right"><small><a ++ href="http://njam.sourceforge.net/"><b><small><font + face="Helvetica, Arial, sans-serif" color="white">HOME >></font></small></b></a></small><br> + </td> + </tr> +diff --git a/levels/readme.txt b/levels/readme.txt +index 98b55fa..8e1c30f 100644 +--- a/levels/readme.txt ++++ b/levels/readme.txt +@@ -18,7 +18,6 @@ Maps Filename Difficulty Contributors + 8 ALLSFAIR.DUEL - Daniel Whigham + 4 BEAMTEAM.DUEL - M.Diener & B.Stryi (aka BeaM-Team) + 3 DULIO.DUEL - Dario Dulic +- + 10 LA_GINECAL.COOP medium Sean Austin + 13 KILLER.DUEL - Thomas Buch + 13 KILLER.COOP medium Thomas Buch +@@ -26,6 +25,14 @@ Maps Filename Difficulty Contributors + 20 BUCHI.COOP easy Thomas Buch + 11 BEAS.DUEL - Tischler Lukas + 9 STEPHANE.DUEL - Stéphane Galtier & Karoline ++ 20 CAT.COOP medium Kristin Langli ++ 20 CASE.COOP easy Kristin Langli ++ 17 RUN.COOP medium Kristin Langli ++ 20 ROOMS.COOP hard ? ++ 6 TIME.COOP hard Haaris Jamil ++ 13 SNERTGAME.DUEL - Laurens Vonder ++ 1 PACMAN.DUEL - Laurens Vonder ++ 6 CLAASSYM.DUEL - Claas Teichmann + + Original levels: + +@@ -40,4 +47,4 @@ Maps Filename Difficulty + "ghost hunt" level of original.duel set + great fun for 4 players + +-Total: 18 levelsets, 262 levels. ++Total: 22 levelsets, 339 levels. +diff --git a/src/njam.cpp b/src/njam.cpp +index 4faf77e..a6b7b18 100644 +--- a/src/njam.cpp ++++ b/src/njam.cpp +@@ -1,13 +1,13 @@ + //----------------------------------------------------------------------------- +-// Filename: njam.cpp +-// Created: 30. May 2003. by Milan Babuskov ++// Filename: njam.cpp ++// Created: 30. May 2003. by Milan Babuskov + // +-// Purpose: Initialization of the game +-// Managing resources +-// Handling Main Menu ++// Purpose: Initialization of the game ++// Managing resources ++// Handling Main Menu + // +-// The order of functions in this file is alphabetical +-// Except for main() and NjamEngine's ctor and destructor. ++// The order of functions in this file is alphabetical ++// Except for main() and NjamEngine's ctor and destructor. + // + // Tabs should be at 4 spaces. + // Each section is separated with line: //-------... +@@ -32,6 +32,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + -----------------------------------------------------------------------------*/ + // needed for chdir + #ifdef __linux__ ++/* this must be done before the first include of unistd.h for setresgid */ ++#define _GNU_SOURCE + #include <unistd.h> + #include <defaults.h> + #endif +@@ -47,285 +49,307 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + #include "njamfont.h" + #include "njammap.h" + #include "njam.h" ++ ++static FILE* highscore_fp; ++ + //----------------------------------------------------------------------------- + int main(int argc, char *argv[]) + { +- bool Fullscreen = true; +- bool SWSurface = true; +- bool UseDGA = false; +- if (argc > 1) +- { +- for (int i=1; i<argc; i++) +- { +- bool ok = true; +- if (argv[i][0] == '-') +- { +- if (argv[i][1] == 'w') +- Fullscreen = false; // use njam.exe -w windowed mode +- else if (argv[i][1] == 'h') +- SWSurface = false; // use -h for hardware surfaces +- else if (argv[i][1] == 'd') +- UseDGA = true; +- else +- ok = false; +- } +- else +- ok = false; +- +- if (!ok) +- { +- printf("Usage: njam -[w|d|h]\n\n"); +- printf("-w start in Windowed mode (as opposed to fullscreen).\n");; +- printf("-h use Hardware surfaces (faster, doesn't work well with all graphic cards).\n"); +- printf("-d use DGA driver on Linux, (much faster, but must run as root).\n"); +- return 1; +- } +- } +- } +- +- // cd to game directory ++ bool Fullscreen = true; ++ bool SWSurface = true; ++ bool UseDGA = false; + #ifdef __linux__ +-/* int i=0, l=0; +- while (argv[0][i]) +- { +- if (argv[0][i] == '/') +- l = i; +- i++; +- } +- +- if (l) +- { +- argv[0][l] = '\0'; +- chdir(argv[0]); +- argv[0][l] = '/'; +- }*/ +- char path[30]; +- sprintf(path, "%s/%s", DEFAULT_LIBDIR, PACKAGE); +- printf("%s",path); +- chdir(path); ++ gid_t realgid; ++ ++ highscore_fp = fopen("/var/lib/games/njam.hs", "r+"); ++ realgid = getgid(); ++ if (setresgid(-1, realgid, realgid) != 0) ++ { ++ perror("Could not drop setgid privileges. Aborting."); ++ return 1; ++ } + #endif + +- NjamEngine Engine; +- if (!Engine.Init(Fullscreen, SWSurface, UseDGA)) +- { +- LogFile("Failed.\n"); +- return 1; +- } ++ if (argc > 1) ++ { ++ for (int i=1; i<argc; i++) ++ { ++ bool ok = true; ++ if (argv[i][0] == '-') ++ { ++ if (argv[i][1] == 'w') ++ Fullscreen = false; // use njam.exe -w windowed mode ++ else if (argv[i][1] == 'h') ++ SWSurface = false; // use -h for hardware surfaces ++ else if (argv[i][1] == 'd') ++ UseDGA = true; ++ else ++ ok = false; ++ } ++ else ++ ok = false; ++ ++ if (!ok) ++ { ++ printf("Usage: njam -[w|d|h]\n\n"); ++ printf("-w start in Windowed mode (as opposed to fullscreen).\n");; ++ printf("-h use Hardware surfaces (faster, doesn't work well with all graphic cards).\n"); ++ printf("-d use DGA driver on Linux, (much faster, but must run as root).\n"); ++ return 1; ++ } ++ } ++ } + +- Engine.Start(); +- return 0; ++ // cd to game directory ++#ifdef __linux__ ++/* int i=0, l=0; ++ while (argv[0][i]) ++ { ++ if (argv[0][i] == '/') ++ l = i; ++ i++; ++ } ++ ++ if (l) ++ { ++ argv[0][l] = '\0'; ++ chdir(argv[0]); ++ argv[0][l] = '/'; ++ }*/ ++ char path[300]; // should be enough ++ sprintf(path, "%s/%s", DEFAULT_LIBDIR, PACKAGE); ++ printf("%s",path); ++ chdir(path); ++#endif ++ ++ NjamEngine Engine; ++ if (!Engine.Init(Fullscreen, SWSurface, UseDGA)) ++ { ++ LogFile("Failed.\n"); ++ return 1; ++ } ++ ++ try ++ { ++ Engine.Start(); ++ } ++ catch (...) ++ { ++ printf("Caught exception.\n"); ++ } ++ return 0; + } + //----------------------------------------------------------------------------- + NjamEngine::NjamEngine() + { +- m_LastHiscore = -1; +- +- m_Skins = NULL; +- m_ScriptDelay = -350; // when it's less than 100, the InfoWindow is empty +- script_file = NULL; +- m_ScriptFilePos = 0; +- m_ScriptLastPos = 0; +- m_ScrollOffset = 810; +- m_Screen = NULL; +- m_FontBlue = NULL; +- m_FontYellow = NULL; +- m_AudioAvailable = false; +- m_NetworkAvailable = false; +- m_ServerSocket = NULL; +- m_SDL = false; +- +- m_Icon = NULL; +- m_MainMenuImage = NULL; +- m_OptionsMenuImage = NULL; +- m_StatsImage = NULL; +- m_SpriteImage = NULL; +- m_HiScoresImage = NULL; +- m_LevelsetImage = NULL; +- m_NetSendImage = NULL; +- m_NetEnterImage = NULL; +- m_NetLobbyImage = NULL; +- m_GameOverImage = NULL; ++ m_LastHiscore = -1; ++ ++ m_Skins = NULL; ++ m_ScriptDelay = -350; // when it's less than 100, the InfoWindow is empty ++ script_file = NULL; ++ m_ScriptFilePos = 0; ++ m_ScriptLastPos = 0; ++ m_ScrollOffset = 810; ++ m_Screen = NULL; ++ m_FontBlue = NULL; ++ m_FontYellow = NULL; ++ m_AudioAvailable = false; ++ m_NetworkAvailable = false; ++ m_ServerSocket = NULL; ++ m_SDL = false; ++ ++ m_Icon = NULL; ++ m_MainMenuImage = NULL; ++ m_OptionsMenuImage = NULL; ++ m_StatsImage = NULL; ++ m_SpriteImage = NULL; ++ m_HiScoresImage = NULL; ++ m_LevelsetImage = NULL; ++ m_NetSendImage = NULL; ++ m_NetEnterImage = NULL; ++ m_NetLobbyImage = NULL; ++ m_GameOverImage = NULL; + + m_MainMenuMusic = NULL; + m_GameMusic1 = NULL; + m_GameMusic2 = NULL; + +- // default values for game options (Init() overrides if njam.conf file exists) +- m_GameOptions.PlayMusic = true; +- m_GameOptions.PlaySound = true; +- m_GameOptions.UsedSkin = 0; +- m_GameOptions.ServerIP[0] = 0; ++ // default values for game options (Init() overrides if njam.conf file exists) ++ m_GameOptions.PlayMusic = true; ++ m_GameOptions.PlaySound = true; ++ m_GameOptions.UsedSkin = 0; ++ m_GameOptions.ServerIP[0] = 0; + } + //----------------------------------------------------------------------------- + NjamEngine::~NjamEngine() + { + #ifdef __linux__ +- char bufsdl[30]; +- sprintf(bufsdl, "SDL_VIDEODRIVER=%s", linux_sdl_driver); +- putenv(bufsdl); ++ char bufsdl[30]; ++ sprintf(bufsdl, "SDL_VIDEODRIVER=%s", linux_sdl_driver); ++ putenv(bufsdl); + #endif + +- if (script_file) +- fclose(script_file); +- +- if (m_Skins) +- { +- for (int i=0; i<m_NumberOfSkins; i++) +- SDL_FreeSurface(m_Skins[i]); +- delete[] m_Skins; +- } +- +- if (m_Icon) +- SDL_FreeSurface(m_Icon); +- if (m_MainMenuImage) +- SDL_FreeSurface(m_MainMenuImage); +- if (m_OptionsMenuImage) +- SDL_FreeSurface(m_OptionsMenuImage); +- if (m_GameOverImage) +- SDL_FreeSurface(m_GameOverImage); +- if (m_StatsImage) +- SDL_FreeSurface(m_StatsImage); +- if (m_SpriteImage) +- SDL_FreeSurface(m_SpriteImage); +- if (m_HiScoresImage) +- SDL_FreeSurface(m_HiScoresImage); +- if (m_LevelsetImage) +- SDL_FreeSurface(m_LevelsetImage); +- if (m_NetSendImage) +- SDL_FreeSurface(m_NetSendImage); +- if (m_NetEnterImage) +- SDL_FreeSurface(m_NetEnterImage); +- if (m_NetLobbyImage) +- SDL_FreeSurface(m_NetLobbyImage); +- +- if (m_FontBlue) +- delete m_FontBlue; +- if (m_FontYellow) +- delete m_FontYellow; +- +- for (int i=0; i<17; i++) +- if (m_Sounds[i]) +- Mix_FreeChunk(m_Sounds[i]); +- +- if (m_MainMenuMusic) +- Mix_FreeMusic(m_MainMenuMusic); +- if (m_GameMusic1) +- Mix_FreeMusic(m_GameMusic1); +- if (m_GameMusic2) +- Mix_FreeMusic(m_GameMusic2); +- +- if (m_AudioAvailable) +- Mix_CloseAudio(); +- +- if (m_NetworkAvailable) +- SDLNet_Quit(); +- +- // write configuration options ++ if (script_file) ++ fclose(script_file); ++ ++ if (m_Skins) ++ { ++ for (int i=0; i<m_NumberOfSkins; i++) ++ SDL_FreeSurface(m_Skins[i]); ++ delete[] m_Skins; ++ } ++ ++ if (m_Icon) ++ SDL_FreeSurface(m_Icon); ++ if (m_MainMenuImage) ++ SDL_FreeSurface(m_MainMenuImage); ++ if (m_OptionsMenuImage) ++ SDL_FreeSurface(m_OptionsMenuImage); ++ if (m_GameOverImage) ++ SDL_FreeSurface(m_GameOverImage); ++ if (m_StatsImage) ++ SDL_FreeSurface(m_StatsImage); ++ if (m_SpriteImage) ++ SDL_FreeSurface(m_SpriteImage); ++ if (m_HiScoresImage) ++ SDL_FreeSurface(m_HiScoresImage); ++ if (m_LevelsetImage) ++ SDL_FreeSurface(m_LevelsetImage); ++ if (m_NetSendImage) ++ SDL_FreeSurface(m_NetSendImage); ++ if (m_NetEnterImage) ++ SDL_FreeSurface(m_NetEnterImage); ++ if (m_NetLobbyImage) ++ SDL_FreeSurface(m_NetLobbyImage); ++ ++ if (m_FontBlue) ++ delete m_FontBlue; ++ if (m_FontYellow) ++ delete m_FontYellow; ++ ++ for (int i=0; i<17; i++) ++ if (m_Sounds[i]) ++ Mix_FreeChunk(m_Sounds[i]); ++ ++ if (m_MainMenuMusic) ++ Mix_FreeMusic(m_MainMenuMusic); ++ if (m_GameMusic1) ++ Mix_FreeMusic(m_GameMusic1); ++ if (m_GameMusic2) ++ Mix_FreeMusic(m_GameMusic2); ++ ++ if (m_AudioAvailable) ++ Mix_CloseAudio(); ++ ++ if (m_NetworkAvailable) ++ SDLNet_Quit(); ++ ++ // write configuration options + LogFile("Opening njam.conf file.\n"); + char *home = getenv("HOME"); + std::string njamconf("njam.conf"); + if (home) + njamconf = std::string(home) + "/.njamconf"; +- FILE *fp = fopen(njamconf.c_str(), "w+"); +- if (fp) +- { +- fprintf(fp, "M=%d\n", (m_GameOptions.PlayMusic ? 1 : 0)); +- fprintf(fp, "S=%d\n", (m_GameOptions.PlaySound ? 1 : 0)); +- fprintf(fp, "U=%d\n", m_GameOptions.UsedSkin); +- fprintf(fp, "I=%s\n", m_GameOptions.ServerIP); +- fclose(fp); +- } +- +- // format: NAME#POINTS#LEVEL# +- fp = fopen("hiscore.dat", "w+"); +- if (fp) +- { +- for (int i=0; i<10; i++) +- fprintf(fp, "%s#%d#%d#\n", TopTenScores[i].name, TopTenScores[i].points, TopTenScores[i].level); +- fclose(fp); +- } +- +- if (m_SDL) +- SDL_Quit(); ++ FILE *fp = fopen(njamconf.c_str(), "w+"); ++ if (fp) ++ { ++ fprintf(fp, "M=%d\n", (m_GameOptions.PlayMusic ? 1 : 0)); ++ fprintf(fp, "S=%d\n", (m_GameOptions.PlaySound ? 1 : 0)); ++ fprintf(fp, "U=%d\n", m_GameOptions.UsedSkin); ++ fprintf(fp, "I=%s\n", m_GameOptions.ServerIP); ++ fclose(fp); ++ } ++ ++ // format: NAME#POINTS#LEVEL# ++ if (highscore_fp) ++ { ++ rewind(highscore_fp); ++ for (int i=0; i<10; i++) ++ fprintf(highscore_fp, "%s#%d#%d#\n", TopTenScores[i].name, TopTenScores[i].points, TopTenScores[i].level); ++ fclose(highscore_fp); ++ } ++ ++ if (m_SDL) ++ SDL_Quit(); + } + //--------------------------------------------------------------------------- +-void NjamEngine::DoScript(void) // loads script.txt file, and show data on main-menu screen ++void NjamEngine::DoScript(void) // loads script.txt file, and show data on main-menu screen + { +- if (m_ScriptDelay < -100) // initial delay, so screen isn't too full when the game is loaded +- { +- m_ScriptDelay++; +- return; +- } +- +- m_ScriptDelay--; +- if (m_ScriptDelay <= 0) // change the script +- { +- m_ScriptDelay = 400; // delay change for 400 cycles +- m_ScriptFilePos = m_ScriptLastPos; +- } +- +- if (script_file == NULL) +- script_file = fopen("data/script.txt", "rb"); +- if (script_file == NULL) +- return; ++ if (m_ScriptDelay < -100) // initial delay, so screen isn't too full when the game is loaded ++ { ++ m_ScriptDelay++; ++ return; ++ } ++ ++ m_ScriptDelay--; ++ if (m_ScriptDelay <= 0) // change the script ++ { ++ m_ScriptDelay = 400; // delay change for 400 cycles ++ m_ScriptFilePos = m_ScriptLastPos; ++ } ++ ++ if (script_file == NULL) ++ script_file = fopen("data/script.txt", "rb"); ++ if (script_file == NULL) ++ return; + + fseek(script_file, m_ScriptFilePos, SEEK_SET); + + char buffer[80]; +- for (int i=0; i<80; i++) // empty buffer +- buffer[i] = 0; ++ for (int i=0; i<80; i++) // empty buffer ++ buffer[i] = 0; + +- // first line of text +- int Row = 175 / m_FontBlue->GetCharHeight(); +- int Column = 440 / m_FontBlue->GetCharWidth(); ++ // first line of text ++ int Row = 175 / m_FontBlue->GetCharHeight(); ++ int Column = 440 / m_FontBlue->GetCharWidth(); + + while (true) + { + fgets(buffer, 79, script_file); + if (feof(script_file)) +- { +- printf("njam.cpp: ERROR: Script.txt not terminated with -- line."); +- m_ScriptLastPos = 0; +- break; +- } +- +- if (buffer[0] == '-' && buffer[1] == '-') // -- end of script +- { ++ { ++ printf("njam.cpp: ERROR: Script.txt not terminated with -- line."); ++ m_ScriptLastPos = 0; ++ break; ++ } ++ ++ if (buffer[0] == '-' && buffer[1] == '-') // -- end of script ++ { + m_ScriptLastPos = 0; +- break; +- } ++ break; ++ } + +- if (buffer[0] == '-') // end of part +- { +- m_ScriptLastPos = ftell(script_file); +- break; +- } ++ if (buffer[0] == '-') // end of part ++ { ++ m_ScriptLastPos = ftell(script_file); ++ break; ++ } + +- if (buffer[0] == '<') // image ++ if (buffer[0] == '<') // image + { +- int i = (int)(buffer[2] - '0'); // image index ++ int i = (int)(buffer[2] - '0'); // image index + +- if (buffer[1] == 'G') // image of a ghost ++ if (buffer[1] == 'G') // image of a ghost + { +- SDL_Rect src, dest; ++ SDL_Rect src, dest; + NjamSetRect(dest, 440, 120); + NjamSetRect(src, i*25, 0, 25, 25); + SDL_BlitSurface(m_SpriteImage, &src, m_Screen, &dest); + } +- else // image of a map-data ++ else // image of a map-data + { + i+=2; + + for (int j=0; j<m_NumberOfSkins; j++) + { +- SDL_Rect src, dest; +- NjamSetRect(dest, 440 + j*30, 120); +- NjamSetRect(src, i*25, 0, 25, 25); +- SDL_BlitSurface(m_Skins[j], &src, m_Screen, &dest); ++ SDL_Rect src, dest; ++ NjamSetRect(dest, 440 + j*30, 120); ++ NjamSetRect(src, i*25, 0, 25, 25); ++ SDL_BlitSurface(m_Skins[j], &src, m_Screen, &dest); + } + } + } +- else // text ++ else // text + { + m_FontBlue->WriteTextColRow(m_Screen, Column, Row, buffer); + Row++; +@@ -336,415 +360,420 @@ void NjamEngine::DoScript(void) // loads script.txt file, and show data on main + bool NjamEngine::Init(bool Fullscreen, bool SoftwareSurface, bool UseDGA) + { + #ifdef __linux__ +- sprintf(linux_sdl_driver, "x11\0"); +- char *driver_name = getenv("SDL_VIDEODRIVER"); +- if (driver_name) +- sprintf(linux_sdl_driver, "%s\0", driver_name); +- +- if (UseDGA) +- { +- printf("You must be root to run DGA\nType ./njam -? for help\n"); +- putenv("SDL_VIDEODRIVER=dga"); +- } ++ // Check if $HOME/.njam-levels exists and if it doesn't create it ++ char buf[512]; ++ char *home = NjamGetHomeDir(); ++ snprintf(buf, sizeof(buf), "%s/.njam-levels", home? home:""); ++ NjamCheckAndCreateDir(buf); ++ ++ sprintf(linux_sdl_driver, "x11\0"); ++ char *driver_name = getenv("SDL_VIDEODRIVER"); ++ if (driver_name) ++ sprintf(linux_sdl_driver, "%s\0", driver_name); ++ ++ if (UseDGA) ++ { ++ printf("You must be root to run DGA\nType ./njam -? for help\n"); ++ putenv("SDL_VIDEODRIVER=dga"); ++ } + #else +- if (UseDGA) +- printf("Parameter -d is ignored for non-Linux platforms.\n"); ++ if (UseDGA) ++ printf("Parameter -d is ignored for non-Linux platforms.\n"); + #endif + +- LogFile("Initializing SDL: VIDEO & AUDIO...", true); +- if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_TIMER ) < 0 ) +- { +- fprintf(stderr, "Error initializing SDL: %s\n", SDL_GetError()); +- return false; +- } +- else ++ LogFile("Initializing SDL: VIDEO & AUDIO...", true); ++ if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_TIMER ) < 0 ) ++ { ++ fprintf(stderr, "Error initializing SDL: %s\n", SDL_GetError()); ++ return false; ++ } ++ else + m_SDL = true; + +- LogFile("OK.\nSetting window title..."); +- SDL_WM_SetCaption("Njam http://njam.sourceforge.net", NULL); +- +- // load .bmp for icon +- LogFile("done.\nLoading icon..."); +- m_Icon = SDL_LoadBMP("data/njamicon.bmp"); +- if (!m_Icon) +- { +- LogFile("FAILED.\n"); +- LogFile((const char *)SDL_GetError()); +- return false; +- } +- LogFile("OK.\n"); +- SDL_WM_SetIcon(m_Icon, NULL); +- +- LogFile("Setting video mode: 800x600x16..."); +- Uint32 flags = SDL_ANYFORMAT; +- +- if (Fullscreen) +- flags |= SDL_FULLSCREEN; +- +- if (SoftwareSurface) +- flags |= SDL_SWSURFACE; +- else +- flags |= SDL_HWSURFACE|SDL_DOUBLEBUF; +- +- m_Screen = SDL_SetVideoMode(800, 600, 16, flags); ++ LogFile("OK.\nSetting window title..."); ++ SDL_WM_SetCaption("Njam http://njam.sourceforge.net", NULL); ++ ++ // load .bmp for icon ++ LogFile("done.\nLoading icon..."); ++ m_Icon = SDL_LoadBMP("data/njamicon.bmp"); ++ if (!m_Icon) ++ { ++ LogFile("FAILED.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return false; ++ } ++ LogFile("OK.\n"); ++ SDL_WM_SetIcon(m_Icon, NULL); ++ ++ LogFile("Setting video mode: 800x600x16..."); ++ Uint32 flags = SDL_ANYFORMAT; ++ ++ if (Fullscreen) ++ flags |= SDL_FULLSCREEN; ++ ++ if (SoftwareSurface) ++ flags |= SDL_SWSURFACE; ++ else ++ flags |= SDL_HWSURFACE|SDL_DOUBLEBUF; ++ ++ m_Screen = SDL_SetVideoMode(800, 600, 16, flags); + if ( m_Screen == NULL ) +- { ++ { + fprintf(stderr, "Couldn't set 800x600x16 video mode: %s\n", SDL_GetError()); + return false; + } +- else +- LogFile("OK\n"); +- +- // hide mouse cursor in fullscreen +- if (Fullscreen) +- SDL_ShowCursor(SDL_DISABLE); +- +- // check & output capabilites: +- const SDL_VideoInfo *info = SDL_GetVideoInfo(); +- printf("VIDEO INFORMATION:\n"); +- printf(" hw_available = %d\n", info->hw_available); +- printf(" wm_available = %d\n", info->wm_available); +- printf(" blit_hw = %d\n", info->blit_hw); +- printf(" blit_hw_CC = %d\n", info->blit_hw_CC); +- printf(" blit_hw_A = %d\n", info->blit_hw_A); +- printf(" blit_sw = %d\n", info->blit_sw); +- printf(" blit_sw_CC = %d\n", info->blit_sw_CC); +- printf(" blit_sw_A = %d\n", info->blit_sw_A); +- printf("END VIDEO INFORMATION.\n"); +- +- // Loading various resources... +- LogFile("Loading resources:\n"); +- +- // load .bmp for main menu +- SDL_Surface *temp; +- LogFile("Loading Main Menu image..."); +- temp = IMG_Load("data/mainmenu.jpg"); +- if (!temp) +- { +- LogFile("FAILED.\n"); +- LogFile((const char *)SDL_GetError()); +- return false; +- } +- LogFile("OK.\n"); +- +- // Convert image to video format +- m_MainMenuImage = SDL_DisplayFormat(temp); +- SDL_FreeSurface(temp); +- if ( m_MainMenuImage == NULL ) +- { +- fprintf(stderr, "Couldn't convert main menu image: %s\n", SDL_GetError()); +- return false; +- } +- +- // load .bmp for options menu +- LogFile("Loading Options Menu image..."); +- temp = IMG_Load("data/options.jpg"); +- if (!temp) +- { +- LogFile("FAILED.\n"); +- LogFile((const char *)SDL_GetError()); +- return false; +- } +- LogFile("OK.\n"); +- +- // Convert image to video format +- m_OptionsMenuImage = SDL_DisplayFormat(temp); +- SDL_FreeSurface(temp); +- if ( m_OptionsMenuImage == NULL ) +- { +- fprintf(stderr, "Couldn't convert options menu image: %s\n", SDL_GetError()); +- return false; +- } +- +- // load .bmp for network-send screen +- LogFile("Loading Net-send image..."); +- m_NetSendImage = IMG_Load("data/netsend.jpg"); +- if (!m_NetSendImage) +- { +- LogFile("FAILED.\n"); +- LogFile((const char *)SDL_GetError()); +- return false; +- } +- LogFile("OK.\n"); +- +- LogFile("Loading Hi-score image..."); +- m_HiScoresImage = IMG_Load("data/hiscore.jpg"); +- if (!m_HiScoresImage) +- { +- LogFile("FAILED.\n"); +- LogFile((const char *)SDL_GetError()); +- return false; +- } +- LogFile("OK.\n"); +- +- LogFile("Loading levelset entry image..."); +- m_LevelsetImage = IMG_Load("data/levelset.jpg"); +- if (!m_LevelsetImage) +- { +- LogFile("FAILED.\n"); +- LogFile((const char *)SDL_GetError()); +- return false; +- } +- LogFile("OK.\n"); +- +- LogFile("Loading Gameover image..."); +- m_GameOverImage = IMG_Load("data/gameover.jpg"); +- if (!m_GameOverImage) +- { +- LogFile("FAILED.\n"); +- LogFile((const char *)SDL_GetError()); +- return false; +- } +- LogFile("OK.\n"); +- +- // load .bmp for network-send screen +- LogFile("Loading Net-lobby image..."); +- m_NetLobbyImage = SDL_LoadBMP("data/network.bmp"); +- if (!m_NetLobbyImage) +- { +- LogFile("FAILED.\n"); +- LogFile((const char *)SDL_GetError()); +- return false; +- } +- LogFile("OK.\n"); +- +- // load .bmp for enter server IP screen +- LogFile("Loading enter server IP image..."); +- m_NetEnterImage = IMG_Load("data/enter-ip.jpg"); +- if (!m_NetEnterImage) +- { +- LogFile("FAILED.\n"); +- LogFile((const char *)SDL_GetError()); +- return false; +- } +- LogFile("OK.\n"); +- +- // load .bmp for stats screen +- LogFile("Loading Stats screen image..."); +- temp = IMG_Load("data/stats.jpg"); +- if (!temp) +- { +- LogFile("FAILED.\n"); +- LogFile((const char *)SDL_GetError()); +- return false; +- } +- LogFile("OK.\n"); +- +- // Convert image to video format +- m_StatsImage = SDL_DisplayFormat(temp); +- SDL_FreeSurface(temp); +- if ( m_StatsImage == NULL ) +- { +- fprintf(stderr, "Couldn't convert stats screen image: %s\n", SDL_GetError()); +- return false; +- } +- +- // load .bmp for sprites and menu selector +- LogFile("Loading Sprites image..."); +- temp = SDL_LoadBMP("data/sprites.bmp"); +- if (!temp) +- { +- LogFile("FAILED.\n"); +- LogFile((const char *)SDL_GetError()); +- return false; +- } +- +- // setting color key for sprites: black is transparent +- Uint32 black = SDL_MapRGB(temp->format, 0, 0, 0); +- SDL_SetColorKey(temp, SDL_SRCCOLORKEY, black); +- LogFile("OK.\n"); +- +- // Convert image to video format +- m_SpriteImage = SDL_DisplayFormat(temp); +- SDL_FreeSurface(temp); +- if ( m_SpriteImage == NULL ) +- { +- fprintf(stderr, "Couldn't convert sprite image: %s\n", SDL_GetError()); +- return false; +- } +- +- // loading skins, first check how many is there +- char Filename[18]; +- m_NumberOfSkins = 0; +- while (true) +- { +- sprintf(Filename, "skins/Back%03d.bmp\0", m_NumberOfSkins); +- FILE *fp = fopen(Filename, "r"); +- if (!fp) +- break; +- +- fclose(fp); ++ else ++ LogFile("OK\n"); ++ ++ // hide mouse cursor in fullscreen ++ if (Fullscreen) ++ SDL_ShowCursor(SDL_DISABLE); ++ ++ // check & output capabilites: ++ const SDL_VideoInfo *info = SDL_GetVideoInfo(); ++ printf("VIDEO INFORMATION:\n"); ++ printf(" hw_available = %d\n", info->hw_available); ++ printf(" wm_available = %d\n", info->wm_available); ++ printf(" blit_hw = %d\n", info->blit_hw); ++ printf(" blit_hw_CC = %d\n", info->blit_hw_CC); ++ printf(" blit_hw_A = %d\n", info->blit_hw_A); ++ printf(" blit_sw = %d\n", info->blit_sw); ++ printf(" blit_sw_CC = %d\n", info->blit_sw_CC); ++ printf(" blit_sw_A = %d\n", info->blit_sw_A); ++ printf("END VIDEO INFORMATION.\n"); ++ ++ // Loading various resources... ++ LogFile("Loading resources:\n"); ++ ++ // load .bmp for main menu ++ SDL_Surface *temp; ++ LogFile("Loading Main Menu image..."); ++ temp = IMG_Load("data/mainmenu.jpg"); ++ if (!temp) ++ { ++ LogFile("FAILED.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return false; ++ } ++ LogFile("OK.\n"); ++ ++ // Convert image to video format ++ m_MainMenuImage = SDL_DisplayFormat(temp); ++ SDL_FreeSurface(temp); ++ if ( m_MainMenuImage == NULL ) ++ { ++ fprintf(stderr, "Couldn't convert main menu image: %s\n", SDL_GetError()); ++ return false; ++ } ++ ++ // load .bmp for options menu ++ LogFile("Loading Options Menu image..."); ++ temp = IMG_Load("data/options.jpg"); ++ if (!temp) ++ { ++ LogFile("FAILED.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return false; ++ } ++ LogFile("OK.\n"); ++ ++ // Convert image to video format ++ m_OptionsMenuImage = SDL_DisplayFormat(temp); ++ SDL_FreeSurface(temp); ++ if ( m_OptionsMenuImage == NULL ) ++ { ++ fprintf(stderr, "Couldn't convert options menu image: %s\n", SDL_GetError()); ++ return false; ++ } ++ ++ // load .bmp for network-send screen ++ LogFile("Loading Net-send image..."); ++ m_NetSendImage = IMG_Load("data/netsend.jpg"); ++ if (!m_NetSendImage) ++ { ++ LogFile("FAILED.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return false; ++ } ++ LogFile("OK.\n"); ++ ++ LogFile("Loading Hi-score image..."); ++ m_HiScoresImage = IMG_Load("data/hiscore.jpg"); ++ if (!m_HiScoresImage) ++ { ++ LogFile("FAILED.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return false; ++ } ++ LogFile("OK.\n"); ++ ++ LogFile("Loading levelset entry image..."); ++ m_LevelsetImage = IMG_Load("data/levelset.jpg"); ++ if (!m_LevelsetImage) ++ { ++ LogFile("FAILED.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return false; ++ } ++ LogFile("OK.\n"); ++ ++ LogFile("Loading Gameover image..."); ++ m_GameOverImage = IMG_Load("data/gameover.jpg"); ++ if (!m_GameOverImage) ++ { ++ LogFile("FAILED.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return false; ++ } ++ LogFile("OK.\n"); ++ ++ // load .bmp for network-send screen ++ LogFile("Loading Net-lobby image..."); ++ m_NetLobbyImage = SDL_LoadBMP("data/network.bmp"); ++ if (!m_NetLobbyImage) ++ { ++ LogFile("FAILED.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return false; ++ } ++ LogFile("OK.\n"); ++ ++ // load .bmp for enter server IP screen ++ LogFile("Loading enter server IP image..."); ++ m_NetEnterImage = IMG_Load("data/enter-ip.jpg"); ++ if (!m_NetEnterImage) ++ { ++ LogFile("FAILED.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return false; ++ } ++ LogFile("OK.\n"); ++ ++ // load .bmp for stats screen ++ LogFile("Loading Stats screen image..."); ++ temp = IMG_Load("data/stats.jpg"); ++ if (!temp) ++ { ++ LogFile("FAILED.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return false; ++ } ++ LogFile("OK.\n"); ++ ++ // Convert image to video format ++ m_StatsImage = SDL_DisplayFormat(temp); ++ SDL_FreeSurface(temp); ++ if ( m_StatsImage == NULL ) ++ { ++ fprintf(stderr, "Couldn't convert stats screen image: %s\n", SDL_GetError()); ++ return false; ++ } ++ ++ // load .bmp for sprites and menu selector ++ LogFile("Loading Sprites image..."); ++ temp = SDL_LoadBMP("data/sprites.bmp"); ++ if (!temp) ++ { ++ LogFile("FAILED.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return false; ++ } ++ ++ // setting color key for sprites: black is transparent ++ Uint32 black = SDL_MapRGB(temp->format, 0, 0, 0); ++ SDL_SetColorKey(temp, SDL_SRCCOLORKEY, black); ++ LogFile("OK.\n"); ++ ++ // Convert image to video format ++ m_SpriteImage = SDL_DisplayFormat(temp); ++ SDL_FreeSurface(temp); ++ if ( m_SpriteImage == NULL ) ++ { ++ fprintf(stderr, "Couldn't convert sprite image: %s\n", SDL_GetError()); ++ return false; ++ } ++ ++ // loading skins, first check how many is there ++ char Filename[18]; ++ m_NumberOfSkins = 0; ++ while (true) ++ { ++ sprintf(Filename, "skins/Back%03d.bmp\0", m_NumberOfSkins); ++ FILE *fp = fopen(Filename, "r"); ++ if (!fp) ++ break; ++ ++ fclose(fp); + m_NumberOfSkins++; +- } +- +- LogFile("Loading skins:\n"); +- if (m_NumberOfSkins > 0) // alloc memory for pointers +- m_Skins = new SDL_Surface *[m_NumberOfSkins]; +- +- for (int i=0; i<m_NumberOfSkins; i++) +- { +- sprintf(Filename, "skins/Back%03d.bmp\0", i); +- LogFile((const char*)Filename); +- temp = SDL_LoadBMP(Filename); +- if (!temp) +- { +- LogFile("...FAILED.\n"); +- LogFile((const char *)SDL_GetError()); +- return false; +- } +- +- m_Skins[i] = SDL_DisplayFormat(temp); +- SDL_FreeSurface(temp); +- if ( m_Skins[i] == NULL ) +- { +- fprintf(stderr, "Couldn't convert skin image: %s\n", SDL_GetError()); +- return false; +- } +- +- LogFile("...OK.\n"); +- } +- +- LogFile("Loading Fonts:\n"); +- m_FontBlue = new NjamFont("data/font-blue.bmp", 6, 9); +- m_FontYellow = new NjamFont("data/font-yellow.bmp", 10, 15); +- +- // Load user settings from .conf file ++ } ++ ++ LogFile("Loading skins:\n"); ++ if (m_NumberOfSkins > 0) // alloc memory for pointers ++ m_Skins = new SDL_Surface *[m_NumberOfSkins]; ++ ++ for (int i=0; i<m_NumberOfSkins; i++) ++ { ++ sprintf(Filename, "skins/Back%03d.bmp\0", i); ++ LogFile((const char*)Filename); ++ temp = SDL_LoadBMP(Filename); ++ if (!temp) ++ { ++ LogFile("...FAILED.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return false; ++ } ++ ++ m_Skins[i] = SDL_DisplayFormat(temp); ++ SDL_FreeSurface(temp); ++ if ( m_Skins[i] == NULL ) ++ { ++ fprintf(stderr, "Couldn't convert skin image: %s\n", SDL_GetError()); ++ return false; ++ } ++ ++ LogFile("...OK.\n"); ++ } ++ ++ LogFile("Loading Fonts:\n"); ++ m_FontBlue = new NjamFont("data/font-blue.bmp", 6, 9); ++ m_FontYellow = new NjamFont("data/font-yellow.bmp", 10, 15); ++ ++ // Load user settings from .conf file + LogFile("Opening njam.conf file.\n"); ++#ifndef __linux__ + char *home = getenv("HOME"); ++#endif + std::string njamconf("njam.conf"); + if (home) + njamconf = std::string(home) + "/.njamconf"; +- FILE *fp = fopen(njamconf.c_str(), "r"); +- if (fp) +- { +- LogFile("Reading njam.conf file.\n"); +- char buff[20]; +- while (true) +- { +- fgets(buff, 20, fp); +- if (feof(fp)) +- break; +- +- if (buff[1] == '=') +- { +- int i; +- switch (buff[0]) +- { +- case 'M': m_GameOptions.PlayMusic = (buff[2] == '1'); break; +- case 'S': m_GameOptions.PlaySound = (buff[2] == '1'); break; +- case 'U': m_GameOptions.UsedSkin = (buff[2] - '0'); break; +- case 'I': // serverIP +- for (i=2; buff[i] != '\n' && buff[i] && i<17; i++) +- m_GameOptions.ServerIP[i-2] = buff[i]; +- m_GameOptions.ServerIP[i] = '\0'; +- break; +- default: +- printf("Unknown configuration file option: %c\n", buff[0]); +- } +- } +- } +- fclose(fp); +- } ++ FILE *fp = fopen(njamconf.c_str(), "r"); ++ if (fp) ++ { ++ LogFile("Reading njam.conf file.\n"); ++ char buff[20]; ++ while (true) ++ { ++ fgets(buff, 20, fp); ++ if (feof(fp)) ++ break; ++ ++ if (buff[1] == '=') ++ { ++ int i; ++ switch (buff[0]) ++ { ++ case 'M': m_GameOptions.PlayMusic = (buff[2] == '1'); break; ++ case 'S': m_GameOptions.PlaySound = (buff[2] == '1'); break; ++ case 'U': m_GameOptions.UsedSkin = (buff[2] - '0'); break; ++ case 'I': // serverIP ++ for (i=2; buff[i] != '\n' && buff[i] && i<17; i++) ++ m_GameOptions.ServerIP[i-2] = buff[i]; ++ m_GameOptions.ServerIP[i] = '\0'; ++ break; ++ default: ++ printf("Unknown configuration file option: %c\n", buff[0]); ++ } ++ } ++ } ++ fclose(fp); ++ } + else + LogFile("Failed to open conf file.\n"); + +- // create default hiscore ++ // create default hiscore + LogFile("Creating default hiscore.\n"); +- char DefaultNames[10][10] = { +- "MILAN", "TANJA", +- "DULIO", "DJORDJE", +- "CLAUS", "ENZO", +- "JOLAN", "JAAP", +- "MARTIN", "RICHARD" }; +- for (int i=0; i<10; i++) +- { +- TopTenScores[i].points = (int)(18 - 1.8*i) * 220; +- TopTenScores[i].level = 18 - (int)(1.9*i); +- sprintf(TopTenScores[i].name, "%s\0", DefaultNames[i]); +- } +- +- // load hiscore from file (if any) +- // format: NAME#POINTS#LEVEL# +- fp = fopen("hiscore.dat", "r"); +- if (fp) +- { +- LogFile("Reading hiscore.dat\n"); +- char buff[40]; +- int number = 0; +- while (!feof(fp) && number < 10) +- { +- fgets(buff, 40, fp); +- int i = 0, last; +- +- // name +- while (buff[i] != '#' && i < 9) +- { +- TopTenScores[number].name[i] = buff[i]; +- i++; +- } +- TopTenScores[number].name[i] = '\0'; +- +- i++; +- last = i; +- while (buff[i] != '#' && i < 40) +- i++; +- if (i >= 40) +- break; +- buff[i] = '\0'; +- TopTenScores[number].points = atoi(buff+last); +- i++; +- last = i; +- while (buff[i] != '#' && i < 40) +- i++; +- if (i >= 40) +- break; +- buff[i] = '\0'; +- TopTenScores[number].level = atoi(buff+last); +- +- number++; +- } +- +- fclose(fp); +- } ++ char DefaultNames[10][10] = { ++ "MILAN", "TANJA", ++ "DULIO", "DJORDJE", ++ "CLAUS", "ENZO", ++ "JOLAN", "JAAP", ++ "MARTIN", "RICHARD" }; ++ for (int i=0; i<10; i++) ++ { ++ TopTenScores[i].points = (int)(18 - 1.8*i) * 220; ++ TopTenScores[i].level = 18 - (int)(1.9*i); ++ sprintf(TopTenScores[i].name, "%s\0", DefaultNames[i]); ++ } ++ ++ // load hiscore from file (if any) ++ // format: NAME#POINTS#LEVEL# ++ if (highscore_fp) ++ { ++ LogFile("Reading /var/games/njam.hs\n"); ++ char buff[40]; ++ int number = 0; ++ while (!feof(highscore_fp) && number < 10) ++ { ++ fgets(buff, 40, highscore_fp); ++ int i = 0, last; ++ ++ // name ++ while (buff[i] != '#' && i < 9) ++ { ++ TopTenScores[number].name[i] = buff[i]; ++ i++; ++ } ++ TopTenScores[number].name[i] = '\0'; ++ ++ i++; ++ last = i; ++ while (buff[i] != '#' && i < 40) ++ i++; ++ if (i >= 40) ++ break; ++ buff[i] = '\0'; ++ TopTenScores[number].points = atoi(buff+last); ++ i++; ++ last = i; ++ while (buff[i] != '#' && i < 40) ++ i++; ++ if (i >= 40) ++ break; ++ buff[i] = '\0'; ++ TopTenScores[number].level = atoi(buff+last); ++ ++ number++; ++ } ++ } + + LogFile("Opening audio..."); + if (Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 1, 2048) == -1) +- { +- m_GameOptions.PlayMusic = false; +- m_GameOptions.PlaySound = false; +- LogFile("Failed.\n"); ++ { ++ m_GameOptions.PlayMusic = false; ++ m_GameOptions.PlaySound = false; ++ LogFile("Failed.\n"); + printf("Mix_OpenAudio: %s\n", Mix_GetError()); +- } +- else +- { +- m_AudioAvailable = true; +- LogFile("OK.\n"); +- +- printf("Reserving 4 channels for sfx...\n"); +- int reserved = Mix_ReserveChannels(4); +- if(reserved != 4) +- { +- printf("Reserved %d channels from default mixing.\n",reserved); +- printf("4 channels were not reserved!\n"); +- } +- +- printf("Loading song: data/satisfy.xm...\n"); +- m_MainMenuMusic = Mix_LoadMUS("data/satisfy.xm");; +- if(!m_MainMenuMusic) +- printf("ERROR: Mix_LoadMUS(): %s\n", Mix_GetError()); +- +- printf("Loading song: data/ritam.s3m...\n"); +- m_GameMusic1 = Mix_LoadMUS("data/ritam.s3m");; +- if(!m_GameMusic1) +- printf("ERROR: Mix_LoadMUS(): %s\n", Mix_GetError()); +- +- printf("Loading song: data/dali.xm...\n"); +- m_GameMusic2 = Mix_LoadMUS("data/dali.xm");; +- if(!m_GameMusic2) +- printf("ERROR: Mix_LoadMUS(): %s\n", Mix_GetError()); +- +- printf("Loading samples..."); +- m_Sounds[0] = Mix_LoadWAV("data/dead.wav"); ++ } ++ else ++ { ++ m_AudioAvailable = true; ++ LogFile("OK.\n"); ++ ++ printf("Reserving 4 channels for sfx...\n"); ++ int reserved = Mix_ReserveChannels(4); ++ if(reserved != 4) ++ { ++ printf("Reserved %d channels from default mixing.\n",reserved); ++ printf("4 channels were not reserved!\n"); ++ } ++ ++ printf("Loading song: data/satisfy.xm...\n"); ++ m_MainMenuMusic = Mix_LoadMUS("data/satisfy.xm");; ++ if(!m_MainMenuMusic) ++ printf("ERROR: Mix_LoadMUS(): %s\n", Mix_GetError()); ++ ++ printf("Loading song: data/ritam.s3m...\n"); ++ m_GameMusic1 = Mix_LoadMUS("data/ritam.s3m");; ++ if(!m_GameMusic1) ++ printf("ERROR: Mix_LoadMUS(): %s\n", Mix_GetError()); ++ ++ printf("Loading song: data/dali.xm...\n"); ++ m_GameMusic2 = Mix_LoadMUS("data/dali.xm");; ++ if(!m_GameMusic2) ++ printf("ERROR: Mix_LoadMUS(): %s\n", Mix_GetError()); ++ ++ printf("Loading samples..."); ++ m_Sounds[0] = Mix_LoadWAV("data/dead.wav"); + m_Sounds[1] = Mix_LoadWAV("data/dead2.wav"); + m_Sounds[2] = Mix_LoadWAV("data/dead3.wav"); + m_Sounds[3] = Mix_LoadWAV("data/kill.wav"); +@@ -762,251 +791,253 @@ bool NjamEngine::Init(bool Fullscreen, bool SoftwareSurface, bool UseDGA) + m_Sounds[15] = Mix_LoadWAV("data/bonus.wav"); + m_Sounds[16] = Mix_LoadWAV("data/50pts.wav"); + for (int i=0; i<17; i++) +- if (!m_Sounds[i]) +- printf("ERROR loading sample nr. %d\n", i); ++ if (!m_Sounds[i]) ++ printf("ERROR loading sample nr. %d\n", i); + printf("done.\n"); +- } ++ } + +- return true; ++ return true; + } + //----------------------------------------------------------------------------- + bool NjamEngine::MenuItemSelected(int& SelectedMenuItem) + { +- if (SelectedMenuItem == m_NumberOfMenuItems-1) // last menu item = EXIT +- { +- m_ActiveMenu = mtMainMenu; // return to main menu... +- m_NumberOfMenuItems = 8; // ...which has 7 items +- SelectedMenuItem = 0; +- return true; +- } +- +- if (m_ActiveMenu == mtMainMenu) // process all items in main menu +- { +- if (SelectedMenuItem == 6) // "LevelEditor" selected +- { +- LevelEditor(); +- return true; +- } +- +- if (SelectedMenuItem == 5) // "Options" menu item selected +- { +- m_ActiveMenu = mtOptionsMenu; +- m_NumberOfMenuItems = 4; // Options menu has 4 items +- SelectedMenuItem = 0; +- return true; +- } +- else // some of the games is selected +- { // also other menu items can get here... +- // play the game +- StartGame((GameType)SelectedMenuItem); +- if (m_NetworkAvailable) +- Disconnect(); // safe to call - checks everthing +- +- // play music again (if not playing already) +- if (m_AudioAvailable && m_MainMenuMusic && m_GameOptions.PlayMusic && !Mix_PlayingMusic() && Mix_PlayMusic(m_MainMenuMusic, -1)==-1) +- printf("ERROR: njam.cpp: MenuItemSelected: Mix_PlayMusic: %s\n", Mix_GetError()); +- +- return true; +- } +- } +- +- if (m_ActiveMenu == mtOptionsMenu) // process all items in Options menu +- { +- if (SelectedMenuItem == 0) // music on/off +- { +- m_GameOptions.PlayMusic = !m_GameOptions.PlayMusic; +- if (!m_AudioAvailable) +- m_GameOptions.PlayMusic = false; +- +- if (m_GameOptions.PlayMusic) +- { +- if (m_AudioAvailable && m_MainMenuMusic && Mix_PlayMusic(m_MainMenuMusic, -1)==-1) +- printf("ERROR: njam.cpp: MenuItemSelected: Mix_PlayMusic: %s\n", Mix_GetError()); +- } +- else if (m_AudioAvailable && m_MainMenuMusic && Mix_PlayingMusic()) +- Mix_HaltMusic(); +- } +- else if (SelectedMenuItem == 1) // sound on/off +- { +- m_GameOptions.PlaySound = !m_GameOptions.PlaySound; +- if (!m_AudioAvailable) +- m_GameOptions.PlaySound = false; +- } +- else if (SelectedMenuItem == 2) // skins on/off +- { +- m_GameOptions.UsedSkin++; +- if (m_GameOptions.UsedSkin > m_NumberOfSkins) +- m_GameOptions.UsedSkin = 0; +- } +- } +- +- return true; ++ if (SelectedMenuItem == m_NumberOfMenuItems-1) // last menu item = EXIT ++ { ++ m_ActiveMenu = mtMainMenu; // return to main menu... ++ m_NumberOfMenuItems = 8; // ...which has 7 items ++ SelectedMenuItem = 0; ++ return true; ++ } ++ ++ if (m_ActiveMenu == mtMainMenu) // process all items in main menu ++ { ++ if (SelectedMenuItem == 6) // "LevelEditor" selected ++ { ++ LevelEditor(); ++ return true; ++ } ++ ++ if (SelectedMenuItem == 5) // "Options" menu item selected ++ { ++ m_ActiveMenu = mtOptionsMenu; ++ m_NumberOfMenuItems = 4; // Options menu has 4 items ++ SelectedMenuItem = 0; ++ return true; ++ } ++ else // some of the games is selected ++ { // also other menu items can get here... ++ // play the game ++ StartGame((GameType)SelectedMenuItem); ++ if (m_NetworkAvailable) ++ Disconnect(); // safe to call - checks everthing ++ ++ // play music again (if not playing already) ++ if (m_AudioAvailable && m_MainMenuMusic && m_GameOptions.PlayMusic && !Mix_PlayingMusic() && Mix_PlayMusic(m_MainMenuMusic, -1)==-1) ++ printf("ERROR: njam.cpp: MenuItemSelected: Mix_PlayMusic: %s\n", Mix_GetError()); ++ ++ return true; ++ } ++ } ++ ++ if (m_ActiveMenu == mtOptionsMenu) // process all items in Options menu ++ { ++ if (SelectedMenuItem == 0) // music on/off ++ { ++ m_GameOptions.PlayMusic = !m_GameOptions.PlayMusic; ++ if (!m_AudioAvailable) ++ m_GameOptions.PlayMusic = false; ++ ++ if (m_GameOptions.PlayMusic) ++ { ++ if (m_AudioAvailable && m_MainMenuMusic && Mix_PlayMusic(m_MainMenuMusic, -1)==-1) ++ printf("ERROR: njam.cpp: MenuItemSelected: Mix_PlayMusic: %s\n", Mix_GetError()); ++ } ++ else if (m_AudioAvailable && m_MainMenuMusic && Mix_PlayingMusic()) ++ Mix_HaltMusic(); ++ } ++ else if (SelectedMenuItem == 1) // sound on/off ++ { ++ m_GameOptions.PlaySound = !m_GameOptions.PlaySound; ++ if (!m_AudioAvailable) ++ m_GameOptions.PlaySound = false; ++ } ++ else if (SelectedMenuItem == 2) // skins on/off ++ { ++ m_GameOptions.UsedSkin++; ++ if (m_GameOptions.UsedSkin > m_NumberOfSkins) ++ m_GameOptions.UsedSkin = 0; ++ } ++ } ++ ++ return true; + } + //--------------------------------------------------------------------------- + void NjamEngine::ScrollText() + { + const char scroll_text[] = "NJAM BY MILAN BABUSKOV USE ARROW KEYS TO NAVIGATE MENU HIT ENTER TO SELECT MENU ITEM VISIT NJAM.SOURCEFORGE.NET ONLINE NJAM IS A FREE GAME, BUT IF YOU WISH TO SUPPORT DEVELOPMENT YOU ARE WELCOME TO SEND SOME MONEY. FIVE USD OR EURO IS QUITE ENOUGH. CONTACT ME AT MBABUSKOV@YAHOO.COM FOR MORE INFO. "; +- m_ScrollOffset-=2; ++ m_ScrollOffset-=2; + +- if (m_ScrollOffset < -3600) // end of message +- m_ScrollOffset = 820; ++ if (m_ScrollOffset < -3600) // end of message ++ m_ScrollOffset = 820; + +- m_FontYellow->WriteTextXY(m_Screen, m_ScrollOffset, 10, scroll_text); ++ m_FontYellow->WriteTextXY(m_Screen, m_ScrollOffset, 10, scroll_text); + } + //----------------------------------------------------------------------------- + void NjamEngine::Start() + { +- // play main menu .mod +- if (m_AudioAvailable && m_GameOptions.PlayMusic && Mix_PlayMusic(m_MainMenuMusic, -1) == -1) ++ // play main menu .mod ++ if (m_AudioAvailable && m_GameOptions.PlayMusic && Mix_PlayMusic(m_MainMenuMusic, -1) == -1) + printf("ERROR: njam.cpp: Mix_PlayMusic: %s\n", Mix_GetError()); + +- int SelectedMenuItem = 0; +- m_NumberOfMenuItems = 8; // 7 options in main menu (can be different for other menus, but last option must be: Exit or Back) +- m_ActiveMenu = mtMainMenu; // MainMenu is active (I used enum to make code readable) +- +- while (true) // loop main menu +- { +- // this screen has animations, so we want it to look the same on all machines +- Uint32 StartTime = SDL_GetTicks(); +- +- if (0 != SDL_BlitSurface(m_MainMenuImage, NULL, m_Screen, NULL)) // draw main image +- { +- LogFile("Failed to blit main menu image.\n"); +- LogFile((const char *)SDL_GetError()); +- return; +- } +- +- // if options -- draw options +- if (m_ActiveMenu == mtOptionsMenu) +- { +- SDL_Rect src,dest; +- dest.x = 50; +- dest.y = 120; +- if (0 != SDL_BlitSurface(m_OptionsMenuImage, NULL, m_Screen, &dest)) +- { +- LogFile("Failed to blit options menu image.\n"); +- LogFile((const char *)SDL_GetError()); +- return; +- } +- +- // draw boxes for selected options +- for (int i=0; i<2; i++) +- { +- bool option; +- switch (i) +- { +- case 0: option = m_GameOptions.PlayMusic; break; +- case 1: option = m_GameOptions.PlaySound; break; +- } +- +- NjamSetRect(dest, 180, 128+35*i, 45, 32); +- if (!option) +- { +- dest.x = 230; +- dest.w = 80; +- } +- SDL_FillRect(m_Screen, &dest, SDL_MapRGB(m_Screen->format, 255, 255, 255)); +- dest.x += 2; +- dest.y += 2; +- NjamSetRect(src, dest.x - 50, dest.y - 120, dest.w - 4, dest.h - 4); +- SDL_BlitSurface(m_OptionsMenuImage, &src, m_Screen, &dest); +- } +- +- // draw selected skin, or random +- if (m_GameOptions.UsedSkin == 0) +- { +- NjamSetRect(dest, 110, 202, 302, 27); +- SDL_FillRect(m_Screen, &dest, SDL_MapRGB(m_Screen->format, 200, 200, 20)); +- NjamSetRect(dest, 111, 203, 300, 25); +- SDL_FillRect(m_Screen, &dest, SDL_MapRGB(m_Screen->format, 0, 0, 0)); +- m_FontYellow->WriteTextXY(m_Screen, 200, 208, "R A N D O M"); +- } +- else +- { +- NjamSetRect(dest, 110, 202, 302, 27); +- SDL_FillRect(m_Screen, &dest, SDL_MapRGB(m_Screen->format, 0, 0, 0)); +- NjamSetRect(dest, 111, 203); +- SDL_BlitSurface(m_Skins[m_GameOptions.UsedSkin - 1], NULL, m_Screen, &dest); +- } +- } +- +- // draw menu selector - at pos: SelectedMenuItem +- SDL_Rect rsrc, rdest; +- NjamSetRect(rsrc, 100, 0, 25, 25); +- NjamSetRect(rdest, 22, 130 + 35 * SelectedMenuItem); +- if (0 != SDL_BlitSurface(m_SpriteImage, &rsrc, m_Screen, &rdest)) +- { +- LogFile("Failed to blit menu selector image.\n"); +- LogFile((const char *)SDL_GetError()); +- return; +- } +- +- DoScript(); // update info window +- ScrollText(); // update text that scrolls at the top of screen +- +- // draw hiscore table +- m_FontBlue->WriteTextXY(m_Screen, 714, 470, "LEVEL SCORE"); +- for (int i=0; i<10; i++) +- { +- if (i == m_LastHiscore) +- { +- SDL_Rect dst; +- NjamSetRect(dst, 658, 479+i*10, 124, 11); +- SDL_FillRect(m_Screen, &dst, SDL_MapRGB(m_Screen->format, 0, 0, 100)); +- } +- +- char text[100]; +- sprintf(text, "%-11s %2d %5d\0", TopTenScores[i].name, TopTenScores[i].level, TopTenScores[i].points); +- m_FontBlue->WriteTextXY(m_Screen, 660, 480+i*10, text); +- } +- +- // draw a version number +- m_FontBlue->WriteTextXY(m_Screen, 92, 85, "VERSION 1.25"); +- +- // handle a keypress +- SDL_Event event; +- while(SDL_PollEvent(&event)) // Loop until there are no events left on the queue +- { +- switch(event.type) +- { +- case SDL_KEYDOWN: // Handle a KEYDOWN event +- if (event.key.keysym.sym==SDLK_ESCAPE) +- { +- if (mtMainMenu == m_ActiveMenu) // ESC - exit game +- return; +- +- SelectedMenuItem = m_NumberOfMenuItems - 1; +- if (!MenuItemSelected(SelectedMenuItem)) // as if last menu item is selected (= Exit from submenu) +- return; +- } +- else if (event.key.keysym.sym==SDLK_UP) // up arrow +- { +- if (SelectedMenuItem > 0) +- SelectedMenuItem--; +- } +- else if (event.key.keysym.sym==SDLK_DOWN) // down arrow +- { +- if (SelectedMenuItem < m_NumberOfMenuItems-1) +- SelectedMenuItem++; +- } +- else if (event.key.keysym.sym==SDLK_RETURN || event.key.keysym.sym==SDLK_KP_ENTER) // ENTER +- { +- if (SelectedMenuItem == m_NumberOfMenuItems-1 && m_ActiveMenu == mtMainMenu) // Exit in main = exit game +- return; +- +- if (!MenuItemSelected(SelectedMenuItem)) // show options/run game/whatever, returns false if fatal error +- return; +- } +- break; +- } +- } +- +- +- // About 30fps. So that it doesn't fly on fast machines... +- while (StartTime + 30 > SDL_GetTicks()) +- SDL_Delay(2); +- +- SDL_Flip(m_Screen); +- } ++ int SelectedMenuItem = 0; ++ m_NumberOfMenuItems = 8; // 7 options in main menu (can be different for other menus, but last option must be: Exit or Back) ++ m_ActiveMenu = mtMainMenu; // MainMenu is active (I used enum to make code readable) ++ ++ while (true) // loop main menu ++ { ++ // this screen has animations, so we want it to look the same on all machines ++ Uint32 StartTime = SDL_GetTicks(); ++ ++ if (0 != SDL_BlitSurface(m_MainMenuImage, NULL, m_Screen, NULL)) // draw main image ++ { ++ LogFile("Failed to blit main menu image.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return; ++ } ++ ++ // if options -- draw options ++ if (m_ActiveMenu == mtOptionsMenu) ++ { ++ SDL_Rect src,dest; ++ dest.x = 50; ++ dest.y = 120; ++ if (0 != SDL_BlitSurface(m_OptionsMenuImage, NULL, m_Screen, &dest)) ++ { ++ LogFile("Failed to blit options menu image.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return; ++ } ++ ++ // draw boxes for selected options ++ for (int i=0; i<2; i++) ++ { ++ bool option; ++ switch (i) ++ { ++ case 0: option = m_GameOptions.PlayMusic; break; ++ case 1: option = m_GameOptions.PlaySound; break; ++ } ++ ++ NjamSetRect(dest, 180, 128+35*i, 45, 32); ++ if (!option) ++ { ++ dest.x = 230; ++ dest.w = 80; ++ } ++ SDL_FillRect(m_Screen, &dest, SDL_MapRGB(m_Screen->format, 255, 255, 255)); ++ dest.x += 2; ++ dest.y += 2; ++ NjamSetRect(src, dest.x - 50, dest.y - 120, dest.w - 4, dest.h - 4); ++ SDL_BlitSurface(m_OptionsMenuImage, &src, m_Screen, &dest); ++ } ++ ++ // draw selected skin, or random ++ if (m_GameOptions.UsedSkin == 0) ++ { ++ NjamSetRect(dest, 110, 202, 302, 27); ++ SDL_FillRect(m_Screen, &dest, SDL_MapRGB(m_Screen->format, 200, 200, 20)); ++ NjamSetRect(dest, 111, 203, 300, 25); ++ SDL_FillRect(m_Screen, &dest, SDL_MapRGB(m_Screen->format, 0, 0, 0)); ++ m_FontYellow->WriteTextXY(m_Screen, 200, 208, "R A N D O M"); ++ } ++ else ++ { ++ NjamSetRect(dest, 110, 202, 302, 27); ++ SDL_FillRect(m_Screen, &dest, SDL_MapRGB(m_Screen->format, 0, 0, 0)); ++ NjamSetRect(dest, 111, 203); ++ SDL_BlitSurface(m_Skins[m_GameOptions.UsedSkin - 1], NULL, m_Screen, &dest); ++ } ++ } ++ ++ // draw menu selector - at pos: SelectedMenuItem ++ SDL_Rect rsrc, rdest; ++ NjamSetRect(rsrc, 100, 0, 25, 25); ++ NjamSetRect(rdest, 22, 130 + 35 * SelectedMenuItem); ++ if (0 != SDL_BlitSurface(m_SpriteImage, &rsrc, m_Screen, &rdest)) ++ { ++ LogFile("Failed to blit menu selector image.\n"); ++ LogFile((const char *)SDL_GetError()); ++ return; ++ } ++ ++ DoScript(); // update info window ++ ScrollText(); // update text that scrolls at the top of screen ++ ++ // draw hiscore table ++ m_FontBlue->WriteTextXY(m_Screen, 714, 470, "LEVEL SCORE"); ++ for (int i=0; i<10; i++) ++ { ++ if (i == m_LastHiscore) ++ { ++ SDL_Rect dst; ++ NjamSetRect(dst, 658, 479+i*10, 124, 11); ++ SDL_FillRect(m_Screen, &dst, SDL_MapRGB(m_Screen->format, 0, 0, 100)); ++ } ++ ++ char text[100]; ++ sprintf(text, "%-11s %2d %5d\0", TopTenScores[i].name, TopTenScores[i].level, TopTenScores[i].points); ++ m_FontBlue->WriteTextXY(m_Screen, 660, 480+i*10, text); ++ } ++ ++ // draw a version number ++ m_FontBlue->WriteTextXY(m_Screen, 92, 85, "VERSION 1.25"); ++ ++ // handle a keypress ++ SDL_Event event; ++ while(SDL_PollEvent(&event)) // Loop until there are no events left on the queue ++ { ++ switch(event.type) ++ { ++ case SDL_QUIT: ++ throw 2; ++ case SDL_KEYDOWN: // Handle a KEYDOWN event ++ if (event.key.keysym.sym==SDLK_ESCAPE) ++ { ++ if (mtMainMenu == m_ActiveMenu) // ESC - exit game ++ return; ++ ++ SelectedMenuItem = m_NumberOfMenuItems - 1; ++ if (!MenuItemSelected(SelectedMenuItem)) // as if last menu item is selected (= Exit from submenu) ++ return; ++ } ++ else if (event.key.keysym.sym==SDLK_UP) // up arrow ++ { ++ if (SelectedMenuItem > 0) ++ SelectedMenuItem--; ++ } ++ else if (event.key.keysym.sym==SDLK_DOWN) // down arrow ++ { ++ if (SelectedMenuItem < m_NumberOfMenuItems-1) ++ SelectedMenuItem++; ++ } ++ else if (event.key.keysym.sym==SDLK_RETURN || event.key.keysym.sym==SDLK_KP_ENTER) // ENTER ++ { ++ if (SelectedMenuItem == m_NumberOfMenuItems-1 && m_ActiveMenu == mtMainMenu) // Exit in main = exit game ++ return; ++ ++ if (!MenuItemSelected(SelectedMenuItem)) // show options/run game/whatever, returns false if fatal error ++ return; ++ } ++ break; ++ } ++ } ++ ++ ++ // About 30fps. So that it doesn't fly on fast machines... ++ while (StartTime + 30 > SDL_GetTicks()) ++ SDL_Delay(2); ++ ++ SDL_Flip(m_Screen); ++ } + } + //--------------------------------------------------------------------------- +diff --git a/src/njam.h b/src/njam.h +index be6e4d4..e04ae9c 100644 +--- a/src/njam.h ++++ b/src/njam.h +@@ -98,6 +98,7 @@ typedef struct + struct list_item + { + char item_text[50]; ++ char item_path[512]; + struct list_item *next; + struct list_item *prev; + }; +@@ -192,7 +193,7 @@ private: + void LevelEditor(); // level editor (njamedit.cpp) + void RenderEditor(bool, int, int, int); + bool EnterFileName(char *file_name); +- int SelectMap(char type, char *filename = NULL); ++ int SelectMap(char type, char *filename = NULL, int filename_size = 0); + struct list_item *SelectFromList(struct list_item *first); + void Message(char *text); + bool Query(char *text); +diff --git a/src/njamedit.cpp b/src/njamedit.cpp +index 92debdf..a895ca9 100644 +--- a/src/njamedit.cpp ++++ b/src/njamedit.cpp +@@ -41,7 +41,7 @@ void NjamEngine::LevelEditor() + { + int level_type = 0; // cooperative + int level_type_was = 0; +- char filename[250]; ++ char filename[512]; + filename[0] = '\0'; + + int x=2, y=1; +@@ -90,7 +90,7 @@ void NjamEngine::LevelEditor() + + if (key == SDLK_l) // select file from directory + { +- if (SelectMap('A', filename) > -1) ++ if (SelectMap('A', filename, sizeof(filename)) > -1) + { + int w=0; + while (filename[w]) +@@ -127,12 +127,20 @@ void NjamEngine::LevelEditor() + { + if (EnterFileName(filename)) + { +- char buf[250]; ++ char buf[512]; + char types[2][5] = { "COOP", "DUEL" }; +- sprintf(buf, "levels/%s.%s\0", filename, types[level_type]); +- sprintf(filename, "%s\0", buf); ++#ifdef __linux__ ++ char *home = NjamGetHomeDir(); ++ snprintf(buf, sizeof(buf), ++ "%s/.njam-levels/%s.%s", ++ home? home:"", ++#else ++ snprintf(buf, sizeof(buf), ++ "levels/%s.%s", ++#endif ++ filename, types[level_type]); + LogFile::LogFile("Saving maps"); +- m_Maps.Save(filename); ++ m_Maps.Save(buf); + level_type_was = level_type; + changed = false; + } +@@ -458,51 +466,72 @@ bool NjamEngine::EnterFileName(char *file_name) + } + } + //--------------------------------------------------------------------------- +-int NjamEngine::SelectMap(char type, char *filename) ++int NjamEngine::SelectMap(char type, char *filename, int filename_size) + { + struct list_item *first = NULL; + +- // open folder, load all entries ++ // open folders, load all entries + DIR *dir; + struct dirent *ent; ++ int i; ++ char dirname[512] = "levels"; + +- if ((dir = opendir("levels")) == NULL) ++#ifdef __linux__ ++ for (i=0; i<2; i++) + { +- printf("Unable to open directory\n"); +- return -1; +- } ++ if (i==0) ++ { ++#endif ++ if ((dir = opendir(dirname)) == NULL) ++ { ++ printf("Unable to open directory\n"); ++ return -1; ++ } ++#ifdef __linux__ ++ } ++ else ++ { ++ char *home = NjamGetHomeDir(); + +- while ((ent = readdir(dir)) != NULL) +- { +- // check if last letter of name maches: +- int p = 0; +- while (ent->d_name[p]) +- p++; +- +- char c = ent->d_name[p-1]; +- if (c != 'P' && c != 'L') +- continue; +- +- if (type != 'A' && c != type) +- continue; +- +- struct list_item *new_file = new struct list_item; +- new_file->next = first; +- new_file->prev = NULL; +- if (first) +- first->prev = new_file; +- first = new_file; +- +- // copy file name +- for (int i=0; ent->d_name[i] && i<29; i++) ++ snprintf(dirname, sizeof(dirname), "%s/.njam-levels", ++ home? home:""); ++ if ((dir = opendir(dirname)) == NULL) ++ break; ++ } ++#endif ++ while ((ent = readdir(dir)) != NULL) + { +- first->item_text[i] = ent->d_name[i]; +- first->item_text[i+1] = '\0'; ++ // check if last letter of name maches: ++ int p = 0; ++ while (ent->d_name[p]) ++ p++; ++ ++ char c = ent->d_name[p-1]; ++ if (c != 'P' && c != 'L') ++ continue; ++ ++ if (type != 'A' && c != type) ++ continue; ++ ++ struct list_item *new_file = new struct list_item; ++ new_file->next = first; ++ new_file->prev = NULL; ++ if (first) ++ first->prev = new_file; ++ first = new_file; ++ ++ // copy file name ++ snprintf(first->item_text, sizeof(first->item_text), ++ "%s", ent->d_name); ++ snprintf(first->item_path, sizeof(first->item_path), ++ "%s/%s", dirname, ent->d_name); + } +- } + +- if (closedir(dir) != 0) +- printf("Unable to close directory\n"); ++ if (closedir(dir) != 0) ++ printf("Unable to close directory\n"); ++#ifdef __linux__ ++ } ++#endif + + // show and let player select if more than one levelset + struct list_item *selected; +@@ -514,11 +543,10 @@ int NjamEngine::SelectMap(char type, char *filename) + int result = 0; // no levels loaded (so far) + if (selected) + { +- char file_name[200]; +- sprintf(file_name, "levels/%s\0", selected->item_text); +- result = m_Maps.Load(file_name); ++ result = m_Maps.Load(selected->item_path); + if (filename) +- sprintf(filename, "%s\0", file_name); ++ snprintf(filename, filename_size, "%s", ++ selected->item_path); + } + + while (first) // free memory +diff --git a/src/njamutils.cpp b/src/njamutils.cpp +index 4885558..4f46f29 100644 +--- a/src/njamutils.cpp ++++ b/src/njamutils.cpp +@@ -43,6 +43,8 @@ SDLKey NjamGetch(bool Wait) + SDL_Event event; + while (SDL_PollEvent(&event)) + { ++ if (event.type == SDL_QUIT) ++ throw 1; + if (event.type == SDL_KEYDOWN) + return event.key.keysym.sym; + } +@@ -162,3 +164,83 @@ bool SurfaceEffect(SDL_Surface *surface, SDL_Rect& r, tEffect Effect) + return true; + } + //----------------------------------------------------------------------------- ++#ifdef __linux__ ++#include <pwd.h> ++#include <unistd.h> ++#include <errno.h> ++#include <sys/types.h> ++#include <sys/stat.h> ++#if defined(__DECC) && defined(VMS) ++#include <unixlib.h> ++static char *vms_to_unix_buffer = NULL; ++static int convert_vms_to_unix(char *vms_dir_name) ++{ ++ vms_to_unix_buffer = vms_dir_name; ++} ++#endif ++ ++char *NjamGetHomeDir() ++{ ++ struct passwd *pw; ++ ++ if (!(pw = getpwuid(getuid()))) ++ { ++ fprintf(stderr, "Who are you? Not found in passwd database!!\n"); ++ return NULL; ++ } ++ ++#if defined(__DECC) && defined(VMS) ++ /* Convert The OpenVMS Formatted "$HOME" Directory Path Into Unix ++ Format. */ ++ decc$from_vms(pw->pw_dir, convert_vms_to_unix, 1); ++ return vms_to_unix_buffer; ++#else ++ return pw->pw_dir; ++#endif ++} ++//----------------------------------------------------------------------------- ++int NjamCheckAndCreateDir(const char *name) ++{ ++ struct stat stat_buffer; ++ ++ if (stat(name, &stat_buffer)) ++ { ++ /* error check if it doesn't exist or something else is wrong */ ++ if (errno == ENOENT) ++ { ++ /* doesn't exist letts create it ;) */ ++#ifdef BSD43 ++ if (mkdir(name, 0775)) ++#else ++ if (mkdir(name, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH)) ++#endif ++ { ++ fprintf(stderr, "Error creating dir %s", name); ++ perror(" "); ++ return -1; ++ } ++ } ++ else ++ { ++ /* something else went wrong yell about it */ ++ fprintf(stderr, "Error opening %s", name); ++ perror(" "); ++ return -1; ++ } ++ } ++ else ++ { ++ /* file exists check it's a dir otherwise yell about it */ ++#ifdef BSD43 ++ if (!(S_IFDIR & stat_buffer.st_mode)) ++#else ++ if (!S_ISDIR(stat_buffer.st_mode)) ++#endif ++ { ++ fprintf(stderr,"Error %s exists but isn't a dir\n", name); ++ return -1; ++ } ++ } ++ return 0; ++} ++#endif +diff --git a/src/njamutils.h b/src/njamutils.h +index 1806d26..8d79bcc 100644 +--- a/src/njamutils.h ++++ b/src/njamutils.h +@@ -25,6 +25,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + void NjamSetRect(SDL_Rect& rect, int x, int y, int w=0, int h=0); + SDLKey NjamGetch(bool Wait); + int NjamRandom(int MaxValue); ++#ifdef __linux__ ++char *NjamGetHomeDir(); ++int NjamCheckAndCreateDir(const char *name); ++#endif + + typedef enum { fxBlackWhite, fxDarken } tEffect; + bool SurfaceEffect(SDL_Surface *surface, SDL_Rect& r, tEffect Effect = fxBlackWhite); |