Browse Source

libswan and core.mod now compiles

feature/replace-renderer
Martin Dørum 3 years ago
parent
commit
447d4e8d39

+ 5
- 2
core.mod/src/DefaultWorldGen.cc View File

@@ -12,11 +12,13 @@ static int getStoneLevel(const siv::PerlinNoise &perlin, int x) {
return (int)(perlin.noise(x / 50.0, 10) * 10) + 10;
}

void DefaultWorldGen::drawBackground(const Swan::Context &ctx, Swan::Win &win, Swan::Vec2 pos) {
void DefaultWorldGen::drawBackground(
const Swan::Context &ctx, Cygnet::Renderer &rnd, Swan::Vec2 pos) {
int texmin = 10;
int texmax = 20;
//int texmax = 20;

if (pos.y > texmin) {
/*
SDL_Texture *tex = bgCave_.texture_.get();

Uint8 alpha = std::clamp(
@@ -27,6 +29,7 @@ void DefaultWorldGen::drawBackground(const Swan::Context &ctx, Swan::Win &win, S
Swan::Draw::parallaxBackground(
win, tex, std::nullopt, std::nullopt,
pos.x * Swan::TILE_SIZE, pos.y * Swan::TILE_SIZE, 0.7);
TODO */
}
}


+ 4
- 3
core.mod/src/DefaultWorldGen.h View File

@@ -13,9 +13,10 @@ public:
tAir_(world.getTileID("@::air")),
tTreeTrunk_(world.getTileID("core::tree-trunk")),
tLeaves_(world.getTileID("core::leaves")),
bgCave_(world.resources_.getImage("core/misc/background-cave")) {}
bgCave_(world.getSprite("core::misc/background-cave")) {}

void drawBackground(const Swan::Context &ctx, Swan::Win &win, Swan::Vec2 pos) override;
void drawBackground(
const Swan::Context &ctx, Cygnet::Renderer &rnd, Swan::Vec2 pos) override;
SDL_Color backgroundColor(Swan::Vec2 pos) override;
void genChunk(Swan::WorldPlane &plane, Swan::Chunk &chunk) override;
Swan::EntityRef spawnPlayer(const Swan::Context &ctx) override;
@@ -23,6 +24,6 @@ public:
private:
Swan::Tile::ID genTile(Swan::TilePos pos);
Swan::Tile::ID tGrass_, tDirt_, tStone_, tAir_, tTreeTrunk_, tLeaves_;
Swan::ImageResource &bgCave_;
Cygnet::RenderSprite bgCave_;
siv::PerlinNoise perlin_ = siv::PerlinNoise(100);
};

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

@@ -19,7 +19,8 @@ ItemStackEntity::ItemStackEntity(const Swan::Context &ctx, const PackObject &obj
deserialize(ctx, obj);
}

