diff --git a/src/gpu/palette.lolfx b/src/gpu/palette.lolfx index 3013b72e..786ef95f 100644 --- a/src/gpu/palette.lolfx +++ b/src/gpu/palette.lolfx @@ -1,6 +1,6 @@ [vert.glsl] -#version 130 +#version 120 attribute vec3 in_Position; attribute vec2 in_TexCoord; @@ -19,22 +19,22 @@ void main() [frag.glsl] -#version 130 +#version 120 #if defined GL_ES precision mediump float; #endif -uniform sampler1D u_palette; uniform sampler2D u_texture; +uniform sampler2D u_palette; uniform vec2 u_texsize; varying vec2 pass_TexCoord; void main() { - vec4 pal_pos = texture2D(u_texture, pass_TexCoord); - vec4 col = texture2D(u_palette, pal_pos.x); - if (col.a == 0.0) + vec4 pal = texture2D(u_texture, pass_TexCoord); + vec4 col = texture2D(u_palette, vec2(pal.x, 0.f)); + if (pal.x == 0.0) discard; gl_FragColor = col; } diff --git a/src/image/codec/zed-image.cpp b/src/image/codec/zed-image.cpp index 7b6b9e22..762b6b6b 100644 --- a/src/image/codec/zed-image.cpp +++ b/src/image/codec/zed-image.cpp @@ -203,10 +203,10 @@ bool ZedImageData::Open(char const *path) //Store size type { ivec2 size_16 = size; - int32_t s_16 = 16; + int32_t s_16 = 8; while (1) { - if (size_16.x <= s_16) + if (size_16.x < s_16) { size_16.x = s_16; break; @@ -216,7 +216,7 @@ bool ZedImageData::Open(char const *path) s_16 = 8; while (1) { - if (size_16.y <= s_16) + if (size_16.y < s_16) { size_16.y = s_16; break; diff --git a/src/lol/base/assert.h b/src/lol/base/assert.h index f9899182..6dc0fa7f 100644 --- a/src/lol/base/assert.h +++ b/src/lol/base/assert.h @@ -67,11 +67,11 @@ static inline void DebugAbort() 2, 1, TOO_FEW_ARGUMENTS)) #define LOL_COUNT_TO_12(...) \ - LOL_EVAL(LOL_GET_63RD(__VA_ARGS__, 10,10,10,10,10,10,10,10,10,10,\ - 10,10,10,10,10,10,10,10,10,10,\ - 10,10,10,10,10,10,10,10,10,10,\ - 10,10,10,10,10,10,10,10,10,10,\ - 10,10,10,10,10,10,10,10,10,10,\ + LOL_EVAL(LOL_GET_63RD(__VA_ARGS__, 12,12,12,12,12,12,12,12,12,12,\ + 12,12,12,12,12,12,12,12,12,12,\ + 12,12,12,12,12,12,12,12,12,12,\ + 12,12,12,12,12,12,12,12,12,12,\ + 12,12,12,12,12,12,12,12,12,12,\ 12,11,10,9, 8, 7, 6, 5, 4, 3, \ 2, 1, TOO_FEW_ARGUMENTS)) diff --git a/src/lol/base/types.h b/src/lol/base/types.h index 0180bc5d..5da9365b 100644 --- a/src/lol/base/types.h +++ b/src/lol/base/types.h @@ -28,6 +28,37 @@ typedef Real<16> real; /* The “half” type used for 16-bit floating point numbers. */ class half; +#define DEFINE_ENUM(NEW_ENUM) struct NEW_ENUM { + +#define START_VALUE enum Value { +#define ADD_VALUE(NEW_VALUE) E##NEW_VALUE, +#define END_VALUE MAX } m_value; + +#define START_TEXT \ +inline String C() \ +{ \ + static String text[] = { +#define ADD_TEXT(NEW_TEXT) #NEW_TEXT, +#define END_TEXT \ +}; \ +if (m_value >= MAX) \ + return "INVALID"; \ +return text[m_value]; \ +}; \ + +#define END_ENUM(NEW_ENUM) \ + inline NEW_ENUM() : m_value(MAX) {} \ + inline NEW_ENUM(Value v) : m_value(v) {} \ + inline NEW_ENUM(int v) : m_value((Value)v) {} \ + inline NEW_ENUM(float v) : m_value((Value)(int)v) {} \ + bool operator==(const NEW_ENUM& v) { return m_value == v.m_value; } \ + bool operator==(const int& v) { return m_value == NEW_ENUM(v); } \ + bool operator==(const float& v) { return m_value == NEW_ENUM(v); } \ + inline operator Value() { return m_value; } \ +}; \ +bool operator== (int e1, NEW_ENUM& e2) { return (e2 == e1); } \ +bool operator== (float e1, NEW_ENUM& e2){ return (e2 == e1); } + } /* namespace lol */ #endif // __LOL_BASE_TYPES_H__ diff --git a/src/lol/sys/thread.h b/src/lol/sys/thread.h index 2bfe20fe..79a4ec17 100644 --- a/src/lol/sys/thread.h +++ b/src/lol/sys/thread.h @@ -113,9 +113,10 @@ public: bool Start(); //Stop the threads bool Stop(); +protected: //Work stuff bool AddWork(ThreadJob* job); -protected: + //Fetch Results bool FetchResult(Array& results); //Base thread work function static void *BaseThreadWork(void* data); @@ -141,6 +142,8 @@ public: char const *GetName() { return ""; } + //Work stuff + bool AddJob(ThreadJob* job) { return AddWork(job); } bool GetWorkResult(Array& results) { results += m_job_result; diff --git a/src/lolcore.vcxproj b/src/lolcore.vcxproj index 8f7ae5a6..79348d31 100644 --- a/src/lolcore.vcxproj +++ b/src/lolcore.vcxproj @@ -404,6 +404,7 @@ + diff --git a/src/lolcore.vcxproj.filters b/src/lolcore.vcxproj.filters index ef33aa62..0b79ac61 100644 --- a/src/lolcore.vcxproj.filters +++ b/src/lolcore.vcxproj.filters @@ -732,6 +732,9 @@ easymesh + + ... + diff --git a/src/scene.cpp b/src/scene.cpp index 6d5d0cd7..b2e6ec92 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -23,6 +23,7 @@ #include "lolgl.h" LOLFX_RESOURCE_DECLARE(tile); +LOLFX_RESOURCE_DECLARE(palette); LOLFX_RESOURCE_DECLARE(line); namespace lol @@ -72,9 +73,11 @@ private: int m_tile_cam; Array m_tiles; + Array m_palettes; Array m_lights; Shader *m_tile_shader; + Shader *m_palette_shader; VertexDeclaration *m_tile_vdecl; Array m_tile_bufs; @@ -97,6 +100,7 @@ Scene::Scene(ivec2 size) data->m_tile_cam = -1; data->m_tile_shader = 0; + data->m_palette_shader = 0; data->m_tile_vdecl = new VertexDeclaration(VertexStream(VertexUsage::Position), VertexStream(VertexUsage::TexCoord)); @@ -194,7 +198,10 @@ void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale, float t.scale = scale; t.angle = angle; - data->m_tiles.Push(t); + if (tileset->GetPalette()) + data->m_palettes.Push(t); + else + data->m_tiles.Push(t); } void Scene::SetLineTime(float new_time) { data->m_new_line_time = new_time; } @@ -270,7 +277,7 @@ void Scene::RenderTiles() // XXX: rename to Blit() RenderContext rc; /* Early test if nothing needs to be rendered */ - if (!data->m_tiles.Count()) + if (!data->m_tiles.Count() && !data->m_palettes.Count()) return; rc.SetDepthFunc(DepthFunc::LessOrEqual); @@ -283,71 +290,96 @@ void Scene::RenderTiles() // XXX: rename to Blit() #endif if (!data->m_tile_shader) data->m_tile_shader = Shader::Create(LOLFX_RESOURCE_NAME(tile)); + if (!data->m_palette_shader) + data->m_palette_shader = Shader::Create(LOLFX_RESOURCE_NAME(palette)); - ShaderUniform uni_mat, uni_tex, uni_texsize; - ShaderAttrib attr_pos, attr_tex; - attr_pos = data->m_tile_shader->GetAttribLocation(VertexUsage::Position, 0); - attr_tex = data->m_tile_shader->GetAttribLocation(VertexUsage::TexCoord, 0); - - data->m_tile_shader->Bind(); + for (int p = 0; p < 2; p++) + { + Shader *shader = (p == 0) ? data->m_tile_shader : data->m_palette_shader; + Array& tiles = (p == 0) ? data->m_tiles : data->m_palettes; - uni_mat = data->m_tile_shader->GetUniformLocation("u_projection"); - data->m_tile_shader->SetUniform(uni_mat, GetCamera(data->m_tile_cam)->GetProjection()); - uni_mat = data->m_tile_shader->GetUniformLocation("u_view"); - data->m_tile_shader->SetUniform(uni_mat, GetCamera(data->m_tile_cam)->GetView()); - uni_mat = data->m_tile_shader->GetUniformLocation("u_model"); - data->m_tile_shader->SetUniform(uni_mat, mat4(1.f)); + if (tiles.Count() == 0) + continue; - uni_tex = data->m_tile_shader->GetUniformLocation("u_texture"); - data->m_tile_shader->SetUniform(uni_tex, 0); - uni_texsize = data->m_tile_shader->GetUniformLocation("u_texsize"); + ShaderUniform uni_mat, uni_tex, uni_pal, uni_texsize; + ShaderAttrib attr_pos, attr_tex; + attr_pos = shader->GetAttribLocation(VertexUsage::Position, 0); + attr_tex = shader->GetAttribLocation(VertexUsage::TexCoord, 0); - for (int buf = 0, i = 0, n; i < data->m_tiles.Count(); i = n, buf += 2) - { - /* Count how many quads will be needed */ - for (n = i + 1; n < data->m_tiles.Count(); n++) - if (data->m_tiles[i].tileset != data->m_tiles[n].tileset) - break; + shader->Bind(); - /* Create a vertex array object */ - VertexBuffer *vb1 = new VertexBuffer(6 * (n - i) * sizeof(vec3)); - vec3 *vertex = (vec3 *)vb1->Lock(0, 0); - VertexBuffer *vb2 = new VertexBuffer(6 * (n - i) * sizeof(vec2)); - vec2 *texture = (vec2 *)vb2->Lock(0, 0); + uni_mat = shader->GetUniformLocation("u_projection"); + shader->SetUniform(uni_mat, GetCamera(data->m_tile_cam)->GetProjection()); + uni_mat = shader->GetUniformLocation("u_view"); + shader->SetUniform(uni_mat, GetCamera(data->m_tile_cam)->GetView()); + uni_mat = shader->GetUniformLocation("u_model"); + shader->SetUniform(uni_mat, mat4(1.f)); - data->m_tile_bufs.Push(vb1); - data->m_tile_bufs.Push(vb2); + uni_tex = shader->GetUniformLocation("u_texture"); + uni_pal = data->m_palette_shader->GetUniformLocation("u_palette"); + uni_texsize = shader->GetUniformLocation("u_texsize"); - for (int j = i; j < n; j++) + for (int buf = 0, i = 0, n; i < tiles.Count(); i = n, buf += 2) { - data->m_tiles[i].tileset->BlitTile(data->m_tiles[j].id, - data->m_tiles[j].pos, data->m_tiles[j].o, - data->m_tiles[j].scale, data->m_tiles[j].angle, - vertex + 6 * (j - i), texture + 6 * (j - i)); + /* Count how many quads will be needed */ + for (n = i + 1; n < tiles.Count(); n++) + if (tiles[i].tileset != tiles[n].tileset) + break; + + /* Create a vertex array object */ + VertexBuffer *vb1 = new VertexBuffer(6 * (n - i) * sizeof(vec3)); + vec3 *vertex = (vec3 *)vb1->Lock(0, 0); + VertexBuffer *vb2 = new VertexBuffer(6 * (n - i) * sizeof(vec2)); + vec2 *texture = (vec2 *)vb2->Lock(0, 0); + + data->m_tile_bufs.Push(vb1); + data->m_tile_bufs.Push(vb2); + + for (int j = i; j < n; j++) + { + tiles[i].tileset->BlitTile(tiles[j].id, + tiles[j].pos, tiles[j].o, + tiles[j].scale, tiles[j].angle, + vertex + 6 * (j - i), texture + 6 * (j - i)); + } + + vb1->Unlock(); + vb2->Unlock(); + + /* Bind texture */ + if (tiles[i].tileset->GetPalette()) + { + if (tiles[i].tileset->GetTexture()) + shader->SetUniform(uni_tex, tiles[i].tileset->GetTexture()->GetTextureUniform(), 0); + if (tiles[i].tileset->GetPalette()->GetTexture()) + shader->SetUniform(uni_pal, tiles[i].tileset->GetPalette()->GetTexture()->GetTextureUniform(), 1); + } + else + { + shader->SetUniform(uni_tex, 0); + if (tiles[i].tileset->GetTexture()) + shader->SetUniform(uni_tex, tiles[i].tileset->GetTexture()->GetTextureUniform(), 0); + tiles[i].tileset->Bind(); + } + shader->SetUniform(uni_texsize, + (vec2)tiles[i].tileset->GetTextureSize()); + + /* Bind vertex and texture coordinate buffers */ + data->m_tile_vdecl->Bind(); + data->m_tile_vdecl->SetStream(vb1, attr_pos); + data->m_tile_vdecl->SetStream(vb2, attr_tex); + + /* Draw arrays */ + data->m_tile_vdecl->DrawElements(MeshPrimitive::Triangles, 0, (n - i) * 6); + data->m_tile_vdecl->Unbind(); + tiles[i].tileset->Unbind(); } - vb1->Unlock(); - vb2->Unlock(); + tiles.Empty(); - /* Bind texture */ - data->m_tiles[i].tileset->Bind(); - data->m_tile_shader->SetUniform(uni_texsize, - (vec2)data->m_tiles[i].tileset->GetTextureSize()); - - /* Bind vertex and texture coordinate buffers */ - data->m_tile_vdecl->Bind(); - data->m_tile_vdecl->SetStream(vb1, attr_pos); - data->m_tile_vdecl->SetStream(vb2, attr_tex); - - /* Draw arrays */ - data->m_tile_vdecl->DrawElements(MeshPrimitive::Triangles, 0, (n - i) * 6); - data->m_tile_vdecl->Unbind(); - data->m_tiles[i].tileset->Unbind(); + shader->Unbind(); } - data->m_tiles.Empty(); - - data->m_tile_shader->Unbind(); #if defined USE_D3D9 || defined _XBOX /* TODO */ diff --git a/src/sys/file.cpp b/src/sys/file.cpp index acdc387a..45f342c7 100644 --- a/src/sys/file.cpp +++ b/src/sys/file.cpp @@ -80,7 +80,9 @@ class FileData #elif HAVE_STDIO_H /* FIXME: no modes, no error checking, no nothing */ stat(file.C(), &m_stat); - m_fd = fopen(file.C(), (!force_binary) ? ("r") : ("rb")); + String access = (mode == FileAccess::Write) ? ("w") : ("r"); + if (force_binary) access += "b"; + m_fd = fopen(file.C(), access.C()); #endif } @@ -293,13 +295,13 @@ File::~File() //-- void File::Open(StreamType stream) { - return m_data->Open(stream); + m_data->Open(stream); } //-- void File::Open(String const &file, FileAccess mode, bool force_binary) { - return m_data->Open(file, mode, force_binary); + m_data->Open(file, mode, force_binary); } //-- diff --git a/src/sys/thread.cpp b/src/sys/thread.cpp index 43c403f1..2128a269 100644 --- a/src/sys/thread.cpp +++ b/src/sys/thread.cpp @@ -101,6 +101,8 @@ void *BaseThreadManager::BaseThreadWork(void* data) void BaseThreadManager::TickGame(float seconds) { + Entity::TickGame(seconds); + //Start if needed Start(); diff --git a/src/tileset.cpp b/src/tileset.cpp index 8594e433..d1fc4855 100644 --- a/src/tileset.cpp +++ b/src/tileset.cpp @@ -147,6 +147,7 @@ void TileSet::Init(char const *path, Image* image) { m_data->m_name = String(" ") + path; + m_palette = nullptr; m_data->m_texture = 0; m_data->m_image = image; m_data->m_image_size = m_data->m_image->GetSize(); @@ -258,6 +259,31 @@ Texture const * TileSet::GetTexture() const return m_data->m_texture; } +Image * TileSet::GetImage() +{ + return m_data->m_image; +} + +Image const * TileSet::GetImage() const +{ + return m_data->m_image; +} + +void TileSet::SetPalette(TileSet* palette) +{ + m_palette = palette; +} + +TileSet* TileSet::GetPalette() +{ + return m_palette; +} + +TileSet const* TileSet::GetPalette() const +{ + return m_palette; +} + void TileSet::Bind() { if (!m_data->m_image && m_data->m_texture) diff --git a/src/tileset.h b/src/tileset.h index ab50269f..c8e78534 100644 --- a/src/tileset.h +++ b/src/tileset.h @@ -53,6 +53,11 @@ public: Texture * GetTexture(); Texture const * GetTexture() const; + Image * GetImage(); + Image const * GetImage() const; + void SetPalette(TileSet* palette); + TileSet* GetPalette(); + TileSet const * GetPalette() const; ivec2 GetTextureSize() const; void Bind(); void Unbind(); @@ -64,6 +69,7 @@ private: void Init(char const *path, Image* image); TileSetData* m_data; + TileSet* m_palette; }; } /* namespace lol */