From 3fa9af58bc907048a8ccadc2bef7736ec554a09d Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Tue, 5 Jun 2018 21:02:51 -0400 Subject: refactored so that the renderer is its own class --- src/main.cpp | 522 ++--------------------------------------------------------- 1 file changed, 15 insertions(+), 507 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 03e7cda..8f20635 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,455 +1,9 @@ -#include -#include -#include -#include #include -#include -#include #include #include -#include -#include #include "util.h" -#include "map.h" - -class sdl_error : public std::logic_error { -public: - - sdl_error() : std::logic_error(SDL_GetError()) - { - } -}; - -class img_error : public std::logic_error { -public: - - img_error() : std::logic_error(IMG_GetError()) - { - } -}; - -class window_deleter { -public: - - void operator()(SDL_Window* ptr) - { - SDL_DestroyWindow(ptr); - } -}; - -using window_ptr = std::unique_ptr; - -class renderer_deleter { -public: - - void operator()(SDL_Renderer* ptr) - { - SDL_DestroyRenderer(ptr); - } -}; - -using renderer_ptr = std::unique_ptr; - -class surface_deleter { -public: - - void operator()(SDL_Surface* ptr) - { - SDL_FreeSurface(ptr); - } -}; - -using surface_ptr = std::unique_ptr; - -class texture_deleter { -public: - - void operator()(SDL_Texture* ptr) - { - SDL_DestroyTexture(ptr); - } -}; - -using texture_ptr = std::unique_ptr; - -enum class Tile { - Floor, - Wall, - Dust, - Lamp -}; - -enum class Source { - None, - Dust, - Lamp, - Player -}; - -enum class LoseState { - None, - PoppingLamps, - PoppingPlayer, - Outro -}; - -const int GAME_WIDTH = 640*2; -const int GAME_HEIGHT = 480*2; -const int TILE_WIDTH = 8*2; -const int TILE_HEIGHT = TILE_WIDTH; -const int INIT_ZOOM = 10; -const int ZOOM_X_FACTOR = 8; -const int ZOOM_Y_FACTOR = 6; -const int RADIUS = 8; - -struct Input { - bool left = false; - bool right = false; - bool up = false; - bool down = false; -}; - -using coord = std::tuple; - -struct Kickup { - int x; - int y; - size_t cur; - size_t radius; - size_t chain; - std::set done; - std::set front; -}; - -struct MapData { - Tile tile = Tile::Floor; - bool lit = false; - bool wasLit = false; - double visibility = 0.0; - size_t dustLife = 0; - Source lightType = Source::None; - int lightRadius = 0; - std::set litTiles; -}; - -class Game { -public: - - Game(std::mt19937& rng) : - rng(rng), - map( - -INIT_ZOOM * ZOOM_X_FACTOR / 2, - -INIT_ZOOM * ZOOM_Y_FACTOR / 2, - INIT_ZOOM * ZOOM_X_FACTOR, - INIT_ZOOM * ZOOM_Y_FACTOR) - { - } - - std::mt19937& rng; - - Map map; - std::list kickups; - int litSpots = 0; - bool dirtyLighting = true; - size_t numLamps = 0; - size_t numDust = 0; - - int player_x = 0; - int player_y = 0; - bool renderPlayer = true; - - int curZoom = INIT_ZOOM; - int maxZoom = INIT_ZOOM; - - bool zooming = false; - //size_t oldZoom; - int zoomProgress = 0; - -}; - -void render( - SDL_Renderer* ren, - const Game& game, - bool drawDark = true) -{ - texture_ptr origFade; - { - surface_ptr pfs(IMG_Load("../res/lighting.png")); - if (!pfs) - { - throw img_error(); - } - - origFade = texture_ptr(SDL_CreateTextureFromSurface(ren, pfs.get())); - } - - SDL_SetTextureBlendMode(origFade.get(), SDL_BLENDMODE_BLEND); - - texture_ptr playerFade( - SDL_CreateTexture( - ren, - SDL_PIXELFORMAT_RGBA4444, - SDL_TEXTUREACCESS_TARGET, - 144, - 144)); - - if (!playerFade) - { - throw sdl_error(); - } - - SDL_SetRenderTarget(ren, playerFade.get()); - SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_NONE); - SDL_SetRenderDrawColor(ren, 0, 0, 0, 0); - SDL_RenderClear(ren); - SDL_RenderCopy(ren, origFade.get(), nullptr, nullptr); - - texture_ptr lampFade( - SDL_CreateTexture( - ren, - SDL_PIXELFORMAT_RGBA4444, - SDL_TEXTUREACCESS_TARGET, - 144, - 144)); - - if (!lampFade) - { - throw sdl_error(); - } - - SDL_SetRenderTarget(ren, lampFade.get()); - - SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_NONE); - SDL_SetRenderDrawColor(ren, 0, 0, 0, 0); - SDL_RenderClear(ren); - SDL_RenderCopy(ren, origFade.get(), nullptr, nullptr); - - SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_MOD); - SDL_SetRenderDrawColor(ren, 255, 204, 58, 255); - SDL_RenderFillRect(ren, nullptr); - - texture_ptr dustFade( - SDL_CreateTexture( - ren, - SDL_PIXELFORMAT_RGBA4444, - SDL_TEXTUREACCESS_TARGET, - 144, - 144)); - - if (!dustFade) - { - throw sdl_error(); - } - - SDL_SetRenderTarget(ren, dustFade.get()); - - SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_NONE); - SDL_SetRenderDrawColor(ren, 0, 0, 0, 0); - SDL_RenderClear(ren); - SDL_RenderCopy(ren, origFade.get(), nullptr, nullptr); - - SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_MOD); - SDL_SetRenderDrawColor(ren, 255, 150, 255, 255); - SDL_RenderFillRect(ren, nullptr); - - texture_ptr canvas( - SDL_CreateTexture( - ren, - SDL_PIXELFORMAT_RGBA8888, - SDL_TEXTUREACCESS_TARGET, - TILE_WIDTH * game.map.getWidth(), - TILE_HEIGHT * game.map.getHeight())); - - if (!canvas) - { - throw sdl_error(); - } - - SDL_SetRenderTarget(ren, canvas.get()); - SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_NONE); - SDL_SetRenderDrawColor(ren, rand() % 255, rand() % 255, rand() % 255, 255); - SDL_RenderClear(ren); - - for (int y = game.map.getTop(); y < game.map.getBottom(); y++) - { - for (int x = game.map.getLeft(); x < game.map.getRight(); x++) - { - bool draw = true; - - if ((game.player_x == x && game.player_y == y) && game.renderPlayer) - { - SDL_SetRenderDrawColor(ren, 255, 255, 0, 255); - } else if (!game.map.at(x,y).lit) - { - if (drawDark) - { - SDL_SetRenderDrawColor(ren, 40, 40, 40, 255); - } else { - draw = false; - } - } else { - int alpha = 255; - - switch (game.map.at(x,y).tile) - { - case Tile::Floor: - { - SDL_SetRenderDrawColor(ren, 210, 210, 210, alpha); - break; - } - - case Tile::Wall: - { - SDL_SetRenderDrawColor(ren, 100, 100, 100, alpha); - break; - } - - case Tile::Dust: - { - SDL_SetRenderDrawColor(ren, 128, 40, 255, alpha); - break; - } - - case Tile::Lamp: - { - SDL_SetRenderDrawColor(ren, 0, 255, 255, alpha); - break; - } - } - } - - if (draw) - { - SDL_Rect rect { - game.map.getTrueX(x) * TILE_WIDTH, - game.map.getTrueY(y) * TILE_HEIGHT, - TILE_WIDTH, - TILE_HEIGHT}; - - //SDL_RenderFillRect(ren, &rect); - - //int alpha = (1.0 - game.map.at(x,y).visibility) * 255; - //SDL_SetRenderDrawColor(ren, 40, 40, 40, 255); - SDL_RenderFillRect(ren, &rect); - } - } - } - - texture_ptr mask( - SDL_CreateTexture( - ren, - SDL_PIXELFORMAT_RGBA8888, - SDL_TEXTUREACCESS_TARGET, - TILE_WIDTH * game.map.getWidth(), - TILE_HEIGHT * game.map.getHeight())); - - if (!mask) - { - throw sdl_error(); - } - - SDL_SetRenderTarget(ren, mask.get()); - SDL_SetRenderDrawColor(ren, 0, 0, 0, 0); - SDL_RenderClear(ren); - - for (int y = game.map.getTop(); y < game.map.getBottom(); y++) - { - for (int x = game.map.getLeft(); x < game.map.getRight(); x++) - { - if (game.map.at(x,y).lightType != Source::None) - { - texture_ptr sourceMask( - SDL_CreateTexture( - ren, - SDL_PIXELFORMAT_RGBA8888, - SDL_TEXTUREACCESS_TARGET, - TILE_WIDTH * game.map.getWidth(), - TILE_HEIGHT * game.map.getHeight())); - - if (!sourceMask) - { - throw sdl_error(); - } - - SDL_SetRenderTarget(ren, sourceMask.get()); - SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_NONE); - SDL_SetRenderDrawColor(ren, 0, 0, 0, 0); - SDL_RenderClear(ren); - - int fadeX = game.map.getTrueX(x) - game.map.at(x,y).lightRadius; - int fadeY = game.map.getTrueY(y) - game.map.at(x,y).lightRadius; - int fadeRight = game.map.getTrueX(x) + game.map.at(x,y).lightRadius; - int fadeBottom = game.map.getTrueY(y) + game.map.at(x,y).lightRadius; - - SDL_Rect fadeRect { - fadeX * TILE_WIDTH, - fadeY * TILE_HEIGHT, - (game.map.at(x,y).lightRadius * 2 + 1) * TILE_WIDTH, - (game.map.at(x,y).lightRadius * 2 + 1) * TILE_HEIGHT}; - - if (game.map.at(x,y).lightType == Source::Lamp) - { - SDL_SetTextureBlendMode(lampFade.get(), SDL_BLENDMODE_NONE); - SDL_RenderCopy(ren, lampFade.get(), nullptr, &fadeRect); - } else if (game.map.at(x,y).lightType == Source::Player) { - SDL_SetTextureBlendMode(playerFade.get(), SDL_BLENDMODE_NONE); - SDL_RenderCopy(ren, playerFade.get(), nullptr, &fadeRect); - } else if (game.map.at(x,y).lightType == Source::Dust) { - SDL_SetTextureBlendMode(dustFade.get(), SDL_BLENDMODE_NONE); - SDL_RenderCopy(ren, dustFade.get(), nullptr, &fadeRect); - } - - SDL_SetRenderDrawColor(ren, 0, 0, 0, 0); - - for (int sy = fadeY; sy < fadeBottom; sy++) - { - for (int sx = fadeX; sx < fadeRight; sx++) - { - if (!game.map.at(x,y).litTiles.count({sx, sy})) - { - SDL_Rect rect { - game.map.getTrueX(sx) * TILE_WIDTH, - game.map.getTrueY(sy) * TILE_HEIGHT, - TILE_WIDTH, - TILE_HEIGHT}; - - SDL_RenderFillRect(ren, &rect); - } - } - } - - SDL_SetRenderTarget(ren, mask.get()); - SDL_SetTextureBlendMode(sourceMask.get(), SDL_BLENDMODE_ADD); - SDL_RenderCopy(ren, sourceMask.get(), nullptr, nullptr); - } - } - } - - SDL_SetRenderTarget(ren, canvas.get()); - SDL_SetTextureBlendMode(mask.get(), SDL_BLENDMODE_MOD); - SDL_RenderCopy(ren, mask.get(), nullptr, nullptr); - - SDL_SetRenderTarget(ren, nullptr); - - if (!game.zooming) - { - SDL_RenderCopy(ren, canvas.get(), nullptr, nullptr); - } else { - // TODO: zooming back in to the player - SDL_Rect zoomRect { - ((game.maxZoom - game.curZoom) * TILE_WIDTH + game.zoomProgress) - * ZOOM_X_FACTOR / 2, - ((game.maxZoom - game.curZoom) * TILE_HEIGHT + game.zoomProgress) - * ZOOM_Y_FACTOR / 2, - (game.curZoom * TILE_WIDTH - game.zoomProgress) * ZOOM_X_FACTOR, - (game.curZoom * TILE_HEIGHT - game.zoomProgress) * ZOOM_Y_FACTOR - }; - - SDL_RenderCopy(ren, canvas.get(), &zoomRect, nullptr); - } - - SDL_RenderPresent(ren); -} +#include "game.h" +#include "renderer.h" void incrementIfSet(Game& game, int& count, int x, int y, Tile val = Tile::Wall) { @@ -543,7 +97,7 @@ void movePlayer(Game& game, int x, int y) } } -void recalculateLighting(Game& game, fov_settings_type* fov) +void recalculateLighting(Game& game) { game.litSpots = 0; @@ -551,12 +105,14 @@ void recalculateLighting(Game& game, fov_settings_type* fov) { md.wasLit = md.lit; md.lit = false; - md.visibility = 0.0; md.litTiles.clear(); } + fov_settings_type fov; + fov_settings_init(&fov); + fov_settings_set_opacity_test_function( - fov, + &fov, [] (void* data, int x, int y) { Game& game = *static_cast(data); @@ -564,7 +120,7 @@ void recalculateLighting(Game& game, fov_settings_type* fov) }); fov_settings_set_apply_lighting_function( - fov, + &fov, [] (void* data, int x, int y, int dx, int dy, void* source) { Game& game = *static_cast(data); @@ -580,21 +136,7 @@ void recalculateLighting(Game& game, fov_settings_type* fov) game.map.at(x,y).lit = true; - /*game.map.at(x,y).visibility = std::max( - game.map.at(x,y).visibility, - std::pow( - std::max( - 0.0, - 1.0 - std::sqrt(dx * dx + dy * dy) / lightRadius), - 1.0/3.0));*/ - sourceData.litTiles.emplace(x,y); - - //Source ls = *static_cast(source); - //if (static_cast(ls) > static_cast(m.lightSource[x+VIEW_WIDTH*y])) - { - //m.lightSource[x+VIEW_WIDTH*y] = ls; - } } }); @@ -620,7 +162,6 @@ void recalculateLighting(Game& game, fov_settings_type* fov) } game.map.at(x,y).lightType = ls; - //game.map.at(x,y).litTiles.clear(); if (ls != Source::None) { @@ -628,7 +169,7 @@ void recalculateLighting(Game& game, fov_settings_type* fov) game.map.at(x,y).litTiles.emplace(x,y); fov_circle( - fov, + &fov, static_cast(&game), static_cast(&game.map.at(x,y)), x, @@ -636,7 +177,6 @@ void recalculateLighting(Game& game, fov_settings_type* fov) lightRadius); game.map.at(x,y).lit = true; - game.map.at(x,y).visibility = 1.0; } } } @@ -832,44 +372,12 @@ int main(int, char**) std::random_device randomEngine; std::mt19937 rng(randomEngine()); - if (SDL_Init(SDL_INIT_VIDEO) != 0) - { - throw sdl_error(); - } - - if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) - { - throw img_error(); - } - try { - window_ptr win( - SDL_CreateWindow("Ether", 100, 100, GAME_WIDTH, GAME_HEIGHT, SDL_WINDOW_SHOWN)); - - if (!win) - { - throw sdl_error(); - } - - renderer_ptr ren( - SDL_CreateRenderer( - win.get(), - -1, - SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)); - - if (!ren) - { - throw sdl_error(); - } - - SDL_SetRenderDrawBlendMode(ren.get(), SDL_BLENDMODE_BLEND); + Renderer renderer; Game game(rng); - std::unique_ptr fov(new fov_settings_type()); - fov_settings_init(fov.get()); - for (MapData& md : game.map.data()) { if (std::bernoulli_distribution(0.5)(rng)) @@ -1091,7 +599,7 @@ int main(int, char**) if (game.dirtyLighting) { - recalculateLighting(game, fov.get()); + recalculateLighting(game); for (int y = game.map.getTop(); y < game.map.getBottom(); y++) { @@ -1140,15 +648,15 @@ int main(int, char**) zoomAcc -= zoomDt; } - render(ren.get(), game, true); + renderer.render(game, true); } } catch (const sdl_error& ex) { std::cout << "SDL error (" << ex.what() << ")" << std::endl; + } catch (const img_error& ex) + { + std::cout << "SDL_IMG error (" << ex.what() << ")" << std::endl; } - IMG_Quit(); - SDL_Quit(); - return 0; } -- cgit 1.4.1