Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

@ -0,0 +1,201 @@
#include <tataki/api__tataki.h>
#include "autobitmap.h"
#include <bfc/assert.h>
#define TIMER_ID_RESET 0x1664
#ifdef DROP_BITMAP_ON_IDLE
// these are in seconds
#define DROP_MINDELAY 3
#define DROP_MAXDELAY 15
#define DROP_INITIALBUMP -5
#define DROP_MINDELAYSINCELASTUSE 7
#endif
/*
#ifdef _WIN32
extern HINSTANCE hInstance;
#endif
*/
AutoSkinBitmap::AutoSkinBitmap(const wchar_t *_name)
{
bitmap = NULL;
use = 0;
id = 0;
colorgroup = 0;
name = 0;
resamplingMode = RESAMPLING_MODE_NONE;
#ifdef WIN32
myInstance = 0;
#endif
#ifdef DROP_BITMAP_ON_IDLE
lastuse = 0;
#endif
setBitmap(_name);
}
AutoSkinBitmap::~AutoSkinBitmap()
{
#ifdef DROP_BITMAP_ON_IDLE
timerclient_killTimer(TIMER_ID_RESET);
#endif
if (bitmap) bitmap->Release();
ASSERT(WASABI_API_SYSCB != NULL);
WASABI_API_SYSCB->syscb_deregisterCallback(this);
free(colorgroup);
free(name);
}
const wchar_t *AutoSkinBitmap::setBitmap(const wchar_t *_name)
{
if (_name == NULL) return NULL;
if (name == NULL || wcscmp(name, _name))
{
reset();
free(name);
name = _wcsdup(_name);
}
return name;
}
int AutoSkinBitmap::setBitmap(int _id)
{
if (_id == 0) return 0;
if (_id != id)
{
reset();
id = _id;
}
return id;
}
#ifdef _WIN32
void AutoSkinBitmap::setHInstance(HINSTANCE hinstance)
{
myInstance = hinstance;
}
#endif
void AutoSkinBitmap::reset()
{
if (bitmap) bitmap->Release(); bitmap = NULL;
#ifdef DROP_BITMAP_ON_IDLE
timerclient_killTimer(TIMER_ID_RESET);
#endif
}
static int modrandom(int max)
{
int ret = AGAVE_API_RANDOM->GetPositiveNumber();
ret %= max;
return ret;
}
SkinBitmap *AutoSkinBitmap::getBitmap()
{
//FG ASSERT(name != NULL);
if ((name == NULL || (name != NULL && *name == NULL)) && id == NULL) return NULL;
if (bitmap == NULL)
{
if (name)
{
switch (resamplingMode)
{
case RESAMPLING_MODE_SUPERSAMPLING:
bitmap = new HQSkinBitmap(name);
break;
case RESAMPLING_MODE_NONE:
default:
bitmap = new SkinBitmap(name);
break;
}
}
else
{
#ifdef WIN32
switch (resamplingMode)
{
case RESAMPLING_MODE_SUPERSAMPLING:
bitmap = new HQSkinBitmap(myInstance, id, colorgroup);
break;
case RESAMPLING_MODE_NONE:
default:
bitmap = new SkinBitmap(myInstance, id, colorgroup);
break;
}
#endif
}
ASSERT(WASABI_API_SYSCB != NULL);
if (bitmap)
WASABI_API_SYSCB->syscb_registerCallback(this);
#ifdef DROP_BITMAP_ON_IDLE
if (bitmap)
{
lastuse = GetTickCount() + DROP_INITIALBUMP;
timerclient_setTimer(TIMER_ID_RESET, DROP_MINDELAY*1000 + modrandom((DROP_MAXDELAY - DROP_MINDELAY)*1000));
return bitmap;
}
#endif
}
#ifdef DROP_BITMAP_ON_IDLE
if (bitmap) lastuse = GetTickCount();
#endif
return bitmap;
}
const wchar_t *AutoSkinBitmap::getBitmapName()
{
return name;
}
int AutoSkinBitmap::skincb_onReset()
{
reset();
return 1;
}
void AutoSkinBitmap::setHInstanceBitmapColorGroup(const wchar_t *_colorgroup)
{
free(colorgroup);
if (_colorgroup)
colorgroup = _wcsdup(_colorgroup);
else
colorgroup=0;
}
#ifdef DROP_BITMAP_ON_IDLE
void AutoSkinBitmap::timerclient_timerCallback(int id)
{
if (id == TIMER_ID_RESET)
{
tryUnload();
}
else TimerClientDI::timerclient_timerCallback(id);
}
void AutoSkinBitmap::tryUnload()
{
DWORD now = GetTickCount();
if (now < lastuse + DROP_MINDELAYSINCELASTUSE*1000) return ;
reset();
}
#endif
void AutoSkinBitmap::setResamplingMode(int mode)
{
this->resamplingMode = mode;
this->reset();
}
int AutoSkinBitmap::getResamplingMode()
{
return this->resamplingMode;
}
#define CBCLASS AutoSkinBitmap
START_DISPATCH;
CB(SYSCALLBACK_GETEVENTTYPE, getEventType);
CB(SYSCALLBACK_NOTIFY, notify);
END_DISPATCH;
#undef CBCLASS