void ItemStackEntity::draw(const Swan::Context &ctx, Swan::Win &win) {
void ItemStackEntity::draw(const Swan::Context &ctx, Cygnet::Renderer &rnd) {
/*
SDL_Rect rect = item_->image_.frameRect();

SDL_Texture *tex = item_->image_.texture_.get();
@@ -27,6 +28,7 @@ void ItemStackEntity::draw(const Swan::Context &ctx, Swan::Win &win) {

win.showTexture(body_.pos, tex, &rect,
{ .hscale = 0.5, .vscale = 0.5 });
TODO */
}

void ItemStackEntity::update(const Swan::Context &ctx, float dt) {

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

@@ -7,7 +7,7 @@ public:
ItemStackEntity(const Swan::Context &ctx, Swan::Vec2 pos, const std::string &item);
ItemStackEntity(const Swan::Context &ctx, const PackObject &obj);

void draw(const Swan::Context &ctx, Swan::Win &win) override;
void draw(const Swan::Context &ctx, Cygnet::Renderer &rnd) override;
void update(const Swan::Context &ctx, float dt) override;
void tick(const Swan::Context &ctx, float dt) override;
void deserialize(const Swan::Context &ctx, const PackObject &obj) override;

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

@@ -14,9 +14,9 @@ PlayerEntity::PlayerEntity(const Swan::Context &ctx, const PackObject &obj):
deserialize(ctx, obj);
}

void PlayerEntity::draw(const Swan::Context &ctx, Swan::Win &win) {
body_.outline(win);
anims_[(int)state_].draw(body_.pos - Swan::Vec2(0.2, 0.1), win);
void PlayerEntity::draw(const Swan::Context &ctx, Cygnet::Renderer &rnd) {
// body_.outline(win); TODO
anims_[(int)state_].draw(body_.pos - Swan::Vec2(0.2, 0.1), rnd);
}

void PlayerEntity::update(const Swan::Context &ctx, float dt) {

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

@@ -11,7 +11,7 @@ public:
using PhysicsEntity::get;
Inventory &get(InventoryTrait::Tag) override { return inventory_; }

void draw(const Swan::Context &ctx, Swan::Win &win) override;
void draw(const Swan::Context &ctx, Cygnet::Renderer &rnd) override;
void update(const Swan::Context &ctx, float dt) override;
void tick(const Swan::Context &ctx, float dt) override;
void deserialize(const Swan::Context &ctx, const PackObject &obj) override;
@@ -36,11 +36,11 @@ private:
PlayerEntity(const Swan::Context &ctx):
PhysicsEntity(SIZE),
anims_{
Swan::Animation(ctx.resources.getImage("core/entity/player-still"), 0.8),
Swan::Animation(ctx.world.getSprite("core::entity/player-still"), 0.8),
Swan::Animation(
ctx.resources.getImage("core/entity/player-running"),
1, SDL_FLIP_HORIZONTAL),
Swan::Animation(ctx.resources.getImage("core/entity/player-running"), 1)
ctx.world.getSprite("core::entity/player-running"),
1, Cygnet::Mat3gf{}.scale({-1, 1})),
Swan::Animation(ctx.world.getSprite("core::entity/player-running"), 1),
} {}

State state_ = State::IDLE;

+ 3
- 9
core.mod/src/main.cc View File

@@ -10,15 +10,9 @@ public:
breakListener_ = world.evtTileBreak_.subscribe(
std::bind_front(&CoreMod::onTileBreak, this));

registerImage("tile/stone");
registerImage("tile/dirt");
registerImage("tile/grass");
registerImage("tile/tree-trunk");
registerImage("tile/leaves");
registerImage("tile/torch");
registerImage("entity/player-running");
registerImage("entity/player-still");
registerImage("misc/background-cave");
registerSprite("entity/player-running");
registerSprite("entity/player-still");
registerSprite("misc/background-cave");

registerTile({
.name = "stone",

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

@@ -30,7 +30,7 @@ struct RenderTile {
struct RenderCamera {
SwanCommon::Vec2 pos;
SwanCommon::Vec2i size;
float zoom;
float zoom = 0;
};

class Renderer {

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

@@ -44,11 +44,8 @@ public:
ResourceManager(ResourceBuilder &&builder);
~ResourceManager();

RenderSprite getSprite(std::string name) { return sprites_.at(std::move(name)); }

void tick();

private:
Renderer &rnd_;
std::unordered_map<std::string, RenderSprite> sprites_;
std::unordered_map<std::string, RenderTile> tiles_;

+ 0
- 1
libswan/CMakeLists.txt View File

@@ -14,7 +14,6 @@ add_library(libswan SHARED
src/LightServer.cc
src/Mod.cc
src/OS.cc
src/Resource.cc
src/World.cc
src/WorldPlane.cc)
target_include_directories(libswan

+ 6
- 7
libswan/include/swan/Animation.h View File

@@ -1,28 +1,27 @@
#pragma once

#include <SDL.h>
#include <cygnet/Renderer.h>

#include "common.h"
#include "Resource.h"
#include "Clock.h"
#include "Resource.h"

namespace Swan {

class Animation {
public:
Animation(ImageResource &resource, float interval, SDL_RendererFlip flip = SDL_FLIP_NONE):
resource_(resource), interval_(interval), timer_(interval), flip_(flip) {}
Animation(Cygnet::RenderSprite sprite, float interval, Cygnet::Mat3gf mat = {}):
sprite_(sprite), interval_(interval), timer_(interval), mat_(mat) {}

void tick(float dt);
void draw(const Vec2 &pos, Win &win);
void draw(const Vec2 &pos, Cygnet::Renderer &rnd);
void reset();

private:
ImageResource &resource_;
Cygnet::RenderSprite sprite_;
float interval_;
float timer_;
SDL_RendererFlip flip_;
Cygnet::Mat3gf mat_;
int frame_ = 0;
};


+ 4
- 12
libswan/include/swan/Chunk.h View File

@@ -47,9 +47,9 @@ public:
return getTileData()[pos.y * CHUNK_WIDTH + pos.x];
}

void setTileID(RelPos pos, Tile::ID id, SDL_Texture *tex) {
void setTileID(RelPos pos, Tile::ID id) {
getTileData()[pos.y * CHUNK_WIDTH + pos.x] = id;
drawList_.push_back({ pos, tex });
drawList_.push_back({pos, id});
}

void setTileData(RelPos pos, Tile::ID id) {
@@ -66,12 +66,9 @@ public:
needLightRender_ = true;
}

void render(const Context &ctx, SDL_Renderer *rnd);
void renderLight(const Context &ctx, SDL_Renderer *rnd);

void compress();
void decompress();
void draw(const Context &ctx, Win &win);
void draw(const Context &ctx, Cygnet::Renderer &rnd);
TickAction tick(float dt);

bool isActive() { return deactivateTimer_ > 0; }
@@ -83,21 +80,16 @@ public:
private:
static constexpr float DEACTIVATE_INTERVAL = 20;

void renderList(SDL_Renderer *rnd);

bool isCompressed() { return compressedSize_ != -1; }

std::unique_ptr<uint8_t[]> data_;
std::vector<std::pair<RelPos, SDL_Texture *>> drawList_;
std::vector<std::pair<RelPos, Tile::ID>> drawList_;

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

}

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

@@ -61,7 +61,7 @@ public:
virtual EntityRef spawn(const Context &ctx, const Entity::PackObject &obj) = 0;
virtual void update(const Context &ctx, float dt) = 0;
virtual void tick(const Context &ctx, float dt) = 0;
virtual void draw(const Context &ctx, Win &win) = 0;
virtual void draw(const Context &ctx, Cygnet::Renderer &rnd) = 0;
virtual void erase(size_t idx, size_t generation) = 0;

private:
@@ -84,7 +84,7 @@ public:
EntityRef spawn(const Context &ctx, const Entity::PackObject &obj) override;
void update(const Context &ctx, float dt) override;
void tick(const Context &ctx, float dt) override;
void draw(const Context &ctx, Win &win) override;
void draw(const Context &ctx, Cygnet::Renderer &rnd) override;
void erase(size_t idx, size_t generation) override;

private:
@@ -190,11 +190,11 @@ inline void EntityCollectionImpl<Ent>::tick(const Context &ctx, float dt) {
}

template<typename Ent>
inline void EntityCollectionImpl<Ent>::draw(const Context &ctx, Win &win) {
inline void EntityCollectionImpl<Ent>::draw(const Context &ctx, Cygnet::Renderer &rnd) {
ZoneScopedN(typeid(Ent).name());
for (auto &ent: entities_) {
ZoneScopedN("draw");
ent->draw(ctx, win);
ent->draw(ctx, rnd);
}
}


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

@@ -33,7 +33,7 @@ public:

virtual ~Entity() = default;

virtual void draw(const Context &ctx, Win &win) {}
virtual void draw(const Context &ctx, Cygnet::Renderer &rnd) {}
virtual void update(const Context &ctx, float dt) {}
virtual void tick(const Context &ctx, float dt) {}
virtual void onDespawn(const Context &ctx) {}

+ 1
- 9
libswan/include/swan/Game.h View File

@@ -8,7 +8,6 @@
#include <cygnet/Renderer.h>

#include "common.h"
#include "Resource.h"
#include "Mod.h"
#include "World.h"

@@ -16,10 +15,6 @@ namespace Swan {

class Game {
public:
Game(Win &win):
win_(win),
mousePos_(0, 0) {}

void createWorld(const std::string &worldgen, const std::vector<std::string> &modPaths);

void onKeyDown(SDL_Keysym sym) {
@@ -69,11 +64,8 @@ public:
void tick(float dt);

std::unique_ptr<World> world_ = NULL;
std::unique_ptr<ImageResource> invalidImage_ = NULL;
std::unique_ptr<Tile> invalidTile_ = NULL;
std::unique_ptr<Item> invalidItem_ = NULL;
Win &win_;
Cygnet::Renderer renderer_;
Cygnet::RenderCamera cam_;

private:
std::bitset<SDL_NUM_SCANCODES> pressedKeys_;

+ 0
- 1
libswan/include/swan/Item.h View File

@@ -2,7 +2,6 @@

#include <string>

#include "Resource.h"
#include "Tile.h"

namespace Swan {

+ 0
- 1
libswan/include/swan/Mod.h View File

@@ -12,7 +12,6 @@
#include "WorldGen.h"
#include "Entity.h"
#include "Collection.h"
#include "Resource.h"
#include "OS.h"
#include "util.h"


+ 0
- 53
libswan/include/swan/Resource.h View File

@@ -1,53 +0,0 @@
#pragma once

#include <SDL.h>
#include <stdint.h>
#include <string>
#include <memory>
#include <unordered_map>

#include "common.h"

namespace Swan {

class ImageResource {
public:
ImageResource(
SDL_Renderer *renderer, const std::string &modpath, const std::string &id);
ImageResource(
SDL_Renderer *renderer, const std::string &name,
int w, int h, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255);

void tick(float dt);

SDL_Rect frameRect(int frame = -1) const {
if (frame == -1) frame = frame_;
return SDL_Rect{ 0, frameHeight_ * frame, surface_->w, frameHeight_ };
}

std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *)> surface_{nullptr, &SDL_FreeSurface};
std::unique_ptr<SDL_Texture, void (*)(SDL_Texture *)> texture_{nullptr, &SDL_DestroyTexture};
int frameHeight_;
int numFrames_;
std::string name_;
int frame_ = 0;

private:
float switchInterval_ = 1;
float switchTimer_ = switchInterval_;
};

class ResourceManager {
public:
ResourceManager(Win &win);

void tick(float dt);

ImageResource &getImage(const std::string &name) const;
void addImage(std::unique_ptr<ImageResource> img) { images_[img->name_] = std::move(img); }

private:
std::unordered_map<std::string, std::unique_ptr<ImageResource>> images_;
};

}

+ 0
- 3
libswan/include/swan/Tile.h View File

@@ -3,9 +3,6 @@
#include <stdint.h>
#include <string>
#include <optional>
#include <memory>

#include "Resource.h"

namespace Swan {


+ 0
- 109
libswan/include/swan/Win.h View File

@@ -1,109 +0,0 @@
#pragma once

#include "log.h"
#include "common.h"

#include <SDL.h>
#include <optional>

namespace Swan {

class Win {
public:
Win(SDL_Window *window, SDL_Renderer *renderer, float scale):
window_(window), renderer_(renderer), scale_(scale) {

if (SDL_GetRendererInfo(renderer_, &rinfo_) < 0) {
panic << "GetRenedrerInfo failed: " << SDL_GetError();
abort();
}

// For HiDPI, we must set the renderer's logical size.
int w, h;
SDL_GetWindowSize(window_, &w, &h);
onResize(w, h);

info << "Using renderer: " << rinfo_.name;
}

Vec2 getPixSize() {
int w, h;
SDL_GetWindowSize(window_, &w, &h);
return Vec2((float)w / scale_, (float)h / scale_);
}

Vec2 getSize() {
int w, h;
SDL_GetWindowSize(window_, &w, &h);
return Vec2(((float)w / (scale_ * zoom_)) / TILE_SIZE, ((float)h / (scale_ * zoom_)) / TILE_SIZE);
}

void onResize(int w, int h) {
SDL_RenderSetLogicalSize(renderer_, (int)((float)w / scale_), (int)((float)h / scale_));
}

SDL_Rect createDestRect(Vec2 pos, Vec2 pixsize) {
return SDL_Rect{
(int)floor((pos.x - cam_.x) * TILE_SIZE * zoom_),
(int)floor((pos.y - cam_.y) * TILE_SIZE * zoom_),
(int)ceil(pixsize.x * zoom_), (int)ceil(pixsize.y * zoom_),
};
}

struct ShowTextureArgs {
SDL_RendererFlip flip = SDL_FLIP_NONE;
double hscale = 1;
double vscale = 1;
double angle = 0;
std::optional<SDL_Point> center = std::nullopt;
};

void showTexture(
const Vec2 &pos, SDL_Texture *tex, SDL_Rect *srcrect,
ShowTextureArgs args) {

SDL_Point *center = args.center ? &*args.center : nullptr;
SDL_Rect destrect = createDestRect(pos, Vec2(srcrect->w * args.hscale, srcrect->h * args.hscale));
if (SDL_RenderCopyEx(renderer_, tex, srcrect, &destrect, args.angle, center, args.flip) < 0)
warn << "RenderCopyEx failed: " << SDL_GetError();
}

void showTexture(const Vec2 &pos, SDL_Texture *tex, SDL_Rect *srcrect,
SDL_Rect *dest, ShowTextureArgs args) {
SDL_Point *center = args.center ? &*args.center : nullptr;
SDL_Rect destrect = createDestRect(pos, Vec2(dest->w * args.hscale, dest->h * args.hscale));
if (SDL_RenderCopyEx(renderer_, tex, srcrect, &destrect, args.angle, center, args.flip) < 0)
warn << "RenderCopyEx failed: " << SDL_GetError();
}

// We want an overload which uses RenderCopy instead of RenderCopyEx,
// because RenderCopy might be faster
void showTexture(const Vec2 &pos, SDL_Texture *tex, SDL_Rect *srcrect) {
SDL_Rect destrect = createDestRect(pos, Vec2(srcrect->w, srcrect->h));
if (SDL_RenderCopy(renderer_, tex, srcrect, &destrect) < 0)
warn << "RenderCopy failed: " << SDL_GetError();
}

// Another overload without RenderCopyEx
void showTexture(const Vec2 &pos, SDL_Texture *tex, SDL_Rect *srcrect,
SDL_Rect *dest) {
SDL_Rect destrect = createDestRect(pos, Vec2(dest->w, dest->h));
if (SDL_RenderCopy(renderer_, tex, srcrect, &destrect) < 0)
warn << "RenderCopy failed: " << SDL_GetError();
}

void drawRect(const Vec2 &pos, const Vec2 &size) {
SDL_Rect destrect = createDestRect(pos, size * TILE_SIZE);
if (SDL_RenderDrawRect(renderer_, &destrect) < 0)
warn << "RenderDrawRect failed: " << SDL_GetError();
}

Vec2 cam_;
float zoom_ = 1;
SDL_Window *window_;
SDL_Renderer *renderer_;
float scale_;
SDL_RendererInfo rinfo_;
};

}

+ 2
- 3
libswan/include/swan/World.h View File

@@ -15,7 +15,6 @@
#include "WorldGen.h"
#include "Entity.h"
#include "Collection.h"
#include "Resource.h"
#include "Mod.h"
#include "EventEmitter.h"

@@ -43,9 +42,10 @@ public:
Tile::ID getTileID(const std::string &name);
Tile &getTile(const std::string &name);
Item &getItem(const std::string &name);
Cygnet::RenderSprite &getSprite(const std::string &name);

SDL_Color backgroundColor();
void draw(Win &win);
void draw(Cygnet::Renderer &rnd);
void update(float dt);
void tick(float dt);

@@ -57,7 +57,6 @@ public:
Game *game_; // TODO: reference, not pointer
std::mt19937 random_;
std::vector<ModWrapper> mods_;
//ResourceManager resources_;
Cygnet::ResourceManager resources_;

// World owns tiles and items, the mod just has Builder objects

+ 1
- 2
libswan/include/swan/WorldGen.h View File

@@ -13,7 +13,6 @@ namespace Swan {

class World;
class WorldPlane;
class ImageResource;

class WorldGen {
public:
@@ -24,7 +23,7 @@ public:

virtual ~WorldGen() = default;

virtual void drawBackground(const Context &ctx, Win &win, Vec2 pos) = 0;
virtual void drawBackground(const Context &ctx, Cygnet::Renderer &rnd, Vec2 pos) = 0;
virtual SDL_Color backgroundColor(Vec2 pos) = 0;

virtual void genChunk(WorldPlane &plane, Chunk &chunk) = 0;

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

@@ -70,7 +70,7 @@ public:
void breakTile(TilePos pos);

SDL_Color backgroundColor();
void draw(Win &win);
void draw(Cygnet::Renderer &rnd);
void update(float dt);
void tick(float dt);


+ 7
- 3
libswan/include/swan/common.h View File

@@ -6,6 +6,13 @@
#include <swan-common/Vector2.h>
#include <swan-common/constants.h>

// Forward declare the Cygnet::Renderer, because lots of functions will need
// to take a reference to it. It's nicer to not have to include Cygnet::Renderer
// in every header.
namespace Cygnet {
class Renderer;
}

namespace Swan {

using namespace SwanCommon;
@@ -16,14 +23,11 @@ using ChunkPos = Vec2i;
class Game;
class World;
class WorldPlane;
class Win;
class ResourceManager;

struct Context {
Game &game;
World &world;
WorldPlane &plane;
ResourceManager &resources;
};

}

+ 2
- 2
libswan/include/swan/drawutil.h View File

@@ -5,18 +5,18 @@
#include <initializer_list>
#include <utility>

#include "Win.h"

namespace Swan {
namespace Draw {

SDL_Color linearGradient(
float val, std::initializer_list<std::pair<float, SDL_Color>> colors);

/*
void parallaxBackground(
Win &win, SDL_Texture *tex,
std::optional<SDL_Rect> srcrect, std::optional<SDL_Rect> destrect,
float x, float y, float factor);
TODO */

}
}

+ 0
- 2
libswan/include/swan/swan.h View File

@@ -12,10 +12,8 @@
#include <swan/ItemStack.h>
#include <swan/Mod.h>
#include <swan/OS.h>
#include <swan/Resource.h>
#include <swan/SlotVector.h>
#include <swan/Tile.h>
#include <swan/Win.h>
#include <swan/World.h>
#include <swan/WorldGen.h>
#include <swan/WorldPlane.h>

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

@@ -4,8 +4,6 @@

namespace Swan {

class Win;

struct BodyTrait {
struct Body;
struct Tag {};
@@ -32,7 +30,7 @@ struct BodyTrait {
Vec2 midRight() { return { right(), midY() }; }
Vec2 bottomRight() { return { right(), bottom() }; }

void outline(Win &win);
//void outline(Win &win); TODO
};
};


+ 5
- 7
libswan/include/swan/util.h View File

@@ -52,21 +52,19 @@ public:
Result(ResultOk, T &&val): isOk_(true), v_(ResultOk{}, std::move(val)) {}
Result(ResultErr, Err &&err): isOk_(false), v_(ResultErr{}, std::move(err)) {}

Result(const Result &other) {
isOk_ = other.isOk_;
if (other.isOk_) {
Result(const Result &other): isOk_(other.isOk_) {
if (isOk_) {
new (&v_.val) T(other.v_.val);
} else {
new (&v_.err) T(other.v_.err);
}
}

Result(Result &&other) {
isOk_ = other.isOk_;
Result(Result &&other): isOk_(other.isOk_) {
if (other.isOk_) {
new (&v_.val) T(std::move(other.v_.val));
} else {
new (&v_.err) T(std::move(other.v_.err));
new (&v_.err) Err(std::move(other.v_.err));
}
}

@@ -77,7 +75,7 @@ public:
Result<T, Err> &operator=(const Result<T, Err> &other) {
destroy();
isOk_ = other.isOk_;
if (other.isOk_) {
if (isOk_) {
new (&v_.val) T(other.v_.val);
} else {
new (&v_.err) Err(other.v_.err);

+ 4
- 6
libswan/src/Animation.cc View File

@@ -1,7 +1,6 @@
#include "Animation.h"

#include "Win.h"
#include "gfxutil.h"
#include <cygnet/Renderer.h>

namespace Swan {

@@ -11,14 +10,13 @@ void Animation::tick(float dt) {
timer_ += interval_;

frame_ += 1;
if (frame_ >= resource_.numFrames_)
if (frame_ >= sprite_.frameCount)
frame_ = 0;
}
}

void Animation::draw(const Vec2 &pos, Win &win) {
SDL_Rect rect = resource_.frameRect(frame_);
win.showTexture(pos, resource_.texture_.get(), &rect, { .flip = flip_ });
void Animation::draw(const Vec2 &pos, Cygnet::Renderer &rnd) {
rnd.drawSprite(sprite_, mat_, frame_);
}

void Animation::reset() {

+ 6
- 105
libswan/src/Chunk.cc View File

@@ -10,7 +10,6 @@
#include "gfxutil.h"
#include "World.h"
#include "Game.h"
#include "Win.h"

namespace Swan {

@@ -32,7 +31,6 @@ void Chunk::compress() {
data_.reset(new uint8_t[destlen]);
memcpy(data_.get(), dest, destlen);

texture_.reset();
compressedSize_ = destlen;

info
@@ -46,6 +44,8 @@ void Chunk::compress() {
} else {
warn << "Chunk compression error: " << ret << " (Out of memory?)";
}

// TODO: Delete renderChunk_
}

void Chunk::decompress() {
@@ -71,101 +71,11 @@ void Chunk::decompress() {
<< compressedSize_ << " bytes to "
<< DATA_SIZE << " bytes.";
compressedSize_ = -1;
}

void Chunk::renderLight(const Context &ctx, SDL_Renderer *rnd) {
std::optional<RenderTarget> target;

// The texture might not be created yet
if (!lightTexture_) {
lightTexture_.reset(SDL_CreateTexture(
ctx.game.win_.renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET,
CHUNK_WIDTH, CHUNK_HEIGHT));
SDL_SetTextureBlendMode(lightTexture_.get(), SDL_BLENDMODE_BLEND);

target.emplace(rnd, texture_.get());
} else {
target.emplace(rnd, texture_.get());
}

// Fill light texture
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) {
for (int x = 0; x < CHUNK_WIDTH; ++x) {
int b = getLightLevel({ x, y });
color.change(0, 0, 0, 255 - b);
SDL_Rect rect{ x, y, 1, 1 };
SDL_RenderFillRect(rnd, &rect);
}
}

needLightRender_ = false;
// TODO: Create renderChunk_
}

void Chunk::render(const Context &ctx, SDL_Renderer *rnd) {
std::optional<RenderTarget> target;

// The texture might not be created yet
if (!texture_) {
texture_.reset(SDL_CreateTexture(
ctx.game.win_.renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET,
CHUNK_WIDTH * TILE_SIZE, CHUNK_HEIGHT * TILE_SIZE));
SDL_SetTextureBlendMode(texture_.get(), SDL_BLENDMODE_BLEND);
target.emplace(rnd, texture_.get());

RenderBlendMode mode(rnd, SDL_BLENDMODE_NONE);
RenderDrawColor color(rnd, 0, 0, 0, 0);
SDL_Rect rect{ 0, 0, CHUNK_WIDTH * TILE_SIZE, CHUNK_HEIGHT * TILE_SIZE };
SDL_RenderFillRect(rnd, &rect);
} else {
target.emplace(rnd, texture_.get());
}

// We're caching tiles so we don't have to world.getTileByID() every time
Tile::ID prevID = World::INVALID_TILE_ID;
Tile *tile = ctx.game.invalidTile_.get();

// Fill tile texture
for (int y = 0; y < CHUNK_HEIGHT; ++y) {
for (int x = 0; x < CHUNK_WIDTH; ++x) {
Tile::ID id = getTileID(RelPos(x, y));
if (id != prevID) {
prevID = id;
tile = &ctx.world.getTileByID(id);
}

SDL_Rect dest{x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE};
SDL_RenderCopy(rnd, tile->image.texture_.get(), nullptr, &dest);
}
}

needRender_ = false;

renderLight(ctx, rnd);
}

void Chunk::renderList(SDL_Renderer *rnd) {
// Here, we know that the texture is created.
// We still wanna render directly to the target texture
RenderTarget target(rnd, texture_.get());

// We must make sure the blend mode is NONE, because we want transparent
// pixels to actually overwrite non-transparent pixels
RenderBlendMode mode(rnd, SDL_BLENDMODE_NONE);

// When we FillRect, we must fill transparency.
RenderDrawColor color(rnd, 0, 0, 0, 0);

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

void Chunk::draw(const Context &ctx, Win &win) {
void Chunk::draw(const Context &ctx, Cygnet::Renderer &rnd) {
if (isCompressed())
return;

@@ -173,21 +83,12 @@ void Chunk::draw(const Context &ctx, Win &win) {
if (needRender_)
return;

// We're responsible for the light level rendering though
if (needLightRender_)
renderLight(ctx, win.renderer_);

if (drawList_.size() > 0) {
renderList(win.renderer_);
//renderList(win.renderer_); TODO
drawList_.clear();
}

auto chunkpos = pos_ * Vec2i(CHUNK_WIDTH, CHUNK_HEIGHT);
SDL_Rect rect{ 0, 0, CHUNK_WIDTH * TILE_SIZE, CHUNK_HEIGHT * TILE_SIZE };
win.showTexture(chunkpos, texture_.get(), &rect);

SDL_Rect texrect{ 0, 0, CHUNK_WIDTH, CHUNK_HEIGHT };
win.showTexture(chunkpos, lightTexture_.get(), &texrect, &rect);
// rnd.drawChunk(renderChunk_, (Vec2)pos_ * Vec2{CHUNK_WIDTH, CHUNK_HEIGHT}); TODO
}

Chunk::TickAction Chunk::tick(float dt) {

+ 10
- 11
libswan/src/Game.cc View File

@@ -7,7 +7,6 @@
#include "log.h"
#include "Tile.h"
#include "OS.h"
#include "Win.h"

namespace Swan {

@@ -22,8 +21,8 @@ void Game::createWorld(const std::string &worldgen, const std::vector<std::strin
TilePos Game::getMouseTile() {
auto mousePos = getMousePos();
return TilePos(
(int)floor(win_.cam_.x + mousePos.x / (Swan::TILE_SIZE * win_.zoom_)),
(int)floor(win_.cam_.y + mousePos.y / (Swan::TILE_SIZE * win_.zoom_)));
(int)floor(cam_.pos.x + mousePos.x / (Swan::TILE_SIZE * cam_.zoom)),
(int)floor(cam_.pos.y + mousePos.y / (Swan::TILE_SIZE * cam_.zoom)));
}

SDL_Color Game::backgroundColor() {
@@ -31,18 +30,18 @@ SDL_Color Game::backgroundColor() {
}

void Game::draw() {
world_->draw(win_);
world_->draw(renderer_);
}

void Game::update(float dt) {
world_->update(dt);

// Zoom the window using the scroll wheel
win_.zoom_ += (float)wasWheelScrolled() * 0.1f * win_.zoom_;
if (win_.zoom_ > 3)
win_.zoom_ = 3;
else if (win_.zoom_ < 0.3)
win_.zoom_ = 0.3;
cam_.zoom += (float)wasWheelScrolled() * 0.1f * cam_.zoom;
if (cam_.zoom > 3)
cam_.zoom = 3;
else if (cam_.zoom < 0.3)
cam_.zoom = 0.3;

world_->update(dt);

didScroll_ = 0;
didPressKeys_.reset();

+ 0
- 132
libswan/src/Resource.cc View File

@@ -1,132 +0,0 @@
#include "Resource.h"

#include <stdio.h>
#include <SDL_image.h>
#include <regex>
#include <cpptoml.h>
#include <string.h>
#include <errno.h>

#include "log.h"
#include "common.h"
#include "Win.h"

namespace Swan {

ImageResource::ImageResource(
SDL_Renderer *renderer, const std::string &modpath, const std::string &id) {
static std::regex first_part_re("^.*?/");

SDL_RendererInfo rinfo;
if (SDL_GetRendererInfo(renderer, &rinfo) < 0) {
panic << "GetRendererInfo failed: " << SDL_GetError();
abort();
}

uint32_t format = rinfo.texture_formats[0];
int bpp = 32;
uint32_t rmask, gmask, bmask, amask;
if (SDL_PixelFormatEnumToMasks(format, &bpp, &rmask, &gmask, &bmask, &amask) < 0) {
panic << "PixelFormatEnumToMasks failed: " << SDL_GetError();
abort();
}

std::string assetpath = modpath + "/assets/" +
std::regex_replace(id, first_part_re, "");

surface_.reset(IMG_Load((assetpath + ".png").c_str()));

// If we don't have a surface yet (either loading or conversion failed),
// create a placeholder
if (!surface_) {
warn << "Loading image " << id << " failed: " << SDL_GetError();

surface_.reset(SDL_CreateRGBSurface(
0, TILE_SIZE, TILE_SIZE, bpp, rmask, gmask, bmask, amask));
SDL_FillRect(surface_.get(), NULL, SDL_MapRGB(surface_->format,
PLACEHOLDER_RED, PLACEHOLDER_GREEN, PLACEHOLDER_BLUE));
}

frameHeight_ = 32;

// Load TOML if it exists
errno = ENOENT; // I don't know if ifstream is guaranteed to set errno
std::ifstream tomlfile(assetpath + ".toml");
if (tomlfile) {
cpptoml::parser parser(tomlfile);
try {
auto toml = parser.parse();
frameHeight_ = toml->get_as<int>("height").value_or(frameHeight_);
} catch (cpptoml::parse_exception &exc) {
warn << "Failed to parse toml file " << assetpath << ".toml: "
<< exc.what();
}
} else if (errno != ENOENT) {
warn << "Couldn't open " << assetpath << ".toml: " << strerror(errno);
}

texture_.reset(SDL_CreateTextureFromSurface(renderer, surface_.get()));
if (!texture_) {
panic << "CreateTexture failed: " << SDL_GetError();
abort();
}

numFrames_ = surface_->h / frameHeight_;
name_ = id;
}

ImageResource::ImageResource(
SDL_Renderer *renderer, const std::string &name,
int w, int h, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {

surface_.reset(SDL_CreateRGBSurface(
0, TILE_SIZE, TILE_SIZE, 32,
0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff));
SDL_FillRect(surface_.get(), NULL, SDL_MapRGBA(surface_->format, r, g, b, a));

texture_.reset(SDL_CreateTextureFromSurface(renderer, surface_.get()));
if (!texture_) {
panic << "CreateTexture failed: " << SDL_GetError();
abort();
}

frameHeight_ = h;
numFrames_ = 1;
name_ = name;
}

void ImageResource::tick(float dt) {
switchTimer_ -= dt;
if (switchTimer_ <= 0) {
switchTimer_ += switchInterval_;
frame_ += 1;
if (frame_ >= numFrames_)
frame_ = 0;
}
}

ResourceManager::ResourceManager(Win &win) {
addImage(std::make_unique<ImageResource>(
win.renderer_, "@::invalid", TILE_SIZE, TILE_SIZE,
PLACEHOLDER_RED, PLACEHOLDER_GREEN, PLACEHOLDER_BLUE));
addImage(std::make_unique<ImageResource>(
win.renderer_, "@::air", TILE_SIZE, TILE_SIZE,
0, 0, 0, 0));
}

void ResourceManager::tick(float dt) {
for (auto &[k, v]: images_) {
v->tick(dt);
}
}

ImageResource &ResourceManager::getImage(const std::string &name) const {
auto it = images_.find(name);
if (it == end(images_)) {
warn << "Couldn't find image " << name << "!";
return getImage("@::invalid");
}
return *it->second;
}

}

+ 23
- 14
libswan/src/World.cc View File

@@ -5,7 +5,6 @@

#include "log.h"
#include "Game.h"
#include "Win.h"
#include "Clock.h"
#include "assets.h"

@@ -260,16 +259,6 @@ WorldPlane &World::addPlane(const std::string &gen) {
return *planes_[id];
}

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

return iter->second;
}

Tile::ID World::getTileID(const std::string &name) {
auto iter = tilesMap_.find(name);
if (iter == tilesMap_.end()) {
@@ -285,14 +274,34 @@ Tile &World::getTile(const std::string &name) {
return getTileByID(id);
}

Item &World::getItem(const std::string &name) {
auto iter = items_.find(name);
if (iter == items_.end()) {
warn << "Tried to get non-existent item " << name << "!";
return items_.at(INVALID_TILE_NAME);
}

return iter->second;
}

Cygnet::RenderSprite &World::getSprite(const std::string &name) {
auto iter = resources_.sprites_.find(name);
if (iter == resources_.sprites_.end()) {
warn << "Tried to get non-existent sprite " << name << "!";
return resources_.sprites_.at(INVALID_TILE_NAME);
}

return iter->second;
}

SDL_Color World::backgroundColor() {
return planes_[currentPlane_]->backgroundColor();
}

void World::draw(Win &win) {
void World::draw(Cygnet::Renderer &rnd) {
ZoneScopedN("World draw");
win.cam_ = player_->pos - (win.getSize() / 2) + (player_->size / 2);
planes_[currentPlane_]->draw(win);
game_->cam_.pos = player_->pos; // - (win.getSize() / 2) + (player_->size / 2); TODO
planes_[currentPlane_]->draw(rnd);
}

void World::update(float dt) {

+ 10
- 8
libswan/src/WorldPlane.cc View File

@@ -8,7 +8,6 @@
#include "World.h"
#include "Game.h"
#include "Clock.h"
#include "Win.h"

namespace Swan {

@@ -38,7 +37,6 @@ Context WorldPlane::getContext() {
.game = *world_->game_,
.world = *world_,
.plane = *this,
.resources = world_->resources_
};
}

@@ -124,7 +122,7 @@ void WorldPlane::setTileID(TilePos pos, Tile::ID id) {
if (id != old) {
Tile &newTile = world_->getTileByID(id);
Tile &oldTile = world_->getTileByID(old);
chunk.setTileID(rp, id, newTile.image.texture_.get());
chunk.setTileID(rp, id);
chunk.markModified();

if (!oldTile.isSolid && newTile.isSolid) {
@@ -203,13 +201,13 @@ SDL_Color WorldPlane::backgroundColor() {
return gen_->backgroundColor(world_->player_->pos);
}

void WorldPlane::draw(Win &win) {
void WorldPlane::draw(Cygnet::Renderer &rnd) {
ZoneScopedN("WorldPlane draw");
std::lock_guard<std::mutex> lock(mut_);
auto ctx = getContext();
auto &pbody = *(world_->player_);

gen_->drawBackground(ctx, win, pbody.pos);
gen_->drawBackground(ctx, rnd, pbody.pos);

ChunkPos pcpos = ChunkPos(
(int)floor(pbody.pos.x / CHUNK_WIDTH),
@@ -217,27 +215,31 @@ void WorldPlane::draw(Win &win) {

// Just init one chunk per frame
if (chunkInitList_.size() > 0) {
/*
Chunk *chunk = chunkInitList_.front();
chunkInitList_.pop_front();
chunk->render(ctx, win.renderer_);
TODO */
}

for (int x = -1; x <= 1; ++x) {
for (int y = -1; y <= 1; ++y) {
auto iter = chunks_.find(pcpos + ChunkPos(x, y));
if (iter != chunks_.end())
iter->second.draw(ctx, win);
iter->second.draw(ctx, rnd);
}
}

for (auto &coll: entColls_)
coll->draw(ctx, win);
coll->draw(ctx, rnd);

/*
if (debugBoxes_.size() > 0) {
for (auto &pos: debugBoxes_) {
win.drawRect(pos, Vec2(1, 1));
rnd.drawRect(pos, Vec2(1, 1));
}
}
TODO */
}

void WorldPlane::update(float dt) {

+ 2
- 0
libswan/src/drawutil.cc View File

@@ -44,6 +44,7 @@ SDL_Color linearGradient(
return arr[size - 1].second;
}

/*
void parallaxBackground(
Win &win, SDL_Texture *tex,
std::optional<SDL_Rect> srcrect, std::optional<SDL_Rect> destrect,
@@ -92,6 +93,7 @@ void parallaxBackground(
}
}
}
TODO */

}
}

+ 2
- 3
libswan/src/traits/BodyTrait.cc View File

@@ -1,11 +1,10 @@
#include "traits/BodyTrait.h"

#include "Win.h"

namespace Swan {

/*
void BodyTrait::Body::outline(Win &win) {
win.drawRect(pos, size);
}
} TODO */

}

+ 0
- 1
libswan/src/traits/PhysicsTrait.cc View File

@@ -1,7 +1,6 @@
#include "traits/PhysicsTrait.h"

#include "WorldPlane.h"
#include "Win.h"

namespace Swan {


Loading…
Cancel
Save