newoswan/oswan/source/SDLptc.h

247 lines
4.6 KiB
C++

/* Some simple emulation classes to get PTC code running on SDL */
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
typedef Uint8 char8;
typedef Sint32 int32;
#define randomize() srand(time(NULL))
#define random(max) (rand()%(max))
#ifndef stricmp
#define stricmp strcasecmp
#endif
class Error {
public:
Error(const char *message) {
strcpy(_message, message);
}
void report(void) {
printf("Error: %s\n", _message);
}
private:
char _message[1024];
};
class Area {
public:
Area(int left, int top, int right, int bottom) {
_left = left;
_top = top;
_right = right;
_bottom = bottom;
}
int left(void) const {
return(_left);
}
int right(void) const {
return(_right);
}
int top(void) const {
return(_top);
}
int bottom(void) const {
return(_bottom);
}
int width(void) const {
return(_right-_left);
}
int height(void) const {
return(_bottom-_top);
}
private:
int _left, _top, _right, _bottom;
};
class Format {
public:
Format(int bpp, int maskR = 0, int maskG = 0, int maskB = 0) {
_bpp = bpp;
_maskR = maskR;
_maskG = maskG;
_maskB = maskB;
}
Uint8 BPP(void) const { return(_bpp); }
Uint32 MaskR(void) const { return(_maskR); }
Uint32 MaskG(void) const { return(_maskG); }
Uint32 MaskB(void) const { return(_maskB); }
private:
Uint8 _bpp;
Uint32 _maskR, _maskG, _maskB;
};
class Surface {
public:
Surface(int w, int h, const Format &format) {
surface = SDL_AllocSurface(SDL_SWSURFACE, w, h, format.BPP(),
format.MaskR(),format.MaskG(),format.MaskB(),0);
if ( surface == NULL ) {
throw Error(SDL_GetError());
}
nupdates = 0;
is_console = 0;
}
Surface(void) {
nupdates = 0;
is_console = 1;
}
virtual ~Surface() {
if ( ! is_console ) {
SDL_FreeSurface(surface);
}
}
virtual int width(void) {
return surface->w;
}
virtual int height(void) {
return surface->h;
}
virtual int pitch(void) {
return surface->pitch;
}
virtual void palette(int32 *pcolors) {
SDL_Color colors[256];
for ( int i=0; i<256; ++i ) {
colors[i].r = (pcolors[i]>>16)&0xFF;
colors[i].g = (pcolors[i]>>8)&0xFF;
colors[i].b = (pcolors[i]>>0)&0xFF;
}
SDL_SetColors(surface, colors, 0, 256);
}
virtual void *lock(void) {
if ( SDL_MUSTLOCK(surface) ) {
while ( SDL_LockSurface(surface) < 0 ) {
SDL_Delay(10);
}
}
return (Uint8 *)surface->pixels;
}
virtual void unlock(void) {
if ( SDL_MUSTLOCK(surface) ) {
SDL_UnlockSurface(surface);
}
}
virtual void copy(Surface &dst,
const Area &srcarea, const Area &dstarea) {
SDL_Rect srcrect, dstrect;
srcrect.x = srcarea.left();
srcrect.y = srcarea.top();
srcrect.w = srcarea.width();
srcrect.h = srcarea.height();
dstrect.x = dstarea.left();
dstrect.y = dstarea.top();
dstrect.w = dstarea.width();
dstrect.h = dstarea.height();
SDL_BlitSurface(surface, &srcrect, dst.surface, &dstrect);
dst.updates[dst.nupdates++] = dstrect;
}
virtual void copy(Surface &dst) {
SDL_Rect srcrect, dstrect;
srcrect.x = 0;
srcrect.y = 0;
srcrect.w = surface->w;
srcrect.h = surface->h;
dstrect.x = 0;
dstrect.y = 0;
dstrect.w = surface->w;
dstrect.h = surface->h;
SDL_LowerBlit(surface, &srcrect, dst.surface, &dstrect);
dst.updates[dst.nupdates++] = dstrect;
}
virtual void update(void) {
SDL_UpdateRects(surface, nupdates, updates);
nupdates = 0;
}
protected:
SDL_Surface *surface;
int nupdates;
SDL_Rect updates[1]; /* Definitely increase this.. */
int is_console;
};
class Console : public Surface {
int fullscreen;
public:
Console() : Surface() {
fullscreen=0;
}
~Console() {
SDL_Quit();
}
void close(void)
{
SDL_Quit();
}
void option(char *option)
{
if (!stricmp(option,"fullscreen output"))
fullscreen=1;
else
if (!stricmp(option,"windowed output"))
fullscreen=0;
}
void open(const char *title, int width, int height, const Format &format) {
Uint32 flags;
if ( SDL_InitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 ) {
throw Error(SDL_GetError());
}
//flags = (SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN);
flags = (SDL_HWSURFACE|SDL_HWPALETTE);
if (fullscreen)
flags|=SDL_FULLSCREEN;
surface = SDL_SetVideoMode(width, height, 0, flags);
if ( surface == NULL ) {
throw Error(SDL_GetError());
}
SDL_WM_SetCaption(title, title);
}
int key(void) {
SDL_Event event;
int keyevent;
keyevent = 0;
while ( SDL_PollEvent(&event) ) {
/* Real key events trigger this function */
if ( event.type == SDL_KEYDOWN ) {
keyevent = 1;
}
/* So do quit events -- let the app know about it */
if ( event.type == SDL_QUIT ) {
keyevent = 1;
}
}
return(keyevent);
}
private:
};