Browse Source

make style consistent

fix/style
Martin Dørum 3 years ago
parent
commit
0db704582d

+ 6
- 5
conventions.md View File

@@ -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


+ 9
- 9
core.mod/src/DefaultWorldGen.cc View File

@@ -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 });
}

+ 2
- 2
core.mod/src/entities/ItemStackEntity.cc View File

@@ -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);
}


+ 1
- 1
core.mod/src/entities/ItemStackEntity.h View File

@@ -21,6 +21,6 @@ private:

ItemStackEntity(): PhysicsEntity(SIZE) {}

float despawn_timer_ = DESPAWN_TIME;
float despawnTimer_ = DESPAWN_TIME;
Swan::Item *item_ = NULL;
};

+ 17
- 17
core.mod/src/entities/PlayerEntity.cc View File

@@ -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;
}
}


+ 5
- 5
core.mod/src/entities/PlayerEntity.h View File

@@ -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};
};

+ 4
- 4
core.mod/src/main.cc View File

@@ -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) {

+ 6
- 6
libcygnet/include/cygnet/Renderer.h View File

@@ -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);
}

}

+ 3
- 3
libcygnet/include/cygnet/ResourceManager.h View File

@@ -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,

+ 4
- 4
libcygnet/src/Renderer.cc View File

@@ -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();
}
}

+ 2
- 2
libcygnet/src/ResourceManager.cc View File

@@ -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;

+ 13
- 13
libswan/include/swan/Chunk.h View File

@@ -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_;
};

}

+ 1
- 1
libswan/include/swan/Collection.h View File

@@ -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];

+ 32
- 32
libswan/include/swan/Game.h View File

@@ -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;
};

}

+ 4
- 4
libswan/include/swan/Item.h View File

@@ -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) {}
};

}

+ 13
- 13
libswan/include/swan/LightServer.h View File

@@ -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();
}


+ 8
- 8
libswan/include/swan/Tile.h View File

@@ -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);

+ 8
- 8
libswan/include/swan/World.h View File

@@ -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_;
};

}

+ 11
- 11
libswan/include/swan/WorldPlane.h View File

@@ -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);
}

}

+ 3
- 3
libswan/include/swan/gfxutil.h View File

@@ -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 {

+ 3
- 3
libswan/include/swan/log.h View File

@@ -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_;
};


+ 1
- 1
libswan/include/swan/traits/PhysicsTrait.h View File

@@ -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));

+ 22
- 22
libswan/src/Chunk.cc View File

@@ -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();
}


+ 5
- 5
libswan/src/Game.cc View File

@@ -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) {

+ 3
- 3
libswan/src/ItemStack.cc View File

@@ -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;

+ 58
- 58
libswan/src/LightServer.cc View File

@@ -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);

+ 1
- 1
libswan/src/Tile.cc View File

@@ -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,
});
}


+ 21
- 22
libswan/src/World.cc View File

@@ -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));
}


+ 41
- 41
libswan/src/WorldPlane.cc View File

@@ -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);
}

}

+ 6
- 6
libswan/src/traits/PhysicsTrait.cc View File

@@ -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;
}
}

+ 3
- 3
libswan/test/ItemStack.t.cc View File

@@ -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);

+ 18
- 18
libswan/test/lib/test.cc View File

@@ -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;

+ 1
- 1
src/lighting-test.cc View File

@@ -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;

+ 57
- 57
src/main.cc View File

@@ -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());

+ 7
- 7
src/perlin-test.cc View File

@@ -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;
}
}

Loading…
Cancel
Save