cmake_minimum_required(VERSION 2.6) | |||||
cmake_minimum_required(VERSION 2.8) | |||||
project(swan) | project(swan) | ||||
find_package(SFML 2.5 COMPONENTS graphics system window REQUIRED) | find_package(SFML 2.5 COMPONENTS graphics system window REQUIRED) |
add_library(core.mod SHARED src/mod.cc) | add_library(core.mod SHARED src/mod.cc) | ||||
set_target_properties(core.mod PROPERTIES OUTPUT_NAME core.mod PREFIX "") | |||||
set_target_properties(core.mod PROPERTIES OUTPUT_NAME mod PREFIX "") | |||||
file(COPY assets DESTINATION .) |
extern "C" void mod_init(Swan::Mod &mod) { | extern "C" void mod_init(Swan::Mod &mod) { | ||||
mod.init("core"); | mod.init("core"); | ||||
mod.registerTile("stone", Swan::Tile("assets/tiles/stone.png")); | |||||
mod.registerTile("dirt", Swan::Tile("assets/tiles/dirt.png")); | |||||
mod.registerTile("grass", Swan::Tile("assets/tiles/grass.png")); | |||||
mod.registerTile("stone", "assets/tiles/stone.png"); | |||||
mod.registerTile("dirt", "assets/tiles/dirt.png"); | |||||
mod.registerTile("grass", "assets/tiles/grass.png"); | |||||
} | } | ||||
int main() { | int main() { |
public: | public: | ||||
int x_; | int x_; | ||||
int y_; | int y_; | ||||
Tile::TileID tiles_[CHUNK_HEIGHT][CHUNK_WIDTH]; | |||||
Tile::TileID tiles_[CHUNK_WIDTH][CHUNK_HEIGHT]; | |||||
void setTile(int x, int y, Tile::TileID tile) { | |||||
tiles_[x][y] = tile; | |||||
} | |||||
void clear(); | void clear(); | ||||
void draw(Win &win); | void draw(Win &win); |
public: | public: | ||||
std::vector<Mod> registered_mods_; | std::vector<Mod> registered_mods_; | ||||
World *world_; | |||||
World *world_ = NULL; | |||||
void loadMod(const std::string &path); | void loadMod(const std::string &path); | ||||
void createWorld(); | |||||
void draw(Win &win); | void draw(Win &win); | ||||
void update(float dt); | void update(float dt); |
using ModID = uint32_t; | using ModID = uint32_t; | ||||
std::string name_; | std::string name_; | ||||
std::string path_; | |||||
std::vector<Tile> tiles_; | std::vector<Tile> tiles_; | ||||
bool inited_ = false; | bool inited_ = false; | ||||
void init(const std::string &name); | void init(const std::string &name); | ||||
void registerTile(const std::string &name, const Tile &tile); | |||||
void registerTile(const std::string &name, const std::string &asset); | |||||
}; | }; | ||||
} | } |
#include <stdint.h> | #include <stdint.h> | ||||
#include <string> | #include <string> | ||||
#include <SFML/Graphics/Image.hpp> | |||||
namespace Swan { | namespace Swan { | ||||
using TileID = uint16_t; | using TileID = uint16_t; | ||||
std::string name_; | std::string name_; | ||||
sf::Image image_; | |||||
}; | }; | ||||
} | } |
public: | public: | ||||
Player *player_; | Player *player_; | ||||
WorldPlane *current_plane_; | |||||
std::vector<WorldPlane *> planes_; | |||||
WorldPlane::PlaneID current_plane_; | |||||
std::vector<WorldPlane> planes_; | |||||
std::vector<Tile> registered_tiles_; | |||||
std::vector<Tile *> registered_tiles_; | |||||
std::map<std::string, Tile::TileID> tile_id_map_; | std::map<std::string, Tile::TileID> tile_id_map_; | ||||
WorldPlane::PlaneID addPlane(); | |||||
void setCurrentPlane(WorldPlane::PlaneID id) { current_plane_ = id; } | |||||
WorldPlane &getPlane(WorldPlane::PlaneID id) { return planes_[id]; } | |||||
Tile::TileID getTileID(const std::string &name) { | Tile::TileID getTileID(const std::string &name) { | ||||
return tile_id_map_[name]; | return tile_id_map_[name]; | ||||
} | } | ||||
void registerTile(Tile *t); | |||||
void draw(Win &win); | void draw(Win &win); | ||||
void update(float dt); | void update(float dt); | ||||
void tick(); | void tick(); |
#include "common.h" | #include "common.h" | ||||
#include "Chunk.h" | #include "Chunk.h" | ||||
#include "Tile.h" | |||||
namespace Swan { | namespace Swan { | ||||
class WorldPlane { | class WorldPlane { | ||||
public: | public: | ||||
using PlaneID = uint16_t; | |||||
std::vector<Chunk> chunks_; | std::vector<Chunk> chunks_; | ||||
int max_chunk_x_ = 0; | |||||
int min_chunk_x_ = 0; | |||||
int max_chunk_y_ = 0; | |||||
int min_chunk_y_ = 0; | |||||
PlaneID id_; | |||||
void setTile(int x, int y, Tile::TileID tile); | |||||
void draw(Win &win); | void draw(Win &win); | ||||
void update(float dt); | void update(float dt); |
namespace Swan { | namespace Swan { | ||||
void Game::loadMod(const std::string &path) { | void Game::loadMod(const std::string &path) { | ||||
void *dl = dlopen(path.c_str(), RTLD_LAZY); | |||||
std::string dlpath = path + "/mod.so"; | |||||
void *dl = dlopen(dlpath.c_str(), RTLD_LAZY); | |||||
if (dl == NULL) { | if (dl == NULL) { | ||||
fprintf(stderr, "%s\n", dlerror()); | fprintf(stderr, "%s\n", dlerror()); | ||||
return; | return; | ||||
registered_mods_.push_back(Mod()); | registered_mods_.push_back(Mod()); | ||||
Mod &mod = registered_mods_.back(); | Mod &mod = registered_mods_.back(); | ||||
mod.path_ = path; | |||||
mod_init(mod); | mod_init(mod); | ||||
} | } | ||||
void Game::createWorld() { | |||||
if (world_ != NULL) | |||||
delete world_; | |||||
world_ = new World(); | |||||
for (auto &mod: registered_mods_) { | |||||
for (auto &tile: mod.tiles_) { | |||||
world_->registerTile(&tile); | |||||
} | |||||
} | |||||
} | |||||
void Game::draw(Win &win) { | void Game::draw(Win &win) { | ||||
if (world_) | if (world_) | ||||
world_->draw(win); | world_->draw(win); |
fprintf(stderr, "Mod initing: %s\n", name_.c_str()); | fprintf(stderr, "Mod initing: %s\n", name_.c_str()); | ||||
} | } | ||||
void Mod::registerTile(const std::string &name, const Tile &tile) { | |||||
tiles_.push_back(tile); | |||||
void Mod::registerTile(const std::string &name, const std::string &asset) { | |||||
tiles_.push_back(Tile()); | |||||
Tile &t = tiles_.back(); | Tile &t = tiles_.back(); | ||||
t.name_ = name_ + "::" + name; | t.name_ = name_ + "::" + name; | ||||
fprintf(stderr, "Adding tile: %s\n", t.name_.c_str()); | |||||
fprintf(stderr, "Added tile: %s\n", t.name_.c_str()); | |||||
std::string asset_path = path_ + "/" + asset; | |||||
if (!t.image_.loadFromFile(asset_path)) { | |||||
fprintf(stderr, "Tile %s: Failed to load image %s!\n", t.name_.c_str(), asset_path.c_str()); | |||||
} | |||||
} | } | ||||
} | } |
namespace Swan { | namespace Swan { | ||||
void World::draw(Win &win) { | |||||
for (WorldPlane *plane: planes_) | |||||
plane->draw(win); | |||||
WorldPlane::PlaneID World::addPlane() { | |||||
WorldPlane::PlaneID id = planes_.size(); | |||||
planes_.push_back(WorldPlane()); | |||||
WorldPlane &plane = planes_.back(); | |||||
plane.id_ = id; | |||||
return id; | |||||
} | |||||
void World::registerTile(Tile *t) { | |||||
Tile::TileID id = registered_tiles_.size(); | |||||
registered_tiles_.push_back(t); | |||||
tile_id_map_[t->name_] = id; | |||||
} | |||||
void World::draw(Win &win) { | |||||
planes_[current_plane_].draw(win); | |||||
player_->draw(win); | player_->draw(win); | ||||
} | } | ||||
void World::update(float dt) { | void World::update(float dt) { | ||||
for (WorldPlane *plane: planes_) | |||||
plane->update(dt); | |||||
for (auto &plane: planes_) | |||||
plane.update(dt); | |||||
player_->update(dt); | player_->update(dt); | ||||
} | } | ||||
void World::tick() { | void World::tick() { | ||||
for (WorldPlane *plane: planes_) | |||||
plane->tick(); | |||||
for (auto &plane: planes_) | |||||
plane.tick(); | |||||
} | } | ||||
} | } |
namespace Swan { | namespace Swan { | ||||
void WorldPlane::setTile(int x, int y, Tile::TileID tile) { | |||||
int chx = x / CHUNK_WIDTH; | |||||
int chy = y / CHUNK_HEIGHT; | |||||
int rx = x % CHUNK_WIDTH; | |||||
int ry = y % CHUNK_HEIGHT; | |||||
Chunk *chunk = NULL; | |||||
for (auto &ch: chunks_) { | |||||
if (ch.x_ == chx && ch.y_ == chy) { | |||||
chunk = &ch; | |||||
break; | |||||
} | |||||
} | |||||
if (chunk == NULL) { | |||||
chunks_.push_back(Chunk()); | |||||
chunk = &chunks_.back(); | |||||
chunk->clear(); | |||||
} | |||||
chunk->setTile(rx, ry, tile); | |||||
} | |||||
void WorldPlane::draw(Win &win) { | void WorldPlane::draw(Win &win) { | ||||
} | } | ||||
return (double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0; | return (double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0; | ||||
} | } | ||||
template<typename T> | |||||
static void draw_ents(std::vector<T> ents) { | |||||
for (auto &ent: ents) | |||||
ent.draw(); | |||||
} | |||||
int main() { | int main() { | ||||
sf::RenderWindow window(sf::VideoMode(800, 600), "good gaem"); | sf::RenderWindow window(sf::VideoMode(800, 600), "good gaem"); | ||||
window.setVerticalSyncEnabled(true); | window.setVerticalSyncEnabled(true); | ||||
Win win = { window, transform }; | Win win = { window, transform }; | ||||
Game game; | Game game; | ||||
game.world_ = new World(); | |||||
game.loadMod("core.mod"); | |||||
game.createWorld(); | |||||
game.world_->setCurrentPlane(game.world_->addPlane()); | |||||
game.world_->player_ = new Player(Vec2(1, 1)); | game.world_->player_ = new Player(Vec2(1, 1)); | ||||
game.world_->current_plane_ = new WorldPlane(); | |||||
game.world_->planes_.push_back(game.world_->current_plane_); | |||||
game.loadMod("core.mod/core.mod.so"); | |||||
Tile::TileID tStone = game.world_->getTileID("core::stone"); | |||||
WorldPlane &plane = game.world_->getPlane(game.world_->current_plane_); | |||||
plane.setTile(2, 2, tStone); | |||||
double prevtime = getTime(); | double prevtime = getTime(); | ||||
double fpsAcc = 0; | double fpsAcc = 0; |