@@ -24,7 +24,12 @@ liblol_a_SOURCES = \ | |||
\ | |||
shader/shader.cpp shader/shader.h \ | |||
\ | |||
image/image.cpp image/image.h \ | |||
image/image.cpp image/image.h image/image-private.h \ | |||
image/codec/android-image.cpp \ | |||
image/codec/ios-image.cpp \ | |||
image/codec/sdl-image.cpp \ | |||
image/codec/ps3-image.cpp \ | |||
image/codec/dummy-image.cpp \ | |||
\ | |||
loldebug.h \ | |||
debug/fps.cpp debug/fps.h debug/sphere.cpp debug/sphere.h \ | |||
@@ -0,0 +1,136 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> | |||
// 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://sam.zoy.org/projects/COPYING.WTFPL for more details. | |||
// | |||
#if defined HAVE_CONFIG_H | |||
# include "config.h" | |||
#endif | |||
#if defined __ANDROID__ | |||
#include <cmath> | |||
#include <jni.h> | |||
#include <android/log.h> | |||
#include "core.h" | |||
#include "image-private.h" | |||
using namespace std; | |||
namespace lol | |||
{ | |||
extern JavaVM *g_vm; | |||
extern jobject g_activity; | |||
/* | |||
* Image implementation class | |||
*/ | |||
DECLARE_IMAGE_LOADER(AndroidImageData, 100) | |||
{ | |||
public: | |||
virtual bool Open(char const *); | |||
virtual bool Close(); | |||
virtual void *GetData() const; | |||
private: | |||
jobject bmp; | |||
jintArray array; | |||
jint *pixels; | |||
}; | |||
bool AndroidImageData::Open(char const *path) | |||
{ | |||
JNIEnv *env; | |||
jint res = g_vm->GetEnv((void **)&env, JNI_VERSION_1_2); | |||
if (res < 0) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not get JVM environment\n"); | |||
#endif | |||
exit(1); | |||
} | |||
jclass cls = env->GetObjectClass(g_activity); | |||
jmethodID mid; | |||
mid = env->GetMethodID(cls, "openImage", | |||
"(Ljava/lang/String;)Landroid/graphics/Bitmap;"); | |||
jstring name = env->NewStringUTF(path); | |||
bmp = env->CallObjectMethod(g_activity, mid, name); | |||
env->DeleteLocalRef(name); | |||
if (!bmp) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not load %s\n", path); | |||
#endif | |||
exit(1); | |||
} | |||
env->NewGlobalRef(bmp); | |||
/* Get image dimensions */ | |||
mid = env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I"); | |||
size.x = env->CallIntMethod(g_activity, mid, bmp); | |||
mid = env->GetMethodID(cls, "getHeight", "(Landroid/graphics/Bitmap;)I"); | |||
size.y = env->CallIntMethod(g_activity, mid, bmp); | |||
/* Get pixels */ | |||
array = env->NewIntArray(size.x * size.y); | |||
env->NewGlobalRef(array); | |||
mid = env->GetMethodID(cls, "getPixels", "(Landroid/graphics/Bitmap;[I)V"); | |||
env->CallVoidMethod(g_activity, mid, bmp, array); | |||
pixels = env->GetIntArrayElements(array, 0); | |||
for (int n = 0; n < size.x * size.y; n++) | |||
{ | |||
uint32_t u = pixels[n]; | |||
u = (u & 0xff00ff00) | ((u & 0xff0000) >> 16) | ((u & 0xff) << 16); | |||
pixels[n] = u; | |||
} | |||
format = FORMAT_RGBA; | |||
return true; | |||
} | |||
bool AndroidImageData::Close() | |||
{ | |||
JNIEnv *env; | |||
jint res = g_vm->GetEnv((void **)&env, JNI_VERSION_1_2); | |||
if (res < 0) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not get JVM environment\n"); | |||
#endif | |||
exit(1); | |||
} | |||
jclass cls = env->GetObjectClass(g_activity); | |||
jmethodID mid; | |||
env->ReleaseIntArrayElements(array, pixels, 0); | |||
env->DeleteGlobalRef(array); | |||
/* Free image */ | |||
mid = env->GetMethodID(cls, "closeImage", "(Landroid/graphics/Bitmap;)V"); | |||
env->CallVoidMethod(g_activity, mid, bmp); | |||
env->DeleteGlobalRef(bmp); | |||
return true; | |||
} | |||
void * AndroidImageData::GetData() const | |||
{ | |||
return pixels; | |||
} | |||
} /* namespace lol */ | |||
#endif /* __ANDROID__ */ | |||
@@ -0,0 +1,76 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> | |||
// 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://sam.zoy.org/projects/COPYING.WTFPL for more details. | |||
// | |||
#if defined HAVE_CONFIG_H | |||
# include "config.h" | |||
#endif | |||
#include <cmath> | |||
#include "core.h" | |||
#include "image/image-private.h" | |||
using namespace std; | |||
namespace lol | |||
{ | |||
/* | |||
* Image implementation class | |||
*/ | |||
DECLARE_IMAGE_LOADER(DummyImageData, 0) | |||
{ | |||
public: | |||
virtual bool Open(char const *); | |||
virtual bool Close(); | |||
virtual void *GetData() const; | |||
private: | |||
uint8_t *pixels; | |||
}; | |||
/* | |||
* Public Image class | |||
*/ | |||
bool DummyImageData::Open(char const *path) | |||
{ | |||
size = 256; | |||
format = Image::FORMAT_RGBA; | |||
pixels = (uint8_t *)malloc(256 * 256 * 4 * sizeof(*pixels)); | |||
uint8_t *parser = pixels; | |||
for (int j = 0; j < 256; j++) | |||
for (int i = 0; i < 256; i++) | |||
{ | |||
*parser++ = ((i ^ j) & 1) * 0xff; | |||
*parser++ = (uint8_t)i; | |||
*parser++ = (uint8_t)j; | |||
*parser++ = (((i >> 4) ^ (j >> 4)) & 1) * 0xff; | |||
} | |||
return true; | |||
} | |||
bool DummyImageData::Close() | |||
{ | |||
free(pixels); | |||
return true; | |||
} | |||
void * DummyImageData::GetData() const | |||
{ | |||
return pixels; | |||
} | |||
} /* namespace lol */ | |||
@@ -0,0 +1,101 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> | |||
// 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://sam.zoy.org/projects/COPYING.WTFPL for more details. | |||
// | |||
#if defined HAVE_CONFIG_H | |||
# include "config.h" | |||
#endif | |||
#if defined __APPLE__ && defined __MACH__ | |||
#include <cmath> | |||
#import <UIKit/UIKit.h> | |||
#include "core.h" | |||
using namespace std; | |||
namespace lol | |||
{ | |||
/* | |||
* Image implementation class | |||
*/ | |||
DECLARE_IMAGE_LOADER(IosImageData, 100) | |||
{ | |||
public: | |||
virtual bool Open(char const *); | |||
virtual bool Close(); | |||
virtual void *GetData() const; | |||
private: | |||
uint8_t *pixels; | |||
}; | |||
/* | |||
* Public Image class | |||
*/ | |||
bool IosImageData::Open(char const *path) | |||
{ | |||
NSString *fullpath = [NSString stringWithUTF8String:path]; | |||
NSArray *chunks = [fullpath componentsSeparatedByString: @"/"]; | |||
NSString *filename = [chunks objectAtIndex: [chunks count] - 1]; | |||
chunks = [filename componentsSeparatedByString: @"."]; | |||
NSString *prefix = [chunks objectAtIndex: 0]; | |||
NSString *mypath = [[NSBundle mainBundle] pathForResource:prefix ofType:@"png"]; | |||
NSData *pngdata = [[NSData alloc] initWithContentsOfFile:mypath]; | |||
UIImage *image = [[UIImage alloc] initWithData:pngdata]; | |||
if (!image) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not load %s\n", path); | |||
#endif | |||
exit(1); | |||
} | |||
int w = CGImageGetWidth(image.CGImage); | |||
int h = CGImageGetHeight(image.CGImage); | |||
size = ivec2(w, h); | |||
format = FORMAT_RGBA; | |||
CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB(); | |||
pixels = (uint8_t *)malloc(w * h * 4); | |||
CGContextRef ctx = | |||
CGBitmapContextCreate(pixels, w, h, 8, 4 * w, cspace, | |||
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); | |||
CGColorSpaceRelease(cspace); | |||
CGContextClearRect(ctx, CGRectMake(0, 0, w, h)); | |||
CGContextTranslateCTM(ctx, 0, h - h); | |||
CGContextDrawImage(ctx, CGRectMake(0, 0, w, h), image.CGImage); | |||
CGContextRelease(ctx); | |||
[image release]; | |||
[pngdata release]; | |||
return true; | |||
} | |||
bool IosImageData::Close() | |||
{ | |||
free(pixels); | |||
return true; | |||
} | |||
void * IosImageData::GetData() const | |||
{ | |||
return pixels; | |||
} | |||
} /* namespace lol */ | |||
#endif /* defined __APPLE__ && defined __MACH__ */ | |||
@@ -0,0 +1,203 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> | |||
// 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://sam.zoy.org/projects/COPYING.WTFPL for more details. | |||
// | |||
#if defined HAVE_CONFIG_H | |||
# include "config.h" | |||
#endif | |||
#if defined __CELLOS_LV2__ | |||
#include <cmath> | |||
#include <cell/sysmodule.h> | |||
#include <cell/codec/pngdec.h> | |||
#include "core.h" | |||
using namespace std; | |||
namespace lol | |||
{ | |||
/* | |||
* Image implementation class | |||
*/ | |||
DECLARE_IMAGE_LOADER(Ps3ImageData, 100) | |||
{ | |||
public: | |||
virtual bool Open(char const *); | |||
virtual bool Close(); | |||
virtual void *GetData() const; | |||
private: | |||
static void* Malloc(uint32_t size, void* data) { return malloc(size); }; | |||
static int32_t Free(void* ptr, void* data) { free(ptr); return 0; }; | |||
uint8_t *pixels; | |||
}; | |||
/* | |||
* Public Image class | |||
*/ | |||
bool Ps3ImageData::Open(char const *path) | |||
{ | |||
int32_t err; | |||
/* Initialise decoding library */ | |||
CellPngDecMainHandle hmain; | |||
err = cellSysmoduleLoadModule(CELL_SYSMODULE_FS); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not open Fs sysmodule\n"); | |||
#endif | |||
exit(1); | |||
} | |||
err = cellSysmoduleLoadModule(CELL_SYSMODULE_PNGDEC); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not open PngDec sysmodule\n"); | |||
#endif | |||
exit(1); | |||
} | |||
CellPngDecThreadInParam in_param; | |||
in_param.spuThreadEnable = CELL_PNGDEC_SPU_THREAD_ENABLE; | |||
in_param.ppuThreadPriority = 1000; | |||
in_param.spuThreadPriority = 200; | |||
in_param.cbCtrlMallocFunc = ImageData::Malloc; | |||
in_param.cbCtrlMallocArg = NULL; | |||
in_param.cbCtrlFreeFunc = ImageData::Free; | |||
in_param.cbCtrlFreeArg = NULL; | |||
CellPngDecThreadOutParam out_param; | |||
err = cellPngDecCreate(&hmain, &in_param, &out_param); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not create PngDec library\n"); | |||
#endif | |||
exit(1); | |||
} | |||
/* Create decoder */ | |||
CellPngDecSubHandle hsub; | |||
char file[1024]; | |||
sprintf(file, "/app_home/c:/Users/s.hocevar/lolengine/%s", path); | |||
CellPngDecSrc dec_src; | |||
dec_src.srcSelect = CELL_PNGDEC_FILE; | |||
dec_src.fileName = file; | |||
dec_src.fileOffset = 0; | |||
dec_src.fileSize = 0; | |||
dec_src.streamPtr = NULL; | |||
dec_src.streamSize = 0; | |||
dec_src.spuThreadEnable = CELL_PNGDEC_SPU_THREAD_ENABLE; | |||
CellPngDecOpnInfo open_info; | |||
err = cellPngDecOpen(hmain, &hsub, &dec_src, &open_info); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not open %s for decoding\n", file); | |||
#endif | |||
exit(1); | |||
} | |||
CellPngDecInfo info; | |||
err = cellPngDecReadHeader(hmain, hsub, &info); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not read image header\n"); | |||
#endif | |||
exit(1); | |||
} | |||
CellPngDecInParam in_dec_param; | |||
in_dec_param.commandPtr = NULL; | |||
in_dec_param.outputMode = CELL_PNGDEC_TOP_TO_BOTTOM; | |||
in_dec_param.outputColorSpace = CELL_PNGDEC_RGBA; | |||
in_dec_param.outputBitDepth = 8; | |||
in_dec_param.outputPackFlag = CELL_PNGDEC_1BYTE_PER_1PIXEL; | |||
in_dec_param.outputAlphaSelect = CELL_PNGDEC_STREAM_ALPHA; | |||
in_dec_param.outputColorAlpha = 0xff; | |||
CellPngDecOutParam out_dec_param; | |||
err = cellPngDecSetParameter(hmain, hsub, &in_dec_param, &out_dec_param); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not configure PngDec decoder\n"); | |||
#endif | |||
exit(1); | |||
} | |||
/* Decode image */ | |||
size = ivec2(info.imageWidth, info.imageHeight); | |||
format = FORMAT_RGBA; | |||
pixels = (uint8_t *)malloc(info.imageWidth * 4 * info.imageHeight); | |||
CellPngDecDataCtrlParam data_ctrl_param; | |||
data_ctrl_param.outputBytesPerLine = info.imageWidth * 4; | |||
CellPngDecDataOutInfo data_out_info; | |||
err = cellPngDecDecodeData(hmain, hsub, pixels, | |||
&data_ctrl_param, &data_out_info); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not run PngDec decoder\n"); | |||
#endif | |||
exit(1); | |||
} | |||
/* Close decoder */ | |||
err = cellPngDecClose(hmain, hsub); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not close PngDec decoder\n"); | |||
#endif | |||
exit(1); | |||
} | |||
/* Deinitialise library */ | |||
err = cellPngDecDestroy(hmain); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not destroy PngDec decoder\n"); | |||
#endif | |||
exit(1); | |||
} | |||
err = cellSysmoduleUnloadModule(CELL_SYSMODULE_PNGDEC); | |||
err = cellSysmoduleUnloadModule(CELL_SYSMODULE_FS); | |||
return true; | |||
} | |||
bool Ps3ImageData::Close() | |||
{ | |||
free(pixels); | |||
return true; | |||
} | |||
void * Ps3ImageData::GetData() const | |||
{ | |||
return pixels; | |||
} | |||
} /* namespace lol */ | |||
#endif /* defined __CELLOS_LV2__ */ | |||
@@ -0,0 +1,86 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> | |||
// 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://sam.zoy.org/projects/COPYING.WTFPL for more details. | |||
// | |||
#if defined HAVE_CONFIG_H | |||
# include "config.h" | |||
#endif | |||
#if defined USE_SDL_IMAGE | |||
#include <cmath> | |||
#include <SDL.h> | |||
#include <SDL_image.h> | |||
#include "core.h" | |||
#include "image/image-private.h" | |||
using namespace std; | |||
namespace lol | |||
{ | |||
/* | |||
* Image implementation class | |||
*/ | |||
DECLARE_IMAGE_LOADER(SdlImageData, 50) | |||
{ | |||
public: | |||
virtual bool Open(char const *); | |||
virtual bool Close(); | |||
virtual void *GetData() const; | |||
private: | |||
SDL_Surface *img; | |||
}; | |||
/* | |||
* Public Image class | |||
*/ | |||
bool SdlImageData::Open(char const *path) | |||
{ | |||
for (char const *name = path; *name; name++) | |||
if ((img = IMG_Load(name))) | |||
break; | |||
if (!img) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not load %s\n", path); | |||
#endif | |||
SDL_Quit(); | |||
exit(1); | |||
} | |||
size = ivec2(img->w, img->h); | |||
format = img->format->Amask ? Image::FORMAT_RGBA : Image::FORMAT_RGB; | |||
return true; | |||
} | |||
bool SdlImageData::Close() | |||
{ | |||
SDL_FreeSurface(img); | |||
return true; | |||
} | |||
void * SdlImageData::GetData() const | |||
{ | |||
return img->pixels; | |||
} | |||
} /* namespace lol */ | |||
#endif /* defined USE_SDL_IMAGE */ | |||
@@ -0,0 +1,127 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> | |||
// 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://sam.zoy.org/projects/COPYING.WTFPL for more details. | |||
// | |||
// | |||
// The ImageData class | |||
// ------------------- | |||
// | |||
#if !defined __LOL_IMAGE_PRIVATE_H__ | |||
#define __LOL_IMAGE_PRIVATE_H__ | |||
#include "image.h" | |||
namespace lol | |||
{ | |||
class ImageLoader | |||
{ | |||
friend class Image; | |||
friend class ImageData; | |||
public: | |||
ImageData *(*fun)(char const *path); | |||
ImageLoader *next; | |||
int priority; | |||
static bool RegisterAllLoaders(); | |||
static void RegisterLoader(ImageLoader *loader) | |||
{ | |||
Helper(loader); | |||
} | |||
private: | |||
static ImageData *Load(char const *path) | |||
{ | |||
ImageLoader *parser = Helper(NULL); | |||
ImageData *ret = NULL; | |||
while (parser && !ret) | |||
{ | |||
ret = parser->fun(path); | |||
parser = parser->next; | |||
} | |||
return ret; | |||
} | |||
static ImageLoader *Helper(ImageLoader *set) | |||
{ | |||
static ImageLoader *loaders = NULL; | |||
if (!set) | |||
return loaders; | |||
ImageLoader **parser = &loaders; | |||
while (*parser && (*parser)->priority > set->priority) | |||
parser = &(*parser)->next; | |||
set->next = *parser; | |||
*parser = set; | |||
return NULL; | |||
} | |||
}; | |||
class ImageData | |||
{ | |||
friend class Image; | |||
public: | |||
virtual bool Open(char const *) = 0; | |||
virtual bool Close() = 0; | |||
virtual void *GetData() const = 0; | |||
protected: | |||
ivec2 size; | |||
Image::format_t format; | |||
private: | |||
}; | |||
#define REGISTER_IMAGE_LOADER(name) \ | |||
extern void (Register##name)(); \ | |||
Register##name(); | |||
#define DECLARE_IMAGE_LOADER(name, prio) \ | |||
template<typename T> class name##ImageLoader : public ImageLoader \ | |||
{ \ | |||
public: \ | |||
name##ImageLoader() \ | |||
{ \ | |||
static ImageLoader loader; \ | |||
loader.fun = Load; \ | |||
loader.priority = prio; \ | |||
RegisterLoader(&loader); \ | |||
} \ | |||
static ImageData *Load(char const *path) \ | |||
{ \ | |||
T *ret = new T(); \ | |||
if (!ret->Open(path)) \ | |||
{ \ | |||
delete ret; \ | |||
return NULL; \ | |||
} \ | |||
return ret; \ | |||
} \ | |||
}; \ | |||
class name; \ | |||
name##ImageLoader<name> name##ImageLoaderInstance; \ | |||
void Register##name() \ | |||
{ \ | |||
(void)&name##ImageLoaderInstance; \ | |||
} \ | |||
class name : public ImageData | |||
} /* namespace lol */ | |||
#endif // __LOL_IMAGE_PRIVATE_H__ | |||
@@ -14,310 +14,42 @@ | |||
#include <cmath> | |||
#if defined __APPLE__ && defined __MACH__ | |||
# import <UIKit/UIKit.h> | |||
#elif defined USE_SDL_IMAGE | |||
# include <SDL.h> | |||
# include <SDL_image.h> | |||
#elif defined __ANDROID__ | |||
# include <jni.h> | |||
# include <android/log.h> | |||
#elif defined __CELLOS_LV2__ | |||
# include <cell/sysmodule.h> | |||
# include <cell/codec/pngdec.h> | |||
#endif | |||
#include "core.h" | |||
#include "image-private.h" | |||
using namespace std; | |||
namespace lol | |||
{ | |||
bool ImageLoader::RegisterAllLoaders() | |||
{ | |||
#if defined __ANDROID__ | |||
extern JavaVM *g_vm; | |||
extern jobject g_activity; | |||
REGISTER_IMAGE_LOADER(AndroidImageData) | |||
#endif | |||
/* | |||
* Image implementation class | |||
*/ | |||
class ImageData | |||
{ | |||
friend class Image; | |||
private: | |||
ivec2 size; | |||
Image::format_t format; | |||
REGISTER_IMAGE_LOADER(DummyImageData) | |||
#if defined __APPLE__ && defined __MACH__ | |||
uint8_t *pixels; | |||
#elif defined USE_SDL_IMAGE | |||
SDL_Surface *img; | |||
#elif defined __ANDROID__ | |||
jobject bmp; | |||
jintArray array; | |||
jint *pixels; | |||
#elif defined __CELLOS_LV2__ | |||
static void* Malloc(uint32_t size, void* data) { return malloc(size); }; | |||
static int32_t Free(void* ptr, void* data) { free(ptr); return 0; }; | |||
uint8_t *pixels; | |||
#else | |||
uint8_t *pixels; | |||
REGISTER_IMAGE_LOADER(IosImageData) | |||
#endif | |||
}; | |||
#if defined __CELLOS_LV2__ | |||
REGISTER_IMAGE_LOADER(Ps3ImageData) | |||
#endif | |||
#if defined USE_SDL_IMAGE | |||
REGISTER_IMAGE_LOADER(SdlImageData) | |||
#endif | |||
return true; | |||
} | |||
/* | |||
* Public Image class | |||
*/ | |||
Image::Image(char const *path) | |||
: data(new ImageData()) | |||
{ | |||
#if defined __APPLE__ && defined __MACH__ | |||
NSString *fullpath = [NSString stringWithUTF8String:path]; | |||
NSArray *chunks = [fullpath componentsSeparatedByString: @"/"]; | |||
NSString *filename = [chunks objectAtIndex: [chunks count] - 1]; | |||
chunks = [filename componentsSeparatedByString: @"."]; | |||
NSString *prefix = [chunks objectAtIndex: 0]; | |||
NSString *mypath = [[NSBundle mainBundle] pathForResource:prefix ofType:@"png"]; | |||
NSData *pngdata = [[NSData alloc] initWithContentsOfFile:mypath]; | |||
UIImage *image = [[UIImage alloc] initWithData:pngdata]; | |||
if (!image) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not load %s\n", path); | |||
#endif | |||
exit(1); | |||
} | |||
int w = CGImageGetWidth(image.CGImage); | |||
int h = CGImageGetHeight(image.CGImage); | |||
data->size = ivec2(w, h); | |||
data->format = FORMAT_RGBA; | |||
CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB(); | |||
data->pixels = (uint8_t *)malloc(w * h * 4); | |||
CGContextRef ctx = | |||
CGBitmapContextCreate(data->pixels, w, h, 8, 4 * w, cspace, | |||
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); | |||
CGColorSpaceRelease(cspace); | |||
CGContextClearRect(ctx, CGRectMake(0, 0, w, h)); | |||
CGContextTranslateCTM(ctx, 0, h - h); | |||
CGContextDrawImage(ctx, CGRectMake(0, 0, w, h), image.CGImage); | |||
CGContextRelease(ctx); | |||
[image release]; | |||
[pngdata release]; | |||
#elif defined USE_SDL_IMAGE | |||
for (char const *name = path; *name; name++) | |||
if ((data->img = IMG_Load(name))) | |||
break; | |||
if (!data->img) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not load %s\n", path); | |||
#endif | |||
SDL_Quit(); | |||
exit(1); | |||
} | |||
data->size = ivec2(data->img->w, data->img->h); | |||
data->format = data->img->format->Amask ? FORMAT_RGBA : FORMAT_RGB; | |||
#elif defined __ANDROID__ | |||
JNIEnv *env; | |||
jint res = g_vm->GetEnv((void **)&env, JNI_VERSION_1_2); | |||
if (res < 0) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not get JVM environment\n"); | |||
#endif | |||
exit(1); | |||
} | |||
jclass cls = env->GetObjectClass(g_activity); | |||
jmethodID mid; | |||
mid = env->GetMethodID(cls, "openImage", | |||
"(Ljava/lang/String;)Landroid/graphics/Bitmap;"); | |||
jstring name = env->NewStringUTF(path); | |||
data->bmp = env->CallObjectMethod(g_activity, mid, name); | |||
env->DeleteLocalRef(name); | |||
if (!data->bmp) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not load %s\n", path); | |||
#endif | |||
exit(1); | |||
} | |||
env->NewGlobalRef(data->bmp); | |||
/* Get image dimensions */ | |||
mid = env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I"); | |||
data->size.x = env->CallIntMethod(g_activity, mid, data->bmp); | |||
mid = env->GetMethodID(cls, "getHeight", "(Landroid/graphics/Bitmap;)I"); | |||
data->size.y = env->CallIntMethod(g_activity, mid, data->bmp); | |||
/* Get pixels */ | |||
data->array = env->NewIntArray(data->size.x * data->size.y); | |||
env->NewGlobalRef(data->array); | |||
mid = env->GetMethodID(cls, "getPixels", "(Landroid/graphics/Bitmap;[I)V"); | |||
env->CallVoidMethod(g_activity, mid, data->bmp, data->array); | |||
data->pixels = env->GetIntArrayElements(data->array, 0); | |||
for (int n = 0; n < data->size.x * data->size.y; n++) | |||
{ | |||
uint32_t u = data->pixels[n]; | |||
u = (u & 0xff00ff00) | ((u & 0xff0000) >> 16) | ((u & 0xff) << 16); | |||
data->pixels[n] = u; | |||
} | |||
data->format = FORMAT_RGBA; | |||
#elif defined __CELLOS_LV2__ | |||
int32_t err; | |||
static bool unused = ImageLoader::RegisterAllLoaders(); | |||
/* Initialise decoding library */ | |||
CellPngDecMainHandle hmain; | |||
err = cellSysmoduleLoadModule(CELL_SYSMODULE_FS); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not open Fs sysmodule\n"); | |||
#endif | |||
exit(1); | |||
} | |||
err = cellSysmoduleLoadModule(CELL_SYSMODULE_PNGDEC); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not open PngDec sysmodule\n"); | |||
#endif | |||
exit(1); | |||
} | |||
CellPngDecThreadInParam in_param; | |||
in_param.spuThreadEnable = CELL_PNGDEC_SPU_THREAD_ENABLE; | |||
in_param.ppuThreadPriority = 1000; | |||
in_param.spuThreadPriority = 200; | |||
in_param.cbCtrlMallocFunc = ImageData::Malloc; | |||
in_param.cbCtrlMallocArg = NULL; | |||
in_param.cbCtrlFreeFunc = ImageData::Free; | |||
in_param.cbCtrlFreeArg = NULL; | |||
CellPngDecThreadOutParam out_param; | |||
err = cellPngDecCreate(&hmain, &in_param, &out_param); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not create PngDec library\n"); | |||
#endif | |||
exit(1); | |||
} | |||
/* Create decoder */ | |||
CellPngDecSubHandle hsub; | |||
char file[1024]; | |||
sprintf(file, "/app_home/c:/Users/s.hocevar/lolengine/%s", path); | |||
CellPngDecSrc dec_src; | |||
dec_src.srcSelect = CELL_PNGDEC_FILE; | |||
dec_src.fileName = file; | |||
dec_src.fileOffset = 0; | |||
dec_src.fileSize = 0; | |||
dec_src.streamPtr = NULL; | |||
dec_src.streamSize = 0; | |||
dec_src.spuThreadEnable = CELL_PNGDEC_SPU_THREAD_ENABLE; | |||
CellPngDecOpnInfo open_info; | |||
err = cellPngDecOpen(hmain, &hsub, &dec_src, &open_info); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not open %s for decoding\n", file); | |||
#endif | |||
exit(1); | |||
} | |||
CellPngDecInfo info; | |||
err = cellPngDecReadHeader(hmain, hsub, &info); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not read image header\n"); | |||
#endif | |||
exit(1); | |||
} | |||
CellPngDecInParam in_dec_param; | |||
in_dec_param.commandPtr = NULL; | |||
in_dec_param.outputMode = CELL_PNGDEC_TOP_TO_BOTTOM; | |||
in_dec_param.outputColorSpace = CELL_PNGDEC_RGBA; | |||
in_dec_param.outputBitDepth = 8; | |||
in_dec_param.outputPackFlag = CELL_PNGDEC_1BYTE_PER_1PIXEL; | |||
in_dec_param.outputAlphaSelect = CELL_PNGDEC_STREAM_ALPHA; | |||
in_dec_param.outputColorAlpha = 0xff; | |||
CellPngDecOutParam out_dec_param; | |||
err = cellPngDecSetParameter(hmain, hsub, &in_dec_param, &out_dec_param); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not configure PngDec decoder\n"); | |||
#endif | |||
exit(1); | |||
} | |||
/* Decode image */ | |||
data->size = ivec2(info.imageWidth, info.imageHeight); | |||
data->format = FORMAT_RGBA; | |||
data->pixels = (uint8_t *)malloc(info.imageWidth * 4 * info.imageHeight); | |||
CellPngDecDataCtrlParam data_ctrl_param; | |||
data_ctrl_param.outputBytesPerLine = info.imageWidth * 4; | |||
CellPngDecDataOutInfo data_out_info; | |||
err = cellPngDecDecodeData(hmain, hsub, data->pixels, | |||
&data_ctrl_param, &data_out_info); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not run PngDec decoder\n"); | |||
#endif | |||
exit(1); | |||
} | |||
/* Close decoder */ | |||
err = cellPngDecClose(hmain, hsub); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not close PngDec decoder\n"); | |||
#endif | |||
exit(1); | |||
} | |||
/* Deinitialise library */ | |||
err = cellPngDecDestroy(hmain); | |||
if (err != CELL_OK) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not destroy PngDec decoder\n"); | |||
#endif | |||
exit(1); | |||
} | |||
err = cellSysmoduleUnloadModule(CELL_SYSMODULE_PNGDEC); | |||
err = cellSysmoduleUnloadModule(CELL_SYSMODULE_FS); | |||
#else | |||
data->size = 256; | |||
data->format = FORMAT_RGBA; | |||
data->pixels = (uint8_t *)malloc(256 * 256 * 4 * sizeof(*data->pixels)); | |||
uint8_t *parser = data->pixels; | |||
for (int j = 0; j < 256; j++) | |||
for (int i = 0; i < 256; i++) | |||
{ | |||
*parser++ = ((i ^ j) & 1) * 0xff; | |||
*parser++ = (uint8_t)i; | |||
*parser++ = (uint8_t)j; | |||
*parser++ = (((i >> 4) ^ (j >> 4)) & 1) * 0xff; | |||
} | |||
#endif | |||
data = ImageLoader::Load(path); | |||
} | |||
ivec2 Image::GetSize() const | |||
@@ -332,50 +64,12 @@ Image::format_t Image::GetFormat() const | |||
void * Image::GetData() const | |||
{ | |||
#if defined __APPLE__ && defined __MACH__ | |||
return data->pixels; | |||
#elif defined USE_SDL_IMAGE | |||
return data->img->pixels; | |||
#elif defined __ANDROID__ | |||
return data->pixels; | |||
#elif defined __CELLOS_LV2__ | |||
return data->pixels; | |||
#else | |||
return data->pixels; | |||
#endif | |||
return data->GetData(); | |||
} | |||
Image::~Image() | |||
{ | |||
#if defined __APPLE__ && defined __MACH__ | |||
free(data->pixels); | |||
#elif defined USE_SDL_IMAGE | |||
SDL_FreeSurface(data->img); | |||
#elif defined __ANDROID__ | |||
JNIEnv *env; | |||
jint res = g_vm->GetEnv((void **)&env, JNI_VERSION_1_2); | |||
if (res < 0) | |||
{ | |||
#if !LOL_RELEASE | |||
Log::Error("could not get JVM environment\n"); | |||
#endif | |||
exit(1); | |||
} | |||
jclass cls = env->GetObjectClass(g_activity); | |||
jmethodID mid; | |||
env->ReleaseIntArrayElements(data->array, data->pixels, 0); | |||
env->DeleteGlobalRef(data->array); | |||
/* Free image */ | |||
mid = env->GetMethodID(cls, "closeImage", "(Landroid/graphics/Bitmap;)V"); | |||
env->CallVoidMethod(g_activity, mid, data->bmp); | |||
env->DeleteGlobalRef(data->bmp); | |||
#elif defined __CELLOS_LV2__ | |||
free(data->pixels); | |||
#else | |||
free(data->pixels); | |||
#endif | |||
data->Close(); | |||
delete data; | |||
} | |||