| @@ -24,8 +24,8 @@ SomeNamespace::someLongFunctionName( | |||
| ``` C++ | |||
| void someLongFunctionName( | |||
| int first_argument, | |||
| int second_argument) { | |||
| int firstArgument, | |||
| int secondArgument) { | |||
| whatever; | |||
| } | |||
| ``` | |||
| @@ -34,9 +34,10 @@ void someLongFunctionName( | |||
| * Classes and structs are PascalCase. | |||
| * Methods and free functions are camelCase. | |||
| * Local variables are snake_case. | |||
| * Class member variables are snake_case_ (with the trailing underscore). | |||
| * Struct member variables are snake_case (without the trailing underscore). | |||
| * Local variables are camelCase. | |||
| * Class member variables are camelCase\_ (with the trailing underscore). | |||
| * Struct member variables are camelCase (without the trailing underscore). | |||
| * Constants are UPPER\_SNAKE\_CASE (no trailing underscore) everywhere. | |||
| ## Structure | |||
| @@ -4,11 +4,11 @@ | |||
| #include "entities/PlayerEntity.h" | |||
| static int grassLevel(const siv::PerlinNoise &perlin, int x) { | |||
| static int getGrassLevel(const siv::PerlinNoise &perlin, int x) { | |||
| return (int)(perlin.noise(x / 50.0, 0) * 13); | |||
| } | |||
| static int stoneLevel(const siv::PerlinNoise &perlin, int x) { | |||
| static int getStoneLevel(const siv::PerlinNoise &perlin, int x) { | |||
| return (int)(perlin.noise(x / 50.0, 10) * 10) + 10; | |||
| } | |||
| @@ -43,18 +43,18 @@ SDL_Color DefaultWorldGen::backgroundColor(Swan::Vec2 pos) { | |||
| } | |||
| Swan::Tile::ID DefaultWorldGen::genTile(Swan::TilePos pos) { | |||
| int grass_level = grassLevel(perlin_, pos.x); | |||
| int stone_level = stoneLevel(perlin_, pos.x); | |||
| int grassLevel = getGrassLevel(perlin_, pos.x); | |||
| int stoneLevel = getStoneLevel(perlin_, pos.x); | |||
| // Caves | |||
| if (pos.y > grass_level + 7 && perlin_.noise(pos.x / 43.37, pos.y / 16.37) > 0.2) | |||
| if (pos.y > grassLevel + 7 && perlin_.noise(pos.x / 43.37, pos.y / 16.37) > 0.2) | |||
| return tAir_; | |||
| if (pos.y > stone_level) | |||
| if (pos.y > stoneLevel) | |||
| return tStone_; | |||
| else if (pos.y > grass_level) | |||
| else if (pos.y > grassLevel) | |||
| return tDirt_; | |||
| else if (pos.y == grass_level) | |||
| else if (pos.y == grassLevel) | |||
| return tGrass_; | |||
| else | |||
| return tAir_; | |||
| @@ -77,5 +77,5 @@ void DefaultWorldGen::genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk) { | |||
| Swan::EntityRef DefaultWorldGen::spawnPlayer(const Swan::Context &ctx) { | |||
| int x = 0; | |||
| return ctx.plane.spawnEntity<PlayerEntity>( | |||
| ctx, Swan::Vec2{ (float)x, (float)grassLevel(perlin_, x) - 4 }); | |||
| ctx, Swan::Vec2{ (float)x, (float)getGrassLevel(perlin_, x) - 4 }); | |||
| } | |||
| @@ -34,8 +34,8 @@ void ItemStackEntity::update(const Swan::Context &ctx, float dt) { | |||
| } | |||
| void ItemStackEntity::tick(const Swan::Context &ctx, float dt) { | |||
| despawn_timer_ -= dt; | |||
| if (despawn_timer_ <= 0) | |||
| despawnTimer_ -= dt; | |||
| if (despawnTimer_ <= 0) | |||
| despawn(ctx); | |||
| } | |||
| @@ -21,6 +21,6 @@ private: | |||
| ItemStackEntity(): PhysicsEntity(SIZE) {} | |||
| float despawn_timer_ = DESPAWN_TIME; | |||
| float despawnTimer_ = DESPAWN_TIME; | |||
| Swan::Item *item_ = NULL; | |||
| }; | |||
| @@ -23,19 +23,19 @@ void PlayerEntity::update(const Swan::Context &ctx, float dt) { | |||
| State oldState = state_; | |||
| state_ = State::IDLE; | |||
| mouse_tile_ = ctx.game.getMouseTile(); | |||
| ctx.plane.debugBox(mouse_tile_); | |||
| jump_timer_.tick(dt); | |||
| place_timer_.tick(dt); | |||
| mouseTile_ = ctx.game.getMouseTile(); | |||
| ctx.plane.debugBox(mouseTile_); | |||
| jumpTimer_.tick(dt); | |||
| placeTimer_.tick(dt); | |||
| // Break block | |||
| if (ctx.game.isMousePressed(SDL_BUTTON_LEFT)) | |||
| ctx.plane.breakTile(mouse_tile_); | |||
| ctx.plane.breakTile(mouseTile_); | |||
| // Place block | |||
| if (ctx.game.isMousePressed(SDL_BUTTON_RIGHT) && place_timer_.periodic(0.50)) { | |||
| if (ctx.plane.getTileID(mouse_tile_) == ctx.world.getTileID("@::air")) { | |||
| ctx.plane.setTile(mouse_tile_, "core::torch"); | |||
| if (ctx.game.isMousePressed(SDL_BUTTON_RIGHT) && placeTimer_.periodic(0.50)) { | |||
| if (ctx.plane.getTileID(mouseTile_) == ctx.world.getTileID("@::air")) { | |||
| ctx.plane.setTile(mouseTile_, "core::torch"); | |||
| } | |||
| } | |||
| @@ -54,15 +54,15 @@ void PlayerEntity::update(const Swan::Context &ctx, float dt) { | |||
| state_ = State::RUNNING_R; | |||
| } | |||
| bool jump_pressed = ctx.game.isKeyPressed(SDL_SCANCODE_SPACE); | |||
| bool jumpPressed = ctx.game.isKeyPressed(SDL_SCANCODE_SPACE); | |||
| // Jump | |||
| if (physics_.on_ground && jump_pressed && jump_timer_.periodic(0.5)) { | |||
| if (physics_.onGround && jumpPressed && jumpTimer_.periodic(0.5)) { | |||
| physics_.vel.y = -JUMP_VEL; | |||
| } | |||
| // Fall down faster than we went up | |||
| if (!physics_.on_ground && (!jump_pressed || physics_.vel.y > 0)) | |||
| if (!physics_.on_ground && (!jumpPressed || physics_.vel.y > 0)) | |||
| physics_.force += Swan::Vec2(0, DOWN_FORCE); | |||
| if (state_ != oldState) | |||
| @@ -74,14 +74,14 @@ void PlayerEntity::update(const Swan::Context &ctx, float dt) { | |||
| // Do this after moving so that it's not behind | |||
| Swan::Vec2 headPos = body_.topMid() + Swan::Vec2(0, 0.5); | |||
| Swan::TilePos tilePos = Swan::Vec2i(floor(headPos.x), floor(headPos.y)); | |||
| if (!placed_light_) { | |||
| if (!placedLight_) { | |||
| ctx.plane.addLight(tilePos, LIGHT_LEVEL); | |||
| placed_light_ = true; | |||
| light_tile_ = tilePos; | |||
| } else if (tilePos != light_tile_) { | |||
| ctx.plane.removeLight(light_tile_, LIGHT_LEVEL); | |||
| placedLight_ = true; | |||
| lightTile_ = tilePos; | |||
| } else if (tilePos != lightTile_) { | |||
| ctx.plane.removeLight(lightTile_, LIGHT_LEVEL); | |||
| ctx.plane.addLight(tilePos, LIGHT_LEVEL); | |||
| light_tile_ = tilePos; | |||
| lightTile_ = tilePos; | |||
| } | |||
| } | |||
| @@ -46,12 +46,12 @@ private: | |||
| State state_ = State::IDLE; | |||
| std::array<Swan::Animation, (int)State::COUNT> anims_; | |||
| Swan::Clock jump_timer_; | |||
| Swan::Clock place_timer_; | |||
| Swan::TilePos mouse_tile_; | |||
| Swan::Clock jumpTimer_; | |||
| Swan::Clock placeTimer_; | |||
| Swan::TilePos mouseTile_; | |||
| Swan::TilePos light_tile_; | |||
| bool placed_light_ = false; | |||
| Swan::TilePos lightTile_; | |||
| bool placedLight_ = false; | |||
| BasicInventory inventory_{INVENTORY_SIZE}; | |||
| }; | |||
| @@ -7,7 +7,7 @@ | |||
| class CoreMod: public Swan::Mod { | |||
| public: | |||
| CoreMod(Swan::World &world): Swan::Mod("core") { | |||
| break_listener_ = world.evt_tile_break_.subscribe( | |||
| breakListener_ = world.evtTileBreak_.subscribe( | |||
| std::bind_front(&CoreMod::onTileBreak, this)); | |||
| registerImage("tile/stone"); | |||
| @@ -75,13 +75,13 @@ public: | |||
| } | |||
| void onTileBreak(const Swan::Context &ctx, Swan::TilePos pos, Swan::Tile &tile) { | |||
| if (tile.dropped_item_) { | |||
| if (tile.droppedItem_) { | |||
| ctx.plane.spawnEntity<ItemStackEntity>( | |||
| ctx, (Swan::Vec2)pos + Swan::Vec2{0.5, 0.5}, *tile.dropped_item_); | |||
| ctx, (Swan::Vec2)pos + Swan::Vec2{0.5, 0.5}, *tile.droppedItem_); | |||
| } | |||
| } | |||
| Swan::EventListener break_listener_; | |||
| Swan::EventListener breakListener_; | |||
| }; | |||
| extern "C" Swan::Mod *mod_create(Swan::World &world) { | |||
| @@ -73,24 +73,24 @@ private: | |||
| std::unique_ptr<RendererState> state_; | |||
| std::vector<DrawChunk> draw_chunks_; | |||
| std::vector<DrawSprite> draw_sprites_; | |||
| std::vector<DrawChunk> drawChunks_; | |||
| std::vector<DrawSprite> drawSprites_; | |||
| }; | |||
| inline void Renderer::drawChunk(RenderChunk chunk, SwanCommon::Vec2 pos) { | |||
| draw_chunks_.emplace_back(pos, chunk); | |||
| drawChunks_.emplace_back(pos, chunk); | |||
| } | |||
| inline void Renderer::drawSprite(RenderSprite sprite, Mat3gf mat, int frame) { | |||
| draw_sprites_.emplace_back(mat, frame, sprite); | |||
| drawSprites_.emplace_back(mat, frame, sprite); | |||
| } | |||
| inline void Renderer::drawSprite(RenderSprite sprite, SwanCommon::Vec2 pos, int frame) { | |||
| draw_sprites_.emplace_back(Mat3gf{}.translate(pos), frame, sprite); | |||
| drawSprites_.emplace_back(Mat3gf{}.translate(pos), frame, sprite); | |||
| } | |||
| inline void Renderer::drawSpriteFlipped(RenderSprite sprite, SwanCommon::Vec2 pos, int frame) { | |||
| draw_sprites_.emplace_back(Mat3gf{}.translate(pos).scale({ -1, 1 }), frame, sprite); | |||
| drawSprites_.emplace_back(Mat3gf{}.translate(pos).scale({ -1, 1 }), frame, sprite); | |||
| } | |||
| } | |||
| @@ -33,7 +33,7 @@ public: | |||
| private: | |||
| Renderer &rnd_; | |||
| std::unordered_map<std::string, RenderSprite> sprites_; | |||
| std::vector<ResourceTileAnimation> tile_anims_; | |||
| std::vector<ResourceTileAnimation> tileAnims_; | |||
| TileAtlas atlas_; | |||
| friend ResourceManager; | |||
| @@ -52,7 +52,7 @@ private: | |||
| Renderer &rnd_; | |||
| std::unordered_map<std::string, RenderSprite> sprites_; | |||
| std::unordered_map<std::string, RenderTile> tiles_; | |||
| std::vector<ResourceTileAnimation> tile_anims_; | |||
| std::vector<ResourceTileAnimation> tileAnims_; | |||
| }; | |||
| inline RenderSprite ResourceBuilder::addSprite( | |||
| @@ -79,7 +79,7 @@ inline void ResourceBuilder::addTile(uint16_t id, void *data, int frames) { | |||
| inline void ResourceBuilder::addTile(Renderer::TileID id, std::unique_ptr<unsigned char[]> data, int frames) { | |||
| atlas_.addTile(id, data.get()); | |||
| if (frames > 1) { | |||
| tile_anims_.push_back({ | |||
| tileAnims_.push_back({ | |||
| .id = id, | |||
| .frames = frames, | |||
| .index = 0, | |||
| @@ -170,14 +170,14 @@ void Renderer::draw(const RenderCamera &cam) { | |||
| glCheck(); | |||
| glActiveTexture(GL_TEXTURE1); | |||
| for (auto [pos, chunk]: draw_chunks_) { | |||
| for (auto [pos, chunk]: drawChunks_) { | |||
| glUniform2f(chunkProg.pos, pos.x, pos.y); | |||
| glBindTexture(GL_TEXTURE_2D, chunk.tex); | |||
| glDrawArrays(GL_TRIANGLES, 0, 6); | |||
| glCheck(); | |||
| } | |||
| draw_chunks_.clear(); | |||
| drawChunks_.clear(); | |||
| chunkProg.disable(); | |||
| } | |||
| @@ -187,7 +187,7 @@ void Renderer::draw(const RenderCamera &cam) { | |||
| glCheck(); | |||
| glActiveTexture(GL_TEXTURE0); | |||
| for (auto [mat, frame, sprite]: draw_sprites_) { | |||
| for (auto [mat, frame, sprite]: drawSprites_) { | |||
| mat.scale(sprite.scale); | |||
| glUniformMatrix3fv(spriteProg.transform, 1, GL_TRUE, mat.data()); | |||
| glUniform3f(spriteProg.frameInfo, sprite.scale.y, sprite.frameCount, frame); | |||
| @@ -196,7 +196,7 @@ void Renderer::draw(const RenderCamera &cam) { | |||
| glCheck(); | |||
| } | |||
| draw_sprites_.clear(); | |||
| drawSprites_.clear(); | |||
| spriteProg.disable(); | |||
| } | |||
| } | |||
| @@ -4,7 +4,7 @@ namespace Cygnet { | |||
| ResourceManager::ResourceManager(ResourceBuilder &&builder): | |||
| rnd_(builder.rnd_), sprites_(std::move(builder.sprites_)), | |||
| tile_anims_(std::move(builder.tile_anims_)) { | |||
| tileAnims_(std::move(builder.tileAnims_)) { | |||
| size_t width, height; | |||
| const unsigned char *data = builder.atlas_.getImage(&width, &height); | |||
| rnd_.uploadTileAtlas(data, width, height); | |||
| @@ -18,7 +18,7 @@ ResourceManager::~ResourceManager() { | |||
| void ResourceManager::tick() { | |||
| // TODO: Maybe do a GPU->GPU copy instead of an upload from the CPU? | |||
| for (auto &anim: tile_anims_) { | |||
| for (auto &anim: tileAnims_) { | |||
| anim.index = (anim.index + 1) % anim.frames; | |||
| unsigned char *data = anim.data.get() + | |||
| SwanCommon::TILE_SIZE * SwanCommon::TILE_SIZE * 4 * anim.index; | |||
| @@ -49,12 +49,12 @@ public: | |||
| void setTileID(RelPos pos, Tile::ID id, SDL_Texture *tex) { | |||
| getTileData()[pos.y * CHUNK_WIDTH + pos.x] = id; | |||
| draw_list_.push_back({ pos, tex }); | |||
| drawList_.push_back({ pos, tex }); | |||
| } | |||
| void setTileData(RelPos pos, Tile::ID id) { | |||
| getTileData()[pos.y * CHUNK_WIDTH + pos.x] = id; | |||
| need_render_ = true; | |||
| needRender_ = true; | |||
| } | |||
| uint8_t getLightLevel(RelPos pos) { | |||
| @@ -63,7 +63,7 @@ public: | |||
| void setLightData(const uint8_t *data) { | |||
| memcpy(getLightData(), data, CHUNK_WIDTH * CHUNK_HEIGHT); | |||
| need_light_render_ = true; | |||
| needLightRender_ = true; | |||
| } | |||
| void render(const Context &ctx, SDL_Renderer *rnd); | |||
| @@ -74,9 +74,9 @@ public: | |||
| void draw(const Context &ctx, Win &win); | |||
| TickAction tick(float dt); | |||
| bool isActive() { return deactivate_timer_ > 0; } | |||
| bool isActive() { return deactivateTimer_ > 0; } | |||
| void keepActive(); | |||
| void markModified() { is_modified_ = true; } | |||
| void markModified() { isModified_ = true; } | |||
| ChunkPos pos_; | |||
| @@ -85,19 +85,19 @@ private: | |||
| void renderList(SDL_Renderer *rnd); | |||
| bool isCompressed() { return compressed_size_ != -1; } | |||
| bool isCompressed() { return compressedSize_ != -1; } | |||
| std::unique_ptr<uint8_t[]> data_; | |||
| std::vector<std::pair<RelPos, SDL_Texture *>> draw_list_; | |||
| std::vector<std::pair<RelPos, SDL_Texture *>> drawList_; | |||
| ssize_t compressed_size_ = -1; // -1 if not compressed, a positive number if compressed | |||
| bool need_render_ = false; | |||
| bool need_light_render_ = false; | |||
| float deactivate_timer_ = DEACTIVATE_INTERVAL; | |||
| bool is_modified_ = false; | |||
| ssize_t compressedSize_ = -1; // -1 if not compressed, a positive number if compressed | |||
| bool needRender_ = false; | |||
| bool needLightRender_ = false; | |||
| float deactivateTimer_ = DEACTIVATE_INTERVAL; | |||
| bool isModified_ = false; | |||
| CPtr<SDL_Texture, SDL_DestroyTexture> texture_; | |||
| CPtr<SDL_Texture, SDL_DestroyTexture> light_texture_; | |||
| CPtr<SDL_Texture, SDL_DestroyTexture> lightTexture_; | |||
| }; | |||
| } | |||
| @@ -146,7 +146,7 @@ inline EntityRef EntityCollection::spawn(Args&&... args) { | |||
| template<typename Ent> | |||
| inline Entity *EntityCollectionImpl<Ent>::get(size_t idx, size_t generation) { | |||
| if (idx >=entities_.size()) | |||
| if (idx >= entities_.size()) | |||
| return nullptr; | |||
| auto &e = entities_[idx]; | |||
| @@ -17,49 +17,49 @@ class Game { | |||
| public: | |||
| Game(Win &win): | |||
| win_(win), | |||
| mouse_pos_(0, 0) {} | |||
| mousePos_(0, 0) {} | |||
| std::optional<ModWrapper> loadMod(std::string path, World &world); | |||
| void createWorld(const std::string &worldgen, const std::vector<std::string> &mods); | |||
| void onKeyDown(SDL_Keysym sym) { | |||
| pressed_keys_[sym.scancode] = true; | |||
| did_press_keys_[sym.scancode] = true; | |||
| pressedKeys_[sym.scancode] = true; | |||
| didPressKeys_[sym.scancode] = true; | |||
| } | |||
| void onKeyUp(SDL_Keysym sym) { | |||
| pressed_keys_[sym.scancode] = false; | |||
| did_release_keys_[sym.scancode] = true; | |||
| pressedKeys_[sym.scancode] = false; | |||
| didReleaseKeys_[sym.scancode] = true; | |||
| } | |||
| void onMouseMove(Sint32 x, Sint32 y) { | |||
| mouse_pos_ = { x, y }; | |||
| mousePos_ = { x, y }; | |||
| } | |||
| void onMouseDown(Sint32 x, Sint32 y, Uint8 button) { | |||
| mouse_pos_ = { x, y }; | |||
| pressed_buttons_[button] = true; | |||
| did_press_buttons_[button] = true; | |||
| mousePos_ = { x, y }; | |||
| pressedButtons_[button] = true; | |||
| didPressButtons_[button] = true; | |||
| } | |||
| void onMouseUp(Sint32 x, Sint32 y, Uint8 button) { | |||
| mouse_pos_ = { x, y }; | |||
| pressed_buttons_[button] = false; | |||
| did_release_buttons_[button] = true; | |||
| mousePos_ = { x, y }; | |||
| pressedButtons_[button] = false; | |||
| didReleaseButtons_[button] = true; | |||
| } | |||
| void onScrollWheel(Sint32 y) { | |||
| did_scroll_ = (y > 0 ? 1 : -1 ); | |||
| didScroll_ = (y > 0 ? 1 : -1 ); | |||
| } | |||
| bool isKeyPressed(SDL_Scancode code) { return pressed_keys_[code]; } | |||
| bool wasKeyPressed(SDL_Scancode code) { return did_press_keys_[code]; } | |||
| bool wasKeyReleased(SDL_Scancode code) { return did_release_keys_[code]; } | |||
| Vec2i getMousePos() { return mouse_pos_; } | |||
| bool isMousePressed(Uint8 button) { return pressed_buttons_[button]; } | |||
| bool wasMousePressed(Uint8 button) { return did_press_buttons_[button]; } | |||
| bool wasMouseReleased(Uint8 button) { return did_release_buttons_[button]; } | |||
| int wasWheelScrolled() { return did_scroll_; } | |||
| bool isKeyPressed(SDL_Scancode code) { return pressedKeys_[code]; } | |||
| bool wasKeyPressed(SDL_Scancode code) { return didPressKeys_[code]; } | |||
| bool wasKeyReleased(SDL_Scancode code) { return didReleaseKeys_[code]; } | |||
| Vec2i getMousePos() { return mousePos_; } | |||
| bool isMousePressed(Uint8 button) { return pressedButtons_[button]; } | |||
| bool wasMousePressed(Uint8 button) { return didPressButtons_[button]; } | |||
| bool wasMouseReleased(Uint8 button) { return didReleaseButtons_[button]; } | |||
| int wasWheelScrolled() { return didScroll_; } | |||
| TilePos getMouseTile(); | |||
| @@ -69,22 +69,22 @@ public: | |||
| void tick(float dt); | |||
| std::unique_ptr<World> world_ = NULL; | |||
| std::unique_ptr<ImageResource> invalid_image_ = NULL; | |||
| std::unique_ptr<Tile> invalid_tile_ = NULL; | |||
| std::unique_ptr<Item> invalid_item_ = NULL; | |||
| std::unique_ptr<ImageResource> invalidImage_ = NULL; | |||
| std::unique_ptr<Tile> invalidTile_ = NULL; | |||
| std::unique_ptr<Item> invalidItem_ = NULL; | |||
| Win &win_; | |||
| private: | |||
| std::bitset<SDL_NUM_SCANCODES> pressed_keys_; | |||
| std::bitset<SDL_NUM_SCANCODES> did_press_keys_; | |||
| std::bitset<SDL_NUM_SCANCODES> did_release_keys_; | |||
| std::bitset<SDL_NUM_SCANCODES> pressedKeys_; | |||
| std::bitset<SDL_NUM_SCANCODES> didPressKeys_; | |||
| std::bitset<SDL_NUM_SCANCODES> didReleaseKeys_; | |||
| Vec2i mouse_pos_; | |||
| std::bitset<SDL_BUTTON_X2> pressed_buttons_; | |||
| std::bitset<SDL_BUTTON_X2> did_press_buttons_; | |||
| std::bitset<SDL_BUTTON_X2> did_release_buttons_; | |||
| Vec2i mousePos_; | |||
| std::bitset<SDL_BUTTON_X2> pressedButtons_; | |||
| std::bitset<SDL_BUTTON_X2> didPressButtons_; | |||
| std::bitset<SDL_BUTTON_X2> didReleaseButtons_; | |||
| int did_scroll_ = 0; | |||
| int didScroll_ = 0; | |||
| }; | |||
| } | |||
| @@ -12,16 +12,16 @@ public: | |||
| struct Builder { | |||
| std::string name; | |||
| std::string image; | |||
| int max_stack = 64; | |||
| int maxStack = 64; | |||
| }; | |||
| Item(const ResourceManager &resources, const Builder &builder): | |||
| name_(builder.name), image_(resources.getImage(builder.image)), | |||
| max_stack_(builder.max_stack) {} | |||
| maxStack_(builder.maxStack) {} | |||
| const std::string name_; | |||
| const ImageResource &image_; | |||
| const int max_stack_; | |||
| const int maxStack_; | |||
| static std::unique_ptr<Item> createInvalid(Context &ctx); | |||
| @@ -33,7 +33,7 @@ public: | |||
| protected: | |||
| Item(const Builder &builder): | |||
| name_(builder.name), image_(*(ImageResource *)this), | |||
| max_stack_(builder.max_stack) {} | |||
| maxStack_(builder.maxStack) {} | |||
| }; | |||
| } | |||
| @@ -14,7 +14,7 @@ namespace Swan { | |||
| struct NewLightChunk { | |||
| std::bitset<CHUNK_WIDTH * CHUNK_HEIGHT> blocks; | |||
| std::map<std::pair<int, int>, float> light_sources; | |||
| std::map<std::pair<int, int>, float> lightSources; | |||
| }; | |||
| struct LightChunk { | |||
| @@ -22,16 +22,16 @@ struct LightChunk { | |||
| LightChunk(NewLightChunk &&ch); | |||
| std::bitset<CHUNK_WIDTH * CHUNK_HEIGHT> blocks; | |||
| uint8_t light_levels[CHUNK_WIDTH * CHUNK_HEIGHT] = { 0 }; | |||
| float light_buffers[CHUNK_WIDTH * CHUNK_HEIGHT * 2] = { 0 }; | |||
| uint8_t lightLevels[CHUNK_WIDTH * CHUNK_HEIGHT] = { 0 }; | |||
| float lightBuffers[CHUNK_WIDTH * CHUNK_HEIGHT * 2] = { 0 }; | |||
| int buffer = 0; | |||
| uint8_t blocks_line[CHUNK_WIDTH] = { 0 }; | |||
| std::map<std::pair<int, int>, float> light_sources; | |||
| uint8_t blocksLine[CHUNK_WIDTH] = { 0 }; | |||
| std::map<std::pair<int, int>, float> lightSources; | |||
| std::vector<std::pair<TilePos, float>> bounces; | |||
| float *light_buffer() { return light_buffers + CHUNK_WIDTH * CHUNK_HEIGHT * buffer; } | |||
| float *lightBuffer() { return lightBuffers + CHUNK_WIDTH * CHUNK_HEIGHT * buffer; } | |||
| bool was_updated = false; | |||
| bool wasUpdated = false; | |||
| }; | |||
| class LightCallback { | |||
| @@ -85,13 +85,13 @@ private: | |||
| LightCallback &cb_; | |||
| bool running_ = true; | |||
| std::map<std::pair<int, int>, LightChunk> chunks_; | |||
| std::set<std::pair<int, int>> updated_chunks_; | |||
| LightChunk *cached_chunk_ = nullptr; | |||
| Vec2i cached_chunk_pos_; | |||
| std::set<std::pair<int, int>> updatedChunks_; | |||
| LightChunk *cachedChunk_ = nullptr; | |||
| Vec2i cachedChunkPos_; | |||
| int buffer_ = 0; | |||
| std::vector<Event> buffers_[2] = { {}, {} }; | |||
| std::vector<NewLightChunk> new_chunk_buffers_[2] = { {}, {} }; | |||
| std::vector<NewLightChunk> newChunkBuffers_[2] = { {}, {} }; | |||
| std::thread thread_; | |||
| std::condition_variable cond_; | |||
| std::mutex mut_; | |||
| @@ -124,8 +124,8 @@ inline void LightServer::onLightRemoved(TilePos pos, float level) { | |||
| inline void LightServer::onChunkAdded(Vec2i pos, NewLightChunk &&chunk) { | |||
| std::lock_guard<std::mutex> lock(mut_); | |||
| buffers_[buffer_].push_back({ Event::Tag::CHUNK_ADDED, pos, | |||
| { .i = (int)new_chunk_buffers_[buffer_].size() } }); | |||
| new_chunk_buffers_[buffer_].push_back(std::move(chunk)); | |||
| { .i = (int)newChunkBuffers_[buffer_].size() } }); | |||
| newChunkBuffers_[buffer_].push_back(std::move(chunk)); | |||
| cond_.notify_one(); | |||
| } | |||
| @@ -18,21 +18,21 @@ public: | |||
| struct Builder { | |||
| std::string name; | |||
| std::string image; | |||
| bool is_solid = true; | |||
| float light_level = 0; | |||
| std::optional<std::string> dropped_item = std::nullopt; | |||
| bool isSolid = true; | |||
| float lightLevel = 0; | |||
| std::optional<std::string> droppedItem = std::nullopt; | |||
| }; | |||
| Tile(const ResourceManager &resources, const Builder &builder): | |||
| name_(builder.name), image_(resources.getImage(builder.image)), | |||
| is_solid_(builder.is_solid), light_level_(builder.light_level), | |||
| dropped_item_(builder.dropped_item) {} | |||
| isSolid_(builder.isSolid), lightLevel_(builder.lightLevel), | |||
| droppedItem_(builder.droppedItem) {} | |||
| const std::string name_; | |||
| const ImageResource &image_; | |||
| const bool is_solid_; | |||
| const float light_level_; | |||
| const std::optional<std::string> dropped_item_; | |||
| const bool isSolid_; | |||
| const float lightLevel_; | |||
| const std::optional<std::string> droppedItem_; | |||
| static std::unique_ptr<Tile> createInvalid(const ResourceManager &ctx); | |||
| static std::unique_ptr<Tile> createAir(const ResourceManager &ctx); | |||
| @@ -31,7 +31,7 @@ public: | |||
| void setCurrentPlane(WorldPlane &plane); | |||
| WorldPlane &addPlane(const std::string &gen); | |||
| WorldPlane &addPlane() { return addPlane(default_world_gen_); } | |||
| WorldPlane &addPlane() { return addPlane(defaultWorldGen_); } | |||
| Tile &getTileByID(Tile::ID id) { return *tiles_[id]; } | |||
| Tile::ID getTileID(const std::string &name); | |||
| @@ -45,19 +45,19 @@ public: | |||
| // Event emitters | |||
| EventEmitter<const Context &, TilePos, Tile &> | |||
| evt_tile_break_; | |||
| evtTileBreak_; | |||
| // World owns all mods | |||
| std::vector<ModWrapper> mods_; | |||
| // World owns tiles and items, the mod just has Builder objects | |||
| std::vector<std::unique_ptr<Tile>> tiles_; | |||
| std::unordered_map<std::string, Tile::ID> tiles_map_; | |||
| std::unordered_map<std::string, Tile::ID> tilesMap_; | |||
| std::unordered_map<std::string, std::unique_ptr<Item>> items_; | |||
| // Mods give us factories to create new world gens and new entity collections | |||
| std::unordered_map<std::string, WorldGen::Factory> worldgen_factories_; | |||
| std::vector<EntityCollection::Factory> ent_coll_factories_; | |||
| std::unordered_map<std::string, WorldGen::Factory> worldgenFactories_; | |||
| std::vector<EntityCollection::Factory> entCollFactories_; | |||
| BodyTrait::Body *player_; | |||
| Game *game_; | |||
| @@ -71,10 +71,10 @@ private: | |||
| void tick(WorldPlane &plane, ChunkPos abspos); | |||
| }; | |||
| ChunkRenderer chunk_renderer_; | |||
| WorldPlane::ID current_plane_; | |||
| ChunkRenderer chunkRenderer_; | |||
| WorldPlane::ID currentPlane_; | |||
| std::vector<std::unique_ptr<WorldPlane>> planes_; | |||
| std::string default_world_gen_; | |||
| std::string defaultWorldGen_; | |||
| }; | |||
| } | |||
| @@ -91,14 +91,14 @@ private: | |||
| std::unique_ptr<LightServer> lighting_; | |||
| std::map<std::pair<int, int>, Chunk> chunks_; | |||
| std::vector<Chunk *> active_chunks_; | |||
| std::vector<std::pair<ChunkPos, Chunk *>> tick_chunks_; | |||
| std::vector<std::unique_ptr<EntityCollection>> ent_colls_; | |||
| std::unordered_map<std::type_index, EntityCollection *> ent_colls_by_type_; | |||
| std::unordered_map<std::string, EntityCollection *> ent_colls_by_name_; | |||
| std::deque<Chunk *> chunk_init_list_; | |||
| std::vector<TilePos> debug_boxes_; | |||
| std::vector<Chunk *> activeChunks_; | |||
| std::vector<std::pair<ChunkPos, Chunk *>> tickChunks_; | |||
| std::vector<std::unique_ptr<EntityCollection>> entColls_; | |||
| std::unordered_map<std::type_index, EntityCollection *> entCollsByType_; | |||
| std::unordered_map<std::string, EntityCollection *> entCollsByName_; | |||
| std::deque<Chunk *> chunkInitList_; | |||
| std::vector<TilePos> debugBoxes_; | |||
| }; | |||
| /* | |||
| @@ -112,15 +112,15 @@ inline EntityRef WorldPlane::spawnEntity(Args&&... args) { | |||
| template<typename Ent> | |||
| inline EntityCollection &WorldPlane::getCollectionOf() { | |||
| return *ent_colls_by_type_.at(typeid(Ent)); | |||
| return *entCollsByType_.at(typeid(Ent)); | |||
| } | |||
| inline EntityCollection &WorldPlane::getCollectionOf(std::string name) { | |||
| return *ent_colls_by_name_.at(name); | |||
| return *entCollsByName_.at(name); | |||
| } | |||
| inline EntityCollection &WorldPlane::getCollectionOf(std::type_index type) { | |||
| return *ent_colls_by_type_.at(type); | |||
| return *entCollsByType_.at(type); | |||
| } | |||
| } | |||
| @@ -74,17 +74,17 @@ private: | |||
| class RenderTarget: NonCopyable { | |||
| public: | |||
| RenderTarget(SDL_Renderer *rnd, SDL_Texture *tex): rnd_(rnd) { | |||
| prev_target_ = SDL_GetRenderTarget(rnd_); | |||
| prevTarget_ = SDL_GetRenderTarget(rnd_); | |||
| SDL_SetRenderTarget(rnd_, tex); | |||
| } | |||
| ~RenderTarget() { | |||
| SDL_SetRenderTarget(rnd_, prev_target_); | |||
| SDL_SetRenderTarget(rnd_, prevTarget_); | |||
| } | |||
| private: | |||
| SDL_Renderer *rnd_; | |||
| SDL_Texture *prev_target_; | |||
| SDL_Texture *prevTarget_; | |||
| }; | |||
| class TexLock: NonCopyable { | |||
| @@ -26,11 +26,11 @@ public: | |||
| }; | |||
| Logger(std::ostream &os, std::string name, bool use_color = false, std::string color = ""): | |||
| os_(os), name_(std::move(name)), use_color_(use_color), color_(std::move(color)) {} | |||
| os_(os), name_(std::move(name)), useColor_(use_color), color_(std::move(color)) {} | |||
| template<typename T> | |||
| NewlineStream operator<<(const T &val) { | |||
| if (use_color_) | |||
| if (useColor_) | |||
| os_ << color_ << name_ << "\033[0m: " << val; | |||
| else | |||
| os_ << name_ << ": " << val; | |||
| @@ -40,7 +40,7 @@ public: | |||
| private: | |||
| std::ostream &os_; | |||
| std::string name_; | |||
| bool use_color_; | |||
| bool useColor_; | |||
| std::string color_; | |||
| }; | |||
| @@ -19,7 +19,7 @@ struct PhysicsTrait { | |||
| struct Physics { | |||
| Vec2 vel{}; | |||
| Vec2 force{}; | |||
| bool on_ground = false; | |||
| bool onGround = false; | |||
| void friction(Vec2 coef = Vec2(400, 50)); | |||
| void gravity(float mass, Vec2 g = Vec2(0, 20)); | |||
| @@ -33,7 +33,7 @@ void Chunk::compress() { | |||
| memcpy(data_.get(), dest, destlen); | |||
| texture_.reset(); | |||
| compressed_size_ = destlen; | |||
| compressedSize_ = destlen; | |||
| info | |||
| << "Compressed chunk " << pos_ << " from " | |||
| @@ -56,7 +56,7 @@ void Chunk::decompress() { | |||
| uLongf destlen = DATA_SIZE; | |||
| int ret = uncompress( | |||
| dest.get(), &destlen, | |||
| (Bytef *)data_.get(), compressed_size_); | |||
| (Bytef *)data_.get(), compressedSize_); | |||
| if (ret != Z_OK) { | |||
| panic << "Decompressing chunk failed: " << ret; | |||
| @@ -64,24 +64,24 @@ void Chunk::decompress() { | |||
| } | |||
| data_ = std::move(dest); | |||
| need_render_ = true; | |||
| needRender_ = true; | |||
| info | |||
| << "Decompressed chunk " << pos_ << " from " | |||
| << compressed_size_ << " bytes to " | |||
| << compressedSize_ << " bytes to " | |||
| << DATA_SIZE << " bytes."; | |||
| compressed_size_ = -1; | |||
| compressedSize_ = -1; | |||
| } | |||
| void Chunk::renderLight(const Context &ctx, SDL_Renderer *rnd) { | |||
| std::optional<RenderTarget> target; | |||
| // The texture might not be created yet | |||
| if (!light_texture_) { | |||
| light_texture_.reset(SDL_CreateTexture( | |||
| if (!lightTexture_) { | |||
| lightTexture_.reset(SDL_CreateTexture( | |||
| ctx.game.win_.renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, | |||
| CHUNK_WIDTH, CHUNK_HEIGHT)); | |||
| SDL_SetTextureBlendMode(light_texture_.get(), SDL_BLENDMODE_BLEND); | |||
| SDL_SetTextureBlendMode(lightTexture_.get(), SDL_BLENDMODE_BLEND); | |||
| target.emplace(rnd, texture_.get()); | |||
| } else { | |||
| @@ -89,7 +89,7 @@ void Chunk::renderLight(const Context &ctx, SDL_Renderer *rnd) { | |||
| } | |||
| // Fill light texture | |||
| target.emplace(rnd, light_texture_.get()); | |||
| target.emplace(rnd, lightTexture_.get()); | |||
| RenderBlendMode mode(rnd, SDL_BLENDMODE_NONE); | |||
| RenderDrawColor color(rnd, 0, 0, 0, 0); | |||
| for (int y = 0; y < CHUNK_HEIGHT; ++y) { | |||
| @@ -101,7 +101,7 @@ void Chunk::renderLight(const Context &ctx, SDL_Renderer *rnd) { | |||
| } | |||
| } | |||
| need_light_render_ = false; | |||
| needLightRender_ = false; | |||
| } | |||
| void Chunk::render(const Context &ctx, SDL_Renderer *rnd) { | |||
| @@ -125,7 +125,7 @@ void Chunk::render(const Context &ctx, SDL_Renderer *rnd) { | |||
| // We're caching tiles so we don't have to world.getTileByID() every time | |||
| Tile::ID prevID = Tile::INVALID_ID; | |||
| Tile *tile = ctx.game.invalid_tile_.get(); | |||
| Tile *tile = ctx.game.invalidTile_.get(); | |||
| // Fill tile texture | |||
| for (int y = 0; y < CHUNK_HEIGHT; ++y) { | |||
| @@ -141,7 +141,7 @@ void Chunk::render(const Context &ctx, SDL_Renderer *rnd) { | |||
| } | |||
| } | |||
| need_render_ = false; | |||
| needRender_ = false; | |||
| renderLight(ctx, rnd); | |||
| } | |||
| @@ -158,7 +158,7 @@ void Chunk::renderList(SDL_Renderer *rnd) { | |||
| // When we FillRect, we must fill transparency. | |||
| RenderDrawColor color(rnd, 0, 0, 0, 0); | |||
| for (auto &[pos, tex]: draw_list_) { | |||
| for (auto &[pos, tex]: drawList_) { | |||
| SDL_Rect dest{pos.x * TILE_SIZE, pos.y * TILE_SIZE, TILE_SIZE, TILE_SIZE}; | |||
| SDL_RenderFillRect(rnd, &dest); | |||
| SDL_RenderCopy(rnd, tex, nullptr, &dest); | |||
| @@ -170,16 +170,16 @@ void Chunk::draw(const Context &ctx, Win &win) { | |||
| return; | |||
| // The world plane is responsible for managing initial renders | |||
| if (need_render_) | |||
| if (needRender_) | |||
| return; | |||
| // We're responsible for the light level rendering though | |||
| if (need_light_render_) | |||
| if (needLightRender_) | |||
| renderLight(ctx, win.renderer_); | |||
| if (draw_list_.size() > 0) { | |||
| if (drawList_.size() > 0) { | |||
| renderList(win.renderer_); | |||
| draw_list_.clear(); | |||
| drawList_.clear(); | |||
| } | |||
| auto chunkpos = pos_ * Vec2i(CHUNK_WIDTH, CHUNK_HEIGHT); | |||
| @@ -187,15 +187,15 @@ void Chunk::draw(const Context &ctx, Win &win) { | |||
| win.showTexture(chunkpos, texture_.get(), &rect); | |||
| SDL_Rect texrect{ 0, 0, CHUNK_WIDTH, CHUNK_HEIGHT }; | |||
| win.showTexture(chunkpos, light_texture_.get(), &texrect, &rect); | |||
| win.showTexture(chunkpos, lightTexture_.get(), &texrect, &rect); | |||
| } | |||
| Chunk::TickAction Chunk::tick(float dt) { | |||
| assert(isActive()); | |||
| deactivate_timer_ -= dt; | |||
| if (deactivate_timer_ <= 0) { | |||
| if (is_modified_) | |||
| deactivateTimer_ -= dt; | |||
| if (deactivateTimer_ <= 0) { | |||
| if (isModified_) | |||
| return TickAction::DEACTIVATE; | |||
| else | |||
| return TickAction::DELETE; | |||
| @@ -205,7 +205,7 @@ Chunk::TickAction Chunk::tick(float dt) { | |||
| } | |||
| void Chunk::keepActive() { | |||
| deactivate_timer_ = DEACTIVATE_INTERVAL; | |||
| deactivateTimer_ = DEACTIVATE_INTERVAL; | |||
| decompress(); | |||
| } | |||
| @@ -63,11 +63,11 @@ void Game::update(float dt) { | |||
| else if (win_.zoom_ < 0.3) | |||
| win_.zoom_ = 0.3; | |||
| did_scroll_ = 0; | |||
| did_press_keys_.reset(); | |||
| did_release_keys_.reset(); | |||
| did_press_buttons_.reset(); | |||
| did_release_buttons_.reset(); | |||
| didScroll_ = 0; | |||
| didPressKeys_.reset(); | |||
| didReleaseKeys_.reset(); | |||
| didPressButtons_.reset(); | |||
| didReleaseButtons_.reset(); | |||
| } | |||
| void Game::tick(float dt) { | |||
| @@ -21,9 +21,9 @@ ItemStack ItemStack::insert(ItemStack st) { | |||
| // Merge | |||
| count_ += st.count_; | |||
| if (count_ > item_->max_stack_) { | |||
| st.count_ = count_ - item_->max_stack_; | |||
| count_ = item_->max_stack_; | |||
| if (count_ > item_->maxStack_) { | |||
| st.count_ = count_ - item_->maxStack_; | |||
| count_ = item_->maxStack_; | |||
| } else { | |||
| st.count_ = 0; | |||
| st.item_ = nullptr; | |||
| @@ -48,11 +48,11 @@ static float attenuateSquared(float squareDist) { | |||
| } | |||
| LightChunk::LightChunk(NewLightChunk &&ch): | |||
| blocks(std::move(ch.blocks)), light_sources(std::move(ch.light_sources)) { | |||
| blocks(std::move(ch.blocks)), lightSources(std::move(ch.lightSources)) { | |||
| for (int y = 0; y < CHUNK_HEIGHT; ++y) { | |||
| for (int x = 0; x < CHUNK_WIDTH; ++x) { | |||
| if (blocks[y * CHUNK_WIDTH + x]) { | |||
| blocks_line[x] += 1; | |||
| blocksLine[x] += 1; | |||
| } | |||
| } | |||
| } | |||
| @@ -79,14 +79,14 @@ bool LightServer::tileIsSolid(TilePos pos) { | |||
| } | |||
| LightChunk *LightServer::getChunk(ChunkPos cpos) { | |||
| if (cached_chunk_ && cached_chunk_pos_ == cpos) { | |||
| return cached_chunk_; | |||
| if (cachedChunk_ && cachedChunkPos_ == cpos) { | |||
| return cachedChunk_; | |||
| } | |||
| auto it = chunks_.find(cpos); | |||
| if (it != chunks_.end()) { | |||
| cached_chunk_ = &it->second; | |||
| cached_chunk_pos_ = cpos; | |||
| cachedChunk_ = &it->second; | |||
| cachedChunkPos_ = cpos; | |||
| return &it->second; | |||
| } | |||
| @@ -97,21 +97,21 @@ void LightServer::processEvent(const Event &evt, std::vector<NewLightChunk> &new | |||
| auto markAdjacentChunksModified = [&](ChunkPos cpos) { | |||
| for (int y = -1; y <= 1; ++y) { | |||
| for (int x = -1; x <= 1; ++x) { | |||
| updated_chunks_.insert(cpos + Vec2i(x, y)); | |||
| updatedChunks_.insert(cpos + Vec2i(x, y)); | |||
| } | |||
| } | |||
| }; | |||
| auto markChunks = [&](ChunkPos cpos, Vec2i rpos, bool l, bool r, bool t, bool b) { | |||
| updated_chunks_.insert(cpos); | |||
| if (l) updated_chunks_.insert(cpos + Vec2i(-1, 0)); | |||
| if (r) updated_chunks_.insert(cpos + Vec2i(1, 0)); | |||
| if (t) updated_chunks_.insert(cpos + Vec2i(0, -1)); | |||
| if (b) updated_chunks_.insert(cpos + Vec2i(0, 1)); | |||
| if (l && t) updated_chunks_.insert(cpos + Vec2i(-1, -1)); | |||
| if (r && t) updated_chunks_.insert(cpos + Vec2i(1, -1)); | |||
| if (l && b) updated_chunks_.insert(cpos + Vec2i(-1, 1)); | |||
| if (r && b) updated_chunks_.insert(cpos + Vec2i(1, 1)); | |||
| updatedChunks_.insert(cpos); | |||
| if (l) updatedChunks_.insert(cpos + Vec2i(-1, 0)); | |||
| if (r) updatedChunks_.insert(cpos + Vec2i(1, 0)); | |||
| if (t) updatedChunks_.insert(cpos + Vec2i(0, -1)); | |||
| if (b) updatedChunks_.insert(cpos + Vec2i(0, 1)); | |||
| if (l && t) updatedChunks_.insert(cpos + Vec2i(-1, -1)); | |||
| if (r && t) updatedChunks_.insert(cpos + Vec2i(1, -1)); | |||
| if (l && b) updatedChunks_.insert(cpos + Vec2i(-1, 1)); | |||
| if (r && b) updatedChunks_.insert(cpos + Vec2i(1, 1)); | |||
| }; | |||
| auto markChunksModified = [&](ChunkPos cpos, Vec2i rpos, float light) { | |||
| @@ -150,28 +150,28 @@ void LightServer::processEvent(const Event &evt, std::vector<NewLightChunk> &new | |||
| switch (evt.tag) { | |||
| case Event::Tag::BLOCK_ADDED: | |||
| ch->blocks.set(rpos.y * CHUNK_WIDTH + rpos.x, true); | |||
| ch->blocks_line[rpos.x] += 1; | |||
| ch->blocksLine[rpos.x] += 1; | |||
| markChunksModifiedRange(cpos, rpos, LIGHT_CUTOFF_DIST); | |||
| break; | |||
| case Event::Tag::BLOCK_REMOVED: | |||
| ch->blocks.set(rpos.y * CHUNK_WIDTH + rpos.x, false); | |||
| ch->blocks_line[rpos.x] -= 1; | |||
| ch->blocksLine[rpos.x] -= 1; | |||
| markChunksModifiedRange(cpos, rpos, LIGHT_CUTOFF_DIST); | |||
| break; | |||
| case Event::Tag::LIGHT_ADDED: | |||
| info << cpos << ": Add " << evt.f << " light to " << rpos; | |||
| ch->light_sources[rpos] += evt.f; | |||
| markChunksModified(cpos, rpos, ch->light_sources[rpos]); | |||
| ch->lightSources[rpos] += evt.f; | |||
| markChunksModified(cpos, rpos, ch->lightSources[rpos]); | |||
| break; | |||
| case Event::Tag::LIGHT_REMOVED: | |||
| info << cpos << ": Remove " << evt.f << " light to " << rpos; | |||
| markChunksModified(cpos, rpos, ch->light_sources[rpos]); | |||
| ch->light_sources[rpos] -= evt.f; | |||
| if (ch->light_sources[rpos] < LIGHT_CUTOFF) { | |||
| ch->light_sources.erase(rpos); | |||
| markChunksModified(cpos, rpos, ch->lightSources[rpos]); | |||
| ch->lightSources[rpos] -= evt.f; | |||
| if (ch->lightSources[rpos] < LIGHT_CUTOFF) { | |||
| ch->lightSources.erase(rpos); | |||
| } | |||
| break; | |||
| @@ -319,14 +319,14 @@ void LightServer::processChunkSun(LightChunk &chunk, ChunkPos cpos) { | |||
| } | |||
| for (int rx = 0; rx < CHUNK_WIDTH; ++rx) { | |||
| bool lit = light > 0 && tc && tc->blocks_line[rx] == 0 && !line[rx]; | |||
| bool lit = light > 0 && tc && tc->blocksLine[rx] == 0 && !line[rx]; | |||
| if (lit) { | |||
| chunk.light_buffer()[ry * CHUNK_WIDTH + rx] = light; | |||
| chunk.lightBuffer()[ry * CHUNK_WIDTH + rx] = light; | |||
| if (chunk.blocks[ry * CHUNK_WIDTH + rx]) { | |||
| line[rx] = true; | |||
| } | |||
| } else { | |||
| chunk.light_buffer()[ry * CHUNK_WIDTH + rx] = 0; | |||
| chunk.lightBuffer()[ry * CHUNK_WIDTH + rx] = 0; | |||
| } | |||
| } | |||
| } | |||
| @@ -336,7 +336,7 @@ void LightServer::processChunkLights(LightChunk &chunk, ChunkPos cpos) { | |||
| TilePos base = cpos * Vec2i(CHUNK_WIDTH, CHUNK_HEIGHT); | |||
| std::vector<std::pair<TilePos, float>> lights; | |||
| for (auto &[pos, level]: chunk.light_sources) { | |||
| for (auto &[pos, level]: chunk.lightSources) { | |||
| lights.emplace_back(Vec2i(pos) + base, level); | |||
| } | |||
| @@ -346,7 +346,7 @@ void LightServer::processChunkLights(LightChunk &chunk, ChunkPos cpos) { | |||
| } | |||
| TilePos b = base + Vec2i(dx * CHUNK_WIDTH, dy * CHUNK_HEIGHT); | |||
| for (auto &[pos, level]: chunk->light_sources) { | |||
| for (auto &[pos, level]: chunk->lightSources) { | |||
| lights.emplace_back(TilePos(pos) + b, level); | |||
| } | |||
| }; | |||
| @@ -362,7 +362,7 @@ void LightServer::processChunkLights(LightChunk &chunk, ChunkPos cpos) { | |||
| for (int y = 0; y < CHUNK_HEIGHT; ++y) { | |||
| for (int x = 0; x < CHUNK_WIDTH; ++x) { | |||
| float light = recalcTile(chunk, cpos, Vec2i(x, y), base, lights); | |||
| chunk.light_buffer()[y * CHUNK_WIDTH + x] += light; | |||
| chunk.lightBuffer()[y * CHUNK_WIDTH + x] += light; | |||
| if (light > 0 && chunk.blocks[y * CHUNK_WIDTH + x]) { | |||
| chunk.bounces.emplace_back(base + Vec2i(x, y), light * 0.1); | |||
| @@ -399,8 +399,8 @@ void LightServer::processChunkBounces(LightChunk &chunk, ChunkPos cpos) { | |||
| for (int y = 0; y < CHUNK_HEIGHT; ++y) { | |||
| for (int x = 0; x < CHUNK_WIDTH; ++x) { | |||
| float light = recalcTile(chunk, cpos, Vec2i(x, y), base, lights); | |||
| float sum = chunk.light_buffer()[y * CHUNK_WIDTH + x] + light; | |||
| chunk.light_buffer()[y * CHUNK_WIDTH + x] = sum; | |||
| float sum = chunk.lightBuffer()[y * CHUNK_WIDTH + x] + light; | |||
| chunk.lightBuffer()[y * CHUNK_WIDTH + x] = sum; | |||
| } | |||
| } | |||
| } | |||
| @@ -412,18 +412,18 @@ void LightServer::processChunkSmoothing(LightChunk &chunk, ChunkPos cpos) { | |||
| LightChunk *rc = getChunk(cpos + Vec2i(1, 0)); | |||
| auto getLight = [&](LightChunk &chunk, int x, int y) { | |||
| return chunk.light_buffer()[y * CHUNK_WIDTH + x]; | |||
| return chunk.lightBuffer()[y * CHUNK_WIDTH + x]; | |||
| }; | |||
| auto calc = [&](int x1, int x2, int y1, int y2, auto tf, auto bf, auto lf, auto rf) { | |||
| float *dest = chunk.light_buffers + CHUNK_WIDTH * CHUNK_HEIGHT * ((chunk.buffer + 1) % 2); | |||
| float *dest = chunk.lightBuffers + CHUNK_WIDTH * CHUNK_HEIGHT * ((chunk.buffer + 1) % 2); | |||
| for (int y = y1; y < y2; ++y) { | |||
| for (int x = x1; x < x2; ++x) { | |||
| float t = tf(x, y); | |||
| float b = bf(x, y); | |||
| float l = lf(x, y); | |||
| float r = rf(x, y); | |||
| float light = chunk.light_buffer()[y * CHUNK_WIDTH + x]; | |||
| float light = chunk.lightBuffer()[y * CHUNK_WIDTH + x]; | |||
| int count = 1; | |||
| if (t > light) { light += t; count += 1; } | |||
| if (b > light) { light += b; count += 1; } | |||
| @@ -443,7 +443,7 @@ void LightServer::processChunkSmoothing(LightChunk &chunk, ChunkPos cpos) { | |||
| if (tc) { | |||
| calc(1, CHUNK_WIDTH - 1, 0, 1, | |||
| [&](int x, int y) { return tc->light_buffer()[(CHUNK_HEIGHT - 1) * CHUNK_WIDTH + x]; }, | |||
| [&](int x, int y) { return tc->lightBuffer()[(CHUNK_HEIGHT - 1) * CHUNK_WIDTH + x]; }, | |||
| [&](int x, int y) { return getLight(chunk, x, y + 1); }, | |||
| [&](int x, int y) { return getLight(chunk, x - 1, y); }, | |||
| [&](int x, int y) { return getLight(chunk, x + 1, y); }); | |||
| @@ -452,7 +452,7 @@ void LightServer::processChunkSmoothing(LightChunk &chunk, ChunkPos cpos) { | |||
| if (bc) { | |||
| calc(1, CHUNK_WIDTH - 1, CHUNK_HEIGHT - 1, CHUNK_HEIGHT, | |||
| [&](int x, int y) { return getLight(chunk, x, y - 1); }, | |||
| [&](int x, int y) { return bc->light_buffer()[x]; }, | |||
| [&](int x, int y) { return bc->lightBuffer()[x]; }, | |||
| [&](int x, int y) { return getLight(chunk, x - 1, y); }, | |||
| [&](int x, int y) { return getLight(chunk, x + 1, y); }); | |||
| } | |||
| @@ -461,7 +461,7 @@ void LightServer::processChunkSmoothing(LightChunk &chunk, ChunkPos cpos) { | |||
| calc(0, 1, 1, CHUNK_HEIGHT - 1, | |||
| [&](int x, int y) { return getLight(chunk, x, y - 1); }, | |||
| [&](int x, int y) { return getLight(chunk, x, y + 1); }, | |||
| [&](int x, int y) { return lc->light_buffer()[y * CHUNK_WIDTH + CHUNK_WIDTH - 1]; }, | |||
| [&](int x, int y) { return lc->lightBuffer()[y * CHUNK_WIDTH + CHUNK_WIDTH - 1]; }, | |||
| [&](int x, int y) { return getLight(chunk, x + 1, y); }); | |||
| } | |||
| @@ -470,47 +470,47 @@ void LightServer::processChunkSmoothing(LightChunk &chunk, ChunkPos cpos) { | |||
| [&](int x, int y) { return getLight(chunk, x, y - 1); }, | |||
| [&](int x, int y) { return getLight(chunk, x, y + 1); }, | |||
| [&](int x, int y) { return getLight(chunk, x - 1, y); }, | |||
| [&](int x, int y) { return rc->light_buffer()[y * CHUNK_WIDTH]; }); | |||
| [&](int x, int y) { return rc->lightBuffer()[y * CHUNK_WIDTH]; }); | |||
| } | |||
| if (tc && lc) { | |||
| calc(0, 1, 0, 1, | |||
| [&](int x, int y) { return tc->light_buffer()[(CHUNK_HEIGHT - 1) * CHUNK_WIDTH + x]; }, | |||
| [&](int x, int y) { return tc->lightBuffer()[(CHUNK_HEIGHT - 1) * CHUNK_WIDTH + x]; }, | |||
| [&](int x, int y) { return getLight(chunk, x, y + 1); }, | |||
| [&](int x, int y) { return lc->light_buffer()[y * CHUNK_WIDTH + CHUNK_WIDTH - 1]; }, | |||
| [&](int x, int y) { return lc->lightBuffer()[y * CHUNK_WIDTH + CHUNK_WIDTH - 1]; }, | |||
| [&](int x, int y) { return getLight(chunk, x + 1, y); }); | |||
| } | |||
| if (tc && rc) { | |||
| calc(CHUNK_WIDTH - 1, CHUNK_WIDTH, 0, 1, | |||
| [&](int x, int y) { return tc->light_buffer()[(CHUNK_HEIGHT - 1) * CHUNK_WIDTH + x]; }, | |||
| [&](int x, int y) { return tc->lightBuffer()[(CHUNK_HEIGHT - 1) * CHUNK_WIDTH + x]; }, | |||
| [&](int x, int y) { return getLight(chunk, x, y + 1); }, | |||
| [&](int x, int y) { return getLight(chunk, x - 1, y); }, | |||
| [&](int x, int y) { return rc->light_buffer()[y * CHUNK_WIDTH]; }); | |||
| [&](int x, int y) { return rc->lightBuffer()[y * CHUNK_WIDTH]; }); | |||
| } | |||
| if (bc && lc) { | |||
| calc(0, 1, CHUNK_HEIGHT - 1, CHUNK_HEIGHT, | |||
| [&](int x, int y) { return getLight(chunk, x, y - 1); }, | |||
| [&](int x, int y) { return bc->light_buffer()[x]; }, | |||
| [&](int x, int y) { return lc->light_buffer()[y * CHUNK_WIDTH + CHUNK_WIDTH - 1]; }, | |||
| [&](int x, int y) { return bc->lightBuffer()[x]; }, | |||
| [&](int x, int y) { return lc->lightBuffer()[y * CHUNK_WIDTH + CHUNK_WIDTH - 1]; }, | |||
| [&](int x, int y) { return getLight(chunk, x + 1, y); }); | |||
| } | |||
| if (bc && rc) { | |||
| calc(CHUNK_WIDTH - 1, CHUNK_WIDTH, CHUNK_HEIGHT - 1, CHUNK_HEIGHT, | |||
| [&](int x, int y) { return getLight(chunk, x, y - 1); }, | |||
| [&](int x, int y) { return bc->light_buffer()[x]; }, | |||
| [&](int x, int y) { return bc->lightBuffer()[x]; }, | |||
| [&](int x, int y) { return getLight(chunk, x - 1, y); }, | |||
| [&](int x, int y) { return rc->light_buffer()[y * CHUNK_WIDTH]; }); | |||
| [&](int x, int y) { return rc->lightBuffer()[y * CHUNK_WIDTH]; }); | |||
| } | |||
| } | |||
| void LightServer::finalizeChunk(LightChunk &chunk) { | |||
| for (int y = 0; y < CHUNK_HEIGHT; ++y) { | |||
| for (int x = 0; x < CHUNK_WIDTH; ++x) { | |||
| chunk.light_levels[y * CHUNK_WIDTH + x] = | |||
| linToSRGB(chunk.light_buffer()[y * CHUNK_HEIGHT + x]); | |||
| chunk.lightLevels[y * CHUNK_WIDTH + x] = | |||
| linToSRGB(chunk.lightBuffer()[y * CHUNK_HEIGHT + x]); | |||
| } | |||
| } | |||
| } | |||
| @@ -522,11 +522,11 @@ void LightServer::run() { | |||
| cond_.wait(lock, [&] { return buffers_[buffer_].size() > 0 || !running_; }); | |||
| std::vector<Event> &buf = buffers_[buffer_]; | |||
| std::vector<NewLightChunk> &newChunks = new_chunk_buffers_[buffer_]; | |||
| std::vector<NewLightChunk> &newChunks = newChunkBuffers_[buffer_]; | |||
| buffer_ = (buffer_ + 1) % 2; | |||
| lock.unlock(); | |||
| updated_chunks_.clear(); | |||
| updatedChunks_.clear(); | |||
| for (auto &evt: buf) { | |||
| processEvent(evt, newChunks); | |||
| } | |||
| @@ -536,21 +536,21 @@ void LightServer::run() { | |||
| auto start = std::chrono::steady_clock::now(); | |||
| for (auto &pos: updated_chunks_) { | |||
| for (auto &pos: updatedChunks_) { | |||
| auto ch = chunks_.find(pos); | |||
| if (ch != chunks_.end()) { | |||
| processChunkSun(ch->second, ChunkPos(pos.first, pos.second)); | |||
| } | |||
| } | |||
| for (auto &pos: updated_chunks_) { | |||
| for (auto &pos: updatedChunks_) { | |||
| auto ch = chunks_.find(pos); | |||
| if (ch != chunks_.end()) { | |||
| processChunkLights(ch->second, ChunkPos(pos.first, pos.second)); | |||
| } | |||
| } | |||
| for (auto &pos: updated_chunks_) { | |||
| for (auto &pos: updatedChunks_) { | |||
| auto ch = chunks_.find(pos); | |||
| if (ch != chunks_.end()) { | |||
| processChunkBounces(ch->second, ChunkPos(pos.first, pos.second)); | |||
| @@ -558,7 +558,7 @@ void LightServer::run() { | |||
| } | |||
| for (int i = 0; i < 4; ++i) { | |||
| for (auto &pos: updated_chunks_) { | |||
| for (auto &pos: updatedChunks_) { | |||
| auto ch = chunks_.find(pos); | |||
| if (ch != chunks_.end()) { | |||
| processChunkSmoothing(ch->second, ChunkPos(pos.first, pos.second)); | |||
| @@ -567,7 +567,7 @@ void LightServer::run() { | |||
| } | |||
| } | |||
| for (auto &pos: updated_chunks_) { | |||
| for (auto &pos: updatedChunks_) { | |||
| auto ch = chunks_.find(pos); | |||
| if (ch != chunks_.end()) { | |||
| finalizeChunk(ch->second); | |||
| @@ -576,10 +576,10 @@ void LightServer::run() { | |||
| auto end = std::chrono::steady_clock::now(); | |||
| auto dur = std::chrono::duration<double, std::milli>(end - start); | |||
| info << "Generating light for " << updated_chunks_.size() | |||
| info << "Generating light for " << updatedChunks_.size() | |||
| << " chunks took " << dur.count() << "ms"; | |||
| for (auto &pos: updated_chunks_) { | |||
| for (auto &pos: updatedChunks_) { | |||
| auto ch = chunks_.find(pos); | |||
| if (ch != chunks_.end()) { | |||
| cb_.onLightChunkUpdated(ch->second, pos); | |||
| @@ -18,7 +18,7 @@ std::unique_ptr<Tile> Tile::createAir(const ResourceManager &resources) { | |||
| return std::make_unique<Tile>(resources, Builder{ | |||
| .name = "@::air", | |||
| .image = "@::air", | |||
| .is_solid = false, | |||
| .isSolid = false, | |||
| }); | |||
| } | |||
| @@ -19,17 +19,16 @@ static void chunkLine(int l, WorldPlane &plane, ChunkPos &abspos, const Vec2i &d | |||
| World::World(Game *game, unsigned long rand_seed): | |||
| game_(game), random_(rand_seed), resources_(game->win_) { | |||
| std::unique_ptr<Tile> invalid_tile = Tile::createInvalid(resources_); | |||
| tiles_map_[invalid_tile->name_] = 0; | |||
| std::unique_ptr<Tile> invalidTile = Tile::createInvalid(resources_); | |||
| tilesMap_[invalidTile->name_] = 0; | |||
| // tiles_ is empty, so pushing back now will ensure invalid_tile | |||
| // ends up at location 0 | |||
| tiles_.push_back(std::move(invalid_tile)); | |||
| tiles_.push_back(std::move(invalidTile)); | |||
| // We're also going to need an air tile at location 1 | |||
| tiles_.push_back(Tile::createAir(resources_)); | |||
| tiles_map_["@::air"] = 1; | |||
| tilesMap_["@::air"] = 1; | |||
| } | |||
| void World::ChunkRenderer::tick(WorldPlane &plane, ChunkPos abspos) { | |||
| @@ -56,7 +55,7 @@ void World::addMod(ModWrapper &&mod) { | |||
| for (auto t: mod.buildTiles(resources_)) { | |||
| Tile::ID id = tiles_.size(); | |||
| tiles_map_[t->name_] = id; | |||
| tilesMap_[t->name_] = id; | |||
| tiles_.push_back(std::move(t)); | |||
| } | |||
| @@ -65,43 +64,43 @@ void World::addMod(ModWrapper &&mod) { | |||
| } | |||
| for (auto fact: mod.getWorldGens()) { | |||
| worldgen_factories_.emplace( | |||
| worldgenFactories_.emplace( | |||
| std::piecewise_construct, | |||
| std::forward_as_tuple(fact.name), | |||
| std::forward_as_tuple(fact)); | |||
| } | |||
| for (auto fact: mod.getEntities()) { | |||
| ent_coll_factories_.push_back(fact); | |||
| entCollFactories_.push_back(fact); | |||
| } | |||
| mods_.push_back(std::move(mod)); | |||
| } | |||
| void World::setWorldGen(std::string gen) { | |||
| default_world_gen_ = std::move(gen); | |||
| defaultWorldGen_ = std::move(gen); | |||
| } | |||
| void World::spawnPlayer() { | |||
| player_ = &((dynamic_cast<BodyTrait *>( | |||
| planes_[current_plane_]->spawnPlayer().get()))->get(BodyTrait::Tag{})); | |||
| planes_[currentPlane_]->spawnPlayer().get()))->get(BodyTrait::Tag{})); | |||
| } | |||
| void World::setCurrentPlane(WorldPlane &plane) { | |||
| current_plane_ = plane.id_; | |||
| currentPlane_ = plane.id_; | |||
| } | |||
| WorldPlane &World::addPlane(const std::string &gen) { | |||
| WorldPlane::ID id = planes_.size(); | |||
| auto it = worldgen_factories_.find(gen); | |||
| if (it == worldgen_factories_.end()) { | |||
| auto it = worldgenFactories_.find(gen); | |||
| if (it == worldgenFactories_.end()) { | |||
| panic << "Tried to add plane with non-existant world gen " << gen << "!"; | |||
| abort(); | |||
| } | |||
| std::vector<std::unique_ptr<EntityCollection>> colls; | |||
| colls.reserve(ent_coll_factories_.size()); | |||
| for (auto &fact: ent_coll_factories_) { | |||
| colls.reserve(entCollFactories_.size()); | |||
| for (auto &fact: entCollFactories_) { | |||
| colls.emplace_back(fact.create(fact.name)); | |||
| } | |||
| @@ -116,15 +115,15 @@ Item &World::getItem(const std::string &name) { | |||
| auto iter = items_.find(name); | |||
| if (iter == items_.end()) { | |||
| warn << "Tried to get non-existant item " << name << "!"; | |||
| return *game_->invalid_item_; | |||
| return *game_->invalidItem_; | |||
| } | |||
| return *iter->second; | |||
| } | |||
| Tile::ID World::getTileID(const std::string &name) { | |||
| auto iter = tiles_map_.find(name); | |||
| if (iter == tiles_map_.end()) { | |||
| auto iter = tilesMap_.find(name); | |||
| if (iter == tilesMap_.end()) { | |||
| warn << "Tried to get non-existant item " << name << "!"; | |||
| return Tile::INVALID_ID; | |||
| } | |||
| @@ -138,13 +137,13 @@ Tile &World::getTile(const std::string &name) { | |||
| } | |||
| SDL_Color World::backgroundColor() { | |||
| return planes_[current_plane_]->backgroundColor(); | |||
| return planes_[currentPlane_]->backgroundColor(); | |||
| } | |||
| void World::draw(Win &win) { | |||
| ZoneScopedN("World draw"); | |||
| win.cam_ = player_->pos - (win.getSize() / 2) + (player_->size / 2); | |||
| planes_[current_plane_]->draw(win); | |||
| planes_[currentPlane_]->draw(win); | |||
| } | |||
| void World::update(float dt) { | |||
| @@ -158,8 +157,8 @@ void World::tick(float dt) { | |||
| for (auto &plane: planes_) | |||
| plane->tick(dt); | |||
| chunk_renderer_.tick( | |||
| *planes_[current_plane_], | |||
| chunkRenderer_.tick( | |||
| *planes_[currentPlane_], | |||
| ChunkPos((int)player_->pos.x / CHUNK_WIDTH, (int)player_->pos.y / CHUNK_HEIGHT)); | |||
| } | |||
| @@ -47,16 +47,16 @@ WorldPlane::WorldPlane( | |||
| std::vector<std::unique_ptr<EntityCollection>> &&colls): | |||
| id_(id), world_(world), gen_(std::move(gen)), | |||
| lighting_(std::make_unique<LightServer>(*this)), | |||
| ent_colls_(std::move(colls)) { | |||
| entColls_(std::move(colls)) { | |||
| for (auto &coll: ent_colls_) { | |||
| ent_colls_by_type_[coll->type()] = coll.get(); | |||
| ent_colls_by_name_[coll->name()] = coll.get(); | |||
| for (auto &coll: entColls_) { | |||
| entCollsByType_[coll->type()] = coll.get(); | |||
| entCollsByName_[coll->name()] = coll.get(); | |||
| } | |||
| } | |||
| EntityRef WorldPlane::spawnEntity(const std::string &name, const Entity::PackObject &obj) { | |||
| return ent_colls_by_name_.at(name)->spawn(getContext(), obj); | |||
| return entCollsByName_.at(name)->spawn(getContext(), obj); | |||
| } | |||
| bool WorldPlane::hasChunk(ChunkPos pos) { | |||
| @@ -66,13 +66,13 @@ bool WorldPlane::hasChunk(ChunkPos pos) { | |||
| // This function will be a bit weird because it's a really fucking hot function. | |||
| Chunk &WorldPlane::getChunk(ChunkPos pos) { | |||
| // First, look through all chunks which have been in use this tick | |||
| for (auto [chpos, chunk]: tick_chunks_) { | |||
| for (auto [chpos, chunk]: tickChunks_) { | |||
| if (chpos == pos) | |||
| return *chunk; | |||
| } | |||
| Chunk &chunk = slowGetChunk(pos); | |||
| tick_chunks_.push_back({ pos, &chunk }); | |||
| tickChunks_.push_back({ pos, &chunk }); | |||
| return chunk; | |||
| } | |||
| @@ -86,8 +86,8 @@ Chunk &WorldPlane::slowGetChunk(ChunkPos pos) { | |||
| Chunk &chunk = iter->second; | |||
| gen_->genChunk(*this, chunk); | |||
| active_chunks_.push_back(&chunk); | |||
| chunk_init_list_.push_back(&chunk); | |||
| activeChunks_.push_back(&chunk); | |||
| chunkInitList_.push_back(&chunk); | |||
| // Need to tell the light engine too | |||
| NewLightChunk lc; | |||
| @@ -95,11 +95,11 @@ Chunk &WorldPlane::slowGetChunk(ChunkPos pos) { | |||
| for (int x = 0; x < CHUNK_WIDTH; ++x) { | |||
| Tile::ID id = chunk.getTileID({ x, y }); | |||
| Tile &tile = world_->getTileByID(id); | |||
| if (tile.is_solid_) { | |||
| if (tile.isSolid_) { | |||
| lc.blocks[y * CHUNK_HEIGHT + x] = true; | |||
| } | |||
| if (tile.light_level_ > 0) { | |||
| lc.light_sources[{ x, y }] = tile.light_level_; | |||
| if (tile.lightLevel_ > 0) { | |||
| lc.light_sources[{ x, y }] = tile.lightLevel_; | |||
| } | |||
| } | |||
| } | |||
| @@ -109,8 +109,8 @@ Chunk &WorldPlane::slowGetChunk(ChunkPos pos) { | |||
| // Otherwise, it might not be active, so let's activate it | |||
| } else if (!iter->second.isActive()) { | |||
| iter->second.keepActive(); | |||
| active_chunks_.push_back(&iter->second); | |||
| chunk_init_list_.push_back(&iter->second); | |||
| activeChunks_.push_back(&iter->second); | |||
| chunkInitList_.push_back(&iter->second); | |||
| } | |||
| return iter->second; | |||
| @@ -127,19 +127,19 @@ void WorldPlane::setTileID(TilePos pos, Tile::ID id) { | |||
| chunk.setTileID(rp, id, newTile.image_.texture_.get()); | |||
| chunk.markModified(); | |||
| if (!oldTile.is_solid_ && newTile.is_solid_) { | |||
| if (!oldTile.isSolid_ && newTile.isSolid_) { | |||
| lighting_->onSolidBlockAdded(pos); | |||
| } else if (oldTile.is_solid_ && !newTile.is_solid_) { | |||
| } else if (oldTile.isSolid_ && !newTile.isSolid_) { | |||
| lighting_->onSolidBlockRemoved(pos); | |||
| } | |||
| if (newTile.light_level_ != oldTile.light_level_) { | |||
| if (oldTile.light_level_ > 0) { | |||
| removeLight(pos, oldTile.light_level_); | |||
| if (newTile.lightLevel_ != oldTile.lightLevel_) { | |||
| if (oldTile.lightLevel_ > 0) { | |||
| removeLight(pos, oldTile.lightLevel_); | |||
| } | |||
| if (newTile.light_level_ > 0) { | |||
| addLight(pos, newTile.light_level_); | |||
| if (newTile.lightLevel_ > 0) { | |||
| addLight(pos, newTile.lightLevel_); | |||
| } | |||
| } | |||
| } | |||
| @@ -196,7 +196,7 @@ void WorldPlane::breakTile(TilePos pos) { | |||
| // Change tile to air and emit event | |||
| setTileID(pos, air); | |||
| world_->evt_tile_break_.emit(getContext(), pos, world_->getTileByID(id)); | |||
| world_->evtTileBreak_.emit(getContext(), pos, world_->getTileByID(id)); | |||
| } | |||
| SDL_Color WorldPlane::backgroundColor() { | |||
| @@ -216,9 +216,9 @@ void WorldPlane::draw(Win &win) { | |||
| (int)floor(pbody.pos.y / CHUNK_HEIGHT)); | |||
| // Just init one chunk per frame | |||
| if (chunk_init_list_.size() > 0) { | |||
| Chunk *chunk = chunk_init_list_.front(); | |||
| chunk_init_list_.pop_front(); | |||
| if (chunkInitList_.size() > 0) { | |||
| Chunk *chunk = chunkInitList_.front(); | |||
| chunkInitList_.pop_front(); | |||
| chunk->render(ctx, win.renderer_); | |||
| } | |||
| @@ -230,11 +230,11 @@ void WorldPlane::draw(Win &win) { | |||
| } | |||
| } | |||
| for (auto &coll: ent_colls_) | |||
| for (auto &coll: entColls_) | |||
| coll->draw(ctx, win); | |||
| if (debug_boxes_.size() > 0) { | |||
| for (auto &pos: debug_boxes_) { | |||
| if (debugBoxes_.size() > 0) { | |||
| for (auto &pos: debugBoxes_) { | |||
| win.drawRect(pos, Vec2(1, 1)); | |||
| } | |||
| } | |||
| @@ -244,9 +244,9 @@ void WorldPlane::update(float dt) { | |||
| ZoneScopedN("WorldPlane update"); | |||
| std::lock_guard<std::mutex> lock(mut_); | |||
| auto ctx = getContext(); | |||
| debug_boxes_.clear(); | |||
| debugBoxes_.clear(); | |||
| for (auto &coll: ent_colls_) | |||
| for (auto &coll: entColls_) | |||
| coll->update(ctx, dt); | |||
| } | |||
| @@ -256,16 +256,16 @@ void WorldPlane::tick(float dt) { | |||
| auto ctx = getContext(); | |||
| // Any chunk which has been in use since last tick should be kept alive | |||
| for (std::pair<ChunkPos, Chunk *> &ch: tick_chunks_) | |||
| for (std::pair<ChunkPos, Chunk *> &ch: tickChunks_) | |||
| ch.second->keepActive(); | |||
| tick_chunks_.clear(); | |||
| tickChunks_.clear(); | |||
| for (auto &coll: ent_colls_) | |||
| for (auto &coll: entColls_) | |||
| coll->tick(ctx, dt); | |||
| // Tick all chunks, figure out if any of them should be deleted or compressed | |||
| auto iter = active_chunks_.begin(); | |||
| auto last = active_chunks_.end(); | |||
| auto iter = activeChunks_.begin(); | |||
| auto last = activeChunks_.end(); | |||
| while (iter != last) { | |||
| auto &chunk = *iter; | |||
| auto action = chunk->tick(dt); | |||
| @@ -274,14 +274,14 @@ void WorldPlane::tick(float dt) { | |||
| case Chunk::TickAction::DEACTIVATE: | |||
| info << "Compressing inactive modified chunk " << chunk->pos_; | |||
| chunk->compress(); | |||
| iter = active_chunks_.erase(iter); | |||
| last = active_chunks_.end(); | |||
| iter = activeChunks_.erase(iter); | |||
| last = activeChunks_.end(); | |||
| break; | |||
| case Chunk::TickAction::DELETE: | |||
| info << "Deleting inactive unmodified chunk " << chunk->pos_; | |||
| chunks_.erase(chunk->pos_); | |||
| iter = active_chunks_.erase(iter); | |||
| last = active_chunks_.end(); | |||
| iter = activeChunks_.erase(iter); | |||
| last = activeChunks_.end(); | |||
| break; | |||
| case Chunk::TickAction::NOTHING: | |||
| ++iter; | |||
| @@ -291,7 +291,7 @@ void WorldPlane::tick(float dt) { | |||
| } | |||
| void WorldPlane::debugBox(TilePos pos) { | |||
| debug_boxes_.push_back(pos); | |||
| debugBoxes_.push_back(pos); | |||
| } | |||
| void WorldPlane::addLight(TilePos pos, float level) { | |||
| @@ -307,7 +307,7 @@ void WorldPlane::removeLight(TilePos pos, float level) { | |||
| void WorldPlane::onLightChunkUpdated(const LightChunk &chunk, ChunkPos pos) { | |||
| std::lock_guard<std::mutex> lock(mut_); | |||
| Chunk &realChunk = getChunk(pos); | |||
| realChunk.setLightData(chunk.light_levels); | |||
| realChunk.setLightData(chunk.lightLevels); | |||
| } | |||
| } | |||
| @@ -15,7 +15,7 @@ static void collideX( | |||
| for (int y = (int)floor(body.top() + epsilon); y <= (int)floor(body.bottom() - epsilon); ++y) { | |||
| int lx = (int)floor(body.left() + epsilon); | |||
| Tile &left = plane.getTile({ lx, y }); | |||
| if (left.is_solid_) { | |||
| if (left.isSolid_) { | |||
| body.pos.x = (float)lx + 1.0; | |||
| collided = true; | |||
| break; | |||
| @@ -23,7 +23,7 @@ static void collideX( | |||
| int rx = (int)floor(body.right() - epsilon); | |||
| Tile &right = plane.getTile({ rx, y }); | |||
| if (right.is_solid_) { | |||
| if (right.isSolid_) { | |||
| body.pos.x = (float)rx - body.size.x; | |||
| collided = true; | |||
| break; | |||
| @@ -41,12 +41,12 @@ static void collideY( | |||
| PhysicsTrait::Physics &phys, BodyTrait::Body &body, | |||
| WorldPlane &plane, const PhysicsTrait::PhysicsProps &props) { | |||
| bool collided = false; | |||
| phys.on_ground = false; | |||
| phys.onGround = false; | |||
| for (int x = (int)floor(body.left() + epsilon); x <= (int)floor(body.right() - epsilon); ++x) { | |||
| int ty = (int)floor(body.top() + epsilon); | |||
| Tile &top = plane.getTile({ x, ty }); | |||
| if (top.is_solid_) { | |||
| if (top.isSolid_) { | |||
| body.pos.y = (float)ty + 1.0; | |||
| collided = true; | |||
| break; | |||
| @@ -54,10 +54,10 @@ static void collideY( | |||
| int by = (int)floor(body.bottom() - epsilon); | |||
| Tile &bottom = plane.getTile({ x, by }); | |||
| if (bottom.is_solid_) { | |||
| if (bottom.isSolid_) { | |||
| body.pos.y = (float)by - body.size.y; | |||
| collided = true; | |||
| phys.on_ground = true; | |||
| phys.onGround = true; | |||
| break; | |||
| } | |||
| } | |||
| @@ -40,12 +40,12 @@ test("Insert never overflows") { | |||
| Swan::ItemStack s2(&item1, 40); | |||
| s2 = s1.insert(s2); | |||
| expecteq(s1.count(), item1.max_stack_); | |||
| expecteq(s2.count(), 80 - item1.max_stack_); | |||
| expecteq(s1.count(), item1.maxStack_); | |||
| expecteq(s2.count(), 80 - item1.maxStack_); | |||
| } | |||
| test("Insert respects max_stack_") { | |||
| MockItem item1({ .name = "item1", .image = "no", .max_stack = 20 }); | |||
| MockItem item1({ .name = "item1", .image = "no", .maxStack = 20 }); | |||
| Swan::ItemStack s1(&item1, 15); | |||
| Swan::ItemStack s2(&item1, 19); | |||
| @@ -9,17 +9,17 @@ | |||
| namespace testlib { | |||
| static const std::string color_reset = "\033[0m"; | |||
| static const std::string color_highlight = "\033[1m"; | |||
| static const std::string color_testing = color_highlight; | |||
| static const std::string color_desc = "\033[33m"; | |||
| static const std::string color_maybe = "\033[35m"; | |||
| static const std::string color_success = "\033[32m"; | |||
| static const std::string color_fail = "\033[31m"; | |||
| static const std::string color_errormsg = "\033[95m"; | |||
| static const std::string COLOR_RESET = "\033[0m"; | |||
| static const std::string COLOR_HIGHLIGHT = "\033[1m"; | |||
| static const std::string COLOR_TESTING = COLOR_HIGHLIGHT; | |||
| static const std::string COLOR_DESC = "\033[33m"; | |||
| static const std::string COLOR_MAYBE = "\033[35m"; | |||
| static const std::string COLOR_SUCCESS = "\033[32m"; | |||
| static const std::string COLOR_FAIL = "\033[31m"; | |||
| static const std::string COLOR_ERRORMSG = "\033[95m"; | |||
| std::string color(const std::string &color, std::string_view str) { | |||
| return std::string(color) + std::string(str) + std::string(color_reset); | |||
| return std::string(color) + std::string(str) + std::string(COLOR_RESET); | |||
| } | |||
| struct TestCase { | |||
| @@ -57,8 +57,8 @@ void addTestCase(TestSpec *testcase) { | |||
| static std::stringstream printFailure(const std::string &msg) { | |||
| std::stringstream str; | |||
| str | |||
| << "\r" << color(color_highlight + color_fail, "✕ ") | |||
| << color(color_fail, "Failed: ") << "\n" | |||
| << "\r" << color(COLOR_HIGHLIGHT + COLOR_FAIL, "✕ ") | |||
| << color(COLOR_FAIL, "Failed: ") << "\n" | |||
| << " " << msg << "\n"; | |||
| return str; | |||
| } | |||
| @@ -91,13 +91,13 @@ int main() { | |||
| if (currfile != testcase.filename) { | |||
| currfile = testcase.filename; | |||
| size_t lastslash = currfile.find_last_of('/'); | |||
| std::cout << '\n' << color(color_testing, currfile.substr(lastslash + 1)) << ":\n"; | |||
| std::cout << '\n' << color(COLOR_TESTING, currfile.substr(lastslash + 1)) << ":\n"; | |||
| } | |||
| std::cout | |||
| << color(color_highlight + color_maybe, "? ") | |||
| << color(color_maybe, "Testing: ") | |||
| << color(color_desc, testcase.description) << " " << std::flush; | |||
| << color(COLOR_HIGHLIGHT + COLOR_MAYBE, "? ") | |||
| << color(COLOR_MAYBE, "Testing: ") | |||
| << color(COLOR_DESC, testcase.description) << " " << std::flush; | |||
| bool casefailed = false; | |||
| @@ -105,9 +105,9 @@ int main() { | |||
| totaltests += 1; | |||
| testcase.func(); | |||
| std::cout | |||
| << "\r" << color(color_highlight + color_success, "✓ ") | |||
| << color(color_success, "Success: ") | |||
| << color(color_desc, testcase.description) << "\n"; | |||
| << "\r" << color(COLOR_HIGHLIGHT + COLOR_SUCCESS, "✓ ") | |||
| << color(COLOR_SUCCESS, "Success: ") | |||
| << color(COLOR_DESC, testcase.description) << "\n"; | |||
| totalsuccess += 1; | |||
| } catch (const TestFailure &failure) { | |||
| casefailed = true; | |||
| @@ -54,7 +54,7 @@ int main() { | |||
| png::image<png::rgb_pixel> image(Swan::CHUNK_WIDTH, Swan::CHUNK_HEIGHT); | |||
| for (int y = 0; y < Swan::CHUNK_HEIGHT; ++y) { | |||
| for (int x = 0; x < Swan::CHUNK_WIDTH; ++x) { | |||
| uint8_t light = cb.chunk_.light_levels[y * Swan::CHUNK_WIDTH + x]; | |||
| uint8_t light = cb.chunk_.lightLevels[y * Swan::CHUNK_WIDTH + x]; | |||
| bool block = false; | |||
| if (cb.chunk_.blocks[y * Swan::CHUNK_WIDTH + x]) { | |||
| block = true; | |||
| @@ -45,24 +45,24 @@ int sdlButtonToImGuiButton(uint8_t button) { | |||
| } | |||
| int main(int argc, char **argv) { | |||
| uint32_t winflags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; | |||
| uint32_t renderflags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC; | |||
| float gui_scale = 1; | |||
| uint32_t winFlags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; | |||
| uint32_t renderFlags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC; | |||
| float guiScale = 1; | |||
| for (int i = 1; i < argc; ++i) { | |||
| if (strcmp(argv[i], "--lodpi") == 0) { | |||
| winflags &= ~SDL_WINDOW_ALLOW_HIGHDPI; | |||
| winFlags &= ~SDL_WINDOW_ALLOW_HIGHDPI; | |||
| } else if (strcmp(argv[i], "--fullscreen") == 0) { | |||
| winflags |= SDL_WINDOW_FULLSCREEN_DESKTOP; | |||
| winFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; | |||
| } else if (strcmp(argv[i], "--no-vsync") == 0) { | |||
| renderflags &= ~SDL_RENDERER_PRESENTVSYNC; | |||
| renderFlags &= ~SDL_RENDERER_PRESENTVSYNC; | |||
| } else if (strcmp(argv[i], "--vulkan") == 0) { | |||
| winflags |= SDL_WINDOW_VULKAN; | |||
| winFlags |= SDL_WINDOW_VULKAN; | |||
| } else if (strcmp(argv[i], "--sw-render") == 0) { | |||
| renderflags &= ~SDL_RENDERER_ACCELERATED; | |||
| renderflags |= SDL_RENDERER_SOFTWARE; | |||
| renderFlags &= ~SDL_RENDERER_ACCELERATED; | |||
| renderFlags |= SDL_RENDERER_SOFTWARE; | |||
| } else if (strcmp(argv[i], "--2x") == 0) { | |||
| gui_scale = 2; | |||
| guiScale = 2; | |||
| } else if (strcmp(argv[i], "--gles") == 0) { | |||
| SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles2"); | |||
| } else { | |||
| @@ -73,16 +73,16 @@ int main(int argc, char **argv) { | |||
| sdlassert(SDL_Init(SDL_INIT_VIDEO) >= 0, "Could not initialize SDL"); | |||
| Deferred<SDL_Quit> sdl; | |||
| int imgflags = IMG_INIT_PNG; | |||
| imgassert(IMG_Init(imgflags) == imgflags, "Could not initialize SDL_Image"); | |||
| Deferred<IMG_Quit> sdl_image; | |||
| int imgFlags = IMG_INIT_PNG; | |||
| imgassert(IMG_Init(imgFlags) == imgFlags, "Could not initialize SDL_Image"); | |||
| Deferred<IMG_Quit> sdlImage; | |||
| // Create the window | |||
| CPtr<SDL_Window, SDL_DestroyWindow> window( | |||
| SDL_CreateWindow( | |||
| "Project: SWAN", | |||
| SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, | |||
| (int)(640 * gui_scale), (int)(480 * gui_scale), winflags)); | |||
| (int)(640 * guiScale), (int)(480 * guiScale), winFlags)); | |||
| // Load and display application icon | |||
| CPtr<SDL_Surface, SDL_FreeSurface> icon( | |||
| @@ -91,40 +91,40 @@ int main(int argc, char **argv) { | |||
| SDL_SetWindowIcon(window.get(), icon.get()); | |||
| CPtr<SDL_Renderer, SDL_DestroyRenderer> renderer( | |||
| SDL_CreateRenderer(window.get(), -1, renderflags)); | |||
| SDL_CreateRenderer(window.get(), -1, renderFlags)); | |||
| sdlassert(renderer, "Could not create renderer"); | |||
| SDL_SetRenderDrawBlendMode(renderer.get(), SDL_BLENDMODE_BLEND); | |||
| SDL_SetRenderDrawColor(renderer.get(), 0, 0, 0, 255); | |||
| Win win(window.get(), renderer.get(), gui_scale); | |||
| Win win(window.get(), renderer.get(), guiScale); | |||
| // Init ImGUI and ImGUI_SDL | |||
| IMGUI_CHECKVERSION(); | |||
| CPtr<ImGuiContext, ImGui::DestroyContext> context( | |||
| ImGui::CreateContext()); | |||
| ImGuiSDL::Initialize(renderer.get(), (int)win.getPixSize().x, (int)win.getPixSize().y); | |||
| Deferred<ImGuiSDL::Deinitialize> imgui_sdl; | |||
| Deferred<ImGuiSDL::Deinitialize> imguiSDL; | |||
| info << "Initialized with window size " << win.getPixSize(); | |||
| // ImGuiIO is to glue SDL and ImGUI together | |||
| ImGuiIO& imgui_io = ImGui::GetIO(); | |||
| imgui_io.BackendPlatformName = "imgui_sdl + Project: SWAN"; | |||
| ImGuiIO& imguiIO = ImGui::GetIO(); | |||
| imguiIO.BackendPlatformName = "imgui_sdl + Project: SWAN"; | |||
| // Create a world | |||
| Game game(win); | |||
| std::vector<std::string> mods{ "core.mod" }; | |||
| game.createWorld("core::default", mods); | |||
| auto prev_time = std::chrono::steady_clock::now(); | |||
| auto prevTime = std::chrono::steady_clock::now(); | |||
| float fps_acc = 0; | |||
| float tick_acc = 0; | |||
| float fpsAcc = 0; | |||
| float tickAcc = 0; | |||
| int fcount = 0; | |||
| int slow_frames = 0; | |||
| int fCount = 0; | |||
| int slowFrames = 0; | |||
| while (1) { | |||
| ZoneScopedN("game loop"); | |||
| RTClock total_time_clock; | |||
| RTClock totalTimeClock; | |||
| SDL_Event evt; | |||
| while (SDL_PollEvent(&evt)) { | |||
| @@ -135,8 +135,8 @@ int main(int argc, char **argv) { | |||
| case SDL_WINDOWEVENT: | |||
| if (evt.window.event == SDL_WINDOWEVENT_RESIZED) { | |||
| imgui_io.DisplaySize.x = (float)evt.window.data1; | |||
| imgui_io.DisplaySize.y = (float)evt.window.data2; | |||
| imguiIO.DisplaySize.x = (float)evt.window.data1; | |||
| imguiIO.DisplaySize.y = (float)evt.window.data2; | |||
| win.onResize(evt.window.data1, evt.window.data2); | |||
| } | |||
| break; | |||
| @@ -150,64 +150,64 @@ int main(int argc, char **argv) { | |||
| break; | |||
| case SDL_MOUSEMOTION: | |||
| imgui_io.MousePos.x = (float)evt.motion.x; | |||
| imgui_io.MousePos.y = (float)evt.motion.y; | |||
| if (!imgui_io.WantCaptureMouse) | |||
| imguiIO.MousePos.x = (float)evt.motion.x; | |||
| imguiIO.MousePos.y = (float)evt.motion.y; | |||
| if (!imguiIO.WantCaptureMouse) | |||
| game.onMouseMove(evt.motion.x, evt.motion.y); | |||
| break; | |||
| case SDL_MOUSEBUTTONDOWN: | |||
| imgui_io.MouseDown[sdlButtonToImGuiButton(evt.button.button)] = true; | |||
| if (!imgui_io.WantCaptureMouse) | |||
| imguiIO.MouseDown[sdlButtonToImGuiButton(evt.button.button)] = true; | |||
| if (!imguiIO.WantCaptureMouse) | |||
| game.onMouseDown(evt.button.x, evt.button.y, evt.button.button); | |||
| break; | |||
| case SDL_MOUSEBUTTONUP: | |||
| imgui_io.MouseDown[sdlButtonToImGuiButton(evt.button.button)] = false; | |||
| if (!imgui_io.WantCaptureMouse) | |||
| imguiIO.MouseDown[sdlButtonToImGuiButton(evt.button.button)] = false; | |||
| if (!imguiIO.WantCaptureMouse) | |||
| game.onMouseUp(evt.button.x, evt.button.y, evt.button.button); | |||
| break; | |||
| case SDL_MOUSEWHEEL: | |||
| imgui_io.MouseWheel += (float)evt.wheel.y; | |||
| if (!imgui_io.WantCaptureMouse) | |||
| imguiIO.MouseWheel += (float)evt.wheel.y; | |||
| if (!imguiIO.WantCaptureMouse) | |||
| game.onScrollWheel(evt.wheel.y); | |||
| break; | |||
| } | |||
| } | |||
| auto now = std::chrono::steady_clock::now(); | |||
| std::chrono::duration<float> dur(now - prev_time); | |||
| prev_time = now; | |||
| std::chrono::duration<float> dur(now - prevTime); | |||
| prevTime = now; | |||
| float dt = dur.count(); | |||
| // Display FPS | |||
| fps_acc += dt; | |||
| fcount += 1; | |||
| if (fps_acc >= 4) { | |||
| info << "FPS: " << fcount / 4.0; | |||
| fps_acc -= 4; | |||
| fcount = 0; | |||
| fpsAcc += dt; | |||
| fCount += 1; | |||
| if (fpsAcc >= 4) { | |||
| info << "FPS: " << fCount / 4.0; | |||
| fpsAcc -= 4; | |||
| fCount = 0; | |||
| } | |||
| // We want to warn if one frame takes over 0.1 seconds... | |||
| if (dt > 0.1) { | |||
| if (slow_frames == 0) | |||
| if (slowFrames == 0) | |||
| warn << "Delta time too high! (" << dt << "s)"; | |||
| slow_frames += 1; | |||
| slowFrames += 1; | |||
| // And we never want to do physics as if our one frame is greater than | |||
| // 0.5 seconds. | |||
| if (dt > 0.5) | |||
| dt = 0.5; | |||
| } else if (slow_frames > 0) { | |||
| if (slow_frames > 1) | |||
| warn << slow_frames << " consecutive slow frames."; | |||
| slow_frames = 0; | |||
| } else if (slowFrames > 0) { | |||
| if (slowFrames > 1) | |||
| warn << slowFrames << " consecutive slow frames."; | |||
| slowFrames = 0; | |||
| } | |||
| // Simple case: we can keep up, only need one physics update | |||
| RTClock update_clock; | |||
| RTClock updateClock; | |||
| if (dt <= 1 / 25.0) { | |||
| ZoneScopedN("game update"); | |||
| game.update(dt); | |||
| @@ -226,10 +226,10 @@ int main(int argc, char **argv) { | |||
| } | |||
| // Tick at a consistent TICK_RATE | |||
| tick_acc += dt; | |||
| while (tick_acc >= 1.0 / TICK_RATE) { | |||
| tickAcc += dt; | |||
| while (tickAcc >= 1.0 / TICK_RATE) { | |||
| ZoneScopedN("game tick"); | |||
| tick_acc -= 1.0 / TICK_RATE; | |||
| tickAcc -= 1.0 / TICK_RATE; | |||
| RTClock tick_clock; | |||
| game.tick(1.0 / TICK_RATE); | |||
| } | |||
| @@ -241,12 +241,12 @@ int main(int argc, char **argv) { | |||
| } | |||
| // ImGUI | |||
| imgui_io.DeltaTime = dt; | |||
| imguiIO.DeltaTime = dt; | |||
| ImGui::NewFrame(); | |||
| { | |||
| ZoneScopedN("game draw"); | |||
| RTClock draw_clock; | |||
| RTClock drawClock; | |||
| game.draw(); | |||
| } | |||
| @@ -257,7 +257,7 @@ int main(int argc, char **argv) { | |||
| ImGuiSDL::Render(ImGui::GetDrawData()); | |||
| } | |||
| RTClock present_clock; | |||
| RTClock presentClock; | |||
| { | |||
| ZoneScopedN("render present"); | |||
| SDL_RenderPresent(renderer.get()); | |||
| @@ -3,11 +3,11 @@ | |||
| #include <PerlinNoise/PerlinNoise.hpp> | |||
| #include <png++/png.hpp> | |||
| static int grassLevel(const siv::PerlinNoise &perlin, int x) { | |||
| static int getGrassLevel(const siv::PerlinNoise &perlin, int x) { | |||
| return (int)(perlin.noise(x / 50.0, 0) * 13); | |||
| } | |||
| static int stoneLevel(const siv::PerlinNoise &perlin, int x) { | |||
| static int getStoneLevel(const siv::PerlinNoise &perlin, int x) { | |||
| return (int)(perlin.noise(x / 50.0, 10) * 10) + 10; | |||
| } | |||
| @@ -24,25 +24,25 @@ int main() { | |||
| for (int x = x1; x <= x2; ++x) { | |||
| int px = x - x1; | |||
| int grass_level = grassLevel(perlin, x); | |||
| int stone_level = stoneLevel(perlin, x); | |||
| int grassLevel = getGrassLevel(perlin, x); | |||
| int stoneLevel = getStoneLevel(perlin, x); | |||
| for (int y = y1; y <= y2; ++y) { | |||
| int py = y - y1; | |||
| if (y > grass_level + 10) { | |||
| if (y > grassLevel + 10) { | |||
| double l = perlin.noise(x / 41.37, y / 16.37); | |||
| if (l > 0.2) | |||
| image[py][px] = 255; | |||
| else | |||
| image[py][px] = 0; | |||
| } else if (y >= grass_level) { | |||
| } else if (y >= grassLevel) { | |||
| image[py][px] = 0; | |||
| } else { | |||
| image[py][px] = 255; | |||
| } | |||
| if (y == grass_level) { | |||
| if (y == grassLevel) { | |||
| image[py][px] = 128; | |||
| } | |||
| } | |||