View file

@ -0,0 +1,106 @@
#ifndef _AUTOBITMAP_H
#define _AUTOBITMAP_H
#include "bitmap.h"
#include <api/syscb/callbacks/syscb.h>
#include <api/syscb/callbacks/skincb.h>
#include <tataki/export.h>
#ifdef DROP_BITMAP_ON_IDLE
#include <api/timer/timerclient.h>
#define DROP_BITMAP_ANCESTOR , public TimerClientDI
#else
#define DROP_BITMAP_ANCESTOR
#endif
class TATAKIAPI AutoSkinBitmap : public SysCallback DROP_BITMAP_ANCESTOR {
public:
AutoSkinBitmap(const wchar_t *_name=NULL);
virtual ~AutoSkinBitmap();
const wchar_t *setBitmap(const wchar_t *_name=NULL);
int setBitmap(int _id=0);
// call this when you get freeResources called on you
// doesn't hurt to call as much as you want
void reset();
void reload() { getBitmap(); } // force a reload
// this loads the bitmap if necessary
SkinBitmap *getBitmap();
operator SkinBitmap *() { return getBitmap(); }
const wchar_t *operator =(const wchar_t *_name) { return setBitmap(_name); }
int operator =(int _id) { return setBitmap(_id); }
const wchar_t *getBitmapName();
void setHInstanceBitmapColorGroup(const wchar_t *_colorgroup);
enum
{
RESAMPLING_MODE_NONE = 0,
RESAMPLING_MODE_SUPERSAMPLING = 1,
};
void setResamplingMode(int mode);
int getResamplingMode();
// feel free to add more methods here to help make using this class
// transparent...
int getWidth() { return getBitmap()->getWidth(); };
int getHeight() { return getBitmap()->getHeight(); };
void stretchToRectAlpha(ifc_canvas *canvas, RECT *r, int alpha=255) {
getBitmap()->stretchToRectAlpha(canvas, r, alpha);
}
void stretchToRectAlpha(ifc_canvas *canvas, RECT *r, RECT *dest, int alpha=255) {
getBitmap()->stretchToRectAlpha(canvas, r, dest, alpha);
}
void stretchToRect(ifc_canvas *canvas, RECT *r) {
getBitmap()->stretchToRect(canvas, r);
}
void blitAlpha(ifc_canvas *canvas, int x, int y, int alpha=255) {
getBitmap()->blitAlpha(canvas, x, y, alpha);
}
#ifdef _WIN32
void setHInstance(HINSTANCE hinstance); // use this if you use autoskinbitmap and resource in a wac
#endif
#ifdef DROP_BITMAP_ON_IDLE
virtual void timerclient_timerCallback(int id);
#endif
protected:
FOURCC getEventType() { return SysCallback::SKINCB; }
int notify(int msg, intptr_t param1 = 0, intptr_t param2 = 0)
{
if (msg == SkinCallback::RESET)
return skincb_onReset();
else
return 0;
}
int skincb_onReset();
#ifdef DROP_BITMAP_ON_IDLE
virtual void tryUnload();
#endif
private:
int use;
int id;
wchar_t *name;
wchar_t *colorgroup;
SkinBitmap *bitmap;
int resamplingMode;
#ifdef _WIN32
HINSTANCE myInstance;
#endif
#ifdef DROP_BITMAP_ON_IDLE
uint32_t lastuse;
#endif
protected:
RECVS_DISPATCH;
};
#endif

