If you have comments or questions concerning this source file, discuss them in the forum.
/*
Copyright (c) 2002 Nicolai Haehnle
See the license.txt for details. If that file was not included in the
source distributions, please email <prefect@rtts.org>
*/
// hal.h -- abstract hardware interface layer classes
#include "keycodes.h"
/*
==============================================================================
HAL
==============================================================================
*/
#define __pic_alpha 1
#define __pic_maskonly 2
#define __pic_onlyalpha 4
#define __pic_colorkey 0x0100
// if RGB = colorkey A := 0
#define __pic_bitmask 0x0200
// create bitmask
#define __pic_redalpha 0x0400
// A := R; R,G,B := 1.0
#define __pic_palkey 0x0800
// palette entry 255 is transparent
#define __pic_nosubpixel 0x1000
// omit subpixel fixes; useful e.g. for HUD
#define __pic_formatmask (__pic_alpha|__pic_maskonly|__pic_onlyalpha)
#define pic_normal (0)
#define pic_colorkey (__pic_colorkey)
#define pic_redalpha (__pic_alpha|__pic_onlyalpha|__pic_redalpha)
#define pic_nosubpixel (__pic_nosubpixel)
#define pic_bitmask (__pic_bitmask)
typedef struct {
void (*Key)(int code, char c, bool down);
void (*MouseButton)(int btn, int x, int y, bool down);
void (*MouseMove)(int x, int y);
void (*QuitRequest)();
} hal_inputcb_t;
class HPicture;
class HFont;
class HAL {
friend class HPicture;
friend class HFont;
public:
int scrsize[2];
int framestart, frametime;
public:
HAL();
virtual ~HAL();
virtual void Init() = 0;
virtual void Shutdown() = 0;
virtual void StartFrame() = 0;
virtual void EndFrame() = 0;
virtual void Input(const hal_inputcb_t *cb) = 0;
virtual byte *GetKeyState() = 0;
virtual unsigned GetMouseState(int *px, int *py) = 0;
virtual void Ortho(int x, int y, int w, int h) = 0;
virtual void SetDrawRect(int x, int y, int w, int h, int ofsx, int ofsy) = 0;
virtual void SetAlphaOnly(bool on) = 0;
virtual void FillRect(int x, int y, int w, int h, int r, int g, int b, int a = 255) = 0;
virtual void DrawLine(float x1, float y1, float x2, float y2,
int r, int g, int b, int a = 255) = 0;
virtual byte *Screenshot(int *size) = 0;
private:
virtual void LoadPicture(HPicture *pic) = 0;
virtual void UnloadPicture(HPicture *pic) = 0;
public:
static int cachecycle;
void CacheCycle();
};
extern HAL *hal; // there can only be one HAL
const char *HAL_NameForKey(int code);
void HAL_Start(LConfig *cfg);
void HAL_Shutdown();
void HAL_Screenshot(const char *basename);
byte *HAL_CanonicalBitmapLoad(const char *fname, int *size, int *ptype,
unsigned int colorkey);
/*
==============================================================================
PICTURES / TEXTURES
==============================================================================
*/
class HPictureImpl {
public:
HPicture *m_pic;
public:
HPictureImpl(HPicture *pic) { m_pic = pic; }
virtual ~HPictureImpl() { }
virtual void Draw(float dstx, float dsty, float srcx, float srcy, float w, float h,
int r, int g, int b, int a) = 0;
};
// HPicture is 'just' a shell around the implementation, which allows
// the implementation to be exchanged on-the-fly (think resolution changes)
class HPicture {
friend class HAL;
public:
HPictureImpl *m_pImpl; // filled in on load
int size[2];
byte *bitmask;
int m_iType; // data needed to reload the picture
u32 m_colorkey;
char m_szName[64];
private:
static HPicture *m_pList;
HPicture **m_ppPrev;
HPicture *m_pNext;
int m_iUsed;
int m_iCacheCycle;
public:
static HPicture *Get(const char *name, int type, u32 colorkey);
public:
inline void AddRef() { m_iUsed++; }
inline void Release() { m_iUsed--; }
inline void Draw(float dstx, float dsty, int r = 255, int g = 255, int b = 255, int a = 255) {
m_pImpl->Draw(dstx, dsty, 0, 0, size[0], size[1], r, g, b, a);
}
inline void DrawEx(float dstx, float dsty, float srcx, float srcy, float w, float h,
int r = 255, int g = 255, int b = 255, int a = 255) {
m_pImpl->Draw(dstx, dsty, srcx, srcy, w, h, r, g, b, a);
}
static void CacheCycle();
static void UnloadAll();
static void LoadAll();
static void Cleanup();
private:
HPicture(const char *name, int type, u32 colorkey);
~HPicture();
};
/*
==============================================================================
FONT
==============================================================================
*/
// it's arguable whether this belongs into the HAL.. I just left it there
#define halign_mask 0x3
#define halign_left 0x0
#define halign_center 0x1
#define halign_right 0x2
#define valign_mask 0xC
#define valign_top 0x0
#define valign_center 0x4
#define valign_bottom 0x8
#define align_wrap 0x10
class HFont {
friend class HAL;
public:
char m_szName[64];
public:
static HFont *Get(const char *name);
inline void AddRef() { m_iUsed++; }
inline void Release() { m_iUsed--; }
virtual void CharRect(const char *string, int num,
int align, int width, int yspacing, LRect *rc) = 0;
virtual void StringSize(const char *string, int width, int yspacing,
int *pw, int *ph) = 0;
virtual void DrawChar(int dstx, int dsty, char c,
int r = 255, int g = 255, int b = 255, int a = 255) = 0;
virtual void DrawString(int dstx, int dsty, const char *string,
int align, int width, int yspacing,
int r = 255, int g = 255, int b = 255, int a = 255) = 0;
public:
HFont(const char *pszName);
virtual ~HFont() = 0;
static void CacheCycle();
static void Cleanup();
static HFont *m_pList;
HFont **m_ppPrev;
HFont *m_pNext;
int m_iUsed;
int m_iCacheCycle;
};
/*
==============================================================================
SPRITES
==============================================================================
*/
#define MAX_ATTACHS 32
#define MAX_ANIMATIONS 8
typedef struct {
int id;
float offset[2];
} spr_attach_t;
typedef struct {
HPicture *pic;
byte r, g, b, a;
float offsets[2];
} spr_frame_t;
typedef struct {
int id;
float speed;
int numframes;
spr_frame_t *frames;
} spr_animation_t;
typedef struct sprite_s {
struct sprite_s **pprev, *next;
int used;
int cachecycle;
char name[64];
float mins[2];
float maxs[2];
int numattachs;
spr_attach_t attachs[MAX_ATTACHS];
spr_animation_t base;
int numanims;
spr_animation_t anims[MAX_ANIMATIONS];
} sprite_t;
sprite_t *SPR_Get(const char *name);
void SPR_Free(sprite_t *spr);
void SPR_Draw(sprite_t *spr, float scrx, float scry, int animnum, float curtime, int alpha = 255);
spr_attach_t *SPR_GetAttach(sprite_t *spr, int id);
// called internally:
void SPR_CacheCycle();
void SPR_Cleanup();