diff --git a/README.md b/README.md index 63550a1..c09b81c 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ This game is inspired by classic 2D RPGs (Final Fantasy, The Legend of Zelda), a ## External Dependencies -* [SDL 1.2](http://www.libsdl.org/) - Simple DirectMedia Layer API +* [SDL 2.0](http://www.libsdl.org/) - Simple DirectMedia Layer API * [SDL_net 2.0](http://www.libsdl.org/projects/SDL_net/) - SDL's networking extension * [lua 5.2](http://www.lua.org/) - The lua programming language * [SQLite3](http://www.sqlite.org/) - A lightweight SQL database engine diff --git a/client/base_scene.cpp b/client/base_scene.cpp index 816f80b..7b6a515 100644 --- a/client/base_scene.cpp +++ b/client/base_scene.cpp @@ -21,91 +21,59 @@ */ #include "base_scene.hpp" -#include - -//------------------------- -//Static declarations -//------------------------- - -SDL_Surface* BaseScene::screen = nullptr; - -//------------------------- -//Public access members -//------------------------- +SDL_Renderer* BaseScene::rendererHandle = nullptr; BaseScene::BaseScene() { - // + //EMPTY } BaseScene::~BaseScene() { - // + //EMPTY } -//------------------------- -//Program control -//------------------------- - -SDL_Surface* BaseScene::SetScreen(int w, int h, int bpp, Uint32 flags) { - if (!bpp) { - bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel; - } - - screen = SDL_SetVideoMode(w, h, bpp, flags); - - if (!screen) { - throw(std::runtime_error("Failed to create the screen surface")); - } - - return screen; -} - -SDL_Surface* BaseScene::GetScreen() { - return screen; -} - -SceneList BaseScene::SetNextScene(SceneList sceneIndex) { - return nextScene = sceneIndex; -} - -SceneList BaseScene::GetNextScene() const { - return nextScene; -} - -//------------------------- -//Frame loop -//------------------------- - void BaseScene::RunFrame() { FrameStart(); - HandleEvents(); + ProcessEvents(); Update(); FrameEnd(); } -void BaseScene::RenderFrame() { - SDL_FillRect(screen, 0, 0); - Render(screen); - SDL_Flip(screen); - SDL_Delay(10); +void BaseScene::RenderFrame(SDL_Renderer* renderer) { + //EMPTY +} + +void BaseScene::SetRenderer(SDL_Renderer* r) { + rendererHandle = r; +} + +SDL_Renderer* BaseScene::GetRenderer() { + return rendererHandle; +} + +void BaseScene::SetSceneSignal(SceneSignal signal) { + sceneSignal = signal; +} + +SceneSignal BaseScene::GetSceneSignal() { + return sceneSignal; } //------------------------- -//Event handlers +//frame phases //------------------------- -void BaseScene::HandleEvents() { - SDL_Event event; +void BaseScene::FrameStart() { + //EMPTY +} +void BaseScene::ProcessEvents() { + SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: QuitEvent(); break; - case SDL_VIDEORESIZE: - SetScreen(event.resize.w, event.resize.h, 0, screen->flags); - break; - case SDL_MOUSEMOTION: MouseMotion(event.motion); break; @@ -126,15 +94,52 @@ void BaseScene::HandleEvents() { KeyUp(event.key); break; -#ifdef USE_EVENT_JOYSTICK - //EMPTY -#endif - -#ifdef USE_EVENT_UNKNOWN - default: - UnknownEvent(event); - break; -#endif - }//switch - }//while + //TODO: joystick and controller events + } + } +} + +void BaseScene::Update() { + //EMPTY +} + +void BaseScene::FrameEnd() { + //EMPTY +} + +//------------------------- +//input events +//------------------------- + +void BaseScene::QuitEvent() { + sceneSignal = SceneSignal::QUIT; +} + +void BaseScene::MouseMotion(SDL_MouseMotionEvent const& event) { + //EMPTY +} + +void BaseScene::MouseButtonDown(SDL_MouseButtonEvent const& event) { + //EMPTY +} + +void BaseScene::MouseButtonUp(SDL_MouseButtonEvent const& event) { + //EMPTY +} + +void BaseScene::MouseWheel(SDL_MouseWheelEvent const& event) { + //EMPTY +} + +void BaseScene::KeyDown(SDL_KeyboardEvent const& event) { + //preference as a default + switch(event.keysym.sym) { + case SDLK_ESCAPE: + QuitEvent(); + break; + } +} + +void BaseScene::KeyUp(SDL_KeyboardEvent const& event) { + //EMPTY } diff --git a/client/base_scene.hpp b/client/base_scene.hpp index 4292e6f..c2ad641 100644 --- a/client/base_scene.hpp +++ b/client/base_scene.hpp @@ -21,51 +21,44 @@ */ #pragma once -#include "scene_list.hpp" +#include "scene_signal.hpp" -#include "SDL/SDL.h" +#include "SDL2/SDL.h" class BaseScene { public: - //Public access members BaseScene(); virtual ~BaseScene(); - //Program control - static SDL_Surface* SetScreen(int w, int h, int bpp = 0, Uint32 flags = SDL_HWSURFACE|SDL_DOUBLEBUF); - static SDL_Surface* GetScreen(); - - SceneList SetNextScene(SceneList sceneIndex); - SceneList GetNextScene() const; - - //Frame loop virtual void RunFrame(); - virtual void RenderFrame(); + virtual void RenderFrame(SDL_Renderer*); + + static void SetRenderer(SDL_Renderer*); + SceneSignal GetSceneSignal(); protected: - virtual void FrameStart() {} - virtual void HandleEvents(); - virtual void Update() {} - virtual void FrameEnd() {} - virtual void Render(SDL_Surface* const screen) {} + //control + static SDL_Renderer* GetRenderer(); + void SetSceneSignal(SceneSignal); - //Event handlers - virtual void QuitEvent() { SetNextScene(SceneList::QUIT); } - virtual void MouseMotion(SDL_MouseMotionEvent const&) {} - virtual void MouseButtonDown(SDL_MouseButtonEvent const&) {} - virtual void MouseButtonUp(SDL_MouseButtonEvent const&) {} - virtual void KeyDown(SDL_KeyboardEvent const&) {} - virtual void KeyUp(SDL_KeyboardEvent const&) {} + //frame phases + virtual void FrameStart(); + virtual void ProcessEvents(); + virtual void Update(); + virtual void FrameEnd(); -#ifdef USE_EVENT_JOYSTICK - //EMPTY -#endif + //input events + virtual void QuitEvent(); + virtual void MouseMotion(SDL_MouseMotionEvent const& event); + virtual void MouseButtonDown(SDL_MouseButtonEvent const& event); + virtual void MouseButtonUp(SDL_MouseButtonEvent const& event); + virtual void MouseWheel(SDL_MouseWheelEvent const& event); + virtual void KeyDown(SDL_KeyboardEvent const& event); + virtual void KeyUp(SDL_KeyboardEvent const& event); -#ifdef USE_EVENT_UNKNOWN - virtual void UnknownEvent(SDL_Event const&) {} -#endif + //TODO: joystick and controller events private: - static SDL_Surface* screen; - SceneList nextScene = SceneList::CONTINUE; -}; + static SDL_Renderer* rendererHandle; + SceneSignal sceneSignal = SceneSignal::CONTINUE; +}; \ No newline at end of file diff --git a/client/scene_list.hpp b/client/scene_signal.hpp similarity index 84% rename from client/scene_list.hpp rename to client/scene_signal.hpp index 42990ae..a2cb2df 100644 --- a/client/scene_list.hpp +++ b/client/scene_signal.hpp @@ -21,17 +21,12 @@ */ #pragma once -enum class SceneList { - //these are reserved - QUIT, - CONTINUE, - FIRST, +enum SceneSignal { + //reserved members for internal use + QUIT = -1, + CONTINUE = 0, + FIRST = 1, - //custom indexes - SPLASHSCREEN, - MAINMENU, - OPTIONSMENU, - LOBBYMENU, - WORLD, - DISCONNECTEDSCREEN, -}; + //custom scenes + EXAMPLE_SCENE +}; \ No newline at end of file diff --git a/common/graphics/image.cpp b/common/graphics/image.cpp index 4089814..bd9e662 100644 --- a/common/graphics/image.cpp +++ b/common/graphics/image.cpp @@ -21,8 +21,10 @@ */ #include "image.hpp" -#include +#include "SDL2/SDL_image.h" + #include +#include Image& Image::operator=(Image const& rhs) { //don't screw yourself @@ -30,10 +32,10 @@ Image& Image::operator=(Image const& rhs) { return *this; } - FreeSurface(); + Free(); //Copy the other Image's stuff - surface = rhs.surface; + texture = rhs.texture; clip = rhs.clip; local = false; } @@ -44,102 +46,139 @@ Image& Image::operator=(Image&& rhs) { return *this; } - FreeSurface(); + Free(); //Steal the other Image's stuff - surface = rhs.surface; + texture = rhs.texture; clip = rhs.clip; local = rhs.local; - rhs.surface = nullptr; + rhs.texture = nullptr; rhs.clip = {0, 0, 0, 0}; rhs.local = false; } -SDL_Surface* Image::LoadSurface(std::string fname) { - FreeSurface(); - SDL_Surface* p = SDL_LoadBMP(fname.c_str()); - if (!p) { - std::ostringstream os; - os << "Failed to load file: " << fname; - throw(std::runtime_error(os.str())); +SDL_Texture* Image::Load(SDL_Renderer* renderer, std::string fname) { + Free(); + + //load the file into a surface + SDL_Surface* surface = IMG_Load(fname.c_str()); + if (!surface) { + std::ostringstream msg; + msg << "Failed to load an image file: " << fname; + msg << "; " << IMG_GetError(); + throw(std::runtime_error(msg.str())); + } + + //create a texture from this surface + texture = SDL_CreateTextureFromSurface(renderer, surface); + if (!texture) { + std::ostringstream msg; + msg << "Failed to convert a newly loaded image file: " << fname; + msg << "; " << SDL_GetError(); + throw(std::runtime_error(msg.str())); + } + + //set the metadata + clip.x = 0; + clip.y = 0; + if (SDL_QueryTexture(texture, nullptr, nullptr, &clip.w, &clip.h)) { + std::ostringstream msg; + msg << "Failed to record metadata for a newly loaded image file: " << fname; + msg << "; " << SDL_GetError(); + throw(std::runtime_error(msg.str())); } - surface = p; - clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h}; local = true; - SetTransparentColor(255, 0, 255); //default - return surface; + + //free the surface & return + SDL_FreeSurface(surface); + return texture; } -SDL_Surface* Image::CreateSurface(Uint16 w, Uint16 h) { - FreeSurface(); - Uint32 rmask, gmask, bmask, amask; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - rmask = 0xff000000; - gmask = 0x00ff0000; - bmask = 0x0000ff00; - amask = 0x000000ff; -#else - rmask = 0x000000ff; - gmask = 0x0000ff00; - bmask = 0x00ff0000; - amask = 0xff000000; -#endif - SDL_Surface* p = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, rmask, gmask, bmask, amask); - if (!p) { - throw(std::runtime_error("Failed to create Image surface")); +SDL_Texture* Image::Create(SDL_Renderer* renderer, Uint16 w, Uint16 h) { + Free(); + + //make the texture + texture = SDL_CreateTexture(renderer, + SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_STATIC, + w, h); + + if (!texture) { + std::ostringstream msg; + msg << "Failed to create a texture; " << SDL_GetError(); + throw(std::runtime_error(msg.str())); + } + + //set the metadata + clip.x = 0; + clip.y = 0; + if (SDL_QueryTexture(texture, nullptr, nullptr, &clip.w, &clip.h)) { + std::ostringstream msg; + msg << "Failed to record metadata for a newly created image"; + msg << "; " << SDL_GetError(); + throw(std::runtime_error(msg.str())); } - surface = p; - clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h}; local = true; - SetTransparentColor(255, 0, 255); //default - return surface; + + return texture; } -SDL_Surface* Image::SetSurface(SDL_Surface* p) { - FreeSurface(); - if (!p) { - throw(std::invalid_argument("No surface pointer provided")); +SDL_Texture* Image::SetTexture(SDL_Texture* ptr) { + Free(); + + texture = ptr; + + //set the metadata + clip.x = 0; + clip.y = 0; + if (SDL_QueryTexture(texture, nullptr, nullptr, &clip.w, &clip.h)) { + std::ostringstream msg; + msg << "Failed to record metadata for a newly image image"; + msg << "; " << SDL_GetError(); + throw(std::runtime_error(msg.str())); } - surface = p; - clip = {0, 0, (Uint16)surface->w, (Uint16)surface->h}; local = false; - return surface; + + return texture; } -void Image::FreeSurface() { +SDL_Texture* Image::GetTexture() const { + return texture; +} + +void Image::Free() { if (local) { - SDL_FreeSurface(surface); + SDL_DestroyTexture(texture); local = false; } - surface = nullptr; + texture = nullptr; clip = {0, 0, 0, 0}; } -void Image::DrawTo(SDL_Surface* dest, Sint16 x, Sint16 y) { - if (!surface) { - throw(std::logic_error("No image surface to draw")); +void Image::DrawTo(SDL_Renderer* const renderer, Sint16 x, Sint16 y, double scaleX, double scaleY) { + if (!texture) { + throw(std::logic_error("No image texture to draw")); } - SDL_Rect sclip = clip, dclip = {x,y}; - SDL_BlitSurface(surface, &sclip, dest, &dclip); + SDL_Rect sclip = clip; + SDL_Rect dclip = {x, y, Uint16(clip.w * scaleX), Uint16(clip.h * scaleY)}; + SDL_RenderCopy(renderer, texture, &sclip, &dclip); } -void Image::SetTransparentColor(Uint8 r, Uint8 g, Uint8 b) { - if (!surface) { - throw(std::logic_error("Failed to set the transparent color")); +void Image::SetAlpha(Uint8 a) { + if (SDL_SetTextureAlphaMod(texture, a)) { + std::ostringstream msg; + msg << "Failed to set alpha; " << SDL_GetError(); + throw(std::runtime_error(msg.str())); } - if (!local) { - throw(std::logic_error("Cannot set the transparent color of a non-local surface")); - } - SDL_SetColorKey(surface, SDL_SRCCOLORKEY, SDL_MapRGB(surface->format, r, g, b)); } -void Image::ClearTransparentColor() { - if (!surface) { - throw(std::logic_error("Failed to clear the transparent color")); +Uint8 Image::GetAlpha() { + Uint8 ret = 0; + if (SDL_GetTextureAlphaMod(texture, &ret)) { + std::ostringstream msg; + msg << "Failed to get alpha; " << SDL_GetError(); + throw(std::runtime_error(msg.str())); } - if (!local) { - throw(std::logic_error("Cannot clear the transparent color of a non-local surface")); - } - SDL_SetColorKey(surface, 0, 0); -} + return ret; +} \ No newline at end of file diff --git a/common/graphics/image.hpp b/common/graphics/image.hpp index 324ae59..f6685e4 100644 --- a/common/graphics/image.hpp +++ b/common/graphics/image.hpp @@ -21,7 +21,8 @@ */ #pragma once -#include "SDL/SDL.h" +#include "SDL2/SDL.h" + #include class Image { @@ -29,21 +30,24 @@ public: Image() = default; Image(Image const& rhs) { *this = rhs; } Image(Image&& rhs) { *this = std::move(rhs); } - Image(std::string fname) { LoadSurface(fname); } - Image(Uint16 w, Uint16 h) { CreateSurface(w, h); } - Image(SDL_Surface* p) { SetSurface(p); } - ~Image() { FreeSurface(); } + Image(SDL_Renderer* r, std::string fname) { Load(r, fname); } + Image(SDL_Renderer* r, Uint16 w, Uint16 h) { Create(r, w, h); } + Image(SDL_Texture* p) { SetTexture(p); } + virtual ~Image() { Free(); } Image& operator=(Image const&); Image& operator=(Image&&); - SDL_Surface* LoadSurface(std::string fname); - SDL_Surface* CreateSurface(Uint16 w, Uint16 h); - SDL_Surface* SetSurface(SDL_Surface*); - SDL_Surface* GetSurface() const { return surface; } - void FreeSurface(); + SDL_Texture* Load(SDL_Renderer* renderer, std::string fname); + SDL_Texture* Create(SDL_Renderer* renderer, Uint16 w, Uint16 h); + SDL_Texture* SetTexture(SDL_Texture*); + SDL_Texture* GetTexture() const; + virtual void Free(); - void DrawTo(SDL_Surface* const, Sint16 x, Sint16 y); + void DrawTo(SDL_Renderer* const, Sint16 x, Sint16 y, double scaleX = 1.0, double scaleY = 1.0); + + void SetAlpha(Uint8 a); + Uint8 GetAlpha(); //Clip handlers SDL_Rect SetClip(SDL_Rect r) { return clip = r; } @@ -61,10 +65,8 @@ public: bool GetLocal() const { return local; } - void SetTransparentColor(Uint8 r, Uint8 g, Uint8 b); - void ClearTransparentColor(); protected: - SDL_Surface* surface = nullptr; + SDL_Texture* texture = nullptr; SDL_Rect clip = {0, 0, 0, 0}; bool local = false; -}; +}; \ No newline at end of file diff --git a/common/graphics/sprite_sheet.cpp b/common/graphics/sprite_sheet.cpp index 93c1984..b0db04d 100644 --- a/common/graphics/sprite_sheet.cpp +++ b/common/graphics/sprite_sheet.cpp @@ -21,82 +21,166 @@ */ #include "sprite_sheet.hpp" -#include #include +#include + +SpriteSheet& SpriteSheet::operator=(SpriteSheet const& rhs) { + //don't screw yourself + if (this == &rhs) { + return *this; + } + + Free(); + + //Copy the other SpriteSheet's stuff + texture = rhs.texture; + clip = rhs.clip; + local = false; + countX = rhs.countX; + countY = rhs.countY; + indexX = rhs.indexX; + indexY = rhs.indexY; + delay = rhs.delay; + tick = rhs.tick; +} + +SpriteSheet& SpriteSheet::operator=(SpriteSheet&& rhs) { + //don't screw yourself + if (this == &rhs) { + return *this; + } + + Free(); + + //Steal the other SpriteSheet's stuff + texture = rhs.texture; + clip = rhs.clip; + local = rhs.local; + countX = rhs.countX; + countY = rhs.countY; + indexX = rhs.indexX; + indexY = rhs.indexY; + delay = rhs.delay; + tick = rhs.tick; + + rhs.texture = nullptr; + rhs.clip = {0, 0, 0, 0}; + rhs.local = false; + rhs.countX = 0; + rhs.countY = 0; + rhs.indexX = 0; + rhs.indexY = 0; + rhs.delay = 0.0; + rhs.tick = 0.0; +} void SpriteSheet::Update(double delta) { + //if the delay has passed if (delay && (tick += delta) >= delay) { - if (++xIndex >= xCount) { - xIndex = 0; + //if the index is out of bounds + if (++indexX >= countX) { + indexX = 0; } tick = 0; } - image.SetClipX(xIndex * image.GetClipW()); - image.SetClipY(yIndex * image.GetClipH()); + //modify area drawn + clip.x = indexX * clip.w; + clip.y = indexX * clip.y; } -SDL_Surface* SpriteSheet::LoadSurface(std::string fname, Uint16 xCellCount, Uint16 yCellCount) { - image.LoadSurface(fname); +SDL_Texture* SpriteSheet::Load(SDL_Renderer* r, std::string fname, Uint16 cx, Uint16 cy) { + //call the base function + Image::Load(r, fname); - xCount = xCellCount; - yCount = yCellCount; + //set the metadata + countX = cx; + countY = cy; - image.SetClipW(image.GetSurface()->w / xCount); - image.SetClipH(image.GetSurface()->h / yCount); + //assume clip.x and clip.y were set to the size of the texture + //reduce the w & h to the size of one cell + clip.w = clip.w / countX; + clip.h = clip.h / countY; - xIndex = yIndex = 0; + indexX = indexY = 0; + delay = tick = 0.0; + + return texture; +} + +SDL_Texture* SpriteSheet::Create(SDL_Renderer* r, Uint16 w, Uint16 h, Uint16 cx, Uint16 cy) { + //call the base function + Image::Create(r, w, h); + + //set the metadata + countX = cx; + countY = cy; + + //assume clip.x and clip.y were set to the size of the texture + //reduce the w & h to the size of one cell + clip.w = clip.w / countX; + clip.h = clip.h / countY; + + indexX = indexY = 0; + delay = tick = 0.0; + + return texture; +} + +SDL_Texture* SpriteSheet::SetTexture(SDL_Texture* ptr, Uint16 cx, Uint16 cy) { + //call the base function + Image::SetTexture(ptr); + + //set the metadata + countX = cx; + countY = cy; + + //assume clip.x and clip.y were set to the size of the texture + //reduce the w & h to the size of one cell + clip.w = clip.w / countX; + clip.h = clip.h / countY; + + indexX = indexY = 0; + delay = tick = 0.0; + + return texture; +} + +void SpriteSheet::Free() { + Image::Free(); + countX = countY = 0; + indexX = indexY = 0; delay = tick = 0.0; } -SDL_Surface* SpriteSheet::SetSurface(SDL_Surface* surface, Uint16 xCellCount, Uint16 yCellCount) { - image.SetSurface(surface); - - xCount = xCellCount; - yCount = yCellCount; - - image.SetClipW(image.GetSurface()->w / xCount); - image.SetClipH(image.GetSurface()->h / yCount); - - xIndex = yIndex = 0; - delay = tick = 0.0; +Uint16 SpriteSheet::SetCountX(Uint16 i) { + indexX = 0; + return countX = i; } -void SpriteSheet::FreeSurface() { - image.FreeSurface(); - xCount = yCount = 0; - xIndex = yIndex = 0; - delay = tick = 0.0; +Uint16 SpriteSheet::SetCountY(Uint16 i) { + indexY = 0; + return countY = i; } -Uint16 SpriteSheet::SetXCount(Uint16 i) { - xIndex = 0; - return xCount = i; -} - -Uint16 SpriteSheet::SetYCount(Uint16 i) { - yIndex = 0; - return yCount = i; -} - -Uint16 SpriteSheet::SetXIndex(Uint16 i) { - if (i > xCount) { - std::ostringstream os; - os << "Cannot set x index to " << i; - throw(std::invalid_argument(os.str())); +Uint16 SpriteSheet::SetIndexX(Uint16 i) { + if (i > countX) { + std::ostringstream msg; + msg << "Cannot set index 'x' to " << i; + throw(std::out_of_range(msg.str())); } - return xIndex = i; + return indexX = i; } -Uint16 SpriteSheet::SetYIndex(Uint16 i) { - if (i > yCount) { - std::ostringstream os; - os << "Cannot set y index to " << i; - throw(std::invalid_argument(os.str())); +Uint16 SpriteSheet::SetIndexY(Uint16 i) { + if (i > countY) { + std::ostringstream msg; + msg << "Cannot set index 'y' to " << i; + throw(std::invalid_argument(msg.str())); } - return yIndex = i; + return indexY = i; } double SpriteSheet::SetDelay(double d) { tick = 0; return delay = d; -} +} \ No newline at end of file diff --git a/common/graphics/sprite_sheet.hpp b/common/graphics/sprite_sheet.hpp index 2eb3238..395cfe3 100644 --- a/common/graphics/sprite_sheet.hpp +++ b/common/graphics/sprite_sheet.hpp @@ -23,41 +23,48 @@ #include "image.hpp" -class SpriteSheet { +class SpriteSheet : public Image { public: SpriteSheet() = default; - SpriteSheet(std::string fname, Uint16 xCellCount, Uint16 yCellCount) { LoadSurface(fname, xCellCount, yCellCount); } - SpriteSheet(SDL_Surface* surface, Uint16 xCellCount, Uint16 yCellCount) { SetSurface(surface, xCellCount, yCellCount); } - ~SpriteSheet() { FreeSurface(); }; + SpriteSheet(SpriteSheet const& rhs) { *this = rhs; } + SpriteSheet(SpriteSheet&& rhs) { *this = std::move(rhs); } + SpriteSheet(SDL_Renderer* r, std::string fname, Uint16 cx, Uint16 cy) + { Load(r, fname, cx, cy); } + SpriteSheet(SDL_Renderer* r, Uint16 w, Uint16 h, Uint16 cx, Uint16 cy) + { Create(r, w, h, cx, cy); } + SpriteSheet(SDL_Texture* p, Uint16 cx, Uint16 cy) + { SetTexture(p, cx, cy); } + ~SpriteSheet() = default; + + SpriteSheet& operator=(SpriteSheet const&); + SpriteSheet& operator=(SpriteSheet&&); void Update(double delta); - SDL_Surface* LoadSurface(std::string fname, Uint16 xCellCount, Uint16 yCellCount); - SDL_Surface* SetSurface(SDL_Surface* surface, Uint16 xCellCount, Uint16 yCellCount); - SDL_Surface* GetSurface() { return image.GetSurface(); } - void FreeSurface(); + SDL_Texture* Load(SDL_Renderer*, std::string fname, Uint16 cx, Uint16 cy); + SDL_Texture* Create(SDL_Renderer*, Uint16 w, Uint16 h, Uint16 cx, Uint16 cy); + SDL_Texture* SetTexture(SDL_Texture*, Uint16 cx, Uint16 cy); + void Free() override; - void DrawTo(SDL_Surface* const dest, Sint16 x, Sint16 y) { image.DrawTo(dest, x, y); } + Uint16 SetCountX(Uint16); + Uint16 SetCountY(Uint16); + Uint16 SetIndexX(Uint16); + Uint16 SetIndexY(Uint16); - //accessors and mutators - Image* GetImage() { return ℑ } //OO breaker - - Uint16 SetXCount(Uint16); - Uint16 SetYCount(Uint16); - Uint16 SetXIndex(Uint16); - Uint16 SetYIndex(Uint16); - - Uint16 GetXCount() const { return xCount; } - Uint16 GetYCount() const { return yCount; } - Uint16 GetXIndex() const { return xIndex; } - Uint16 GetYIndex() const { return yIndex; } + Uint16 GetCountX() const { return countX; } + Uint16 GetCountY() const { return countY; } + Uint16 GetIndexX() const { return indexX; } + Uint16 GetIndexY() const { return indexY; } double SetDelay(double d); double GetDelay() const { return delay; } private: - Image image; - Uint16 xCount = 0, yCount = 0; //number of cells - Uint16 xIndex = 0, yIndex = 0; //current cell being drawn + Uint16 countX = 0, countY = 0, indexX = 0, indexY = 0; double delay = 0.0, tick = 0.0; -}; + + //disable access + using Image::Load; + using Image::Create; + using Image::SetTexture; +}; \ No newline at end of file diff --git a/common/graphics/tile_sheet.cpp b/common/graphics/tile_sheet.cpp index 6f47337..137b77a 100644 --- a/common/graphics/tile_sheet.cpp +++ b/common/graphics/tile_sheet.cpp @@ -21,28 +21,71 @@ */ #include "tile_sheet.hpp" -void TileSheet::Load(std::string fname, int tileWidth, int tileHeight) { - image.LoadSurface(fname); - image.SetClipW(tileWidth); - image.SetClipH(tileHeight); - xCount = image.GetSurface()->w / image.GetClipW(); - yCount = image.GetSurface()->h / image.GetClipH(); +TileSheet& TileSheet::operator=(TileSheet const& rhs) { + //don't screw yourself + if (this == &rhs) { + return *this; + } + + Free(); + + //Copy the other TileSheet's stuff + texture = rhs.texture; + clip = rhs.clip; + local = false; + countX = rhs.countX; + countY = rhs.countY; } -void TileSheet::Unload() { - image.FreeSurface(); - xCount = yCount = 0; +TileSheet& TileSheet::operator=(TileSheet&& rhs) { + //don't screw yourself + if (this == &rhs) { + return *this; + } + + Free(); + + //Copy the other TileSheet's stuff + texture = rhs.texture; + clip = rhs.clip; + local = false; + countX = rhs.countX; + countY = rhs.countY; + + rhs.texture = nullptr; + rhs.clip = {0, 0, 0, 0}; + rhs.local = false; + rhs.countX = 0; + rhs.countY = 0; } -void TileSheet::DrawTileTo(SDL_Surface* const dest, int x, int y, Region::type_t tile) { - //0 is invisible - if (tile == 0) return; - image.SetClipX((tile-1) % xCount * image.GetClipW()); - image.SetClipY((tile-1) / xCount * image.GetClipH()); - image.DrawTo(dest, x, y); +void TileSheet::Load(SDL_Renderer* renderer, std::string fname, int tileWidth, int tileHeight) { + Image::Load(renderer, fname); + countX = clip.w / tileWidth; + countY = clip.h / tileHeight; + clip.w = tileWidth; + clip.h = tileHeight; } -void TileSheet::DrawRegionTo(SDL_Surface* const dest, Region* const region, int camX, int camY) { +SDL_Texture* TileSheet::SetTexture(SDL_Texture* ptr, int tileWidth, int tileHeight) { + Image::SetTexture(ptr); + countX = clip.w / tileWidth; + countY = clip.h / tileHeight; + clip.w = tileWidth; + clip.h = tileHeight; +} + +void TileSheet::Free() { + Image::Free(); + countX = countY = 0; +} + +void TileSheet::DrawLayerTo(SDL_Renderer* const renderer, Region* const region, int layer, int camX, int camY, double scaleX, double scaleY) { + //TODO: empty +} + +void TileSheet::DrawRegionTo(SDL_Renderer* const renderer, Region* const region, int camX, int camY, double scaleX, double scaleY) { + //TODO: (2) make TileSheet a friend class of Region Region::type_t tile = 0; for (register int i = 0; i < REGION_WIDTH; ++i) { for (register int j = 0; j < REGION_HEIGHT; ++j) { @@ -50,12 +93,14 @@ void TileSheet::DrawRegionTo(SDL_Surface* const dest, Region* const region, int tile = region->GetTile(i, j, k); //0 is invisible if (tile == 0) continue; - image.SetClipX((tile-1) % xCount * image.GetClipW()); - image.SetClipY((tile-1) / xCount * image.GetClipH()); - image.DrawTo(dest, - (region->GetX() + i) * image.GetClipW() - camX, - (region->GetY() + j) * image.GetClipH() - camY); + clip.x = (tile-1) % countX * clip.h; + clip.y = (tile-1) / countX * clip.w; + //TODO: (2) raw rendering; improve preformance + Image::DrawTo(renderer, + (region->GetX() + i) * clip.w - camX, + (region->GetY() + j) * clip.h - camY, + scaleX, scaleY); } } } -} \ No newline at end of file +} diff --git a/common/graphics/tile_sheet.hpp b/common/graphics/tile_sheet.hpp index 8ac142f..f327151 100644 --- a/common/graphics/tile_sheet.hpp +++ b/common/graphics/tile_sheet.hpp @@ -27,25 +27,41 @@ #include -class TileSheet { +class TileSheet : public Image { public: TileSheet() = default; - TileSheet(std::string f, int w, int h) { Load(f, w, h); } + TileSheet(TileSheet const& rhs) { *this = rhs; } + TileSheet(TileSheet&& rhs) { *this = std::move(rhs); } + TileSheet(SDL_Renderer* r, std::string fn, int tw, int th) { Load(r, fn, tw, th); } + TileSheet(SDL_Texture* p, int tw, int th) { SetTexture(p, tw, th); } ~TileSheet() = default; - void Load(std::string fname, int tileWidth, int tileHeight); - void Unload(); + TileSheet& operator=(TileSheet const&); + TileSheet& operator=(TileSheet&&); - void DrawTileTo(SDL_Surface* const dest, int x, int y, Region::type_t tile); - void DrawRegionTo(SDL_Surface* const dest, Region* const region, int camX, int camY); + void Load(SDL_Renderer*, std::string fname, int tileWidth, int tileHeight); + SDL_Texture* SetTexture(SDL_Texture*, int tileWidth, int tileHeight); + void Free() override; + + void DrawLayerTo(SDL_Renderer* const renderer, Region* const region, int layer, int camX, int camY, double scaleX = 1.0, double scaleY = 1.0); + void DrawRegionTo(SDL_Renderer* const renderer, Region* const region, int camX, int camY, double scaleX = 1.0, double scaleY = 1.0); //accessors - Image* GetImage() { return ℑ } - int GetXCount() { return xCount; } - int GetYCount() { return yCount; } - int GetTileW() { return image.GetClipW(); } - int GetTileH() { return image.GetClipH(); } -private: - Image image; - int xCount = 0, yCount = 0; + //DOCS: reuse Image::clip for tile sizes + int GetCountX() { return countX; } + int GetCountY() { return countY; } + int GetTileW() { return clip.w; } + int GetTileH() { return clip.h; } + +protected: + int countX = 0, countY = 0; + + using Image::Load; + using Image::Create; + using Image::SetTexture; + using Image::SetClip; + using Image::SetClipX; + using Image::SetClipY; + using Image::SetClipW; + using Image::SetClipH; }; diff --git a/common/makefile b/common/makefile index e2d1029..59bcb4f 100644 --- a/common/makefile +++ b/common/makefile @@ -4,5 +4,5 @@ all: $(MAKE) -C graphics $(MAKE) -C map $(MAKE) -C network - $(MAKE) -C ui +# $(MAKE) -C ui #TODO: reenable this $(MAKE) -C utilities diff --git a/common/utilities/config_utility.cpp b/common/utilities/config_utility.cpp index 832680e..3161501 100644 --- a/common/utilities/config_utility.cpp +++ b/common/utilities/config_utility.cpp @@ -61,7 +61,7 @@ void ConfigUtility::Load(std::string fname, bool skipMissingFile, int argc, char memset(key, 0, 256); //read the key-value pair - if (sscanf(argv[i], "-%[^=]=%[^\0]", key, val) != 2) { + if (sscanf(argv[i], "-%[^=]=%[^\\0]", key, val) != 2) { std::ostringstream os; os << "Failed to read a command line config argument (expected -%s=%s):" << std::endl; os << "\targv[" << i << "]: " << argv[i] << std::endl;