View file

@ -0,0 +1,7 @@
#ifdef _WIN32
#include "win/bitmap.h"
#elif defined(__APPLE__)
#include "mac/osx_bitmap_cgimage.h"
#else
#error port me
#endif

View file

@ -0,0 +1,51 @@
#ifndef NULLSOFT_WASABI_IFC_BITMAP_H
#define NULLSOFT_WASABI_IFC_BITMAP_H
#include <bfc/dispatch.h>
#include <bfc/platform/types.h>
#include <bfc/platform/platform.h>
#warning move this typedef to bfc/platform/platform.h
#ifdef _WIN32
typedef HBITMAP OSBITMAPHANDLE;
#elif defined(__APPLE__)
typedef CGImageRef OSBITMAPHANDLE;
#else
#error port me
#endif
class ifc_bitmap : public Dispatchable
{
protected:
ifc_bitmap() {}
~ifc_bitmap() {}
public:
OSBITMAPHANDLE GetBitmap();
uint8_t *GetBits();
void UpdateBits(uint8_t *bits); // call to signify that you've modified the underlying bits.
DISPATCH_CODES
{
IFC_BITMAP_GETBITMAP = 10,
IFC_BITMAP_GETBITS = 20,
IFC_BITMAP_UPDATEBITS = 30,
};
};
inline OSBITMAPHANDLE ifc_bitmap::GetBitmap()
{
return _call(IFC_BITMAP_GETBITMAP, (OSBITMAPHANDLE)0);
}
inline uint8_t *ifc_bitmap::GetBits()
{
return _call(IFC_BITMAP_GETBITS, (uint8_t *)0);
}
inline void ifc_bitmap::UpdateBits(uint8_t *bits)
{
_voidcall(IFC_BITMAP_UPDATEBITS, bits);
}
#endif

View file

