Moved ImageLoader to ResourceLoader, so that loading is extensible. i.e. here: Zed image loader now loads up a tileset instead of being a hacked image loader. Goal is to support more funky stuff (wad, pak .....)legacy
@@ -54,7 +54,7 @@ liblol_core_headers = \ | |||
lol/sys/threadtypes.h lol/sys/timer.h \ | |||
\ | |||
lol/image/all.h \ | |||
lol/image/pixel.h lol/image/color.h lol/image/image.h lol/image/movie.h \ | |||
lol/image/pixel.h lol/image/color.h lol/image/image.h lol/image/resource.h lol/image/movie.h \ | |||
\ | |||
lol/gpu/all.h \ | |||
lol/gpu/shader.h lol/gpu/indexbuffer.h lol/gpu/vertexbuffer.h \ | |||
@@ -115,6 +115,7 @@ liblol_core_sources = \ | |||
sys/init.cpp sys/file.cpp sys/hacks.cpp \ | |||
sys/thread.cpp sys/threadtypes.cpp sys/getopt.cpp \ | |||
\ | |||
image/resource.cpp image/resource-private.h \ | |||
image/image.cpp image/image-private.h image/kernel.cpp image/pixel.cpp \ | |||
image/crop.cpp image/resample.cpp image/noise.cpp image/combine.cpp \ | |||
image/codec/gdiplus-image.cpp image/codec/imlib2-image.cpp \ | |||
@@ -21,7 +21,7 @@ extern "C" { | |||
#include <android_native_app_glue.h> | |||
} | |||
#include "../../image/image-private.h" | |||
#include "../../image/resource-private.h" | |||
namespace lol | |||
{ | |||
@@ -32,12 +32,12 @@ extern ANativeActivity *g_activity; | |||
* Image implementation class | |||
*/ | |||
class AndroidImageCodec : public ImageCodec | |||
class AndroidImageCodec : public ResourceCodec | |||
{ | |||
public: | |||
virtual char const *GetName() { return "<AndroidImageCodec>"; } | |||
virtual bool Load(Image *image, char const *path); | |||
virtual bool Save(Image *image, char const *path); | |||
virtual ResourceCodecData* Load(char const *path); | |||
virtual bool Save(char const *path, ResourceCodecData* data); | |||
virtual bool Close(); | |||
virtual uint8_t *GetData() const; | |||
@@ -50,7 +50,7 @@ private: | |||
DECLARE_IMAGE_CODEC(AndroidImageCodec, 100) | |||
bool AndroidImageCodec::Load(Image *image, char const *path) | |||
ResourceCodecData* AndroidImageCodec::Load(char const *path) | |||
{ | |||
JNIEnv *env; | |||
jint res = g_activity->vm->GetEnv((void **)&env, JNI_VERSION_1_2); | |||
@@ -106,12 +106,12 @@ bool AndroidImageCodec::Load(Image *image, char const *path) | |||
} | |||
m_format = PixelFormat::RGBA_8; | |||
return true; | |||
return new ResourceCodecData(); | |||
} | |||
bool AndroidImageCodec::Save(Image *image, char const *path) | |||
bool AndroidImageCodec::Save(char const *path, ResourceCodecData* data) | |||
{ | |||
UNUSED(path); | |||
UNUSED(path, data); | |||
/* TODO: unimplemented */ | |||
} | |||
@@ -10,7 +10,7 @@ | |||
#include <lol/engine-internal.h> | |||
#include "../../image/image-private.h" | |||
#include "../../image/resource-private.h" | |||
namespace lol | |||
{ | |||
@@ -19,12 +19,12 @@ namespace lol | |||
* Image implementation class | |||
*/ | |||
class DummyImageCodec : public ImageCodec | |||
class DummyImageCodec : public ResourceCodec | |||
{ | |||
public: | |||
virtual char const *GetName() { return "<DummyImageCodec>"; } | |||
virtual bool Load(Image *image, char const *path); | |||
virtual bool Save(Image *image, char const *path); | |||
virtual ResourceCodecData* Load(char const *path); | |||
virtual bool Save(char const *path, ResourceCodecData* data); | |||
}; | |||
//Priority 0 because it's supposed to be the last one | |||
@@ -34,11 +34,13 @@ DECLARE_IMAGE_CODEC(DummyImageCodec, 0) | |||
* Public Image class | |||
*/ | |||
bool DummyImageCodec::Load(Image *image, char const *path) | |||
ResourceCodecData* DummyImageCodec::Load(char const *path) | |||
{ | |||
UNUSED(path); | |||
if (strcmp("DUMMY", path)) | |||
return nullptr; | |||
image->SetSize(ivec2(256)); | |||
auto data = new ResourceImageData(new Image(ivec2(256))); | |||
auto image = data->m_image; | |||
u8vec4 *pixels = image->Lock<PixelFormat::RGBA_8>(), *tmp = pixels; | |||
for (int j = 0; j < 256; j++) | |||
for (int i = 0; i < 256; i++) | |||
@@ -51,13 +53,12 @@ bool DummyImageCodec::Load(Image *image, char const *path) | |||
} | |||
image->Unlock(pixels); | |||
//return false, because we're not supposed to be here. | |||
return false; | |||
return data; | |||
} | |||
bool DummyImageCodec::Save(Image *image, char const *path) | |||
bool DummyImageCodec::Save(char const *path, ResourceCodecData* data) | |||
{ | |||
UNUSED(path); | |||
UNUSED(path, data); | |||
return false; | |||
} | |||
@@ -26,7 +26,7 @@ using std::max; | |||
#if LOL_USE_GDIPLUS | |||
#include "../../image/image-private.h" | |||
#include "../../image/resource-private.h" | |||
namespace lol | |||
{ | |||
@@ -35,12 +35,12 @@ namespace lol | |||
* Image implementation class | |||
*/ | |||
class GdiPlusImageCodec : public ImageCodec | |||
class GdiPlusImageCodec : public ResourceCodec | |||
{ | |||
public: | |||
virtual char const *GetName() { return "<GdiPlusImageCodec>"; } | |||
virtual bool Load(Image *image, char const *path); | |||
virtual bool Save(Image *image, char const *path); | |||
virtual ResourceCodecData* Load(char const *path); | |||
virtual bool Save(char const *path, ResourceCodecData* data); | |||
}; | |||
DECLARE_IMAGE_CODEC(GdiPlusImageCodec, 100) | |||
@@ -49,7 +49,7 @@ DECLARE_IMAGE_CODEC(GdiPlusImageCodec, 100) | |||
* Public Image class | |||
*/ | |||
bool GdiPlusImageCodec::Load(Image *image, char const *path) | |||
ResourceCodecData* GdiPlusImageCodec::Load(char const *path) | |||
{ | |||
Gdiplus::Status status; | |||
ULONG_PTR token; | |||
@@ -58,7 +58,7 @@ bool GdiPlusImageCodec::Load(Image *image, char const *path) | |||
if (status != Gdiplus::Ok) | |||
{ | |||
msg::error("error %d while initialising GDI+\n", status); | |||
return false; | |||
return nullptr; | |||
} | |||
array<String> pathlist = sys::get_path_list(path); | |||
@@ -99,7 +99,7 @@ bool GdiPlusImageCodec::Load(Image *image, char const *path) | |||
if (!bitmap) | |||
{ | |||
msg::error("could not load %s\n", path); | |||
return false; | |||
return nullptr; | |||
} | |||
ivec2 size(bitmap->GetWidth(), bitmap->GetHeight()); | |||
@@ -110,13 +110,14 @@ bool GdiPlusImageCodec::Load(Image *image, char const *path) | |||
{ | |||
msg::error("could not lock bits in %s\n", path); | |||
delete bitmap; | |||
return false; | |||
return nullptr; | |||
} | |||
/* FIXME: GDI+ doesn't know about RGBA, only ARGB. And OpenGL doesn't | |||
* know about ARGB, only RGBA. So we swap bytes. We could also fix | |||
* this in the shader. */ | |||
image->SetSize(size); | |||
auto data = new ResourceImageData(new Image(ivec2(size))); | |||
auto image = data->m_image; | |||
u8vec4 *pdst = image->Lock<PixelFormat::RGBA_8>(); | |||
u8vec4 *psrc = static_cast<u8vec4 *>(bdata.Scan0); | |||
for (int n = 0; n < size.x * size.y; n++) | |||
@@ -126,11 +127,15 @@ bool GdiPlusImageCodec::Load(Image *image, char const *path) | |||
bitmap->UnlockBits(&bdata); | |||
delete bitmap; | |||
return true; | |||
return data; | |||
} | |||
bool GdiPlusImageCodec::Save(Image *image, char const *path) | |||
bool GdiPlusImageCodec::Save(char const *path, ResourceCodecData* data) | |||
{ | |||
auto data_image = dynamic_cast<ResourceImageData*>(data); | |||
if (data_image == nullptr) | |||
return false; | |||
ULONG_PTR token; | |||
Gdiplus::GdiplusStartupInput input; | |||
Gdiplus::GdiplusStartup(&token, &input, nullptr); | |||
@@ -178,6 +183,7 @@ bool GdiPlusImageCodec::Save(Image *image, char const *path) | |||
return false; | |||
} | |||
auto image = data_image->m_image; | |||
ivec2 size = image->GetSize(); | |||
Gdiplus::Bitmap *b = new Gdiplus::Bitmap(size.x, size.y, | |||
@@ -16,7 +16,7 @@ | |||
#import <UIKit/UIKit.h> | |||
#include "../../image/image-private.h" | |||
#include "../../image/resource-private.h" | |||
namespace lol | |||
{ | |||
@@ -25,12 +25,12 @@ namespace lol | |||
* Image implementation class | |||
*/ | |||
class IosImageCodec : public ImageCodec | |||
class IosImageCodec : public ResourceCodec | |||
{ | |||
public: | |||
virtual char const *GetName() { return "<IosImageCodec>"; } | |||
virtual bool Load(Image *image, char const *path); | |||
virtual bool Save(Image *image, char const *path); | |||
virtual ResourceCodecData* Load(char const *path); | |||
virtual bool Save(char const *path, ResourceCodecData* data); | |||
}; | |||
DECLARE_IMAGE_CODEC(IosImageCodec, 100) | |||
@@ -39,7 +39,7 @@ DECLARE_IMAGE_CODEC(IosImageCodec, 100) | |||
* Public Image class | |||
*/ | |||
bool IosImageCodec::Load(Image *image, char const *path) | |||
ResourceCodecData* IosImageCodec::Load(char const *path) | |||
{ | |||
NSString *fullpath = [NSString stringWithUTF8String:path]; | |||
NSArray *chunks = [fullpath componentsSeparatedByString: @"/"]; | |||
@@ -54,7 +54,7 @@ bool IosImageCodec::Load(Image *image, char const *path) | |||
#if !LOL_BUILD_RELEASE | |||
msg::error("could not load %s\n", path); | |||
#endif | |||
return false; | |||
return nullptr; | |||
} | |||
int w = CGImageGetWidth(image.CGImage); | |||
@@ -75,12 +75,12 @@ bool IosImageCodec::Load(Image *image, char const *path) | |||
[image release]; | |||
[pngdata release]; | |||
return true; | |||
return new ResourceCodecData(); | |||
} | |||
bool IosImageCodec::Save(Image *image, char const *path) | |||
bool IosImageCodec::Save(char const *path, ResourceCodecData* data) | |||
{ | |||
UNUSED(path); | |||
UNUSED(path, data); | |||
/* TODO: unimplemented */ | |||
return true; | |||
@@ -12,7 +12,7 @@ | |||
#include <cctype> | |||
#include "../../image/image-private.h" | |||
#include "../../image/resource-private.h" | |||
namespace lol | |||
{ | |||
@@ -27,12 +27,12 @@ namespace lol | |||
* Image implementation class | |||
*/ | |||
class OricImageCodec : public ImageCodec | |||
class OricImageCodec : public ResourceCodec | |||
{ | |||
public: | |||
virtual char const *GetName() { return "<OricImageCodec>"; } | |||
virtual bool Load(Image *image, char const *path); | |||
virtual bool Save(Image *image, char const *path); | |||
virtual ResourceCodecData* Load(char const *path); | |||
virtual bool Save(char const *path, ResourceCodecData* data); | |||
private: | |||
static String ReadScreen(char const *name); | |||
@@ -45,7 +45,7 @@ DECLARE_IMAGE_CODEC(OricImageCodec, 100) | |||
* Public Image class | |||
*/ | |||
bool OricImageCodec::Load(Image *image, char const *path) | |||
ResourceCodecData* OricImageCodec::Load(char const *path) | |||
{ | |||
static u8vec4 const pal[8] = | |||
{ | |||
@@ -61,9 +61,10 @@ bool OricImageCodec::Load(Image *image, char const *path) | |||
String screen = ReadScreen(path); | |||
if (screen.count() == 0) | |||
return false; | |||
return nullptr; | |||
image->SetSize(ivec2(WIDTH, screen.count() * 6 / WIDTH)); | |||
auto data = new ResourceImageData(new Image(ivec2(WIDTH, screen.count() * 6 / WIDTH))); | |||
auto image = data->m_image; | |||
u8vec4 *pixels = image->Lock<PixelFormat::RGBA_8>(); | |||
@@ -102,12 +103,16 @@ bool OricImageCodec::Load(Image *image, char const *path) | |||
image->Unlock(pixels); | |||
return true; | |||
return data; | |||
} | |||
bool OricImageCodec::Save(Image *image, char const *path) | |||
bool OricImageCodec::Save(char const *path, ResourceCodecData* data) | |||
{ | |||
int len = strlen(path); | |||
auto data_image = dynamic_cast<ResourceImageData*>(data); | |||
if (data_image == nullptr) | |||
return false; | |||
int len = (int)strlen(path); | |||
if (len < 4 || path[len - 4] != '.' | |||
|| toupper(path[len - 3]) != 'T' | |||
|| toupper(path[len - 2]) != 'A' | |||
@@ -124,6 +129,7 @@ bool OricImageCodec::Save(Image *image, char const *path) | |||
result << (uint8_t)name[0]; | |||
result << 0; | |||
auto image = data_image->m_image; | |||
Image tmp; | |||
ivec2 size = image->GetSize(); | |||
if (size.x != WIDTH) | |||
@@ -481,7 +487,7 @@ void OricImageCodec::WriteScreen(Image &image, array<uint8_t> &result) | |||
for (int y = 0; y < size.y; y++) | |||
for (int x = 0; x < size.x; x++) | |||
for (int c = 0; c < 3; c++) | |||
src[x][y][c] = 0xffff * pixels[y * size.x + x][2 - c]; | |||
src[x][y][c] = 0xffff * (int32_t)pixels[y * size.x + x][2 - c]; | |||
/* Let the fun begin */ | |||
for (int y = 0; y < size.y; y++) | |||
@@ -25,7 +25,7 @@ | |||
# include <SDL_image.h> | |||
#endif | |||
#include "../../image/image-private.h" | |||
#include "../../image/resource-private.h" | |||
namespace lol | |||
{ | |||
@@ -34,19 +34,19 @@ namespace lol | |||
* Image implementation class | |||
*/ | |||
class SdlImageCodec : public ImageCodec | |||
class SdlImageCodec : public ResourceCodec | |||
{ | |||
public: | |||
virtual char const *GetName() { return "<SdlImageCodec>"; } | |||
virtual bool Load(Image *image, char const *path); | |||
virtual bool Save(Image *image, char const *path); | |||
virtual ResourceCodecData* Load(char const *path); | |||
virtual bool Save(char const *path, ResourceCodecData* data); | |||
static SDL_Surface *Create32BppSurface(ivec2 size); | |||
}; | |||
DECLARE_IMAGE_CODEC(SdlImageCodec, 50) | |||
bool SdlImageCodec::Load(Image *image, char const *path) | |||
ResourceCodecData* SdlImageCodec::Load(char const *path) | |||
{ | |||
SDL_Surface *surface = nullptr; | |||
@@ -75,24 +75,30 @@ bool SdlImageCodec::Load(Image *image, char const *path) | |||
surface = tmp; | |||
} | |||
image->SetSize(size); | |||
u8vec4 *data = image->Lock<PixelFormat::RGBA_8>(); | |||
memcpy(data, surface->pixels, 4 * size.x * size.y); | |||
image->Unlock(data); | |||
auto data = new ResourceImageData(new Image(size)); | |||
auto image = data->m_image; | |||
u8vec4 *pixel_data = image->Lock<PixelFormat::RGBA_8>(); | |||
memcpy(pixel_data, surface->pixels, 4 * size.x * size.y); | |||
image->Unlock(pixel_data); | |||
SDL_FreeSurface(surface); | |||
return true; | |||
return data; | |||
} | |||
bool SdlImageCodec::Save(Image *image, char const *path) | |||
bool SdlImageCodec::Save(char const *path, ResourceCodecData* data) | |||
{ | |||
auto data_image = dynamic_cast<ResourceImageData*>(data); | |||
if (data_image == nullptr) | |||
return false; | |||
auto image = data_image->m_image; | |||
ivec2 size = image->GetSize(); | |||
SDL_Surface *surface = Create32BppSurface(size); | |||
u8vec4 *data = image->Lock<PixelFormat::RGBA_8>(); | |||
memcpy(surface->pixels, data, 4 * size.x * size.y); | |||
image->Unlock(data); | |||
u8vec4 *pixel_data = image->Lock<PixelFormat::RGBA_8>(); | |||
memcpy(surface->pixels, pixel_data, 4 * size.x * size.y); | |||
image->Unlock(pixel_data); | |||
int ret = SDL_SaveBMP(surface, path); | |||
SDL_FreeSurface(surface); | |||
@@ -11,7 +11,7 @@ | |||
#include <lol/engine-internal.h> | |||
#include "../../image/image-private.h" | |||
#include "../../image/resource-private.h" | |||
namespace lol | |||
{ | |||
@@ -20,24 +20,12 @@ namespace lol | |||
* Image implementation class | |||
*/ | |||
class ZedImageCodec : public ImageCodec | |||
class ZedImageCodec : public ResourceCodec | |||
{ | |||
public: | |||
virtual char const *GetName() { return "<ZedImageCodec>"; } | |||
virtual bool Load(Image *image, char const *path); | |||
virtual bool Save(Image *image, char const *path); | |||
virtual bool RetrieveTiles(array<ivec2, ivec2>& tiles) | |||
{ | |||
bool result = m_tiles.count() > 0; | |||
tiles += m_tiles; | |||
m_tiles.empty(); | |||
return result; | |||
} | |||
private: | |||
//<Pos, Size> | |||
array<ivec2, ivec2> m_tiles; | |||
virtual ResourceCodecData* Load(char const *path); | |||
virtual bool Save(char const *path, ResourceCodecData* data); | |||
}; | |||
DECLARE_IMAGE_CODEC(ZedImageCodec, 10) | |||
@@ -46,10 +34,10 @@ DECLARE_IMAGE_CODEC(ZedImageCodec, 10) | |||
* Public Image class | |||
*/ | |||
bool ZedImageCodec::Load(Image *image, char const *path) | |||
ResourceCodecData* ZedImageCodec::Load(char const *path) | |||
{ | |||
if (!lol::String(path).ends_with(".RSC")) | |||
return false; | |||
return nullptr; | |||
// Compacter definition | |||
struct CompactSecondary | |||
@@ -142,7 +130,9 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||
} | |||
file_offset << file_size; | |||
m_tiles.reserve(file_count); | |||
//<Pos, Size> | |||
array<ivec2, ivec2> tiles; | |||
tiles.reserve(file_count); | |||
Compacter2d compacter; | |||
compacter.StepSetup(8, 8, 10); | |||
@@ -151,6 +141,7 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||
array<uint8_t> file_convert; | |||
file_convert.reserve(file_size); | |||
array<ivec2> available_sizes; | |||
//got through all the files and store them | |||
for (int i = 0; i < file_count; i++) | |||
{ | |||
file_pos = file_offset[i]; | |||
@@ -187,8 +178,10 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||
//Prepare buffer and tiles infos | |||
int32_t convert_pos = file_convert.count(); | |||
ivec2 size = ivec2(size_x, size_y); | |||
compacter.Store(m_tiles.count(), ivec2(size_x, size_y)); | |||
m_tiles.push(ivec2(file_convert.count(), data_length), ivec2(size_x, size_y)); | |||
//store tile in compacter | |||
compacter.Store(tiles.count(), ivec2(size_x, size_y)); | |||
//push tile on the stack | |||
tiles.push(ivec2(file_convert.count(), data_length), ivec2(size_x, size_y)); | |||
file_convert.resize(convert_pos + data_length); | |||
//Retrieve actual datas | |||
@@ -233,8 +226,9 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||
while (tex_size < tex_sqrt) | |||
tex_size <<= 1; | |||
//Prepare final imqge | |||
image->SetSize(ivec2(tex_size)); | |||
//Prepare final image | |||
auto data = new ResourceTilesetData(new Image(ivec2(tex_size))); | |||
auto image = data->m_image; | |||
uint8_t *pixels = image->Lock<PixelFormat::Y_8>(); | |||
//Data refactor stage | |||
@@ -255,8 +249,8 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||
compacter.m_primary[j].m_count--; | |||
int i = compacter.m_primary[j].m_secondary[k].m_tiles.pop(); | |||
int32_t file_off = m_tiles[i].m1[0]; | |||
ivec2 t_size = m_tiles[i].m2; | |||
int32_t file_off = tiles[i].m1[0]; | |||
ivec2 t_size = tiles[i].m2; | |||
ASSERT(pos.y + t_size.y < tex_size); | |||
@@ -277,7 +271,7 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||
} | |||
//Register new pos and move to next | |||
m_tiles[i].m1 = pos; | |||
tiles[i].m1 = pos; | |||
pos.x += t_size.x; | |||
} | |||
} | |||
@@ -292,12 +286,14 @@ bool ZedImageCodec::Load(Image *image, char const *path) | |||
} | |||
image->Unlock(pixels); | |||
return true; | |||
data->m_tiles = tiles; | |||
return data; | |||
} | |||
bool ZedImageCodec::Save(Image *image, char const *path) | |||
bool ZedImageCodec::Save(char const *path, ResourceCodecData* data) | |||
{ | |||
UNUSED(path); | |||
UNUSED(path, data); | |||
/* FIXME: do we need to implement this? */ | |||
return true; | |||
} | |||
@@ -10,7 +10,7 @@ | |||
#include <lol/engine-internal.h> | |||
#include "../../image/image-private.h" | |||
#include "../../image/resource-private.h" | |||
namespace lol | |||
{ | |||
@@ -19,12 +19,12 @@ namespace lol | |||
* Image implementation class | |||
*/ | |||
class ZedPaletteImageCodec : public ImageCodec | |||
class ZedPaletteImageCodec : public ResourceCodec | |||
{ | |||
public: | |||
virtual char const *GetName() { return "<ZedPaletteImageCodec>"; } | |||
virtual bool Load(Image *image, char const *path); | |||
virtual bool Save(Image *image, char const *path); | |||
virtual ResourceCodecData* Load(char const *path); | |||
virtual bool Save(char const *path, ResourceCodecData* data); | |||
}; | |||
DECLARE_IMAGE_CODEC(ZedPaletteImageCodec, 10) | |||
@@ -33,10 +33,10 @@ DECLARE_IMAGE_CODEC(ZedPaletteImageCodec, 10) | |||
* Public Image class | |||
*/ | |||
bool ZedPaletteImageCodec::Load(Image *image, char const *path) | |||
ResourceCodecData* ZedPaletteImageCodec::Load(char const *path) | |||
{ | |||
if (!lol::String(path).ends_with(".pal")) | |||
return false; | |||
return nullptr; | |||
File file; | |||
file.Open(path, FileAccess::Read, true); | |||
@@ -53,13 +53,15 @@ bool ZedPaletteImageCodec::Load(Image *image, char const *path) | |||
int32_t tex_size = 2; | |||
while (tex_size < tex_sqrt) | |||
tex_size <<= 1; | |||
image->m_data->m_size = ivec2(tex_size); | |||
auto data = new ResourceImageData(new Image(ivec2(tex_size))); | |||
auto image = data->m_image; | |||
#else | |||
int32_t tex_sqrt = file_size / 3; | |||
int32_t tex_size = 2; | |||
while (tex_size < tex_sqrt) | |||
tex_size <<= 1; | |||
image->SetSize(ivec2(tex_size, 1)); | |||
auto data = new ResourceImageData(new Image(ivec2(tex_size, 1))); | |||
auto image = data->m_image; | |||
#endif | |||
u8vec4 *pixels = image->Lock<PixelFormat::RGBA_8>(); | |||
@@ -73,12 +75,12 @@ bool ZedPaletteImageCodec::Load(Image *image, char const *path) | |||
} | |||
image->Unlock(pixels); | |||
return true; | |||
return data; | |||
} | |||
bool ZedPaletteImageCodec::Save(Image *image, char const *path) | |||
bool ZedPaletteImageCodec::Save(char const *path, ResourceCodecData* data) | |||
{ | |||
UNUSED(path); | |||
UNUSED(path, data); | |||
/* FIXME: do we need to implement this? */ | |||
return true; | |||
} | |||
@@ -66,38 +66,5 @@ public: | |||
PixelFormat m_format; | |||
}; | |||
class ImageCodec | |||
{ | |||
public: | |||
virtual char const *GetName() { return "<ImageCodec>"; } | |||
virtual bool Load(Image *image, char const *path) = 0; | |||
virtual bool Save(Image *image, char const *path) = 0; | |||
/* TODO: this should become more fine-grained */ | |||
int m_priority; | |||
}; | |||
#define REGISTER_IMAGE_CODEC(name) \ | |||
extern ImageCodec *Register##name(); \ | |||
{ \ | |||
/* Insert image codecs in a sorted list */ \ | |||
ImageCodec *codec = Register##name(); \ | |||
int i = 0, prio = codec->m_priority; \ | |||
for ( ; i < codeclist.count(); ++i) \ | |||
{ \ | |||
if (codeclist[i]->m_priority <= prio) \ | |||
break; \ | |||
} \ | |||
codeclist.insert(codec, i); \ | |||
} | |||
#define DECLARE_IMAGE_CODEC(name, priority) \ | |||
ImageCodec *Register##name() \ | |||
{ \ | |||
ImageCodec *ret = new name(); \ | |||
ret->m_priority = priority; \ | |||
return ret; \ | |||
} | |||
} /* namespace lol */ | |||
@@ -19,61 +19,6 @@ | |||
namespace lol | |||
{ | |||
/* HACK: We cannot make this an ImageLoader member function, because the | |||
* REGISTER_IMAGE_CODEC macro forward-declares free functions from | |||
* the "lol" namespace. An apparent bug in Visual Studio's compiler | |||
* makes it think these functions are actually in the top-level | |||
* namespace when the forward declaration is in a class member function. | |||
* To avoid the problem, we make the forward declaration in a free | |||
* function. | |||
* The bug was reported to Microsoft and fixed by them, but the fix | |||
* is not yet available. | |||
* https://connect.microsoft.com/VisualStudio/feedback/details/730878/ */ | |||
static bool RegisterAllCodecs(array<ImageCodec *> &codeclist) | |||
{ | |||
#if defined __ANDROID__ | |||
REGISTER_IMAGE_CODEC(AndroidImageCodec) | |||
#endif | |||
#if defined LOL_USE_GDIPLUS | |||
REGISTER_IMAGE_CODEC(GdiPlusImageCodec) | |||
#endif | |||
#if defined __APPLE__ && defined __MACH__ && defined __arm__ | |||
REGISTER_IMAGE_CODEC(IosImageCodec) | |||
#endif | |||
#if defined LOL_USE_SDL_IMAGE | |||
REGISTER_IMAGE_CODEC(SdlImageCodec) | |||
#endif | |||
#if defined LOL_USE_IMLIB2 | |||
REGISTER_IMAGE_CODEC(Imlib2ImageCodec) | |||
#endif | |||
REGISTER_IMAGE_CODEC(DummyImageCodec) | |||
REGISTER_IMAGE_CODEC(ZedImageCodec) | |||
REGISTER_IMAGE_CODEC(ZedPaletteImageCodec) | |||
REGISTER_IMAGE_CODEC(OricImageCodec) | |||
return true; | |||
} | |||
/* | |||
* Our static image loader | |||
*/ | |||
static class ImageLoader | |||
{ | |||
friend class Image; | |||
public: | |||
inline ImageLoader() | |||
{ | |||
RegisterAllCodecs(m_codecs); | |||
} | |||
private: | |||
array<ImageCodec *> m_codecs; | |||
map<String, Image *> m_images; | |||
} | |||
g_image_loader; | |||
/* | |||
* Public Image class | |||
*/ | |||
@@ -117,77 +62,59 @@ Image::~Image() | |||
delete m_data; | |||
} | |||
void Image::DummyFill() | |||
{ | |||
//TODO: This is not very beautiful | |||
for (auto codec : g_image_loader.m_codecs) | |||
{ | |||
if (String(codec->GetName()).contains("Dummy")) | |||
{ | |||
codec->Load(this, nullptr); | |||
return; | |||
} | |||
} | |||
} | |||
void Image::Copy(uint8_t* pixels, ivec2 const& size, PixelFormat fmt) | |||
void Image::Copy(uint8_t* src_pixels, ivec2 const& size, PixelFormat fmt) | |||
{ | |||
ASSERT(fmt != PixelFormat::Unknown); | |||
SetSize(size); | |||
SetFormat(fmt); | |||
memcpy(m_data->m_pixels[(int)fmt]->data(), pixels, | |||
memcpy(m_data->m_pixels[(int)fmt]->data(), src_pixels, | |||
size.x * size.y * BytesPerPixel(fmt)); | |||
} | |||
void Image::Copy(Image const &other) | |||
void Image::Copy(Image const &src) | |||
{ | |||
ivec2 size = other.GetSize(); | |||
PixelFormat fmt = other.GetFormat(); | |||
ivec2 size = src.GetSize(); | |||
PixelFormat fmt = src.GetFormat(); | |||
SetSize(size); | |||
if (fmt != PixelFormat::Unknown) | |||
{ | |||
SetFormat(fmt); | |||
memcpy(m_data->m_pixels[(int)fmt]->data(), | |||
other.m_data->m_pixels[(int)fmt]->data(), | |||
src.m_data->m_pixels[(int)fmt]->data(), | |||
size.x * size.y * BytesPerPixel(fmt)); | |||
} | |||
} | |||
void Image::DummyFill() | |||
{ | |||
Load("DUMMY"); | |||
} | |||
bool Image::Load(char const *path) | |||
{ | |||
ImageCodec* last_codec = nullptr; | |||
for (auto codec : g_image_loader.m_codecs) | |||
auto resource = ResourceLoader::Load(path); | |||
if (resource == nullptr) | |||
return false; | |||
auto image_resource = dynamic_cast<ResourceImageData*>(resource); | |||
if (image_resource == nullptr) | |||
{ | |||
last_codec = codec; | |||
if (codec->Load(this, path)) | |||
{ | |||
msg::info("Image::Load: Codec %s succesfully loaded %s.\n", codec->GetName(), path); | |||
return true; | |||
} | |||
delete image_resource; | |||
return false; | |||
} | |||
//Log error, because we shouldn't be here | |||
msg::error("Image::Load: Last codec %s, Error loading image %s.\n", last_codec->GetName(), path); | |||
return false; | |||
Copy(*image_resource->m_image); | |||
delete image_resource; | |||
return true; | |||
} | |||
bool Image::Save(char const *path) | |||
{ | |||
ImageCodec* last_codec = nullptr; | |||
for (auto codec : g_image_loader.m_codecs) | |||
{ | |||
last_codec = codec; | |||
if (codec->Save(this, path)) | |||
{ | |||
msg::info("Image::Save: Codec %s succesfully saved %s.\n", codec->GetName(), path); | |||
return true; | |||
} | |||
} | |||
//Log error, because we shouldn't be here | |||
msg::error("Image::Save: Last codec %s, Error saving image %s.\n", last_codec->GetName(), path); | |||
return false; | |||
auto data = new ResourceImageData(new Image(*this)); | |||
auto result = ResourceLoader::Save(path, data); | |||
delete data; | |||
return result; | |||
} | |||
ivec2 Image::GetSize() const | |||
@@ -281,12 +208,5 @@ void Image::Unlock(void const *pixels) | |||
ASSERT(pixels == m_data->m_pixels[(int)m_data->m_format]->data()); | |||
} | |||
bool Image::RetrieveTiles(array<ivec2, ivec2>& tiles) const | |||
{ | |||
/* TODO: re-implement this */ | |||
//return m_data->m_codecdata->RetrieveTiles(tiles); | |||
return false; | |||
} | |||
} /* namespace lol */ | |||
@@ -0,0 +1,57 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2016—2017 Sam Hocevar <sam@hocevar.net> | |||
// Copyright © 2016—2017 Benjamin “Touky” Huet <huet.benjamin@gmail.com> | |||
// | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// | |||
#pragma once | |||
// | |||
// The ResourceCodecData class | |||
// ------------------------ | |||
// | |||
namespace lol | |||
{ | |||
class ResourceCodec | |||
{ | |||
public: | |||
virtual char const *GetName() { return "<ResourceCodec>"; } | |||
virtual ResourceCodecData* Load(char const *path) = 0; | |||
virtual bool Save(char const *path, ResourceCodecData* data) = 0; | |||
/* TODO: this should become more fine-grained */ | |||
int m_priority; | |||
}; | |||
#define REGISTER_IMAGE_CODEC(name) \ | |||
extern ResourceCodec *Register##name(); \ | |||
{ \ | |||
/* Insert image codecs in a sorted list */ \ | |||
ResourceCodec *codec = Register##name(); \ | |||
int i = 0, prio = codec->m_priority; \ | |||
for ( ; i < codeclist.count(); ++i) \ | |||
{ \ | |||
if (codeclist[i]->m_priority <= prio) \ | |||
break; \ | |||
} \ | |||
codeclist.insert(codec, i); \ | |||
} | |||
#define DECLARE_IMAGE_CODEC(name, priority) \ | |||
ResourceCodec *Register##name() \ | |||
{ \ | |||
ResourceCodec *ret = new name(); \ | |||
ret->m_priority = priority; \ | |||
return ret; \ | |||
} | |||
} /* namespace lol */ | |||
@@ -0,0 +1,121 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright © 2016—2017 Sam Hocevar <sam@hocevar.net> | |||
// Copyright © 2016—2017 Benjamin “Touky” Huet <huet.benjamin@gmail.com> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#include <lol/engine-internal.h> | |||
#include "resource-private.h" | |||
#include <algorithm> /* for std::swap */ | |||
namespace lol | |||
{ | |||
/* HACK: We cannot make this an ImageLoader member function, because the | |||
* REGISTER_IMAGE_CODEC macro forward-declares free functions from | |||
* the "lol" namespace. An apparent bug in Visual Studio's compiler | |||
* makes it think these functions are actually in the top-level | |||
* namespace when the forward declaration is in a class member function. | |||
* To avoid the problem, we make the forward declaration in a free | |||
* function. | |||
* The bug was reported to Microsoft and fixed by them, but the fix | |||
* is not yet available. | |||
* https://connect.microsoft.com/VisualStudio/feedback/details/730878/ */ | |||
static bool RegisterAllCodecs(array<ResourceCodec *> &codeclist) | |||
{ | |||
#if defined __ANDROID__ | |||
REGISTER_IMAGE_CODEC(AndroidImageCodec) | |||
#endif | |||
#if defined LOL_USE_GDIPLUS | |||
REGISTER_IMAGE_CODEC(GdiPlusImageCodec) | |||
#endif | |||
#if defined __APPLE__ && defined __MACH__ && defined __arm__ | |||
REGISTER_IMAGE_CODEC(IosImageCodec) | |||
#endif | |||
#if defined LOL_USE_SDL_IMAGE | |||
REGISTER_IMAGE_CODEC(SdlImageCodec) | |||
#endif | |||
#if defined LOL_USE_IMLIB2 | |||
REGISTER_IMAGE_CODEC(Imlib2ImageCodec) | |||
#endif | |||
REGISTER_IMAGE_CODEC(ZedImageCodec) | |||
REGISTER_IMAGE_CODEC(ZedPaletteImageCodec) | |||
REGISTER_IMAGE_CODEC(OricImageCodec) | |||
REGISTER_IMAGE_CODEC(DummyImageCodec) | |||
return true; | |||
} | |||
/* | |||
* Our static image loader | |||
*/ | |||
static class StaticResourceLoader | |||
{ | |||
friend class ResourceLoader; | |||
public: | |||
inline StaticResourceLoader() | |||
{ | |||
RegisterAllCodecs(m_codecs); | |||
} | |||
private: | |||
array<ResourceCodec *> m_codecs; | |||
} | |||
g_resource_loader; | |||
/* | |||
* The public resource loader | |||
*/ | |||
ResourceCodecData* ResourceLoader::Load(char const *path) | |||
{ | |||
ResourceCodec* last_codec = nullptr; | |||
for (auto codec : g_resource_loader.m_codecs) | |||
{ | |||
last_codec = codec; | |||
auto data = codec->Load(path); | |||
if (data != nullptr) | |||
{ | |||
msg::info("Image::Load: Codec %s succesfully loaded %s.\n", codec->GetName(), path); | |||
return data; | |||
} | |||
} | |||
//Log error, because we shouldn't be here | |||
msg::error("Image::Load: Last codec %s, Error loading resource %s.\n", last_codec->GetName(), path); | |||
return false; | |||
} | |||
bool ResourceLoader::Save(char const *path, ResourceCodecData* data) | |||
{ | |||
ResourceCodec* last_codec = nullptr; | |||
for (auto codec : g_resource_loader.m_codecs) | |||
{ | |||
last_codec = codec; | |||
if (codec->Save(path, data)) | |||
{ | |||
msg::info("Image::Save: Codec %s succesfully saved %s.\n", codec->GetName(), path); | |||
return true; | |||
} | |||
} | |||
//Log error, because we shouldn't be here | |||
msg::error("Image::Save: Last codec %s, Error saving resource %s.\n", last_codec->GetName(), path); | |||
return false; | |||
} | |||
} /* namespace lol */ | |||
@@ -148,6 +148,7 @@ | |||
<ClCompile Include="image\noise.cpp" /> | |||
<ClCompile Include="image\pixel.cpp" /> | |||
<ClCompile Include="image\resample.cpp" /> | |||
<ClCompile Include="image\resource.cpp" /> | |||
<ClCompile Include="input\controller.cpp" /> | |||
<ClCompile Include="input\input.cpp" /> | |||
<ClCompile Include="light.cpp" /> | |||
@@ -238,6 +239,7 @@ | |||
<ClInclude Include="forge.h" /> | |||
<ClInclude Include="gradient.h" /> | |||
<ClInclude Include="image\image-private.h" /> | |||
<ClInclude Include="image\resource-private.h" /> | |||
<ClInclude Include="input\controller.h" /> | |||
<ClInclude Include="input\input.h" /> | |||
<ClInclude Include="input\input_internal.h" /> | |||
@@ -285,6 +287,7 @@ | |||
<ClInclude Include="lol\image\image.h" /> | |||
<ClInclude Include="lol\image\movie.h" /> | |||
<ClInclude Include="lol\image\pixel.h" /> | |||
<ClInclude Include="lol\image\resource.h" /> | |||
<ClInclude Include="lol\math\all.h" /> | |||
<ClInclude Include="lol\math\arraynd.h" /> | |||
<ClInclude Include="lol\math\bigint.h" /> | |||
@@ -397,4 +400,4 @@ | |||
<ImportGroup Label="ExtensionTargets"> | |||
<Import Project="$(LolDir)\build\msbuild\lolfx.targets" /> | |||
</ImportGroup> | |||
</Project> | |||
</Project> |
@@ -15,5 +15,6 @@ | |||
#include <lol/image/pixel.h> | |||
#include <lol/image/color.h> | |||
#include <lol/image/image.h> | |||
#include <lol/image/resource.h> | |||
#include <lol/image/movie.h> | |||
@@ -106,9 +106,6 @@ public: | |||
template<typename T> | |||
void Unlock2D(array2d<T> const &); | |||
/* XXX: this does not belong here */ | |||
bool RetrieveTiles(array<ivec2, ivec2>& tiles) const; | |||
/* Image processing kernels */ | |||
static array2d<float> BayerKernel(ivec2 size); | |||
static array2d<float> HalftoneKernel(ivec2 size); | |||
@@ -0,0 +1,74 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright © 2016—2017 Sam Hocevar <sam@hocevar.net> | |||
// Copyright © 2016—2017 Benjamin “Touky” Huet <huet.benjamin@gmail.com> | |||
// | |||
// Lol Engine is free software. It comes without any warranty, to | |||
// the extent permitted by applicable law. You can redistribute it | |||
// and/or modify it under the terms of the Do What the Fuck You Want | |||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||
// See http://www.wtfpl.net/ for more details. | |||
// | |||
#pragma once | |||
// | |||
// The Resource class | |||
// --------------- | |||
// | |||
#include <lol/math/arraynd.h> | |||
#include <lol/math/vector.h> | |||
#include <lol/math/geometry.h> | |||
#include <lol/image/pixel.h> | |||
namespace lol | |||
{ | |||
//ResourceCodecData ----------------------------------------------------------- | |||
class ResourceCodecData | |||
{ | |||
public: | |||
ResourceCodecData() { } | |||
virtual ~ResourceCodecData() { } | |||
}; | |||
//ResourceImageData ----------------------------------------------------------- | |||
class ResourceImageData : public ResourceCodecData | |||
{ | |||
public: | |||
ResourceImageData(Image* image) | |||
{ | |||
m_image = image; | |||
} | |||
virtual ~ResourceImageData() | |||
{ | |||
if (m_image) | |||
delete m_image; | |||
} | |||
Image* m_image = nullptr; | |||
}; | |||
//ResourceImageData ----------------------------------------------------------- | |||
class ResourceTilesetData : public ResourceImageData | |||
{ | |||
public: | |||
ResourceTilesetData(Image* image) | |||
: ResourceImageData(image) | |||
{ } | |||
array<ivec2, ivec2> m_tiles; | |||
}; | |||
//ResourceLoader -------------------------------------------------------------- | |||
class ResourceLoader | |||
{ | |||
public: | |||
static ResourceCodecData* Load(char const *path); | |||
static bool Save(char const *path, ResourceCodecData* data); | |||
}; | |||
} /* namespace lol */ | |||
@@ -278,10 +278,10 @@ void SdlInputData::Tick(float seconds) | |||
# endif | |||
{ | |||
//Lock management | |||
# if defined SDLOL_CapsLock && defined SDLOL_ScrollLock && defined SDLOL_NumLockClear | |||
case SDLOL_CapsLock: | |||
case SDLOL_ScrollLock: | |||
case SDLOL_NumLockClear: | |||
# if defined SDLOL_CapsLock && defined SDLOL_ScrollLock && defined SDLOL_NumLockClear | |||
//Update status on key down only | |||
if (event.type == SDL_KEYDOWN) | |||
{ | |||
@@ -104,6 +104,13 @@ void init(int argc, char *argv[], | |||
rootdir += "../src/"; /* FIXME: use SEPARATOR? */ | |||
add_data_dir(rootdir); | |||
/* This data dir is for submodule support stuff */ | |||
rootdir = solutiondir; | |||
if (rootdir.count() && rootdir.last() != SEPARATOR) | |||
rootdir += SEPARATOR; | |||
rootdir += "./lol/src/"; /* FIXME: use SEPARATOR? */ | |||
add_data_dir(rootdir); | |||
/* This data dir is for project-specific stuff */ | |||
rootdir = projectdir; | |||
if (rootdir.count() && rootdir.last() != SEPARATOR) | |||
@@ -57,7 +57,19 @@ TextureImage::~TextureImage() | |||
void TextureImage::Init(char const *path) | |||
{ | |||
Init(path, new Image(path)); | |||
Init(path, ResourceLoader::Load(path)); | |||
} | |||
void TextureImage::Init(char const *path, ResourceCodecData* loaded_data) | |||
{ | |||
//Load image if available | |||
auto image_data = dynamic_cast<ResourceImageData*>(loaded_data); | |||
if (image_data != nullptr) | |||
{ | |||
Init(path, new Image(*image_data->m_image)); | |||
} | |||
delete image_data; | |||
} | |||
void TextureImage::Init(char const *path, Image* image) | |||
@@ -18,6 +18,7 @@ | |||
// zero, the texture is freed. | |||
// | |||
#include <lol/image/resource.h> | |||
#include <lol/image/image.h> | |||
#include <lol/gpu/texture.h> | |||
@@ -43,6 +44,7 @@ public: | |||
protected: | |||
void Init(char const *path); | |||
virtual void Init(char const *path, ResourceCodecData* loaded_data); | |||
virtual void Init(char const *path, Image* image); | |||
protected: | |||
@@ -46,25 +46,25 @@ protected: | |||
*/ | |||
TileSet::TileSet(char const *path) | |||
: TextureImage(path), | |||
: m_tileset_data(new TileSetData()), | |||
m_palette(nullptr), | |||
TextureImage(path) | |||
{ | |||
} | |||
TileSet::TileSet(char const *path, Image* image) | |||
: TextureImage(path, image), | |||
m_tileset_data(new TileSetData()), | |||
m_palette(nullptr) | |||
{ | |||
array<ivec2, ivec2> tiles; | |||
if (m_data->m_image->RetrieveTiles(tiles)) | |||
for (int i = 0; i < tiles.count(); i++) | |||
define_tile(ibox2(tiles[0].m1, tiles[0].m1 + tiles[0].m2)); | |||
} | |||
TileSet::TileSet(char const *path, Image* image) | |||
: TextureImage(path, image), | |||
TileSet::TileSet(char const *path, Image* image, array<ivec2, ivec2>& tiles) | |||
: TextureImage(path, image), | |||
m_tileset_data(new TileSetData()), | |||
m_palette(nullptr) | |||
{ | |||
array<ivec2, ivec2> tiles; | |||
if (m_data->m_image->RetrieveTiles(tiles)) | |||
for (int i = 0; i < tiles.count(); i++) | |||
define_tile(ibox2(tiles[0].m1, tiles[0].m1 + tiles[0].m2)); | |||
define_tile(tiles); | |||
} | |||
TileSet::TileSet(char const *path, ivec2 size, ivec2 count) | |||
@@ -118,6 +118,20 @@ TileSet::~TileSet() | |||
delete m_tileset_data; | |||
} | |||
void TileSet::Init(char const *path, ResourceCodecData* loaded_data) | |||
{ | |||
//Load tileset if available | |||
auto tileset_data = dynamic_cast<ResourceTilesetData*>(loaded_data); | |||
if (tileset_data != nullptr) | |||
{ | |||
define_tile(tileset_data->m_tiles); | |||
} | |||
m_data->m_name = String("<tileset> ") + path; | |||
super::Init(path, loaded_data); | |||
} | |||
void TileSet::Init(char const *path, Image* image) | |||
{ | |||
super::Init(path, image); | |||
@@ -132,6 +146,11 @@ char const *TileSet::GetName() | |||
} | |||
//New methods ----------------------------------------------------------------- | |||
void TileSet::clear_all() | |||
{ | |||
m_tileset_data->m_tiles.empty(); | |||
} | |||
int TileSet::define_tile(ibox2 rect) | |||
{ | |||
m_tileset_data->m_tiles.push(rect, | |||
@@ -152,6 +171,18 @@ void TileSet::define_tile(ivec2 count) | |||
} | |||
} | |||
void TileSet::define_tile(array<ibox2>& tiles) | |||
{ | |||
for (int i = 0; i < tiles.count(); i++) | |||
define_tile(tiles[i]); | |||
} | |||
void TileSet::define_tile(array<ivec2, ivec2>& tiles) | |||
{ | |||
for (int i = 0; i < tiles.count(); i++) | |||
define_tile(ibox2(tiles[i].m1, tiles[i].m1 + tiles[i].m2)); | |||
} | |||
int TileSet::GetTileCount() const | |||
{ | |||
return m_tileset_data->m_tiles.count(); | |||
@@ -43,6 +43,7 @@ class TileSet : public TextureImage | |||
public: | |||
TileSet(char const *path); | |||
TileSet(char const *path, Image* image); | |||
TileSet(char const *path, Image* image, array<ivec2, ivec2>& tiles); | |||
/* Old style: path to PNG file */ | |||
TileSet(char const *path, ivec2 size, ivec2 count); | |||
@@ -51,6 +52,7 @@ public: | |||
virtual ~TileSet(); | |||
protected: | |||
virtual void Init(char const *path, ResourceCodecData* loaded_data); | |||
virtual void Init(char const *path, Image* image); | |||
public: | |||
@@ -58,8 +60,11 @@ public: | |||
virtual char const *GetName(); | |||
/* New methods */ | |||
void clear_all(); | |||
int define_tile(ibox2 rect); | |||
void define_tile(ivec2 count); | |||
void define_tile(array<ibox2>& tiles); | |||
void define_tile(array<ivec2, ivec2>& tiles); | |||
int GetTileCount() const; | |||
ivec2 GetTileSize(int tileid) const; | |||
ibox2 GetTilePixel(int tileid) const; | |||