Kaynağa Gözat

ResourceLoader + tileset tweaks

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
touky 10 yıl önce
ebeveyn
işleme
24d9405ff3
23 değiştirilmiş dosya ile 476 ekleme ve 261 silme
  1. +2
    -1
      src/Makefile.am
  2. +8
    -8
      src/image/codec/android-image.cpp
  3. +12
    -11
      src/image/codec/dummy-image.cpp
  4. +17
    -11
      src/image/codec/gdiplus-image.cpp
  5. +9
    -9
      src/image/codec/ios-image.cpp
  6. +17
    -11
      src/image/codec/oric-image.cpp
  7. +20
    -14
      src/image/codec/sdl-image.cpp
  8. +25
    -29
      src/image/codec/zed-image.cpp
  9. +13
    -11
      src/image/codec/zed-palette-image.cpp
  10. +0
    -33
      src/image/image-private.h
  11. +26
    -106
      src/image/image.cpp
  12. +57
    -0
      src/image/resource-private.h
  13. +121
    -0
      src/image/resource.cpp
  14. +4
    -1
      src/lol-core.vcxproj
  15. +1
    -0
      src/lol/image/all.h
  16. +0
    -3
      src/lol/image/image.h
  17. +74
    -0
      src/lol/image/resource.h
  18. +1
    -1
      src/platform/sdl/sdlinput.cpp
  19. +7
    -0
      src/sys/init.cpp
  20. +13
    -1
      src/textureimage.cpp
  21. +2
    -0
      src/textureimage.h
  22. +42
    -11
      src/tileset.cpp
  23. +5
    -0
      src/tileset.h

+ 2
- 1
src/Makefile.am Dosyayı Görüntüle

@@ -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 \


+ 8
- 8
src/image/codec/android-image.cpp Dosyayı Görüntüle

@@ -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 */
}


+ 12
- 11
src/image/codec/dummy-image.cpp Dosyayı Görüntüle

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


+ 17
- 11
src/image/codec/gdiplus-image.cpp Dosyayı Görüntüle

@@ -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,


+ 9
- 9
src/image/codec/ios-image.cpp Dosyayı Görüntüle

@@ -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;


+ 17
- 11
src/image/codec/oric-image.cpp Dosyayı Görüntüle

@@ -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++)


+ 20
- 14
src/image/codec/sdl-image.cpp Dosyayı Görüntüle

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


+ 25
- 29
src/image/codec/zed-image.cpp Dosyayı Görüntüle

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


+ 13
- 11
src/image/codec/zed-palette-image.cpp Dosyayı Görüntüle

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


+ 0
- 33
src/image/image-private.h Dosyayı Görüntüle

@@ -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 */


+ 26
- 106
src/image/image.cpp Dosyayı Görüntüle

@@ -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 */


+ 57
- 0
src/image/resource-private.h Dosyayı Görüntüle

@@ -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 */


+ 121
- 0
src/image/resource.cpp Dosyayı Görüntüle

@@ -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 */


+ 4
- 1
src/lol-core.vcxproj Dosyayı Görüntüle

@@ -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>

+ 1
- 0
src/lol/image/all.h Dosyayı Görüntüle

@@ -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>


+ 0
- 3
src/lol/image/image.h Dosyayı Görüntüle

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


+ 74
- 0
src/lol/image/resource.h Dosyayı Görüntüle

@@ -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 */


+ 1
- 1
src/platform/sdl/sdlinput.cpp Dosyayı Görüntüle

@@ -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)
{


+ 7
- 0
src/sys/init.cpp Dosyayı Görüntüle

@@ -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)


+ 13
- 1
src/textureimage.cpp Dosyayı Görüntüle

@@ -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)


+ 2
- 0
src/textureimage.h Dosyayı Görüntüle

@@ -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:


+ 42
- 11
src/tileset.cpp Dosyayı Görüntüle

@@ -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();


+ 5
- 0
src/tileset.h Dosyayı Görüntüle

@@ -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;


Yükleniyor…
İptal
Kaydet