@ -0,0 +1,219 @@
#include "osx_bitmap_cgimage.h"
SkinBitmap::SkinBitmap(ARGB32 *_bits, int w, int h) : image(0)
{
// TODO: allow a mechanism for SkinBitmap to take ownership of the data
bits = malloc(w*h*4);
if (bits)
{
memcpy(bits, _bits, w*h*4);
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
imageContext = CGBitmapContextCreate(bits, w, h, 8, w*4, colorSpace, kCGBitmapByteOrder32Little|kCGImageAlphaPremultipliedFirst);
image = CGBitmapContextCreateImage(imageContext);
CGColorSpaceRelease(colorSpace);
}
}
SkinBitmap::~SkinBitmap()
{
CGImageRelease(image);
#ifndef SKINBITMAP_USE_CGIMAGE
free(bits);
CGContextRelease(imageContext);
#endif
}
#ifdef WASABI_COMPILE_IMGLDR
SkinBitmap::SkinBitmap(const wchar_t *elementname, int _cached)
{
ASSERT(elementname!= NULL);
bitmapname = elementname;
x_offset = -1;
y_offset = -1;
subimage_w = -1;
subimage_h = -1;
fullimage_w=fullimage_h=0;
ownbits=1;
bits = NULL;
fromskin = 0;
last_failed = 0;
#ifdef WASABI_COMPILE_SKIN
bits = WASABI_API_IMGLDR->imgldr_requestSkinBitmap(elementname, &has_alpha, &x_offset, &y_offset, &subimage_w, &subimage_h, &fullimage_w, &fullimage_h,_cached);
fromskin = (bits != NULL);
#endif
if (bits == NULL)
bits = WASABI_API_IMGLDR->imgldr_makeBmp(elementname, &has_alpha, &fullimage_w, &fullimage_h);
#ifdef WASABI_COMPILE_SKIN
if (bits == NULL)
{
bits = WASABI_API_IMGLDR->imgldr_requestSkinBitmap(ERRORBMP, &has_alpha, &x_offset, &y_offset, &subimage_w, &subimage_h, &fullimage_w, &fullimage_h,_cached);
last_failed = 1;
}
#endif
if (bits == NULL)
{
bits = WASABI_API_IMGLDR->imgldr_makeBmp(HARDERRORBMP, &has_alpha, &fullimage_w, &fullimage_h);
last_failed = 1;
}
// check that coordinates are correct
if(x_offset!=-1 && x_offset>fullimage_w) x_offset=fullimage_w-1;
if(y_offset!=-1 && y_offset>fullimage_h) y_offset=fullimage_h-1;
if(subimage_w!=-1 && (x_offset+subimage_w)>fullimage_w) subimage_w=fullimage_w-x_offset;
if(subimage_h!=-1 && (y_offset+subimage_h)>fullimage_h) subimage_h=fullimage_h-y_offset;
// ASSERTPR(bits != NULL, elementname);
if (bits == NULL) {
DebugString("element not found ! %s\n", elementname);
int n = 10*10;
bits = (ARGB32 *)WASABI_API_MEMMGR->sysMalloc(n * 4);
ARGB32 *p = bits;
while (n--)
*p++ = 0xFFFF00FF;
}
}
#endif
int SkinBitmap::getWidth()
{
if (!image)
return 0;
return CGImageGetWidth(image);
}
int SkinBitmap::getFullWidth()
{
if (!image)
return 0;
return CGImageGetBytesPerRow(image)/4; // assumes 32bit pixel data
}
int SkinBitmap::getHeight()
{
if (!image)
return 0;
return CGImageGetHeight(image);
}
void SkinBitmap::blit(api_canvas *canvas, int x, int y)
{
if (!image)
return;
CGContextRef context = canvas->getHDC();
CGRect rect = CGRectMake(x, y, getWidth(), getHeight());
CGContextDrawImage(context, rect, image);
}
void SkinBitmap::blitAlpha(api_canvas *canvas, int x, int y, int alpha)
{
if (!image)
return;
float floatAlpha = alpha / 255.f;
CGContextRef context = canvas->getHDC();
CGContextSaveGState(context);
// CGContextTranslateCTM(context, 0, r->bottom);
// CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetAlpha(context, floatAlpha);
CGRect rect = CGRectMake(x, y, getWidth(), getHeight());
CGContextDrawImage(context, rect, image);
CGContextRestoreGState(context);
}
void SkinBitmap::stretchToRect(api_canvas *canvas, RECT *r)
{
if (!image)
return;
CGContextRef context = canvas->getHDC();
CGContextSaveGState(context);
CGContextTranslateCTM (context, 0, r->bottom);
CGContextScaleCTM(context, 1.0, -1.0);
CGRect rect = CGRectMake(r->left, r->top, r->right-r->left, r->bottom-r->top);
CGContextDrawImage(context, rect, image);
CGContextRestoreGState(context);
}
void SkinBitmap::stretchToRectAlpha(api_canvas *canvas, RECT *r, int alpha)
{
if (!image)
return;
float floatAlpha = alpha / 255.f;
CGContextRef context = canvas->getHDC();
CGContextSaveGState(context);
CGContextTranslateCTM (context, 0, r->bottom);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetAlpha(context, floatAlpha);
CGRect rect = CGRectMake(r->left, r->top, r->right-r->left, r->bottom-r->top);
CGContextDrawImage(context, rect, image);
CGContextRestoreGState(context);
}
void SkinBitmap::stretchToRectAlpha(api_canvas *canvas, RECT *src, RECT *dst, int alpha)
{
if (!image)
return;
float floatAlpha = alpha / 255.f;
// make a new image ref clipped to the source rect
CGRect srcRect = CGRectMake(src->left, src->top, src->right-src->left, src->bottom-src->top);
CGImageRef clippedImage = CGImageCreateWithImageInRect(image, srcRect);
// blit onto canvas
CGContextRef context = canvas->getHDC();
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0, dst->bottom);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetAlpha(context, floatAlpha);
CGRect rect = CGRectMake(dst->left, dst->top, dst->right-dst->left, dst->bottom-dst->top);
CGContextDrawImage(context, rect, clippedImage);
CGContextRestoreGState(context);
// release the reference to our clipped image
CGImageRelease(clippedImage);
}
uint8_t *SkinBitmap::getBits()
{
return static_cast<uint8_t *>(CGBitmapContextGetData(imageContext));
}
void SkinBitmap::UpdateBits(uint8_t *bits)
{
CGImageRelease(image);
image = CGBitmapContextCreateImage(imageContext);
}
ARGB32 SkinBitmap::getPixel(int x, int y)
{
ARGB32 *array = (ARGB32 *)getBits();
return array[x + y*getFullWidth()];
}
#define CBCLASS SkinBitmap
START_DISPATCH;
CB(IFC_BITMAP_GETBITMAP, GetBitmap);
CB(IFC_BITMAP_GETBITS, getBits);
VCB(IFC_BITMAP_UPDATEBITS, UpdateBits);
END_DISPATCH;
#undef CBCLASS

