diff --git a/source/code/CppSdl/CppSdlException.cpp b/source/code/CppSdl/CppSdlException.cpp index a05c6da..fbec9e6 100644 --- a/source/code/CppSdl/CppSdlException.cpp +++ b/source/code/CppSdl/CppSdlException.cpp @@ -18,8 +18,8 @@ CppSdlException::CppSdlException(Subsystem subsystem,long errorNumber, std::stri CppSdlException::CppSdlException(const CppSdlException& orig) { } -//CppSdlException::~CppSdlException() { -//} +CppSdlException::~CppSdlException() throw() { +} const char* CppSdlException::what() const throw() { return _message.c_str(); @@ -33,4 +33,4 @@ Subsystem CppSdlException::GetSubSystem() { return _subsystem; } -} \ No newline at end of file +} diff --git a/source/code/CppSdl/CppSdlException.hpp b/source/code/CppSdl/CppSdlException.hpp index f4ba246..8460466 100644 --- a/source/code/CppSdl/CppSdlException.hpp +++ b/source/code/CppSdl/CppSdlException.hpp @@ -27,7 +27,7 @@ public: virtual ~CppSdlException() throw(); virtual const char* what() const throw(); long GetErrorNumber(); - long GetSubSystem(); + Subsystem GetSubSystem(); private: std::string _message; long _errorNumber; diff --git a/source/code/CppSdl/CppSdlImageHolder.cpp b/source/code/CppSdl/CppSdlImageHolder.cpp index 5bc5b62..46b0916 100644 --- a/source/code/CppSdl/CppSdlImageHolder.cpp +++ b/source/code/CppSdl/CppSdlImageHolder.cpp @@ -10,6 +10,12 @@ namespace CppSdl { +CppSdlImageHolder::CppSdlImageHolder() { + data = NULL; + counter = new int; + (*counter)=1; +} + CppSdlImageHolder::CppSdlImageHolder(std::string filename) { data = IMG_Load(filename.c_str()); if(!data) @@ -20,65 +26,91 @@ CppSdlImageHolder::CppSdlImageHolder(std::string filename) { } SDL_GetClipRect(data,&area); OptimizeForBlit(); - counter=1; + counter = new int; + *counter=1; } CppSdlImageHolder::CppSdlImageHolder(const CppSdlImageHolder& orig) { //Just take the data from the original. This is technically wrong but adds a little performance. data = orig.data; area = orig.area; - counter++; + if(orig.counter) { + counter = orig.counter; + (*counter)++; + } +} + +CppSdlImageHolder& CppSdlImageHolder::operator =(const CppSdlImageHolder& rhs) { + // Check for self-assignment! + if (this == &rhs) // Same object? + return *this; // Yes, so skip assignment, and just return *this. + MakeNull(); + data = rhs.data; + area = rhs.area; + if(rhs.counter) { + counter = rhs.counter; + (*counter)++; + } + return *this; } CppSdlImageHolder::CppSdlImageHolder(char* rawdata, int datasize) { SDL_RWops *rw = SDL_RWFromMem (rawdata, datasize); - //The above might fail an return null. + //The above might fail and return null. if(!rw) { CppSdlException e(IMAGE,CPPSDL_ERROR_NULLPOINTER, "Could not read raw data"); throw e; } - SDL_Surface* data = IMG_Load_RW(rw,false); //the second argument tells the function to three RWops + data = IMG_Load_RW(rw,true); //the second argument tells the function to free RWops if(!data) { - CppSdlException e(IMAGE,CPPSDL_ERROR_DATA,"Could not read raw data"); + CppSdlException e(IMAGE,CPPSDL_ERROR_DATA,"Could not convert raw data to image"); throw e; } SDL_GetClipRect(data,&area); OptimizeForBlit(); - counter = 1; + counter = new int; + *counter = 1; } CppSdlImageHolder::~CppSdlImageHolder() { - counter--; - if(counter == 0) - { - SDL_FreeSurface(data); - data = NULL; + if(!counter) + return; //There are no counter, so already freed + MakeNull(); + if(*counter == 0) { + delete counter; + counter = NULL; } } SDL_Surface* CppSdlImageHolder::GetRawDataInsecure() { + Initialized(); return data; } Uint32 CppSdlImageHolder::GetWidth() { + if(IsNull()) + return 0; return area.w; } Uint32 CppSdlImageHolder::GetHeight() { + if(IsNull()) + return 0; return area.h; } void CppSdlImageHolder::Cut(Uint32 x, Uint32 y, Sint32 w = -1, Sint32 h = -1) { + Initialized(); if(w<0) { w = GetWidth() - x; @@ -111,13 +143,16 @@ void CppSdlImageHolder::Cut(Uint32 x, Uint32 y, Sint32 w = -1, Sint32 h = -1) void CppSdlImageHolder::PaintTo(SDL_Surface* target, int x, int y) { static SDL_Rect dest; //static for reuse + if(IsNull()) + return; dest.x = x; dest.y = y; SDL_BlitSurface(data,&area, target,&dest); } void CppSdlImageHolder::OptimizeForBlit(bool allowAlpha) { - static SDL_Surface tmp; + static SDL_Surface *tmp; + Initialized(); if(allowAlpha) tmp = SDL_DisplayFormatAlpha(data); else @@ -126,19 +161,27 @@ void CppSdlImageHolder::OptimizeForBlit(bool allowAlpha) { data = tmp; } +void CppSdlImageHolder::Initialized() { + if(data == NULL) + throw(CppSdlException(IMAGE,CPPSDL_ERROR_NULLPOINTER,"ImageHolder used uninitialized!")); } -/* - void DrawIMG(SDL_Surface *img, SDL_Surface * target, int x, int y, int w, int h, int x2, int y2) -{ - SDL_Rect dest; - dest.x = x; - dest.y = y; - SDL_Rect dest2; - dest2.x = x2; - dest2.y = y2; - dest2.w = w; - dest2.h = h; - SDL_BlitSurface(img, &dest2, target, &dest); -} - */ \ No newline at end of file +bool CppSdlImageHolder::IsNull() { + if(data == NULL || counter == NULL) + return true; + else + return false; +} + +void CppSdlImageHolder::MakeNull() { + if(IsNull()) + return; + (*counter)--; + if(*counter == 0 && data != NULL) + { + SDL_FreeSurface(data); + data = NULL; + } +} + +} diff --git a/source/code/CppSdl/CppSdlImageHolder.hpp b/source/code/CppSdl/CppSdlImageHolder.hpp index bdcb9e4..73607bf 100644 --- a/source/code/CppSdl/CppSdlImageHolder.hpp +++ b/source/code/CppSdl/CppSdlImageHolder.hpp @@ -16,18 +16,23 @@ namespace CppSdl { class CppSdlImageHolder { public: + CppSdlImageHolder(); CppSdlImageHolder(std::string filename); CppSdlImageHolder(const CppSdlImageHolder& orig); CppSdlImageHolder(char *rawdata, int datasize); virtual ~CppSdlImageHolder(); SDL_Surface *GetRawDataInsecure(); + CppSdlImageHolder & operator=(const CppSdlImageHolder &rhs); void Cut(Uint32 x,Uint32 y,Sint32 w,Sint32 h); Uint32 GetWidth(); Uint32 GetHeight(); void PaintTo(SDL_Surface *target, int x, int y); void OptimizeForBlit(bool allowAlpha = true); + bool IsNull(); + void MakeNull(); private: - Uint32 counter; + void Initialized(); //throws an exception if *data is null + int *counter; SDL_Rect area; SDL_Surface *data; }; diff --git a/source/code/CppSdl/Makefile b/source/code/CppSdl/Makefile index 803910b..37f04b5 100644 --- a/source/code/CppSdl/Makefile +++ b/source/code/CppSdl/Makefile @@ -1,6 +1,8 @@ #CppSdl/Makefile +ifndef CPP CPP=g++ +endif OUTDIR=../build @@ -9,6 +11,8 @@ ODIR=$(OUTDIR)/ BASE_CFLAGS=-c $(shell sdl-config --cflags) BASE_LIBS=$(shell sdl-config --libs) -lSDL_image -lSDL_mixer +DEBUG=1 + #Compile with debug information or optimized. ifeq ($(DEBUG),1) BASE_CFLAGS += -g -DDEBUG=1 diff --git a/source/code/block.make b/source/code/block.make index 6090ab8..b3660ad 100644 --- a/source/code/block.make +++ b/source/code/block.make @@ -2,12 +2,19 @@ GAMEDIR=../../Game/ BINARY=$(GAMEDIR)blockattack +ifndef CC CC=gcc +endif +ifndef CPP CPP=g++ +endif BASE_CFLAGS=-c $(shell sdl-config --cflags) +ifndef BUILDDIR +BUILDDIR=build +endif BASE_LIBS=$(shell sdl-config --libs) -lSDL_image -lSDL_mixer #-lSDL_ttf @@ -37,51 +44,52 @@ endif BASE_LIBS += -lphysfs -$(BINARY): build/main.o build/highscore.o build/SFont.o build/ReadKeyboard.o build/joypad.o build/listFiles.o build/replay.o build/common.o build/stats.o - $(CPP) -O -o $(BINARY) build/main.o build/highscore.o build/SFont.o build/ReadKeyboard.o build/joypad.o build/listFiles.o build/replay.o build/common.o build/stats.o $(BASE_LIBS) +$(BINARY): $(BUILDDIR)/main.o $(BUILDDIR)/highscore.o $(BUILDDIR)/SFont.o $(BUILDDIR)/ReadKeyboard.o $(BUILDDIR)/joypad.o $(BUILDDIR)/listFiles.o $(BUILDDIR)/replay.o $(BUILDDIR)/common.o $(BUILDDIR)/stats.o + @make -C CppSdl + $(CPP) -O -o $(BINARY) $(BUILDDIR)/main.o $(BUILDDIR)/highscore.o $(BUILDDIR)/SFont.o $(BUILDDIR)/ReadKeyboard.o $(BUILDDIR)/joypad.o $(BUILDDIR)/listFiles.o $(BUILDDIR)/replay.o $(BUILDDIR)/common.o $(BUILDDIR)/stats.o $(BUILDDIR)/CppSdlException.o $(BUILDDIR)/CppSdlImageHolder.o $(BASE_LIBS) #-lphysfs -build/main.o: main.cpp mainVars.hpp common.h - $(CPP) $(BASE_CFLAGS) main.cpp -o build/main.o +$(BUILDDIR)/main.o: main.cpp mainVars.hpp common.h + $(CPP) $(BASE_CFLAGS) main.cpp -o $(BUILDDIR)/main.o -build/blockgame.o: BlockGame.hpp BlockGame.cpp - $(CPP) $(BASE_CFLAGS) BlockGame.cpp -o build/blockgame.o +$(BUILDDIR)/blockgame.o: BlockGame.hpp BlockGame.cpp + $(CPP) $(BASE_CFLAGS) BlockGame.cpp -o $(BUILDDIR)/blockgame.o -build/highscore.o: highscore.h highscore.cpp - $(CPP) $(BASE_CFLAGS) highscore.cpp -o build/highscore.o +$(BUILDDIR)/highscore.o: highscore.h highscore.cpp + $(CPP) $(BASE_CFLAGS) highscore.cpp -o $(BUILDDIR)/highscore.o -build/SFont.o: SFont.h SFont.c - $(CC) $(BASE_CFLAGS) SFont.c -o build/SFont.o +$(BUILDDIR)/SFont.o: SFont.h SFont.c + $(CC) $(BASE_CFLAGS) SFont.c -o $(BUILDDIR)/SFont.o -build/ReadKeyboard.o: ReadKeyboard.h ReadKeyboard.cpp - $(CPP) $(BASE_CFLAGS) ReadKeyboard.cpp -o build/ReadKeyboard.o +$(BUILDDIR)/ReadKeyboard.o: ReadKeyboard.h ReadKeyboard.cpp + $(CPP) $(BASE_CFLAGS) ReadKeyboard.cpp -o $(BUILDDIR)/ReadKeyboard.o -build/joypad.o: joypad.h joypad.cpp - $(CPP) $(BASE_CFLAGS) joypad.cpp -o build/joypad.o +$(BUILDDIR)/joypad.o: joypad.h joypad.cpp + $(CPP) $(BASE_CFLAGS) joypad.cpp -o $(BUILDDIR)/joypad.o -build/listFiles.o: listFiles.h listFiles.cpp - $(CPP) $(BASE_CFLAGS) listFiles.cpp -o build/listFiles.o +$(BUILDDIR)/listFiles.o: listFiles.h listFiles.cpp + $(CPP) $(BASE_CFLAGS) listFiles.cpp -o $(BUILDDIR)/listFiles.o -build/replay.o: replay.h replay.cpp - $(CPP) $(BASE_CFLAGS) replay.cpp -o build/replay.o +$(BUILDDIR)/replay.o: replay.h replay.cpp + $(CPP) $(BASE_CFLAGS) replay.cpp -o $(BUILDDIR)/replay.o -build/stats.o: stats.h stats.cc - $(CPP) $(BASE_CFLAGS) stats.cc -o build/stats.o +$(BUILDDIR)/stats.o: stats.h stats.cc + $(CPP) $(BASE_CFLAGS) stats.cc -o $(BUILDDIR)/stats.o -build/common.o: common.h common.cc - $(CPP) $(BASE_CFLAGS) common.cc -o build/common.o +$(BUILDDIR)/common.o: common.h common.cc + $(CPP) $(BASE_CFLAGS) common.cc -o $(BUILDDIR)/common.o -#build/uploadReplay.o: uploadReplay.cc uploadReplay.h -# $(CPP) $(BASE_CFLAGS) uploadReplay.cc -o build/uploadReplay.o +#$(BUILDDIR)/uploadReplay.o: uploadReplay.cc uploadReplay.h +# $(CPP) $(BASE_CFLAGS) uploadReplay.cc -o $(BUILDDIR)/uploadReplay.o -#build/MenuSystem.o: MenuSystem.cc MenuSystem.h -# $(CPP) $(BASE_CFLAGS) MenuSystem.cc -o build/MenuSystem.o +#$(BUILDDIR)/MenuSystem.o: MenuSystem.cc MenuSystem.h +# $(CPP) $(BASE_CFLAGS) MenuSystem.cc -o $(BUILDDIR)/MenuSystem.o -#build/ttfont.o: ttfont.h ttfont.cc -# $(CPP) $(BASE_CFLAGS) ttfont.cc -o build/ttfont.o +#$(BUILDDIR)/ttfont.o: ttfont.h ttfont.cc +# $(CPP) $(BASE_CFLAGS) ttfont.cc -o $(BUILDDIR)/ttfont.o run: $(BINARY) clean: - rm build/*o + rm $(BUILDDIR)/*o diff --git a/source/code/main.cpp b/source/code/main.cpp index 44b7760..770e9fd 100644 --- a/source/code/main.cpp +++ b/source/code/main.cpp @@ -69,6 +69,7 @@ Copyright (C) 2008 Poul Sander //#include "config.h" #include #include +#include "CppSdl/CppSdlImageHolder.hpp" //#include "MenuSystem.h" //if SHAREDIR is not used we look in current directory @@ -166,6 +167,40 @@ SDL_Surface * IMG_Load2(string path) return surface; } +CppSdl::CppSdlImageHolder IMG_Load3(string path) +{ + if (!PHYSFS_exists(path.c_str())) + { + cout << "File not in blockattack.data: " << path << endl; + throw exception(); + } + + PHYSFS_file* myfile = PHYSFS_openRead(path.c_str()); + + // Get the lenght of the file + unsigned int m_size = PHYSFS_fileLength(myfile); + + // Get the file data. + char *m_data = new char[m_size]; + + int length_read = PHYSFS_read (myfile, m_data, 1, m_size); + + if (length_read != (int)m_size) + { + delete [] m_data; + m_data = 0; + PHYSFS_close(myfile); + cout << "Error. Curropt data file!" << endl; + throw exception(); + } + + PHYSFS_close(myfile); + + CppSdl::CppSdlImageHolder surface(m_data, m_size); + + return surface; +} + static void UnloadImages(); static int InitImages(); @@ -453,13 +488,19 @@ static int InitImages() //&& (menuMarked = IMG_Load2((char*)"gfx/menu/marked.png")) //&& (menuUnmarked = IMG_Load2((char*)"gfx/menu/unmarked.png")) //end new in 1.4.0 - && (mouse = IMG_Load2((char*)"gfx/mouse.png")) + //&& (mouse = IMG_Load2((char*)"gfx/mouse.png")) )) //if there was a problem ie. "File not found" { cout << "Error loading image file: " << SDL_GetError() << endl; exit(1); } + try{ + mouse = IMG_Load3("gfx/mouse.png"); + } catch (exception e) { + cout << e.what() << endl; + exit(1); + } //Prepare for fast blittering! @@ -548,7 +589,8 @@ static int InitImages() CONVERTA(iBlueFont); CONVERTA(iSmallFont); CONVERTA(iGameOver); - CONVERTA(mouse); +// CONVERTA(mouse); + mouse.OptimizeForBlit(true); CONVERTA(stageBobble); CONVERTA(transCover); //Editor: @@ -702,7 +744,8 @@ void UnloadImages() SDL_FreeSurface(smiley[2]); SDL_FreeSurface(smiley[3]); SDL_FreeSurface(transCover); - SDL_FreeSurface(mouse); + //SDL_FreeSurface(mouse); + mouse.MakeNull(); } @@ -1763,7 +1806,8 @@ int OpenControlsBox(int x, int y, int player) } } //get mouse state - DrawIMG(mouse,screen,mousex,mousey); + //DrawIMG(mouse,screen,mousex,mousey); + mouse.PaintTo(screen,mousex,mousey); SDL_Flip(screen); } //while !done DrawIMG(background, screen, 0, 0); @@ -2059,7 +2103,8 @@ void OpenScoresDisplay() } } - DrawIMG(mouse,screen,mousex,mousey); + //DrawIMG(mouse,screen,mousex,mousey); + mouse.PaintTo(screen,mousex,mousey); SDL_Flip(screen); //Update screen } @@ -2158,7 +2203,8 @@ bool OpenFileDialogbox(int x, int y, char *name) } } - DrawIMG(mouse,screen,mousex,mousey); + //DrawIMG(mouse,screen,mousex,mousey); + mouse.PaintTo(screen,mousex,mousey); SDL_Flip(screen); //Update screen } } @@ -2255,7 +2301,8 @@ bool SelectThemeDialogbox(int x, int y, char *name) } } - DrawIMG(mouse,screen,mousex,mousey); + //DrawIMG(mouse,screen,mousex,mousey); + mouse.PaintTo(screen,mousex,mousey); SDL_Flip(screen); //Update screen } } @@ -2357,7 +2404,8 @@ bool OpenReplayDialogbox(int x, int y, char *name) } } - DrawIMG(mouse,screen,mousex,mousey); + //DrawIMG(mouse,screen,mousex,mousey); + mouse.PaintTo(screen,mousex,mousey); SDL_Flip(screen); //Update screen } } @@ -2812,7 +2860,8 @@ int PuzzleLevelSelect() } } - DrawIMG(mouse,screen,mousex,mousey); + //DrawIMG(mouse,screen,mousex,mousey); + mouse.PaintTo(screen,mousex,mousey); SDL_Flip(screen); //draws it all to the screen } while (!levelSelected); @@ -2964,7 +3013,8 @@ int StageLevelSelect() string totalString = "Total score: " +itoa(totalScore) + " in " + itoa(totalTime/1000/60) + " : " + itoa2((totalTime/1000)%60); SFont_Write(screen,fBlueFont,200,600,totalString.c_str()); - DrawIMG(mouse,screen,mousex,mousey); + //DrawIMG(mouse,screen,mousex,mousey); + mouse.PaintTo(screen,mousex,mousey); SDL_Flip(screen); //draws it all to the screen } while (!levelSelected); @@ -3046,7 +3096,8 @@ int startSingleVs() SDL_GetMouseState(&mousex,&mousey); DrawIMG(background, screen, 0, 0); - DrawIMG(mouse,screen,mousex,mousey); + //DrawIMG(mouse,screen,mousex,mousey); + mouse.PaintTo(screen,mousex,mousey); SDL_Flip(screen); //draws it all to the screen }while (!done); @@ -3186,7 +3237,8 @@ void startVsMenu() done = true; } - DrawIMG(mouse,screen,mousex,mousey); + //DrawIMG(mouse,screen,mousex,mousey); + mouse.PaintTo(screen,mousex,mousey); SDL_Flip(screen); //draws it all to the screen SDL_Delay(10); @@ -4843,7 +4895,8 @@ int main(int argc, char *argv[]) oldMousex = mousex; oldMousey = mousey; //Draw the mouse: - DrawIMG(mouse,screen,mousex,mousey); + //DrawIMG(mouse,screen,mousex,mousey); + mouse.PaintTo(screen,mousex,mousey); SDL_Flip(screen); } //game loop diff --git a/source/code/mainVars.hpp b/source/code/mainVars.hpp index 67a4b4b..95addc7 100644 --- a/source/code/mainVars.hpp +++ b/source/code/mainVars.hpp @@ -147,7 +147,8 @@ static SDL_Surface *bNext; //SDL_Surface *menuMarked; //SDL_Surface *menuUnmarked; //end new in 1.4.0 -static SDL_Surface *mouse; //The mouse cursor +//static SDL_Surface *mouse; //The mouse cursor +static CppSdl::CppSdlImageHolder mouse; static SDL_Surface *tmp; //a temporary surface to use DisplayFormat