@@ -3,7 +3,7 @@ project(swan) | |||
find_package(SFML 2.5 COMPONENTS graphics system window REQUIRED) | |||
add_compile_options(-std=c++17 -Wall -Wextra -Wpedantic -Wno-unused-parameter) | |||
add_compile_options(-std=c++2a -Wall -Wextra -Wpedantic -Wno-unused-parameter) | |||
if(CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL "") | |||
message(STATUS "Build mode: Debug") | |||
add_compile_options(-g -fsanitize=address) |
@@ -6,10 +6,23 @@ | |||
extern "C" void mod_init(Swan::Mod &mod) { | |||
mod.init("core"); | |||
mod.registerTile("air", (new Swan::Tile("assets/tiles/air.png"))->solid(false)); | |||
mod.registerTile("stone", (new Swan::Tile("assets/tiles/stone.png"))->drops("core::stone")); | |||
mod.registerTile("dirt", (new Swan::Tile("assets/tiles/dirt.png"))->drops("core::dirt")); | |||
mod.registerTile("grass", (new Swan::Tile("assets/tiles/grass.png"))->drops("core::dirt")); | |||
mod.registerTile("air", new Swan::Tile{ | |||
.image = mod.loadImage("assets/tiles/air.png"), | |||
.is_solid = false, | |||
.dropped_item = "dirt", | |||
}); | |||
mod.registerTile("stone", new Swan::Tile{ | |||
.image = mod.loadImage("assets/tiles/stone.png"), | |||
.dropped_item = "stone", | |||
}); | |||
mod.registerTile("dirt", new Swan::Tile{ | |||
.image = mod.loadImage("assets/tiles/dirt.png"), | |||
.dropped_item = "dirt", | |||
}); | |||
mod.registerTile("grass", new Swan::Tile{ | |||
.image = mod.loadImage("assets/tiles/grass.png"), | |||
.dropped_item = "grass", | |||
}); | |||
mod.registerWorldGen("default", new WGDefault::Factory()); | |||
@@ -4,6 +4,7 @@ | |||
#include <string> | |||
#include <vector> | |||
#include <memory> | |||
#include <SFML/Graphics/Image.hpp> | |||
#include "Tile.h" | |||
#include "WorldGen.h" | |||
@@ -22,6 +23,8 @@ public: | |||
void registerEntity(const std::string &name, Entity::Factory *ent); | |||
void registerAsset(const std::string &name, Asset *asset); | |||
std::unique_ptr<sf::Image> loadImage(const std::string &path); | |||
std::string name_; | |||
std::string path_; | |||
std::vector<std::shared_ptr<Tile>> tiles_; |
@@ -2,27 +2,21 @@ | |||
#include <stdint.h> | |||
#include <string> | |||
#include <memory> | |||
#include <SFML/Graphics/Image.hpp> | |||
namespace Swan { | |||
class Tile { | |||
struct Tile { | |||
public: | |||
using ID = uint16_t; | |||
Tile(std::string path): path_(path) {} | |||
std::unique_ptr<sf::Image> image; | |||
bool is_solid = true; | |||
std::string dropped_item = ""; | |||
Tile *solid(bool b) { is_solid_ = b; return this; } | |||
Tile *drops(std::string item) { dropped_item_ = item; return this; } | |||
std::string name = ""; | |||
bool is_solid_ = true; | |||
std::string dropped_item_ = ""; | |||
std::string path_; | |||
std::string name_; | |||
sf::Image image_; | |||
static sf::Image INVALID_IMAGE; | |||
static Tile INVALID_TILE; | |||
static ID INVALID_ID; | |||
static Tile *createInvalid(); |
@@ -25,11 +25,11 @@ void Body::collide(WorldPlane &plane) { | |||
for (int x = startx; x <= endx; ++x) { | |||
for (int ry = y - 1; ry <= y; ++ry) { | |||
Tile &wall = plane.getTile(TilePos(x, ry)); | |||
if (x == startx && vel_.x_ < 0 && wall.is_solid_) { | |||
if (x == startx && vel_.x_ < 0 && wall.is_solid) { | |||
vel_.x_ = 0; | |||
pos_.x_ = startx + 1.001; | |||
startx = (int)floor(pos_.x_); | |||
} else if (x == endx && vel_.x_ > 0 && wall.is_solid_) { | |||
} else if (x == endx && vel_.x_ > 0 && wall.is_solid) { | |||
vel_.x_ = 0; | |||
pos_.x_ = endx - size_.x_ - 0.001; | |||
endx = (int)floor(pos_.x_ + size_.x_); | |||
@@ -42,7 +42,7 @@ void Body::collide(WorldPlane &plane) { | |||
y = (int)ceil(pos_.y_ - 1); | |||
for (int x = startx; x <= endx; ++x) { | |||
Tile &roof = plane.getTile(TilePos(x, y)); | |||
if (roof.is_solid_ && vel_.y_ < 0) { | |||
if (roof.is_solid && vel_.y_ < 0) { | |||
pos_.y_ = y + 1; | |||
vel_.y_ = 0; | |||
} | |||
@@ -55,7 +55,7 @@ void Body::collide(WorldPlane &plane) { | |||
y = (int)ceil(pos_.y_ + size_.y_ - 1); | |||
for (int x = startx; x <= endx; ++x) { | |||
Tile &ground = plane.getTile(TilePos(x, y)); | |||
if (ground.is_solid_ && vel_.y_ > 0) { | |||
if (ground.is_solid && vel_.y_ > 0) { | |||
pos_.y_ = y - size_.y_; | |||
vel_.y_ = 0; | |||
on_ground_ = true; |
@@ -29,7 +29,7 @@ void Chunk::drawBlock(RelPos pos, const Tile &t) { | |||
if (compressed_size_ != -1) | |||
decompress(); | |||
visuals_->tex_.update(t.image_, pos.x_ * TILE_SIZE, pos.y_ * TILE_SIZE); | |||
visuals_->tex_.update(*t.image, pos.x_ * TILE_SIZE, pos.y_ * TILE_SIZE); | |||
visuals_->dirty_ = true; | |||
} | |||
@@ -91,17 +91,17 @@ void Chunk::decompress() { | |||
void Chunk::render(World &world) { | |||
Tile::ID prevID = Tile::INVALID_ID; | |||
Tile &tile = Tile::INVALID_TILE; | |||
Tile *tile = &Tile::INVALID_TILE; | |||
for (int x = 0; x < CHUNK_WIDTH; ++x) { | |||
for (int y = 0; y < CHUNK_HEIGHT; ++y) { | |||
Tile::ID id = getTileID(RelPos(x, y)); | |||
if (id != prevID) { | |||
prevID = id; | |||
tile = world.getTileByID(id); | |||
tile = &world.getTileByID(id); | |||
} | |||
const sf::Uint8 *imgptr = tile.image_.getPixelsPtr(); | |||
const sf::Uint8 *imgptr = tile->image->getPixelsPtr(); | |||
for (int imgy = 0; imgy < TILE_SIZE; ++imgy) { | |||
int pixx = x * TILE_SIZE; | |||
int pixy = y * TILE_SIZE + imgy; |
@@ -12,15 +12,8 @@ void Mod::init(const std::string &name) { | |||
} | |||
void Mod::registerTile(const std::string &name, Tile *tile) { | |||
tile->name_ = name_ + "::" + name; | |||
fprintf(stderr, "Adding tile: %s\n", tile->name_.c_str()); | |||
std::string asset_path = path_ + "/" + tile->path_; | |||
if (!tile->image_.loadFromFile(asset_path)) { | |||
fprintf(stderr, "Tile %s: Failed to load image %s\n", tile->name_.c_str(), asset_path.c_str()); | |||
tile->image_ = Tile::INVALID_IMAGE; | |||
} | |||
tile->name = name_ + "::" + name; | |||
fprintf(stderr, "Adding tile: %s\n", tile->name.c_str()); | |||
tiles_.push_back(std::shared_ptr<Tile>(tile)); | |||
} | |||
@@ -45,4 +38,12 @@ void Mod::registerAsset(const std::string &name, Asset *asset) { | |||
assets_.push_back(std::shared_ptr<Asset>(asset)); | |||
} | |||
std::unique_ptr<sf::Image> Mod::loadImage(const std::string &path) { | |||
std::unique_ptr<sf::Image> img(new sf::Image()); | |||
if (!img->loadFromFile(path_ + "/" + path)) | |||
img->create(TILE_SIZE, TILE_SIZE, sf::Color(245, 66, 242)); | |||
return img; | |||
} | |||
} |
@@ -3,24 +3,23 @@ | |||
namespace Swan { | |||
sf::Image Tile::INVALID_IMAGE; | |||
Tile Tile::INVALID_TILE(""); | |||
Tile Tile::INVALID_TILE; | |||
Tile::ID Tile::INVALID_ID = 0; | |||
static void initInvalid(Tile *t) { | |||
t->name_ = "@internal::invalid"; | |||
t->image_ = Tile::INVALID_IMAGE; | |||
t->is_solid_ = false; | |||
t->name = "@internal::invalid"; | |||
t->image.reset(new sf::Image()); | |||
t->image->create(TILE_SIZE, TILE_SIZE, sf::Color(245, 66, 242)); | |||
t->is_solid = false; | |||
} | |||
Tile *Tile::createInvalid() { | |||
Tile *t = new Tile(""); | |||
Tile *t = new Tile(); | |||
initInvalid(t); | |||
return t; | |||
} | |||
void Tile::initGlobal() { | |||
INVALID_IMAGE.create(TILE_SIZE, TILE_SIZE, sf::Color(245, 66, 242)); | |||
initInvalid(&INVALID_TILE); | |||
} | |||
@@ -51,7 +51,7 @@ void World::spawnPlayer() { | |||
void World::registerTile(std::shared_ptr<Tile> t) { | |||
Tile::ID id = tiles_.size(); | |||
tiles_.push_back(t); | |||
tiles_map_[t->name_] = id; | |||
tiles_map_[t->name] = id; | |||
} | |||
void World::registerWorldGen(std::shared_ptr<WorldGen::Factory> gen) { |