commit 8d488d32
Startet to refactor some surface handling
git-svn-id: https://blockattack.svn.sourceforge.net/svnroot/blockattack/trunk@109 9d7177f8-192b-0410-8f35-a16a89829b06
Changed files
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 <vector>
#include <SDL/SDL_timer.h>
+#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