Implements element handling.
This commit is contained in:
parent
213902021c
commit
e74a599ac1
@ -156,8 +156,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\common.h" />
|
||||
<ClInclude Include="src\ElementStore.h" />
|
||||
<ClInclude Include="src\Font.h" />
|
||||
<ClInclude Include="src\Game.h" />
|
||||
<ClInclude Include="src\GlyphElementFactory.h" />
|
||||
<ClInclude Include="src\iDrawable.h" />
|
||||
<ClInclude Include="src\iElement.h" />
|
||||
<ClInclude Include="src\iElementDriver.h" />
|
||||
@ -180,6 +182,7 @@
|
||||
<ClInclude Include="src\SystemClock.h" />
|
||||
<ClInclude Include="src\Text.h" />
|
||||
<ClInclude Include="src\Texture.h" />
|
||||
<ClInclude Include="src\TextureElement.h" />
|
||||
<ClInclude Include="src\TickingClock.h" />
|
||||
<ClInclude Include="thirdparty\lauxlib.h" />
|
||||
<ClInclude Include="thirdparty\linalg.h" />
|
||||
@ -189,6 +192,7 @@
|
||||
<ClInclude Include="thirdparty\lualib.h" />
|
||||
<ClInclude Include="thirdparty\stb_truetype.h" />
|
||||
<ClInclude Include="src\Win32Console.h" />
|
||||
<ClInclude Include="thirdparty\utf8.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CopyFileToFolders Include="thirdparty\lua5.1.dll">
|
||||
|
@ -33,10 +33,10 @@
|
||||
<ClCompile Include="src\Game.cc">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\PlayScene.cc">
|
||||
<ClCompile Include="src\Lua.cc">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Lua.cc">
|
||||
<ClCompile Include="src\PlayScene.cc">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
@ -143,6 +143,18 @@
|
||||
<ClInclude Include="src\iElementDriver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\TextureElement.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\GlyphElementFactory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\ElementStore.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thirdparty\utf8.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Library Include="thirdparty\lua5.1.lib" />
|
||||
|
81
src/ElementStore.h
Normal file
81
src/ElementStore.h
Normal file
@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "iAllocator.h"
|
||||
#include "iClock.h"
|
||||
#include "iElement.h"
|
||||
|
||||
|
||||
namespace gj {
|
||||
|
||||
|
||||
class ElementStore {
|
||||
public:
|
||||
ElementStore() = delete;
|
||||
|
||||
ElementStore(ElementStore&&) = delete;
|
||||
ElementStore(const ElementStore&) = delete;
|
||||
|
||||
ElementStore& operator=(ElementStore&&) = delete;
|
||||
ElementStore& operator=(const ElementStore&) = delete;
|
||||
|
||||
ElementStore(iClock* clock, size_t reserve) : clock_(clock) {
|
||||
pending_.reserve(reserve);
|
||||
performing_.reserve(reserve);
|
||||
}
|
||||
|
||||
void Schedule(UniqPtr<iElement>&& e) {
|
||||
const uint64_t st = e->period.start;
|
||||
|
||||
auto insert_pos = std::find_if(pending_.begin(), pending_.end(),
|
||||
[st](auto& x) { return x->period.start > st; });
|
||||
|
||||
pending_.insert(insert_pos, std::move(e));
|
||||
}
|
||||
|
||||
void Update(Frame& frame) {
|
||||
const uint64_t now = clock_->now();
|
||||
|
||||
auto pending_beg = pending_.begin();
|
||||
auto pending_end = pending_.end();
|
||||
auto pending_itr = pending_beg;
|
||||
for (; pending_itr < pending_end; ++pending_itr) {
|
||||
iElement* e = pending_itr->get();
|
||||
if (e->period.start > now) {
|
||||
break;
|
||||
}
|
||||
performing_.push_back(std::move(*pending_itr));
|
||||
}
|
||||
pending_.erase(pending_beg, pending_itr);
|
||||
|
||||
for (auto& eptr : performing_) {
|
||||
iElement* e = eptr.get();
|
||||
if (e->period.end <= now) {
|
||||
eptr = nullptr;
|
||||
} else {
|
||||
e->Update(frame, e->period.Normalize(now));
|
||||
}
|
||||
}
|
||||
|
||||
/* erase nullptr */
|
||||
performing_.erase(
|
||||
std::remove_if(
|
||||
performing_.begin(), performing_.end(), [](auto& x) {return !x; }),
|
||||
performing_.end());
|
||||
}
|
||||
|
||||
bool IsEmpty() {
|
||||
return pending_.empty() && performing_.empty();
|
||||
}
|
||||
|
||||
private:
|
||||
const iClock* clock_;
|
||||
|
||||
std::vector<UniqPtr<iElement>> pending_;
|
||||
std::vector<UniqPtr<iElement>> performing_;
|
||||
};
|
||||
|
||||
|
||||
}
|
56
src/Font.h
56
src/Font.h
@ -42,7 +42,7 @@ namespace gj {
|
||||
}
|
||||
}
|
||||
|
||||
Colorbuffer&& RenderGlyph(char16_t c, uint32_t fontsize = 32) {
|
||||
Colorbuffer RenderGlyph(char16_t c, uint32_t fontsize = 32) {
|
||||
int w, h;
|
||||
|
||||
const float s = stbtt_ScaleForPixelHeight(&stb_, fontsize*1.f);
|
||||
@ -60,6 +60,60 @@ namespace gj {
|
||||
}
|
||||
return std::move(ret);
|
||||
}
|
||||
Colorbuffer RenderGlyphs(const std::wstring& str, uint32_t fontsize = 32) {
|
||||
const float s = stbtt_ScaleForPixelHeight(&stb_, fontsize * 1.f);
|
||||
|
||||
int ascent;
|
||||
stbtt_GetFontVMetrics(&stb_, &ascent, 0, 0);
|
||||
|
||||
const int baseline = static_cast<int>(ascent * s);
|
||||
|
||||
/* calculate bitmap size */
|
||||
float h = 0, w = 2;
|
||||
for (auto c : str) {
|
||||
int advance, lsb;
|
||||
stbtt_GetCodepointHMetrics(&stb_, c, &advance, &lsb);
|
||||
|
||||
int x0, y0, x1, y1;
|
||||
const float x_shift = w - (int) w;
|
||||
stbtt_GetCodepointBitmapBoxSubpixel(&stb_, c, s, s, x_shift, 0, &x0, &y0, &x1, &y1);
|
||||
|
||||
const int ch = y1 - y0;
|
||||
if (h < ch) h = static_cast<float>(ch);
|
||||
|
||||
w += advance * s;
|
||||
}
|
||||
|
||||
Colorbuffer buf(alloc_, static_cast<uint32_t>(w), static_cast<uint32_t>(h));
|
||||
buf.Clear();
|
||||
|
||||
float* dst = buf.ptr();
|
||||
|
||||
float x = 2;
|
||||
for (auto c : str) {
|
||||
int advance, lsb;
|
||||
stbtt_GetCodepointHMetrics(&stb_, c, &advance, &lsb);
|
||||
|
||||
int x0, y0, x1, y1;
|
||||
const float x_shift = x - (int)x;
|
||||
stbtt_GetCodepointBitmapBoxSubpixel(&stb_, c, s, s, x_shift, 0, &x0, &y0, &x1, &y1);
|
||||
|
||||
uint8_t ptr[64][64] = {0};
|
||||
stbtt_MakeCodepointBitmapSubpixel(&stb_, &ptr[0][0], x1-x0, y1-y0, 64, s, s, x_shift, 0, c);
|
||||
|
||||
const int l = static_cast<int>(x) + x0;
|
||||
const int r = static_cast<int>(x) + x1;
|
||||
const int u = baseline + y0;
|
||||
const int b = baseline + y1;
|
||||
for (int y = 0; y < b-u; ++y) {
|
||||
for (int x = 0; x < r-l; ++x) {
|
||||
dst[y*static_cast<int>(w) + l+x] = static_cast<float>(ptr[y][x]*1. / UINT8_MAX);
|
||||
}
|
||||
}
|
||||
x += advance * s;
|
||||
}
|
||||
return std::move(buf);
|
||||
}
|
||||
|
||||
private:
|
||||
iAllocator* alloc_;
|
||||
|
57
src/GlyphElementFactory.h
Normal file
57
src/GlyphElementFactory.h
Normal file
@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include "Font.h"
|
||||
#include "iAllocator.h"
|
||||
#include "iClock.h"
|
||||
#include "iElementFactory.h"
|
||||
#include "Texture.h"
|
||||
#include "TextureElement.h"
|
||||
|
||||
|
||||
namespace gj {
|
||||
|
||||
class GlyphElementFactory : public iElementFactory {
|
||||
public:
|
||||
GlyphElementFactory(GlyphElementFactory&&) = delete;
|
||||
GlyphElementFactory(const GlyphElementFactory&) = delete;
|
||||
|
||||
GlyphElementFactory& operator=(GlyphElementFactory&&) = delete;
|
||||
GlyphElementFactory& operator=(const GlyphElementFactory&) = delete;
|
||||
|
||||
GlyphElementFactory(iAllocator* alloc) : alloc_(alloc) {
|
||||
}
|
||||
|
||||
UniqPtr<iElement> Create(Param&& param) override {
|
||||
if (param.custom.size() != 3) return nullptr;
|
||||
|
||||
const std::string text = std::get<std::string>(param.custom[0]);
|
||||
const std::string name = std::get<std::string>(param.custom[1]);
|
||||
const intmax_t size = std::get<double>(param.custom[2]);
|
||||
|
||||
auto& font = FindOrCreateFont(name);
|
||||
auto tex = std::move(font.RenderGlyphs(ConvertUtf8ToUtf16(text), size)); /* TODO */
|
||||
|
||||
return alloc_->MakeUniq<iElement, TextureElement>(
|
||||
param.period, std::move(tex), std::move(param.driver));
|
||||
}
|
||||
|
||||
private:
|
||||
Font& FindOrCreateFont(const std::string& name) {
|
||||
auto found = fonts_.find(name);
|
||||
if (found != fonts_.end()) {
|
||||
return *found->second;
|
||||
}
|
||||
auto f = alloc_->MakeUniq<Font>(alloc_, "res/font/"+name);
|
||||
auto ptr = f.get();
|
||||
fonts_[name] = std::move(f);
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
iAllocator* alloc_;
|
||||
|
||||
std::map<std::string, UniqPtr<Font>> fonts_;
|
||||
};
|
||||
|
||||
|
||||
}
|
@ -76,6 +76,9 @@ public:
|
||||
|
||||
hprev->next += h->next;
|
||||
hnext->prev += h->prev;
|
||||
|
||||
// chaos test
|
||||
// std::memset(h, 0xFF, h->next);
|
||||
}
|
||||
|
||||
private:
|
||||
|
104
src/Lua.cc
104
src/Lua.cc
@ -1,6 +1,45 @@
|
||||
#include "Lua.h"
|
||||
|
||||
|
||||
struct LuaPusher {
|
||||
LuaPusher() = delete;
|
||||
LuaPusher(lua_State* L) : L(L) {
|
||||
}
|
||||
|
||||
void operator()(int64_t v) {
|
||||
lua_pushinteger(L, v);
|
||||
}
|
||||
void operator()(double v) {
|
||||
lua_pushnumber(L, v);
|
||||
}
|
||||
void operator()(const std::string& v) {
|
||||
lua_pushstring(L, v.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
lua_State* L;
|
||||
};
|
||||
struct LuaTaker {
|
||||
LuaTaker() = delete;
|
||||
LuaTaker(lua_State* L, int index) : L(L), index_(index) {
|
||||
}
|
||||
|
||||
void operator()(int64_t& v) {
|
||||
v = luaL_checkinteger(L, index_);
|
||||
}
|
||||
void operator()(double& v) {
|
||||
v = luaL_checknumber(L, index_);
|
||||
}
|
||||
void operator()(std::string& v) {
|
||||
v = luaL_checkstring(L, index_);
|
||||
}
|
||||
|
||||
private:
|
||||
lua_State* L;
|
||||
int index_;
|
||||
};
|
||||
|
||||
|
||||
class LuaFunc : public gj::iElementDriver {
|
||||
public:
|
||||
LuaFunc() = delete;
|
||||
@ -10,7 +49,8 @@ class LuaFunc : public gj::iElementDriver {
|
||||
LuaFunc& operator=(LuaFunc&&) = delete;
|
||||
LuaFunc& operator=(const LuaFunc&) = delete;
|
||||
|
||||
LuaFunc(lua_State* L) : L(L) {
|
||||
LuaFunc(lua_State* L, int index) : L(L) {
|
||||
lua_pushvalue(L, index);
|
||||
func_ = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
@ -20,26 +60,19 @@ class LuaFunc : public gj::iElementDriver {
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, func_);
|
||||
}
|
||||
|
||||
void Update(Param& param) override {
|
||||
void Update(Param& param, double t) override {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, func_);
|
||||
|
||||
lua_pushnumber(L, t);
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, table_);
|
||||
for (const auto& p : param) {
|
||||
lua_pushstring(L, p.first.c_str());
|
||||
if (std::holds_alternative<int64_t>(p.second)) {
|
||||
lua_pushinteger(L, std::get<int64_t>(p.second));
|
||||
} else if (std::holds_alternative<double>(p.second)) {
|
||||
lua_pushnumber(L, std::get<double>(p.second));
|
||||
} else if (std::holds_alternative<std::string>(p.second)) {
|
||||
const std::string str = std::get<std::string>(p.second);
|
||||
lua_pushstring(L, str.c_str());
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
std::visit(LuaPusher(L), p.second);
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
|
||||
const int ret = lua_pcall(L, 1, 0, 0);
|
||||
const int ret = lua_pcall(L, 2, 0, 0);
|
||||
if (ret) {
|
||||
gj::Abort(std::string("Lua error: ")+lua_tostring(L, -1));
|
||||
}
|
||||
@ -48,16 +81,7 @@ class LuaFunc : public gj::iElementDriver {
|
||||
for (auto& p : param) {
|
||||
lua_pushstring(L, p.first.c_str());
|
||||
lua_rawget(L, -2);
|
||||
|
||||
if (std::holds_alternative<int64_t>(p.second)) {
|
||||
p.second = luaL_checkinteger(L, -1);
|
||||
} else if (std::holds_alternative<double>(p.second)) {
|
||||
p.second = luaL_checknumber(L, -1);
|
||||
} else if (std::holds_alternative<std::string>(p.second)) {
|
||||
p.second = luaL_checkstring(L, -1);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
std::visit(LuaTaker(L, -1), p.second);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
@ -74,25 +98,46 @@ class LuaFunc : public gj::iElementDriver {
|
||||
static int CallFactory_(lua_State* L) {
|
||||
gj::iAllocator* alloc =
|
||||
reinterpret_cast<gj::iAllocator*>(lua_touserdata(L, lua_upvalueindex(1)));
|
||||
gj::ElementStore* store =
|
||||
reinterpret_cast<gj::ElementStore*>(lua_touserdata(L, lua_upvalueindex(2)));
|
||||
gj::iElementFactory* factory =
|
||||
reinterpret_cast<gj::iElementFactory*>(lua_touserdata(L, lua_upvalueindex(2)));
|
||||
reinterpret_cast<gj::iElementFactory*>(lua_touserdata(L, lua_upvalueindex(3)));
|
||||
|
||||
const int n = lua_gettop(L);
|
||||
|
||||
const lua_Integer st = luaL_checkinteger(L, 1);
|
||||
const lua_Integer ed = luaL_checkinteger(L, 2);
|
||||
if (st >= ed) {
|
||||
return luaL_error(L, "invalid period");
|
||||
}
|
||||
if (!lua_isfunction(L, 3)) {
|
||||
if (!lua_isfunction(L, n)) {
|
||||
return luaL_error(L, "no driver specified");
|
||||
}
|
||||
|
||||
lua_pushvalue(L, 3);
|
||||
factory->Create(gj::Period(st, ed), alloc->MakeUniq<gj::iElementDriver, LuaFunc>(L));
|
||||
gj::iElementFactory::Param param;
|
||||
param.period = gj::Period(st, ed);
|
||||
param.driver = alloc->MakeUniq<gj::iElementDriver, LuaFunc>(L, n);
|
||||
|
||||
for (int i = 3; i < n; ++i) {
|
||||
gj::iElementFactory::Param::CustomValue v;
|
||||
if (lua_isnumber(L, i)) {
|
||||
v = lua_tonumber(L, i);
|
||||
} else if (lua_isstring(L, i)) {
|
||||
v = lua_tostring(L, i);
|
||||
} else {
|
||||
return luaL_error(L, "invalid args");
|
||||
}
|
||||
param.custom.push_back(v);
|
||||
}
|
||||
|
||||
auto e = factory->Create(std::move(param));
|
||||
if (!e) return luaL_error(L, "factory returned nullptr");
|
||||
store->Schedule(std::move(e));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
gj::Lua::Lua(iAllocator* alloc, const FactoryMap& factory, const std::string& path) {
|
||||
gj::Lua::Lua(iAllocator* alloc, ElementStore* store, const FactoryMap& factory, const std::string& path) {
|
||||
L = luaL_newstate();
|
||||
if (L == nullptr) {
|
||||
Abort("lua_newstate failure");
|
||||
@ -102,8 +147,9 @@ gj::Lua::Lua(iAllocator* alloc, const FactoryMap& factory, const std::string& pa
|
||||
lua_pushstring(L, f.first.c_str());
|
||||
|
||||
lua_pushlightuserdata(L, alloc);
|
||||
lua_pushlightuserdata(L, store);
|
||||
lua_pushlightuserdata(L, f.second);
|
||||
lua_pushcclosure(L, CallFactory_, 2);
|
||||
lua_pushcclosure(L, CallFactory_, 3);
|
||||
|
||||
lua_rawset(L, LUA_GLOBALSINDEX);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "common.h"
|
||||
#include "iAllocator.h"
|
||||
#include "iElementFactory.h"
|
||||
#include "ElementStore.h"
|
||||
|
||||
|
||||
namespace gj {
|
||||
@ -24,7 +25,7 @@ class Lua {
|
||||
Lua& operator=(Lua&&) = delete;
|
||||
Lua& operator=(const Lua&) = delete;
|
||||
|
||||
Lua(iAllocator* alloc, const FactoryMap& factory, const std::string& path);
|
||||
Lua(iAllocator* alloc, ElementStore* store, const FactoryMap& factory, const std::string& path);
|
||||
|
||||
~Lua() {
|
||||
lua_close(L);
|
||||
|
10
src/Period.h
10
src/Period.h
@ -7,13 +7,17 @@ namespace gj {
|
||||
|
||||
struct Period {
|
||||
public:
|
||||
Period() = delete;
|
||||
|
||||
Period() : Period(0, 0) {
|
||||
}
|
||||
Period(uint64_t st, uint64_t ed) : start(st), end(ed) {
|
||||
assert(st <= ed);
|
||||
}
|
||||
|
||||
bool isHit(uint64_t now) const {
|
||||
double Normalize(uint64_t now) const {
|
||||
return (static_cast<int64_t>(now) - start)*1./duration();
|
||||
}
|
||||
|
||||
bool IsHit(uint64_t now) const {
|
||||
return start <= now && now < end;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,18 @@
|
||||
#include "PlayScene.h"
|
||||
|
||||
#include "GlyphElementFactory.h"
|
||||
|
||||
gj::PlayScene::PlayScene(gj::PlayScene::Param&& p) :
|
||||
|
||||
gj::PlayScene::PlayScene(Param&& p) :
|
||||
alloc_(p.alloc), logger_(p.logger), w_(p.w), h_(p.h),
|
||||
clock_(p.clock) {
|
||||
lua_ = alloc_->MakeUniq<Lua>(alloc_, Lua::FactoryMap(), "res/score/"+p.score+".lua");
|
||||
clock_(p.clock), store_(&clock_, 256) {
|
||||
GlyphElementFactory glyph(alloc_);
|
||||
|
||||
Lua::FactoryMap map;
|
||||
map["Glyph"] = &glyph;
|
||||
|
||||
lua_ = alloc_->MakeUniq<Lua>(
|
||||
alloc_, &store_, map, "res/score/" + p.score + ".lua");
|
||||
|
||||
logger_->Print(L"PlayScene init");
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "ElementStore.h"
|
||||
#include "Frame.h"
|
||||
#include "iAllocator.h"
|
||||
#include "iLogger.h"
|
||||
@ -33,6 +35,10 @@ class PlayScene : public iScene {
|
||||
PlayScene(Param&& p);
|
||||
|
||||
UniqPtr<iScene> Update(Frame& f) override {
|
||||
if (store_.IsEmpty()) {
|
||||
/* TODO create and return next scene */
|
||||
}
|
||||
store_.Update(f);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -44,6 +50,7 @@ class PlayScene : public iScene {
|
||||
|
||||
OffsetClock clock_;
|
||||
|
||||
ElementStore store_;
|
||||
UniqPtr<Lua> lua_;
|
||||
};
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "iAllocator.h"
|
||||
|
||||
@ -15,36 +16,18 @@ class Rasterbuffer {
|
||||
Rasterbuffer(const Rasterbuffer&) = delete;
|
||||
Rasterbuffer& operator=(const Rasterbuffer&) = delete;
|
||||
|
||||
Rasterbuffer(Rasterbuffer&& src) = default;
|
||||
Rasterbuffer& operator=(Rasterbuffer&& src) = default;
|
||||
|
||||
Rasterbuffer(iAllocator* alloc, uint32_t w, uint32_t h) :
|
||||
alloc_(alloc), w_(w), h_(h),
|
||||
buf_(alloc->Alloc<T>(static_cast<uint64_t>(w_)*h_)) {
|
||||
_ASSERT(buf_ != nullptr);
|
||||
buf_(alloc->MakeUniqArray<T>(static_cast<uint64_t>(w_)*h_)) {
|
||||
}
|
||||
~Rasterbuffer() {
|
||||
alloc_->Free(buf_);
|
||||
}
|
||||
|
||||
Rasterbuffer(Rasterbuffer&& src) noexcept :
|
||||
alloc_(src.alloc_), w_(src.w_), h_(src.h_), buf_(src.buf_) {
|
||||
src.buf_ = nullptr;
|
||||
}
|
||||
Rasterbuffer& operator=(Rasterbuffer&& src) noexcept {
|
||||
if (this != &src) {
|
||||
alloc_ = src.alloc_;
|
||||
w_ = src.w_;
|
||||
h_ = src.h_;
|
||||
buf_ = src.buf_;
|
||||
src.buf_ = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void Clear() {
|
||||
memset(buf_, 0, static_cast<uint64_t>(w_) * h_ * sizeof(T));
|
||||
std::memset(buf_.get(), 0, static_cast<uint64_t>(w_) * h_ * sizeof(T));
|
||||
}
|
||||
|
||||
|
||||
uint32_t width() const {
|
||||
return w_;
|
||||
}
|
||||
@ -52,17 +35,17 @@ class Rasterbuffer {
|
||||
return h_;
|
||||
}
|
||||
T* ptr() {
|
||||
return buf_;
|
||||
return buf_.get();
|
||||
}
|
||||
const T* ptr() const {
|
||||
return buf_;
|
||||
return buf_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
iAllocator* alloc_;
|
||||
|
||||
uint32_t w_, h_;
|
||||
T* buf_;
|
||||
UniqPtr<T> buf_;
|
||||
};
|
||||
|
||||
using Colorbuffer = Rasterbuffer<float>;
|
||||
|
@ -72,7 +72,7 @@ void gj::Texture::Draw(Colorbuffer& fb) const {
|
||||
if (std::abs(xf) > 1 || std::abs(yf) > 1) continue;
|
||||
|
||||
int32_t srcx = static_cast<int32_t>((xf+1)/2 * srcw);
|
||||
int32_t srcy = srch - 1 - static_cast<int32_t>((yf+1)/2 * srch);
|
||||
int32_t srcy = static_cast<int32_t>((yf+1)/2 * srch);
|
||||
if (srcx >= srcw) srcx = srcw - 1;
|
||||
if (srcy >= srch) srcy = srch - 1;
|
||||
|
||||
@ -81,7 +81,7 @@ void gj::Texture::Draw(Colorbuffer& fb) const {
|
||||
if (dstx < 0 || w <= dstx) continue;
|
||||
if (dsty < 0 || h <= dsty) continue;
|
||||
|
||||
dst[dstx + w*dsty] = src[srcx + srcw*srcy];
|
||||
dst[dstx + w*dsty] = src[srcx + srcw*srcy] * alpha_;
|
||||
}
|
||||
}
|
||||
}
|
55
src/TextureElement.h
Normal file
55
src/TextureElement.h
Normal file
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include "iElement.h"
|
||||
#include "iElementDriver.h"
|
||||
#include "Texture.h"
|
||||
|
||||
namespace gj {
|
||||
|
||||
|
||||
class TextureElement : public iElement {
|
||||
public:
|
||||
TextureElement() = delete;
|
||||
TextureElement(TextureElement&&) = delete;
|
||||
TextureElement(const TextureElement&) = delete;
|
||||
|
||||
TextureElement& operator=(TextureElement&&) = delete;
|
||||
TextureElement& operator=(const TextureElement&) = delete;
|
||||
|
||||
TextureElement(const Period& p, Texture&& tex, UniqPtr<iElementDriver>&& drv) :
|
||||
iElement(p), tex_(std::move(tex)), drv_(std::move(drv)) {
|
||||
param_["posX"] = 0.;
|
||||
param_["posY"] = 0.;
|
||||
param_["scaleX"] = 1.;
|
||||
param_["scaleY"] = 1.;
|
||||
param_["alpha"] = 1.;
|
||||
}
|
||||
|
||||
void Update(Frame& frame, double t) override {
|
||||
drv_->Update(param_, t);
|
||||
|
||||
const double posX = std::get<double>(param_["posX"]);
|
||||
const double posY = std::get<double>(param_["posY"]);
|
||||
const double scaleX = std::get<double>(param_["scaleX"]);
|
||||
const double scaleY = std::get<double>(param_["scaleY"]);
|
||||
const double alpha = std::get<double>(param_["alpha"]);
|
||||
|
||||
tex_.SetMatrix(mat3{
|
||||
{ scaleX, 0, 0 },
|
||||
{ 0, scaleY, 0 },
|
||||
{ posX, posY, 1},
|
||||
});
|
||||
tex_.SetAlpha(static_cast<float>(alpha));
|
||||
|
||||
frame.Add(&tex_);
|
||||
}
|
||||
|
||||
private:
|
||||
Texture tex_;
|
||||
UniqPtr<iElementDriver> drv_;
|
||||
|
||||
iElementDriver::Param param_;
|
||||
};
|
||||
|
||||
|
||||
}
|
16
src/common.h
16
src/common.h
@ -1,8 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <codecvt>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#define NOMINMAX
|
||||
@ -10,6 +9,7 @@
|
||||
#undef NOMINMAX
|
||||
|
||||
#include "thirdparty/linalg.h"
|
||||
#include "thirdparty/utf8.h"
|
||||
|
||||
namespace gj {
|
||||
|
||||
@ -19,9 +19,15 @@ using vec3 = ::linalg::vec<double, 3>;
|
||||
|
||||
|
||||
static inline std::wstring ConvertUtf8ToUtf16(const std::string& str) {
|
||||
std::wostringstream conv;
|
||||
conv << str.c_str();
|
||||
return conv.str();
|
||||
std::wstring ret;
|
||||
|
||||
const void* c = str.c_str();
|
||||
for (;;) {
|
||||
int32_t code;
|
||||
c = utf8codepoint(c, &code);
|
||||
if (!code) return ret;
|
||||
ret += static_cast<wchar_t>(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,9 +40,15 @@ class DrawableBase : public iDrawable {
|
||||
invmat_ = ::linalg::inverse(mat_);
|
||||
}
|
||||
|
||||
void SetAlpha(float a) {
|
||||
alpha_ = a;
|
||||
}
|
||||
|
||||
protected:
|
||||
mat3 mat_ = ::linalg::identity;
|
||||
mat3 invmat_ = ::linalg::identity;
|
||||
|
||||
float alpha_ = 1;
|
||||
};
|
||||
|
||||
|
||||
|
@ -9,16 +9,19 @@ namespace gj {
|
||||
|
||||
class iElement {
|
||||
public:
|
||||
iElement() = delete;
|
||||
iElement(iElement&&) = default;
|
||||
iElement(const iElement&) = default;
|
||||
|
||||
iElement& operator=(iElement&&) = default;
|
||||
iElement& operator=(const iElement&) = default;
|
||||
|
||||
iElement() = default;
|
||||
virtual ~iElement() = default;
|
||||
|
||||
virtual void Update(Frame& f) = 0;
|
||||
iElement(const Period& p) : period(p) {
|
||||
}
|
||||
|
||||
virtual void Update(Frame& frame, double t) = 0;
|
||||
|
||||
/* Interfaces had better not have a variable but this is for optimization. */
|
||||
const Period period;
|
||||
|
@ -22,7 +22,7 @@ class iElementDriver {
|
||||
iElementDriver() = default;
|
||||
virtual ~iElementDriver() = default;
|
||||
|
||||
virtual void Update(Param&) = 0;
|
||||
virtual void Update(Param&, double t) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,5 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "iAllocator.h"
|
||||
#include "iElement.h"
|
||||
#include "iElementDriver.h"
|
||||
@ -11,6 +16,14 @@ namespace gj {
|
||||
|
||||
class iElementFactory {
|
||||
public:
|
||||
struct Param {
|
||||
using CustomValue = std::variant<int64_t, double, std::string>;
|
||||
|
||||
Period period;
|
||||
std::vector<CustomValue> custom;
|
||||
UniqPtr<iElementDriver> driver;
|
||||
};
|
||||
|
||||
iElementFactory(iElementFactory&&) = default;
|
||||
iElementFactory(const iElementFactory&) = default;
|
||||
|
||||
@ -20,7 +33,7 @@ class iElementFactory {
|
||||
iElementFactory() = default;
|
||||
virtual ~iElementFactory() = default;
|
||||
|
||||
virtual UniqPtr<iElement> Create(const Period& p, UniqPtr<iElementDriver>&& drv) = 0;
|
||||
virtual UniqPtr<iElement> Create(Param&& p) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
1662
thirdparty/utf8.h
vendored
Normal file
1662
thirdparty/utf8.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user