View file

@ -0,0 +1,48 @@
#ifndef NULLSOFT_WASABI_OSX_BITMAP_CGIMAGE_H
#define NULLSOFT_WASABI_OSX_BITMAP_CGIMAGE_H
#include <tataki/export.h>
#include <bfc/platform/platform.h>
#include <tataki/canvas/api_canvas.h>
#include <api/wnd/ifc_bitmap.h>
/*
TODO:
need some kind of updateBits() so that the underlying image can be updated to reflect changes
*/
class TATAKIAPI SkinBitmap : public ifc_bitmap
{
public:
SkinBitmap(ARGB32 *bits, int w, int h); // added by benski, use if you have raw image bits
SkinBitmap(const wchar_t *elementname, int cached = 1);
~SkinBitmap();
int getWidth();
int getHeight();
int getFullWidth(); // aka pitch
// blits
void blit(api_canvas *canvas, int x, int y);
void blitAlpha(api_canvas *canvas, int x, int y, int alpha = 255);
// stretch blits
void stretchToRect(api_canvas *canvas, RECT *r);
void stretchToRectAlpha(api_canvas *canvas, RECT *r, int alpha = 255);
void stretchToRectAlpha(api_canvas *canvas, RECT *src, RECT *dst, int alpha = 255);
// tiled blits
void blitTile(api_canvas *canvas, RECT *dest, int xoffs = 0, int yoffs = 0, int alpha = 255);
ARGB32 getPixel(int x, int y);
public: // ifc_bitmap implementations
OSBITMAPHANDLE GetBitmap() { return image; }
uint8_t *getBits();
void UpdateBits(uint8_t *bits);
private:
CGImageRef image;
CGContextRef imageContext;
void *bits;
protected:
RECVS_DISPATCH;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,113 @@
//NONPORTABLE
#ifndef _BITMAP_H
#define _BITMAP_H
#pragma warning( disable: 4251 )
// http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
#include <tataki/export.h>
#include <bfc/platform/platform.h>
class ifc_canvas; // see canvas.h
//#define NO_MMX
class api_region;
// a skinnable bitmap
class TATAKIAPI SkinBitmap
{
public:
void AddRef();
void Release();
#ifndef _NOSTUDIO
#ifdef _WIN32
SkinBitmap(HINSTANCE hInst, int _id, const wchar_t *colorgroup = NULL); //NONPORTABLE
#endif
SkinBitmap(const wchar_t *elementname, int cached = 1);
#endif
// SkinBitmap(SkinBitmap *source, int w, int h);
SkinBitmap(int w, int h, ARGB32 bgcolor = RGBA(255,255,255,255)); //untested --BU
#ifdef _WIN32
SkinBitmap(HBITMAP bitmap);
SkinBitmap(HBITMAP bitmap, HDC dc, int has_alpha = 0, void *bits = NULL);
#endif
SkinBitmap(ARGB32 *bits, int w, int h, bool own=false); // added by benski, use if you have raw image bits
SkinBitmap(ifc_canvas *canvas);
~SkinBitmap();
int getWidth() const { return subimage_w == -1 ? fullimage_w : subimage_w; };
int getHeight() const { return subimage_h == -1 ? fullimage_h : subimage_h; };
int getFullWidth() const { return fullimage_w; };
int getFullHeight() const { return fullimage_h; };
int getX() const { return x_offset == -1 ? 0 : x_offset; };
int getY() const { return y_offset == -1 ? 0 : y_offset; };
int getBpp() const { return 32; };
int getAlpha() const { return has_alpha; };
void setHasAlpha(int ha);
virtual void *getBits();
int isInvalid();
const wchar_t *getBitmapName();
void blit(ifc_canvas *canvas, int x, int y);
void blitAlpha(ifc_canvas *canvas, int x, int y, int alpha = 255);
// blits a chunk of source into dest rect
void blitToRect(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255);
void blitTile(ifc_canvas *canvas, RECT *dest, int xoffs = 0, int yoffs = 0, int alpha = 255);
void blitRectToTile(ifc_canvas *canvas, RECT *dest, RECT *src, int xoffs = 0, int yoffs = 0, int alpha = 255);
void stretch(ifc_canvas *canvas, int x, int y, int w, int h);
void stretchToRect(ifc_canvas *canvas, RECT *r);
void stretchRectToRect(ifc_canvas *canvas, RECT *src, RECT *dst);
void stretchToRectAlpha(ifc_canvas *canvas, RECT *r, int alpha = 255);
void stretchToRectAlpha(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255);
ARGB32 getPixel(int x, int y);
private:
#ifdef _WIN32
void bmpToBits(HBITMAP hbmp, HDC defaultDC = NULL);
#endif
int has_alpha;
int x_offset, y_offset, subimage_w, subimage_h, fullimage_w, fullimage_h;
ARGB32 *bits;
int ownbits;
int last_failed;
wchar_t *bitmapname;
int fromskin;
size_t references;
enum
{
OWNBITS_NOTOURS =0 ,
OWNBITS_USEIMGLDR = 1,
OWNBITS_USESTDFREE = 2,
OWNBITS_USECFREE = 3,
OWNBITS_USESYSFREE = 4,
};
protected:
bool high_quality_resampling;
};
#ifndef _NOSTUDIO
class HQSkinBitmap : public SkinBitmap
{
public:
HQSkinBitmap(ARGB32 *bits, int w, int h, bool own=false) : SkinBitmap(bits, w, h, own)
{
high_quality_resampling=true;
}
HQSkinBitmap(const wchar_t *elementname, int cached = 1) : SkinBitmap(elementname, cached)
{
high_quality_resampling=true;
}
#ifdef _WIN32
HQSkinBitmap(HINSTANCE hInst, int _id, const wchar_t *colorgroup = NULL) : SkinBitmap(hInst, _id, colorgroup)
{
high_quality_resampling=true;
}
#endif
};
#endif
#endif