Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
425 KB
Referenced Files
None
Subscribers
None
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/util/allegro/bitmap.cpp b/util/allegro/bitmap.cpp
index 05be6226..9a2f5b64 100644
--- a/util/allegro/bitmap.cpp
+++ b/util/allegro/bitmap.cpp
@@ -1,1791 +1,1796 @@
/* allegro.h must be on top, don't move it!!!! */
#include <allegro.h>
#ifdef _WIN32
#include <winalleg.h>
#endif
#include "../gif/algif.h"
#include "../bitmap.h"
#include "../lit_bitmap.h"
#include "../trans-bitmap.h"
#include <stdarg.h>
#include <vector>
#include <string>
#include <iostream>
#include <math.h>
#include "../funcs.h"
#include <stdio.h>
#include "../load_exception.h"
#include "../memory.h"
#include <sstream>
// #include <fblend.h>
#ifdef _WIN32
#include <winalleg.h>
#define EXTERNAL_VARIABLE __declspec(dllimport)
#else
#define EXTERNAL_VARIABLE
#endif
using namespace std;
#ifndef debug
#define debug cout<<"File: "<<__FILE__<<" Line: "<<__LINE__<<endl;
#endif
+/* These have to go outside the Graphics namespace for some reason */
+/* defined at allegro/include/internal/aintern.h:457 */
+extern EXTERNAL_VARIABLE BLENDER_FUNC _blender_func16;
+/* defined at allegro/include/internal/aintern.h:466 */
+extern EXTERNAL_VARIABLE int _blender_col_16;
+/* defined at allegro/include/internal/aintern.h:470 */
+extern EXTERNAL_VARIABLE int _blender_alpha;
+
+namespace Graphics{
+
static void paintown_draw_sprite_ex16( BITMAP * dst, BITMAP * src, int dx, int dy, int mode, int flip, Bitmap::Filter * filter);
static void paintown_draw_sprite_filter_ex16(BITMAP * dst, BITMAP * src, int x, int y, const Bitmap::Filter & filter);
static void paintown_light16(BITMAP * dst, const int x, const int y, const int width, const int height, const int start_y, const int focus_alpha, const int edge_alpha, const int focus_color, const int edge_color);
static void paintown_applyTrans16(BITMAP * dst, const int color);
int Bitmap::MaskColor(){
return MASK_COLOR_16;
}
Bitmap * Bitmap::Screen = NULL;
static Bitmap * Scaler = NULL;
static Bitmap * Buffer = NULL;
Bitmap::Bitmap():
own( NULL ),
mustResize(false),
error( false ),
bit8MaskColor(0){
getData().setBitmap( create_bitmap( 10, 10 ) );
if (! getData().getBitmap()){
error = true;
cerr << "Could not create bitmap!" << endl;
} else {
clear();
own = new int;
*own = 1;
}
}
Bitmap::Bitmap( int x, int y ):
own( NULL ),
mustResize(false),
error( false ),
bit8MaskColor(0){
if ( x < 1 ){
x = 1;
}
if ( y < 1 ){
y = 1;
}
getData().setBitmap( create_bitmap( x, y ) );
if ( ! getData().getBitmap() ){
error = true;
cerr << "Could not create bitmap!" << endl;
} else {
clear();
own = new int;
*own = 1;
}
}
enum Format{
PNG,
GIF,
};
static BITMAP * memoryGIF(const char * data, int length){
PACKFILE_VTABLE table = Memory::makeTable();
Memory::memory memory((unsigned char *) data, length);
PACKFILE * pack = pack_fopen_vtable(&table, &memory);
/* need to supply a proper palette at some point */
RGB * palette = NULL;
/* algif will close the packfile for us in both error and success cases */
BITMAP * gif = load_gif_packfile(pack, palette);
if (!gif){
// pack_fclose(pack);
ostringstream out;
out <<"Could not load gif from memory: " << (void*) data << " length " << length;
throw LoadException(__FILE__, __LINE__, out.str());
}
#if 0
/* converts 8-bit pcx mask to allegro's mask */
if (mask){
/* warning! 8-bit assumptions */
int colors = 256;
int maskR = (int)data[length - colors*3 + 0];
int maskG = (int)data[length - colors*3 + 1];
int maskB = (int)data[length - colors*3 + 2];
int mask = makeColor(maskR, maskG, maskB);
// printf("mask r %d g %d b %d = %d\n", maskR, maskG, maskB, mask);
if (mask != MaskColor()){
for( int i = 0; i < pcx->h; ++i ){
for( int j = 0; j < pcx->w; ++j ){
/* use getPixel/putPixel? */
int pix = getpixel(pcx,j,i);
if (pix == mask){
putpixel(pcx,j,i, MaskColor());
}
}
}
}
}
#endif
BITMAP * out = create_bitmap(gif->w, gif->h);
blit(gif, out, 0, 0, 0, 0, gif->w, gif->h);
destroy_bitmap(gif);
// pack_fclose(pack);
return out;
}
static BITMAP * load_bitmap_from_memory(const char * data, int length, Format type){
switch (type){
case PNG : {
break;
}
case GIF : {
return memoryGIF(data, length);
break;
}
}
throw Exception::Base(__FILE__, __LINE__);
}
Bitmap::Bitmap(const char * data, int length):
own(NULL),
mustResize(false),
error(false),
bit8MaskColor(0){
/* FIXME: pass the type in */
Format type = GIF;
getData().setBitmap(load_bitmap_from_memory(data, length, type));
own = new int;
*own = 1;
}
/* If a BITMAP is given to us, we didn't make it so we don't own it */
Bitmap::Bitmap( BITMAP * who, bool deep_copy ):
own( NULL ),
mustResize(false),
error( false ),
bit8MaskColor(0){
if ( deep_copy ){
BITMAP * his = who;
getData().setBitmap( create_bitmap( his->w, his->h ) );
if ( ! getData().getBitmap() ){
cout << "Could not create bitmap" << endl;
error = true;
}
::blit( his, getData().getBitmap(), 0, 0, 0, 0, his->w, his->h );
own = new int;
*own = 1;
} else {
getData().setBitmap( who );
own = NULL;
}
}
Bitmap::Bitmap( const char * load_file ):
own( NULL ),
mustResize(false),
error( false ),
bit8MaskColor(0){
internalLoadFile( load_file );
/*
my_bitmap = load_bitmap( load_file, NULL );
if ( !my_bitmap ){
my_bitmap = create_bitmap( 100, 100 );
clear( my_bitmap );
cout<<"Could not load "<<load_file<<endl;
error = true;
}
own = true;
*/
}
Bitmap::Bitmap( const string & load_file ):
own( NULL ),
mustResize(false),
error( false ),
bit8MaskColor(0){
internalLoadFile( load_file.c_str() );
}
Bitmap::Bitmap( const char * load_file, int sx, int sy ):
own( NULL ),
mustResize(false),
error( false ),
bit8MaskColor(0){
path = load_file;
BITMAP * temp = load_bitmap( load_file, NULL );
// my_bitmap = load_bitmap( load_file, NULL );
getData().setBitmap( create_bitmap( sx, sy ) );
// clear( my_bitmap );
if ( !temp || ! getData().getBitmap() ){
cout<<"Could not load "<<load_file<<endl;
error = true;
} else {
clear();
stretch_blit( temp, getData().getBitmap(), 0, 0, temp->w, temp->h, 0, 0, getData().getBitmap()->w, getData().getBitmap()->h );
destroy_bitmap( temp );
}
// own = true;
own = new int;
*own = 1;
}
Bitmap::Bitmap( const char * load_file, int sx, int sy, double accuracy ):
own( NULL ),
mustResize(false),
error( false ),
bit8MaskColor(0){
path = load_file;
BITMAP * temp = load_bitmap( load_file, NULL );
own = new int;
*own = 1;
if ( !temp ){
cout<<"Could not load "<<load_file<<endl;
getData().setBitmap( create_bitmap( sx, sy ) );
// clear( my_bitmap );
clear();
error = true;
} else {
if ( temp->w > sx || temp->h > sy ){
double bx = temp->w / sx;
double by = temp->h / sy;
double use;
use = bx > by ? bx : by;
int fx = (int)(sx / use);
int fy = (int)(sy / use);
getData().setBitmap( create_bitmap( fx, fy ) );
stretch_blit( temp, getData().getBitmap(), 0, 0, temp->w, temp->h, 0, 0, getData().getBitmap()->w, getData().getBitmap()->h );
destroy_bitmap( temp );
} else getData().setBitmap( temp );
}
// own = true;
}
Bitmap::Bitmap( const Bitmap & copy, int sx, int sy ):
own( NULL ),
mustResize(false),
error( false ),
bit8MaskColor(copy.bit8MaskColor){
path = copy.getPath();
BITMAP * temp = copy.getData().getBitmap();
getData().setBitmap( create_bitmap( sx, sy ) );
if ( ! getData().getBitmap() ){
error = true;
cout << "Could not copy bitmap" << endl;
}
// clear( my_bitmap );
clear();
stretch_blit( temp, getData().getBitmap(), 0, 0, temp->w, temp->h, 0, 0, getData().getBitmap()->w, getData().getBitmap()->h );
// own = true;
// own = copy.own;
own = new int;
*own = 1;
}
Bitmap::Bitmap( const Bitmap & copy, int sx, int sy, double accuracy ):
own( NULL ),
mustResize(false),
error( false ),
bit8MaskColor(copy.bit8MaskColor){
path = copy.getPath();
BITMAP * temp = copy.getData().getBitmap();
own = new int;
*own = 1;
if ( temp->w > sx || temp->h > sy ){
double bx = (double)temp->w / (double)sx;
double by = (double)temp->h / (double)sy;
double use;
use = bx > by ? bx : by;
int fx = (int)(temp->w / use);
int fy = (int)(temp->h / use);
getData().setBitmap( create_bitmap( fx, fy ) );
if ( ! getData().getBitmap() ){
allegro_message("Could not create bitmap\n");
// own = false;
// own = copy.own;
// *own++;
error = true;
return;
}
stretch_blit( temp, getData().getBitmap(), 0, 0, temp->w, temp->h, 0, 0, getData().getBitmap()->w, getData().getBitmap()->h );
// destroy_bitmap( temp );
} else {
getData().setBitmap( create_bitmap( temp->w, temp->h ) );
blit( temp, getData().getBitmap(), 0, 0, 0, 0, temp->w, temp->h );
// own = new int
// own = true;
}
}
Bitmap::Bitmap( const Bitmap & copy, bool deep_copy ):
own( NULL ),
mustResize(false),
error( false ),
bit8MaskColor(copy.bit8MaskColor){
path = copy.getPath();
if ( deep_copy ){
BITMAP * his = copy.getData().getBitmap();
getData().setBitmap( create_bitmap( his->w, his->h ) );
if ( ! getData().getBitmap() ){
cout << "Could not create bitmap" << endl;
error = true;
}
::blit( his, getData().getBitmap(), 0, 0, 0, 0, his->w, his->h );
own = new int;
*own = 1;
} else {
getData().setBitmap( copy.getData().getBitmap() );
// own = false;
own = copy.own;
if ( own ){
*own = *own + 1;
}
}
/*
BITMAP * his = copy.getBitmap();
my_bitmap = create_bitmap( his->w, his->h );
::blit( his, my_bitmap, 0, 0, 0, 0, his->w, his->h );
own = true;
*/
}
Bitmap::Bitmap( const Bitmap & copy, int x, int y, int width, int height ):
own( NULL ),
mustResize(false),
error( false ),
bit8MaskColor(copy.bit8MaskColor){
path = copy.getPath();
BITMAP * his = copy.getData().getBitmap();
if ( x < 0 )
x = 0;
if ( y < 0 )
y = 0;
if ( width + x > his->w )
width = his->w - x;
if ( height + y > his->h )
height = his->h - y;
getData().setBitmap( create_sub_bitmap( his, x, y, width, height ) );
if ( ! getData().getBitmap() ){
cout<<"Could not create sub-bitmap"<<endl;
getData().setBitmap( create_bitmap( 10, 10 ) );
// clear( my_bitmap );
clear();
}
// own = true;
own = new int;
*own = 1;
}
void Bitmap::internalLoadFile( const char * load_file ){
path = load_file;
getData().setBitmap( load_bitmap( load_file, NULL ) );
if ( ! getData().getBitmap() ){
cout<<"Could not load "<<load_file<<". Using default"<<endl;
getData().setBitmap( create_bitmap( 10, 10 ) );
if ( ! getData().getBitmap() ){
cout<<"Out of memory or Allegro not initialized"<<endl;
error = true;
return;
}
// clear( my_bitmap );
clear();
// cout<<"Could not load "<<load_file<<endl;
error = true;
}
// own = true;
own = new int;
*own = 1;
}
void Bitmap::save( const string & str ) const {
save_bitmap( str.c_str(), getData().getBitmap(), NULL );
}
Bitmap Bitmap::memoryPCX(unsigned char * const data, const int length, const bool mask){
PACKFILE_VTABLE table = Memory::makeTable();
Memory::memory memory(data, length);
PACKFILE * pack = pack_fopen_vtable(&table, &memory);
/* need to supply a proper palette at some point */
RGB * palette = NULL;
BITMAP * pcx = load_pcx_pf(pack, palette);
if (!pcx){
pack_fclose(pack);
ostringstream out;
out <<"Could not load pcx from memory: " << (void*) data << " length " << length;
throw LoadException(__FILE__, __LINE__, out.str());
}
int colors = 256;
int maskR = (int)data[length - colors*3 + 0];
int maskG = (int)data[length - colors*3 + 1];
int maskB = (int)data[length - colors*3 + 2];
int maskColor = makeColor(maskR, maskG, maskB);
#if 0
/* converts 8-bit pcx mask to allegro's mask */
if (mask){
/* warning! 8-bit assumptions */
int colors = 256;
int maskR = (int)data[length - colors*3 + 0];
int maskG = (int)data[length - colors*3 + 1];
int maskB = (int)data[length - colors*3 + 2];
int mask = makeColor(maskR, maskG, maskB);
// printf("mask r %d g %d b %d = %d\n", maskR, maskG, maskB, mask);
if (mask != MaskColor()){
for( int i = 0; i < pcx->h; ++i ){
for( int j = 0; j < pcx->w; ++j ){
/* use getPixel/putPixel? */
int pix = getpixel(pcx,j,i);
if (pix == mask){
putpixel(pcx,j,i, MaskColor());
}
}
}
}
}
#endif
Bitmap bitmap(pcx, true);
bitmap.set8BitMaskColor(maskColor);
destroy_bitmap(pcx);
pack_fclose(pack);
return bitmap;
}
void Bitmap::initializeExtraStuff(){
/* nothing yet */
}
void Bitmap::destroyPrivateData(){
destroy_bitmap(getData().getBitmap());
}
int Bitmap::getWidth() const{
return getData().getBitmap()->w;
}
int Bitmap::getHeight() const{
return getData().getBitmap()->h;
}
int Bitmap::getRed( int x ){
return ::getr( x );
}
int Bitmap::getBlue( int x ){
return ::getb( x );
}
int Bitmap::getGreen( int x ){
return ::getg( x );
}
void Bitmap::setClipRect( int x1, int y1, int x2, int y2 ) const {
::set_clip_rect( getData().getBitmap(), x1, y1, x2, y2 );
}
void Bitmap::getClipRect(int & x1, int & y1, int & x2, int & y2) const {
::get_clip_rect(getData().getBitmap(), &x1, &y1, &x2, &y2);
}
/*
const string & Bitmap::getPath() const{
return path;
}
*/
void Bitmap::debugSelf() const{
cout<<"Bitmap: "<<endl;
cout<<"Self = "<< getData().getBitmap() <<endl;
cout<<"Own = "<< own <<" : "<< *own <<endl;
cout<<"Path = "<<path<<endl;
}
Bitmap & Bitmap::operator=( const Bitmap & copy ){
/*
if ( own ){
(*own)--;
if ( *own == 0 ){
destroy_bitmap( getBitmap() );
delete own;
}
}
*/
releaseInternalBitmap();
path = copy.getPath();
getData().setBitmap( copy.getData().getBitmap() );
// own = false;
own = copy.own;
if ( own )
*own += 1;
return *this;
}
/*
Bitmap::~Bitmap(){
releaseInternalBitmap();
}
*/
void Bitmap::detach(){
/*
if ( own ){
(*own)--;
if ( *own == 0 ){
destroy_bitmap( getBitmap() );
delete own;
}
}
*/
releaseInternalBitmap();
}
/*
BITMAP * Bitmap::getBitmap() const{
return my_bitmap;
}
*/
bool Bitmap::getError(){
return error;
}
/*
int Bitmap::getWidth(){
return my_bitmap->w;
}
int Bitmap::getHeight(){
return my_bitmap->h;
}
*/
void Bitmap::acquire(){
acquire_bitmap( getData().getBitmap() );
}
void Bitmap::release(){
release_bitmap( getData().getBitmap() );
}
void Bitmap::circleFill( int x, int y, int radius, int color ) const {
::circlefill( getData().getBitmap(), x, y, radius, color );
}
void TranslucentBitmap::circleFill(int x, int y, int radius, int color) const {
drawingMode(MODE_TRANS);
Bitmap::circleFill(x, y, radius, color);
drawingMode(MODE_SOLID);
}
void Bitmap::circle( int x, int y, int radius, int color ) const{
::circle( getData().getBitmap(), x, y, radius, color );
}
void Bitmap::line( const int x1, const int y1, const int x2, const int y2, const int color ) const{
::fastline( getData().getBitmap(), x1, y1, x2, y2, color );
}
void Bitmap::floodfill( const int x, const int y, const int color ) const {
::floodfill( getData().getBitmap(), x, y, color );
}
void Bitmap::drawCharacter( const int x, const int y, const int color, const int background, const Bitmap & where ) const {
::draw_character_ex( where.getData().getBitmap(), getData().getBitmap(), x, y, color, background );
}
void Bitmap::transBlender( int r, int g, int b, int a ){
set_trans_blender( r, g, b, a );
}
void Bitmap::multiplyBlender( int r, int g, int b, int a ){
set_multiply_blender( r, g, b, a );
}
void Bitmap::dissolveBlender( int r, int g, int b, int a ){
set_dissolve_blender( r, g, b, a );
}
void Bitmap::addBlender( int r, int g, int b, int a ){
set_add_blender( r, g, b, a );
}
void Bitmap::burnBlender( int r, int g, int b, int a ){
set_burn_blender( r, g, b, a );
}
void Bitmap::colorBlender( int r, int g, int b, int a ){
set_color_blender( r, g, b, a );
}
void Bitmap::differenceBlender( int r, int g, int b, int a ){
set_difference_blender( r, g, b, a );
}
void Bitmap::dodgeBlender( int r, int g, int b, int a ){
set_dodge_blender( r, g, b, a );
}
void Bitmap::hueBlender( int r, int g, int b, int a ){
set_hue_blender( r, g, b, a );
}
void Bitmap::luminanceBlender( int r, int g, int b, int a ){
set_luminance_blender( r, g, b, a );
}
void Bitmap::invertBlender( int r, int g, int b, int a ){
set_invert_blender( r, g, b, a );
}
void Bitmap::screenBlender( int r, int g, int b, int a ){
set_screen_blender( r, g, b, a );
}
void Bitmap::replaceColor(int original, int replaced){
int height = getHeight();
int width = getWidth();
BITMAP * bitmap = getData().getBitmap();
for (int i = 0; i < height; ++i ){
for( int j = 0; j < width; ++j ){
/* use getPixel/putPixel? */
int pix = getpixel(bitmap, j,i);
if (pix == original){
putpixel(bitmap, j, i, replaced);
}
}
}
}
void Bitmap::drawingMode( int mode ){
// drawing_mode( DRAW_MODE_TRANS, NULL, 0, 0 );
switch( mode ){
case MODE_TRANS : {
drawing_mode( DRAW_MODE_TRANS, NULL, 0, 0 );
break;
}
case MODE_SOLID : {
drawing_mode( DRAW_MODE_SOLID, NULL, 0, 0 );
break;
}
}
}
int Bitmap::setGraphicsMode( int mode, int width, int height ){
int ok = ::set_gfx_mode(mode, width, height, 0, 0);
if ( ok == 0 ){
if (SCALE_X == 0){
SCALE_X = width;
}
if (SCALE_Y == 0){
SCALE_Y = height;
}
if ( Screen != NULL ){
delete Screen;
Screen = NULL;
}
if ( Scaler != NULL ){
delete Scaler;
Scaler = NULL;
}
if ( Buffer != NULL ){
delete Buffer;
Buffer = NULL;
}
if (width != 0 && height != 0){
Screen = new Bitmap( ::screen );
Scaler = new Bitmap(width, height);
/*
if ( width != 0 && height != 0 && (width != SCALE_X || height != SCALE_Y) ){
Scaler = new Bitmap(width, height);
// Buffer = new Bitmap(SCALE_X, SCALE_Y);
}
*/
}
}
return ok;
}
void Bitmap::shutdown(){
delete Screen;
Screen = NULL;
delete Scaler;
Scaler = NULL;
delete Buffer;
Buffer = NULL;
}
/*
const int Bitmap::getWidth() const{
return getBitmap()->w;
}
const int Bitmap::getHeight() const{
return getBitmap()->h;
}
*/
int Bitmap::getPixel( const int x, const int y ) const{
if ( x >= 0 && x < getData().getBitmap()->w && y >= 0 && y < getData().getBitmap()->h )
return _getpixel16( getData().getBitmap(), x, y );
return -1;
}
void Bitmap::readLine( vector< int > & vec, int y ){
if ( y >= 0 && y < getData().getBitmap()->h ){
for ( int q = 0; q < getData().getBitmap()->w; q++ ){
// int col = my_bitmap->line[ y ][ q ];
int col = _getpixel16( getData().getBitmap(), q, y );
vec.push_back( col );
}
}
}
int Bitmap::setGfxModeText(){
return setGraphicsMode(GFX_TEXT, 0, 0);
}
int Bitmap::setGfxModeFullscreen(int x, int y){
return setGraphicsMode(GFX_AUTODETECT_FULLSCREEN, x, y);
}
int Bitmap::setGfxModeWindowed(int x, int y){
return setGraphicsMode(GFX_AUTODETECT_WINDOWED, x, y);
}
int Bitmap::makeColor( int r, int g, int b ){
return ::makecol16( r, g, b );
}
void Bitmap::hsvToRGB( float h, float s, float v, int * r, int * g, int * b ){
::hsv_to_rgb( h, s, v, r, g, b );
}
void Bitmap::rgbToHSV(int r, int g, int b, float * h, float * s, float * v){
::rgb_to_hsv(r, g, b, h, s, v);
}
int Bitmap::addColor( int color1, int color2 ){
return makeColor( getr( color1 ) + getr( color2 ),
getg( color1 ) + getg( color2 ),
getb( color1 ) + getb( color2 ) );
}
void Bitmap::putPixelNormal(int x, int y, int col) const {
BITMAP * dst = getData().getBitmap();
::putpixel(dst, x, y, col);
}
/* FIXME: its pretty slow to keep setting the drawing mode. Either
* 1) dont use translucent putpixel that much or
* 2) somehow cache the drawing mode so that its not reset every time
*/
void TranslucentBitmap::putPixelNormal(int x, int y, int color) const {
drawingMode(MODE_TRANS);
Bitmap::putPixelNormal(x, y, color);
drawingMode(MODE_SOLID);
}
void Bitmap::putPixel( int x, int y, int col ) const{
BITMAP * dst = getData().getBitmap();
if (dst->clip && ((x < dst->cl) || (x >= dst->cr) || (y < dst->ct) || (y >= dst->cb))){
return;
}
if ( x >= 0 && x < getData().getBitmap()->w && y >= 0 && y < getData().getBitmap()->h )
_putpixel16( getData().getBitmap(), x, y, col );
}
/*
void Bitmap::printf( int x, int y, int color, FONT * f, const char * str, ... ) const{
char buf[512];
va_list ap;
va_start(ap, str);
uvszprintf(buf, sizeof(buf), str, ap);
va_end(ap);
textout_ex( getBitmap(), f, buf, x, y, color, -1);
}
void Bitmap::printf( int x, int y, int color, const Font * const f, const char * str, ... ) const{
char buf[512];
va_list ap;
va_start(ap, str);
uvszprintf(buf, sizeof(buf), str, ap);
va_end(ap);
textout_ex( getBitmap(), f->getInternalFont(), buf, x, y, color, -1);
}
void Bitmap::printf( int x, int y, int color, const Font * const f, const string & str ) const{
printf( x, y, color, f, str.c_str() );
}
void Bitmap::printf( int x, int y, int color, const Font & f, const string & str ) const{
printf( x, y, color, &f, str );
}
void Bitmap::printfNormal( int x, int y, int color, const char * str, ... ) const{
char buf[512];
va_list ap;
va_start(ap, str);
uvszprintf(buf, sizeof(buf), str, ap);
va_end(ap);
textout_ex( getBitmap(), font, buf, x, y, color, -1);
}
void Bitmap::printfNormal( int x, int y, int color, const string & str ) const{
printfNormal( x, y, color, "%s", str.c_str() );
}
*/
void Bitmap::triangle( int x1, int y1, int x2, int y2, int x3, int y3, int color ) const{
::triangle( getData().getBitmap(), x1, y1, x2, y2, x3, y3, color );
}
void Bitmap::ellipse( int x, int y, int rx, int ry, int color ) const {
::ellipse( getData().getBitmap(), x, y, rx, ry, color );
}
void TranslucentBitmap::ellipse(int x, int y, int rx, int ry, int color) const {
drawingMode(MODE_TRANS);
Bitmap::ellipse(x, y, rx, ry, color);
drawingMode(MODE_SOLID);
}
void Bitmap::ellipseFill( int x, int y, int rx, int ry, int color ) const {
::ellipsefill( getData().getBitmap(), x, y, rx, ry, color );
}
void Bitmap::rectangle( int x1, int y1, int x2, int y2, int color ) const{
::rect( getData().getBitmap(), x1, y1, x2, y2, color );
}
void TranslucentBitmap::rectangle( int x1, int y1, int x2, int y2, int color ) const {
drawingMode(MODE_TRANS);
Bitmap::rectangle(x1, y1, x2, y2, color);
drawingMode(MODE_SOLID);
}
void Bitmap::rectangleFill( int x1, int y1, int x2, int y2, int color ) const{
::rectfill( getData().getBitmap(), x1, y1, x2, y2, color );
}
void TranslucentBitmap::rectangleFill( int x1, int y1, int x2, int y2, int color ) const{
drawingMode(MODE_TRANS);
Bitmap::rectangleFill(x1, y1, x2, y2, color);
drawingMode(MODE_SOLID);
}
/*
int Bitmap::getPixel( int x, int y ){
if ( x >= 0 && x < my_bitmap->w && y >= 0 && y <= my_bitmap->h )
return _getpixel16( my_bitmap, x, y );
return -1;
}
*/
/*
int Bitmap::makeColor( int r, int g, int b ){
return makecol16( r, g, b );
}
*/
void Bitmap::hLine( const int x1, const int y, const int x2, const int color ) const{
::hline( getData().getBitmap(), x1, y, x2, color );
}
void TranslucentBitmap::hLine( const int x1, const int y, const int x2, const int color ) const{
drawingMode(MODE_TRANS);
::hline(getData().getBitmap(), x1, y, x2, color);
drawingMode(MODE_SOLID);
}
void Bitmap::vLine( const int y1, const int x, const int y2, const int color ) const{
::vline( getData().getBitmap(), x, y1, y2, color );
}
void Bitmap::polygon( const int * verts, const int nverts, const int color ) const{
::polygon( getData().getBitmap(), nverts, verts, color );
}
void Bitmap::arc(const int x, const int y, const double ang1, const double ang2, const int radius, const int color ) const{
::arc( getData().getBitmap(), x, y, ::ftofix(ang1), ::ftofix(ang2), radius, color );
}
/*
void Bitmap::clear(){
this->fill( 0 );
}
*/
void Bitmap::fill( int color ) const{
::clear_to_color( getData().getBitmap(), color );
}
/*
void TranslucentBitmap::fill(int color) const {
rectangleFill(0, 0, getWidth(), getHeight(), color);
}
*/
void Bitmap::draw( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_NO_FLIP, NULL);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_NORMAL, SPRITE_NO_FLIP, NULL);
// ::draw_sprite( where.getData().getBitmap(), getBitmap(), x, y );
}
void Bitmap::draw(const int x, const int y, Filter * filter, const Bitmap & where) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_NO_FLIP, filter);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_NORMAL, SPRITE_NO_FLIP, filter);
}
void Bitmap::drawHFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_H_FLIP, NULL);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_NORMAL, SPRITE_H_FLIP, NULL);
// ::draw_sprite_h_flip( where.getBitmap(), getBitmap(), x, y );
}
void Bitmap::drawHFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_H_FLIP, filter);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_NORMAL, SPRITE_H_FLIP, filter);
// ::draw_sprite_h_flip( where.getBitmap(), getBitmap(), x, y );
}
void Bitmap::drawVFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_V_FLIP, NULL);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_NORMAL, SPRITE_V_FLIP, NULL);
}
void Bitmap::drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_V_FLIP, filter);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_NORMAL, SPRITE_V_FLIP, filter);
}
void Bitmap::drawHVFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_V_FLIP | Bitmap::SPRITE_H_FLIP, NULL);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_NORMAL, SPRITE_V_FLIP | SPRITE_H_FLIP, NULL);
}
void Bitmap::drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_V_FLIP | Bitmap::SPRITE_H_FLIP, filter);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_NORMAL, SPRITE_V_FLIP | SPRITE_H_FLIP, filter);
}
/*
void Bitmap::drawLit( const int x, const int y, const int level, const Bitmap & where ) const{
::draw_lit_sprite( where.getBitmap(), getBitmap(), x, y, level );
}
*/
void TranslucentBitmap::draw( const int x, const int y, const Bitmap & where ) const{
// ::draw_trans_sprite( where.getBitmap(), getBitmap(), x, y );
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_NO_FLIP, NULL);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_TRANS, SPRITE_NO_FLIP, NULL);
}
void TranslucentBitmap::draw( const int x, const int y, Filter * filter, const Bitmap & where ) const{
// ::draw_trans_sprite( where.getBitmap(), getBitmap(), x, y );
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_NO_FLIP, filter);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_TRANS, SPRITE_NO_FLIP, filter);
}
void TranslucentBitmap::drawHFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_H_FLIP, NULL);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_TRANS, SPRITE_H_FLIP, NULL);
}
void TranslucentBitmap::drawHFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_H_FLIP, filter);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_TRANS, SPRITE_H_FLIP, filter);
}
void TranslucentBitmap::drawVFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_V_FLIP, NULL);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_TRANS, SPRITE_V_FLIP, NULL);
}
void TranslucentBitmap::drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_V_FLIP, filter);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_TRANS, SPRITE_V_FLIP, filter);
}
void TranslucentBitmap::drawHVFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_V_FLIP | Bitmap::SPRITE_H_FLIP, NULL);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_TRANS, SPRITE_V_FLIP | SPRITE_H_FLIP, NULL);
}
void TranslucentBitmap::drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_V_FLIP | Bitmap::SPRITE_H_FLIP, filter);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_TRANS, SPRITE_V_FLIP | SPRITE_H_FLIP, filter);
}
void Bitmap::drawRotate( const int x, const int y, const int angle, const Bitmap & where ){
::fixed fang = itofix( (360 - angle) % 360 * 256 / 360 );
::rotate_sprite( where.getData().getBitmap(), getData().getBitmap(), x, y, fang );
}
void Bitmap::drawPivot( const int centerX, const int centerY, const int x, const int y, const int angle, const Bitmap & where ){
::fixed fang = ftofix( (double)((360 - angle) % 360) * 256.0 / 360.0 );
::pivot_sprite( where.getData().getBitmap(), getData().getBitmap(), x, y, centerX, centerY, fang );
}
void Bitmap::drawPivot( const int centerX, const int centerY, const int x, const int y, const int angle, const double scale, const Bitmap & where ){
::fixed fscale = ftofix(scale);
::fixed fang = ftofix( (double)((360 - angle) % 360) * 256.0 / 360.0 );
::pivot_scaled_sprite( where.getData().getBitmap(), getData().getBitmap(), x, y, centerX, centerY, fang, fscale );
}
void Bitmap::drawStretched( const int x, const int y, const int new_width, const int new_height, const Bitmap & who ) const {
BITMAP * bmp = who.getData().getBitmap();
::masked_stretch_blit( getData().getBitmap(), bmp, 0, 0, getData().getBitmap()->w, getData().getBitmap()->h, x,y, new_width, new_height );
}
void Bitmap::light(int x, int y, int width, int height, int start_y, int focus_alpha, int edge_alpha, int focus_color, int edge_color) const {
paintown_light16(getData().getBitmap(), x, y, width, height, start_y, focus_alpha, edge_alpha, focus_color, edge_color);
}
void Bitmap::applyTrans(const int color) const {
paintown_applyTrans16(getData().getBitmap(), color);
}
void Bitmap::StretchBy2( const Bitmap & where ){
BITMAP * bmp = where.getData().getBitmap();
if ( where.getWidth() == getWidth() && where.getHeight() == getHeight() ){
::blit( getData().getBitmap(), bmp, 0, 0, 0, 0, getData().getBitmap()->w, getData().getBitmap()->h );
return;
}
if ( where.getWidth() != getWidth()*2 ||
where.getHeight() != getHeight()*2 ){
cout<<"Wrong dimensions"<<endl;
cout<<"My: "<< getWidth() << " " << getHeight() << endl;
cout<<"Him: "<<where.getWidth()<< " " << where.getHeight()<<endl;
return;
}
// debug
::stretch_blit( getData().getBitmap(), bmp, 0, 0, getData().getBitmap()->w, getData().getBitmap()->h, 0, 0, bmp->w, bmp->h );
// fblend_2x_stretch( my_bitmap, bmp, 0, 0, 0, 0, my_bitmap->w, my_bitmap->h);
// scale2x_allegro( my_bitmap, bmp, 2 );
// debug
}
void Bitmap::StretchBy4( const Bitmap & where ){
BITMAP * bmp = where.getData().getBitmap();
if ( where.getWidth() != getWidth()*4 ||
where.getHeight() != getHeight()*4 ){
cout<<"Wrong dimensions"<<endl;
cout<<"My: "<< getWidth() << " " << getHeight() << endl;
cout<<"Him: "<<where.getWidth()<< " " << where.getHeight()<<endl;
cout<<"Scaled: "<<getWidth()*4<<" "<< getHeight()*4<<endl;
return;
}
// fblend_2x_stretch( my_bitmap, bmp, 0, 0, 0, 0, my_bitmap->w, my_bitmap->h);
// scale4x_allegro( my_bitmap, bmp, 2 );
::stretch_blit( getData().getBitmap(), bmp, 0, 0, getData().getBitmap()->w, getData().getBitmap()->h, 0, 0, bmp->w, bmp->h );
}
#if 0
void Bitmap::Stretch( const Bitmap & where ) const {
Stretch( where, 0, 0, getData().getBitmap()->w, getData().getBitmap()->h, 0, 0, where.getData().getBitmap()->w, where.getData().getBitmap()->h );
/*
BITMAP * bmp = where.getBitmap();
::stretch_blit( getBitmap(), bmp, 0, 0, getBitmap()->w, getBitmap()->h, 0, 0, bmp->w, bmp->h );
*/
}
#endif
void Bitmap::Stretch( const Bitmap & where, const int sourceX, const int sourceY, const int sourceWidth, const int sourceHeight, const int destX, const int destY, const int destWidth, const int destHeight ) const {
BITMAP * bmp = where.getData().getBitmap();
::stretch_blit( getData().getBitmap(), bmp, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight );
}
#if 0
void Bitmap::Blit( const int x, const int y, const Bitmap & where ) const {
BITMAP * bmp = where.getData().getBitmap();
/*
acquire_bitmap( bmp );
acquire_bitmap( my_bitmap );
*/
::blit( getData().getBitmap(), bmp, 0, 0, x, y, getData().getBitmap()->w, getData().getBitmap()->h );
/*
release_bitmap( my_bitmap );
release_bitmap( bmp );
*/
}
#endif
/*
void Bitmap::Blit( const int mx, const int my, const int wx, const int wy, const Bitmap & where ) const {
BITMAP * bmp = where.getData().getBitmap();
::blit( getData().getBitmap(), bmp, mx, my, wx, wy, getData().getBitmap()->w, getData().getBitmap()->h );
}
*/
void Bitmap::Blit( const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where ) const {
BITMAP * bmp = where.getData().getBitmap();
::blit( getData().getBitmap(), bmp, mx, my, wx, wy, width, height );
}
void Bitmap::BlitMasked( const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where ) const {
BITMAP * bmp = where.getData().getBitmap();
::masked_blit( getData().getBitmap(), bmp, mx, my, wx, wy, width, height );
}
void Bitmap::BlitToScreen(const int upper_left_x, const int upper_left_y) const {
if ( Scaler == NULL ){
this->Blit( upper_left_x, upper_left_y, *Bitmap::Screen );
} else {
if (upper_left_x != 0 || upper_left_y != 0){
Bitmap buffer = temporaryBitmap(getWidth(), getHeight());
buffer.clear();
this->Blit(upper_left_x, upper_left_y, buffer);
buffer.Stretch(*Scaler);
} else {
this->Stretch(*Scaler);
}
Scaler->Blit( 0, 0, 0, 0, *Screen );
}
}
void Bitmap::BlitAreaToScreen(const int upper_left_x, const int upper_left_y) const {
if ( Scaler != NULL ){
double mult_x = (double) Scaler->getWidth() / (double) SCALE_X;
double mult_y = (double) Scaler->getHeight() / (double) SCALE_Y;
int x = (int)(upper_left_x * mult_x);
int y = (int)(upper_left_y * mult_y);
int w = (int)(this->getWidth() * mult_x);
int h = (int)(this->getHeight() * mult_y);
// printf("ux %d uy %d uw %d uh %d. x %d y %d w %d h %d\n", upper_left_x, upper_left_y, getWidth(), getHeight(), x, y, w, h );
this->Stretch( *Scaler, 0, 0, this->getWidth(), this->getHeight(), x, y, w, h );
Bitmap tmp(*Scaler, x, y, w, h );
tmp.Blit( x, y, *Screen );
// Scaler->Blit( x, y, w, h, *Screen );
} else {
this->Blit( upper_left_x, upper_left_y, *Screen );
}
}
void LitBitmap::draw( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_NO_FLIP, NULL);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_LIT, SPRITE_NO_FLIP, NULL);
}
void LitBitmap::draw( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_NO_FLIP, filter);
+ paintown_draw_sprite_ex16( where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_LIT, SPRITE_NO_FLIP, filter);
}
void LitBitmap::drawHFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_H_FLIP, NULL);
+ paintown_draw_sprite_ex16(where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_LIT, SPRITE_H_FLIP, NULL);
}
void LitBitmap::drawHFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_H_FLIP, filter);
+ paintown_draw_sprite_ex16(where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_LIT, SPRITE_H_FLIP, filter);
}
void LitBitmap::drawVFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_V_FLIP, NULL);
+ paintown_draw_sprite_ex16(where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_LIT, SPRITE_V_FLIP, NULL);
}
void LitBitmap::drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_V_FLIP, filter);
+ paintown_draw_sprite_ex16(where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_LIT, SPRITE_V_FLIP, filter);
}
void LitBitmap::drawHVFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_V_FLIP | Bitmap::SPRITE_H_FLIP, NULL);
+ paintown_draw_sprite_ex16(where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_LIT, SPRITE_V_FLIP | SPRITE_H_FLIP, NULL);
}
void LitBitmap::drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getBitmap(), getData().getBitmap(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_V_FLIP | Bitmap::SPRITE_H_FLIP, filter);
+ paintown_draw_sprite_ex16(where.getData().getBitmap(), getData().getBitmap(), x, y, SPRITE_LIT, SPRITE_V_FLIP | SPRITE_H_FLIP, filter);
}
/* this function should be in allegro but its not yet so just store it
* here for now
*/
#define PAINTOWN_DLS_BLENDER BLENDER_FUNC
#define PAINTOWN_DTS_BLENDER BLENDER_FUNC
#define PAINTOWN_MAKE_DLS_BLENDER(a) _blender_func16
#define PAINTOWN_MAKE_DTS_BLENDER() _blender_func16
#define PAINTOWN_PIXEL_PTR unsigned short*
#define PAINTOWN_OFFSET_PIXEL_PTR(p,x) ((PAINTOWN_PIXEL_PTR) (p) + (x))
#define PAINTOWN_INC_PIXEL_PTR(p) ((p)++)
#define PAINTOWN_INC_PIXEL_PTR_EX(p,d) ((p) += d)
#define PAINTOWN_GET_MEMORY_PIXEL(p) (*(p))
#define PAINTOWN_IS_SPRITE_MASK(b,c) ((unsigned long) (c) == (unsigned long) (b)->vtable->mask_color)
#define PAINTOWN_DLSX_BLEND(b,n) ((*(b))(_blender_col_16, (n), _blender_alpha))
#define PAINTOWN_GET_PIXEL(p) bmp_read16((uintptr_t) (p))
-#define PAINTOWN_DTS_BLEND(b,o,n) ((*(b))((n), (o), _blender_alpha))
+#define PAINTOWN_DTS_BLEND(b,o,n) ((*(b))((n), (o), ::_blender_alpha))
#define PAINTOWN_PUT_PIXEL(p,c) bmp_write16((uintptr_t) (p), (c))
#define PAINTOWN_PUT_MEMORY_PIXEL(p,c) (*(p) = (c))
#define PAINTOWN_SET_ALPHA(a) (_blender_alpha = (a))
-/* defined at allegro/include/internal/aintern.h:457 */
-extern EXTERNAL_VARIABLE BLENDER_FUNC _blender_func16;
-/* defined at allegro/include/internal/aintern.h:466 */
-extern EXTERNAL_VARIABLE int _blender_col_16;
-/* defined at allegro/include/internal/aintern.h:470 */
-extern EXTERNAL_VARIABLE int _blender_alpha;
-
static void paintown_draw_sprite_ex16( BITMAP * dst, BITMAP * src, int dx, int dy, int mode, int flip, Bitmap::Filter * filter ){
int x, y, w, h;
int x_dir = 1, y_dir = 1;
int dxbeg, dybeg;
int sxbeg, sybeg;
PAINTOWN_DLS_BLENDER lit_blender;
PAINTOWN_DTS_BLENDER trans_blender;
ASSERT(dst);
ASSERT(src);
- if ( flip & Bitmap::SPRITE_V_FLIP ){
+ if ( flip & SPRITE_V_FLIP ){
y_dir = -1;
}
- if ( flip & Bitmap::SPRITE_H_FLIP ){
+ if ( flip & SPRITE_H_FLIP ){
x_dir = -1;
}
if (dst->clip) {
int tmp;
tmp = dst->cl - dx;
sxbeg = ((tmp < 0) ? 0 : tmp);
dxbeg = sxbeg + dx;
tmp = dst->cr - dx;
w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
if (w <= 0)
return;
- if ( flip & Bitmap::SPRITE_H_FLIP ){
+ if ( flip & SPRITE_H_FLIP ){
/* use backward drawing onto dst */
sxbeg = src->w - (sxbeg + w);
dxbeg += w - 1;
}
tmp = dst->ct - dy;
sybeg = ((tmp < 0) ? 0 : tmp);
dybeg = sybeg + dy;
tmp = dst->cb - dy;
h = ((tmp > src->h) ? src->h : tmp) - sybeg;
if (h <= 0)
return;
- if ( flip & Bitmap::SPRITE_V_FLIP ){
+ if ( flip & SPRITE_V_FLIP ){
/* use backward drawing onto dst */
sybeg = src->h - (sybeg + h);
dybeg += h - 1;
}
} else {
w = src->w;
h = src->h;
sxbeg = 0;
sybeg = 0;
dxbeg = dx;
- if ( flip & Bitmap::SPRITE_H_FLIP ){
+ if ( flip & SPRITE_H_FLIP ){
dxbeg = dx + w - 1;
}
dybeg = dy;
- if ( flip & Bitmap::SPRITE_V_FLIP ){
+ if ( flip & SPRITE_V_FLIP ){
dybeg = dy + h - 1;
}
}
lit_blender = PAINTOWN_MAKE_DLS_BLENDER(0);
trans_blender = PAINTOWN_MAKE_DTS_BLENDER();
if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
bmp_select(dst);
#if 0
switch (mode){
case Bitmap::SPRITE_NORMAL : {
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
PAINTOWN_PUT_PIXEL(d, c);
}
}
}
break;
}
case Bitmap::SPRITE_LIT : {
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
c = PAINTOWN_DLSX_BLEND(lit_blender, c);
PAINTOWN_PUT_PIXEL(d, c);
}
}
}
break;
}
case Bitmap::SPRITE_TRANS : {
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
c = PAINTOWN_DTS_BLEND(trans_blender, PAINTOWN_GET_PIXEL(d), c);
PAINTOWN_PUT_PIXEL(d, c);
}
}
}
break;
}
}
#endif
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
/* flipped if y_dir is -1 */
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
/* d is incremented by x_dir, -1 if flipped */
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
switch (mode){
- case Bitmap::SPRITE_NORMAL: {
+ case SPRITE_NORMAL: {
if (filter){
c = filter->filter(c);
}
break;
}
- case Bitmap::SPRITE_LIT : {
+ case SPRITE_LIT : {
if (filter){
c = PAINTOWN_DLSX_BLEND(lit_blender, filter->filter(c));
} else {
c = PAINTOWN_DLSX_BLEND(lit_blender, c);
}
break;
}
- case Bitmap::SPRITE_TRANS : {
+ case SPRITE_TRANS : {
if (filter){
c = PAINTOWN_DTS_BLEND(trans_blender, PAINTOWN_GET_PIXEL(d), filter->filter(c));
} else {
c = PAINTOWN_DTS_BLEND(trans_blender, PAINTOWN_GET_PIXEL(d), c);
}
break;
}
}
PAINTOWN_PUT_PIXEL(d, c);
}
}
}
bmp_unwrite_line(dst);
} else {
switch (mode){
- case Bitmap::SPRITE_NORMAL : {
+ case SPRITE_NORMAL : {
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
if (filter){
PAINTOWN_PUT_MEMORY_PIXEL(d, filter->filter(c));
} else {
PAINTOWN_PUT_MEMORY_PIXEL(d, c);
}
}
}
}
break;
}
- case Bitmap::SPRITE_LIT : {
+ case SPRITE_LIT : {
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
if (filter){
c = PAINTOWN_DLSX_BLEND(lit_blender, filter->filter(c));
} else {
c = PAINTOWN_DLSX_BLEND(lit_blender, c);
}
PAINTOWN_PUT_MEMORY_PIXEL(d, c);
}
}
}
break;
}
- case Bitmap::SPRITE_TRANS : {
+ case SPRITE_TRANS : {
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
if (filter){
c = PAINTOWN_DTS_BLEND(trans_blender, PAINTOWN_GET_PIXEL(d), filter->filter(c));
} else {
c = PAINTOWN_DTS_BLEND(trans_blender, PAINTOWN_GET_PIXEL(d), c);
}
PAINTOWN_PUT_MEMORY_PIXEL(d, c);
}
}
}
break;
}
}
#if 0
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
switch( mode ){
case Bitmap::SPRITE_NORMAL : break;
case Bitmap::SPRITE_LIT : {
c = PAINTOWN_DLSX_BLEND(lit_blender, c);
break;
}
case Bitmap::SPRITE_TRANS : {
c = PAINTOWN_DTS_BLEND(trans_blender, PAINTOWN_GET_PIXEL(d), c);
break;
}
}
PAINTOWN_PUT_MEMORY_PIXEL(d, c);
}
}
}
#endif
}
}
/* mix pixels with the given color in with each non-masking pixel in dst */
static void paintown_applyTrans16(BITMAP * dst, const int color){
int y1 = 0;
int y2 = dst->h;
int x1 = 0;
int x2 = dst->w - 1;
if (dst->clip){
y1 = dst->ct;
y2 = dst->cb - 1;
x1 = dst->cl;
x2 = dst->cr - 1;
}
PAINTOWN_DTS_BLENDER trans_blender;
trans_blender = PAINTOWN_MAKE_DTS_BLENDER();
if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
} else {
for (int y = y1; y < y2; y++) {
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, y), x1);
for (int x = x2; x >= x1; PAINTOWN_INC_PIXEL_PTR_EX(d,1), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(d);
if (!PAINTOWN_IS_SPRITE_MASK(dst, c)) {
c = PAINTOWN_DTS_BLEND(trans_blender, c, color);
PAINTOWN_PUT_MEMORY_PIXEL(d, c);
}
}
}
}
}
/* ultra special-case for drawing a light (like from a lamp).
* center of light is x,y and shines in a perfect isosolese triangle.
*/
static void paintown_light16(BITMAP * dst, const int x, const int y, const int width, const int height, const int start_y, const int focus_alpha, const int edge_alpha, const int focus_color, const int edge_color){
int dxbeg = x - width;
int x_dir = 1;
unsigned char * alphas = new unsigned char[width];
int * colors = new int[width];
for (int i = 0; i < width; i++){
alphas[i] = (unsigned char)((double)(edge_alpha - focus_alpha) * (double)i / (double)width + focus_alpha);
}
Util::blend_palette(colors, width, focus_color, edge_color);
int min_y, max_y, min_x, max_x;
if (dst->clip){
min_y = dst->ct;
max_y = dst->cb - 1;
min_x = dst->cl;
max_x = dst->cr - 1;
} else {
min_y = y < 0 ? 0 : y;
max_y = dst->h - 1;
min_x = (x-width) < 0 ? 0 : x-width;
max_x = (x+width) > dst->w-1 ? dst->w-1 : x+width;
}
int dybeg = y;
/* tan(theta) = y / x */
double xtan = (double) height / (double) width;
PAINTOWN_DTS_BLENDER trans_blender;
trans_blender = PAINTOWN_MAKE_DTS_BLENDER();
if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
} else {
for (int sy = start_y; sy < height; sy++) {
if (dybeg + sy < min_y || dybeg + sy > max_y){
continue;
}
/* x = y / tan(theta) */
int top_width = (int)((double) sy / xtan);
if (top_width == 0){
continue;
}
dxbeg = x - top_width;
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + sy), dxbeg);
for (int sx = -top_width; sx <= top_width; PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), sx++) {
if (sx + x < min_x || sx + x > max_x){
continue;
}
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(d);
/* TODO:
* converting to a double and calling fabs is overkill, just
* write an integer abs() function.
*/
int sx_abs = (int) fabs((double) sx);
PAINTOWN_SET_ALPHA(alphas[sx_abs]);
int color = colors[sx_abs];
c = PAINTOWN_DTS_BLEND(trans_blender, c, color);
PAINTOWN_PUT_MEMORY_PIXEL(d, c);
}
}
}
delete[] alphas;
delete[] colors;
}
/* there is a bug in this function that causes memory corruption. if that bug
* is ever found then use this method, otherwise don't use it.
*/
static void paintown_draw_sprite_ex16_old( BITMAP * dst, BITMAP * src, int dx, int dy, int mode, int flip, Bitmap::Filter * filter){
int x, y, w, h;
int x_dir = 1, y_dir = 1;
int dxbeg, dybeg;
int sxbeg, sybeg;
PAINTOWN_DLS_BLENDER lit_blender;
PAINTOWN_DTS_BLENDER trans_blender;
ASSERT(dst);
ASSERT(src);
- if ( flip & Bitmap::SPRITE_V_FLIP ){
+ if ( flip & SPRITE_V_FLIP ){
y_dir = -1;
}
- if ( flip & Bitmap::SPRITE_H_FLIP ){
+ if ( flip & SPRITE_H_FLIP ){
x_dir = -1;
}
if (dst->clip) {
int tmp;
tmp = dst->cl - dx;
sxbeg = ((tmp < 0) ? 0 : tmp);
dxbeg = sxbeg + dx;
tmp = dst->cr - dx;
w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
if (w <= 0)
return;
- if ( flip & Bitmap::SPRITE_H_FLIP ){
+ if ( flip & SPRITE_H_FLIP ){
/* use backward drawing onto dst */
sxbeg = src->w - (sxbeg + w);
dxbeg += w - 1;
}
tmp = dst->ct - dy;
sybeg = ((tmp < 0) ? 0 : tmp);
dybeg = sybeg + dy;
tmp = dst->cb - dy;
h = ((tmp > src->h) ? src->h : tmp) - sybeg;
if (h <= 0)
return;
- if ( flip & Bitmap::SPRITE_V_FLIP ){
+ if ( flip & SPRITE_V_FLIP ){
/* use backward drawing onto dst */
sybeg = src->h - (sybeg + h);
dybeg += h - 1;
}
} else {
w = src->w;
h = src->h;
sxbeg = 0;
sybeg = 0;
dxbeg = dx;
- if ( flip & Bitmap::SPRITE_H_FLIP ){
+ if ( flip & SPRITE_H_FLIP ){
dxbeg = dx + w - 1;
}
dybeg = dy;
- if ( flip & Bitmap::SPRITE_V_FLIP ){
+ if ( flip & SPRITE_V_FLIP ){
dybeg = dy + h - 1;
}
}
lit_blender = PAINTOWN_MAKE_DLS_BLENDER(0);
trans_blender = PAINTOWN_MAKE_DTS_BLENDER();
if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
bmp_select(dst);
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
/* flipped if y_dir is -1 */
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
/* d is incremented by x_dir, -1 if flipped */
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
switch( mode ){
- case Bitmap::SPRITE_NORMAL : break;
- case Bitmap::SPRITE_LIT : {
+ case SPRITE_NORMAL : break;
+ case SPRITE_LIT : {
if (filter){
c = PAINTOWN_DLSX_BLEND(lit_blender, filter->filter(c));
} else {
c = PAINTOWN_DLSX_BLEND(lit_blender, c);
}
break;
}
- case Bitmap::SPRITE_TRANS : {
+ case SPRITE_TRANS : {
if (filter){
c = PAINTOWN_DTS_BLEND(trans_blender, PAINTOWN_GET_PIXEL(d), filter->filter(c));
} else {
c = PAINTOWN_DTS_BLEND(trans_blender, PAINTOWN_GET_PIXEL(d), c);
}
break;
}
}
PAINTOWN_PUT_PIXEL(d, c);
}
}
}
bmp_unwrite_line(dst);
}
else {
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
switch( mode ){
- case Bitmap::SPRITE_NORMAL : break;
- case Bitmap::SPRITE_LIT : {
+ case SPRITE_NORMAL : break;
+ case SPRITE_LIT : {
if (filter){
c = PAINTOWN_DLSX_BLEND(lit_blender, filter->filter(c));
} else {
c = PAINTOWN_DLSX_BLEND(lit_blender, c);
}
break;
}
- case Bitmap::SPRITE_TRANS : {
+ case SPRITE_TRANS : {
if (filter){
c = PAINTOWN_DTS_BLEND(trans_blender, PAINTOWN_GET_PIXEL(d), filter->filter(c));
} else {
c = PAINTOWN_DTS_BLEND(trans_blender, PAINTOWN_GET_PIXEL(d), c);
}
break;
}
}
PAINTOWN_PUT_MEMORY_PIXEL(d, c);
}
}
}
}
}
static void paintown_draw_sprite_filter_ex16(BITMAP * dst, BITMAP * src, int dx, int dy, const Bitmap::Filter & filter){
int x, y, w, h;
int x_dir = 1, y_dir = 1;
int dxbeg, dybeg;
int sxbeg, sybeg;
if (true /* dst->clip*/ ) {
int tmp;
tmp = dst->cl - dx;
sxbeg = ((tmp < 0) ? 0 : tmp);
dxbeg = sxbeg + dx;
tmp = dst->cr - dx;
w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
if (w <= 0)
return;
tmp = dst->ct - dy;
sybeg = ((tmp < 0) ? 0 : tmp);
dybeg = sybeg + dy;
tmp = dst->cb - dy;
h = ((tmp > src->h) ? src->h : tmp) - sybeg;
if (h <= 0)
return;
}
unsigned int mask = Bitmap::makeColor(255, 0, 255);
// int bpp = src->format->BytesPerPixel;
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
PAINTOWN_PUT_MEMORY_PIXEL(d, filter.filter(c));
} else {
PAINTOWN_PUT_MEMORY_PIXEL(d, mask);
}
}
}
}
+
+}
diff --git a/util/allegro5/bitmap.cpp b/util/allegro5/bitmap.cpp
index 9ac1604f..bb40463d 100644
--- a/util/allegro5/bitmap.cpp
+++ b/util/allegro5/bitmap.cpp
@@ -1,673 +1,677 @@
#include <sstream>
#include <allegro5/allegro_memfile.h>
#include "util/debug.h"
+namespace Graphics{
+
static const int rgb_r_shift_16 = 0;
static const int rgb_g_shift_16 = 5;
static const int rgb_b_shift_16 = 11;
static inline int pack565(unsigned char red, unsigned char green, unsigned char blue){
return (((red >> 3) << rgb_r_shift_16) |
((green >> 2) << rgb_g_shift_16) |
((blue >> 3) << rgb_b_shift_16));
}
/* from allegro4 */
static inline void unpack565(int color, unsigned char * red, unsigned char * green, unsigned char * blue){
static int _rgb_scale_5[32] = {
0, 8, 16, 24, 33, 41, 49, 57,
66, 74, 82, 90, 99, 107, 115, 123,
132, 140, 148, 156, 165, 173, 181, 189,
198, 206, 214, 222, 231, 239, 247, 255
};
static int _rgb_scale_6[64] = {
0, 4, 8, 12, 16, 20, 24, 28,
32, 36, 40, 44, 48, 52, 56, 60,
65, 69, 73, 77, 81, 85, 89, 93,
97, 101, 105, 109, 113, 117, 121, 125,
130, 134, 138, 142, 146, 150, 154, 158,
162, 166, 170, 174, 178, 182, 186, 190,
195, 199, 203, 207, 211, 215, 219, 223,
227, 231, 235, 239, 243, 247, 251, 255
};
*red = _rgb_scale_5[(color >> rgb_r_shift_16) & 0x1F];
*green = _rgb_scale_6[(color >> rgb_g_shift_16) & 0x3F];
*blue = _rgb_scale_5[(color >> rgb_b_shift_16) & 0x1F];
}
int Bitmap::MaskColor(){
static int mask = makeColor(255, 0, 255);
return mask;
}
static const int WINDOWED = 0;
static const int FULLSCREEN = 1;
Bitmap * Bitmap::Screen = NULL;
static Bitmap * Scaler = NULL;
Bitmap::Bitmap():
own(NULL),
mustResize(false),
bit8MaskColor(0){
/* TODO */
}
Bitmap::Bitmap( const char * load_file ):
own(NULL),
mustResize(false),
bit8MaskColor(0){
internalLoadFile(load_file);
}
Bitmap::Bitmap( const std::string & load_file ):
own(NULL),
mustResize(false){
internalLoadFile(load_file.c_str());
}
Bitmap::Bitmap(ALLEGRO_BITMAP * who, bool deep_copy):
own(NULL),
mustResize(false),
bit8MaskColor(0){
if (deep_copy){
ALLEGRO_BITMAP * clone = al_clone_bitmap(who);
getData().setBitmap(clone);
own = new int;
*own = 1;
} else {
getData().setBitmap(who);
}
}
Bitmap::Bitmap(int width, int height):
own(NULL),
mustResize(false),
bit8MaskColor(0){
ALLEGRO_BITMAP * bitmap = al_create_bitmap(width, height);
if (bitmap == NULL){
std::ostringstream out;
out << "Could not create bitmap with dimensions " << width << ", " << height;
throw BitmapException(__FILE__, __LINE__, out.str());
}
getData().setBitmap(bitmap);
own = new int;
*own = 1;
}
Bitmap::Bitmap( const Bitmap & copy, bool deep_copy):
own(NULL),
mustResize(false),
bit8MaskColor(copy.bit8MaskColor){
if (deep_copy){
ALLEGRO_BITMAP * clone = al_clone_bitmap(copy.getData().getBitmap());
getData().setBitmap(clone);
own = new int;
*own = 1;
} else {
getData().setBitmap(copy.getData().getBitmap());
own = copy.own;
if (own){
*own += 1;
}
}
}
enum Format{
PNG,
GIF,
};
Bitmap Bitmap::memoryPCX(unsigned char * const data, const int length, const bool mask){
/* TODO */
return Bitmap();
}
void Bitmap::replaceColor(int original, int replaced){
/* TODO */
}
static ALLEGRO_BITMAP * memoryGIF(const char * data, int length){
ALLEGRO_FILE * memory = al_open_memfile((void *) data, length, "r");
al_fclose(memory);
/* FIXME: get gif addon for a5 */
#if 0
RGB * palette = NULL;
/* algif will close the packfile for us in both error and success cases */
BITMAP * gif = load_gif_packfile(pack, palette);
if (!gif){
al_fclose(memory);
// pack_fclose(pack);
ostringstream out;
out <<"Could not load gif from memory: " << (void*) data << " length " << length;
throw LoadException(__FILE__, __LINE__, out.str());
}
BITMAP * out = create_bitmap(gif->w, gif->h);
blit(gif, out, 0, 0, 0, 0, gif->w, gif->h);
destroy_bitmap(gif);
// pack_fclose(pack);
#endif
ALLEGRO_BITMAP * out = NULL;
return out;
}
void Bitmap::internalLoadFile(const char * path){
this->path = path;
ALLEGRO_BITMAP * loaded = al_load_bitmap(path);
if (loaded == NULL){
std::ostringstream out;
out << "Could not load file '" << path << "'";
throw BitmapException(__FILE__, __LINE__, out.str());
}
getData().setBitmap(loaded);
/*
ALLEGRO_BITMAP * loaded = IMG_Load(path);
if (loaded){
getData().setSurface(optimizedSurface(loaded));
SDL_FreeSurface(loaded);
} else {
std::ostringstream out;
out << "Could not load file '" << path << "'";
throw BitmapException(__FILE__, __LINE__, out.str());
}
*/
own = new int;
*own = 1;
}
static ALLEGRO_BITMAP * load_bitmap_from_memory(const char * data, int length, Format type){
switch (type){
case PNG : {
break;
}
case GIF : {
return memoryGIF(data, length);
break;
}
}
throw Exception::Base(__FILE__, __LINE__);
}
Bitmap::Bitmap(const char * data, int length):
own(NULL),
mustResize(false),
bit8MaskColor(0){
Format type = GIF;
getData().setBitmap(load_bitmap_from_memory(data, length, type));
if (getData().getBitmap() == NULL){
std::ostringstream out;
out << "Could not create bitmap from memory";
throw BitmapException(__FILE__, __LINE__, out.str());
}
own = new int;
*own = 1;
}
Bitmap::Bitmap( const Bitmap & copy, int x, int y, int width, int height ):
own(NULL),
mustResize(false),
bit8MaskColor(copy.bit8MaskColor){
path = copy.getPath();
ALLEGRO_BITMAP * his = copy.getData().getBitmap();
if (x < 0)
x = 0;
if (y < 0)
y = 0;
if (width + x > al_get_bitmap_width(his)){
width = al_get_bitmap_width(his) - x;
}
if (height + y > al_get_bitmap_height(his)){
height = al_get_bitmap_height(his) - y;
}
ALLEGRO_BITMAP * sub = al_create_sub_bitmap(his, x, y, width, height);
getData().setBitmap(sub);
own = new int;
*own = 1;
}
int Bitmap::getWidth() const {
if (getData().getBitmap() != NULL){
return al_get_bitmap_width(getData().getBitmap());
}
return 0;
}
int Bitmap::getRed(int color){
unsigned char red, green, blue;
unpack565(color, &red, &green, &blue);
return red;
}
int Bitmap::getGreen(int color){
unsigned char red, green, blue;
unpack565(color, &red, &green, &blue);
return green;
}
int Bitmap::getBlue(int color){
unsigned char red, green, blue;
unpack565(color, &red, &green, &blue);
return blue;
}
int Bitmap::makeColor(int red, int blue, int green){
return pack565(red, blue, green);
}
int Bitmap::getHeight() const {
if (getData().getBitmap() != NULL){
return al_get_bitmap_height(getData().getBitmap());
}
return 0;
}
int Bitmap::setGraphicsMode(int mode, int width, int height){
initializeExtraStuff();
switch (mode){
case FULLSCREEN: {
al_set_new_display_flags(ALLEGRO_FULLSCREEN);
break;
}
case WINDOWED: {
al_set_new_display_flags(ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE);
break;
}
default: break;
}
ALLEGRO_DISPLAY * display = al_create_display(width, height);
if (display == NULL){
std::ostringstream out;
out << "Could not create display with dimensions " << width << ", " << height;
throw BitmapException(__FILE__, __LINE__, out.str());
}
Screen = new Bitmap(al_get_backbuffer(display));
Scaler = new Bitmap(width, height);
return 0;
}
int Bitmap::getPixel(const int x, const int y) const {
ALLEGRO_COLOR color = al_get_pixel(getData().getBitmap(), x, y);
return pack565(color.r, color.g, color.b);
}
void Bitmap::putPixel(int x, int y, int pixel) const {
/* TODO */
}
void Bitmap::putPixelNormal(int x, int y, int col) const {
putPixel(x, y, col);
}
void Bitmap::fill(int color) const {
unsigned char red, green, blue;
unpack565(color, &red, &green, &blue);
// al_set_target_bitmap(getData().getBitmap());
al_clear_to_color(al_map_rgb(red, green, blue));
}
void Bitmap::transBlender( int r, int g, int b, int a ){
/* TODO */
/*
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
globalBlend.currentBlender = ::transBlender;
*/
}
void Bitmap::Stretch( const Bitmap & where, const int sourceX, const int sourceY, const int sourceWidth, const int sourceHeight, const int destX, const int destY, const int destWidth, const int destHeight ) const {
/* TODO */
}
void Bitmap::StretchBy2( const Bitmap & where ){
/* TODO */
}
void Bitmap::StretchBy4( const Bitmap & where ){
/* TODO */
}
void Bitmap::drawRotate( const int x, const int y, const int angle, const Bitmap & where ){
/* TODO */
}
void Bitmap::drawPivot( const int centerX, const int centerY, const int x, const int y, const int angle, const Bitmap & where ){
/* TODO */
}
void Bitmap::drawPivot( const int centerX, const int centerY, const int x, const int y, const int angle, const double scale, const Bitmap & where ){
/* TODO */
}
void Bitmap::drawStretched( const int x, const int y, const int new_width, const int new_height, const Bitmap & who ) const {
/* TODO */
}
void Bitmap::Blit(const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where) const {
// double start = al_get_time();
// al_set_target_bitmap(where.getData().getBitmap());
// al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
/*
if (&where != Screen){
al_draw_bitmap(getData().getBitmap(), wx, wy, 0);
}
*/
al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
al_draw_bitmap(getData().getBitmap(), wx, wy, 0);
/*
double end = al_get_time();
Global::debug(0) << "Draw in " << (end - start) << " seconds" << std::endl;
*/
}
void Bitmap::drawHFlip(const int x, const int y, const Bitmap & where) const {
/* TODO */
}
void Bitmap::drawHFlip(const int x, const int y, Filter * filter, const Bitmap & where) const {
/* TODO */
}
void Bitmap::drawVFlip( const int x, const int y, const Bitmap & where ) const {
/* TODO */
}
void Bitmap::drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
/* TODO */
}
void Bitmap::drawHVFlip( const int x, const int y, const Bitmap & where ) const {
/* TODO */
}
void Bitmap::drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
/* TODO */
}
void Bitmap::BlitMasked(const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where) const {
/* TODO */
}
void Bitmap::BlitToScreen(const int upper_left_x, const int upper_left_y) const {
#if 0
if (getWidth() != Screen->getWidth() || getHeight() != Screen->getHeight()){
/*
this->Blit( upper_left_x, upper_left_y, *Buffer );
Buffer->Stretch(*Scaler);
Scaler->Blit(0, 0, 0, 0, *Screen);
*/
this->Stretch(*Scaler, 0, 0, getWidth(), getHeight(), upper_left_x, upper_left_y, Scaler->getWidth(), Scaler->getHeight());
Scaler->Blit(0, 0, 0, 0, *Screen);
} else {
this->Blit(upper_left_x, upper_left_y, *Screen);
}
#endif
/*
if (&where == Screen){
al_flip_display();
}
*/
al_flip_display();
}
void Bitmap::BlitAreaToScreen(const int upper_left_x, const int upper_left_y) const {
/* TODO */
}
void Bitmap::draw(const int x, const int y, const Bitmap & where) const {
// al_set_target_bitmap(where.getData().getBitmap());
// al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
al_draw_bitmap(getData().getBitmap(), x, y, 0);
}
void Bitmap::draw(const int x, const int y, Filter * filter, const Bitmap & where) const {
/* TODO */
}
void Bitmap::hLine( const int x1, const int y, const int x2, const int color ) const {
/* TODO */
}
void Bitmap::vLine( const int x1, const int y, const int x2, const int color ) const {
/* TODO */
}
void Bitmap::arc(const int x, const int y, const double ang1, const double ang2, const int radius, const int color ) const {
/* TODO */
}
void Bitmap::floodfill( const int x, const int y, const int color ) const {
/* TODO */
}
void Bitmap::line( const int x1, const int y1, const int x2, const int y2, const int color ) const {
/* TODO */
}
void Bitmap::circleFill(int x, int y, int radius, int color) const {
/* TODO */
}
void Bitmap::circle(int x, int y, int radius, int color) const {
/* TODO */
}
void Bitmap::rectangle( int x1, int y1, int x2, int y2, int color ) const {
/* TODO */
}
void Bitmap::rectangleFill( int x1, int y1, int x2, int y2, int color ) const {
/* TODO */
}
void Bitmap::triangle( int x1, int y1, int x2, int y2, int x3, int y3, int color ) const {
/* TODO */
}
void Bitmap::polygon( const int * verts, const int nverts, const int color ) const {
/* TODO */
}
void Bitmap::ellipse( int x, int y, int rx, int ry, int color ) const {
/* TODO */
}
void Bitmap::ellipseFill( int x, int y, int rx, int ry, int color ) const {
/* TODO */
}
void Bitmap::applyTrans(const int color) const {
/* TODO */
}
void Bitmap::light(int x, int y, int width, int height, int start_y, int focus_alpha, int edge_alpha, int focus_color, int edge_color) const {
/* TODO */
}
void Bitmap::drawCharacter( const int x, const int y, const int color, const int background, const Bitmap & where ) const {
/* TODO */
}
void Bitmap::save( const std::string & str ) const {
/* TODO */
}
void Bitmap::readLine( std::vector< int > & line, int y ){
/* TODO */
}
void TranslucentBitmap::draw(const int x, const int y, const Bitmap & where) const {
/* FIXME */
// al_set_target_bitmap(where.getData().getBitmap());
// al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE);
al_draw_bitmap(getData().getBitmap(), x, y, 0);
}
void LitBitmap::draw( const int x, const int y, const Bitmap & where ) const {
/* TODO */
}
void LitBitmap::draw( const int x, const int y, Filter * filter, const Bitmap & where ) const {
/* TODO */
}
void LitBitmap::drawHFlip( const int x, const int y, const Bitmap & where ) const {
/* TODO */
}
void LitBitmap::drawHFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
/* TODO */
}
void LitBitmap::drawVFlip( const int x, const int y, const Bitmap & where ) const {
/* TODO */
}
void LitBitmap::drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
/* TODO */
}
void LitBitmap::drawHVFlip( const int x, const int y, const Bitmap & where ) const {
/* TODO */
}
void LitBitmap::drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
/* TODO */
}
void TranslucentBitmap::draw( const int x, const int y, Filter * filter, const Bitmap & where ) const {
/* TODO */
}
void TranslucentBitmap::drawHFlip( const int x, const int y, const Bitmap & where ) const {
/* TODO */
}
void TranslucentBitmap::drawHFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
/* TODO */
}
void TranslucentBitmap::drawVFlip( const int x, const int y, const Bitmap & where ) const {
/* TODO */
}
void TranslucentBitmap::drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
/* TODO */
}
void TranslucentBitmap::drawHVFlip( const int x, const int y, const Bitmap & where ) const {
/* TODO */
}
void TranslucentBitmap::drawHVFlip( const int x, const int y, Filter * filter,const Bitmap & where ) const {
/* TODO */
}
void TranslucentBitmap::hLine( const int x1, const int y, const int x2, const int color ) const {
/* TODO */
}
void TranslucentBitmap::circleFill(int x, int y, int radius, int color) const {
/* TODO */
}
void TranslucentBitmap::putPixelNormal(int x, int y, int color) const {
/* TODO */
}
void TranslucentBitmap::rectangle( int x1, int y1, int x2, int y2, int color ) const {
/* TODO */
}
void TranslucentBitmap::rectangleFill(int x1, int y1, int x2, int y2, int color) const {
/* TODO */
}
void TranslucentBitmap::ellipse( int x, int y, int rx, int ry, int color ) const {
/* TODO */
}
void Bitmap::initializeExtraStuff(){
al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_RGB_565);
}
Bitmap & Bitmap::operator=(const Bitmap & copy){
releaseInternalBitmap();
path = copy.getPath();
getData().setBitmap(copy.getData().getBitmap());
// own = false;
own = copy.own;
if (own)
*own += 1;
return *this;
}
void Bitmap::setClipRect( int x1, int y1, int x2, int y2 ) const {
/* TODO */
}
void Bitmap::getClipRect(int & x1, int & y1, int & x2, int & y2) const {
/* TODO */
}
void Bitmap::destroyPrivateData(){
al_destroy_bitmap(getData().getBitmap());
}
int Bitmap::setGfxModeFullscreen(int x, int y){
return setGraphicsMode(FULLSCREEN, x, y);
}
int Bitmap::setGfxModeWindowed( int x, int y ){
return setGraphicsMode(WINDOWED, x, y);
}
int Bitmap::setGfxModeText(){
/* TODO */
return 0;
}
bool Bitmap::getError(){
/* TODO */
return false;
}
void Bitmap::addBlender( int r, int g, int b, int a ){
/* TODO */
}
void Bitmap::differenceBlender( int r, int g, int b, int a ){
/* TODO */
}
void Bitmap::multiplyBlender( int r, int g, int b, int a ){
/* TODO */
}
void Bitmap::drawingMode(int type){
/* TODO */
}
void Bitmap::shutdown(){
delete Screen;
Screen = NULL;
/*
delete Scaler;
Scaler = NULL;
delete Buffer;
Buffer = NULL;
*/
}
+
+}
diff --git a/util/bitmap.cpp b/util/bitmap.cpp
index d3648965..457e53d8 100644
--- a/util/bitmap.cpp
+++ b/util/bitmap.cpp
@@ -1,373 +1,380 @@
/*
#ifdef USE_ALLEGRO
#include <allegro.h>
#endif
*/
#include "funcs.h"
#include "bitmap.h"
#include "trans-bitmap.h"
#include "lit_bitmap.h"
#include <string>
+#include <stdio.h>
#include <math.h>
+namespace Graphics{
+
/* implementation independant definitions can go here */
Bitmap * Bitmap::temporary_bitmap = NULL;
Bitmap * Bitmap::temporary_bitmap2 = NULL;
std::vector<Bitmap*> Bitmap::needResize;
int Bitmap::SCALE_X = 0;
int Bitmap::SCALE_Y = 0;
const int Bitmap::MODE_TRANS = 0;
const int Bitmap::MODE_SOLID = 1;
-const int Bitmap::SPRITE_NO_FLIP = 0;
-const int Bitmap::SPRITE_V_FLIP = 1;
-const int Bitmap::SPRITE_H_FLIP = 2;
+const int SPRITE_NO_FLIP = 0;
+const int SPRITE_V_FLIP = 1;
+const int SPRITE_H_FLIP = 2;
-const int Bitmap::SPRITE_NORMAL = 1;
-const int Bitmap::SPRITE_LIT = 2;
-const int Bitmap::SPRITE_TRANS = 3;
-
-#ifdef USE_ALLEGRO
-#include "allegro/bitmap.cpp"
-#endif
-#ifdef USE_SDL
-#include "sdl/bitmap.cpp"
-#endif
-#ifdef USE_ALLEGRO5
-#include "allegro5/bitmap.cpp"
-#endif
+const int SPRITE_NORMAL = 1;
+const int SPRITE_LIT = 2;
+const int SPRITE_TRANS = 3;
static inline int max(int a, int b){
return a > b ? a : b;
}
Bitmap::~Bitmap(){
if (mustResize){
for (std::vector<Bitmap*>::iterator it = needResize.begin(); it != needResize.end(); it++){
Bitmap * who = *it;
if (who == this){
needResize.erase(it);
break;
}
}
}
releaseInternalBitmap();
}
static Bitmap makeTemporaryBitmap(Bitmap *& temporary, int w, int h){
if (temporary == NULL){
temporary = new Bitmap(w, h);
} else if (temporary->getWidth() < w || temporary->getHeight() < h){
int mw = max(temporary->getWidth(), w);
int mh = max(temporary->getHeight(), h);
// printf("Create temporary bitmap %d %d\n", mw, mh);
delete temporary;
temporary = new Bitmap(mw, mh);
}
if (temporary == NULL){
printf("*bug* temporary bitmap is null\n");
}
return Bitmap(*temporary, 0, 0, w, h);
}
Bitmap Bitmap::temporaryBitmap(int w, int h){
return makeTemporaryBitmap(temporary_bitmap, w, h);
}
Bitmap Bitmap::temporaryBitmap2(int w, int h){
return makeTemporaryBitmap(temporary_bitmap2, w, h);
}
void Bitmap::cleanupTemporaryBitmaps(){
if (temporary_bitmap != NULL){
delete temporary_bitmap;
temporary_bitmap = NULL;
}
if (temporary_bitmap2 != NULL){
delete temporary_bitmap2;
temporary_bitmap2 = NULL;
}
}
double Bitmap::getScale(){
/* the game is pretty much hard coded to run at 320 scaled upto 640
* and then scaled to whatever the user wants, but as long as
* 320 and 640 remain this number will be 2.
* maybe calculate this at some point
*/
return 2;
/*
if (Scaler != NULL && Buffer != NULL){
double x1 = Scaler->getWidth();
double x2 = Buffer->getWidth();
return x2 / x1;
}
return 1;
*/
}
/* taken from the color addon from allegro 4.9 */
static void al_color_cmyk_to_rgb(float cyan, float magenta, float yellow, float key, float *red, float *green, float *blue){
float max = 1 - key;
*red = max - cyan * max;
*green = max - magenta * max;
*blue = max - yellow * max;
}
void Bitmap::cymkToRGB(int c, int y, int m, int k, int * r, int * g, int * b){
float fc = (float)c / 255.0;
float fy = (float)y / 255.0;
float fm = (float)m / 255.0;
float fk = (float)k / 255.0;
float fr, fg, fb;
al_color_cmyk_to_rgb(fc, fm, fy, fk, &fr, &fg, &fb);
*r = (int)(fr * 255.0);
*g = (int)(fg * 255.0);
*b = (int)(fb * 255.0);
}
int Bitmap::getScreenWidth(){
if (Screen != 0){
return Screen->getWidth();
}
return 0;
}
int Bitmap::getScreenHeight(){
if (Screen != 0){
return Screen->getHeight();
}
return 0;
}
void Bitmap::updateOnResize(){
if (!mustResize){
mustResize = true;
needResize.push_back(this);
}
}
/* resize the internal bitmap. not guaranteed to destroy the internal bitmap */
void Bitmap::resize( const int width, const int height ){
/* if internal bitmap is already the proper size, do nothing */
if ( getWidth() == width && getHeight() == height ){
return;
}
Bitmap created(width, height);
Stretch(created);
*this = created;
/*
BITMAP * b = create_bitmap( width, height );
::stretch_blit( getData().getBitmap(), b, 0, 0, getData().getBitmap()->w, getData().getBitmap()->h, 0, 0, b->w, b->h );
releaseInternalBitmap();
own = new int;
getData().setBitmap( b );
*own = 1;
*/
}
/* decrement bitmap reference counter and free memory if counter hits 0 */
void Bitmap::releaseInternalBitmap(){
const int MAGIC_DEBUG = 0xa5a5a5;
if (own != NULL){
if (*own == MAGIC_DEBUG){
printf("[bitmap] Trying to delete an already deleted reference counter %p\n", own);
}
(*own) -= 1;
if ( *own == 0 ){
*own = MAGIC_DEBUG;
delete own;
destroyPrivateData();
own = NULL;
}
}
}
void Bitmap::BlitToScreen() const {
// this->Blit( *Bitmap::Screen );
this->BlitToScreen(0, 0);
}
void Bitmap::load( const std::string & str ){
releaseInternalBitmap();
internalLoadFile( str.c_str() );
}
void Bitmap::border( int min, int max, int color ) const {
int w = getWidth();
int h = getHeight();
for (int i = min; i < max; i++){
rectangle(i, i, w - 1 - i, h - 1 - i, color);
}
}
void Bitmap::drawHFlip(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, const Bitmap & where) const {
drawHFlip(x, y, startWidth, startHeight, width, height, NULL, where);
}
void Bitmap::drawHFlip(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, Filter * filter, const Bitmap & where) const {
Bitmap sub(*this, getWidth() - width, getHeight() - height, getWidth() - startWidth, getHeight() - startHeight);
sub.drawHFlip(x + startWidth, y + startHeight, filter, where);
}
void Bitmap::draw(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, const Bitmap & where) const {
draw(x, y, startWidth, startHeight, width, height, NULL, where);
/*
Bitmap sub(*this, startWidth, startHeight, width, height);
sub.draw(x + startWidth, y + startHeight, where);
*/
}
void Bitmap::draw(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, Filter * filter, const Bitmap & where) const {
Bitmap sub(*this, startWidth, startHeight, width, height);
sub.draw(x + startWidth, y + startHeight, filter, where);
}
void Bitmap::horizontalLine( const int x1, const int y, const int x2, const int color ) const{
this->hLine( x1, y, x2, color );
}
void Bitmap::equilateralTriangle(int x, int y, int angle, int size, int color) const {
double radians = Util::radians(angle);
int x1 = x + size / 2 * cos(radians + 2 * Util::pi / 3);
int y1 = y + size / 2 * sin(radians + 2 * Util::pi / 3);
int x2 = x + size / 2 * cos(radians - 2 * Util::pi / 3);
int y2 = y + size / 2 * sin(radians - 2 * Util::pi / 3);
int x3 = x + size / 2 * cos(radians);
int y3 = y + size / 2 * sin(radians);
triangle(x1, y1, x2, y2, x3, y3, color);
}
Bitmap Bitmap::greyScale(){
Bitmap grey(getWidth(), getHeight());
for (int x = 0; x < getWidth(); x++){
for (int y = 0; y < getHeight(); y++){
int pixel = getPixel(x, y);
int val = (int)((0.299*getRed(pixel) + 0.587*getGreen(pixel) + 0.114*getBlue(pixel) + 0.5) + 16);
if (val > 255){
val = 255;
}
grey.putPixel(x, y, makeColor(val, val, val));
}
}
return grey;
}
bool Bitmap::inRange(int x, int y) const {
int x1, y1, x2, y2;
getClipRect(x1, y1, x2, y2);
return (x >= x1 && x <= x2 &&
y >= y1 && y <= y2);
}
void Bitmap::drawMask( const int _x, const int _y, const Bitmap & where ){
int mask = Bitmap::MaskColor();
for ( int x = 0; x < getWidth(); x++ ){
for ( int y = 0; y < getHeight(); y++ ){
if ( getPixel( x,y ) == mask ){
where.putPixel( x+_x, y+_y, mask );
}
}
}
}
void Bitmap::set8BitMaskColor(int color){
bit8MaskColor = color;
}
int Bitmap::get8BitMaskColor(){
return bit8MaskColor;
}
void Bitmap::setFakeGraphicsMode(int width, int height){
initializeExtraStuff();
Screen = new Bitmap(width, height);
}
void Bitmap::Blit( const std::string & xpath ) const {
Bitmap duh(xpath);
duh.Blit(*this);
}
void Bitmap::Blit(const Bitmap & where) const {
this->Blit(0, 0, where);
}
void Bitmap::Blit(const int x, const int y, const Bitmap & where) const {
Blit(0, 0, x, y, where);
}
void Bitmap::Blit(const int mx, const int my, const int wx, const int wy, const Bitmap & where) const {
Blit(mx, my, getWidth(), getHeight(), wx, wy, where);
}
void Bitmap::BlitFromScreen(const int x, const int y) const {
Screen->Blit(x, y, getWidth(), getHeight(), 0, 0, *this);
}
void Bitmap::Stretch( const Bitmap & where ) const {
if (getWidth() == where.getWidth() && getHeight() == where.getHeight()){
Blit(where);
} else {
Stretch(where, 0, 0, getWidth(), getHeight(), 0, 0, where.getWidth(), where.getHeight());
}
}
int Bitmap::darken( int color, double factor ){
int r = (int)((double)getRed(color) / factor);
int g = (int)((double)getGreen(color) / factor);
int b = (int)((double)getBlue(color) / factor);
return makeColor(r, g, b);
}
LitBitmap::LitBitmap(const Bitmap & b):
Bitmap(b){
int x1, y1, x2, y2;
b.getClipRect(x1, y1, x2, y2);
setClipRect(x1, y1, x2, y2);
}
LitBitmap::LitBitmap():
Bitmap(){
}
LitBitmap::~LitBitmap(){
}
TranslucentBitmap Bitmap::translucent() const {
return TranslucentBitmap(*this);
}
TranslucentBitmap::TranslucentBitmap(const Bitmap & b):
Bitmap(b){
int x1, y1, x2, y2;
b.getClipRect(x1, y1, x2, y2);
setClipRect(x1, y1, x2, y2);
}
TranslucentBitmap::TranslucentBitmap():
Bitmap(){
}
TranslucentBitmap::~TranslucentBitmap(){
}
void TranslucentBitmap::fill(int color) const {
Bitmap::applyTrans(color);
}
+
+}
+
+
+#ifdef USE_ALLEGRO
+#include "allegro/bitmap.cpp"
+#endif
+#ifdef USE_SDL
+#include "sdl/bitmap.cpp"
+#endif
+#ifdef USE_ALLEGRO5
+#include "allegro5/bitmap.cpp"
+#endif
+
diff --git a/util/bitmap.h b/util/bitmap.h
index c3507c43..5e79d8a4 100644
--- a/util/bitmap.h
+++ b/util/bitmap.h
@@ -1,390 +1,394 @@
#ifndef _paintown_bitmap_h_
#define _paintown_bitmap_h_
+#include "exceptions/exception.h"
+#include <string>
+#include <vector>
+#include <iostream>
+
#ifdef USE_ALLEGRO
#include "allegro/bitmap.h"
#endif
#ifdef USE_SDL
#include "sdl/bitmap.h"
#endif
#ifdef USE_ALLEGRO5
#include "allegro5/bitmap.h"
#endif
-#include "exceptions/exception.h"
-#include <string>
-#include <vector>
-#include <iostream>
+namespace Graphics{
class TranslucentBitmap;
+extern const int SPRITE_NORMAL;
+extern const int SPRITE_LIT;
+extern const int SPRITE_TRANS;
+
+extern const int SPRITE_NO_FLIP;
+extern const int SPRITE_V_FLIP;
+extern const int SPRITE_H_FLIP;
+
class BitmapException: public Exception::Base {
public:
BitmapException(const std::string & file, int line, const std::string & reason):
Base(file, line),
reason(reason){
}
BitmapException(const BitmapException & copy):
Base(copy),
reason(copy.reason){
}
virtual void throwSelf() const {
throw *this;
}
virtual ~BitmapException() throw () {
}
protected:
virtual const std::string getReason() const {
return reason;
}
std::string reason;
};
class Bitmap{
private:
static Bitmap * Screen;
/* these constructors don't really matter, get rid of them at some point */
Bitmap( const Bitmap & copy, int sx, int sy, double accuracy );
Bitmap( const char * load_file, int sx, int sy, double accuracy );
public:
/* equivalent to a GPU shader */
class Filter{
public:
virtual unsigned int filter(unsigned int pixel) const = 0;
virtual ~Filter(){
}
};
static int SCALE_X;
static int SCALE_Y;
/* default constructor makes 10x10 bitmap */
Bitmap();
Bitmap( int x, int y );
Bitmap( const char * load_file );
Bitmap(const char * data, int length);
Bitmap( const std::string & load_file );
Bitmap( const char * load_file, int sx, int sy );
/* 4/24/2010: remove this at some point */
#ifdef USE_ALLEGRO
explicit Bitmap( BITMAP * who, bool deep_copy = false );
#endif
#ifdef USE_SDL
explicit Bitmap(SDL_Surface * who, bool deep_copy = false );
#endif
#ifdef USE_ALLEGRO5
explicit Bitmap(ALLEGRO_BITMAP * who, bool deep_copy = false );
#endif
Bitmap( const Bitmap & copy, bool deep_copy = false );
Bitmap( const Bitmap & copy, int sx, int sy );
Bitmap( const Bitmap & copy, int x, int y, int width, int height );
virtual ~Bitmap();
virtual TranslucentBitmap translucent() const;
virtual void save( const std::string & str ) const;
Bitmap & operator=( const Bitmap & );
virtual void load( const std::string & str );
int getWidth() const;
int getHeight() const;
/*
inline const int getWidth() const{
return getBitmap()->w;
}
inline const int getHeight() const{
return getBitmap()->h;
}
*/
/*
inline const int getWidth() const{
return my_bitmap->w;
}
inline const int getHeight() const{
return my_bitmap->h;
}
*/
static Bitmap memoryPCX(unsigned char * const data, const int length, const bool mask = true);
void detach();
/* replace all pixels that have value `original' with `replaced' */
void replaceColor(int original, int replaced);
void set8BitMaskColor(int color);
int get8BitMaskColor();
static void transBlender( int r, int g, int b, int a );
static void multiplyBlender( int r, int g, int b, int a );
static void dissolveBlender( int r, int g, int b, int a );
static void addBlender( int r, int g, int b, int a );
static void burnBlender( int r, int g, int b, int a );
static void colorBlender( int r, int g, int b, int a );
static void differenceBlender( int r, int g, int b, int a );
static void dodgeBlender( int r, int g, int b, int a );
static void hueBlender( int r, int g, int b, int a );
static void luminanceBlender( int r, int g, int b, int a );
static void invertBlender( int r, int g, int b, int a );
static void screenBlender( int r, int g, int b, int a );
static int setGraphicsMode( int mode, int width, int height );
/* for testing */
static void setFakeGraphicsMode(int width, int height);
/* clean up any remaining state */
static void shutdown();
static void drawingMode( int type );
void acquire();
void release();
void updateOnResize();
void resize(const int width, const int height);
void debugSelf() const;
/* convert to a grey scale version */
virtual Bitmap greyScale();
virtual void triangle( int x1, int y1, int x2, int y2, int x3, int y3, int color ) const;
/* draws an equilateral triangle centered at (x,y) pointing at `angle'
* where each side has `size' pixels using the color.
*/
virtual void equilateralTriangle(int x, int y, int angle, int size, int color) const;
virtual void ellipse( int x, int y, int rx, int ry, int color ) const;
virtual void ellipseFill( int x, int y, int rx, int ry, int color ) const;
virtual void light(int x, int y, int width, int height, int start_y, int focus_alpha, int edge_alpha, int focus_color, int edge_color) const;
virtual void applyTrans(const int color) const;
virtual void border( int min, int max, int color ) const;
virtual void rectangle( int x1, int y1, int x2, int y2, int color ) const;
virtual void rectangleFill( int x1, int y1, int x2, int y2, int color ) const;
virtual void circleFill( int x, int y, int radius, int color ) const;
virtual void circle( int x, int y, int radius, int color ) const;
virtual void line( const int x1, const int y1, const int x2, const int y2, const int color ) const;
virtual void floodfill( const int x, const int y, const int color ) const;
virtual void horizontalLine( const int x1, const int y, const int x2, const int color ) const;
virtual void hLine( const int x1, const int y, const int x2, const int color ) const;
virtual void vLine( const int y1, const int x, const int y2, const int color ) const;
virtual void polygon( const int * verts, const int nverts, const int color ) const;
virtual void arc(const int x, const int y, const double ang1, const double ang2, const int radius, const int color ) const;
virtual void draw(const int x, const int y, const Bitmap & where) const;
virtual void draw(const int x, const int y, Filter * filter, const Bitmap & where) const;
virtual void draw(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, const Bitmap & where) const;
virtual void draw(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, Filter * filter, const Bitmap & where) const;
virtual void drawCharacter( const int x, const int y, const int color, const int background, const Bitmap & where ) const;
/* flip horizontally */
virtual void drawHFlip(const int x, const int y, const Bitmap & where) const;
virtual void drawHFlip(const int x, const int y, Filter * filter, const Bitmap & where) const;
virtual void drawHFlip(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, const Bitmap & where) const;
virtual void drawHFlip(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, Filter * filter, const Bitmap & where) const;
/* flip vertically */
virtual void drawVFlip( const int x, const int y, const Bitmap & where ) const;
virtual void drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
/* flip horizontal and vertical */
virtual void drawHVFlip( const int x, const int y, const Bitmap & where ) const;
virtual void drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
// virtual void drawTrans( const int x, const int y, const Bitmap & where ) const;
// virtual void drawTrans( const int x, const int y, Filter * filter, const Bitmap & where ) const;
// virtual void drawTransHFlip( const int x, const int y, const Bitmap & where ) const;
// virtual void drawTransHFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
// virtual void drawTransVFlip( const int x, const int y, const Bitmap & where ) const;
// virtual void drawTransVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
// virtual void drawTransHVFlip( const int x, const int y, const Bitmap & where ) const;
// virtual void drawTransHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
virtual void drawMask( const int x, const int y, const Bitmap & where );
virtual void drawStretched( const int x, const int y, const int new_width, const int new_height, const Bitmap & who ) const;
virtual void drawRotate( const int x, const int y, const int angle, const Bitmap & where );
virtual void drawPivot( const int centerX, const int centerY, const int x, const int y, const int angle, const Bitmap & where );
virtual void drawPivot( const int centerX, const int centerY, const int x, const int y, const int angle, const double scale, const Bitmap & where );
virtual void Stretch( const Bitmap & where ) const;
virtual void Stretch( const Bitmap & where, const int sourceX, const int sourceY, const int sourceWidth, const int sourceHeight, const int destX, const int destY, const int destWidth, const int destHeight ) const;
virtual void StretchBy2( const Bitmap & where );
virtual void StretchBy4( const Bitmap & where );
virtual void Blit( const std::string & xpath ) const;
virtual void Blit( const Bitmap & where ) const;
virtual void Blit( const int x, const int y, const Bitmap & where ) const;
virtual void Blit( const int mx, const int my, const int wx, const int wy, const Bitmap & where ) const;
virtual void Blit( const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where ) const;
virtual void BlitMasked( const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where ) const;
virtual void BlitToScreen() const;
virtual void BlitAreaToScreen(const int upper_left_x, const int upper_left_y) const;
virtual void BlitToScreen(const int upper_left_x, const int upper_left_y) const;
virtual void BlitFromScreen(const int x, const int y) const;
/* try to call Global::getScreenWidth/Height() instead of these directly */
static int getScreenWidth();
static int getScreenHeight();
virtual void fill( int color ) const;
inline void clear() const{
this->fill( 0 );
}
inline void clearToMask() const{
this->fill(MaskColor());
}
bool getError();
inline const BitmapData & getData() const {
return data;
}
inline BitmapData & getData(){
return data;
}
virtual void readLine( std::vector< int > & vec, int y );
int getPixel( const int x, const int y ) const;
/* true if the point is within the bounds of the bitmap */
bool inRange(int x, int y) const;
/* uses _putpixel16 underneath which ignores translucent behavior */
void putPixel( int x, int y, int col ) const;
/* respects the current trans mode */
virtual void putPixelNormal(int x, int y, int col) const;
/*
inline int getPixel( int x, int y ) const{
if ( x >= 0 && x < my_bitmap->w && y >= 0 && y <= my_bitmap->h )
return _getpixel16( my_bitmap, x, y );
return -1;
}
inline void putPixel( int x, int y, int col ) const{
if ( x >= 0 && x < my_bitmap->w && y >= 0 && y <= my_bitmap->h )
_putpixel16( my_bitmap, x, y, col );
}
*/
void setClipRect( int x1, int y1, int x2, int y2 ) const;
void getClipRect( int & x1, int & y1, int & x2, int & y2 ) const;
inline const std::string & getPath() const{
return path;
}
/* produce a temporary bitmap that is not guaranteed to be preserved
* after your function returns. do *not* hold references to this bitmap
* and if you make a temporary bitmap, do *not* call functions that
* might also make temporary bitmaps.
*/
static Bitmap temporaryBitmap(int w, int h);
static Bitmap temporaryBitmap2(int w, int h);
/* call this method to delete all temporary bitmaps.
* don't call this unless you know what you are doing
*/
static void cleanupTemporaryBitmaps();
static double getScale();
static int setGfxModeText();
static int setGfxModeFullscreen( int x, int y );
static int setGfxModeWindowed( int x, int y );
static int makeColor( int r, int g, int b );
static int darken( int color, double factor );
static void hsvToRGB( float h, float s, float v, int * r, int * g, int * b );
/*
* Convert color values between the HSV and RGB color spaces. The RGB values
* range from 0 to 255, hue is from 0 to 360, and saturation and value are
* from 0 to 1.
*/
static void rgbToHSV(int r, int g, int b, float * h, float * s, float * v);
/* convert cymk to rgb. values should be in the range 0-255 */
static void cymkToRGB(int c, int y, int m, int k, int * r, int * g, int * b);
static int getRed( int x );
static int getBlue( int x );
static int getGreen( int x );
/* Add two RGB16 colors together
* r = c1.r + c2.r
* g = c1.g + c2.g
* b = c1.b + c2.b
*/
static int addColor( int color1, int color2 );
/*
inline static int makeColor( int r, int g, int b ){
return makecol16( r, g, b );
}
*/
// static const int MaskColor = MASK_COLOR_16;
static int MaskColor();
static const int MODE_TRANS;
static const int MODE_SOLID;
- static const int SPRITE_NO_FLIP;
- static const int SPRITE_V_FLIP;
- static const int SPRITE_H_FLIP;
-
- static const int SPRITE_NORMAL;
- static const int SPRITE_LIT;
- static const int SPRITE_TRANS;
-
protected:
static void initializeExtraStuff();
/* release a reference count, and possibly destroy data */
void releaseInternalBitmap();
/* really destroy private data */
void destroyPrivateData();
/*
inline void setBitmap( BITMAP * bitmap ){
if ( bitmap == NULL ){
std::cout << "*FATAL* Setting null bitmap" << std::endl;
}
_my_bitmap = bitmap;
}
*/
void internalLoadFile( const char * load_file );
/* implementation specific data */
BitmapData data;
int * own;
bool mustResize;
// bool own;
bool error;
std::string path;
static Bitmap * temporary_bitmap;
static Bitmap * temporary_bitmap2;
int bit8MaskColor;
/* bitmaps that should always be resized to the dimensions of the screen */
static std::vector<Bitmap*> needResize;
};
+}
+
#endif
diff --git a/util/ebox.cpp b/util/ebox.cpp
index 878c4ee6..63c49c8b 100644
--- a/util/ebox.cpp
+++ b/util/ebox.cpp
@@ -1,722 +1,722 @@
/* ebox version 3:
* by Jon Rafkind
*/
#include "ebox.h"
#include <stdio.h>
#include "funcs.h"
#include "bitmap.h"
#include <iostream>
using namespace std;
// extern "C" void rest( int i );
// using namespace Ebox2;
#ifndef debug
// #define debug printf("File: %s Line: %d\n", __FILE__, __LINE__ );
#define debug std::cout<<"File: "<<__FILE__<<" Line: "<<__LINE__<<std::endl;
#endif
// #define MIN_SIZE 8
const int MIN_SIZE = 8;
/* copy constructor but with a pointer */
EQuad::EQuad( EQuad * const head ):
width( head->width ),
height( head->height ),
full( head->full ),
min_x( head->min_x ),
min_y( head->min_y ),
parent( NULL ),
num_quads( head->num_quads ){
for ( int q = 0; q < 4; q++ )
quads[q] = NULL;
for ( int i = 0; i < head->numQuads(); i++ ){
// EQuad * tmp = head->getQuad( i );
quads[i] = new EQuad( head->getQuad( i ) );
quads[i]->parent = this;
}
}
EQuad::EQuad( int w, int h, EQuad * _parent ):
width( w ),
height( h ),
min_x( 0 ),
min_y( 0 ),
parent( _parent ),
num_quads( 0 ){
full = true;
for ( int i = 0; i < 4; i++ )
quads[i] = NULL;
}
-EQuad::EQuad( const Bitmap * who, int min_size, int mask_pixel, int _min_x, int _min_y, EQuad * _parent ):
+EQuad::EQuad( const Graphics::Bitmap * who, int min_size, int mask_pixel, int _min_x, int _min_y, EQuad * _parent ):
width( who->getWidth() ),
height( who->getHeight() ),
full( false ),
min_x( _min_x ),
min_y( _min_y ),
parent( _parent ){
- Bitmap * b1, * b2, * b3, * b4;
+ Graphics::Bitmap * b1, * b2, * b3, * b4;
EQuad * quad1, * quad2, * quad3, * quad4;
quad1 = quad2 = quad3 = quad4 = NULL;
if ( width > min_size && height > min_size ){
int w = who->getWidth() >> 1;
int h = who->getHeight() >> 1;
// b1 = create_sub_Bitmap( who, 0, 0, w, h );
- b1 = new Bitmap( *who, 0, 0, w, h );
+ b1 = new Graphics::Bitmap( *who, 0, 0, w, h );
quad1 = new EQuad( b1, min_size, mask_pixel, 0, 0, this );
// destroy_Bitmap( b1 );
delete b1;
// b2 = create_sub_Bitmap( who, w, 0, w, h );
- b2 = new Bitmap( *who, w, 0, w, h );
+ b2 = new Graphics::Bitmap( *who, w, 0, w, h );
quad2 = new EQuad( b2, min_size, mask_pixel, w, 0, this );
delete b2;
// destroy_Bitmap( b2 );
// b3 = create_sub_Bitmap( who, 0, h, w, h );
- b3 = new Bitmap( *who, 0, h, w, h );
+ b3 = new Graphics::Bitmap( *who, 0, h, w, h );
quad3 = new EQuad( b3, min_size, mask_pixel, 0, h, this );
delete b3;
// destroy_Bitmap( b3 );
// b4 = create_sub_Bitmap( who, w, h, w, h );
- b4 = new Bitmap( *who, w, h, w, h );
+ b4 = new Graphics::Bitmap( *who, w, h, w, h );
quad4 = new EQuad( b4, min_size, mask_pixel, w, h, this );
delete b4;
// destroy_Bitmap( b4 );
if ( quad1->empty() ){
delete quad1;
quad1 = NULL;
}
if ( quad2->empty() ){
delete quad2;
quad2 = NULL;
}
if ( quad3->empty() ){
delete quad3;
quad3 = NULL;
}
if ( quad4->empty() ){
delete quad4;
quad4 = NULL;
}
if ( quad1 && quad2 && quad3 && quad4 )
if ( quad1->full && quad2->full && quad3->full && quad4->full ){
delete quad1;
delete quad2;
delete quad3;
delete quad4;
quad1 = NULL;
quad2 = NULL;
quad3 = NULL;
quad4 = NULL;
full = true;
}
checkQuad( quad1 );
checkQuad( quad2 );
checkQuad( quad3 );
checkQuad( quad4 );
} else {
// printf("Size X:%d Y:%d\n", width, height );
int total = 0;
int denom = who->getWidth() * who->getHeight();
/* empty sprite? */
if (denom < 1){
denom = 1;
}
for ( int x = 0; x < who->getWidth(); x++ ){
for ( int y = 0; y < who->getHeight(); y++ ){
// int pixel = _getpixel16( who, x, y );
int pixel = who->getPixel( x, y );
if ( pixel != mask_pixel ){
++total;
}
if ( total * 100 / denom > 50 ){
/* we're done already,
* stop counting pixels
*/
goto short_circuit;
}
}
}
/* johnny 5 alive! */
short_circuit:
if ( total * 100 / denom > 50 ){
full = true;
}
}
for ( int i = 0; i < 4; i++ )
quads[i] = NULL;
int i = 0;
if ( quad1 ) quads[i++] = quad1;
if ( quad2 ) quads[i++] = quad2;
if ( quad3 ) quads[i++] = quad3;
if ( quad4 ) quads[i++] = quad4;
num_quads = numQuads();
}
bool EQuad::addQuad( EQuad * who ){
int n = numQuads();
if ( n < 4 ){
quads[n] = who;
full = false;
return true;
} else return false;
}
void EQuad::checkQuad( EQuad *& q ){
if ( q != NULL ){
while ( q->numQuads() == 1 ){
EQuad * const newquad = q->getQuad();
q->detach( newquad );
int x = q->getMinX();
int y = q->getMinY();
delete q;
q = newquad;
newquad->setMinX( newquad->getMinX() + x );
newquad->setMinY( newquad->getMinY() + y );
q->parent = this;
}
}
}
int EQuad::totalQuads(){
if ( full ) return 1;
int total = 0;
for ( int i = 0; i < numQuads(); i++ )
if ( quads[i] )
total += quads[i]->totalQuads();
/*
if ( quad1 ) total += quad1->totalQuads();
if ( quad2 ) total += quad2->totalQuads();
if ( quad3 ) total += quad3->totalQuads();
if ( quad4 ) total += quad4->totalQuads();
*/
return total;
}
void EQuad::setMinX( int x ){
min_x = x;
}
void EQuad::setMinY( int y ){
min_y = y;
}
/*
int EQuad::numQuads() const{
int total = 0;
/ *
if ( quad1 ) ++total;
if ( quad2 ) ++total;
if ( quad3 ) ++total;
if ( quad4 ) ++total;
* /
for ( total = 0; total < 4 && quads[total] != NULL; total++ );
return total;
}
*/
EQuad * EQuad::getQuad() const {
return quads[0];
/*
if ( quad1 ) return quad1;
if ( quad2 ) return quad2;
if ( quad3 ) return quad3;
if ( quad4 ) return quad4;
return NULL;
*/
}
EQuad * EQuad::getQuad( int x ) const {
return quads[x];
}
void EQuad::detach( EQuad * const who ){
// printf("Detach %p\n", who );
/*
if ( who == quad1 ) quad1 = NULL;
if ( who == quad2 ) quad2 = NULL;
if ( who == quad3 ) quad3 = NULL;
if ( who == quad4 ) quad4 = NULL;
*/
for ( int i = 0; i < numQuads(); i++ )
if ( who == quads[i] )
quads[i] = NULL;
EQuad * tmp[ 4 ];
int begin = 0;
for ( int i = 0; i < 4; i++ )
if ( quads[i] ){
tmp[begin++] = quads[i];
quads[i] = NULL;
}
for ( int q = 0; q < begin; q++ )
quads[q] = tmp[q];
}
int EQuad::calcSize(){
int total = sizeof(*this);
for ( int q = 0; q < numQuads(); q++ ){
total += quads[q]->calcSize();
}
return total;
}
bool EQuad::empty(){
if ( numQuads() == 0 ) return !full;
// if ( !quad1 && !quad2 && !quad3 && !quad4 ) return !full;
return false;
}
-void EQuad::draw( const Bitmap & work, int x, int y, int color, bool flipped ){
+void EQuad::draw( const Graphics::Bitmap & work, int x, int y, int color, bool flipped ){
int mx = x + getMinX();
int my = y + getMinY();
// std::cout<<"getMinX: "<<getMinX()<<std::endl;
if ( flipped ){
if ( parent ){
mx = x + parent->getWidth() - (getMinX()+getWidth());
// mx = getMinX() - parent->getWidth()/2 + x;
// my = y + parent->getHeight()/2 - getMinY();
// my = y + getMinY();
// mx2 = mx - getWidth();
// mx2 = mx + getWidth();
/*
int i;
i = mx;
mx = mx2;
mx2 = i;
*/
}
}
int mx2 = mx + getWidth();
int my2 = my + getHeight();
for ( int i = 0; i < numQuads(); i++ )
quads[i]->draw( work, mx, my, color, flipped );
if ( full )
work.rectangle( mx, my, mx2, my2, color );
/*
if ( full )
work->rectangle( x+getMinX(), y+getMinY(), x+getMinX()+getWidth(), y+getMinY()+getHeight(), Bitmap::makeColor(255,64,32) );
else
work->rectangle( x+getMinX(), y+getMinY(), x+getMinX()+getWidth(), y+getMinY()+getHeight(), color );
*/
}
-void EQuad::draw( const Bitmap & work, int x, int y, int color, EQuad * who ){
+void EQuad::draw( const Graphics::Bitmap & work, int x, int y, int color, EQuad * who ){
bool cy = false;
for ( int i = 0; i < numQuads(); i++ )
if ( who == quads[i] )
cy = true;
int mx = x + getMinX();
int my = y + getMinY();
if ( cy )
who->draw( work, mx, my, color );
else {
for ( int i = 0; i < numQuads(); i++ )
quads[i]->draw( work, mx, my, color, who );
}
}
static bool boxCollide( int zx1, int zy1, int zx2, int zy2, int zx3, int zy3, int zx4, int zy4 ){
if ( zx1 < zx3 && zx1 < zx4 &&
zx2 < zx3 && zx2 < zx4 ) return false;
if ( zx1 > zx3 && zx1 > zx4 &&
zx2 > zx3 && zx2 > zx4 ) return false;
if ( zy1 < zy3 && zy1 < zy4 &&
zy2 < zy3 && zy2 < zy4 ) return false;
if ( zy1 > zy3 && zy1 > zy4 &&
zy2 > zy3 && zy2 > zy4 ) return false;
return true;
}
/* sure this could be simplified, but thats no fun :p */
int EQuad::getX1( bool xflipped ){
if ( parent ){
if ( xflipped ){
return parent->getWidth() - (getMinX() + getWidth());
} else {
return getMinX();
}
} else {
return getMinX();
}
}
int EQuad::getFullX1( bool xflipped ){
if ( parent ){
if ( xflipped ){
return parent->getFullX1( xflipped ) + parent->getWidth() - (getMinX() + getWidth());
} else {
return parent->getFullX1( xflipped ) + getMinX();
}
} else {
return getMinX();
}
}
int EQuad::getY1( bool yflipped ){
if ( parent ){
if ( yflipped ){
return parent->getHeight() - (getMinY() + getHeight());
} else {
return getMinY();
}
} else {
return getMinY();
}
}
int EQuad::getFullY1( bool yflipped ){
if ( parent ){
if ( yflipped ){
return parent->getFullY1( yflipped ) - (parent->getHeight() + getMinY() + getHeight());
} else {
return parent->getFullY1( yflipped ) + getMinY();
}
} else {
return getMinY();
}
}
void EQuad::gather( int mx, int my, int x1, int y1, int x2, int y2, vector< EQuad * > & collides, bool xflipped, bool yflipped ){
/*
int rx = mx + getX1();
int ry = my + getY1();
*/
int rx = mx;
int ry = my;
int rx2 = rx + getWidth();
int ry2 = ry + getHeight();
if ( ! boxCollide( rx, ry, rx2, ry2, x1, y1, x2, y2 ) ){
return;
}
for ( int i = 0; i < numQuads(); i++ ){
quads[i]->gather( rx + quads[i]->getX1( xflipped ), ry + quads[i]->getY1( yflipped ), x1, y1, x2, y2, collides, xflipped, yflipped );
}
if ( full ){
collides.push_back( this );
}
}
bool EQuad::collide( int mx, int my, int x1, int y1, int x2, int y2, EQuad ** last, bool xflipped, bool yflipped ){
/*
int rx = mx + getMinX();
int ry = my + getMinY();
if ( parent ){
if ( xflipped ){
rx = mx + parent->getWidth() - (getMinX()+getWidth());
}
if ( yflipped ){
ry = my + parent->getHeight() - (getMinY()+getHeight());
}
}
*/
int rx = mx + getX1( xflipped );
int ry = my + getY1( yflipped );
int rx2 = rx + getWidth();
int ry2 = ry + getHeight();
// rect( screen, rx, ry, rx2, ry2, makecol(255,255,0) );
bool cy = boxCollide( rx, ry, rx2, ry2, x1, y1, x2, y2 );
if ( !cy ) return false;
for ( int i = 0; i < numQuads(); i++ )
if ( quads[i]->collide( rx, ry, x1, y1, x2, y2, last ) )
return true;
if ( !full ) return false;
if ( cy ) *last = this;
return cy;
return false;
}
EQuad::~EQuad(){
/*
if ( quad1 ) delete quad1;
if ( quad2 ) delete quad2;
if ( quad3 ) delete quad3;
if ( quad4 ) delete quad4;
*/
for ( int q = 0; q < 4; q++ )
if ( quads[q] != NULL )
delete quads[q];
}
long long ECollide::totalTime = 0;
-void ECollide::initECollide( const Bitmap * who, int mask_pixel ){
+void ECollide::initECollide( const Graphics::Bitmap * who, int mask_pixel ){
/*
TimeDifference dif;
dif.startTime();
*/
head_quad = new EQuad( who, MIN_SIZE, mask_pixel, 0, 0, NULL );
last_collide = NULL;
/*
dif.endTime();
totalTime += dif.getTime();
cout<<"Total time taken: "<< totalTime / 1000 <<" ms" <<endl;
*/
}
-ECollide::ECollide( const Bitmap * who, int mask_pixel ){
+ECollide::ECollide( const Graphics::Bitmap * who, int mask_pixel ){
initECollide( who, mask_pixel );
/*
head_quad = new EQuad( who, MIN_SIZE, mask_pixel, 0, 0, NULL );
last_collide = NULL;
*/
}
-ECollide::ECollide( const Bitmap & who, int mask_pixel ){
+ECollide::ECollide( const Graphics::Bitmap & who, int mask_pixel ){
initECollide( &who, mask_pixel );
/*
head_quad = new EQuad( &who, MIN_SIZE, mask_pixel, 0, 0, NULL );
last_collide = NULL;
*/
}
#if 0
ECollide::ECollide( BITMAP * who, int mask_pixel ){
Bitmap tmp( who );
initECollide( &tmp, mask_pixel );
/*
head_quad = new EQuad( &tmp, MIN_SIZE, mask_pixel, 0, 0, NULL );
last_collide = NULL;
*/
}
#endif
ECollide::ECollide( int width, int height ){
last_collide = NULL;
head_quad = new EQuad( width, height, NULL );
}
ECollide::ECollide( const ECollide * e ){
initQuad( e->head_quad );
/*
last_collide = NULL;
head_quad = new EQuad( e->head_quad );
*/
}
ECollide::ECollide( const ECollide & e ){
initQuad( e.head_quad );
/*
last_collide = NULL;
head_quad = new EQuad( e.head_quad );
*/
}
ECollide::ECollide( EQuad * const head ){
initQuad( head );
/*
last_collide = NULL;
head_quad = new EQuad( head );
*/
}
void ECollide::initQuad( EQuad * const head ){
last_collide = NULL;
head_quad = new EQuad( head );
}
ECollide * ECollide::copy(){
return new ECollide( head_quad );
}
int ECollide::getMinHeight(){
return head_quad->getMinY();
}
int ECollide::getMaxHeight(){
return head_quad->getMinY() + head_quad->getHeight();
}
int ECollide::getMinWidth(){
return head_quad->getMinX();
}
int ECollide::getMaxWidth(){
return head_quad->getMinX() + head_quad->getWidth();
}
int ECollide::calcSize(){
int total = sizeof(*this);
if ( head_quad )
total += head_quad->calcSize();
return total;
}
bool ECollide::collide( int mx, int my, int x1, int y1, int x2, int y2, bool xflipped, bool yflipped ){
last_collide = NULL;
return head_quad->collide(mx,my,x1,y1,x2,y2, &last_collide, xflipped, yflipped );
}
bool ECollide::collide( int mx, int my, int x1, int y1, int x2, int y2, EQuad ** last, bool xflipped, bool yflipped ){
return head_quad->collide(mx,my,x1,y1,x2,y2, last, xflipped, yflipped );
}
void ECollide::gather( int mx, int my, int x1, int y1, int x2, int y2, vector< EQuad * > & e, bool xflipped, bool yflipped ){
return head_quad->gather( mx, my, x1, y1, x2, y2, e, xflipped, yflipped );
}
bool ECollide::Collision( int mx, int my, int ax, int ay, bool xflipped, bool ylfipped ){
return collide( mx, my, ax, ay, ax, ay );
}
bool ECollide::Collision( int mx, int my, int x1, int y1, int x2, int y2, bool xflipped, bool yflipped ){
return collide( mx, my, x1, y1, x2, y2 );
}
bool ECollide::Collision( ECollide * col, int mx, int my, int ax, int ay, bool my_xflipped, bool my_yflipped, bool him_xflipped, bool him_yflipped ){
if ( !col ) return false;
int x1 = mx > ax ? mx : ax;
int y1 = my > ay ? my : ay;
int x2 = (mx+getWidth()) < (ax+col->getWidth()) ? (mx+getWidth()) : (ax+col->getWidth());
int y2 = (my+getHeight()) < (ay+col->getHeight()) ? (my+getHeight()) : (ay+col->getHeight());
if ( x1 > x2 ) return false;
if ( y1 > y2 ) return false;
vector< EQuad * > collides1;
gather( mx, my, x1, y1, x2, y2, collides1, my_xflipped, my_yflipped );
vector< EQuad * > collides2;
col->gather( ax, ay, x1, y1, x2, y2, collides2, him_xflipped, him_yflipped );
for ( vector< EQuad * >::iterator it = collides1.begin(); it != collides1.end(); it++ ){
EQuad * e = *it;
int px1 = mx + e->getFullX1( my_xflipped );
int py1 = my + e->getFullY1( my_yflipped );
int px2 = px1 + e->getWidth();
int py2 = py1 + e->getHeight();
// Bitmap::Screen->rectangle( px1, py1, px2, py2, Bitmap::makeColor( 128, 128, 255 ) );
for ( vector< EQuad * >::iterator it2 = collides2.begin(); it2 != collides2.end(); it2++ ){
EQuad * e2 = *it2;
int zx1 = ax + e2->getFullX1( him_xflipped );
int zy1 = ay + e2->getFullY1( him_yflipped );
// printf( "Test %d,%d,%d,%d against %d,%d,%d,%d\n", px1, py1, px2, py2, zx1, zy1, zx1 + e2->getWidth(), zy1 + e2->getHeight() );
// Bitmap::Screen->rectangle( zx1, zy1, zx1 + e2->getWidth(), zy1 + e2->getHeight(), Bitmap::makeColor( Util::rnd( 255 ), 255, 255 ) );
// if ( e2->collide( zx1, zy1, px1, py1, px2, py2, &last_collide, him_xflipped, him_yflipped ) ){
if ( boxCollide( px1, py1, px2, py2, zx1, zy1, zx1 + e2->getWidth(), zy1 + e2->getHeight() ) ){
// Bitmap::Screen->rectangle( zx1, zy1, zx1 + e2->getWidth(), zy1 + e2->getHeight(), Bitmap::makeColor( 255, 255, 0 ) );
// cout << "Collided!" << endl;
// rest( 1000 );
return true;
}
}
}
// rest( 100 );
return false;
/*
return ( collide(mx,my,x1,y1,x2,y2,my_xflipped,my_yflipped) && col->collide(ax,ay,x1,y1,x2,y2,him_xflipped,him_yflipped) );
*/
}
/*
int ECollide::getWidth() const{
return head_quad->getWidth();
}
int ECollide::getHeight() const{
return head_quad->getHeight();
}
*/
-void ECollide::draw( const Bitmap & work, int x, int y, int color, bool flipped ){
+void ECollide::draw( const Graphics::Bitmap & work, int x, int y, int color, bool flipped ){
head_quad->draw( work, x, y, color, flipped );
}
int ECollide::numQuads() const{
return head_quad->totalQuads();
}
-void ECollide::draw( const Bitmap & work, int x, int y, int color, EQuad * who ){
+void ECollide::draw( const Graphics::Bitmap & work, int x, int y, int color, EQuad * who ){
if ( head_quad == who )
head_quad->draw( work, x, y, color );
else head_quad->draw( work, x, y, color, who );
}
EQuad * ECollide::getLast(){
return last_collide;
}
ECollide::~ECollide(){
delete head_quad;
}
diff --git a/util/ebox.h b/util/ebox.h
index 7108b95b..ca37db3f 100644
--- a/util/ebox.h
+++ b/util/ebox.h
@@ -1,176 +1,176 @@
/* ebox version 3:
* by Jon Rafkind
*/
#ifndef _ebox_3_h
#define _ebox_3_h
#include "bitmap.h"
#include <vector>
class EQuad{
public:
EQuad( EQuad * const head );
EQuad( int w, int h, EQuad * _parent );
- EQuad( const Bitmap * who, int min_size, int mask_pixel, int min_x, int min_y, EQuad * _parent );
+ EQuad( const Graphics::Bitmap * who, int min_size, int mask_pixel, int min_x, int min_y, EQuad * _parent );
- void draw( const Bitmap & work, int x, int y, int color, bool flipped = false );
- void draw( const Bitmap & work, int x, int y, int color, EQuad * who );
+ void draw( const Graphics::Bitmap & work, int x, int y, int color, bool flipped = false );
+ void draw( const Graphics::Bitmap & work, int x, int y, int color, EQuad * who );
inline int getWidth() const{
return width;
}
inline int getHeight() const{
return height;
}
inline void setFull( bool x ){
full = x;
}
EQuad * getQuad( int x ) const;
bool addQuad( EQuad * who );
inline int getPosX() const {
if ( parent )
return min_x + parent->getPosX();
return min_x;
}
inline int getPosY() const {
if ( parent )
return min_y + parent->getPosY();
return min_y;
}
void gather( int mx, int my, int x1, int y1, int x2, int y2, std::vector< EQuad * > & collides, bool xflipped, bool yflipped );
// bool collide( int mx, int my, int x1, int y1, int x2, int y2, EQuad ** last );
bool collide( int mx, int my, int x1, int y1, int x2, int y2, EQuad ** last, bool xflipped = false, bool yflipped = false );
// int collide( int mx, int my, int x1, int y1, int x2, int y2, EQuad ** last, int depth );
int calcSize();
void setMinX( int x );
void setMinY( int y );
int getFullX1( bool xflipped = false );
int getFullY1( bool yflipped = false );
inline int getMinX() const{
return min_x;
}
inline int getMinY() const{
return min_y;
}
int totalQuads();
~EQuad();
protected:
int getX1( bool xflipped = false );
int getY1( bool yflipped = false );
EQuad * getQuad() const;
void detach( EQuad * const who );
void checkQuad( EQuad *& q );
inline int numQuads() const{
int total = 0;
if ( quads[0] != NULL ) total++;
if ( quads[1] != NULL ) total++;
if ( quads[2] != NULL ) total++;
if ( quads[3] != NULL ) total++;
// for ( int total = 0; total < 4 && quads[total] != NULL; total++ );
return total;
}
bool empty();
// bool boxCollide( int zx1, int zy1, int zx2, int zy2, int zx3, int zy3, int zx4, int zy4 );
protected:
int width, height;
// EQuad * quad1, * quad2, * quad3, * quad4;
bool full;
int min_x, min_y;
EQuad * quads[ 4 ];
EQuad * parent;
int num_quads;
};
class ECollide{
public:
ECollide( EQuad * const head );
- // ECollide( BITMAP * who, int mask_pixel = Bitmap::MaskColor );
- ECollide( const Bitmap * who, int mask_pixel = Bitmap::MaskColor() );
- ECollide( const Bitmap & who, int mask_pixel = Bitmap::MaskColor() );
+ // ECollide( Graphics::BITMAP * who, int mask_pixel = Bitmap::MaskColor );
+ ECollide( const Graphics::Bitmap * who, int mask_pixel = Graphics::Bitmap::MaskColor() );
+ ECollide( const Graphics::Bitmap & who, int mask_pixel = Graphics::Bitmap::MaskColor() );
ECollide( const ECollide & e );
ECollide( const ECollide * e );
ECollide( int width, int height );
- void draw( const Bitmap & work, int x, int y, int color, bool flipped = false );
- void draw( const Bitmap & work, int x, int y, int color, EQuad * who );
+ void draw( const Graphics::Bitmap & work, int x, int y, int color, bool flipped = false );
+ void draw( const Graphics::Bitmap & work, int x, int y, int color, EQuad * who );
bool Collision( ECollide * col, int mx, int my, int ax, int ay, bool my_xflipped = false, bool my_yflipped = false, bool him_xflipped = false, bool him_flipped = false );
bool Collision( int mx, int my, int ax, int ay, bool xflipped = false, bool yflipped = false );
bool Collision( int mx, int my, int x1, int y1, int x2, int y2, bool xflipped = false, bool yflipped = false );
int getMinHeight();
int getMaxHeight();
int getMinWidth();
int getMaxWidth();
ECollide * copy();
EQuad * getLast();
EQuad * getHead() const{
return head_quad;
}
void gather( int mx, int my, int x1, int y1, int x2, int y2, std::vector< EQuad * > & e, bool xflipped, bool yflipped );
int calcSize();
inline int getWidth() const{
return head_quad->getWidth();
}
inline int getHeight() const{
return head_quad->getHeight();
}
int numQuads() const;
~ECollide();
private:
- void initECollide( const Bitmap * who, int mask_pixel );
+ void initECollide( const Graphics::Bitmap * who, int mask_pixel );
void initQuad( EQuad * const head );
static long long totalTime;
protected:
bool collide( int mx, int my, int x1, int y1, int x2, int y2, bool xflipped = false, bool yflipped = false );
bool collide( int mx, int my, int x1, int y1, int x2, int y2, EQuad ** last, bool xflipped, bool yflipped );
// bool collide( int mx, int my, int x1, int y1 );
EQuad * head_quad;
EQuad * last_collide;
};
#endif
diff --git a/util/events.cpp b/util/events.cpp
index 5e070673..6d1d0258 100644
--- a/util/events.cpp
+++ b/util/events.cpp
@@ -1,230 +1,230 @@
#ifdef USE_SDL
#include <SDL.h>
#endif
#include "bitmap.h"
#include "events.h"
#include "exceptions/shutdown_exception.h"
#include "configuration.h"
#include "debug.h"
#include "funcs.h"
#include "thread.h"
#include "input/keyboard.h"
#include "input/joystick.h"
#include "input/input-manager.h"
namespace Util{
EventManager::EventManager():
bufferKeys(false){
}
#ifdef USE_SDL
static void handleKeyDown(Keyboard & keyboard, const SDL_Event & event){
keyboard.press(event.key.keysym.sym, event.key.keysym.unicode);
}
static void handleKeyUp(Keyboard & keyboard, const SDL_Event & event){
keyboard.release(event.key.keysym.sym);
}
static void handleJoystickButtonUp(Joystick * joystick, const SDL_Event & event){
int device = event.jbutton.which;
int button = event.jbutton.button;
if (device == joystick->getDeviceId()){
joystick->releaseButton(button);
}
}
static void handleJoystickHat(Joystick * joystick, const SDL_Event & event){
int device = event.jhat.which;
int motion = event.jhat.value;
/* should up/down control left/right -- flip these values? */
#if WII
const int axis_up_down = 0;
const int axis_left_right = 1;
const int up = 1;
const int down = -1;
const int left = -1;
const int right = 1;
#else
const int axis_up_down = 1;
const int axis_left_right = 0;
const int up = -1;
const int down = 1;
const int left = -1;
const int right = 1;
#endif
switch (motion){
case SDL_HAT_CENTERED: break;
case SDL_HAT_UP: joystick->axisMotion(axis_up_down, up); break;
case SDL_HAT_DOWN: joystick->axisMotion(axis_up_down, down); break;
case SDL_HAT_RIGHT: joystick->axisMotion(axis_left_right, right); break;
case SDL_HAT_LEFT: joystick->axisMotion(axis_left_right, left); break;
default: break;
}
}
static void handleJoystickButtonDown(Joystick * joystick, const SDL_Event & event){
int device = event.jbutton.which;
int button = event.jbutton.button;
if (device == joystick->getDeviceId()){
joystick->pressButton(button);
}
}
static void handleJoystickAxis(Joystick * joystick, const SDL_Event & event){
int device = event.jaxis.which;
int axis = event.jaxis.axis;
int value = event.jaxis.value;
if (device == joystick->getDeviceId()){
joystick->axisMotion(axis, value);
}
}
void EventManager::runSDL(Keyboard & keyboard, Joystick * joystick){
keyboard.poll();
if (joystick){
joystick->poll();
}
SDL_Event event;
while (SDL_PollEvent(&event) == 1){
switch (event.type){
case SDL_QUIT : {
dispatch(CloseWindow);
break;
}
case SDL_KEYDOWN : {
handleKeyDown(keyboard, event);
// dispatch(Key, event.key.keysym.sym);
break;
}
case SDL_KEYUP : {
handleKeyUp(keyboard, event);
break;
}
case SDL_JOYBUTTONDOWN: {
if (joystick != NULL){
handleJoystickButtonDown(joystick, event);
}
break;
}
case SDL_JOYHATMOTION : {
if (joystick != NULL){
handleJoystickHat(joystick, event);
}
break;
}
case SDL_JOYBUTTONUP: {
if (joystick != NULL){
handleJoystickButtonUp(joystick, event);
}
break;
}
case SDL_JOYAXISMOTION: {
if (joystick != NULL){
handleJoystickAxis(joystick, event);
}
break;
}
case SDL_VIDEORESIZE : {
int width = event.resize.w;
int height = event.resize.h;
/* to keep the perspective correct
* 640/480 = 1.33333
*/
if (width > height){
height = (int)((double) width / 1.3333333333);
} else {
width = (int)((double) height * 1.3333333333);
}
dispatch(ResizeScreen, width, height);
break;
}
default : {
break;
}
}
}
}
#endif
#ifdef USE_ALLEGRO
void EventManager::runAllegro(Keyboard & keyboard, Joystick * joystick){
keyboard.poll();
}
#endif
void EventManager::run(Keyboard & keyboard, Joystick * joystick){
#ifdef USE_SDL
runSDL(keyboard, joystick);
#elif USE_ALLEGRO
runAllegro(keyboard, joystick);
#endif
}
/* kill the program if the user requests */
void EventManager::waitForThread(WaitThread & thread){
// Keyboard dummy;
while (!thread.isRunning()){
try{
/* input manager will run the event manager */
InputManager::poll();
// run(dummy);
} catch (const ShutdownException & death){
thread.kill();
throw death;
}
Util::rest(10);
}
}
EventManager::~EventManager(){
}
void EventManager::enableKeyBuffer(){
bufferKeys = true;
}
void EventManager::disableKeyBuffer(){
bufferKeys = false;
}
void EventManager::dispatch(Event type, int arg1){
switch (type){
case Key : {
if (bufferKeys){
keys.push_back(KeyType(arg1));
}
break;
}
default : {
break;
}
}
}
void EventManager::dispatch(Event type, int arg1, int arg2){
switch (type){
case ResizeScreen : {
Global::debug(1) << "Resizing screen to " << arg1 << ", " << arg2 << std::endl;
- if (Bitmap::setGraphicsMode(0, arg1, arg2) == 0){
+ if (Graphics::Bitmap::setGraphicsMode(0, arg1, arg2) == 0){
Configuration::setScreenWidth(arg1);
Configuration::setScreenHeight(arg2);
}
break;
}
default : break;
}
}
void EventManager::dispatch(Event type){
switch (type){
case CloseWindow : {
throw ShutdownException();
}
default : break;
}
}
}
diff --git a/util/fire.cpp b/util/fire.cpp
index 18775c99..f7ebdde9 100644
--- a/util/fire.cpp
+++ b/util/fire.cpp
@@ -1,172 +1,170 @@
#include "bitmap.h"
#include <vector>
#include "fire.h"
#include <string.h>
#include "funcs.h"
#include <math.h>
-class Bitmap;
-
namespace Paintown{
static int MAX_X = 320;
static int MAX_Y = 240;
Fire::Fire(){
- Util::blend_palette(colors, 64, Bitmap::makeColor(64, 0, 0), Bitmap::makeColor(255, 0, 0));
- Util::blend_palette(colors + 64, 64, Bitmap::makeColor(255, 0, 0), Bitmap::makeColor(255, 255, 0));
- Util::blend_palette(colors + 64 + 64, 96, Bitmap::makeColor(255, 255, 0), Bitmap::makeColor(255, 255, 255));
- Util::blend_palette(colors + 64 + 64 + 64 + 32, 32, Bitmap::makeColor(255, 255, 255), Bitmap::makeColor(255, 255, 255));
+ Util::blend_palette(colors, 64, Graphics::Bitmap::makeColor(64, 0, 0), Graphics::Bitmap::makeColor(255, 0, 0));
+ Util::blend_palette(colors + 64, 64, Graphics::Bitmap::makeColor(255, 0, 0), Graphics::Bitmap::makeColor(255, 255, 0));
+ Util::blend_palette(colors + 64 + 64, 96, Graphics::Bitmap::makeColor(255, 255, 0), Graphics::Bitmap::makeColor(255, 255, 255));
+ Util::blend_palette(colors + 64 + 64 + 64 + 32, 32, Graphics::Bitmap::makeColor(255, 255, 255), Graphics::Bitmap::makeColor(255, 255, 255));
data = new unsigned char*[MAX_Y];
for (int i = 0; i < MAX_Y; i++){
data[i] = new unsigned char[MAX_X];
memset(data[i], 0, MAX_X);
}
for (int i = 0; i < MAX_HOTSPOTS; i++){
hotspots[i] = Util::rnd(MAX_X);
directions[i] = 0;
}
for (int i = 0; i < MAX_WISPS; i++){
Wisp & wisp = wisps[i];
wisp.y = MAX_Y-1 + Util::rnd(MAX_Y);
wisp.x = Util::rnd(MAX_X);
wisp.life = MAX_Y;
wisp.angle = Util::rnd(360);
}
}
void Fire::updateHotspots(){
for (int i = 0; i < MAX_HOTSPOTS; i++){
// hotspots[i] = (hotspots[i] + Util::rnd(5) - 2) % MAX_X;
hotspots[i] += directions[i];
if (hotspots[i] >= MAX_X){
hotspots[i] -= MAX_X;
}
if (hotspots[i] < 0){
hotspots[i] += MAX_X;
}
directions[i] += (double) (Util::rnd(7) - 3) / 5.0;
if (directions[i] < -4){
directions[i] = -4;
}
if (directions[i] > 4){
directions[i] = 4;
}
}
int hotspot_length = 40;
for (int i = 0; i < MAX_HOTSPOTS; i++){
for (int x = -hotspot_length/2; x < hotspot_length/2; x++){
int position = ((int) hotspots[i] + x + MAX_X) % MAX_X;
int more = (int) (data[MAX_Y-1][position] + (hotspot_length / 2 - fabs(x)));
if (more >= MAX_COLORS){
more = MAX_COLORS - 1;
}
data[MAX_Y-1][position] = more;
}
}
}
void Fire::updateWisps(){
for (int i = 0; i < MAX_WISPS; i++){
Wisp & wisp = wisps[i];
wisp.y -= 2;
wisp.life -= 1;
wisp.angle = (wisp.angle + 1) % 360;
if (wisp.life < 0){
wisp.y = MAX_Y-1 + Util::rnd(MAX_Y);
wisp.life = MAX_Y;
}
int my = (int) wisp.y;
int mx = (int)(wisp.x + sin(Util::radians(wisp.angle)) * 10);
if (mx < 0){
mx += MAX_X;
}
if (mx >= MAX_X){
mx -= MAX_X;
}
if (my > 0 && my < MAX_Y){
int z = data[my][mx] + wisp.life * 2;
if (z >= MAX_COLORS){
z = MAX_COLORS - 1;
}
// z = MAX_COLORS - 1;
// std::cout << "Update flicker at " << mx << ", " << my << " to " << z << std::endl;
data[my][mx] = z;
}
}
}
void Fire::update(){
updateHotspots();
// updateWisps();
int decay = 1;
// for (int y = MAX_Y-1; y > 0; y--){
for (int y = 0; y < MAX_Y; y++){
for (int x = 0; x < MAX_X; x++){
if (y < MAX_Y-1){
int lx = x-1;
if (lx < 0){
lx += MAX_X;
}
int rx = x+1;
if (rx >= MAX_X){
rx -= MAX_X;
}
// int less = (int)((double) data[y+1][x] * 0.6 + (double) data[y+1][lx] * 0.3 + (double) data[y+1][rx] * 0.3);
unsigned char * down = data[y+1];
/* dont change these numbers (0.2, 0.62, 9) because they affect
* the height of the flames. if the value of fire does not go down
* monotonically then the entire screen will be filled with flames.
*/
int less = (int)((double) down[lx] * 0.19);
less += (int)((double) down[rx] * 0.19);
less += (int)((double) down[x] * (0.4 + Util::rnd(25) / 100.0));
less += (int)((double) data[y][x] * 0.10);
// less -= Util::rnd(15);
if (less < 0){
less = 0;
}
if (less >= MAX_COLORS){
less = MAX_COLORS - 1;
}
data[y][x] = (unsigned char) less;
} else {
int less = (int)((double) data[y][x] * 0.95);
if (less < 0){
less = 0;
}
data[y][x] = (unsigned char) less;
}
}
}
}
-void Fire::draw(const Bitmap & work){
+void Fire::draw(const Graphics::Bitmap & work){
// Bitmap::drawingMode(Bitmap::MODE_TRANS);
for (int y = 0; y < MAX_Y; y++){
for (int x = 0; x < MAX_X; x++){
// work.putPixel(x, y, colors[data[y][x]]);
if (data[y][x] > 0){
work.rectangleFill(x*2, y*2, x*2+1, y*2+1, colors[data[y][x]]);
}
}
}
// Bitmap::drawingMode(Bitmap::MODE_SOLID);
}
Fire::~Fire(){
for (int y = 0; y < MAX_Y; y++){
delete[] data[y];
}
delete[] data;
}
}
diff --git a/util/fire.h b/util/fire.h
index 900d5fb0..439a1249 100644
--- a/util/fire.h
+++ b/util/fire.h
@@ -1,41 +1,43 @@
#ifndef _paintown_fire_93c6678306f3542737be4288dc09cfa9
#define _paintown_fire_93c6678306f3542737be4288dc09cfa9
+namespace Graphics{
class Bitmap;
+}
namespace Paintown{
struct Wisp{
double x, y;
int life;
int angle;
};
class Fire{
public:
Fire();
void update();
- void draw(const Bitmap & work);
+ void draw(const Graphics::Bitmap & work);
virtual ~Fire();
protected:
void updateHotspots();
void updateWisps();
protected:
unsigned char ** data;
/* enough to fill an unsigned char */
static const int MAX_COLORS = 256;
int colors[MAX_COLORS];
static const int MAX_HOTSPOTS = 10;
double hotspots[MAX_HOTSPOTS];
double directions[MAX_HOTSPOTS];
static const int MAX_WISPS = 30;
Wisp wisps[MAX_WISPS];
};
}
#endif
diff --git a/util/font.cpp b/util/font.cpp
index de4ae83b..839c14ec 100644
--- a/util/font.cpp
+++ b/util/font.cpp
@@ -1,306 +1,306 @@
#ifdef USE_ALLEGRO
/* for textout_* and whatnot */
#include <allegro.h>
#endif
#include "bitmap.h"
#include "font.h"
#include "funcs.h"
#include "init.h"
#include "ftalleg.h"
#include "factory/font_factory.h"
#include <string.h>
using namespace std;
Font::Font(){
}
/* copy/pasted from network/message.cpp */
static vector< string > wrapStrings( const string & left, const string & right, const Font & font, int max, vector< string > accum ){
if ( left == "" ){
return accum;
}
int length = font.textLength(left.c_str());
if (length >= max){
return wrapStrings( left.substr( 0, left.length() / 2 ), left.substr( left.length() / 2 ) + right, font, max, accum );
} else if ( length >= max - font.textLength( "E" ) || right == "" ){
accum.push_back( left );
return wrapStrings( right, "", font, max, accum );
} else {
return wrapStrings( left + right.substr( 0, 1 ), right.substr( 1 ), font, max, accum );
}
}
-void Font::printfWrapLine(int x, int & y, int color, const Bitmap & work, int maxWidth, const char * line) const {
+void Font::printfWrapLine(int x, int & y, int color, const Graphics::Bitmap & work, int maxWidth, const char * line) const {
vector< string > all;
all = wrapStrings(string(line), "", *this, maxWidth, all );
for ( vector< string >::iterator str = all.begin(); str != all.end(); str++ ){
printf(x, y, color, work, *str, 0);
y += getHeight();
}
y += getHeight() / 2;
}
#if 0
void Font::printfWrapLine2(int x, int & y, int color, const Bitmap & work, int maxWidth, const char * line) const {
int height = getHeight();
while (*line != '\0'){
char tmp2[1024];
int left = strlen(line);
int min = 0;
int max = left;
int current = (min + max) / 2;
strncpy(tmp2, line, current);
tmp2[current] = '\0';
bool done = false;
while (!done){
int length = textLength(tmp2);
if (length >= maxWidth){
max = current;
current = (min + max) / 2;
strncpy(tmp2, line, current);
tmp2[current] = '\0';
} else if (length < maxWidth && current < max){
min = current;
current = (min + max) / 2;
if (current == max - 1){
current = max;
done = true;
}
strncpy(tmp2, line, current);
tmp2[current] = '\0';
} else {
done = true;
}
}
printf(x, y, color, work, string(tmp2), 0);
y += height;
line += current;
}
y += height / 2;
}
#endif
-void Font::printfWrap(int x, int y, int color, const Bitmap & work, int maxWidth, const std::string & str, int marker, ... ) const {
+void Font::printfWrap(int x, int y, int color, const Graphics::Bitmap & work, int maxWidth, const std::string & str, int marker, ... ) const {
char buf[4096];
va_list ap;
va_start(ap, marker);
Util::limitPrintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
char * start = buf;
char * end = strchr(start, '\n');
while (end != NULL){
char tmp[1024];
unsigned int ender = end - start;
if (ender >= sizeof(tmp) - 1){
ender = sizeof(tmp) - 1;
}
strncpy(tmp, start, ender);
tmp[ender] = '\0';
printfWrapLine(x, y, color, work, maxWidth, tmp);
start = end + 1;
end = strchr(start, '\n');
}
printfWrapLine(x, y, color, work, maxWidth, start);
}
Font::~Font(){
}
#ifdef USE_ALLEGRO
AllegroFont::AllegroFont( const FONT * const font ):
font(font){
}
AllegroFont::AllegroFont( const AllegroFont & copy ):
font( copy.getInternalFont() ){
}
AllegroFont::~AllegroFont(){
}
int AllegroFont::textLength( const char * text ) const{
return text_length( getInternalFont(), text );
}
int AllegroFont::getHeight( const string & str ) const {
return getHeight();
}
int AllegroFont::getHeight() const {
return text_height( getInternalFont() );
}
void AllegroFont::setSize( const int x, const int y ){
}
int AllegroFont::getSizeX() const {
return 0;
}
int AllegroFont::getSizeY() const {
return 0;
}
-void AllegroFont::printf( int x, int y, int xSize, int ySize, int color, const Bitmap & work, const string & str, int marker, ... ) const {
+void AllegroFont::printf( int x, int y, int xSize, int ySize, int color, const Graphics::Bitmap & work, const string & str, int marker, ... ) const {
char buf[512];
va_list ap;
va_start(ap, marker);
Util::limitPrintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
textout_ex(work.getData().getBitmap(), getInternalFont(), buf, x, y, color, -1);
}
-void AllegroFont::printf( int x, int y, int color, const Bitmap & work, const string & str, int marker, ... ) const {
+void AllegroFont::printf( int x, int y, int color, const Graphics::Bitmap & work, const string & str, int marker, ... ) const {
char buf[512];
va_list ap;
va_start(ap, marker);
uvszprintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
textout_ex(work.getData().getBitmap(), getInternalFont(), buf, x, y, color, -1);
}
#endif
const Font & Font::getDefaultFont(){
// return getFont( "tmp/comic.ttf" );
// return *FontFactory::getFont(Filesystem::RelativePath("bios"), 16, 16);
return *FontFactory::getFont(Filesystem::RelativePath("fonts/arial.ttf"), 16, 16);
}
const Font & Font::getDefaultFont(int width, int height){
return *FontFactory::getFont(Filesystem::RelativePath("fonts/arial.ttf"), width, height);
}
/* name should be the path of a .ttf file in the fonts/ directory.
* something like 'arial.ttf'
*/
const Font & Font::getFont(const Filesystem::RelativePath & name, const int x, const int y){
Font & font = *FontFactory::getFont(name, x, y);
/* sanity check */
if (font.getHeight("A") == 0){
return getDefaultFont();
}
return font;
}
const Font & Font::getFont( const Filesystem::AbsolutePath & name, const int x, const int y){
return *FontFactory::getFont(name, x, y);
}
FreeTypeFont::FreeTypeFont(const Filesystem::AbsolutePath & str ):
sizeX( 16 ),
sizeY( 16 ),
own(true){
this->font = new ftalleg::freetype(str, getSizeX(), getSizeY() );
}
int FreeTypeFont::getHeight( const string & str ) const {
return this->font->getHeight( str );
}
int FreeTypeFont::getHeight() const {
return getHeight( "A" );
}
int FreeTypeFont::textLength( const char * text ) const {
return this->font->getLength(string(text));
}
-void FreeTypeFont::printf( int x, int y, int xSize, int ySize, int color, const Bitmap & work, const string & str, int marker, ... ) const {
+void FreeTypeFont::printf( int x, int y, int xSize, int ySize, int color, const Graphics::Bitmap & work, const string & str, int marker, ... ) const {
char buf[512];
va_list ap;
va_start(ap, marker);
vsnprintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
int old_x = 0;
int old_y = 0;
this->font->getSize(&old_x, &old_y);
this->font->setSize(xSize, ySize);
this->font->render( x, y, color, work, ftalleg::freetype::ftLeft, string( buf ), 0 );
this->font->setSize(old_x, old_y);
}
-void FreeTypeFont::printf( int x, int y, int color, const Bitmap & work, const string & str, int marker, ... ) const {
+void FreeTypeFont::printf( int x, int y, int color, const Graphics::Bitmap & work, const string & str, int marker, ... ) const {
char buf[512];
va_list ap;
va_start(ap, marker);
vsnprintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
this->font->render(x, y, color, work, ftalleg::freetype::ftLeft, string(buf), 0);
}
void FreeTypeFont::setSize( const int x, const int y ){
this->sizeX = x;
this->sizeY = y;
this->font->setSize( this->sizeX, this->sizeY );
}
int FreeTypeFont::getSizeX() const {
return this->sizeX;
}
int FreeTypeFont::getSizeY() const {
return this->sizeY;
}
FreeTypeFont::~FreeTypeFont(){
// cout << "Delete font " << this->font << endl;
if (own){
delete this->font;
}
}
NullFont::NullFont(){
}
NullFont::~NullFont(){
}
void NullFont::setSize( const int x, const int y ){
}
int NullFont::getSizeX() const {
return 0;
}
int NullFont::getSizeY() const {
return 0;
}
int NullFont::textLength( const char * text ) const {
return 0;
}
int NullFont::getHeight( const std::string & str ) const {
return 0;
}
int NullFont::getHeight() const {
return 0;
}
-void NullFont::printf( int x, int y, int xSize, int ySize, int color, const Bitmap & work, const std::string & str, int marker, ... ) const {
+void NullFont::printf( int x, int y, int xSize, int ySize, int color, const Graphics::Bitmap & work, const std::string & str, int marker, ... ) const {
}
-void NullFont::printf( int x, int y, int color, const Bitmap & work, const std::string & str, int marker, ... ) const {
+void NullFont::printf( int x, int y, int color, const Graphics::Bitmap & work, const std::string & str, int marker, ... ) const {
}
diff --git a/util/font.h b/util/font.h
index 3b817849..4191b245 100644
--- a/util/font.h
+++ b/util/font.h
@@ -1,120 +1,123 @@
#ifndef _paintown_font_h
#define _paintown_font_h
#include <string>
#include <vector>
// #include "ftalleg.h"
+namespace Graphics{
class Bitmap;
+}
+
struct FONT;
namespace ftalleg{
class freetype;
}
namespace Filesystem{
class RelativePath;
class AbsolutePath;
}
/* handle allegro fonts and true type fonts */
class Font{
public:
Font();
virtual ~Font();
virtual void setSize( const int x, const int y ) = 0;
virtual int getSizeX() const = 0;
virtual int getSizeY() const = 0;
virtual int textLength( const char * text ) const = 0;
virtual int getHeight( const std::string & str ) const = 0;
virtual int getHeight() const = 0;
- virtual void printf( int x, int y, int xSize, int ySize, int color, const Bitmap & work, const std::string & str, int marker, ... ) const = 0;
- virtual void printf( int x, int y, int color, const Bitmap & work, const std::string & str, int marker, ... ) const = 0;
- virtual void printfWrap( int x, int y, int color, const Bitmap & work, int maxWidth, const std::string & str, int marker, ... ) const;
+ virtual void printf( int x, int y, int xSize, int ySize, int color, const Graphics::Bitmap & work, const std::string & str, int marker, ... ) const = 0;
+ virtual void printf( int x, int y, int color, const Graphics::Bitmap & work, const std::string & str, int marker, ... ) const = 0;
+ virtual void printfWrap( int x, int y, int color, const Graphics::Bitmap & work, int maxWidth, const std::string & str, int marker, ... ) const;
static const Font & getDefaultFont();
static const Font & getDefaultFont(int width, int height);
static const Font & getFont( const Filesystem::RelativePath & name, const int x = 32, const int y = 32 );
static const Font & getFont( const Filesystem::AbsolutePath & name, const int x = 32, const int y = 32 );
/* store all the freetype fonts forever */
// static std::vector< ftalleg::freetype * > cacheFreeType;
protected:
- void printfWrapLine(int x, int & y, int color, const Bitmap & work, int maxWidth, const char * line) const;
+ void printfWrapLine(int x, int & y, int color, const Graphics::Bitmap & work, int maxWidth, const char * line) const;
};
class NullFont: public Font {
public:
NullFont();
virtual ~NullFont();
virtual void setSize( const int x, const int y );
virtual int getSizeX() const;
virtual int getSizeY() const;
virtual int textLength( const char * text ) const;
virtual int getHeight( const std::string & str ) const;
virtual int getHeight() const;
- virtual void printf( int x, int y, int xSize, int ySize, int color, const Bitmap & work, const std::string & str, int marker, ... ) const;
- virtual void printf( int x, int y, int color, const Bitmap & work, const std::string & str, int marker, ... ) const;
+ virtual void printf( int x, int y, int xSize, int ySize, int color, const Graphics::Bitmap & work, const std::string & str, int marker, ... ) const;
+ virtual void printf( int x, int y, int color, const Graphics::Bitmap & work, const std::string & str, int marker, ... ) const;
};
#ifdef USE_ALLEGRO
class AllegroFont: public Font {
public:
AllegroFont( const FONT * const font );
AllegroFont( const AllegroFont & copy );
virtual ~AllegroFont();
virtual int getHeight() const;
virtual int getHeight( const std::string & str ) const;
virtual int textLength( const char * text ) const;
- virtual void printf( int x, int y, int color, const Bitmap & work, const std::string & str, int marker, ... ) const;
- virtual void printf( int x, int y, int xSize, int ySize, int color, const Bitmap & work, const std::string & str, int marker, ... ) const;
+ virtual void printf( int x, int y, int color, const Graphics::Bitmap & work, const std::string & str, int marker, ... ) const;
+ virtual void printf( int x, int y, int xSize, int ySize, int color, const Graphics::Bitmap & work, const std::string & str, int marker, ... ) const;
virtual void setSize( const int x, const int y );
virtual int getSizeX() const;
virtual int getSizeY() const;
private:
inline const FONT * getInternalFont() const {
return font;
}
const FONT * const font;
};
#endif
class FreeTypeFont: public Font {
public:
FreeTypeFont(const Filesystem::AbsolutePath & filename);
FreeTypeFont(const FreeTypeFont & copy);
virtual ~FreeTypeFont();
virtual int getHeight() const;
virtual int getHeight( const std::string & str ) const;
virtual int textLength( const char * text ) const;
- virtual void printf( int x, int y, int color, const Bitmap & work, const std::string & str, int marker, ... ) const;
- virtual void printf( int x, int y, int xSize, int ySize, int color, const Bitmap & work, const std::string & str, int marker, ... ) const;
+ virtual void printf( int x, int y, int color, const Graphics::Bitmap & work, const std::string & str, int marker, ... ) const;
+ virtual void printf( int x, int y, int xSize, int ySize, int color, const Graphics::Bitmap & work, const std::string & str, int marker, ... ) const;
virtual void setSize( const int x, const int y );
virtual int getSizeX() const;
virtual int getSizeY() const;
private:
ftalleg::freetype * font;
int sizeX;
int sizeY;
bool own;
};
#endif
diff --git a/util/ftalleg.cpp b/util/ftalleg.cpp
index beb7f4fc..1e3c7424 100644
--- a/util/ftalleg.cpp
+++ b/util/ftalleg.cpp
@@ -1,593 +1,593 @@
/*
--------------
About
--------------
A Freetype wrapper for use with allegro
Feel free to do whatever you like with this, by all means enjoy!
Just add it to your project
--------------
Linking
--------------
on linux:
g++ `freetype-config --cflags` ftalleg.cpp myfiles.cpp `freetype-config --libs` `allegro-config --libs`
on windows (you may need to include the freetype dir location, ie -Ic:/mingw/include):
g++ ftalleg.cpp myfiles.cpp -lfreetype -lalleg
--------------
Disclaimer
--------------
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE
SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef FT_FONT_CPP
#define FT_FONT_CPP
#include "bitmap.h"
/*
#include <allegro.h>
#ifdef _WIN32
#include <winalleg.h>
#endif
*/
#include "ftalleg.h"
#include <iostream>
#include <sstream>
#include <cassert>
#include <exception>
namespace ftalleg{
Exception::Exception():
std::exception(){
}
Exception::Exception(const std::string reason):
std::exception(),
reason(reason){
}
Exception::~Exception() throw(){
}
// typedef void (*pixeler)( BITMAP * bitmap, int x, int y, int color );
static int fixColor(const unsigned char c, short grays){
// Safety checks
// assert(c != 0);
assert(grays != 1);
// invariant: c can be dereferenced safely
// invariant: (grays - 1) != 0, thus it can be used as divisor.
int red = c * 255 / (grays - 1);
int green = c * 255 / (grays - 1);
int blue = c * 255 / (grays - 1);
//alpha = *c * 255 / (grays - 1);
- return Bitmap::makeColor(red,green,blue);
+ return Graphics::Bitmap::makeColor(red,green,blue);
}
// Static count of instances of fonts to track library
static int instances = 0;
static FT_Library ftLibrary = 0;
character::character() {
}
character::~character() {
if (line){
delete [] line;
}
}
fontSize::fontSize() {
width = height = italics = angle = 0;
}
fontSize::~fontSize() {
}
bool fontSize::operator<(const fontSize &fs) const {
return (width<fs.width || height<fs.height || italics<fs.italics);
}
/* im not sure this is a very unique key.. */
int fontSize::createKey() const {
return ((width+10) * (height+20) * (italics+250));
}
//! Constructor
freetype::freetype(const Filesystem::AbsolutePath & str, const int x, const int y ):
face(NULL){
//Load library
if (!ftLibrary){
FT_Init_FreeType(&ftLibrary);
}
instances += 1;
faceLoaded = kerning = false;
currentIndex = 0;
currentFilename = "";
faceName = "";
// currentChar = new character;
systemName = "";
internalFix = false;
this->load(str, 0, x, y );
}
//! Destructor
freetype::~freetype(){
//if(face!=NULL)FT_Done_Face(face);
if (faceLoaded && face != NULL){
FT_Done_Face(face);
face = NULL;
}
instances -= 1;
if (instances == 0){
FT_Done_FreeType(ftLibrary);
ftLibrary = NULL;
}
destroyGlyphIndex();
/*
if ( currentChar ){
delete currentChar;
}
*/
}
void freetype::destroyGlyphIndex(){
for (std::map<int, std::map<signed long, character*> >::iterator i1 = fontTable.begin(); i1 != fontTable.end(); i1++){
std::map<signed long, character*> & characters = (*i1).second;
for (std::map<signed long, character*>::iterator i2 = characters.begin(); i2 != characters.end(); i2++){
character * character = (*i2).second;
delete character;
}
}
}
// Extract glyph
character * freetype::extractGlyph(signed long unicode){
int w, h, ew;
character * tempChar = new character();
// Translate it according to the given italics
double italics = (double)(size.italics)*GLYPH_PI/180;
FT_Matrix matrix;
matrix.xx = 0x10000L;
matrix.xy = (FT_Fixed)( sin( italics ) * (GLYPH_SQRT2*0x10000L) );
matrix.yx = 0;
matrix.yy = 0x10000L;
FT_Set_Transform( face, &matrix, 0 );
FT_Load_Char(face, unicode, FT_LOAD_TARGET_NORMAL | FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT);
w = face->glyph->bitmap.width;
h = face->glyph->bitmap.rows;
ew = 0;
if (!w)ew = 1;
if (!h)h = 1;
tempChar->width = (w + ew);
tempChar->height = h;
tempChar->rows = face->glyph->bitmap.rows;
tempChar->grays = face->glyph->bitmap.num_grays;
tempChar->pitch = face->glyph->bitmap.pitch;
tempChar->line = new unsigned char[tempChar->rows * tempChar->pitch];
memcpy(tempChar->line, face->glyph->bitmap.buffer, tempChar->rows * tempChar->pitch);
tempChar->left = face->glyph->bitmap_left;
tempChar->top = face->glyph->bitmap_top;
tempChar->right = face->glyph->advance.x >> 6;
tempChar->unicode = unicode;
tempChar->length = ((w + ew)+face->glyph->advance.x) >> 6;
return tempChar;
}
// Create single index
void freetype::createIndex(){
std::map<int, std::map<signed long, character*> >::iterator p;
p = fontTable.find(size.createKey());
if (p == fontTable.end()){
FT_Set_Pixel_Sizes(face, size.width, size.height);
FT_UInt glyphIndex;
FT_ULong unicode = FT_Get_First_Char(face, &glyphIndex);
std::map<signed long, character*> tempMap;
while (glyphIndex != 0){
tempMap.insert(std::make_pair(unicode, extractGlyph(unicode)));
unicode = FT_Get_Next_Char(face, unicode, &glyphIndex);
}
fontTable.insert(std::make_pair(size.createKey(), tempMap));
}
if (fontTable.find(size.createKey()) == fontTable.end()){
printf("ftalleg: inconsistency error\n");
throw std::exception();
}
}
/*
pixeler getPutPixel(){
switch( get_color_depth() ){
case 8 : return _putpixel;
case 15 : return _putpixel15;
case 16 : return _putpixel16;
case 24 : return _putpixel24;
case 32 : return _putpixel32;
default : return putpixel;
}
}
*/
- void drawOneCharacter(const character * tempChar, int & x1, int & y1, FT_UInt sizeHeight, const Bitmap & bitmap, const int & color){
+ void drawOneCharacter(const character * tempChar, int & x1, int & y1, FT_UInt sizeHeight, const Graphics::Bitmap & bitmap, const int & color){
unsigned char * line = tempChar->line;
- int colorRed = Bitmap::getRed(color);
- int colorGreen = Bitmap::getGreen(color);
- int colorBlue = Bitmap::getBlue(color);
+ int colorRed = Graphics::Bitmap::getRed(color);
+ int colorGreen = Graphics::Bitmap::getGreen(color);
+ int colorBlue = Graphics::Bitmap::getBlue(color);
/* cache the last color, there is a good chance it will be reused */
unsigned char lastData = -1;
short lastGrays = -1;
int lastColor = -1;
for (int y = 0; y < tempChar->rows; y++){
unsigned char * buffer = line;
for (int x = 0; x < tempChar->width; x++){
int finalColor = 0;
unsigned char current = *buffer;
buffer++;
if (current == lastData && lastGrays == tempChar->grays){
finalColor = lastColor;
} else {
int col = fixColor(current, tempChar->grays);
- int red = Bitmap::getRed(col);
- int green = Bitmap::getGreen(col);
- int blue = Bitmap::getBlue(col);
+ int red = Graphics::Bitmap::getRed(col);
+ int green = Graphics::Bitmap::getGreen(col);
+ int blue = Graphics::Bitmap::getBlue(col);
if ((red < 50) ||
(green < 50) ||
(blue < 50)){
continue;
}
red = red * colorRed / 255;
green = green * colorGreen / 255;
blue = blue * colorBlue / 255;
- finalColor = Bitmap::makeColor(red, green, blue);
+ finalColor = Graphics::Bitmap::makeColor(red, green, blue);
lastData = current;
lastColor = finalColor;
lastGrays = tempChar->grays;
}
//col.alpha= col.alpha * color.alpha / 255;
// putpixel(bitmap,x1+tempChar.left+x,y1 - tempChar.top+y + size.height,makecol(red,blue,green));
/* dangerous! putter is probably one of the _putpixel* routines so if x or y are off the bitmap
* you will get a segfault
*/
// putter(bitmap,x1+tempChar.left+x,y1 - tempChar.top+y + size.height,makecol(red,blue,green));
// putter = 0;
int finalX = x1+tempChar->left+x;
int finalY = y1 - tempChar->top + y + sizeHeight;
bitmap.putPixelNormal(finalX, finalY, finalColor);
}
line += tempChar->pitch;
}
x1 += tempChar->right;
}
// Render a character from the lookup table
- void freetype::drawCharacter(signed long unicode, int &x1, int &y1, const Bitmap & bitmap, const int &color){
+ void freetype::drawCharacter(signed long unicode, int &x1, int &y1, const Graphics::Bitmap & bitmap, const int &color){
// pixeler putter = getPutPixel();
std::map<int, std::map<signed long, character*> >::iterator ft;
ft = fontTable.find(size.createKey());
if (ft != fontTable.end()){
std::map<signed long, character*>::iterator p;
p = (ft->second).find(unicode);
if (p != ft->second.end()){
const character * tempChar = p->second;
drawOneCharacter(tempChar, x1, y1, size.height, bitmap, color);
}
}
}
//! Load font from memory
bool freetype::load(const unsigned char *memoryFont, unsigned int length, int index, unsigned int width, unsigned int height) {
if(!FT_New_Memory_Face(ftLibrary,memoryFont, length,index,&face)) {
currentFilename = "memoryFont";
currentIndex = index;
faceLoaded = true;
size.italics = 0;
setSize(width, height);
if (FT_HAS_GLYPH_NAMES(face)){
char buff[1024];
if(!FT_Get_Glyph_Name(face, currentIndex,buff, sizeof(buff))){
faceName = currentFilename;
}
else faceName = std::string(buff);
} else {
faceName = currentFilename;
}
if(FT_HAS_KERNING(face))kerning=true;
else kerning = false;
} else {
faceLoaded=false;
std::cout << "Load system font failed\n";
}
return faceLoaded;
}
//! Load font from file
bool freetype::load(const Filesystem::AbsolutePath & filename, int index, unsigned int width, unsigned int height){
FT_Error error = FT_New_Face(ftLibrary, filename.path().c_str(), index, &face);
if (error == 0){
currentFilename = filename.path();
currentIndex = index;
faceLoaded = true;
size.italics = 0;
setSize(width, height);
if (FT_HAS_GLYPH_NAMES(face)){
char buff[1024];
if (!FT_Get_Glyph_Name(face, currentIndex, buff, sizeof(buff))) {
faceName = currentFilename;
} else {
faceName = std::string(buff);
}
} else {
faceName = currentFilename;
}
kerning = FT_HAS_KERNING(face);
} else {
faceLoaded=false;
}
return faceLoaded;
}
/* utf8 decoding */
static long decodeUnicode(const std::string & input, unsigned int * position){
unsigned char byte1 = (unsigned char) input[*position];
/* one byte - ascii */
if (byte1 >> 7 == 0){
return byte1;
}
if (byte1 >> 5 == 6){
*position += 1;
unsigned char byte2 = (unsigned char) input[*position];
int top = byte1 & 31;
int bottom = byte2 & 63;
return (top << 6) + bottom;
}
if (byte1 >> 4 == 14){
*position += 1;
unsigned char byte2 = (unsigned char) input[*position];
*position += 1;
unsigned char byte3 = (unsigned char) input[*position];
int top4 = byte1 & 15;
int middle6 = byte2 & 63;
int bottom6 = byte3 & 63;
return (top4 << (6+6)) + (middle6 << 6) + bottom6;
}
if (byte1 >> 3 == 30){
*position += 1;
unsigned char byte2 = (unsigned char) input[*position];
*position += 1;
unsigned char byte3 = (unsigned char) input[*position];
*position += 1;
unsigned char byte4 = (unsigned char) input[*position];
int unit1 = byte1 & 7;
int unit2 = byte2 & 63;
int unit3 = byte3 & 63;
int unit4 = byte4 & 63;
return (unit1 << 18) + (unit2 << 12) + (unit3 << 6) + unit4;
}
return 0;
}
//! Get text length
int freetype::getLength(const std::string & text) {
int length=0;
std::map<int, std::map<signed long, character*> >::iterator ft;
ft = fontTable.find(size.createKey());
if (ft != fontTable.end()){
for (unsigned int i = 0; i < text.length(); i++) {
std::map<signed long, character*>::iterator p;
signed long unicode = decodeUnicode(text, &i);
p = (ft->second).find(unicode);
if (p != (ft->second).end()){
if (p != fontTable[size.createKey()].end()){
length += (p->second)->length;
}
}
}
}
return length;
}
//! Render font to a bitmap
- void freetype::render(int x, int y, const int & color, const Bitmap & bmp, ftAlign alignment, const std::string & text, int marker ...) {
+ void freetype::render(int x, int y, const int & color, const Graphics::Bitmap & bmp, ftAlign alignment, const std::string & text, int marker ...) {
if (faceLoaded){
int rend_x = 0;
int rend_y = 0;
std::ostringstream str;
/* use vsnprintf/Util::limitPrintf here? */
// Get extra arguments
va_list ap;
va_start(ap, marker);
for(unsigned int i = 0; i<text.length();++i) {
if (text[i] == '%') {
if(text[i+1]=='s') {
str << va_arg(ap, char *);
++i;
} else if(text[i+1]=='d'||text[i+1]=='i') {
str << va_arg(ap, signed int);
++i;
} else if(text[i+1]=='c') {
str << (char)va_arg(ap, int);
++i;
} else str << text[i];
} else {
str << text[i];
}
}
va_end(ap);
std::string fixedText(str.str());
switch (alignment) {
case ftLeft:
rend_x = x;
rend_y = y;
break;
case ftCenter:
rend_x = x - getLength(fixedText)/2;
rend_y = y;
break;
case ftRight:
rend_x = x - getLength(fixedText);
rend_y = y;
break;
default:
rend_x = x;
rend_y = y;
break;
}
int previous = 0;
int next = 0;
for (unsigned int i = 0; i<fixedText.length(); i++){
long unicode = decodeUnicode(fixedText, &i);
if (kerning && previous && next){
next = FT_Get_Char_Index(face, unicode);
FT_Vector delta;
FT_Get_Kerning(face, previous, next, FT_KERNING_DEFAULT, &delta);
rend_x += delta.x >> 6;
previous = next;
}
drawCharacter(unicode, rend_x, rend_y, bmp, color);
}
}
}
int freetype::calculateMaximumHeight(){
/* uhh, comment out the printf's ?? */
std::map<int, std::map<signed long, character*> >::iterator ft;
ft = fontTable.find(size.createKey());
int top = 0;
long code = 0;
if ( ft != fontTable.end() ){
std::map<signed long, character*>::iterator p;
std::map< signed long, character* > & map = ft->second;
for ( p = map.begin(); p != map.end(); p++ ){
const character * ch = p->second;
printf( "%c( %ld ). top = %d. rows = %d. total = %d\n", (char) ch->unicode, ch->unicode, ch->top, ch->rows, ch->top + ch->rows );
if ( ch->top + ch->rows > top ){
code = ch->unicode;
top = ch->top + ch->rows;
}
}
}
printf( "Largest letter = %ld\n", code );
return top;
}
int freetype::height( long code ) const {
std::map<int, std::map<signed long, character*> >::const_iterator ft;
ft = fontTable.find( size.createKey() );
if ( ft != fontTable.end() ){
std::map<signed long, character*>::const_iterator p;
p = (ft->second).find( code );
if ( p != (ft->second).end() ){
const character * temp = p->second;
// printf( "%c top = %d rows = %d\n", (char) code, temp.top, temp.rows );
return temp->top + temp->rows;
}
} else {
throw Exception("Internal inconsistency");
}
return 0;
}
int freetype::calculateHeight( const std::string & str ) const {
int max = 0;
for ( unsigned int i = 0; i < str.length(); i++ ){
int q = height( str[ i ] );
// printf( "Height of %c is %d\n", str[ i ], q );
if ( q > max ){
max = q;
}
}
return max;
}
//! Set size
void freetype::setSize( unsigned int w, unsigned int h){
if ( w != size.width || h != size.height ){
if (internalFix)return;
if (w<=0 || h<=0)return;
size.width = w;
size.height = h;
createIndex();
// maximumHeight = calculateMaximumHeight();
}
}
//! Set italics
void freetype::setItalics(int i){
if(internalFix)return;
if(i<-45)i=(-45);
else if(i>45)i=45;
size.italics = i;
createIndex();
}
void freetype::getSize(int * w, int * h) const {
*w = size.width;
*h = size.height;
}
//! Get Width
int freetype::getWidth() const {
return size.width;
}
//! Get Height
int freetype::getHeight( const std::string & str ) const {
// return size.height;
return calculateHeight( str );
}
//! Get Italics
int freetype::getItalics(){
return size.italics;
}
}
#endif /* FONT_BASE_CPP */
diff --git a/util/ftalleg.h b/util/ftalleg.h
index 73eb075e..60bee085 100644
--- a/util/ftalleg.h
+++ b/util/ftalleg.h
@@ -1,242 +1,238 @@
/*
--------------
About
--------------
A Freetype wrapper for use with allegro
Feel free to do whatever you like with this, by all means enjoy!
Just add it to your project
--------------
Linking
--------------
on linux:
g++ `freetype-config --cflags` ftalleg.cpp myfiles.cpp `freetype-config --libs` `allegro-config --libs`
on windows (you may need to include the freetype dir location, ie -Ic:/mingw/include):
g++ ftalleg.cpp myfiles.cpp -lfreetype -lalleg
--------------
Disclaimer
--------------
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE
SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef FT_FONT_H
#define FT_FONT_H
-#ifdef _WIN32
-#define BITMAP dummyBITMAP
-#include <windows.h>
-#undef BITMAP
-#endif
-
// #include <allegro.h>
#include <map>
#include <string>
#include <math.h>
#include <exception>
#include "file-system.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#define GLYPH_PI 3.14159265358979323846
#define GLYPH_SQRT2 1.41421356237309504880
+namespace Graphics{
class Bitmap;
+}
namespace ftalleg {
class Exception: public std::exception {
public:
Exception();
Exception(const std::string reason);
inline const std::string & getReason() const {
return reason;
}
virtual ~Exception() throw();
protected:
std::string reason;
};
//! Internal class for freetype to use
/*!
* This holds necessary information regarding a character \n
* from Freetype.
*/
class character
{
public:
//! Constructor
character();
//! Destructor
~character();
//! Unicode representation of character
signed long unicode;
//! Width of character
int width;
//! Height of character
int height;
//! Space on the left of a character (assists on positioning the character)
int left;
//! Space on top of the character (assists on positioning the character)
int top;
//! Space on the right of a character (assists on positioning the character)
int right;
//! Pitch of a character (assists on positioning the character)
int pitch;
//! Amount of shades of grays the FT_Bitmap holds
int grays;
//! Entire rows of the FT_Bitmap
int rows;
//! Entire length of the character with spacing and all
int length;
//! FT_Bitmap raw data
unsigned char *line;
};
//! Internal class for freetype to use
/*!
* Properties used for indexing a given font according to its size and matrix \n
*/
class fontSize
{
public:
fontSize();
~fontSize();
FT_UInt width;
FT_UInt height;
int italics;
int angle;
bool operator<(const fontSize &fs) const;
int createKey() const;
};
//! Freetype based font system
/*!
* Allows us to use freetype in allegro
*/
class freetype
{
private:
//! Filename
std::string currentFilename;
//! Is the face loaded
bool faceLoaded;
//! Does the face have kerning
bool kerning;
//! Current index default 0
int currentIndex;
//! for internal use disregard
bool internalFix;
int maximumHeight;
//! Font size
fontSize size;
//! Current Set system name
std::string systemName;
//! Face
FT_Face face;
//! Face Name
std::string faceName;
/*
//! Current character
character *currentChar;
*/
//! Lookup Table by size
std::map<int, std::map<signed long, character*> >fontTable;
//! Extract glyph
character * extractGlyph(signed long unicode);
int calculateMaximumHeight();
//! Create single index
void createIndex();
//! Render a character from the lookup table (utilizing the workBitmap)
- void drawCharacter(signed long unicode, int &x1, int &y1, const Bitmap & bitmap, const int & color);
+ void drawCharacter(signed long unicode, int &x1, int &y1, const Graphics::Bitmap & bitmap, const int & color);
int height( long code ) const;
int calculateHeight( const std::string & str ) const;
/* only called by the destructor */
void destroyGlyphIndex();
public:
//! Constructor
freetype(const Filesystem::AbsolutePath & str, const int x, const int y );
//! Destructor
~freetype();
//! Enum list of alignments
enum ftAlign
{
ftLeft = 0,
ftCenter = 1,
ftRight = 2
};
//! Load font from memory
bool load(const unsigned char *memoryFont, unsigned int length, int index, unsigned int width, unsigned int height);
//! Load font from file
bool load(const Filesystem::AbsolutePath & filename, int index, unsigned int width, unsigned int height);
//! Get text length
int getLength(const std::string & text);
//! Render font to a bitmap
- void render(int x, int y, const int & color, const Bitmap & bmp, ftAlign alignment, const std::string & text, int marker, ...);
+ void render(int x, int y, const int & color, const Graphics::Bitmap & bmp, ftAlign alignment, const std::string & text, int marker, ...);
//! Set size
void setSize( unsigned int w, unsigned int h);
//! Set italics
void setItalics(int i);
/* get the size attributes (close to width/height) */
void getSize(int * w, int * h) const;
//! Get Width
int getWidth() const;
//! Get Height
int getHeight( const std::string & str ) const;
//! Get Italics
int getItalics();
};
}
#endif /* FT_FONT_H */
diff --git a/util/funcs.cpp b/util/funcs.cpp
index 14490b91..9e40b5ae 100644
--- a/util/funcs.cpp
+++ b/util/funcs.cpp
@@ -1,329 +1,329 @@
#ifdef USE_ALLEGRO
#include <allegro.h>
#endif
#ifdef USE_SDL
#include <SDL.h>
#endif
#ifdef USE_ALLEGRO5
#include <allegro5/allegro.h>
#endif
#include "funcs.h"
#include "globals.h"
#include "debug.h"
#include <vector>
#include <string>
#include <string.h>
#include <algorithm>
#include "file-system.h"
#include "bitmap.h"
#include "trans-bitmap.h"
#include "font.h"
#include "init.h"
#include <sstream>
#ifndef USE_ALLEGRO
/* FIXME: move this to the filesystem module */
#include "sfl/sfl.h"
#include "sfl/sflfile.h"
#endif
#ifndef WINDOWS
#include <unistd.h>
#endif
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
using namespace std;
/* remove this once cmake and scons properly set DATA_PATH */
#ifndef DATA_PATH
#define DATA_PATH "data"
#endif
/* the build system should define DATA_PATH */
static string dataPath = DATA_PATH;
const double Util::pi = 3.14159265;
double Util::radians(double degree){
return degree * pi / 180.0;
}
/*
inline int rnd( int q ){
if ( q <= 0 ) return 0;
return (int)( rand() % q );
}
*/
int Util::max(int a, int b){
if (a>b){
return a;
}
return b;
}
/*
int Util::min(int a, int b){
if (a<b){
return a;
}
return b;
}
*/
int Util::clamp(int value, int min, int max){
return Util::min(Util::max(value, min), max);
}
int Util::rnd( int q, int min, int range ){
return q - min + rnd( range );
}
int Util::rnd( int min, int max ){
return rnd( max - min ) + min;
}
/* sleep for `x' milliseconds */
void Util::rest( int x ){
#ifdef USE_ALLEGRO
::rest(x);
#endif
#ifdef USE_SDL
SDL_Delay(x);
#endif
#ifdef USE_ALLEGRO5
al_rest((double) x / 1000.0);
#endif
}
void Util::restSeconds(double x){
Util::rest((int)(x * 1000));
}
bool Util::checkVersion(int version){
if (version == Global::getVersion()){
return true;
}
/* when an incompatible version is made, add a check here, like
* version < getVersion(3, 5)
* would mean any client below version 3.5 is incompatible.
*
* assume versions of client's greater than ourself is compatible, but
* this may not be true. There is no way to check this.
*/
if (version < 0){
return false;
}
return true;
}
void Util::setDataPath( const string & str ){
dataPath = str;
}
Filesystem::AbsolutePath Util::getDataPath2(){
return Filesystem::AbsolutePath(dataPath + "/");
}
bool Util::exists( const string & file ){
#ifdef USE_ALLEGRO
return ::exists(file.c_str()) != 0;
#else
return file_exists(file.c_str());
#endif
}
/*
vector<Filesystem::AbsolutePath> Util::getFiles(const Filesystem::AbsolutePath & dataPath, const string & find){
return Filesystem::getFiles(dataPath, find);
}
*/
void Util::blend_palette(int * pal, int mp, int startColor, int endColor ) {
/*
ASSERT(pal);
ASSERT(mp != 0);
*/
- int sc_r = Bitmap::getRed(startColor);
- int sc_g = Bitmap::getGreen(startColor);
- int sc_b = Bitmap::getBlue(startColor);
+ int sc_r = Graphics::Bitmap::getRed(startColor);
+ int sc_g = Graphics::Bitmap::getGreen(startColor);
+ int sc_b = Graphics::Bitmap::getBlue(startColor);
- int ec_r = Bitmap::getRed(endColor);
- int ec_g = Bitmap::getGreen(endColor);
- int ec_b = Bitmap::getBlue(endColor);
+ int ec_r = Graphics::Bitmap::getRed(endColor);
+ int ec_g = Graphics::Bitmap::getGreen(endColor);
+ int ec_b = Graphics::Bitmap::getBlue(endColor);
for ( int q = 0; q < mp; q++ ) {
float j = (float)( q + 1 ) / (float)( mp );
int f_r = (int)( 0.5 + (float)( sc_r ) + (float)( ec_r-sc_r ) * j );
int f_g = (int)( 0.5 + (float)( sc_g ) + (float)( ec_g-sc_g ) * j );
int f_b = (int)( 0.5 + (float)( sc_b ) + (float)( ec_b-sc_b ) * j );
- pal[q] = Bitmap::makeColor( f_r, f_g, f_b );
+ pal[q] = Graphics::Bitmap::makeColor( f_r, f_g, f_b );
}
}
string Util::trim(const std::string & str){
string s;
size_t startpos = str.find_first_not_of(" \t");
size_t endpos = str.find_last_not_of(" \t");
// if all spaces or empty return an empty string
if ((string::npos == startpos) ||
(string::npos == endpos)){
return "";
} else {
return str.substr(startpos, endpos-startpos+1);
}
return str;
}
/* makes the first letter of a string upper case */
string Util::upcase(std::string str){
if ( str.length() > 0 && (str[0] >= 'a' && str[0] <= 'z') ){
str[0] = str[0] - 'a' + 'A';
}
return str;
}
static int lowerCase(int c){
return tolower(c);
}
static int upperCase(int c){
return toupper(c);
}
string Util::upperCaseAll(std::string str){
std::transform(str.begin(), str.end(), str.begin(), upperCase);
return str;
}
string Util::lowerCaseAll(std::string str){
std::transform(str.begin(), str.end(), str.begin(), lowerCase);
/*
for (unsigned int i = 0; i < str.length(); i++){
if (str[0] >= 'A' && str[0] <= 'Z'){
str[0] = str[0] - 'A' + 'a';
}
}
*/
return str;
}
/*Gets the minimum of three values*/
static int minimum(int a,int b,int c){
int min=a;
if(b<min)
min=b;
if(c<min)
min=c;
return min;
}
/* Compute levenshtein distance between s and t
* from: http://www.merriampark.com/ldc.htm
*/
static int levenshtein_distance(const char *s, const char *t){
//Step 1
int k,i,j,n,m,cost,distance;
int * d;
n=strlen(s);
m=strlen(t);
if(n!=0&&m!=0){
d = (int*) malloc((sizeof(int))*(m+1)*(n+1));
m++;
n++;
//Step 2
for(k=0;k<n;k++)
d[k]=k;
for(k=0;k<m;k++)
d[k*n]=k;
//Step 3 and 4
for(i=1;i<n;i++)
for(j=1;j<m;j++)
{
//Step 5
if(s[i-1]==t[j-1])
cost=0;
else
cost=1;
//Step 6
d[j*n+i]=minimum(d[(j-1)*n+i]+1,d[j*n+i-1]+1,d[(j-1)*n+i-1]+cost);
}
distance=d[n*m-1];
free(d);
return distance;
} else {
return -1; //a negative return value means that one or both strings are empty.
}
}
int Util::levenshtein(const std::string & str1, const std::string & str2){
return levenshtein_distance(str1.c_str(), str2.c_str());
}
void Util::limitPrintf(char * buffer, int size, const char * format, va_list args){
#ifdef USE_ALLEGRO
uvszprintf(buffer, size, format, args);
#else
vsnprintf(buffer, size, format, args);
#endif
}
#ifndef WINDOWS
int Util::getPipe(int files[2]){
#ifdef PS3
return 0;
#else
return pipe(files);
#endif
}
#endif
-void Util::showError(const Bitmap & screen, const Exception::Base & exception, const string & info){
+void Util::showError(const Graphics::Bitmap & screen, const Exception::Base & exception, const string & info){
screen.BlitFromScreen(0, 0);
- Bitmap error(screen.getWidth() - 100, screen.getHeight() - 100);
- error.fill(Bitmap::darken(Bitmap::makeColor(160, 0, 0), 3));
- error.border(1, 2, Bitmap::makeColor(240, 0, 0));
+ Graphics::Bitmap error(screen.getWidth() - 100, screen.getHeight() - 100);
+ error.fill(Graphics::Bitmap::darken(Graphics::Bitmap::makeColor(160, 0, 0), 3));
+ error.border(1, 2, Graphics::Bitmap::makeColor(240, 0, 0));
const Font & font = Font::getFont(Global::DEFAULT_FONT, 17, 17);
int y = 10;
std::ostringstream out;
out << info;
out << " " << exception.getTrace();
- font.printfWrap(10, 10, Bitmap::makeColor(240, 240, 240), error, error.getWidth() - 20, out.str(), 0);
+ font.printfWrap(10, 10, Graphics::Bitmap::makeColor(240, 240, 240), error, error.getWidth() - 20, out.str(), 0);
Global::debug(0) << out.str() << std::endl;
- Bitmap::transBlender(0, 0, 0, 220);
+ Graphics::Bitmap::transBlender(0, 0, 0, 220);
error.translucent().draw(50, 50, screen);
screen.BlitToScreen();
}
void Util::showError(const Exception::Base & exception, const std::string & info){
- Bitmap screen(GFX_X, GFX_Y);
+ Graphics::Bitmap screen(GFX_X, GFX_Y);
showError(screen, exception, info);
}
string Util::niceSize(unsigned long size){
const char sizes[] = {'b', 'k', 'm', 'g', 't'};
double real = size;
for (unsigned int i = 0; i < sizeof(sizes) / sizeof(const char); i++){
if (real > 1024){
real /= 1024.0;
} else {
ostringstream in;
in << real << sizes[i];
return in.str();
}
}
ostringstream in;
in << real << "t";
return in.str();
}
diff --git a/util/funcs.h b/util/funcs.h
index 399a1291..9a4368fb 100644
--- a/util/funcs.h
+++ b/util/funcs.h
@@ -1,101 +1,103 @@
#ifndef _paintown_funcs_h
#define _paintown_funcs_h
#include <stdlib.h>
#include <vector>
#include <string>
#include <stdarg.h>
#include "regex.h"
#include "file-system.h"
namespace Exception{
class Base;
}
+namespace Graphics{
class Bitmap;
+}
namespace Util{
extern const double pi;
/* returns a number between 0 and q-1. you will never get `q'. if
* you wanted to get `q' then pass in q+1
*/
inline int rnd( int q ){
if (q <= 0){
return 0;
}
return (int)(rand() % q);
}
// std::vector< std::string > getFiles(const Filesystem::AbsolutePath & dataPath, const std::string & find );
double radians(double degree);
Filesystem::AbsolutePath getDataPath2();
void setDataPath( const std::string & str );
bool exists( const std::string & file );
/* check that `version' is compatible with this program, mostly used
* for network clients.
*/
bool checkVersion(int version);
/* return a random number + some range between min/max */
int rnd( int q, int min, int max );
int max(int a, int b);
inline int min(int a, int b){
if (a<b){
return a;
}
return b;
}
int clamp(int value, int min, int max);
/* return a number between min/max */
int rnd( int min, int max );
void blend_palette( int * pal, int mp, int sc, int ec );
/* rest in milliseconds */
void rest( int x );
/* rest in seconds */
void restSeconds(double x);
std::string trim(const std::string & str);
/* only upper cases the first letter of a string */
std::string upcase(std::string str);
/* lower cases the entire string */
std::string lowerCaseAll(std::string str);
/* upper cases the entire string */
std::string upperCaseAll(std::string str);
/* convert a size in bytes into human readable form.
* 234823592 = 223.94m
*/
std::string niceSize(unsigned long size);
int levenshtein(const std::string & str1, const std::string & str2);
int getPipe(int files[2]);
void limitPrintf(char * buffer, int size, const char * format, va_list args);
-void showError(const Bitmap & screen, const Exception::Base & exception, const std::string & info);
+void showError(const Graphics::Bitmap & screen, const Exception::Base & exception, const std::string & info);
/* will create a screen of size GFX_X, GFX_Y */
void showError(const Exception::Base & exception, const std::string & info);
}
#endif
diff --git a/util/gui/animation.cpp b/util/gui/animation.cpp
index 297f83a8..e5f5d433 100644
--- a/util/gui/animation.cpp
+++ b/util/gui/animation.cpp
@@ -1,385 +1,385 @@
#include "animation.h"
#include <vector>
#include <math.h>
#include <sstream>
#include "util/token.h"
#include "util/trans-bitmap.h"
#include "util/bitmap.h"
#include "globals.h"
#include "../debug.h"
#include "../funcs.h"
#include "../file-system.h"
using namespace std;
using namespace Gui;
// Temporary solution
-static void renderSprite(const Bitmap & bmp, const int x, const int y, const int alpha, const bool hflip, const bool vflip, const Bitmap & work){
+static void renderSprite(const Graphics::Bitmap & bmp, const int x, const int y, const int alpha, const bool hflip, const bool vflip, const Graphics::Bitmap & work){
if (alpha != 255){
- Bitmap::transBlender( 0, 0, 0, alpha );
+ Graphics::Bitmap::transBlender( 0, 0, 0, alpha );
if (hflip && !vflip){
bmp.translucent().drawHFlip(x,y, work);
} else if (!hflip && vflip){
bmp.translucent().drawVFlip(x,y, work);
} else if (hflip && vflip){
bmp.translucent().drawHVFlip(x,y, work);
} else if (!hflip && !vflip){
bmp.translucent().draw(x,y, work);
}
} else {
if (hflip && !vflip){
bmp.drawHFlip(x,y, work);
} else if (!hflip && vflip){
bmp.drawVFlip(x,y, work);
} else if (hflip && vflip){
bmp.drawHVFlip(x,y, work);
} else if (!hflip && !vflip){
bmp.draw(x,y, work);
}
}
}
Frame::Frame(const Token *the_token, imageMap &images) throw (LoadException):
bmp(0),
time(0),
horizontalFlip(false),
verticalFlip(false),
alpha(255){
if ( *the_token != "frame" ){
throw LoadException(__FILE__, __LINE__, "Not an frame");
}
const Token & tok = *the_token;
/* The usual setup of an animation frame is
// use image -1 to not draw anything, it can be used to get a blinking effect
(frame (image NUM) (alpha NUM) (offset x y) (hflip 0|1) (vflip 0|1) (time NUM))
*/
TokenView view = tok.view();
while (view.hasMore()){
try{
const Token * token;
view >> token;
if (*token == "image"){
// get the number
int num;
token->view() >> num;
// now assign the bitmap
bmp = images[num];
} else if (*token == "alpha"){
// get alpha
token->view() >> alpha;
} else if (*token == "offset"){
// Get the offset location it defaults to 0,0
double x=0, y=0;
try {
token->view() >> x >> y;
} catch (const TokenException & ex){
}
offset.set(x,y);
} else if (*token == "hflip"){
// horizontal flip
token->view() >> horizontalFlip;
} else if (*token == "vflip"){
// horizontal flip
token->view() >> verticalFlip;
} else if (*token == "time"){
// time to display
token->view() >> time;
} else {
Global::debug( 3 ) << "Unhandled menu attribute: "<<endl;
if (Global::getDebug() >= 3){
token->print(" ");
}
}
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Menu animation parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
}
-Frame::Frame(Bitmap * bmp):
+Frame::Frame(Graphics::Bitmap * bmp):
bmp(bmp),
time(0),
horizontalFlip(false),
verticalFlip(false),
alpha(255){
}
Frame::~Frame(){
}
void Frame::act(double xvel, double yvel){
scrollOffset.moveBy(xvel,yvel);
if (scrollOffset.getDistanceFromCenterX() >=bmp->getWidth()){
scrollOffset.setX(0);
} else if (scrollOffset.getDistanceFromCenterX() <= -(bmp->getWidth())){
scrollOffset.setX(0);
}
if (scrollOffset.getDistanceFromCenterY() >=bmp->getHeight()){
scrollOffset.setY(0);
} else if (scrollOffset.getDistanceFromCenterY() <= -(bmp->getHeight())){
scrollOffset.setY(0);
}
}
static bool closeFloat(double a, double b){
const double epsilon = 0.001;
return fabs(a-b) < epsilon;
}
-void Frame::draw(const int xaxis, const int yaxis, const Bitmap & work){
+void Frame::draw(const int xaxis, const int yaxis, const Graphics::Bitmap & work){
if (!bmp){
return;
}
if (!closeFloat(scrollOffset.getDistanceFromCenterX(), 0) || !closeFloat(scrollOffset.getDistanceFromCenterY(), 0)){
// Lets do some scrolling
- Bitmap temp = Bitmap::temporaryBitmap(bmp->getWidth(), bmp->getHeight());
+ Graphics::Bitmap temp = Graphics::Bitmap::temporaryBitmap(bmp->getWidth(), bmp->getHeight());
//AnimationPoint loc;
AbsolutePoint loc;
if (scrollOffset.getRelativeX() < 0){
loc.setX(scrollOffset.getDistanceFromCenterX() + bmp->getWidth());
} else if (scrollOffset.getRelativeX() > 0){
loc.setX(scrollOffset.getDistanceFromCenterX() - bmp->getWidth());
}
if (scrollOffset.getRelativeY() < 0){
loc.setY(scrollOffset.getDistanceFromCenterY() + bmp->getHeight());
} else if (scrollOffset.getRelativeY() > 0){
loc.setY(scrollOffset.getDistanceFromCenterY() - bmp->getHeight());
}
bmp->Blit((int) scrollOffset.getDistanceFromCenterX(), (int) scrollOffset.getDistanceFromCenterY(), temp);
bmp->Blit((int) scrollOffset.getDistanceFromCenterX(), (int) loc.getY(), temp);
bmp->Blit((int) loc.getX(), (int) scrollOffset.getDistanceFromCenterY(), temp);
bmp->Blit((int) loc.getX(), (int) loc.getY(), temp);
renderSprite(temp, (int)(xaxis+offset.getDistanceFromCenterX()), (int)(yaxis+offset.getDistanceFromCenterY()), alpha, horizontalFlip, verticalFlip, work);
} else {
renderSprite(*bmp, (int)(xaxis+offset.getDistanceFromCenterX()), (int)(yaxis+offset.getDistanceFromCenterY()), alpha, horizontalFlip, verticalFlip, work);
}
}
Animation::Animation(const Token *the_token) throw (LoadException):
id(0),
depth(BackgroundBottom),
ticks(0),
currentFrame(0),
loop(0),
allowReset(true){
images[-1] = 0;
std::string basedir = "";
if ( *the_token != "anim" ){
throw LoadException(__FILE__, __LINE__, "Not an animation");
}
/* The usual setup of an animation is
The images must be listed prior to listing any frames, basedir can be used to set the directory where the images are located
loop will begin at the subsequent frame listed after loop
axis is the location in which the drawing must be placed
location *old* - used to render in background or foreground (0 == background [default]| 1 == foreground)
depth - used to render in background or foreground space (depth background bottom|middle|top) | (depth foreground bottom|midle|top)
reset - used to allow resetting of animation (0 == no | 1 == yes [default])
velocity - used to get a wrapping scroll effect while animating
window - area in which the item will be contained
(anim (id NUM)
(location NUM)
(depth background|foreground NUM)
(basedir LOCATION)
(image NUM FILE)
(velocity x y)
(axis x y)
(frame "Read comments above in constructor")
(loop)
(reset NUM)
(window x1 y1 x2 y2))
*/
const Token & tok = *the_token;
TokenView view = tok.view();
while (view.hasMore()){
try{
const Token * token;
view >> token;
if (*token == "id"){
// get the id
token->view() >> id;
} else if (*token == "location"){
// translate location to depth
int location = 0;
token->view() >> location;
if (location == 0){
depth = BackgroundBottom;
} else if (location == 1){
depth = ForegroundBottom;
}
} else if (*token == "depth"){
// get the depth
std::string name, level;
token->view() >> name >> level;
if (name == "background"){
if (level == "bottom"){
depth = BackgroundBottom;
} else if (level == "middle"){
depth = BackgroundMiddle;
} else if (level == "top"){
depth = BackgroundTop;
}
} else if (name == "foreground"){
if (level == "bottom"){
depth = ForegroundBottom;
} else if (level == "middle"){
depth = ForegroundMiddle;
} else if (level == "top"){
depth = ForegroundTop;
}
}
} else if (*token == "basedir"){
// set the base directory for loading images
token->view() >> basedir;
} else if (*token == "image"){
// add bitmaps by number to the map
int number;
std::string temp;
token->view() >> number >> temp;
- Bitmap *bmp = new Bitmap(Filesystem::find(Filesystem::RelativePath(basedir + temp)).path());
+ Graphics::Bitmap *bmp = new Graphics::Bitmap(Filesystem::find(Filesystem::RelativePath(basedir + temp)).path());
if (bmp->getError()){
delete bmp;
} else {
images[number] = bmp;
}
} else if (*token == "axis"){
// Get the axis location it defaults to 0,0
double x=0, y=0;
try {
token->view() >> x >> y;
} catch (const TokenException & ex){
}
axis.set(x,y);
} else if (*token == "window"){
// Windowed area where to clip if necessary otherwise it defaults to max
double x1=0,x2=0, y1=0,y2=0;
try {
token->view() >> x1 >> y1 >> x2 >> y2;
} catch (const TokenException & ex){
}
window.set(x1,y1,x2,y2);
} else if (*token == "velocity"){
// This allows the animation to get a wrapping scroll action going on
double x=0, y=0;
try {
token->view() >> x >> y;
} catch (const TokenException & ex){
}
velocity.set(x,y);
} else if (*token == "frame"){
// new frame
Frame *frame = new Frame(token, images);
frames.push_back(frame);
} else if (*token == "loop"){
// start loop here
int l;
token->view() >> l;
if (l >= (int)frames.size()){
ostringstream out;
out << "Loop location is larger than the number of frames. Loop: " << loop << " Frames: " << frames.size();
throw LoadException(__FILE__, __LINE__, out.str());
}
loop = l;
} else if (*token == "reset"){
// Allow reset of animation
token->view() >> allowReset;
} else {
Global::debug( 3 ) << "Unhandled menu attribute: "<<endl;
if (Global::getDebug() >= 3){
token->print(" ");
}
}
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Menu animation parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
}
Animation::Animation(const std::string & background) throw (LoadException):
id(0),
depth(BackgroundBottom),
ticks(0),
currentFrame(0),
loop(0),
allowReset(true){
// add bitmap
- Bitmap *bmp = new Bitmap(Filesystem::find(Filesystem::RelativePath(background)).path());
+ Graphics::Bitmap *bmp = new Graphics::Bitmap(Filesystem::find(Filesystem::RelativePath(background)).path());
if (bmp->getError()){
delete bmp;
throw LoadException(__FILE__,__LINE__, "Problem loading file: " + background);
} else {
images[0] = bmp;
}
Frame *frame = new Frame(bmp);
frames.push_back(frame);
}
-Animation::Animation(Bitmap * image):
+Animation::Animation(Graphics::Bitmap * image):
id(0),
depth(BackgroundBottom),
ticks(0),
currentFrame(0),
loop(0),
allowReset(true){
images[0] = image;
Frame *frame = new Frame(image);
frames.push_back(frame);
}
Animation::~Animation(){
for (std::vector<Frame *>::iterator i = frames.begin(); i != frames.end(); ++i){
if (*i){
delete *i;
}
}
for (imageMap::iterator i = images.begin(); i != images.end(); ++i){
if (i->second){
delete i->second;
}
}
}
void Animation::act(){
// Used for scrolling
for (std::vector<Frame *>::iterator i = frames.begin(); i != frames.end(); ++i){
(*i)->act(velocity.getRelativeX(), velocity.getRelativeY());
}
if( frames[currentFrame]->time != -1 ){
ticks++;
if(ticks >= frames[currentFrame]->time){
ticks = 0;
forwardFrame();
}
}
}
-void Animation::draw(const Bitmap & work){
+void Animation::draw(const Graphics::Bitmap & work){
/* should use sub-bitmaps here */
// Set clip from the axis default is 0,0,bitmap width, bitmap height
work.setClipRect(-(window.getPosition().getDistanceFromCenterX()),-(window.getPosition().getDistanceFromCenterY()),work.getWidth() - window.getPosition2().getDistanceFromCenterX(),work.getHeight() - window.getPosition2().getDistanceFromCenterY());
frames[currentFrame]->draw(axis.getDistanceFromCenterX(), axis.getDistanceFromCenterY(),work);
work.setClipRect(0,0,work.getWidth(),work.getHeight());
}
void Animation::forwardFrame(){
if (currentFrame < frames.size() -1){
currentFrame++;
} else {
currentFrame = loop;
}
}
void Animation::backFrame(){
if (currentFrame > loop){
currentFrame--;
} else {
currentFrame = frames.size() - 1;
}
}
diff --git a/util/gui/animation.h b/util/gui/animation.h
index e682f28f..dafedfd5 100644
--- a/util/gui/animation.h
+++ b/util/gui/animation.h
@@ -1,76 +1,78 @@
#ifndef _paintown_gui_animation_h
#define _paintown_gui_animation_h
#include <vector>
#include <map>
#include "../load_exception.h"
#include "coordinate.h"
class Token;
+namespace Graphics{
class Bitmap;
+}
namespace Gui{
// To hold images by number easier to access and reuse
-typedef std::map< int, Bitmap *> imageMap;
+typedef std::map< int, Graphics::Bitmap *> imageMap;
class Frame{
public:
Frame(const Token *token, imageMap &images) throw (LoadException);
- Frame(Bitmap *);
+ Frame(Graphics::Bitmap *);
virtual ~Frame();
virtual void act(double xvel, double yvel);
- virtual void draw(int xaxis, int yaxis, const Bitmap &);
- Bitmap *bmp;
+ virtual void draw(int xaxis, int yaxis, const Graphics::Bitmap &);
+ Graphics::Bitmap *bmp;
RelativePoint offset;
RelativePoint scrollOffset;
int time;
bool horizontalFlip;
bool verticalFlip;
int alpha;
};
class Animation{
public:
Animation(const Token *token) throw (LoadException);
/*! Load only a single bitmap (for bacwards compatibility of backgrounds in menu) */
Animation(const std::string &) throw (LoadException);
/* use an existing bitmap */
- Animation(Bitmap * image);
+ Animation(Graphics::Bitmap * image);
virtual ~Animation();
// Logic
virtual void act();
- virtual void draw(const Bitmap &);
+ virtual void draw(const Graphics::Bitmap &);
virtual void forwardFrame();
virtual void backFrame();
inline void reset(){ if (allowReset){ currentFrame = 0; } }
inline int getID() const { return id; }
enum Depth {
BackgroundBottom,
BackgroundMiddle,
BackgroundTop,
ForegroundBottom,
ForegroundMiddle,
ForegroundTop,
};
inline const Depth & getDepth() const { return this->depth; }
private:
int id;
Depth depth;
int ticks;
unsigned int currentFrame;
unsigned int loop;
bool allowReset;
RelativePoint axis;
// This allows the frames to scroll in place
RelativePoint velocity;
Coordinate window;
std::vector<Frame *> frames;
imageMap images;
};
}
#endif
diff --git a/util/gui/box.cpp b/util/gui/box.cpp
index dfae2bcd..5b841da4 100644
--- a/util/gui/box.cpp
+++ b/util/gui/box.cpp
@@ -1,73 +1,73 @@
#include "util/bitmap.h"
#include "util/trans-bitmap.h"
#include "box.h"
#include "menu/menu.h"
#include "util/font.h"
using namespace Gui;
Box::Box(){
// Nothing yet
}
Box::Box( const Box & b ){
this->location = b.location;
this->workArea = b.workArea;
}
Box::~Box(){
// Nothing yet
}
Box &Box::operator=( const Box &copy){
location = copy.location;
workArea = copy.workArea;
return *this;
}
// Logic
void Box::act(const Font & font){
// Nothing yet
}
// Render
-void Box::render(const Bitmap & work){
+void Box::render(const Graphics::Bitmap & work){
checkWorkArea();
// Check if we are using a rounded box
if (location.getRadius() > 0){
roundRectFill(*workArea, (int)location.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.body);
roundRect(*workArea, (int)location.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.border);
} else {
workArea->rectangleFill(0, 0, location.getWidth()-1, location.getHeight()-1, colors.body );
workArea->rectangle(0, 0, location.getWidth()-1, location.getHeight()-1, colors.border );
}
- Bitmap::transBlender( 0, 0, 0, colors.bodyAlpha );
+ Graphics::Bitmap::transBlender( 0, 0, 0, colors.bodyAlpha );
// workArea->drawingMode( Bitmap::MODE_TRANS );
workArea->translucent().draw(location.getX(), location.getY(), work);
// work.drawingMode( Bitmap::MODE_SOLID );
}
void Box::messageDialog(int centerWidth, int centerHeight, const std::string & message, int radius){
/* FIXME Get rid of this */
#if 0
const Font &vFont = Font::getFont(OldMenu::Menu::getFont(),OldMenu::Menu::getFontWidth(),OldMenu::Menu::getFontHeight());
const int width = vFont.textLength(message.c_str()) + 10;
const int height = vFont.getHeight() + 10;
const int x = (centerWidth/2) - (width/2);
const int y = (centerHeight/2) - (height/2);
Box dialog;
dialog.location.setDimensions(width, height);
dialog.location.setRadius(radius);
dialog.colors.body = Bitmap::makeColor(0,0,0);
dialog.colors.bodyAlpha = 200;
dialog.colors.border = Bitmap::makeColor(255,255,255);
dialog.colors.borderAlpha = 255;
Bitmap temp = Bitmap::temporaryBitmap(width,height);
dialog.render(temp);
vFont.printf( 5, 5, Bitmap::makeColor(255,255,255), temp, message, -1);
temp.BlitToScreen(x,y);
#endif
}
diff --git a/util/gui/box.h b/util/gui/box.h
index 1d104073..df0da48d 100644
--- a/util/gui/box.h
+++ b/util/gui/box.h
@@ -1,34 +1,34 @@
#ifndef _paintown_gui_box_h
#define _paintown_gui_box_h
#include <string>
#include "widget.h"
namespace Gui{
class Box : public Widget {
public:
Box();
Box( const Box & b );
virtual ~Box();
// copy
Box &operator=( const Box &);
// Logic
virtual void act(const Font &);
// Render
using Widget::render;
- virtual void render(const Bitmap &);
+ virtual void render(const Graphics::Bitmap &);
// Do a message Dialog centered with respect to the given width/height
static void messageDialog(int width, int height, const std::string & message, int radius = 0);
protected:
};
}
#endif
diff --git a/util/gui/container.cpp b/util/gui/container.cpp
index 8a289120..014e3724 100644
--- a/util/gui/container.cpp
+++ b/util/gui/container.cpp
@@ -1,50 +1,50 @@
#include "container.h"
#include "../bitmap.h"
#include "widget.h"
using namespace Gui;
Container::Container()
{
// Nothing yet
}
Container::~Container()
{
// Nothing yet
}
// Add widget
void Container::add(Widget *widget)
{
widgets.push_back(widget);
}
// Remove widget
void Container::remove(Widget *widget)
{
widgets.remove(widget);
}
// Logic
void Container::act(const Font & font){
std::list<Widget *>::iterator i = widgets.begin(), end = widgets.end();
while(i!=end){
(*i)->act(font);
i++;
}
}
// Render
-void Container::render(const Bitmap & work)
+void Container::render(const Graphics::Bitmap & work)
{
work.setClipRect(position.x,position.y,position.getX2(),position.getY2());
std::list<Widget *>::iterator i = widgets.begin(), end = widgets.end();
while(i!=end)
{
(*i)->render(work);
i++;
}
work.setClipRect(0,0,work.getWidth(),work.getHeight());
}
diff --git a/util/gui/container.h b/util/gui/container.h
index 8cd09234..e122a389 100644
--- a/util/gui/container.h
+++ b/util/gui/container.h
@@ -1,40 +1,42 @@
#ifndef _paintown_gui_container_h
#define _paintown_gui_container_h
#include <list>
#include "rectarea.h"
+namespace Graphics{
class Bitmap;
+}
class Font;
namespace Gui{
class Widget;
class Container{
public:
Container();
virtual ~Container();
// position info
RectArea position;
// Logic
void act(const Font & font);
// Render
- void render(const Bitmap &);
+ void render(const Graphics::Bitmap &);
// Add widget
void add(Widget *widget);
// Remove widget
void remove(Widget *widget);
private:
std::list<Widget *>widgets;
};
}
#endif
diff --git a/util/gui/context-box.cpp b/util/gui/context-box.cpp
index 12c47a8b..76f73e2b 100644
--- a/util/gui/context-box.cpp
+++ b/util/gui/context-box.cpp
@@ -1,332 +1,332 @@
#include "util/bitmap.h"
#include "util/trans-bitmap.h"
#include "context-box.h"
#include "util/font.h"
static const double FONT_SPACER = 1.3;
static const int GradientMax = 50;
static int selectedGradientStart(){
- static int color = Bitmap::makeColor(19, 167, 168);
+ static int color = Graphics::Bitmap::makeColor(19, 167, 168);
return color;
}
static int selectedGradientEnd(){
- static int color = Bitmap::makeColor(27, 237, 239);
+ static int color = Graphics::Bitmap::makeColor(27, 237, 239);
return color;
}
using namespace std;
using namespace Gui;
ContextItem::ContextItem(){
}
ContextItem::~ContextItem(){
}
bool ContextItem::isAdjustable(){
return false;
}
int ContextItem::getLeftColor(){
return 0;
}
int ContextItem::getRightColor(){
return 0;
}
ContextBox::ContextBox():
current(0),
fadeState(NotActive),
/*
fontWidth(0),
fontHeight(0),
*/
fadeSpeed(12),
fadeAlpha(0),
cursorCenter(0),
cursorLocation(0),
scrollWait(4),
selectedGradient(GradientMax, selectedGradientStart(), selectedGradientEnd()),
useGradient(true),
renderOnlyText(false){
}
ContextBox::ContextBox( const ContextBox & copy ):
current(0),
fadeState(NotActive),
selectedGradient(GradientMax, selectedGradientStart(), selectedGradientEnd()),
renderOnlyText(false){
this->context = copy.context;
/*
this->font = copy.font;
this->fontWidth = copy.fontWidth;
this->fontHeight = copy.fontHeight;
*/
this->fadeSpeed = copy.fadeSpeed;
this->fadeAlpha = copy.fadeAlpha;
this->cursorCenter = copy.cursorCenter;
this->cursorLocation = copy.cursorLocation;
this->scrollWait = copy.scrollWait;
this->useGradient = copy.useGradient;
this->renderOnlyText = copy.renderOnlyText;
}
ContextBox::~ContextBox(){
}
ContextBox & ContextBox::operator=( const ContextBox & copy){
this->current = 0;
this->fadeState = NotActive;
this->context = copy.context;
/*
this->font = copy.font;
this->fontWidth = copy.fontWidth;
this->fontHeight = copy.fontHeight;
*/
this->fadeSpeed = copy.fadeSpeed;
this->fadeAlpha = copy.fadeAlpha;
this->cursorCenter = copy.cursorCenter;
this->cursorLocation = copy.cursorLocation;
this->scrollWait = copy.scrollWait;
this->useGradient = copy.useGradient;
this->renderOnlyText = copy.renderOnlyText;
return *this;
}
void ContextBox::act(const Font & font){
// update board
board.act(font);
// Calculate text info
calculateText(font);
// do fade
doFade();
// Update gradient
selectedGradient.update();
}
-void ContextBox::render(const Bitmap & work){
+void ContextBox::render(const Graphics::Bitmap & work){
}
-void ContextBox::render(const Bitmap & work, const Font & font){
+void ContextBox::render(const Graphics::Bitmap & work, const Font & font){
if (!renderOnlyText){
board.render(work);
}
drawText(work, font);
}
bool ContextBox::next(const Font & font){
if (fadeState == FadeOut){
return false;
}
/*
const Font & vFont = Font::getFont(font, fontWidth, fontHeight);
*/
cursorLocation += (int)(font.getHeight()/FONT_SPACER);
if (current < context.size()-1){
current++;
} else {
current = 0;
}
return true;
}
bool ContextBox::previous(const Font & font){
if (fadeState == FadeOut){
return false;
}
/*
const Font & vFont = Font::getFont(font, fontWidth, fontHeight);
*/
cursorLocation -= (int)(font.getHeight()/FONT_SPACER);
if (current > 0){
current--;
} else {
current = context.size()-1;
}
return true;
}
void ContextBox::adjustLeft(){
}
void ContextBox::adjustRight(){
}
void ContextBox::open(){
// Set the fade stuff
fadeState = FadeIn;
//board.position = position;
board.location = location;
board.colors = colors;
board.open();
fadeAlpha = 0;
cursorLocation = 0;
}
void ContextBox::close(){
fadeState = FadeOut;
board.close();
fadeAlpha = 255;
cursorLocation = 480;
}
void ContextBox::doFade(){
switch ( fadeState ){
case FadeIn: {
if (fadeAlpha < 255){
fadeAlpha += (fadeSpeed+2);
}
if (fadeAlpha >= 255){
fadeAlpha = 255;
if (board.isActive()){
fadeState = Active;
}
}
break;
}
case FadeOut: {
if (fadeAlpha > 0){
fadeAlpha -= (fadeSpeed+2);
}
if (fadeAlpha <= 0){
fadeAlpha = 0;
if (!board.isActive()){
fadeState = NotActive;
}
}
break;
}
case Active:
case NotActive:
default:
break;
}
}
void ContextBox::calculateText(const Font & vFont){
if (context.empty()){
return;
}
// const Font & vFont = Font::getFont(font, fontWidth, fontHeight);
cursorCenter = (location.getY() + (int)location.getHeight()/2) - vFont.getHeight()/2;//(position.y + (int)position.height/2) - vFont.getHeight()/2;
if (cursorLocation == cursorCenter){
scrollWait = 4;
} else {
if (scrollWait <= 0){
cursorLocation = (cursorLocation + cursorCenter)/2;
scrollWait = 4;
} else {
scrollWait--;
}
}
}
-void ContextBox::drawText(const Bitmap & bmp, const Font & vFont){
+void ContextBox::drawText(const Graphics::Bitmap & bmp, const Font & vFont){
if (context.empty()){
return;
}
// const Font & vFont = Font::getFont(font, fontWidth, fontHeight);
const int x1 = board.getArea().getX()+(int)(board.getArea().getRadius()/2);
const int y1 = board.getArea().getY()+2;//(board.getArea().radius/2);
const int x2 = board.getArea().getX2()-(int)(board.getArea().getRadius()/2);
const int y2 = board.getArea().getY2()-2;//(board.getArea().radius/2);
bmp.setClipRect(x1, y1, x2, y2);
int locationY = cursorLocation;
int currentOption = current;
int count = 0;
while (locationY < location.getX2() + vFont.getHeight()){
const int startx = (location.getWidth()/2)-(vFont.textLength(context[currentOption]->getName().c_str())/2);
if (count == 0){
- Bitmap::transBlender(0, 0, 0, fadeAlpha);
- TranslucentBitmap translucent(bmp);
+ Graphics::Bitmap::transBlender(0, 0, 0, fadeAlpha);
+ Graphics::TranslucentBitmap translucent(bmp);
// Bitmap::drawingMode( Bitmap::MODE_TRANS );
const int color = useGradient ? selectedGradient.current() : selectedGradientStart();
vFont.printf(location.getX() + startx, locationY, color, translucent, context[currentOption]->getName(), 0 );
if (context[currentOption]->isAdjustable()){
const int triangleSize = 14;
int cx = (location.getX() + startx) - 15;
int cy = (int)(locationY + (vFont.getHeight()/FONT_SPACER) / 2 + 2);
/*
int cx1 = cx + triangleSize / 2;
int cy1 = cy - triangleSize / 2;
int cx2 = cx - triangleSize;
int cy2 = cy;
int cx3 = cx + triangleSize / 2;
int cy3 = cy + triangleSize / 2;
*/
/* do the triangles need to be translucent? */
// translucent.triangle(cx1, cy1, cx2, cy2, cx3, cy3, context[currentOption]->getLeftColor());
translucent.equilateralTriangle(cx, cy, 180, triangleSize, context[currentOption]->getLeftColor());
cx = (location.getX()+startx + vFont.textLength(context[currentOption]->getName().c_str()))+15;
translucent.equilateralTriangle(cx, cy, 0, triangleSize, context[currentOption]->getLeftColor());
// translucent.triangle( cx - triangleSize / 2, cy - triangleSize / 2, cx + triangleSize, cy, cx - triangleSize / 2, cy + triangleSize / 2, context[currentOption]->getRightColor() );
}
// Bitmap::drawingMode(Bitmap::MODE_SOLID);
} else {
int textAlpha = fadeAlpha - (count * 35);
if (textAlpha < 0){
textAlpha = 0;
}
- Bitmap::transBlender(0, 0, 0, textAlpha);
+ Graphics::Bitmap::transBlender(0, 0, 0, textAlpha);
// Bitmap::drawingMode( Bitmap::MODE_TRANS );
- const int color = Bitmap::makeColor(255,255,255);
+ const int color = Graphics::Bitmap::makeColor(255,255,255);
vFont.printf(location.getX() + startx, locationY, color, bmp.translucent(), context[currentOption]->getName(), 0 );
// Bitmap::drawingMode( Bitmap::MODE_SOLID );
}
if (context.size() == 1){
bmp.setClipRect(0, 0, bmp.getWidth(), bmp.getHeight());
return;
}
currentOption++;
if (currentOption == (int)context.size()){
currentOption = 0;
}
locationY += (int)(vFont.getHeight()/FONT_SPACER);
count++;
/*if (context.size() < 2 && count == 2){
break;
}*/
}
locationY = cursorLocation - (int)(vFont.getHeight()/FONT_SPACER);
currentOption = current;
currentOption--;
count = 0;
while (locationY > location.getX() - vFont.getHeight()){
if (currentOption < 0){
currentOption = context.size()-1;
}
const int startx = (location.getWidth()/2)-(vFont.textLength(context[currentOption]->getName().c_str())/2);
int textAlpha = fadeAlpha - (count * 35);
if (textAlpha < 0){
textAlpha = 0;
}
- Bitmap::transBlender(0, 0, 0, textAlpha);
+ Graphics::Bitmap::transBlender(0, 0, 0, textAlpha);
// Bitmap::drawingMode( Bitmap::MODE_TRANS );
- const int color = Bitmap::makeColor(255,255,255);
+ const int color = Graphics::Bitmap::makeColor(255,255,255);
vFont.printf(location.getX() + startx, locationY, color, bmp.translucent(), context[currentOption]->getName(), 0 );
// Bitmap::drawingMode( Bitmap::MODE_SOLID );
currentOption--;
locationY -= (int)(vFont.getHeight()/FONT_SPACER);
count++;
/*if (context.size() < 2 && count == 1){
break;
}*/
}
bmp.setClipRect(0, 0, bmp.getWidth(), bmp.getHeight());
}
diff --git a/util/gui/context-box.h b/util/gui/context-box.h
index 53f4dc1a..a7a6c00a 100644
--- a/util/gui/context-box.h
+++ b/util/gui/context-box.h
@@ -1,151 +1,151 @@
#ifndef _paintown_gui_context_box_h
#define _paintown_gui_context_box_h
#include <string>
#include <vector>
#include "widget.h"
#include "popup-box.h"
#include "../gradient.h"
#include "../file-system.h"
namespace Gui{
class ContextItem{
public:
ContextItem();
virtual ~ContextItem();
virtual const std::string getName() = 0;
virtual bool isAdjustable();
virtual int getLeftColor();
virtual int getRightColor();
};
class ContextBox : public Widget {
public:
ContextBox();
ContextBox(const ContextBox &);
virtual ~ContextBox();
//! copy
ContextBox &operator=(const ContextBox &);
//! Logic
virtual void act(const Font &);
//! Render
using Widget::render;
- virtual void render(const Bitmap &);
- virtual void render(const Bitmap &, const Font & font);
+ virtual void render(const Graphics::Bitmap &);
+ virtual void render(const Graphics::Bitmap &, const Font & font);
//! Next
virtual bool next(const Font &);
//! Previous
virtual bool previous(const Font &);
//! Adjust left
virtual void adjustLeft();
//! Adjust right
virtual void adjustRight();
//! open context box
virtual void open();
//! Close context box
virtual void close();
//! Set context list
virtual inline void setList(const std::vector<ContextItem *> & list){
this->context = list;
this->current = 0;
}
//! Set current font
/*
virtual inline void setFont(const Filesystem::RelativePath & font, int width, int height){
this->font = font;
this->fontWidth = width;
this->fontHeight = height;
}
*/
//! Get current index
virtual inline unsigned int getCurrentIndex(){
return this->current;
}
//! Is active?
virtual inline bool isActive(){
return (this->fadeState != NotActive);
}
//!set fadespeed
virtual inline void setFadeSpeed(int speed){
this->fadeSpeed = speed;
this->board.setFadeSpeed(speed);
}
//!set fade alpha
virtual inline void setFadeAlpha(int alpha){
this->fadeAlpha = alpha;
}
//! use gradient?
virtual inline void setUseGradient(bool useGradient){
this->useGradient = useGradient;
}
//! Set to use only text on background
virtual inline void setRenderOnlyText(bool render){
this->renderOnlyText = render;
}
private:
void doFade();
void calculateText(const Font & font);
- void drawText(const Bitmap &, const Font & font);
+ void drawText(const Graphics::Bitmap &, const Font & font);
enum FadeState{
NotActive,
FadeIn,
Active,
FadeOut,
};
//! Current index
unsigned int current;
//! Current fade state
FadeState fadeState;
//! Context list
std::vector<ContextItem *> context;
//! Current font
/*
Filesystem::RelativePath font;
int fontWidth;
int fontHeight;
*/
//! Fade speed
int fadeSpeed;
//! Fade Aplha
int fadeAlpha;
//! Board
PopupBox board;
//! The centered position
int cursorCenter;
//! Current y coordinate to render text from
int cursorLocation;
//! scroll wait
int scrollWait;
//! Gradient for selected cursor
Effects::Gradient selectedGradient;
//! Use gradient
bool useGradient;
//! Render Text only
bool renderOnlyText;
};
}
#endif
diff --git a/util/gui/coordinate.cpp b/util/gui/coordinate.cpp
index 3c73afee..b8e5c6e5 100644
--- a/util/gui/coordinate.cpp
+++ b/util/gui/coordinate.cpp
@@ -1,475 +1,475 @@
#include "util/bitmap.h"
#include "coordinate.h"
#include "globals.h"
#include "util/load_exception.h"
#include <sstream>
using namespace Gui;
namespace Gui{
namespace Space{
Point::Point(double x, double y, const Space & space):
x(x),
y(y),
space(space){
}
Point::Point(const Point & point, const Space & space):
space(space){
x = space.getLocalX(point.physicalX());
y = space.getLocalY(point.physicalY());
}
Point::Point(const Point & point):
x(point.x),
y(point.y),
space(point.space){
}
Point & Point::operator=(const Point & point){
if (!sameSpace(point)){
/* FIXME: throw an error */
}
this->x = point.x;
this->y = point.y;
return *this;
}
Point & Point::operator+=(const Point & point){
*this = *this + point;
return *this;
}
Point Point::operator+(const Point & point){
if (sameSpace(point)){
x += point.x;
y += point.y;
return *this;
} else {
return *this + Point(point, space);
}
}
bool Point::sameSpace(const Point & point){
return space == point.space;
}
int Point::physicalX() const {
return (x * space.sizeX() / 2) + space.centerX();
}
int Point::physicalY() const {
return (y * space.sizeY() / 2) + space.centerY();
}
Space::Space(double minX, double minY, double maxX, double maxY):
minX(minX),
minY(minY),
maxX(maxX),
maxY(maxY){
}
bool Space::operator==(const Space & space) const {
if (this == &space){
return true;
}
return minX == space.minX &&
minY == space.minY &&
maxX == space.maxX &&
maxY == space.maxY;
}
Point Space::fromPhysical(int x, int y){
return Point(getLocalX(x), getLocalY(y), *this);
}
double Space::sizeX() const {
return maxX - minX;
}
double Space::sizeY() const {
return maxY - minY;
}
double Space::centerX() const {
return (maxX - minX) / 2;
}
double Space::centerY() const {
return (maxY - minY) / 2;
}
double Space::getLocalX(int physicalX) const {
return (physicalX - centerX()) / sizeX();
}
double Space::getLocalY(int physicalY) const {
return (physicalY - centerY()) / sizeY();
}
}
}
static int relativeToAbsolute(double x, int center){
return (int)(center + (center * x));
}
static int amountFromCenterX(int x){
return x - (640 / 2);
}
static int amountFromCenterY(int y){
return y - (480 / 2);
}
/* scale an absolute distance to a relative distance
* distance / absolute = X / relative
* absolute space = 0 to 640
* relative space = -1 to 1
* X = distance * relative / absolute
*/
static double scaleAbsoluteToRelativeDistanceX(int distance){
return distance * (1.0 - (-1.0)) / (640.0 - 0);
}
static double scaleAbsoluteToRelativeDistanceY(int distance){
return distance * (1.0 - (-1.0)) / (480.0 - 0);
}
/* convert a point in absolute space to relative space */
static double absoluteToRelative(int x, int center){
return (double)(x-center)/center;
}
static double relativeToAbsoluteX(double x){
// return relativeToAbsolute(x, Global::getScreenWidth() / 2);
return relativeToAbsolute(x, 640 / 2);
}
static double relativeToAbsoluteY(double y){
// return relativeToAbsolute(y, Global::getScreenHeight() / 2);
return relativeToAbsolute(y, 480 / 2);
}
static double absoluteToRelativeX(int x){
return absoluteToRelative(x, 640/2);
}
static double absoluteToRelativeY(int y){
return absoluteToRelative(y, 480/2);
}
AbsolutePoint::AbsolutePoint():
x(0),
y(0){
}
AbsolutePoint::AbsolutePoint(int x, int y):
x(x),
y(y){
}
AbsolutePoint::AbsolutePoint(const AbsolutePoint & copy):
x(copy.x),
y(copy.y){
}
AbsolutePoint::~AbsolutePoint(){
}
const AbsolutePoint & AbsolutePoint::operator=(const AbsolutePoint & copy){
this->x = copy.x;
this->y = copy.y;
return *this;
}
int AbsolutePoint::getX() const {
return x;
}
int AbsolutePoint::getY() const {
return y;
}
RelativePoint::RelativePoint():
x(0),
y(0){
}
RelativePoint::RelativePoint(double x, double y):
x(x),
y(y){
}
RelativePoint::RelativePoint(const RelativePoint & copy):
x(copy.x),
y(copy.y){
}
RelativePoint::RelativePoint(const AbsolutePoint & point):
x(absoluteToRelativeX(point.getX())),
y(absoluteToRelativeY(point.getY())){
}
RelativePoint::~RelativePoint(){
}
const RelativePoint & RelativePoint::operator=(const RelativePoint & copy){
this->x = copy.x;
this->y = copy.y;
return *this;
}
const RelativePoint & RelativePoint::operator=(const AbsolutePoint & point){
this->x = absoluteToRelativeX(point.getX());
this->y = absoluteToRelativeY(point.getY());
return *this;
}
bool RelativePoint::operator==(const RelativePoint & point){
return (this->x == point.x && this->y == point.y);
}
bool RelativePoint::operator!=(const RelativePoint & point){
return !(*this == point);
}
int RelativePoint::getX() const{
return relativeToAbsoluteX(x);
}
int RelativePoint::getY() const{
return relativeToAbsoluteY(y);
}
int RelativePoint::getDistanceFromCenterX(){
return amountFromCenterX(getX());
}
int RelativePoint::getDistanceFromCenterY(){
return amountFromCenterY(getY());
}
void RelativePoint::moveX(double percent){
x += percent;
}
void RelativePoint::moveY(double percent){
y += percent;
}
void RelativePoint::moveBy(double x, double y){
moveX(x);
moveY(y);
}
AbsolutePoint RelativePoint::getAbsolute(){
return AbsolutePoint(relativeToAbsoluteX(x), relativeToAbsoluteY(y));
}
double RelativePoint::getRelativeX() const{
return x;
}
double RelativePoint::getRelativeY() const{
return y;
}
Coordinate::Coordinate():
z(0),
radius(0){
}
Coordinate::Coordinate(AbsolutePoint & position, AbsolutePoint & position2):
position(position),
position2(position2),
z(0),
radius(0){
}
Coordinate::Coordinate(const RelativePoint & position, const RelativePoint & position2):
position(position),
position2(position2),
z(0),
radius(0){
}
Coordinate::Coordinate(const Coordinate & copy):
position(copy.position),
position2(copy.position2),
z(copy.z),
radius(copy.radius){
}
Coordinate::~Coordinate(){
}
const Coordinate & Coordinate::operator=(const Coordinate & copy){
this->position = copy.position;
this->position2 = copy.position2;
this->z = copy.z;
this->radius = copy.radius;
return *this;
}
int Coordinate::getX() const{
return position.getX();
}
int Coordinate::getY() const{
return position.getY();
}
int Coordinate::getWidth() const {
return position2.getX() - position.getX();
}
int Coordinate::getHeight() const {
return position2.getY() - position.getY();
}
int Coordinate::getX2() const{
return position2.getX();
}
int Coordinate::getY2() const{
return position2.getY();
}
void Coordinate::growHorizontal(double by){
position.moveX(-(by));
position2.moveX(by);
}
void Coordinate::growHorizontalAbsolute(int distance){
growHorizontal(scaleAbsoluteToRelativeDistanceX(distance));
}
void Coordinate::growVerticalAbsolute(int distance){
growVertical(scaleAbsoluteToRelativeDistanceY(distance));
}
void Coordinate::growVertical(double by){
position.moveY(-(by));
position2.moveY(by);
}
void Coordinate::growTo(const Coordinate & coord, double percent){
if (position.getRelativeX() > coord.position.getRelativeX()){
position.moveX(-(percent));
if (position.getRelativeX() < coord.position.getRelativeX()){
position.setX(coord.position.getRelativeX());
}
} else if (position.getRelativeX() < coord.position.getRelativeX()){
position.moveX(percent);
if (position.getRelativeX() > coord.position.getRelativeX()){
position.setX(coord.position.getRelativeX());
}
}
if (position.getRelativeY() > coord.position.getRelativeY()){
position.moveY(-(percent));
if (position.getRelativeY() < coord.position.getRelativeY()){
position.setY(coord.position.getRelativeY());
}
} else if (position.getRelativeY() < coord.position.getRelativeY()){
position.moveY(percent);
if (position.getRelativeY() > coord.position.getRelativeY()){
position.setY(coord.position.getRelativeY());
}
}
if (position2.getRelativeX() > coord.position2.getRelativeX()){
position2.moveX(-(percent));
if (position2.getRelativeX() < coord.position2.getRelativeX()){
position2.setX(coord.position2.getRelativeX());
}
} else if (position2.getRelativeX() < coord.position2.getRelativeX()){
position2.moveX(percent);
if (position2.getRelativeX() > coord.position2.getRelativeX()){
position2.setX(coord.position2.getRelativeX());
}
}
if (position2.getRelativeY() > coord.position2.getRelativeY()){
position2.moveY(-(percent));
if (position2.getRelativeY() < coord.position2.getRelativeY()){
position2.setY(coord.position2.getRelativeY());
}
} else if (position2.getRelativeY() < coord.position2.getRelativeY()){
position2.moveY(percent);
if (position2.getRelativeY() > coord.position2.getRelativeY()){
position2.setY(coord.position2.getRelativeY());
}
}
}
void Coordinate::center(const Coordinate & coord){
const double centerx = (coord.getRelativeX1() + coord.getRelativeX2())/2;
const double centery = (coord.getRelativeY1() + coord.getRelativeY2())/2;
set(centerx, centery, centerx, centery);
}
void Coordinate::moveBy(double x, double y){
position.moveBy(x, y);
position2.moveBy(x, y);
}
bool Coordinate::operator==( const Coordinate & coord){
return ( (position == coord.position) &&
(position2 == coord.position2));
}
bool Coordinate::operator!=( const Coordinate & coord){
return ( !(position == coord.position) ||
!(position2 == coord.position2));
}
-bool Coordinate::operator==( const Bitmap & bmp){
+bool Coordinate::operator==( const Graphics::Bitmap & bmp){
return ( (getWidth() == bmp.getWidth()) &&
(getHeight() == bmp.getHeight()));
}
-bool Coordinate::operator!=( const Bitmap & bmp){
+bool Coordinate::operator!=( const Graphics::Bitmap & bmp){
return !(*this == bmp);
}
void Coordinate::setPosition(const RelativePoint & point){
position = point;
}
void Coordinate::setPosition(const AbsolutePoint & point){
position = RelativePoint(point);
}
void Coordinate::setPosition2(const RelativePoint & point){
position2 = point;
}
void Coordinate::setPosition2(const AbsolutePoint & point){
position2 = RelativePoint(point);
}
void Coordinate::moveTo(const AbsolutePoint & where){
double dx = position2.getRelativeX() - position.getRelativeX();
double dy = position2.getRelativeY() - position.getRelativeY();
setPosition(where);
/* sort of ugly, use operator+ for RelativePosition */
setPosition2(RelativePoint(position.getRelativeX() + dx, position.getRelativeY() + dy));
}
void Coordinate::checkDimensions(){
if (getWidth() < 0 || getHeight() < 0){
std::ostringstream out;
out << "Cannot have a negative coordinate dimension " << getWidth() << ", " << getHeight();
throw LoadException(__FILE__, __LINE__, out.str());
}
}
void Coordinate::setDimensions(int width, int height){
position2 = RelativePoint(AbsolutePoint(getX() + width, getY() + height));
}
void Coordinate::setCenterPosition(const RelativePoint & center){
int width = getWidth();
int height = getHeight();
this->position = center;
this->position2 = center;
growHorizontalAbsolute(width / 2.0);
growVerticalAbsolute(height / 2.0);
}
diff --git a/util/gui/coordinate.h b/util/gui/coordinate.h
index 0fbb1f1b..8b0498fc 100644
--- a/util/gui/coordinate.h
+++ b/util/gui/coordinate.h
@@ -1,231 +1,233 @@
#ifndef _paintown_gui_coordinate_h
#define _paintown_gui_coordinate_h
+namespace Graphics{
class Bitmap;
+}
namespace Gui {
namespace Space{
class Space;
/* a 2-d point */
class Point{
public:
Point(double x, double y, const Space & space);
Point(const Point & point, const Space & space);
Point(const Point & point);
Point operator+(const Point &);
Point & operator+=(const Point &);
Point & operator=(const Point &);
/* convert to physical space */
int physicalX() const;
int physicalY() const;
double x;
double y;
const Space & space;
private:
/* true if points use the same space system */
bool sameSpace(const Point & point);
};
/* mapping from coordinate space to physical space */
class Space{
public:
Space(double minX, double minY, double maxX, double maxY);
Point fromPhysical(int x, int y);
bool operator==(const Space & space) const;
double sizeX() const;
double sizeY() const;
double centerX() const;
double centerY() const;
double getLocalX(int physicalX) const;
double getLocalY(int physicalY) const;
private:
double minX, minY, maxX, maxY;
};
}
/* Coordinate system for handling scalable graphics */
class AbsolutePoint {
public:
AbsolutePoint();
explicit AbsolutePoint(int x, int y);
AbsolutePoint(const AbsolutePoint &);
virtual ~AbsolutePoint();
const AbsolutePoint & operator=(const AbsolutePoint &);
virtual inline void setX(int x){
this->x = x;
}
virtual int getX() const;
virtual inline void setY(int y){
this->y = y;
}
virtual int getY() const;
private:
int x;
int y;
};
class RelativePoint {
public:
RelativePoint();
explicit RelativePoint(double x, double y);
RelativePoint(const RelativePoint &);
RelativePoint(const AbsolutePoint &);
virtual ~RelativePoint();
const RelativePoint & operator=(const RelativePoint &);
const RelativePoint & operator=(const AbsolutePoint &);
bool operator==(const RelativePoint &);
bool operator!=(const RelativePoint &);
virtual inline void setX(double x){
this->x = x;
}
virtual int getX() const;
virtual inline void setY(double y){
this->y = y;
}
virtual int getY() const;
virtual inline void set(double x, double y){
this->x = x;
this->y = y;
}
virtual int getDistanceFromCenterX();
virtual int getDistanceFromCenterY();
virtual void moveX(double percent);
virtual void moveY(double percent);
virtual void moveBy(double x, double y);
virtual AbsolutePoint getAbsolute();
virtual double getRelativeX() const;
virtual double getRelativeY() const;
private:
double x;
double y;
};
class Coordinate {
public:
Coordinate();
Coordinate(AbsolutePoint &, AbsolutePoint &);
Coordinate(const RelativePoint &, const RelativePoint &);
Coordinate(const Coordinate &);
virtual ~Coordinate();
const Coordinate & operator=(const Coordinate &);
virtual inline void setZ(double z){
this->z = z;
}
virtual inline double getZ() const{
return this->z;
}
virtual inline void setRadius(double radius){
this->radius = radius;
}
virtual inline double getRadius() const{
return this->radius;
}
virtual int getX() const;
virtual int getY() const;
virtual int getWidth() const;
virtual int getHeight() const;
virtual int getX2() const;
virtual int getY2() const;
/* give a relative quantity */
virtual void growHorizontal(double by);
/* give an absolute quantity */
virtual void growHorizontalAbsolute(int by);
/* give a relative quantity */
virtual void growVertical(double by);
/* give an absolute quantity */
virtual void growVerticalAbsolute(int by);
virtual void growTo(const Coordinate &, double percent = 0.005);
virtual void center(const Coordinate &);
virtual void moveBy(double x, double y);
virtual inline double getRelativeX1() const{
return this->position.getRelativeX();
}
virtual inline double getRelativeX2() const{
return this->position2.getRelativeX();
}
virtual inline double getRelativeY1() const{
return this->position.getRelativeY();
}
virtual inline double getRelativeY2() const{
return this->position2.getRelativeY();
}
virtual inline void set(double x1, double y1, double x2, double y2){
this->position.setX(x1);
this->position.setY(y1);
this->position2.setX(x2);
this->position2.setY(y2);
}
virtual inline void setX1(double x){
this->position.setX(x);
}
virtual inline void setX2(double x){
this->position2.setX(x);
}
virtual inline void setY1(double y){
this->position.setY(y);
}
virtual inline void setY2(double y){
this->position2.setY(y);
}
bool operator==( const Coordinate &);
bool operator!=( const Coordinate &);
- bool operator==( const Bitmap &);
- bool operator!=( const Bitmap &);
+ bool operator==( const Graphics::Bitmap &);
+ bool operator!=( const Graphics::Bitmap &);
/* moves the positions so that `center' is in the middle but the
* width/height is maintained
*/
virtual void setCenterPosition(const RelativePoint & center);
virtual void setPosition(const RelativePoint &);
virtual void setPosition(const AbsolutePoint &);
virtual void setPosition2(const RelativePoint &);
virtual void setPosition2(const AbsolutePoint &);
virtual void moveTo(const AbsolutePoint &);
virtual void setDimensions(int width, int height);
virtual inline RelativePoint & getPosition(){
return this->position;
}
virtual inline RelativePoint & getPosition2(){
return this->position2;
}
virtual inline bool empty(){
return (getWidth() == 0 && getHeight() == 0);
}
private:
void checkDimensions();
RelativePoint position;
RelativePoint position2;
double z;
double radius;
};
}
#endif
diff --git a/util/gui/fadetool.cpp b/util/gui/fadetool.cpp
index d960e861..b2e432d0 100644
--- a/util/gui/fadetool.cpp
+++ b/util/gui/fadetool.cpp
@@ -1,152 +1,152 @@
#include "fadetool.h"
#include "../bitmap.h"
#include "../trans-bitmap.h"
#include "../token.h"
#include "../load_exception.h"
using namespace Gui;
FadeTool::FadeTool():
currentState(FadeIn),
lastState(FadeIn),
fadeTime(0),
fadeInTime(0),
fadeOutTime(0),
-fadeInColor(Bitmap::makeColor(0,0,0)),
-fadeOutColor(Bitmap::makeColor(0,0,0)){
+fadeInColor(Graphics::Bitmap::makeColor(0,0,0)),
+fadeOutColor(Graphics::Bitmap::makeColor(0,0,0)){
}
FadeTool::~FadeTool(){
}
void FadeTool::parseDefaults(const Token * token){
if ( *token != "fade" ){
throw LoadException(__FILE__, __LINE__, "Not a fader");
}
/*!
* (fade
(in (color 0 0 0) (time 0) )
(out (color 0 0 0) (time 0) ))
*/
const Token & ourToken = *token;
TokenView view = ourToken.view();
/* FIXME: this code looks like its expecting a structure like
* (in (color ...) (out ...))
* But its not parsing that way, rewrite it
*/
while (view.hasMore()){
try{
const Token * tok;
view >> tok;
if (*tok == "in"){
TokenView inView = tok->view();
/* FIXME: this loop is pretty wierd, shouldn't the if's be on the outside? */
while (inView.hasMore()){
if (*tok == "color"){
int r=0,g=0,b=0;
try {
inView >> r >> g >> b;
} catch (const TokenException & ex){
}
- setFadeInColor(Bitmap::makeColor(r,b,g));
+ setFadeInColor(Graphics::Bitmap::makeColor(r,b,g));
} else if (*tok == "time"){
int time=0;
try {
inView >> time;
} catch (const TokenException & ex){
}
setFadeInTime(time);
}
}
} else if (*tok == "out"){
/*
Token & out = *tok;
while (out.hasTokens()){
if (out == "color"){
int r=0,g=0,b=0;
try {
out >> r >> g >> b;
} catch (const TokenException & ex){
}
setFadeOutColor(Bitmap::makeColor(r,b,g));
} else if (out == "time"){
int time=0;
try {
out >> time;
} catch (const TokenException & ex){
}
setFadeOutTime(time);
}
}
*/
}
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Fade tool parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
}
void FadeTool::setState( const State & f){
lastState = currentState;
currentState = f;
switch (currentState){
case FadeIn:
fadeTime = 255;
break;
case FadeOut:
fadeTime = 0;
break;
case NoFade:
case EndFade:
default:
fadeTime = 0;
break;
}
}
void FadeTool::act(){
switch (currentState){
case FadeIn:
fadeTime-=(255/(fadeInTime <= 0 ? 1 : fadeInTime));
if (fadeTime<=0){
setState(NoFade);
}
break;
case FadeOut:
fadeTime+=(255/(fadeOutTime <= 0 ? 1 : fadeOutTime));
if (fadeTime>=255){
setState(EndFade);
}
break;
case NoFade:
case EndFade:
default:
break;
}
}
-void FadeTool::draw(const Bitmap &bmp){
+void FadeTool::draw(const Graphics::Bitmap &bmp){
switch (currentState){
case FadeIn:
- // Bitmap::drawingMode(Bitmap::MODE_TRANS);
- Bitmap::transBlender(0,0,0,fadeTime);
+ // Graphics::Bitmap::drawingMode(Bitmap::MODE_TRANS);
+ Graphics::Bitmap::transBlender(0,0,0,fadeTime);
bmp.translucent().rectangleFill(0, 0, bmp.getWidth(),bmp.getHeight(),fadeInColor);
// Bitmap::drawingMode(Bitmap::MODE_SOLID);
break;
case FadeOut:
- // Bitmap::drawingMode(Bitmap::MODE_TRANS);
- Bitmap::transBlender(0,0,0,fadeTime);
+ // Graphics::Bitmap::drawingMode(Bitmap::MODE_TRANS);
+ Graphics::Bitmap::transBlender(0,0,0,fadeTime);
bmp.translucent().rectangleFill(0, 0, bmp.getWidth(),bmp.getHeight(),fadeOutColor);
// Bitmap::drawingMode(Bitmap::MODE_SOLID);
break;
case NoFade:
case EndFade:
default:
break;
}
}
diff --git a/util/gui/fadetool.h b/util/gui/fadetool.h
index b6b1ea0d..fc584f08 100644
--- a/util/gui/fadetool.h
+++ b/util/gui/fadetool.h
@@ -1,76 +1,78 @@
#ifndef gui_fadetool_h
#define gui_fadetool_h
-/*! FADE UTILITY */
+/*! Fade utility */
+namespace Graphics{
class Bitmap;
+}
class Token;
namespace Gui{
class FadeTool{
public:
FadeTool();
virtual ~FadeTool();
enum State{
FadeIn,
FadeOut,
NoFade,
EndFade,
};
//! Read info from Token
void parseDefaults(const Token *);
// Fade state
void setState(const State &);
// update
void act();
// Fade to whatever state it is at
- virtual void draw(const Bitmap &);
+ virtual void draw(const Graphics::Bitmap &);
inline const State & getState() const {
return currentState;
}
inline void setFadeInTime(const int time){
fadeInTime = time;
}
inline void setFadeOutTime(const int time){
fadeOutTime = time;
}
inline int getFadeInTime() const {
return fadeInTime;
}
inline int getFadeOutTime() const {
return fadeOutTime;
}
inline void setFadeInColor( int c ){
fadeInColor = c;
}
inline int getFadeInColor() const {
return fadeInColor;
}
inline void setFadeOutColor( int c ){
fadeInColor = c;
}
inline int getFadeOutColor() const {
return fadeInColor;
}
private:
State currentState;
State lastState;
int fadeTime;
int fadeInTime;
int fadeOutTime;
int fadeInColor;
int fadeOutColor;
};
}
#endif
diff --git a/util/gui/lineedit.cpp b/util/gui/lineedit.cpp
index f70bc1ad..d0a0014d 100644
--- a/util/gui/lineedit.cpp
+++ b/util/gui/lineedit.cpp
@@ -1,360 +1,360 @@
#include "util/bitmap.h"
#include "util/trans-bitmap.h"
#include "util/font.h"
#include "lineedit.h"
#include "keys.h"
#include "globals.h"
#include "util/debug.h"
#include <iostream>
using namespace Gui;
static std::ostream & debug( int level ){
Global::debug(level) << "[line edit] ";
return Global::debug(level);
}
LineEdit::LineEdit() :
currentSetFont(0),
hAlignment(T_Middle),
hAlignMod(T_Middle),
vAlignment(T_Middle),
inputTypeValue(inputGeneral),
changed_(0),
autoResizable(0),
textX(0),
textY(0),
cursorX(0),
cursorY(0),
cursorIndex(0),
textColor(0),
textSizeH(0),
limit(0),
blinkRate(500),
blink(false),
focused(false),
changeCounter(0){
cursorTime.reset();
}
LineEdit::~LineEdit()
{
}
void LineEdit::hookKey(int key, void (*callback)(void *), void * arg){
input.addBlockingHandle(key, callback, arg);
}
bool LineEdit::didChanged(unsigned long long & counter){
bool did = counter < changeCounter;
counter = changeCounter;
return did;
}
// If the font size changes
void LineEdit::fontChange(){
changed();
}
// Update
void LineEdit::act(const Font & font){
if (cursorTime.msecs() >= blinkRate){
cursorTime.reset();
blink = !blink;
changed();
}
/*
if ((blinkRate * 2) <= cursorTime.msecs()){
cursorTime.reset();
changed();
}
*/
if (input.doInput()){
changed();
cursorIndex = input.getText().size();
}
if (changed_){
textSizeH = currentSetFont->getHeight();
if (autoResizable) {
location.setDimensions(textSizeH+2, currentSetFont->textLength(input.getText().c_str()) + 4);
} else {
if (hAlignMod==T_Left){
if (currentSetFont->textLength(input.getText().c_str())>location.getWidth()){
hAlignment = T_Right;
} else {
hAlignment = T_Left;
}
}
}
switch (hAlignment) {
case T_Left:
textX = 2;
cursorX = textX + currentSetFont->textLength(input.getText().substr(0,cursorIndex).c_str()) + 1;
break;
case T_Middle:
textX = (location.getWidth()/2) - (currentSetFont->textLength(input.getText().c_str())/2);
cursorX = (textX) + currentSetFont->textLength(input.getText().substr(0,cursorIndex).c_str()) + 1;
break;
case T_Right:
textX = location.getWidth() - currentSetFont->textLength(input.getText().c_str());//(position.width - 1)-2;
cursorX = location.getWidth() - currentSetFont->textLength(input.getText().substr(0, input.getText().length()-cursorIndex).c_str());
break;
case T_Bottom:
case T_Top:
break;
}
switch (vAlignment) {
case T_Top:
textY = 1;
cursorY = 1;
break;
case T_Middle:
textY = cursorY = (location.getHeight() - textSizeH-(5))/2;
break;
case T_Bottom:
textY = (location.getHeight() - 1) - textSizeH - 1;
cursorY = textY - textSizeH;
break;
case T_Right:
case T_Left:
break;
}
//textY++;
//textX++;
stable();
}
}
// Draw
-void LineEdit::render(const Bitmap & work){
+void LineEdit::render(const Graphics::Bitmap & work){
checkWorkArea();
// Check if we are using a rounded box
if (location.getRadius()>0) {
- Bitmap::transBlender( 0, 0, 0, colors.bodyAlpha );
+ Graphics::Bitmap::transBlender( 0, 0, 0, colors.bodyAlpha );
roundRectFill( *workArea, (int)location.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.body );
workArea->translucent().draw(location.getX(),location.getY(),work);
- workArea->fill(Bitmap::makeColor(255,0,255));
+ workArea->fill(Graphics::Bitmap::makeColor(255,0,255));
- Bitmap::transBlender( 0, 0, 0, colors.borderAlpha );
+ Graphics::Bitmap::transBlender( 0, 0, 0, colors.borderAlpha );
roundRect( *workArea, (int)location.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.border );
workArea->translucent().draw(location.getX(),location.getY(),work);
} else {
- Bitmap::transBlender( 0, 0, 0, colors.bodyAlpha );
+ Graphics::Bitmap::transBlender( 0, 0, 0, colors.bodyAlpha );
workArea->rectangleFill( 0, 0, location.getWidth()-1, location.getHeight()-1, colors.body );
workArea->translucent().draw(location.getX(),location.getY(),work);
- workArea->fill(Bitmap::makeColor(255,0,255));
+ workArea->fill(Graphics::Bitmap::makeColor(255,0,255));
- Bitmap::transBlender( 0, 0, 0, colors.borderAlpha );
+ Graphics::Bitmap::transBlender( 0, 0, 0, colors.borderAlpha );
workArea->rectangle( 0, 0, location.getWidth()-1, location.getHeight()-1, colors.border );
workArea->translucent().draw(location.getX(),location.getY(),work);
}
// work.drawingMode( Bitmap::MODE_SOLID );
- workArea->fill(Bitmap::makeColor(255,0,255));
+ workArea->fill(Graphics::Bitmap::makeColor(255,0,255));
if (currentSetFont){
currentSetFont->printf(textX,textY,textColor,*workArea, input.getText(), 0);
}
if (focused){
/*
if (cursorTime.msecs() <= blinkRate){
workArea->line(cursorX,cursorY,cursorX,cursorY+textSizeH-5,textColor);
}
*/
if (blink){
workArea->line(cursorX,cursorY,cursorX,cursorY+textSizeH-5,textColor);
}
}
workArea->draw(location.getX(), location.getY(), work);
}
#if 0
// Keypresses
sigslot::slot LineEdit::keyPress(const keys &k)
{
debug( 5 ) << "Received key press " << k.getValue() << std::endl;
if(focused)
{
if(k.isCharacter())
{
char keyValue = k.getValue();
bool addValue = false;
switch(inputTypeValue){
case inputNumerical:
if ( k.isNumber() ) addValue = !addValue;
break;
case inputNoCaps:
keyValue = tolower(keyValue);
addValue = !addValue;
break;
case inputAllCaps:
keyValue = toupper(keyValue);
addValue = !addValue;
break;
case inputGeneral:
default:
addValue = !addValue;
break;
}
if(addValue){
if(limit!=0)
{
if(currentSetText.length()<limit)
{
//currentSetText += k.getValue();
currentSetText.insert(cursorIndex, std::string(1,keyValue));
++cursorIndex;
changed();
}
}
else
{
//currentSetText += k.getValue();
currentSetText.insert(cursorIndex, std::string(1,keyValue));
++cursorIndex;
changed();
}
}
}
else
{
switch(k.getValue())
{
case keys::DEL:
if(cursorIndex<currentSetText.length())
{
currentSetText.erase(cursorIndex,1);
}
break;
case keys::BACKSPACE:
if(cursorIndex>0)
{
currentSetText.erase(cursorIndex - 1, 1);
--cursorIndex;
}
break;
case keys::RIGHT:
if(cursorIndex<currentSetText.length())++cursorIndex;
break;
case keys::LEFT:
if(cursorIndex>0)--cursorIndex;
break;
case keys::INSERT:
break;
}
changed();
}
}
}
#endif
// Set text
void LineEdit::setText(const std::string & text){
input.setText(text);
if (limit!=0) {
if (input.getText().length() > limit) {
while (input.getText().length() > limit){
// currentSetText.erase(currentSetText.begin()+currentSetText.length()-1);
}
}
}
cursorIndex = input.getText().length();
changed();
}
//! Get text
const std::string LineEdit::getText(){
return input.getText();
}
//! Clear text
void LineEdit::clearText(){
input.clearInput();
cursorIndex=0;
changed();
}
//! Set text limit
void LineEdit::setLimit(unsigned int l){
limit = l;
if (limit!=0){
if (input.getText().length()>limit){
while (input.getText().length()>limit){
// currentSetText.erase(currentSetText.begin()+currentSetText.length()-1);
}
}
}
cursorIndex = input.getText().length();
changed();
}
// Set Horizontal Alignment
void LineEdit::setHorizontalAlign(const textAlign & a){
hAlignment = hAlignMod = a;
changed();
}
// Set Vertical Alignment
void LineEdit::setVerticalAlign(const textAlign & a){
vAlignment = a;
changed();
}
//! Set the type of input default general
void LineEdit::setInputType(const inputType i){
inputTypeValue = i;
}
// Set textColor
void LineEdit::setTextColor(const int color){
textColor = color;
}
//! Set textColor
void LineEdit::setCursorColor(const int color){
textColor = color;
}
// Set font
void LineEdit::setFont(const Font *f){
currentSetFont = f;
if (currentSetFont) changed();
}
// Set autoResizeable
void LineEdit::setAutoResize(bool r){
autoResizable = r;
}
// Set the cursor blink rate in miliseconds (default 500)
void LineEdit::setCursorBlinkRate(unsigned int msecs){
blinkRate = msecs;
}
//! set Focus
void LineEdit::setFocused(bool focus){
focused = focus;
if (focus){
input.enable();
} else {
input.disable();
}
}
//! check Focus
bool LineEdit::isFocused(){
return focused;
}
diff --git a/util/gui/lineedit.h b/util/gui/lineedit.h
index e00f5957..5d9487a5 100644
--- a/util/gui/lineedit.h
+++ b/util/gui/lineedit.h
@@ -1,178 +1,178 @@
#ifndef paintown_gui_lineedit_h
#define paintown_gui_lineedit_h
#include <iostream>
#include <vector>
#include "widget.h"
#include "timer.h"
#include "sigslot.h"
#include "util/input/text-input.h"
class Font;
class keys;
namespace Gui{
class LineEdit: public Widget, public sigslot::has_slots<> {
public:
//! enumerator housing alignment positions
enum textAlign {
T_Left = 0,
T_Middle,
T_Right,
T_Top,
T_Bottom
};
//! enumerator housing alignment positions
enum inputType {
inputGeneral = 0,
inputAllCaps,
inputNoCaps,
inputNumerical
};
//! Constructor
LineEdit();
//! Destructor
virtual ~LineEdit();
//! Set text
void setText(const std::string & text);
//! Get text
const std::string getText();
//! Clear text
void clearText();
//! Set text limit (default 0, no limit)
void setLimit(unsigned int l);
void hookKey(int key, void (*callback)(void *), void * arg);
//! Set Horizontal Alignment
void setHorizontalAlign(const textAlign & a);
//! Set Vertical Alignment
void setVerticalAlign(const textAlign & a);
//! Set the type of input default general
void setInputType(const inputType i = inputGeneral);
//! Set textColor
void setTextColor(const int color);
//! Set textColor
void setCursorColor(const int color);
//! Set font
void setFont(const Font *f);
//! Set autoResizeable
void setAutoResize(bool r);
//! Set the cursor blink rate in miliseconds (default 500)
void setCursorBlinkRate(unsigned int msecs);
//! Update
void act(const Font &);
//! Draw
using Widget::render;
- void render(const Bitmap &);
+ void render(const Graphics::Bitmap &);
//! set Focus
void setFocused(bool focus);
//! check Focus
bool isFocused();
//! Keypresses
// sigslot::slot keyPress(const keys &k);
bool didChanged( unsigned long long & counter );
protected:
//! Current font the label is currently using (uses systemFont by default)
const Font *currentSetFont;
//! Current set text
// std::string currentSetText;
//! Horizontal Alignment (RIGHT, MIDDLE, LEFT)
textAlign hAlignment;
//! Additional checker for Horizontal alignment for easy adjustment
textAlign hAlignMod;
//! Vertical Alignment (TOP, MIDDLE, BOTTOM)
textAlign vAlignment;
//! Input type
inputType inputTypeValue;
//! Has changed?
bool changed_;
//! Auto resize
bool autoResizable;
//! Text horizontal position
int textX;
//! Text vertical position
int textY;
//! Cursor horizontal position
int cursorX;
//! Cursor vertical position
int cursorY;
//! Cursor index relative to the string
unsigned int cursorIndex;
//! Text color
int textColor;
//! Text size Height check in case it changes
int textSizeH;
//! Text limit
unsigned int limit;
//! Cursor timer
guiTimer cursorTime;
//! Cursor blink rate
unsigned int blinkRate;
bool blink;
//! Focused?
bool focused;
TextInput input;
// keeps track of changes
unsigned long long changeCounter;
//! If the font size changes
void fontChange();
inline void changed(){
changed_ = true;
changeCounter += 1;
}
inline void stable(){
changed_ = false;
}
};
}
#endif
diff --git a/util/gui/popup-box.cpp b/util/gui/popup-box.cpp
index 1537219d..e344f160 100644
--- a/util/gui/popup-box.cpp
+++ b/util/gui/popup-box.cpp
@@ -1,98 +1,98 @@
#include "util/bitmap.h"
#include "popup-box.h"
using namespace std;
using namespace Gui;
PopupBox::PopupBox():
fadeState(Closed),
fadeSpeed(12){
}
PopupBox::PopupBox( const PopupBox & copy ):
fadeState(Closed){
this->fadeSpeed = copy.fadeSpeed;
}
PopupBox::~PopupBox(){
}
PopupBox & PopupBox::operator=( const PopupBox & copy){
this->fadeState = Closed;
this->fadeSpeed = copy.fadeSpeed;
return *this;
}
void PopupBox::act(const Font & font){
// do fade
doFade();
}
-void PopupBox::render(const Bitmap & work){
+void PopupBox::render(const Graphics::Bitmap & work){
board.render(work);
}
void PopupBox::open(){
// Set the fade stuff
fadeState = FadeIn;
board.location = location;
board.colors = colors;
board.location.center(location);
board.colors.borderAlpha = board.colors.bodyAlpha = 0;
}
void PopupBox::close(){
fadeState = FadeOut;
}
void PopupBox::doFade(){
switch (fadeState){
case FadeIn: {
board.location.growTo(location, 0.0025 * fadeSpeed);
if (board.colors.borderAlpha < colors.borderAlpha){
board.colors.borderAlpha += (int)(fadeSpeed/2);
if (board.colors.borderAlpha >= colors.borderAlpha){
board.colors.borderAlpha = colors.borderAlpha;
}
}
if (board.colors.bodyAlpha < colors.bodyAlpha){
board.colors.bodyAlpha += (int)(fadeSpeed/2);
if (board.colors.bodyAlpha >= colors.bodyAlpha){
board.colors.bodyAlpha = colors.bodyAlpha;
}
}
if (board.location == location && board.colors.bodyAlpha == colors.bodyAlpha && board.colors.borderAlpha == colors.borderAlpha){
fadeState = Open;
}
break;
}
case FadeOut: {
Coordinate coord;
coord.center(location);
board.location.growTo(coord, 0.0025 * fadeSpeed);
if (board.colors.borderAlpha > 0){
board.colors.borderAlpha -= (int)(fadeSpeed/2);
if (board.colors.borderAlpha <= 0){
board.colors.borderAlpha = 0;
}
}
if (board.colors.bodyAlpha > 0){
board.colors.bodyAlpha -= (int)(fadeSpeed/2);
if (board.colors.bodyAlpha <= 0){
board.colors.bodyAlpha = 0;
}
}
if (board.location.empty() && board.colors.borderAlpha == 0 && board.colors.bodyAlpha == 0){
fadeState = Closed;
}
break;
}
case Open:
case Closed:
default:
break;
}
}
diff --git a/util/gui/popup-box.h b/util/gui/popup-box.h
index ea0d0a85..c4e382b4 100644
--- a/util/gui/popup-box.h
+++ b/util/gui/popup-box.h
@@ -1,65 +1,65 @@
#ifndef _paintown_gui_popup_box_h
#define _paintown_gui_popup_box_h
#include <string>
#include <vector>
#include "widget.h"
#include "box.h"
#include "../gradient.h"
namespace Gui{
class PopupBox : public Widget {
public:
PopupBox();
PopupBox(const PopupBox &);
virtual ~PopupBox();
//! copy
PopupBox &operator=(const PopupBox &);
//! Logic
virtual void act(const Font &);
//! Render
using Widget::render;
- virtual void render(const Bitmap &);
+ virtual void render(const Graphics::Bitmap &);
//! Open box
virtual void open();
//! Close box
virtual void close();
//! Is active?
virtual inline bool isActive(){
return (this->fadeState != Closed);
}
//!set fadespeed
virtual inline void setFadeSpeed(int speed){
this->fadeSpeed = speed;
}
//! Get current box coordinates
virtual inline const Coordinate & getArea(){
return this->board.location;
}
private:
void doFade();
enum FadeState{
Closed,
FadeIn,
Open,
FadeOut,
};
//! Current fade state
FadeState fadeState;
//! Fade speed
int fadeSpeed;
//! Board
Box board;
};
}
#endif
diff --git a/util/gui/rectarea.cpp b/util/gui/rectarea.cpp
index 78f05e2c..5c3c3613 100644
--- a/util/gui/rectarea.cpp
+++ b/util/gui/rectarea.cpp
@@ -1,51 +1,51 @@
#include "../bitmap.h"
#include "rectarea.h"
using namespace Gui;
RectArea::RectArea():
x(0),
y(0),
width(0),
height(0),
radius(0){
}
RectArea::RectArea(int x, int y, int w, int h):
x(x),
y(y),
width(w),
height(h),
radius(0){
}
bool RectArea::empty(){
// return (x==0 && y==0 && width==0 && height==0);
return width == 0 && height == 0;
}
bool RectArea::operator==( const RectArea &rect){
return ( (x == rect.x) &&
(y == rect.y) &&
(width == rect.width) &&
(height == rect.height));
}
bool RectArea::operator!=( const RectArea &rect){
return ( (x != rect.x) ||
(y != rect.y) ||
(width != rect.width) ||
(height != rect.height));
}
-bool RectArea::operator==( const Bitmap &bmp){
+bool RectArea::operator==( const Graphics::Bitmap &bmp){
return ( (width == bmp.getWidth()) &&
(height == bmp.getHeight()));
}
-bool RectArea::operator!=( const Bitmap &bmp){
+bool RectArea::operator!=( const Graphics::Bitmap &bmp){
return ( (width != bmp.getWidth()) ||
(height != bmp.getHeight()));
}
diff --git a/util/gui/rectarea.h b/util/gui/rectarea.h
index 398db4df..e37fc18a 100644
--- a/util/gui/rectarea.h
+++ b/util/gui/rectarea.h
@@ -1,29 +1,31 @@
#ifndef _paintown_gui_rectarea_h
#define _paintown_gui_rectarea_h
+namespace Graphics{
class Bitmap;
+}
namespace Gui{
struct RectArea{
RectArea();
RectArea(int x, int y, int w, int h);
inline int getX1() const { return x; }
inline int getY1() const { return y; }
inline int getX2() const { return x + width; }
inline int getY2() const { return y + height; }
bool operator==( const RectArea &);
bool operator!=( const RectArea &);
- bool operator==( const Bitmap &);
- bool operator!=( const Bitmap &);
+ bool operator==( const Graphics::Bitmap &);
+ bool operator!=( const Graphics::Bitmap &);
bool empty();
int x;
int y;
int width;
int height;
int radius;
};
}
#endif
diff --git a/util/gui/tabbed-box.cpp b/util/gui/tabbed-box.cpp
index 810b76ec..cc8a6e88 100644
--- a/util/gui/tabbed-box.cpp
+++ b/util/gui/tabbed-box.cpp
@@ -1,301 +1,301 @@
#include "../bitmap.h"
#include "../trans-bitmap.h"
#include "tabbed-box.h"
#include "menu/menu.h"
#include "util/font.h"
#include "context-box.h"
using namespace Gui;
#if 0
/* FIXME add rounded tabs */
static void roundTab( const Bitmap & work, int radius, int x1, int y1, int x2, int y2, int color, bool bottom = true ){
const int width = x2 - x1;
const int height = y2 - y1;
radius = Mid(0, radius, Min((x1+width - x1)/2, (y1+height - y1)/2));
work.circleFill(x1+radius, y1+radius, radius, color);
work.circleFill((x1+width)-radius, y1+radius, radius, color);
work.circleFill(x1+radius, (y1+height)-radius, radius, color);
work.circleFill((x1+width)-radius, (y1+height)-radius, radius, color);
work.rectangleFill( x1+radius, y1, x2-radius, y1+radius, color);
work.rectangleFill( x1, y1+radius, x2, y2-radius, color);
work.rectangleFill( x1+radius, y2-radius, x2-radius, y2, color);
work.line(x1+radius, y1, x1+width-radius, y1, color);
work.line(x1+radius, y1+height, x1+width-radius,y1+height, color);
work.line(x1, y1+radius,x1, y1+height-radius, color);
work.line(x1+width, y1+radius,x1+width, y1+height-radius, color);
arc(work, x1+radius, y1+radius, S_PI-1.115, radius, color);
arc(work, x1+radius + (width - radius *2), y1+radius, -S_PI/2 +0.116, radius, color);
arc(work, x1+width-radius, y1+height-radius, -0.110, radius ,color);
arc(work, x1+radius, y1+height-radius, S_PI/2-0.119, radius, color);
}
#endif
Tab::Tab():
context(new ContextBox()),
active(false){
// Set alpha to 0 as we are not interested in the box
context->setRenderOnlyText(true);
}
Tab::~Tab(){
delete context;
}
TabbedBox::TabbedBox():
current(0),
fontWidth(24),
fontHeight(24),
inTab(false),
tabWidthMax(0),
-tabFontColor(Bitmap::makeColor(255,255,255)),
-currentTabFontColor(Bitmap::makeColor(0,0,255)){
+tabFontColor(Graphics::Bitmap::makeColor(255,255,255)),
+currentTabFontColor(Graphics::Bitmap::makeColor(0,0,255)){
activeTabFontColor = new Effects::Gradient(50, tabFontColor, currentTabFontColor);
}
TabbedBox::TabbedBox(const TabbedBox & b):
activeTabFontColor(NULL){
this->location = b.location;
this->workArea = b.workArea;
}
TabbedBox::~TabbedBox(){
for (std::vector<Gui::Tab *>::iterator i = tabs.begin(); i != tabs.end(); ++i){
Gui::Tab * tab = *i;
if (tab){
delete tab;
}
}
if (activeTabFontColor){
delete activeTabFontColor;
}
}
TabbedBox &TabbedBox::operator=( const TabbedBox &copy){
location = copy.location;
workArea = copy.workArea;
return *this;
}
// Logic
void TabbedBox::act(const Font & font){
if (!tabs.empty()){
// const Font & vFont = Font::getFont(font, fontWidth, fontHeight);
//tabWidthMax = location.getWidth()/tabs.size();
const int width = font.textLength(tabs[current]->name.c_str()) + 5;
tabWidthMax = (location.getWidth() - width) / (tabs.size() - 1);
} else {
return;
}
if (!tabs[current]->active){
tabs[current]->active = true;
}
tabs[current]->context->act(font);
if (inTab){
if (activeTabFontColor){
activeTabFontColor->update();
}
}
}
-void TabbedBox::render(const Bitmap & work){
+void TabbedBox::render(const Graphics::Bitmap & work){
/* nothing */
}
// Render
-void TabbedBox::render(const Bitmap & work, const Font & font){
+void TabbedBox::render(const Graphics::Bitmap & work, const Font & font){
const int tabHeight = fontHeight + 5;
// checkWorkArea();
- Bitmap area(work, location.getX(), location.getY(), location.getWidth(), location.getHeight());
+ Graphics::Bitmap area(work, location.getX(), location.getY(), location.getWidth(), location.getHeight());
// Check if we are using a rounded box
if (location.getRadius() > 0){
//roundRectFill( *workArea, (int)location.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.body );
//roundRect( *workArea, (int)location.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.border );
} else {
area.translucent().rectangleFill(0, tabHeight+1, location.getWidth()-1, location.getHeight()-1, colors.body );
//area.translucent().rectangle(0, tabHeight, location.getWidth()-1, location.getHeight()-1, colors.border );
area.translucent().vLine(tabHeight,0,location.getHeight()-1,colors.border);
area.translucent().hLine(0,location.getHeight()-1,location.getWidth()-1,colors.border);
area.translucent().vLine(tabHeight,location.getWidth()-1,location.getHeight()-1,colors.border);
}
tabs[current]->context->render(area, font);
renderTabs(area, font);
/* FIXME: only render the background in translucent mode, the text should
* not be translucent
*/
// workArea->draw(location.getX(), location.getY(), work);
}
// Add tab
void TabbedBox::addTab(const std::string & name, const std::vector<ContextItem *> & list){
for (std::vector<Tab *>::iterator i = tabs.begin(); i != tabs.end(); ++i){
Tab * tab = *i;
if (tab->name == name){
return;
}
}
Tab * tab = new Tab();
tab->name = name;
tab->context->setList(list);
// tab->context->setFont(font, fontWidth, fontHeight);
const int modifier = fontHeight * .35;
tab->context->location.setPosition(Gui::AbsolutePoint(0, fontHeight + modifier));
tab->context->location.setPosition2(Gui::AbsolutePoint(location.getWidth(), location.getHeight()- modifier));
tab->context->open();
tabs.push_back(tab);
}
void TabbedBox::moveTab(int direction){
tabs[current]->context->close();
tabs[current]->active = false;
current = (unsigned int) ((int)current + direction + (int) tabs.size()) % tabs.size();
/*
if (current == 0){
current = tabs.size()-1;
} else {
current--;
}
*/
tabs[current]->context->open();
tabs[current]->active = true;
}
void TabbedBox::up(const Font & font){
if (tabs.size() == 0){
return;
}
if (!inTab){
moveTab(-1);
} else {
tabs[current]->context->previous(font);
}
}
void TabbedBox::down(const Font & font){
if (tabs.size() == 0){
return;
}
if (!inTab){
moveTab(1);
} else {
tabs[current]->context->next(font);
}
}
void TabbedBox::left(const Font & font){
if (tabs.size() == 0){
return;
}
if (!inTab){
moveTab(-1);
} else {
tabs[current]->context->adjustLeft();
}
}
void TabbedBox::right(const Font & font){
if (tabs.size() == 0){
return;
}
if (!inTab){
moveTab(1);
} else {
tabs[current]->context->adjustRight();
}
}
void TabbedBox::toggleTabSelect(){
inTab = !inTab;
}
unsigned int TabbedBox::getCurrentIndex() const {
if (tabs.size() == 0){
return 0;
}
return this->tabs[current]->context->getCurrentIndex();
}
void TabbedBox::setTabFontColor(int color){
tabFontColor = color;
if (activeTabFontColor){
delete activeTabFontColor;
}
activeTabFontColor = new Effects::Gradient(50, tabFontColor, currentTabFontColor);
}
void TabbedBox::setSelectedTabFontColor(int color){
currentTabFontColor = color;
if (activeTabFontColor){
delete activeTabFontColor;
}
activeTabFontColor = new Effects::Gradient(50, tabFontColor, currentTabFontColor);
}
-void TabbedBox::renderTabs(const Bitmap & bmp, const Font & vFont){
+void TabbedBox::renderTabs(const Graphics::Bitmap & bmp, const Font & vFont){
const int tabHeight = fontHeight + 5;
// const Font & vFont = Font::getFont(font, fontWidth, fontHeight);
int x = 0;
- Bitmap::transBlender(0, 0, 0, colors.bodyAlpha);
+ Graphics::Bitmap::transBlender(0, 0, 0, colors.bodyAlpha);
for (std::vector<Gui::Tab *>::iterator i = tabs.begin(); i != tabs.end(); ++i){
Gui::Tab * tab = *i;
const int textWidth = vFont.textLength(tab->name.c_str()) + 5;
// for last tab
int modifier = 0;
// Check last tab so we can ensure proper sizing
if ( i == (tabs.begin() + tabs.size() -1)){
if ( ( (tabWidthMax * (tabs.size() - 1) ) + textWidth ) != (unsigned int)location.getWidth() ){
modifier = location.getWidth() - x - (tab->active ? textWidth : tabWidthMax);
}
}
if (tab->context->location.getRadius() > 0){
} else {
if (tab->active){
if (!inTab){
//bmp.translucent().rectangle(x, 0, x+textWidth + modifier - 1, tabHeight, colors.border);
bmp.translucent().vLine(0,x,tabHeight,colors.border);
bmp.translucent().hLine(x,0,x+textWidth+modifier-1,colors.border);
bmp.translucent().vLine(0,x+textWidth+modifier-1,tabHeight,colors.border);
bmp.translucent().rectangleFill( x+1, 1, x+textWidth + modifier - 2, tabHeight, colors.body);
bmp.setClipRect(x, 0, x+textWidth + modifier, tabHeight-1);
vFont.printf(x + (((textWidth + modifier)/2)-(((textWidth + modifier) - 5)/2)), 0, currentTabFontColor, bmp, tab->name, 0 );
} else {
//bmp.translucent().rectangle(x, 0, x+textWidth + modifier -1, tabHeight, colors.border);
bmp.translucent().vLine(0,x,tabHeight,colors.border);
bmp.translucent().hLine(x,0,x+textWidth+modifier-1,colors.border);
bmp.translucent().vLine(0,x+textWidth+modifier-1,tabHeight,colors.border);
bmp.translucent().rectangleFill( x+1, 1, x+textWidth-2 + modifier, tabHeight, colors.body );
bmp.setClipRect(x, 0, x+textWidth + modifier, tabHeight-1);
vFont.printf(x + (((textWidth + modifier)/2)-(((textWidth + modifier) - 5)/2)), 0, activeTabFontColor->current(), bmp, tab->name, 0 );
}
x+=textWidth + modifier;
} else {
const int heightMod = tabHeight * .15;
bmp.translucent().rectangle(x, 1 + heightMod, x+tabWidthMax + modifier -1, tabHeight, tabColors.border);
bmp.translucent().hLine(x,tabHeight,x+tabWidthMax+modifier-1,colors.border);
bmp.translucent().rectangleFill( x+1, 2 + heightMod, x+tabWidthMax + modifier -2, tabHeight-2, tabColors.body);
bmp.setClipRect(x+2, 6 + heightMod, x+tabWidthMax + modifier -3, tabHeight-1);
vFont.printf(x + (((tabWidthMax + modifier)/2)-((textWidth + modifier)/2)), 0, tabFontColor, bmp, tab->name, 0 );
x += tabWidthMax + modifier;
}
bmp.setClipRect(0, 0, bmp.getWidth(), bmp.getHeight());
}
}
}
diff --git a/util/gui/tabbed-box.h b/util/gui/tabbed-box.h
index cb7ab213..7e051c6d 100644
--- a/util/gui/tabbed-box.h
+++ b/util/gui/tabbed-box.h
@@ -1,134 +1,134 @@
#ifndef _paintown_gui_tabbed_box_h
#define _paintown_gui_tabbed_box_h
#include <string>
#include <vector>
#include "widget.h"
#include "../file-system.h"
#include "../gradient.h"
class Token;
namespace Gui{
class ContextBox;
class ContextItem;
class Tab{
public:
Tab();
~Tab();
std::string name;
Gui::ContextBox * context;
bool active;
};
class TabbedBox : public Widget{
public:
TabbedBox();
TabbedBox( const TabbedBox & );
virtual ~TabbedBox();
//! copy
TabbedBox &operator=( const TabbedBox &);
//! Logic
virtual void act(const Font &);
//! Render
using Widget::render;
- virtual void render(const Bitmap &);
- virtual void render(const Bitmap &, const Font &);
+ virtual void render(const Graphics::Bitmap &);
+ virtual void render(const Graphics::Bitmap &, const Font &);
//! Add tab
virtual void addTab(const std::string &, const std::vector<ContextItem *> & list);
//! Up
virtual void up(const Font &);
//! Down
virtual void down(const Font &);
//! Left
virtual void left(const Font &);
//! Right
virtual void right(const Font &);
//! Virtual
virtual void toggleTabSelect();
//! Set current font
virtual inline void setFont(const Filesystem::RelativePath & font, int width, int height){
this->font = font;
this->fontWidth = width;
this->fontHeight = height;
}
//! Get current tab
virtual inline unsigned int getCurrentTab() const {
return this->current;
}
//! Get current index on selected tab
virtual unsigned int getCurrentIndex() const;
//! Set tab font colors
virtual void setTabFontColor(int color);
//! Set selected tab font color
virtual void setSelectedTabFontColor(int color);
//! Empty
virtual inline bool empty() const {
return this->tabs.empty();
}
virtual inline bool isInTab() const {
return this->inTab;
}
/*! Tab Colors */
ColorInfo tabColors;
/*! Selected Tab Colors */
ColorInfo selectedTabColors;
/*! Selected Tab Colors */
ColorInfo runningTabColors;
protected:
void moveTab(int direction);
std::vector<Gui::Tab *> tabs;
unsigned int current;
Filesystem::RelativePath font;
int fontWidth;
int fontHeight;
/*! Is in tab */
bool inTab;
/*! Max Width of tabs */
int tabWidthMax;
/*! Render tab */
- void renderTabs(const Bitmap &, const Font &);
+ void renderTabs(const Graphics::Bitmap &, const Font &);
/*! Font Color */
int tabFontColor;
/*! Current Tab Font Color */
int currentTabFontColor;
/*! Gradient for selected Font */
Effects::Gradient * activeTabFontColor;
};
}
#endif
diff --git a/util/gui/widget.cpp b/util/gui/widget.cpp
index 2d90853b..6fd4e4e4 100644
--- a/util/gui/widget.cpp
+++ b/util/gui/widget.cpp
@@ -1,249 +1,249 @@
#include "util/bitmap.h"
#include "widget.h"
#include <math.h>
#include "globals.h"
#include "util/token.h"
#include "coordinate.h"
#include "util/load_exception.h"
#include <sstream>
using namespace Gui;
static const double S_PI = 3.14159265358979323846;
static const double DEG_TO_RAD = 180.0/S_PI;
static const double RAD_TO_DEG = S_PI/180.0;
static void round_double (double dbl_to_round , int &rounded_num) {
rounded_num = static_cast<int>(dbl_to_round);
if ((dbl_to_round - static_cast<double>(rounded_num)) >= 0.5) {rounded_num++;}
}
//! min (borrowed from allegro)
static inline int Min(int x, int y){ return (((x) < (y)) ? (x) : (y)); }
//! max (borrowed from allegro)
static inline int Max(int x, int y){ return (((x) > (y)) ? (x) : (y)); }
//! mid (borrowed from allegro)
static inline int Mid(int x,int y,int z){ return (Max((x), Min((y), (z)))); }
Widget::Widget() : workArea(0)
{
// Nothing yet
}
Widget::Widget( const Widget & w ){
this->location = w.location;
this->workArea = w.workArea;
}
Widget::~Widget(){
if ( workArea ){
delete workArea;
}
}
// copy
Widget &Widget::operator=( const Widget &copy){
location = copy.location;
workArea = copy.workArea;
return *this;
}
void Widget::setCoordinates(const Token * token){
if ( *token == "position" ){
int x, y, width, height;
token->view() >> x >> y >> width >> height;
AbsolutePoint pos(x, y);
AbsolutePoint dimensions(x + width, y + height);
location.setPosition(pos);
location.setPosition2(dimensions);
} else if ( *token == "relative-position" ){
double x1, y1, x2, y2;
token->view() >> x1 >> y1 >> x2 >> y2;
RelativePoint pos(x1,y1);
RelativePoint dimensions(x2,y2);
location = Coordinate(pos, dimensions);
} else if ( *token == "coordinate" ){
TokenView view = token->view();
while (view.hasMore()){
const Token * coordToken;
view >> coordToken;
if (*coordToken == "absolute"){
int x, y, width, height;
coordToken->view() >> x >> y >> width >> height;
AbsolutePoint pos(x, y);
AbsolutePoint dimensions(x + width, y + height);
location = Coordinate(pos, dimensions);
} else if (*coordToken == "relative"){
double x1, y1, x2, y2;
coordToken->view() >> x1 >> y1 >> x2 >> y2;
RelativePoint pos(x1,y1);
RelativePoint dimensions(x2,y2);
location = Coordinate(pos, dimensions);
} else if (*coordToken == "radius"){
double radius;
coordToken->view() >> radius;
location.setRadius(radius);
} else if (*coordToken == "z"){
double z;
coordToken->view() >> z;
location.setZ(z);
}
}
}
if (location.getWidth() < 0 || location.getHeight() < 0){
std::ostringstream out;
out << "Invalid location dimension (cannot have a negative size). Width " << location.getWidth() << " Height " << location.getHeight() << ". From token: ";
token->toString(out, "");
throw LoadException(__FILE__, __LINE__, out.str());
}
}
void Widget::setColors(const Token * token){
if ( *token == "position-body" ) {
// This handles the body color of the widget
int r,g,b;
token->view() >> r >> g >> b >> colors.bodyAlpha;
- colors.body = Bitmap::makeColor(r,g,b);
+ colors.body = Graphics::Bitmap::makeColor(r,g,b);
} else if ( *token == "position-border" ) {
// This handles the border color of the widget
int r,g,b;
token->view() >> r >> g >> b >> colors.borderAlpha;
- colors.border = Bitmap::makeColor(r,g,b);
+ colors.border = Graphics::Bitmap::makeColor(r,g,b);
}
}
-void Widget::render(const Bitmap & bitmap, const Font & font){
+void Widget::render(const Graphics::Bitmap & bitmap, const Font & font){
render(bitmap);
}
-void Widget::arc( const Bitmap & work, int x, int y, double startAngle, int radius, int color ){
+void Widget::arc( const Graphics::Bitmap & work, int x, int y, double startAngle, int radius, int color ){
int q = 0;// for counters
double d_q = 0.0;// for percentage of loop completed
double d_q_plus_one = 0.0;
const double d_angular_length_deg = 0.030;
const double d_start_angle_rad = startAngle*DEG_TO_RAD;
const double d_angular_length_rad = d_angular_length_deg*DEG_TO_RAD;
const double d_arc_distance_between_points = 0.25*pow(2.0 , static_cast<double>(10) / 10.0);
double d_angular_length_rad_per_segment = 0.0;
double arc_length = radius*d_angular_length_rad;
if (arc_length < 0.0) {arc_length *= -1.0;}
const double d_num_segments = arc_length / d_arc_distance_between_points;
int num_segments = 0;
round_double(d_num_segments , num_segments);
if (num_segments == 0) {num_segments += 1;} // need at least one segment (two points)
const int num_points = num_segments + 1;
const double d_num_points_minus_one = static_cast<double>(num_points - 1);
int arc_point_x;//[num_points];
int arc_point_y;//[num_points];
int arc_point2_x;//[num_points];
int arc_point2_y;//[num_points];
double d_arc_point_x = 0.0;
double d_arc_point_y = 0.0;
double d_arc_point2_x = 0.0;
double d_arc_point2_y = 0.0;
double current_angle_rad = 0.0;
double current_angle2_rad = 0.0;
if (d_arc_distance_between_points <= 1.0) {
for (q = 0 ; q < num_points ; q++) {
d_q = static_cast<double>(q);
current_angle_rad = d_start_angle_rad + (d_q / d_num_points_minus_one)*d_angular_length_rad;
d_arc_point_x = x + radius*cos(current_angle_rad);
d_arc_point_y = y + radius*sin(current_angle_rad);
round_double(d_arc_point_x , arc_point_x);
round_double(d_arc_point_y , arc_point_y);
work.putPixel(arc_point_x,arc_point_y,color);
}
}
if (d_arc_distance_between_points > 1.0) {
d_angular_length_rad_per_segment = d_angular_length_rad / d_num_points_minus_one;
for (q = 0 ; q < num_segments ; q++) {
d_q = static_cast<double>(q);
d_q_plus_one = static_cast<double>(q + 1);
current_angle_rad = d_start_angle_rad + d_q*d_angular_length_rad_per_segment;
current_angle2_rad = d_start_angle_rad + d_q_plus_one*d_angular_length_rad_per_segment;
d_arc_point_x = x + radius*cos(current_angle_rad);
d_arc_point_y = y + radius*sin(current_angle_rad);
round_double(d_arc_point_x , arc_point_x);
round_double(d_arc_point_y , arc_point_y);
d_arc_point2_x = x + radius*cos(current_angle2_rad);
d_arc_point2_y = y + radius*sin(current_angle2_rad);
round_double(d_arc_point2_x , arc_point2_x);
round_double(d_arc_point2_y , arc_point2_y);
work.line(arc_point_x,arc_point_y, arc_point2_x, arc_point2_y,color);
}
}
}
-void Widget::roundRect( const Bitmap & work, int radius, int x1, int y1, int x2, int y2, int color ){
+void Widget::roundRect( const Graphics::Bitmap & work, int radius, int x1, int y1, int x2, int y2, int color ){
const int width = x2 - x1;
const int height = y2 - y1;
radius = Mid(0, radius, Min((x1+width - x1)/2, (y1+height - y1)/2));
work.line(x1+radius, y1, x1+width-radius, y1, color);
work.line(x1+radius, y1+height, x1+width-radius,y1+height, color);
work.line(x1, y1+radius,x1, y1+height-radius, color);
work.line(x1+width, y1+radius,x1+width, y1+height-radius, color);
arc(work, x1+radius, y1+radius, S_PI-1.115, radius, color);
arc(work, x1+radius + (width - radius *2), y1+radius, -S_PI/2 +0.116, radius, color);
arc(work, x1+width-radius, y1+height-radius, -0.110, radius ,color);
arc(work, x1+radius, y1+height-radius, S_PI/2-0.119, radius, color);
}
-void Widget::roundRectFill( const Bitmap & work, int radius, int x1, int y1, int x2, int y2, int color ){
+void Widget::roundRectFill( const Graphics::Bitmap & work, int radius, int x1, int y1, int x2, int y2, int color ){
const int width = x2 - x1;
const int height = y2 - y1;
radius = Mid(0, radius, Min((x1+width - x1)/2, (y1+height - y1)/2));
work.circleFill(x1+radius, y1+radius, radius, color);
work.circleFill((x1+width)-radius, y1+radius, radius, color);
work.circleFill(x1+radius, (y1+height)-radius, radius, color);
work.circleFill((x1+width)-radius, (y1+height)-radius, radius, color);
work.rectangleFill( x1+radius, y1, x2-radius, y1+radius, color);
work.rectangleFill( x1, y1+radius, x2, y2-radius, color);
work.rectangleFill( x1+radius, y2-radius, x2-radius, y2, color);
}
static void foobar(int a, int b){
a = a + b;
}
void Widget::checkWorkArea(){
/*
if (location.getWidth() < 0 || location.getHeight() < 0){
foobar(location.getWidth(), location.getHeight());
}
*/
if ( ! workArea ){
- workArea = new Bitmap(location.getWidth(), location.getHeight());
+ workArea = new Graphics::Bitmap(location.getWidth(), location.getHeight());
} else if (location.getWidth() < workArea->getWidth() || location.getHeight() < workArea->getHeight()){
delete workArea;
- workArea = new Bitmap(location.getWidth(), location.getHeight());
+ workArea = new Graphics::Bitmap(location.getWidth(), location.getHeight());
} else if (location.getWidth() > workArea->getWidth() || location.getHeight() > workArea->getHeight()){
delete workArea;
- workArea = new Bitmap(location.getWidth(), location.getHeight());
+ workArea = new Graphics::Bitmap(location.getWidth(), location.getHeight());
}
if (workArea){
- workArea->fill(Bitmap::makeColor(255,0,255));
+ workArea->fill(Graphics::Bitmap::makeColor(255,0,255));
}
}
diff --git a/util/gui/widget.h b/util/gui/widget.h
index 102ecfcf..eaef544f 100644
--- a/util/gui/widget.h
+++ b/util/gui/widget.h
@@ -1,65 +1,67 @@
#ifndef _paintown_gui_widget_h
#define _paintown_gui_widget_h
#include "rectarea.h"
#include "coordinate.h"
+namespace Graphics{
class Bitmap;
+}
class Token;
class Font;
namespace Gui{
struct ColorInfo{
ColorInfo():
body(0),
bodyAlpha(0),
border(0),
borderAlpha(0){
}
int body;
int bodyAlpha;
int border;
int borderAlpha;
};
class Widget{
public:
Widget();
Widget( const Widget & w );
virtual ~Widget();
// copy
Widget &operator=( const Widget &);
void setCoordinates(const Token * token);
void setColors(const Token * token);
//! New position data
Coordinate location;
//! Colors
ColorInfo colors;
// Logic
virtual void act(const Font &)=0;
// Render
- virtual void render(const Bitmap &) = 0;
+ virtual void render(const Graphics::Bitmap &) = 0;
/* default behavior is just to call render() */
- virtual void render(const Bitmap &, const Font &);
+ virtual void render(const Graphics::Bitmap &, const Font &);
protected:
- void arc( const Bitmap &, int x, int y, double startAngle, int radius, int color );
- void roundRect( const Bitmap &, int radius, int x1, int y1, int x2, int y2, int color );
- void roundRectFill( const Bitmap &, int radius, int x1, int y1, int x2, int y2, int color );
+ void arc( const Graphics::Bitmap &, int x, int y, double startAngle, int radius, int color );
+ void roundRect( const Graphics::Bitmap &, int radius, int x1, int y1, int x2, int y2, int color );
+ void roundRectFill( const Graphics::Bitmap &, int radius, int x1, int y1, int x2, int y2, int color );
void checkWorkArea();
- Bitmap *workArea;
+ Graphics::Bitmap *workArea;
};
}
#endif
diff --git a/util/init.cpp b/util/init.cpp
index 030acf81..8ce9ee34 100644
--- a/util/init.cpp
+++ b/util/init.cpp
@@ -1,502 +1,502 @@
#ifdef USE_ALLEGRO
#include <allegro.h>
#ifdef ALLEGRO_WINDOWS
#include <winalleg.h>
#endif
#endif
#ifdef USE_ALLEGRO5
#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#endif
#ifdef USE_SDL
#include <SDL.h>
#endif
#ifndef WINDOWS
#include <signal.h>
#include <string.h>
#endif
#ifdef LINUX
#include <execinfo.h>
#endif
/* don't be a boring tuna */
// #warning you are ugly
#include "globals.h"
#include "init.h"
#include "network/network.h"
#include "thread.h"
#include <time.h>
#include <ostream>
#include "dumb/include/dumb.h"
#ifdef USE_ALLEGRO
#include "dumb/include/aldumb.h"
#include "loadpng/loadpng.h"
#include "gif/algif.h"
#endif
#include "bitmap.h"
#include "funcs.h"
#include "file-system.h"
#include "font.h"
#include "sound.h"
#include "configuration.h"
#include "script/script.h"
#include "music.h"
#include "loading.h"
#include "input/keyboard.h"
#ifdef WII
#include <fat.h>
#endif
using namespace std;
volatile int Global::speed_counter = 0;
/* enough seconds for 136 years */
volatile unsigned int Global::second_counter = 0;
/* the original engine was running at 90 ticks per second, but we dont
* need to render that fast, so TICS_PER_SECOND is really fps and
* LOGIC_MULTIPLIER will be used to adjust the speed counter to its
* original value.
*/
const int Global::TICS_PER_SECOND = 40;
const double Global::LOGIC_MULTIPLIER = (double) 90 / (double) Global::TICS_PER_SECOND;
#ifdef USE_ALLEGRO
const int Global::WINDOWED = GFX_AUTODETECT_WINDOWED;
const int Global::FULLSCREEN = GFX_AUTODETECT_FULLSCREEN;
#else
/* FIXME: use enums here or something */
const int Global::WINDOWED = 0;
const int Global::FULLSCREEN = 1;
#endif
/* game counter, controls FPS */
static void inc_speed_counter(){
/* probably put input polling here, InputManager::poll() */
Global::speed_counter += 1;
}
#ifdef USE_ALLEGRO
END_OF_FUNCTION( inc_speed_counter )
#endif
/* if you need to count seconds for some reason.. */
static void inc_second_counter() {
Global::second_counter += 1;
}
#ifdef USE_ALLEGRO
END_OF_FUNCTION( inc_second_counter )
#endif
#if !defined(WINDOWS) && !defined(WII) && !defined(MINPSPW) && !defined(PS3) && !defined(NDS)
#ifdef LINUX
static void print_stack_trace(){
/* use addr2line on these addresses to get a filename and line number */
void *trace[128];
int frames = backtrace(trace, 128);
printf("Stack trace\n");
for (int i = 0; i < frames; i++){
printf(" %p\n", trace[i]);
}
}
#endif
static void handleSigSegV(int i, siginfo_t * sig, void * data){
const char * message = "Bug! Caught a memory violation. Shutting down..\n";
int dont_care = write(1, message, 48);
dont_care = dont_care;
#ifdef LINUX
print_stack_trace();
#endif
// Global::shutdown_message = "Bug! Caught a memory violation. Shutting down..";
- Bitmap::setGfxModeText();
+ Graphics::Bitmap::setGfxModeText();
#ifdef USE_ALLEGRO
allegro_exit();
#endif
#ifdef USE_SDL
SDL_Quit();
#endif
/* write to a log file or something because sigsegv shouldn't
* normally happen.
*/
exit(1);
}
#else
#endif
/* catch a socket being closed prematurely on unix */
#if !defined(WINDOWS) && !defined(WII) && !defined(MINPSPW) && !defined(PS3) && !defined(NDS)
static void handleSigPipe( int i, siginfo_t * sig, void * data ){
}
/*
static void handleSigUsr1( int i, siginfo_t * sig, void * data ){
pthread_exit( NULL );
}
*/
#endif
static void registerSignals(){
#if !defined(WINDOWS) && !defined(WII) && !defined(MINPSPW) && !defined(PS3) && !defined(NDS)
struct sigaction action;
memset( &action, 0, sizeof(struct sigaction) );
action.sa_sigaction = handleSigPipe;
sigaction( SIGPIPE, &action, NULL );
memset( &action, 0, sizeof(struct sigaction) );
action.sa_sigaction = handleSigSegV;
sigaction( SIGSEGV, &action, NULL );
/*
action.sa_sigaction = handleSigUsr1;
sigaction( SIGUSR1, &action, NULL );
*/
#endif
}
/* should probably call the janitor here or something */
static void close_paintown(){
Music::pause();
- Bitmap::setGfxModeText();
+ Graphics::Bitmap::setGfxModeText();
#ifdef USE_ALLEGRO
allegro_exit();
#endif
exit(0);
}
namespace Global{
extern int do_shutdown;
}
static void close_window(){
/* when do_shutdown is 1 the game will attempt to throw ShutdownException
* wherever it is. If the game is stuck or the code doesn't throw
* ShutdownException then when the user tries to close the window
* twice we just forcifully shutdown.
*/
Global::do_shutdown += 1;
if (Global::do_shutdown == 2){
close_paintown();
}
}
#ifdef USE_ALLEGRO
END_OF_FUNCTION(close_window)
#endif
#ifdef USE_ALLEGRO5
struct TimerInfo{
TimerInfo(void (*x)(), ALLEGRO_TIMER * y):
tick(x), timer(y){}
void (*tick)();
ALLEGRO_TIMER * timer;
};
static void * do_timer(void * info){
TimerInfo * timerInfo = (TimerInfo*) info;
ALLEGRO_EVENT_SOURCE * source = al_get_timer_event_source(timerInfo->timer);
ALLEGRO_EVENT_QUEUE * queue = al_create_event_queue();
al_register_event_source(queue, source);
while (true){
ALLEGRO_EVENT event;
al_wait_for_event(queue, &event);
timerInfo->tick();
}
al_destroy_event_queue(queue);
al_destroy_timer(timerInfo->timer);
delete timerInfo;
}
static Util::Thread::Id start_timer(void (*func)(), int frequency){
ALLEGRO_TIMER * timer = al_create_timer(ALLEGRO_BPS_TO_SECS(frequency));
if (timer == NULL){
Global::debug(0) << "Could not create timer" << endl;
}
al_start_timer(timer);
TimerInfo * info = new TimerInfo(func, timer);
Util::Thread::Id thread;
Util::Thread::createThread(&thread, NULL, (Util::Thread::ThreadFunction) do_timer, (void*) info);
return thread;
}
static void initSystem(ostream & out){
out << "Allegro5 initialize " << (al_init() ? "Ok" : "Failed") << endl;
uint32_t version = al_get_allegro_version();
int major = version >> 24;
int minor = (version >> 16) & 255;
int revision = (version >> 8) & 255;
int release = version & 255;
out << "Allegro5 version " << major << "." << minor << "." << revision << "." << release << endl;
al_init_image_addon();
al_install_keyboard();
al_set_app_name("Paintown");
start_timer(inc_speed_counter, Global::TICS_PER_SECOND);
// start_timer(inc_second_counter, 1);
}
#endif
#ifdef USE_ALLEGRO
static void initSystem(ostream & out){
out << "Allegro version: " << ALLEGRO_VERSION_STR << endl;
out << "Allegro init: " <<allegro_init()<<endl;
out << "Install timer: " <<install_timer()<<endl;
/* png */
loadpng_init();
algif_init();
out<<"Install keyboard: "<<install_keyboard()<<endl;
/* do we need the mouse?? */
// out<<"Install mouse: "<<install_mouse()<<endl;
out<<"Install joystick: "<<install_joystick(JOY_TYPE_AUTODETECT)<<endl;
/* 16 bit color depth */
set_color_depth(16);
LOCK_VARIABLE( speed_counter );
LOCK_VARIABLE( second_counter );
LOCK_FUNCTION( (void *)inc_speed_counter );
LOCK_FUNCTION( (void *)inc_second_counter );
/* set up the timers */
out<<"Install game timer: "<< install_int_ex(inc_speed_counter, BPS_TO_TIMER(Global::TICS_PER_SECOND))<<endl;
out<<"Install second timer: "<<install_int_ex(inc_second_counter, BPS_TO_TIMER(1))<<endl;
/* keep running in the background */
set_display_switch_mode(SWITCH_BACKGROUND);
/* close window when the X is pressed */
LOCK_FUNCTION(close_window);
set_close_button_callback(close_window);
}
#endif
#ifdef USE_SDL
// static pthread_t events;
struct TimerInfo{
TimerInfo(void (*x)(), int y):
tick(x), frequency(y){}
void (*tick)();
int frequency;
};
static void * do_timer(void * arg){
TimerInfo info = *(TimerInfo *) arg;
uint32_t delay = (uint32_t)(1000.0 / (double) info.frequency);
/* assuming SDL_GetTicks() starts at 0, this should last for about 50 days
* before overflowing. overflow should work out fine. Assuming activate occurs
* when the difference between now and ticks is at least 6, the following will happen.
* ticks now now-ticks
* 4294967294 4294967294 0
* 4294967294 4294967295 1
* 4294967294 0 2
* 4294967294 1 3
* 4294967294 2 4
* 4294967294 3 5
* 4294967294 4 6
* Activate
* 3 5 2
* 3 6 3
* 3 7 4
* 3 8 5
* 3 9 6
* Activate
*
* Can 'now' ever be much larger than 'ticks' due to overflow?
* It doesn't seem like it.
*/
uint32_t ticks = SDL_GetTicks();
/* TODO: pass in some variable that tells this loop to quit */
while (true){
uint32_t now = SDL_GetTicks();
while (now - ticks >= delay){
// Global::debug(0) << "Tick!" << endl;
info.tick();
ticks += delay;
}
SDL_Delay(1);
}
delete (TimerInfo *) arg;
return NULL;
}
static Util::Thread::Id start_timer(void (*func)(), int frequency){
TimerInfo * speed = new TimerInfo(func, frequency);
/*
speed.tick = func;
speed.frequency = frequency;
*/
Util::Thread::Id thread;
Util::Thread::createThread(&thread, NULL, (Util::Thread::ThreadFunction) do_timer, (void*) speed);
return thread;
}
#if 0
static void * handleEvents(void * arg){
bool done = false;
while (!done){
SDL_Event event;
int ok = SDL_WaitEvent(&event);
if (ok){
switch (event.type){
case SDL_QUIT : {
done = true;
close_window();
break;
}
default : {
// Global::debug(0) << "Ignoring SDL event " << event.type << endl;
break;
}
}
}
}
return NULL;
}
#endif
/*
static void doSDLQuit(){
SDL_Event quit;
quit.type = SDL_QUIT;
SDL_PushEvent(&quit);
Global::debug(0) << "Waiting for SDL event handler to finish" << endl;
pthread_join(events, NULL);
SDL_Quit();
}
*/
static void initSystem(ostream & out){
out << "SDL Init: ";
int ok = SDL_Init(SDL_INIT_VIDEO |
SDL_INIT_AUDIO |
SDL_INIT_TIMER |
SDL_INIT_JOYSTICK |
SDL_INIT_NOPARACHUTE);
if (ok == 0){
out << "Ok" << endl;
} else {
out << "Failed (" << ok << ") - " << SDL_GetError() << endl;
exit(ok);
}
/* Just do SDL thread init
#ifdef MINPSPW
pthread_init();
#endif
*/
start_timer(inc_speed_counter, Global::TICS_PER_SECOND);
start_timer(inc_second_counter, 1);
try{
SDL_Surface * icon = SDL_LoadBMP(Filesystem::find(Filesystem::RelativePath("menu/icon.bmp")).path().c_str());
if (icon != NULL){
SDL_WM_SetIcon(icon, NULL);
}
} catch (const Filesystem::NotFound & failed){
Global::debug(0) << "Could not find window icon: " << failed.getTrace() << endl;
}
SDL_WM_SetCaption("Paintown", NULL);
SDL_EnableUNICODE(1);
SDL_JoystickEventState(1);
atexit(SDL_Quit);
// atexit(doSDLQuit);
}
#endif
bool Global::init(int gfx){
ostream & out = Global::debug( 0 );
out << "-- BEGIN init --" << endl;
out << "Data path is " << Util::getDataPath2().path() << endl;
out << "Paintown version " << Global::getVersionString() << endl;
out << "Build date " << __DATE__ << " " << __TIME__ << endl;
#ifdef WII
fatInitDefault();
#endif
/* do implementation specific setup */
initSystem(out);
dumb_register_stdfiles();
Sound::initialize();
Filesystem::initialize();
- Bitmap::SCALE_X = GFX_X;
- Bitmap::SCALE_Y = GFX_Y;
+ Graphics::Bitmap::SCALE_X = GFX_X;
+ Graphics::Bitmap::SCALE_Y = GFX_Y;
Configuration::loadConfigurations();
const int sx = Configuration::getScreenWidth();
const int sy = Configuration::getScreenHeight();
if (gfx == -1){
gfx = Configuration::getFullscreen() ? Global::FULLSCREEN : Global::WINDOWED;
} else {
Configuration::setFullscreen(gfx == Global::FULLSCREEN);
}
/* set up the screen */
- int gfxCode = Bitmap::setGraphicsMode(gfx, sx, sy);
+ int gfxCode = Graphics::Bitmap::setGraphicsMode(gfx, sx, sy);
if (gfxCode == 0){
out << "Set graphics mode: Ok" << endl;
} else {
out << "Set graphics mode: Failed! (" << gfxCode << ")" << endl;
return false;
}
/* music */
atexit(&dumb_exit);
out << "Initialize random number generator" << endl;
/* initialize random number generator */
srand(time(NULL));
registerSignals();
#ifdef HAVE_NETWORKING
out << "Initialize network" << endl;
Network::init();
atexit(Network::closeAll);
#endif
/* this mutex is used to show the loading screen while the game loads */
// Util::Thread::initializeLock(&Loader::loading_screen_mutex);
out << "-- END init --" << endl;
/*
const Font & font = Font::getDefaultFont();
// font.setSize(30, 30);
Bitmap temp(font.textLength("Loading") + 1, font.getHeight("Loading") + 1);
font.printf(0, 0, Bitmap::makeColor(255, 255, 255), temp, "Loading", 0);
temp.BlitToScreen(sx / 2, sy / 2);
*/
- Bitmap white(sx, sy);
- white.fill(Bitmap::makeColor(255, 255, 255));
+ Graphics::Bitmap white(sx, sy);
+ white.fill(Graphics::Bitmap::makeColor(255, 255, 255));
white.BlitToScreen();
return true;
}
diff --git a/util/lit_bitmap.h b/util/lit_bitmap.h
index 4473d90f..9def50f1 100644
--- a/util/lit_bitmap.h
+++ b/util/lit_bitmap.h
@@ -1,26 +1,30 @@
#ifndef _paintown_lit_bitmap_h
#define _paintown_lit_bitmap_h
#include "bitmap.h"
+namespace Graphics{
+
class LitBitmap: public Bitmap {
public:
LitBitmap( const Bitmap & b );
LitBitmap();
virtual ~LitBitmap();
using Bitmap::draw;
virtual void draw(const int x, const int y, const Bitmap & where) const;
virtual void draw(const int x, const int y, Filter * filter, const Bitmap & where ) const;
using Bitmap::drawHFlip;
virtual void drawHFlip( const int x, const int y, const Bitmap & where ) const;
virtual void drawHFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
using Bitmap::drawVFlip;
virtual void drawVFlip( const int x, const int y, const Bitmap & where ) const;
virtual void drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
using Bitmap::drawHVFlip;
virtual void drawHVFlip( const int x, const int y, const Bitmap & where ) const;
virtual void drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
};
+}
+
#endif
diff --git a/util/loading.cpp b/util/loading.cpp
index 9b226956..123816d5 100644
--- a/util/loading.cpp
+++ b/util/loading.cpp
@@ -1,530 +1,530 @@
#include "bitmap.h"
#include "trans-bitmap.h"
#include <math.h>
#include <iostream>
/* FIXME: get rid of this dependancy */
#include "paintown-engine/level/utils.h"
#include "messages.h"
#include "loading.h"
#include "file-system.h"
#include "font.h"
#include "funcs.h"
#include "gradient.h"
#include "thread.h"
#include "globals.h"
#include <vector>
#include "thread.h"
#include "message-queue.h"
#include "init.h"
using namespace std;
namespace Loader{
// Util::Thread::Lock loading_screen_mutex;
volatile bool done_loading = true;
typedef struct pair{
int x, y;
} ppair;
class Info{
public:
Info(){
Global::registerInfo(&messages);
}
bool transferMessages(Messages & box){
bool did = false;
while (messages.hasAny()){
const string & str = messages.get();
box.addMessage(str);
did = true;
}
return did;
}
~Info(){
Global::unregisterInfo(&messages);
}
private:
MessageQueue messages;
};
void * loadingScreenSimple1(void * arg);
#if 0
void startLoading(Util::Thread::Id * thread, void * arg, Kind kind){
bool create = false;
Util::Thread::acquireLock(&loading_screen_mutex);
create = done_loading;
done_loading = false;
Util::Thread::releaseLock(&loading_screen_mutex);
/* prevent multiple loading threads from being made */
if (create){
switch (kind){
case Default: Util::Thread::createThread(thread, NULL, (Util::Thread::ThreadFunction) loadingScreen, arg); break;
case SimpleCircle: Util::Thread::createThread(thread, NULL, (Util::Thread::ThreadFunction) loadingScreenSimple1, arg); break;
}
}
}
void stopLoading(Util::Thread::Id thread){
bool needJoin = false;
Util::Thread::acquireLock( &loading_screen_mutex );
needJoin = ! done_loading;
done_loading = true;
Util::Thread::releaseLock( &loading_screen_mutex );
if (needJoin){
Util::Thread::joinThread(thread);
}
}
#endif
-static void setupBackground(const Bitmap & background, int load_x, int load_y, int load_width, int load_height, int infobox_x, int infobox_y, int infoWidth, int infoHeight, const Bitmap & infoBackground, const Bitmap & work){
+static void setupBackground(const Graphics::Bitmap & background, int load_x, int load_y, int load_width, int load_height, int infobox_x, int infobox_y, int infoWidth, int infoHeight, const Graphics::Bitmap & infoBackground, const Graphics::Bitmap & work){
background.Blit(load_x, load_y, load_width, load_height, 0, 0, work);
- Font::getDefaultFont().printf( 400, 480 - Font::getDefaultFont().getHeight() * 5 / 2 - Font::getDefaultFont().getHeight(), Bitmap::makeColor( 192, 192, 192 ), background, "Paintown version %s", 0, Global::getVersionString().c_str());
- Font::getDefaultFont().printf( 400, 480 - Font::getDefaultFont().getHeight() * 5 / 2, Bitmap::makeColor( 192, 192, 192 ), background, "Made by Jon Rafkind", 0 );
+ Font::getDefaultFont().printf( 400, 480 - Font::getDefaultFont().getHeight() * 5 / 2 - Font::getDefaultFont().getHeight(), Graphics::Bitmap::makeColor( 192, 192, 192 ), background, "Paintown version %s", 0, Global::getVersionString().c_str());
+ Font::getDefaultFont().printf( 400, 480 - Font::getDefaultFont().getHeight() * 5 / 2, Graphics::Bitmap::makeColor( 192, 192, 192 ), background, "Made by Jon Rafkind", 0 );
background.BlitToScreen();
background.Blit(infobox_x, infobox_y, infoWidth, infoHeight, 0, 0, infoBackground);
}
static vector<ppair> generateFontPixels(const Font & myFont, const string & message, int width, int height){
- Bitmap letters(width, height);
- letters.fill( Bitmap::MaskColor() );
- myFont.printf( 0, 0, Bitmap::makeColor(255, 255, 255), letters, message.c_str(), 0 );
+ Graphics::Bitmap letters(width, height);
+ letters.fill( Graphics::Bitmap::MaskColor() );
+ myFont.printf( 0, 0, Graphics::Bitmap::makeColor(255, 255, 255), letters, message.c_str(), 0 );
vector< ppair > pairs;
/* store every pixel we need to draw */
for ( int x = 0; x < letters.getWidth(); x++ ){
for ( int y = 0; y < letters.getHeight(); y++ ){
int pixel = letters.getPixel(x, y);
- if (pixel != Bitmap::MaskColor()){
+ if (pixel != Graphics::Bitmap::MaskColor()){
ppair p;
p.x = x;
p.y = y;
pairs.push_back( p );
}
}
}
return pairs;
}
/* shows time elapsed */
class TimeCounter{
public:
TimeCounter():
work(200, 40){
start = Global::second_counter;
last = 0;
}
void draw(int x, int y){
const Font & font = Font::getDefaultFont(24, 24);
if (Global::second_counter != last){
work.clear();
last = Global::second_counter;
- font.printf(0, 0, Bitmap::makeColor(192, 192, 192), work, "Waiting.. %d", 0, last - start);
+ font.printf(0, 0, Graphics::Bitmap::makeColor(192, 192, 192), work, "Waiting.. %d", 0, last - start);
work.BlitAreaToScreen(x, y);
}
}
- Bitmap work;
+ Graphics::Bitmap work;
unsigned int start;
unsigned int last;
};
/* FIXME: get rid of this method */
#if 0
void * loadingScreen(void * arg){
int load_x = 80;
int load_y = 220;
const int infobox_width = 300;
const int infobox_height = 150;
Info info;
const Font & myFont = Font::getFont(Global::DEFAULT_FONT, 24, 24);
const Font & infoFont = Font::getFont(Global::DEFAULT_FONT, 24, 24);
Level::LevelInfo levelInfo;
if (arg != NULL){
levelInfo = *(Level::LevelInfo*) arg;
}
if (levelInfo.getPositionX() != -1){
load_x = levelInfo.getPositionX();
}
if (levelInfo.getPositionY() != -1){
load_y = levelInfo.getPositionY();
}
// const char * the_string = (arg != NULL) ? (const char *) arg : "Loading...";
int load_width = myFont.textLength(levelInfo.loadingMessage().c_str());
int load_height = myFont.getHeight(levelInfo.loadingMessage().c_str());
const int infobox_x = load_x;
const int infobox_y = load_y + load_height * 2;
Global::debug( 2 ) << "loading screen" << endl;
Bitmap work( load_width, load_height );
vector<ppair> pairs = generateFontPixels(myFont, levelInfo.loadingMessage(), load_width, load_height);
Messages infobox(infobox_width, infobox_height);
Bitmap infoWork(infobox_width, infobox_height);
Bitmap infoBackground(infobox_width, infobox_height);
const int MAX_COLOR = 200;
/* blend from dark grey to light red */
Effects::Gradient gradient(MAX_COLOR, Bitmap::makeColor(16, 16, 16), Bitmap::makeColor(192, 8, 8));
Global::speed_counter = 0;
if (levelInfo.getBackground() != 0){
setupBackground(*levelInfo.getBackground(), load_x, load_y, load_width, load_height, infobox_x, infobox_y, infoBackground.getWidth(), infoBackground.getHeight(), infoBackground, work);
} else {
setupBackground(Bitmap(levelInfo.loadingBackground().path()), load_x, load_y, load_width, load_height, infobox_x, infobox_y, infoBackground.getWidth(), infoBackground.getHeight(), infoBackground, work);
}
Util::ThreadBoolean quit(done_loading, loading_screen_mutex);
TimeCounter counter;
bool firstDraw = true;
while ( ! quit.get() ){
/* true if a logic loop has passed */
bool draw = firstDraw;
/* will be true if any new info messages appeared */
bool drawInfo = firstDraw;
firstDraw = false;
if ( Global::speed_counter > 0 ){
double think = Global::speed_counter;
Global::speed_counter = 0;
draw = true;
while ( think > 0 ){
gradient.backward();
think -= 1;
}
/* if no new messages appeared this will be false */
drawInfo = info.transferMessages(infobox);
} else {
Util::rest( 1 );
}
if (draw){
for ( vector< ppair >::iterator it = pairs.begin(); it != pairs.end(); it++ ){
int color = gradient.current(it->x);
work.putPixel(it->x, it->y, color);
}
// counter.draw(200, 100);
/* we might not have to draw the whole info box again if no new
* messages appeared.
*/
if (drawInfo){
infoBackground.Blit(infoWork);
/* cheesy hack to change the font size. the font
* should store the size and change it on its own
*/
Font::getFont(Global::DEFAULT_FONT, 13, 13);
infobox.draw(0, 0, infoWork, infoFont);
Font::getFont(Global::DEFAULT_FONT, 24, 24);
infoWork.BlitAreaToScreen(infobox_x, infobox_y);
}
/* work already contains the correct background */
// work.Blit( load_x, load_y, *Bitmap::Screen );
work.BlitAreaToScreen(load_x, load_y);
}
}
return NULL;
}
#endif
static void loadingScreen1(LoadingContext & context, const Level::LevelInfo & levelInfo){
int load_x = 80;
int load_y = 220;
const int infobox_width = 300;
const int infobox_height = 150;
Info info;
const Font & myFont = Font::getFont(Global::DEFAULT_FONT, 24, 24);
const Font & infoFont = Font::getFont(Global::DEFAULT_FONT, 24, 24);
if (levelInfo.getPositionX() != -1){
load_x = levelInfo.getPositionX();
}
if (levelInfo.getPositionY() != -1){
load_y = levelInfo.getPositionY();
}
// const char * the_string = (arg != NULL) ? (const char *) arg : "Loading...";
int load_width = myFont.textLength(levelInfo.loadingMessage().c_str());
int load_height = myFont.getHeight(levelInfo.loadingMessage().c_str());
const int infobox_x = load_x;
const int infobox_y = load_y + load_height * 2;
Global::debug(2) << "loading screen" << endl;
- Bitmap work(load_width, load_height);
+ Graphics::Bitmap work(load_width, load_height);
vector<ppair> pairs = generateFontPixels(myFont, levelInfo.loadingMessage(), load_width, load_height);
Messages infobox(infobox_width, infobox_height);
- Bitmap infoWork(infobox_width, infobox_height);
- Bitmap infoBackground(infobox_width, infobox_height);
+ Graphics::Bitmap infoWork(infobox_width, infobox_height);
+ Graphics::Bitmap infoBackground(infobox_width, infobox_height);
const int MAX_COLOR = 200;
/* blend from dark grey to light red */
- Effects::Gradient gradient(MAX_COLOR, Bitmap::makeColor(16, 16, 16), Bitmap::makeColor(192, 8, 8));
+ Effects::Gradient gradient(MAX_COLOR, Graphics::Bitmap::makeColor(16, 16, 16), Graphics::Bitmap::makeColor(192, 8, 8));
Global::speed_counter = 0;
if (levelInfo.getBackground() != 0){
setupBackground(*levelInfo.getBackground(), load_x, load_y, load_width, load_height, infobox_x, infobox_y, infoBackground.getWidth(), infoBackground.getHeight(), infoBackground, work);
} else {
- setupBackground(Bitmap(levelInfo.loadingBackground().path()), load_x, load_y, load_width, load_height, infobox_x, infobox_y, infoBackground.getWidth(), infoBackground.getHeight(), infoBackground, work);
+ setupBackground(Graphics::Bitmap(levelInfo.loadingBackground().path()), load_x, load_y, load_width, load_height, infobox_x, infobox_y, infoBackground.getWidth(), infoBackground.getHeight(), infoBackground, work);
}
TimeCounter counter;
bool firstDraw = true;
while (! context.done()){
/* true if a logic loop has passed */
bool draw = firstDraw;
/* will be true if any new info messages appeared */
bool drawInfo = firstDraw;
firstDraw = false;
if ( Global::speed_counter > 0 ){
double think = Global::speed_counter;
Global::speed_counter = 0;
draw = true;
while ( think > 0 ){
gradient.backward();
think -= 1;
}
/* if no new messages appeared this will be false */
drawInfo = info.transferMessages(infobox);
} else {
Util::rest( 1 );
}
if (draw){
for ( vector< ppair >::iterator it = pairs.begin(); it != pairs.end(); it++ ){
int color = gradient.current(it->x);
work.putPixel(it->x, it->y, color);
}
// counter.draw(200, 100);
/* we might not have to draw the whole info box again if no new
* messages appeared.
*/
if (drawInfo){
infoBackground.Blit(infoWork);
/* cheesy hack to change the font size. the font
* should store the size and change it on its own
*/
Font::getFont(Global::DEFAULT_FONT, 13, 13);
infobox.draw(0, 0, infoWork, infoFont);
Font::getFont(Global::DEFAULT_FONT, 24, 24);
infoWork.BlitAreaToScreen(infobox_x, infobox_y);
}
/* work already contains the correct background */
// work.Blit( load_x, load_y, *Bitmap::Screen );
work.BlitAreaToScreen(load_x, load_y);
}
}
}
/* shows some circles rotating around a center point */
/* FIXME: get rid of this method */
#if 0
void * loadingScreenSimple1(void * arg){
Bitmap work(40, 40);
Bitmap original(40, 40);
original.BlitFromScreen(0, 0);
Util::ThreadBoolean quit(done_loading, loading_screen_mutex);
Global::speed_counter = 0;
int angle = 0;
int color1 = Bitmap::makeColor(0, 0, 0);
int color2 = Bitmap::makeColor(0x00, 0x99, 0xff);
int color3 = Bitmap::makeColor(0xff, 0x22, 0x33);
int color4 = Bitmap::makeColor(0x44, 0x77, 0x33);
/* the length of this array is the number of circles to show */
int colors[4] = {color1, color2, color3, color4};
Bitmap::transBlender(0, 0, 0, 64);
/* speed of rotation */
int speed = 7;
while (! quit.get()){
bool draw = false;
if (Global::speed_counter > 0){
double think = Global::speed_counter;
Global::speed_counter = 0;
draw = true;
while (think > 0){
angle += speed;
think -= 1;
}
} else {
Util::rest(1);
}
if (draw){
int max = sizeof(colors) / sizeof(int);
double middleX = work.getWidth() / 2;
double middleY = work.getHeight() / 2;
original.Blit(work);
for (int i = 0; i < max; i++){
double x = cos(Util::radians(angle + 360 / max * i)) * 15;
double y = sin(Util::radians(angle + 360 / max * i)) * 15;
/* ghost circle */
work.translucent().circleFill(middleX + x, middleY + y, 2, colors[i]);
x = cos(Util::radians(angle + speed + 360 / max * i)) * 15;
y = sin(Util::radians(angle + speed + 360 / max * i)) * 15;
/* real circle */
work.circleFill(middleX + x, middleY + y, 2, colors[i]);
}
work.BlitAreaToScreen(0, 0);
}
}
return NULL;
}
#endif
static void loadingScreenSimpleX1(LoadingContext & context, const Level::LevelInfo & levelInfo){
- Bitmap work(40, 40);
- Bitmap original(40, 40);
+ Graphics::Bitmap work(40, 40);
+ Graphics::Bitmap original(40, 40);
original.BlitFromScreen(0, 0);
Global::speed_counter = 0;
int angle = 0;
- int color1 = Bitmap::makeColor(0, 0, 0);
- int color2 = Bitmap::makeColor(0x00, 0x99, 0xff);
- int color3 = Bitmap::makeColor(0xff, 0x22, 0x33);
- int color4 = Bitmap::makeColor(0x44, 0x77, 0x33);
+ int color1 = Graphics::Bitmap::makeColor(0, 0, 0);
+ int color2 = Graphics::Bitmap::makeColor(0x00, 0x99, 0xff);
+ int color3 = Graphics::Bitmap::makeColor(0xff, 0x22, 0x33);
+ int color4 = Graphics::Bitmap::makeColor(0x44, 0x77, 0x33);
/* the length of this array is the number of circles to show */
int colors[4] = {color1, color2, color3, color4};
- Bitmap::transBlender(0, 0, 0, 64);
+ Graphics::Bitmap::transBlender(0, 0, 0, 64);
/* speed of rotation */
int speed = 7;
while (! context.done()){
bool draw = false;
if (Global::speed_counter > 0){
double think = Global::speed_counter;
Global::speed_counter = 0;
draw = true;
while (think > 0){
angle += speed;
think -= 1;
}
} else {
Util::rest(1);
}
if (draw){
int max = sizeof(colors) / sizeof(int);
double middleX = work.getWidth() / 2;
double middleY = work.getHeight() / 2;
original.Blit(work);
for (int i = 0; i < max; i++){
double x = cos(Util::radians(angle + 360 / max * i)) * 15;
double y = sin(Util::radians(angle + 360 / max * i)) * 15;
/* ghost circle */
work.translucent().circleFill(middleX + x, middleY + y, 2, colors[i]);
x = cos(Util::radians(angle + speed + 360 / max * i)) * 15;
y = sin(Util::radians(angle + speed + 360 / max * i)) * 15;
/* real circle */
work.circleFill(middleX + x, middleY + y, 2, colors[i]);
}
work.BlitAreaToScreen(0, 0);
}
}
}
LoadingContext::LoadingContext():
finished(false){
Util::Thread::initializeLock(&lock);
}
LoadingContext::~LoadingContext(){
}
void LoadingContext::doLoad(){
this->load();
Util::Thread::acquireLock(&lock);
finished = true;
Util::Thread::releaseLock(&lock);
}
bool LoadingContext::done(){
bool ok = false;
Util::Thread::acquireLock(&lock);
ok = this->finished;
Util::Thread::releaseLock(&lock);
return ok;
}
void * LoadingContext::load_it(void * arg){
LoadingContext * context = (LoadingContext*) arg;
context->doLoad();
return NULL;
}
static void showLoadMessage(){
int screenX = 80;
int screenY = 50;
- Bitmap work(110, 50);
+ Graphics::Bitmap work(110, 50);
work.BlitFromScreen(screenX, screenY);
- Bitmap top(110, 50);
- top.fill(Bitmap::makeColor(0, 0, 0));
- Font::getDefaultFont(25, 25).printf(10, 5, Bitmap::makeColor(192, 192, 192), top, "Loading", 0);
- Bitmap::transBlender(0, 0, 0, 200);
+ Graphics::Bitmap top(110, 50);
+ top.fill(Graphics::Bitmap::makeColor(0, 0, 0));
+ Font::getDefaultFont(25, 25).printf(10, 5, Graphics::Bitmap::makeColor(192, 192, 192), top, "Loading", 0);
+ Graphics::Bitmap::transBlender(0, 0, 0, 200);
top.translucent().draw(0, 0, work);
work.BlitAreaToScreen(screenX, screenY);
}
void loadScreen(LoadingContext & context, const Level::LevelInfo & info, Kind kind){
Util::Thread::Id loadingThread;
bool created = Util::Thread::createThread(&loadingThread, NULL, (Util::Thread::ThreadFunction) LoadingContext::load_it, &context);
if (!created){
Global::debug(0) << "Could not create loading thread. Loading will occur in the main thread" << endl;
showLoadMessage();
LoadingContext::load_it(&context);
// throw LoadException(__FILE__, __LINE__, "Could not create loader thread");
} else {
switch (kind){
case Default: loadingScreen1(context, info); break;
case SimpleCircle: loadingScreenSimpleX1(context, info); break;
default: loadingScreen1(context, info); break;
}
Util::Thread::joinThread(loadingThread);
}
}
}
diff --git a/util/messages.cpp b/util/messages.cpp
index 9b32ecbf..fc9d47b5 100644
--- a/util/messages.cpp
+++ b/util/messages.cpp
@@ -1,101 +1,101 @@
#include "util/bitmap.h"
#include "util/trans-bitmap.h"
#include "messages.h"
#include "util/font.h"
#include "globals.h"
using namespace std;
Messages::Messages( int width, int height, int opaque ):
width(width),
height(height),
opaque(opaque),
-borderColor(Bitmap::makeColor(200,200,200)){
+borderColor(Graphics::Bitmap::makeColor(200,200,200)){
}
static vector< string > wrapStrings( const string & left, const string & right, const Font & font, int max, vector< string > accum ){
if ( left == "" ){
return accum;
}
int length = font.textLength( left.c_str() );
if ( length >= max ){
return wrapStrings( left.substr( 0, left.length() / 2 ), left.substr( left.length() / 2 ) + right, font, max, accum );
} else if ( length >= max - font.textLength( "E" ) || right == "" ){
accum.push_back( left );
return wrapStrings( right, "", font, max, accum );
} else {
return wrapStrings( left + right.substr( 0, 1 ), right.substr( 1 ), font, max, accum );
}
}
/*
static int wrapPrint( const Bitmap & area, int y, int top, const Font & font, const string & left, const string & right ){
if ( left == "" ){
return top;
}
int length = font.textLength( left.c_str() );
int max = area.getWidth();
if ( length >= max ){
return wrapPrint( area, y - font.getHeight(), top - font.getHeight(), font, left.substr( 0, left.length() / 2 ), left.substr( left.length() / 2 ) + right );
} else if ( length >= max - font.textLength( "E" ) || right == "" ){
font.printf( 0, y, Bitmap::makeColor( 255, 255, 255 ), area, left, 0 );
return wrapPrint( area, y + font.getHeight(), top, font, right, "" );
} else {
return wrapPrint( area, y, top, font, left + right.substr( 0, 1 ), right.substr( 1 ) );
}
}
*/
void Messages::addMessage( const std::string & s ){
messages.push_back( s );
}
-void Messages::draw( int x, int y, const Bitmap & work, const Font & font ){
+void Messages::draw( int x, int y, const Graphics::Bitmap & work, const Font & font ){
// work.drawingMode( Bitmap::MODE_TRANS );
- Bitmap::transBlender(0, 0, 0, this->opaque);
- work.translucent().rectangleFill( x, y, x + width, y + height, Bitmap::makeColor( 0, 0, 0 ) );
+ Graphics::Bitmap::transBlender(0, 0, 0, this->opaque);
+ work.translucent().rectangleFill( x, y, x + width, y + height, Graphics::Bitmap::makeColor( 0, 0, 0 ) );
// work.drawingMode( Bitmap::MODE_SOLID );
// work.rectangle( x, y, x + width-1, y + height-1, Bitmap::makeColor( 255, 255, 255 ) );
work.border(0, 1, borderColor);
/* fast because its a sub-bitmap */
- Bitmap area(work, x, y, width, height);
+ Graphics::Bitmap area(work, x, y, width, height);
int current_y = height - font.getHeight() - 1;
// int max_length = area.getWidth() / font.textLength( "E" );
for ( vector< string >::reverse_iterator it = messages.rbegin(); it != messages.rend(); it++ ){
if ( current_y < 0 - font.getHeight() ){
break;
}
const string & s = *it;
vector< string > all;
all = wrapStrings(s, "", font, area.getWidth() - 3, all);
current_y -= font.getHeight() * (all.size() - 1);
int my = current_y;
for ( vector< string >::iterator str = all.begin(); str != all.end(); str++ ){
- font.printf(2, my, Bitmap::makeColor( 255, 255, 255 ), area, *str, 0);
+ font.printf(2, my, Graphics::Bitmap::makeColor( 255, 255, 255 ), area, *str, 0);
my += font.getHeight();
}
// current_y = wrapPrint( area, current_y, current_y, font, s, "" );
/*
int lines = font.textLength( s.c_str() ) / area.getWidth();
current_y -= font.getHeight() * lines;
int my = current_y;
while ( s != "" ){
string sub = s.substr( 0, max_length );
s.erase( 0, max_length );
font.printf( 0, my, Bitmap::makeColor( 255, 255, 255 ), area, sub, 0 );
my += font.getHeight();
}
*/
current_y -= font.getHeight();
}
}
Messages::~Messages(){
}
diff --git a/util/messages.h b/util/messages.h
index 8600ab8f..868d9c04 100644
--- a/util/messages.h
+++ b/util/messages.h
@@ -1,36 +1,38 @@
#ifndef _paintown_messages_h
#define _paintown_messages_h
#include <string>
#include <vector>
+namespace Graphics{
class Bitmap;
+}
class Font;
class Messages{
public:
Messages(int width, int height, int opaque = 128);
virtual inline int getHeight() const {
return height;
}
virtual inline int getWidth() const {
return width;
}
virtual void addMessage( const std::string & s );
- virtual void draw( int x, int y, const Bitmap & work, const Font & font );
+ virtual void draw( int x, int y, const Graphics::Bitmap & work, const Font & font );
virtual ~Messages();
protected:
int width;
int height;
int opaque;
int borderColor;
std::vector< std::string > messages;
};
#endif
diff --git a/util/resource.cpp b/util/resource.cpp
index fd247fda..c2613a7c 100644
--- a/util/resource.cpp
+++ b/util/resource.cpp
@@ -1,50 +1,50 @@
#include "bitmap.h"
#include "resource.h"
#include "factory/collector.h"
#include "funcs.h"
#include "sound.h"
#include "load_exception.h"
#include "file-system.h"
#include <string>
#include <vector>
using namespace std;
Resource * Resource::resource = NULL;
Sound * Resource::getSound(const Filesystem::RelativePath & path) throw (LoadException){
return resource->_getSound(Filesystem::find(path));
}
-Bitmap * Resource::getBitmap(const Filesystem::RelativePath & path) throw (LoadException){
+Graphics::Bitmap * Resource::getBitmap(const Filesystem::RelativePath & path) throw (LoadException){
return resource->_getBitmap(Filesystem::find(path));
}
/* the resource is created in the Collector */
Resource::Resource(){
resource = this;
}
Resource::~Resource(){
for (std::map<std::string, Sound*>::iterator it = sounds.begin(); it != sounds.end(); it++){
delete (*it).second;
}
- for (std::map<std::string, Bitmap*>::iterator it = bitmaps.begin(); it != bitmaps.end(); it++){
+ for (std::map<std::string, Graphics::Bitmap*>::iterator it = bitmaps.begin(); it != bitmaps.end(); it++){
delete (*it).second;
}
}
Sound * Resource::_getSound(const Filesystem::AbsolutePath & path) throw (LoadException){
if (sounds[path.path()] == NULL){
sounds[path.path()] = new Sound(path.path());
}
return sounds[path.path()];
}
-Bitmap * Resource::_getBitmap(const Filesystem::AbsolutePath & path) throw (LoadException){
+Graphics::Bitmap * Resource::_getBitmap(const Filesystem::AbsolutePath & path) throw (LoadException){
if (bitmaps[path.path()] == NULL){
- bitmaps[path.path()] = new Bitmap(path.path());
+ bitmaps[path.path()] = new Graphics::Bitmap(path.path());
}
return bitmaps[path.path()];
}
diff --git a/util/resource.h b/util/resource.h
index 4b977d93..2fc1052e 100644
--- a/util/resource.h
+++ b/util/resource.h
@@ -1,34 +1,36 @@
#ifndef _paintown_resource_manager_h
#define _paintown_resource_manager_h
#include "factory/collector.h"
#include "load_exception.h"
#include "file-system.h"
#include <map>
#include <string>
#include <vector>
class Sound;
+namespace Graphics{
class Bitmap;
+}
class Resource{
public:
/* do not prepend Util::getDataPath() to paths. Resource will do it for you.
*/
static Sound * getSound(const Filesystem::RelativePath & path) throw (LoadException);
- static Bitmap * getBitmap(const Filesystem::RelativePath & path) throw (LoadException);
+ static Graphics::Bitmap * getBitmap(const Filesystem::RelativePath & path) throw (LoadException);
private:
friend class Collector;
Resource();
virtual ~Resource();
Sound * _getSound(const Filesystem::AbsolutePath & path) throw (LoadException);
- Bitmap * _getBitmap(const Filesystem::AbsolutePath & path) throw (LoadException);
+ Graphics::Bitmap * _getBitmap(const Filesystem::AbsolutePath & path) throw (LoadException);
private:
static Resource * resource;
std::map<std::string, Sound*> sounds;
- std::map<std::string, Bitmap*> bitmaps;
+ std::map<std::string, Graphics::Bitmap*> bitmaps;
};
#endif
diff --git a/util/sdl/bitmap.cpp b/util/sdl/bitmap.cpp
index 2171b1b4..d1ca0c7e 100644
--- a/util/sdl/bitmap.cpp
+++ b/util/sdl/bitmap.cpp
@@ -1,1882 +1,1863 @@
#include "../bitmap.h"
#include "../lit_bitmap.h"
#include "../trans-bitmap.h"
#include "../funcs.h"
#include "../../util/debug.h"
#include "../system.h"
#include "sprig/sprig.h"
#include "stretch/SDL_stretch.h"
#include <SDL.h>
#include "image/SDL_image.h"
#include <math.h>
#include "exceptions/exception.h"
#include <string>
#include <sstream>
+namespace Graphics{
+
static const int WINDOWED = 0;
static const int FULLSCREEN = 1;
/* bits per pixel */
static int SCREEN_DEPTH = 16;
static SDL_Surface * screen;
static SDL_PixelFormat format565;
typedef unsigned int (*blender)(unsigned int color1, unsigned int color2, unsigned int alpha);
/* taken from allegro 4.2: src/colblend.c, _blender_trans16 */
/* this function performs a psuedo-SIMD operation on the pixel
* components in RGB 5-6-5 format. To get this to work for some
* other format probably all that needs to happen is to change
* the 0x7E0F81F constant to something else. 5-5-5:
* binary: 0011 1110 000 0111 1100 0001 1111
* hex: 0x174076037
*/
static inline unsigned int transBlender(unsigned int x, unsigned int y, unsigned int n){
unsigned long result;
if (n)
n = (n + 1) / 8;
/* hex: 0x7E0F81F
* binary: 0111 1110 0000 1111 1000 0001 1111
*/
x = ((x & 0xFFFF) | (x << 16)) & 0x7E0F81F;
y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F;
result = ((x - y) * n / 32 + y) & 0x7E0F81F;
return ((result & 0xFFFF) | (result >> 16));
}
static inline unsigned int multiplyBlender(unsigned int x, unsigned int y, unsigned int n){
Uint8 redX = 0;
Uint8 greenX = 0;
Uint8 blueX = 0;
SDL_GetRGB(x, &format565, &redX, &greenX, &blueX);
Uint8 redY = 0;
Uint8 greenY = 0;
Uint8 blueY = 0;
SDL_GetRGB(y, &format565, &redY, &greenY, &blueY);
int r = redX * redY / 256;
int g = greenX * greenY / 256;
int b = blueX * blueY / 256;
return transBlender(Bitmap::makeColor(r, g, b), y, n);
}
static inline unsigned int addBlender(unsigned int x, unsigned int y, unsigned int n){
Uint8 redX = 0;
Uint8 greenX = 0;
Uint8 blueX = 0;
SDL_GetRGB(x, &format565, &redX, &greenX, &blueX);
Uint8 redY = 0;
Uint8 greenY = 0;
Uint8 blueY = 0;
SDL_GetRGB(y, &format565, &redY, &greenY, &blueY);
int r = redY + redX * n / 256;
int g = greenY + greenX * n / 256;
int b = blueY + blueX * n / 256;
r = Util::min(r, 255);
g = Util::min(g, 255);
b = Util::min(b, 255);
return Bitmap::makeColor(r, g, b);
}
static inline int iabs(int x){
return x < 0 ? -x : x;
}
static inline unsigned int differenceBlender(unsigned int x, unsigned int y, unsigned int n){
Uint8 redX = 0;
Uint8 greenX = 0;
Uint8 blueX = 0;
SDL_GetRGB(x, &format565, &redX, &greenX, &blueX);
Uint8 redY = 0;
Uint8 greenY = 0;
Uint8 blueY = 0;
SDL_GetRGB(y, &format565, &redY, &greenY, &blueY);
// int r = iabs(redY - redX);
// int g = iabs(greenY - greenX);
// int b = iabs(blueY - blueX);
int r = redY - redX;
int g = greenY - greenX;
int b = blueY - blueX;
if (r < 0){
r = 0;
}
if (g < 0){
g = 0;
}
if (b < 0){
b = 0;
}
return transBlender(Bitmap::makeColor(r, g, b), y, n);
}
static inline unsigned int burnBlender(unsigned int x, unsigned int y, unsigned int n){
Uint8 redX = 0;
Uint8 greenX = 0;
Uint8 blueX = 0;
SDL_GetRGB(x, &format565, &redX, &greenX, &blueX);
Uint8 redY = 0;
Uint8 greenY = 0;
Uint8 blueY = 0;
SDL_GetRGB(y, &format565, &redY, &greenY, &blueY);
int r = redX - redY;
int g = greenX - greenY;
int b = blueX - blueY;
if (r < 0){
r = 0;
}
if (g < 0){
g = 0;
}
if (b < 0){
g = 0;
}
return transBlender(Bitmap::makeColor(r, g, b), y, n);
}
static inline unsigned int noBlender(unsigned int a, unsigned int b, unsigned int c){
return a;
}
struct BlendingData{
BlendingData():
red(0), green(0), blue(0), alpha(0), currentBlender(noBlender){}
int red, green, blue, alpha;
blender currentBlender;
};
static BlendingData globalBlend;
static int drawingMode = Bitmap::MODE_SOLID;
static int drawingAlpha(){
- switch (::drawingMode){
- case Bitmap::MODE_SOLID : return 255;
- case Bitmap::MODE_TRANS : return globalBlend.alpha;
- default : return 255;
+ if (drawingMode == Bitmap::MODE_SOLID){
+ return 255;
+ }
+ if (drawingMode == Bitmap::MODE_TRANS){
+ return globalBlend.alpha;
}
+ return 255;
}
static void paintown_applyTrans16(SDL_Surface * dst, const int color);
static void paintown_replace16(SDL_Surface * dst, const int original, const int replace);
static void paintown_draw_sprite_ex16(SDL_Surface * dst, SDL_Surface * src, int dx, int dy, int mode, int flip, Bitmap::Filter * filter);
static void paintown_draw_sprite_filter_ex16(SDL_Surface * dst, SDL_Surface * src, int x, int y, Bitmap::Filter * filter);
static void paintown_light16(SDL_Surface * dst, const int x, const int y, int width, int height, const int start_y, const int focus_alpha, const int edge_alpha, const int focus_color, const int edge_color);
int Bitmap::MaskColor(){
static int mask = makeColor(255, 0, 255);
return mask;
}
static SDL_Surface * optimizedSurface(SDL_Surface * in){
/* SDL_DisplayFormat will return 0 if a graphics context is not set,
* like if a test is running instead of the real game.
*/
// SDL_Surface * out = SDL_DisplayFormat(in);
SDL_Surface * out = SDL_ConvertSurface(in, &format565, SDL_SWSURFACE);
if (out == NULL){
// out = SDL_CreateRGBSurface(SDL_SWSURFACE, in->w, in->h, in->format->BitsPerPixel, 0, 0, 0, 0);
out = SDL_CreateRGBSurface(SDL_SWSURFACE, in->w, in->h, SCREEN_DEPTH, format565.Rmask, format565.Gmask, format565.Bmask, format565.Amask);
if (out == NULL){
std::ostringstream out;
out << "Could not create RGB surface of size " << in->w << ", " << in->h << ". Memory usage: " << System::memoryUsage();
throw BitmapException(__FILE__, __LINE__, out.str());
}
SDL_Rect source;
SDL_Rect destination;
source.w = in->w;
source.h = in->h;
source.x = 0;
source.y = 0;
destination.w = in->w;
destination.h = in->h;
destination.x = 0;
destination.y = 0;
SDL_BlitSurface(in, &source, out, &destination);
}
return out;
}
Bitmap * Bitmap::Screen = NULL;
static Bitmap * Scaler = NULL;
static Bitmap * Buffer = NULL;
void BitmapData::setSurface(SDL_Surface * surface){
this->surface = surface;
clip_left = 0;
clip_top = 0;
if (surface){
clip_right = surface->w;
clip_bottom = surface->h;
} else {
clip_right = 0;
clip_bottom = 0;
}
}
Bitmap::Bitmap():
own(NULL),
mustResize(false),
bit8MaskColor(0){
/* TODO */
}
Bitmap::Bitmap(const char * data, int length):
own(NULL),
mustResize(false),
bit8MaskColor(0){
SDL_RWops * ops = SDL_RWFromConstMem(data, length);
SDL_Surface * loaded = IMG_Load_RW(ops, 1);
if (loaded){
getData().setSurface(optimizedSurface(loaded));
SDL_FreeSurface(loaded);
} else {
std::ostringstream out;
out << "Could not load surface from memory " << (void*) data << " length " << length;
throw BitmapException(__FILE__, __LINE__, out.str());
}
own = new int;
*own = 1;
}
Bitmap::Bitmap(SDL_Surface * who, bool deep_copy):
own(NULL),
mustResize(false),
bit8MaskColor(0){
if (deep_copy){
SDL_Surface * surface = SDL_CreateRGBSurface(SDL_SWSURFACE, who->w, who->h, SCREEN_DEPTH, format565.Rmask, format565.Gmask, format565.Bmask, format565.Amask);
SDL_Rect source;
SDL_Rect destination;
source.w = surface->w;
source.h = surface->h;
source.x = 0;
source.y = 0;
destination.w = surface->w;
destination.h = surface->h;
destination.x = 0;
destination.y = 0;
SDL_BlitSurface(who, &source, surface, &destination);
getData().setSurface(surface);
own = new int;
*own = 1;
} else {
getData().setSurface(who);
}
}
Bitmap::Bitmap(int w, int h):
mustResize(false),
bit8MaskColor(0){
SDL_Surface * surface = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, SCREEN_DEPTH, format565.Rmask, format565.Gmask, format565.Bmask, format565.Amask);
if (surface == NULL){
std::ostringstream out;
out << "Could not create surface with dimensions " << w << ", " << h;
throw BitmapException(__FILE__, __LINE__, out.str());
}
getData().setSurface(surface);
own = new int;
*own = 1;
}
Bitmap::Bitmap( const char * load_file ):
own(NULL),
mustResize(false),
bit8MaskColor(0){
internalLoadFile(load_file);
}
Bitmap::Bitmap( const std::string & load_file ):
own(NULL),
mustResize(false){
internalLoadFile(load_file.c_str());
}
Bitmap::Bitmap( const char * load_file, int sx, int sy ):
own(NULL),
mustResize(false),
bit8MaskColor(0){
Bitmap temp(load_file);
SDL_Surface * surface = SDL_CreateRGBSurface(SDL_SWSURFACE, sx, sy, SCREEN_DEPTH, format565.Rmask, format565.Gmask, format565.Bmask, format565.Amask);
getData().setSurface(surface);
own = new int;
*own = 1;
temp.Stretch(*this);
}
/* unused */
Bitmap::Bitmap( const char * load_file, int sx, int sy, double accuracy ):
own(NULL),
mustResize(false),
bit8MaskColor(0){
throw BitmapException(__FILE__, __LINE__, "Unimplemented constructor");
}
Bitmap::Bitmap( const Bitmap & copy, bool deep_copy):
own(NULL),
mustResize(false),
bit8MaskColor(copy.bit8MaskColor){
if (deep_copy){
SDL_Surface * who = copy.getData().getSurface();
SDL_Surface * surface = SDL_CreateRGBSurface(SDL_SWSURFACE, who->w, who->h, SCREEN_DEPTH, format565.Rmask, format565.Gmask, format565.Bmask, format565.Amask);
SDL_Rect source;
SDL_Rect destination;
source.w = surface->w;
source.h = surface->h;
source.x = 0;
source.y = 0;
destination.w = surface->w;
destination.h = surface->h;
destination.x = 0;
destination.y = 0;
SDL_BlitSurface(who, &source, surface, &destination);
getData().setSurface(surface);
own = new int;
*own = 1;
} else {
getData().setSurface(copy.getData().getSurface());
own = copy.own;
if (own){
*own += 1;
}
}
}
Bitmap::Bitmap( const Bitmap & copy, int sx, int sy ):
own(NULL),
mustResize(false),
bit8MaskColor(copy.bit8MaskColor){
/* TODO */
}
Bitmap::Bitmap( const Bitmap & copy, int sx, int sy, double accuracy ):
own(NULL),
mustResize(false),
bit8MaskColor(copy.bit8MaskColor){
/* TODO */
}
static inline Uint8* computeOffset(SDL_Surface * surface, int x, int y){
int bpp = surface->format->BytesPerPixel;
return ((Uint8*)surface->pixels) + y * surface->pitch + x * bpp;
}
Bitmap::Bitmap( const Bitmap & copy, int x, int y, int width, int height ):
own(NULL),
mustResize(false),
bit8MaskColor(copy.bit8MaskColor){
path = copy.getPath();
SDL_Surface * his = copy.getData().getSurface();
if (x < 0)
x = 0;
if (y < 0)
y = 0;
if (width + x > his->w )
width = his->w - x;
if (height + y > his->h)
height = his->h - y;
SDL_Surface * sub = SDL_CreateRGBSurfaceFrom(computeOffset(his, x, y), width, height, SCREEN_DEPTH, his->pitch, format565.Rmask, format565.Gmask, format565.Bmask, format565.Amask);
getData().setSurface(sub);
own = new int;
*own = 1;
}
void Bitmap::internalLoadFile(const char * path){
this->path = path;
SDL_Surface * loaded = IMG_Load(path);
if (loaded){
getData().setSurface(optimizedSurface(loaded));
SDL_FreeSurface(loaded);
} else {
std::ostringstream out;
out << "Could not load file '" << path << "'";
throw BitmapException(__FILE__, __LINE__, out.str());
}
own = new int;
*own = 1;
}
int Bitmap::getWidth() const {
if (getData().getSurface() != NULL){
return getData().getSurface()->w;
}
return 0;
}
int Bitmap::getHeight() const {
if (getData().getSurface() != NULL){
return getData().getSurface()->h;
}
return 0;
}
int Bitmap::getRed(int c){
Uint8 red = 0;
Uint8 green = 0;
Uint8 blue = 0;
SDL_GetRGB(c, &format565, &red, &green, &blue);
return red;
}
int Bitmap::getBlue(int c){
Uint8 red = 0;
Uint8 green = 0;
Uint8 blue = 0;
SDL_GetRGB(c, &format565, &red, &green, &blue);
return blue;
}
int Bitmap::getGreen(int c){
Uint8 red = 0;
Uint8 green = 0;
Uint8 blue = 0;
SDL_GetRGB(c, &format565, &red, &green, &blue);
return green;
}
int Bitmap::makeColor(int red, int blue, int green){
return SDL_MapRGB(&format565, red, blue, green);
}
void Bitmap::initializeExtraStuff(){
/* this is as good a place as any to initialize our format */
format565.palette = 0;
format565.BitsPerPixel = 16;
format565.BytesPerPixel = 2;
format565.Rloss = 3;
format565.Gloss = 2;
format565.Bloss = 3;
format565.Aloss = 0;
format565.Rshift = 11;
format565.Gshift = 5;
format565.Bshift = 0;
format565.Ashift = 0;
format565.Rmask = 63488;
format565.Gmask = 2016;
format565.Bmask = 31;
format565.Amask = 0;
#ifndef PS3
format565.colorkey = 0;
format565.alpha = 255;
#endif
}
int Bitmap::setGraphicsMode(int mode, int width, int height){
initializeExtraStuff();
switch (mode){
case WINDOWED : {
// screen = SDL_SetVideoMode(width, height, SCREEN_DEPTH, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_RESIZABLE);
screen = SDL_SetVideoMode(width, height, SCREEN_DEPTH, SDL_SWSURFACE | SDL_RESIZABLE);
SDL_ShowCursor(0);
// screen = SDL_SetVideoMode(width, height, SCREEN_DEPTH, SDL_SWSURFACE | SDL_DOUBLEBUF);
if (!screen){
return 1;
}
break;
}
case FULLSCREEN : {
screen = SDL_SetVideoMode(width, height, SCREEN_DEPTH, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN);
SDL_ShowCursor(0);
// screen = SDL_SetVideoMode(width, height, SCREEN_DEPTH, SDL_SWSURFACE | SDL_DOUBLEBUF);
if (!screen){
return 1;
}
break;
}
}
Global::debug(1) << "SDL Screen format palette: " << screen->format->palette <<
" bits per pixel: " << (int) screen->format->BitsPerPixel <<
" bytes per pixel: " << (int) screen->format->BytesPerPixel <<
" rloss: " << (int) screen->format->Rloss <<
" gloss: " << (int) screen->format->Gloss <<
" bloss: " << (int) screen->format->Bloss <<
" aloss: " << (int) screen->format->Aloss <<
" rshift: " << (int) screen->format->Rshift <<
" gshift: " << (int) screen->format->Gshift <<
" bshift: " << (int) screen->format->Bshift <<
" ashift: " << (int) screen->format->Ashift <<
" rmask: " << (int) screen->format->Rmask <<
" gmask: " << (int) screen->format->Gmask <<
" bmask: " << (int) screen->format->Bmask <<
" amask: " << (int) screen->format->Amask <<
#ifndef PS3
" colorkey: " << (int) screen->format->colorkey <<
" alpha: " << (int) screen->format->alpha << std::endl;
#else
std::endl;
#endif
if (SCALE_X == 0){
SCALE_X = width;
}
SCALE_X = width;
if (SCALE_Y == 0){
SCALE_Y = height;
}
SCALE_Y = height;
/* does this need to be here? I think configuration will set SCALE_ */
SCALE_X = 640;
SCALE_Y = 480;
if ( Screen != NULL ){
delete Screen;
Screen = NULL;
}
if ( Scaler != NULL ){
delete Scaler;
Scaler = NULL;
}
if ( Buffer != NULL ){
delete Buffer;
Buffer = NULL;
}
if (width != 0 && height != 0){
Screen = new Bitmap(screen);
Scaler = new Bitmap(width, height);
/*
if ( width != 0 && height != 0 && (width != SCALE_X || height != SCALE_Y) ){
Scaler = new Bitmap(width, height);
Buffer = new Bitmap(SCALE_X, SCALE_Y);
}
*/
}
for (std::vector<Bitmap*>::iterator it = needResize.begin(); it != needResize.end(); it++){
Bitmap * who = *it;
who->resize(width, height);
}
return 0;
}
void Bitmap::shutdown(){
delete Screen;
Screen = NULL;
delete Scaler;
Scaler = NULL;
delete Buffer;
Buffer = NULL;
}
void Bitmap::addBlender( int r, int g, int b, int a ){
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
- globalBlend.currentBlender = ::addBlender;
+ globalBlend.currentBlender = Graphics::addBlender;
}
void Bitmap::multiplyBlender( int r, int g, int b, int a ){
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
- globalBlend.currentBlender = ::multiplyBlender;
+ globalBlend.currentBlender = Graphics::multiplyBlender;
}
void Bitmap::differenceBlender( int r, int g, int b, int a ){
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
- globalBlend.currentBlender = ::differenceBlender;
+ globalBlend.currentBlender = Graphics::differenceBlender;
}
void Bitmap::burnBlender(int r, int g, int b, int a){
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
- globalBlend.currentBlender = ::burnBlender;
+ globalBlend.currentBlender = Graphics::burnBlender;
}
Bitmap & Bitmap::operator=(const Bitmap & copy){
releaseInternalBitmap();
path = copy.getPath();
getData().setSurface(copy.getData().getSurface());
// own = false;
own = copy.own;
if (own)
*own += 1;
return *this;
}
int Bitmap::setGfxModeText(){
/* TODO */
return 0;
}
int Bitmap::setGfxModeFullscreen(int x, int y){
return setGraphicsMode(FULLSCREEN, x, y);
}
int Bitmap::setGfxModeWindowed( int x, int y ){
return setGraphicsMode(WINDOWED, x, y);
}
void Bitmap::drawingMode(int type){
- ::drawingMode = type;
+ Graphics::drawingMode = type;
}
void Bitmap::transBlender( int r, int g, int b, int a ){
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
- globalBlend.currentBlender = ::transBlender;
+ globalBlend.currentBlender = Graphics::transBlender;
}
void Bitmap::setClipRect( int x1, int y1, int x2, int y2 ) const {
SDL_Rect area;
area.x = x1;
area.y = y1;
area.w = x2 - x1;
area.h = y2 - y1;
SDL_SetClipRect(getData().getSurface(), &area);
SDL_GetClipRect(getData().getSurface(), &area);
getData().setClip(area.x, area.y, area.x + area.w, area.y + area.h);
}
void Bitmap::getClipRect(int & x1, int & y1, int & x2, int & y2) const {
x1 = getData().clip_left;
y1 = getData().clip_top;
x2 = getData().clip_right;
y2 = getData().clip_bottom;
}
void Bitmap::destroyPrivateData(){
SDL_FreeSurface(getData().getSurface());
}
static void doPutPixel(SDL_Surface * surface, int x, int y, int pixel, bool translucent){
if (SDL_MUSTLOCK(surface)){
SDL_LockSurface(surface);
}
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to set */
Uint8 *p = computeOffset(surface, x, y);
switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
if (translucent){
*(Uint16 *)p = globalBlend.currentBlender(pixel, *(Uint16*)p, globalBlend.alpha);
} else {
*(Uint16 *)p = pixel;
}
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
if (SDL_MUSTLOCK(surface)){
SDL_UnlockSurface(surface);
}
}
void Bitmap::putPixel(int x, int y, int pixel) const {
/* clip it */
if (getData().isClipped(x, y)){
return;
}
SDL_Surface * surface = getData().getSurface();
doPutPixel(surface, x, y, pixel, false);
}
void Bitmap::putPixelNormal(int x, int y, int col) const {
putPixel(x, y, col);
}
void TranslucentBitmap::putPixelNormal(int x, int y, int color) const {
if (getData().isClipped(x, y)){
return;
}
SDL_Surface * surface = getData().getSurface();
doPutPixel(surface, x, y, color, true);
}
bool Bitmap::getError(){
/* TODO */
return false;
}
void Bitmap::rectangle( int x1, int y1, int x2, int y2, int color ) const {
SPG_Rect(getData().getSurface(), x1, y1, x2, y2, color);
}
void TranslucentBitmap::rectangle( int x1, int y1, int x2, int y2, int color ) const {
int alpha = globalBlend.alpha;
SPG_RectBlend(getData().getSurface(), x1, y1, x2, y2, color, alpha);
}
void Bitmap::rectangleFill( int x1, int y1, int x2, int y2, int color ) const {
SPG_RectFilled(getData().getSurface(), x1, y1, x2, y2, color);
}
void TranslucentBitmap::rectangleFill(int x1, int y1, int x2, int y2, int color) const {
int alpha = globalBlend.alpha;
SPG_RectFilledBlend(getData().getSurface(), x1, y1, x2, y2, color, alpha);
}
void Bitmap::circleFill(int x, int y, int radius, int color) const {
- switch (::drawingMode){
- case MODE_SOLID : {
- SPG_CircleFilled(getData().getSurface(), x, y, radius, color);
- break;
- }
- case MODE_TRANS : {
- int alpha = globalBlend.alpha;
- SPG_CircleFilledBlend(getData().getSurface(), x, y, radius, color, alpha);
- break;
- }
+ if (Graphics::drawingMode == MODE_SOLID){
+ SPG_CircleFilled(getData().getSurface(), x, y, radius, color);
+ } else if (Graphics::drawingMode == MODE_TRANS){
+ int alpha = globalBlend.alpha;
+ SPG_CircleFilledBlend(getData().getSurface(), x, y, radius, color, alpha);
}
}
void TranslucentBitmap::circleFill(int x, int y, int radius, int color) const {
int alpha = globalBlend.alpha;
SPG_CircleFilledBlend(getData().getSurface(), x, y, radius, color, alpha);
}
void Bitmap::circle(int x, int y, int radius, int color) const {
// Uint8 red, green, blue;
// SDL_GetRGB(color, getData().getSurface()->format, &red, &green, &blue);
// int alpha = 255;
- switch (::drawingMode){
- case MODE_SOLID : {
- SPG_Circle(getData().getSurface(), x, y, radius, color);
- break;
- }
- case MODE_TRANS : {
- int alpha = globalBlend.alpha;
- SPG_CircleBlend(getData().getSurface(), x, y, radius, color, alpha);
- break;
- }
+ if (Graphics::drawingMode == MODE_SOLID){
+ SPG_Circle(getData().getSurface(), x, y, radius, color);
+ } else if (Graphics::drawingMode == MODE_TRANS){
+ int alpha = globalBlend.alpha;
+ SPG_CircleBlend(getData().getSurface(), x, y, radius, color, alpha);
}
// circleRGBA(getData().getSurface(), x, y, radius, red, green, blue, alpha);
}
void Bitmap::line( const int x1, const int y1, const int x2, const int y2, const int color ) const {
- switch (::drawingMode){
- case MODE_SOLID : {
- SPG_Line(getData().getSurface(), x1, y1, x2, y2, color);
- break;
- }
- case MODE_TRANS : {
- int alpha = globalBlend.alpha;
- SPG_LineBlend(getData().getSurface(), x1, y1, x2, y2, color, alpha);
- break;
- }
+ if (Graphics::drawingMode == MODE_SOLID){
+ SPG_Line(getData().getSurface(), x1, y1, x2, y2, color);
+ } else if (Graphics::drawingMode == MODE_TRANS){
+ int alpha = globalBlend.alpha;
+ SPG_LineBlend(getData().getSurface(), x1, y1, x2, y2, color, alpha);
}
}
void Bitmap::draw(const int x, const int y, const Bitmap & where) const {
if (getData().getSurface() != NULL){
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_NO_FLIP, NULL);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_NORMAL, SPRITE_NO_FLIP, NULL);
/*
SDL_SetColorKey(getData().getSurface(), SDL_SRCCOLORKEY, makeColor(255, 0, 255));
Blit(x, y, where);
*/
}
}
void Bitmap::drawHFlip(const int x, const int y, const Bitmap & where) const {
- paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_H_FLIP, NULL);
+ paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_NORMAL, SPRITE_H_FLIP, NULL);
}
void Bitmap::drawHFlip(const int x, const int y, Filter * filter, const Bitmap & where) const {
- paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_H_FLIP, filter);
+ paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_NORMAL, SPRITE_H_FLIP, filter);
}
void Bitmap::drawVFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_V_FLIP, NULL);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_NORMAL, SPRITE_V_FLIP, NULL);
}
void Bitmap::drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_V_FLIP, filter);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_NORMAL, SPRITE_V_FLIP, filter);
}
void Bitmap::drawHVFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_V_FLIP | Bitmap::SPRITE_H_FLIP, NULL);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_NORMAL, SPRITE_V_FLIP | SPRITE_H_FLIP, NULL);
}
void Bitmap::drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_V_FLIP | Bitmap::SPRITE_H_FLIP, filter);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_NORMAL, SPRITE_V_FLIP | SPRITE_H_FLIP, filter);
}
void TranslucentBitmap::draw(const int x, const int y, const Bitmap & where) const {
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_NO_FLIP, NULL);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_TRANS, SPRITE_NO_FLIP, NULL);
}
void TranslucentBitmap::draw( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_NO_FLIP, filter);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_TRANS, SPRITE_NO_FLIP, filter);
}
void TranslucentBitmap::drawHFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_H_FLIP, NULL);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_TRANS, SPRITE_H_FLIP, NULL);
}
void TranslucentBitmap::drawHFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_H_FLIP, filter);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_TRANS, SPRITE_H_FLIP, filter);
}
void TranslucentBitmap::drawVFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_V_FLIP, NULL);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_TRANS, SPRITE_V_FLIP, NULL);
}
void TranslucentBitmap::drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_TRANS, Bitmap::SPRITE_V_FLIP, filter);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_TRANS, SPRITE_V_FLIP, filter);
}
void TranslucentBitmap::drawHVFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_TRANS, SPRITE_V_FLIP | SPRITE_H_FLIP, NULL);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_TRANS, SPRITE_V_FLIP | SPRITE_H_FLIP, NULL);
}
void TranslucentBitmap::drawHVFlip( const int x, const int y, Filter * filter,const Bitmap & where ) const {
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_TRANS, SPRITE_V_FLIP | SPRITE_H_FLIP, filter);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_TRANS, SPRITE_V_FLIP | SPRITE_H_FLIP, filter);
}
void Bitmap::drawStretched( const int x, const int y, const int new_width, const int new_height, const Bitmap & who ) const {
if (getData().getSurface() != NULL){
SDL_SetColorKey(getData().getSurface(), SDL_SRCCOLORKEY, makeColor(255, 0, 255));
SDL_Surface * src = getData().getSurface();
SDL_Surface * dst = who.getData().getSurface();
int myWidth = src->w;
int myHeight = src->h;
int hisWidth = new_width;
int hisHeight = new_height;
int useX = x;
int useY = y;
int myX = 0;
int myY = 0;
float xscale = (float) hisWidth / (float) myWidth;
float yscale = (float) hisHeight / (float) myHeight;
/* sprig wont do the clipping right, if you start drawing from a negative offset
* sprig will do nothing.
*/
if (useX < 0){
useX = 0;
myX = -x / xscale;
}
if (useY < 0){
useY = 0;
myY = -y / yscale;
}
SPG_TransformX(src, dst, 0, xscale, yscale, myX, myY, useX, useY, SPG_TCOLORKEY);
}
}
static void doBlit(SDL_Surface * mine, const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where ){
SDL_Rect source;
SDL_Rect destination;
source.w = width;
source.h = height;
source.x = mx;
source.y = my;
destination.w = width;
destination.h = height;
destination.x = wx;
destination.y = wy;
SDL_BlitSurface(mine, &source, where.getData().getSurface(), &destination);
}
void Bitmap::Blit( const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where ) const {
SDL_SetColorKey(getData().getSurface(), 0, MaskColor());
doBlit(getData().getSurface(), mx, my, width, height, wx, wy, where);
/* FIXME: this is a hack, maybe put a call here for the other bitmap to update stuff
* like where->Blitted()
*/
if (&where == Screen){
SDL_Flip(Screen->getData().getSurface());
}
}
void Bitmap::BlitMasked( const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where ) const {
SDL_SetColorKey(getData().getSurface(), SDL_SRCCOLORKEY, MaskColor());
doBlit(getData().getSurface(),mx, my, width, height, wx, wy, where);
/* FIXME: this is a hack, maybe put a call here for the other bitmap to update stuff
* like where->Blitted()
*/
if (&where == Screen){
SDL_Flip(Screen->getData().getSurface());
}
}
void Bitmap::BlitToScreen(const int upper_left_x, const int upper_left_y) const {
if (getWidth() != Screen->getWidth() || getHeight() != Screen->getHeight()){
/*
this->Blit( upper_left_x, upper_left_y, *Buffer );
Buffer->Stretch(*Scaler);
Scaler->Blit(0, 0, 0, 0, *Screen);
*/
this->Stretch(*Scaler, 0, 0, getWidth(), getHeight(), upper_left_x, upper_left_y, Scaler->getWidth(), Scaler->getHeight());
Scaler->Blit(0, 0, 0, 0, *Screen);
} else {
this->Blit( upper_left_x, upper_left_y, *Screen );
}
/*
if ( Scaler == NULL ){
this->Blit( upper_left_x, upper_left_y, *Screen );
} else {
this->Blit( upper_left_x, upper_left_y, *Buffer );
Buffer->Stretch(*Scaler);
Scaler->Blit(0, 0, 0, 0, *Screen);
}
*/
// SDL_Flip(Screen->getData().getSurface());
// SDL_UpdateRect(Screen->getData().getSurface(), 0, 0, Screen->getWidth(), Screen->getHeight());
}
void Bitmap::BlitAreaToScreen(const int upper_left_x, const int upper_left_y) const {
if ( Scaler != NULL ){
double mult_x = (double) Scaler->getWidth() / (double) SCALE_X;
double mult_y = (double) Scaler->getHeight() / (double) SCALE_Y;
int x = (int)(upper_left_x * mult_x);
int y = (int)(upper_left_y * mult_y);
int w = (int)(this->getWidth() * mult_x);
int h = (int)(this->getHeight() * mult_y);
// printf("ux %d uy %d uw %d uh %d. x %d y %d w %d h %d\n", upper_left_x, upper_left_y, getWidth(), getHeight(), x, y, w, h );
this->Stretch( *Scaler, 0, 0, this->getWidth(), this->getHeight(), x, y, w, h );
Bitmap tmp(*Scaler, x, y, w, h );
tmp.Blit( x, y, *Screen );
// Scaler->Blit( x, y, w, h, *Screen );
} else {
this->Blit( upper_left_x, upper_left_y, *Screen );
}
}
/*
void Bitmap::Stretch( const Bitmap & where ) const {
if (getWidth() == where.getWidth() && getHeight() == where.getHeight()){
Blit(where);
} else {
Stretch(where, 0, 0, getWidth(), getHeight(), 0, 0, where.getWidth(), where.getHeight());
}
}
*/
void Bitmap::Stretch( const Bitmap & where, const int sourceX, const int sourceY, const int sourceWidth, const int sourceHeight, const int destX, const int destY, const int destWidth, const int destHeight ) const {
Bitmap subSource(*this, sourceX, sourceY, sourceWidth, sourceHeight);
Bitmap subDestination(where, destX, destY, destWidth, destHeight);
SDL_Surface * src = subSource.getData().getSurface();
SDL_Surface * dst = subDestination.getData().getSurface();
if (SDL_MUSTLOCK(src)){
SDL_LockSurface(src);
}
if (SDL_MUSTLOCK(dst)){
SDL_LockSurface(dst);
}
SDL_StretchSurfaceRect(src, NULL, dst, NULL);
if (SDL_MUSTLOCK(src)){
SDL_UnlockSurface(src);
}
if (SDL_MUSTLOCK(dst)){
SDL_UnlockSurface(dst);
}
/*
SDL_Surface * src = getData().getSurface();
SDL_Surface * dst = where.getData().getSurface();
*/
/*
float xscale = (float) destWidth / (float) sourceWidth;
float yscale = (float) destHeight / (float) sourceHeight;
SDL_SetColorKey(src, 0, MaskColor());
SPG_TransformX(src, dst, 0, xscale, yscale, sourceX, sourceY, destX, destY, SPG_NONE);
*/
/*
SDL_Rect source;
SDL_Rect destination;
source.x = sourceX;
source.y = sourceY;
source.w = sourceWidth;
source.h = sourceHeight;
destination.x = destX;
destination.y = destY;
destination.w = destWidth;
destination.h = destHeight;
// SDL_StretchSurfaceRect(getData().getSurface(), &source, where.getData().getSurface(), &destination);
SDL_Surface * src = getData().getSurface();
SDL_Surface * dst = where.getData().getSurface();
if (SDL_MUSTLOCK(src)){
SDL_LockSurface(src);
}
if (SDL_MUSTLOCK(dst)){
SDL_LockSurface(dst);
}
SDL_StretchSurfaceRect(src, &source, dst, &destination);
if (SDL_MUSTLOCK(src)){
SDL_UnlockSurface(src);
}
if (SDL_MUSTLOCK(dst)){
SDL_UnlockSurface(dst);
}
*/
}
void Bitmap::save( const std::string & str ) const {
/* TODO */
}
void Bitmap::triangle( int x1, int y1, int x2, int y2, int x3, int y3, int color ) const {
- switch (::drawingMode){
- case MODE_SOLID : {
- SPG_TrigonFilled(getData().getSurface(), x1, y1, x2, y2, x3, y3, color);
- break;
- }
- case MODE_TRANS : {
- int alpha = globalBlend.alpha;
- SPG_TrigonFilledBlend(getData().getSurface(), x1, y1, x2, y2, x3, y3, color, alpha);
- break;
- }
+ if (Graphics::drawingMode == MODE_SOLID){
+ SPG_TrigonFilled(getData().getSurface(), x1, y1, x2, y2, x3, y3, color);
+ } else if (Graphics::drawingMode == MODE_TRANS){
+ int alpha = globalBlend.alpha;
+ SPG_TrigonFilledBlend(getData().getSurface(), x1, y1, x2, y2, x3, y3, color, alpha);
}
}
void Bitmap::ellipse( int x, int y, int rx, int ry, int color ) const {
- switch (::drawingMode){
- case MODE_SOLID : {
- SPG_Ellipse(getData().getSurface(), x, y, rx, ry, color);
- break;
- }
- case MODE_TRANS : {
- int alpha = globalBlend.alpha;
- SPG_EllipseBlend(getData().getSurface(), x, y, rx, ry, color, alpha);
- break;
- }
+ if (Graphics::drawingMode == MODE_SOLID){
+ SPG_Ellipse(getData().getSurface(), x, y, rx, ry, color);
+ } else if (Graphics::drawingMode == MODE_TRANS){
+ int alpha = globalBlend.alpha;
+ SPG_EllipseBlend(getData().getSurface(), x, y, rx, ry, color, alpha);
}
}
void TranslucentBitmap::ellipse( int x, int y, int rx, int ry, int color ) const {
int alpha = globalBlend.alpha;
SPG_EllipseBlend(getData().getSurface(), x, y, rx, ry, color, alpha);
}
void Bitmap::ellipseFill( int x, int y, int rx, int ry, int color ) const {
SPG_EllipseFilled(getData().getSurface(), x, y, rx, ry, color);
}
void Bitmap::light(int x, int y, int width, int height, int start_y, int focus_alpha, int edge_alpha, int focus_color, int edge_color) const {
paintown_light16(getData().getSurface(), x, y, width, height, start_y, focus_alpha, edge_alpha, focus_color, edge_color);
}
void Bitmap::applyTrans(const int color) const {
paintown_applyTrans16(getData().getSurface(), color);
}
void Bitmap::floodfill( const int x, const int y, const int color ) const {
SPG_FloodFill(getData().getSurface(), x, y, color);
}
/*
void Bitmap::horizontalLine( const int x1, const int y, const int x2, const int color ) const {
SPG_LineH(getData().getSurface(), x1, y, x2, color);
}
*/
void Bitmap::hLine( const int x1, const int y, const int x2, const int color ) const {
SPG_LineH(getData().getSurface(), x1, y, x2, color);
}
void TranslucentBitmap::hLine( const int x1, const int y, const int x2, const int color ) const {
int alpha = globalBlend.alpha;
SPG_LineHBlend(getData().getSurface(), x1, y, x2, color, alpha);
}
void Bitmap::vLine( const int y1, const int x, const int y2, const int color ) const {
SPG_LineV(getData().getSurface(), x, y1, y2, color);
}
void Bitmap::polygon( const int * verts, const int nverts, const int color ) const {
SPG_Point * points = new SPG_Point[nverts];
for (int i = 0; i < nverts; i++){
points[i].x = verts[i*2];
points[i].y = verts[i*2+1];
}
SPG_PolygonFilled(getData().getSurface(), nverts, points, color);
delete[] points;
}
void Bitmap::arc(const int x, const int y, const double ang1, const double ang2, const int radius, const int color ) const {
SPG_Arc(getData().getSurface(), x, y, radius, ang1, ang2, color);
}
void Bitmap::fill(int color) const {
SDL_Rect area;
area.x = 0;
area.y = 0;
area.w = getWidth();
area.h = getHeight();
SDL_FillRect(getData().getSurface(), &area, color);
}
/*
void TranslucentBitmap::fill(int color) const {
rectangleFill(0, 0, getWidth(), getHeight(), color);
}
*/
void Bitmap::drawCharacter( const int x, const int y, const int color, const int background, const Bitmap & where ) const {
/* TODO */
}
void Bitmap::drawRotate( const int x, const int y, const int angle, const Bitmap & where ){
SDL_SetColorKey(getData().getSurface(), SDL_SRCCOLORKEY, MaskColor());
SDL_Surface * src = getData().getSurface();
SDL_Surface * dst = where.getData().getSurface();
SPG_TransformX(src, dst, angle, 1, 1, 0, 0, x, y, SPG_TCOLORKEY);
}
void Bitmap::drawPivot( const int centerX, const int centerY, const int x, const int y, const int angle, const Bitmap & where ){
SDL_SetColorKey(getData().getSurface(), SDL_SRCCOLORKEY, MaskColor());
SDL_Surface * src = getData().getSurface();
SDL_Surface * dst = where.getData().getSurface();
SPG_TransformX(src, dst, angle, 1, 1, centerX, centerY, x, y, SPG_TCOLORKEY);
}
void Bitmap::drawPivot( const int centerX, const int centerY, const int x, const int y, const int angle, const double scale, const Bitmap & where ){
SDL_SetColorKey(getData().getSurface(), SDL_SRCCOLORKEY, MaskColor());
SDL_Surface * src = getData().getSurface();
SDL_Surface * dst = where.getData().getSurface();
SPG_TransformX(src, dst, angle, scale, scale, centerX, centerY, x, y, SPG_TCOLORKEY);
}
void Bitmap::replaceColor(int original, int replaced){
paintown_replace16(getData().getSurface(), original, replaced);
}
Bitmap Bitmap::memoryPCX(unsigned char * const data, const int length, const bool mask){
SDL_RWops * ops = SDL_RWFromConstMem(data, length);
SDL_Surface * pcx = IMG_LoadPCX_RW(ops);
SDL_FreeRW(ops);
if (!pcx){
std::ostringstream out;
out << "Could not load PCX file at " << (void*) data << " length " << length;
throw BitmapException(__FILE__, __LINE__, out.str());
}
SDL_Surface * display = optimizedSurface(pcx);
Bitmap out(display, true);
#ifndef PS3
if (pcx->format->BitsPerPixel == 8){
SDL_Color color = pcx->format->palette->colors[pcx->format->colorkey];
int bad = makeColor(color.r, color.g, color.b);
out.set8BitMaskColor(bad);
// int mask = MaskColor();
// out.replaceColor(bad, mask);
}
#endif
SDL_FreeSurface(pcx);
SDL_FreeSurface(display);
// out.floodfill(0, 0, makeColor(255, 0, 255));
return out;
}
int Bitmap::getPixel( const int x, const int y ) const {
return SPG_GetPixel(getData().getSurface(), x, y);
}
void Bitmap::readLine( std::vector< int > & line, int y ){
for (int x = 0; x < getWidth(); x++){
line.push_back(getPixel(x, y));
}
}
void Bitmap::StretchBy2( const Bitmap & where ){
/* TODO */
}
void Bitmap::StretchBy4( const Bitmap & where ){
/* TODO */
}
void Bitmap::draw(const int x, const int y, Filter * filter, const Bitmap & where) const {
// paintown_draw_sprite_filter_ex16(where.getData().getSurface(), getData().getSurface(), x, y, filter);
- paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_NORMAL, Bitmap::SPRITE_NO_FLIP, filter);
+ paintown_draw_sprite_ex16(where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_NORMAL, SPRITE_NO_FLIP, filter);
}
void LitBitmap::draw( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_NO_FLIP, NULL);
+ paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_LIT, SPRITE_NO_FLIP, NULL);
}
void LitBitmap::draw( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_NO_FLIP, filter);
+ paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_LIT, SPRITE_NO_FLIP, filter);
}
void LitBitmap::drawHFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_H_FLIP, NULL);
+ paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_LIT, SPRITE_H_FLIP, NULL);
}
void LitBitmap::drawHFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_H_FLIP, filter);
+ paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_LIT, SPRITE_H_FLIP, filter);
}
void LitBitmap::drawVFlip( const int x, const int y, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_V_FLIP, NULL);
+ paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_LIT, SPRITE_V_FLIP, NULL);
}
void LitBitmap::drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
- paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, Bitmap::SPRITE_LIT, Bitmap::SPRITE_V_FLIP, filter);
+ paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_LIT, SPRITE_V_FLIP, filter);
}
void LitBitmap::drawHVFlip( const int x, const int y, const Bitmap & where ) const {
paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_LIT, SPRITE_V_FLIP | SPRITE_H_FLIP, NULL);
}
void LitBitmap::drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
paintown_draw_sprite_ex16( where.getData().getSurface(), getData().getSurface(), x, y, SPRITE_LIT, SPRITE_V_FLIP | SPRITE_H_FLIP, filter);
}
/*
#define PAINTOWN_DLS_BLENDER BLENDER_FUNC
#define PAINTOWN_DTS_BLENDER BLENDER_FUNC
#define PAINTOWN_MAKE_DLS_BLENDER(a) _blender_func16
#define PAINTOWN_MAKE_DTS_BLENDER() _blender_func16
#define PAINTOWN_PIXEL_PTR unsigned short*
#define PAINTOWN_OFFSET_PIXEL_PTR(p,x) ((PAINTOWN_PIXEL_PTR) (p) + (x))
#define PAINTOWN_INC_PIXEL_PTR(p) ((p)++)
#define PAINTOWN_INC_PIXEL_PTR_EX(p,d) ((p) += d)
#define PAINTOWN_GET_MEMORY_PIXEL(p) (*(p))
#define PAINTOWN_IS_SPRITE_MASK(b,c) ((unsigned long) (c) == (unsigned long) MASK_COLOR)
#define PAINTOWN_DLSX_BLEND(b,n) ((*(b))(_blender_col_16, (n), globalBlend.alpha))
#define PAINTOWN_GET_PIXEL(p) *((unsigned short *) (p))
#define PAINTOWN_DTS_BLEND(b,o,n) ((*(b))((n), (o), globalBlend.alpha))
#define PAINTOWN_PUT_PIXEL(p,c) (*((unsigned short *) p) = (c))
#define PAINTOWN_PUT_MEMORY_PIXEL(p,c) (*(p) = (c))
#define PAINTOWN_SET_ALPHA(a) (globalBlend.alpha = (a))
*/
static void paintown_applyTrans16(SDL_Surface * dst, const int color){
int y1 = 0;
int y2 = dst->h;
int x1 = 0;
int x2 = dst->w - 1;
y1 = dst->clip_rect.y;
y2 = dst->clip_rect.y + dst->clip_rect.h;
x1 = dst->clip_rect.x;
x2 = dst->clip_rect.x + dst->clip_rect.w;
int bpp = dst->format->BytesPerPixel;
unsigned int mask = Bitmap::makeColor(255, 0, 255);
for (int y = y1; y < y2; y++) {
Uint8 * sourceLine = computeOffset(dst, x1, y);
for (int x = x2 - 1; x >= x1; sourceLine += bpp, x--) {
unsigned long sourcePixel = *(Uint16*) sourceLine;
if (!(sourcePixel == mask)){
sourcePixel = globalBlend.currentBlender(color, sourcePixel, globalBlend.alpha);
*(Uint16 *)sourceLine = sourcePixel;
}
}
}
}
static void paintown_replace16(SDL_Surface * dst, const int original, const int replace){
int y1 = 0;
int y2 = dst->h;
int x1 = 0;
int x2 = dst->w - 1;
y1 = dst->clip_rect.y;
y2 = dst->clip_rect.y + dst->clip_rect.h;
x1 = dst->clip_rect.x;
x2 = dst->clip_rect.x + dst->clip_rect.w;
int bpp = dst->format->BytesPerPixel;
/* Attempted manual unrolling. Gcc can optimize the naive loop below better
* than this unrolling attempt.
*/
/*
for (int y = y1; y < y2; y += 4){
switch (y2 - y1){
case 1 : {
Uint8 * source1 = computeOffset(dst, x1, y);
for (int x = x2 - 1; x >= x1; source1 += bpp, x--) {
unsigned long sourcePixel = *(Uint16*) source1;
if ((int) sourcePixel == original){
*(Uint16 *)source1 = replace;
}
}
break;
}
case 2 : {
Uint8 * source1 = computeOffset(dst, x1, y);
Uint8 * source2 = computeOffset(dst, x1, y + 1);
for (int x = x2 - 1; x >= x1; source1 += bpp, source2 += bpp, x--) {
unsigned long sourcePixel = *(Uint16*) source1;
unsigned long sourcePixel2 = *(Uint16*) source2;
if ((int) sourcePixel == original){
*(Uint16 *)source1 = replace;
}
if ((int) sourcePixel2 == original){
*(Uint16 *)source2 = replace;
}
}
break;
}
case 3 : {
Uint8 * source1 = computeOffset(dst, x1, y);
Uint8 * source2 = computeOffset(dst, x1, y + 1);
Uint8 * source3 = computeOffset(dst, x1, y + 2);
for (int x = x2 - 1; x >= x1; source1 += bpp, source2 += bpp, source3 += bpp, x--) {
unsigned long sourcePixel = *(Uint16*) source1;
unsigned long sourcePixel2 = *(Uint16*) source2;
unsigned long sourcePixel3 = *(Uint16*) source3;
if ((int) sourcePixel == original){
*(Uint16 *)source1 = replace;
}
if ((int) sourcePixel2 == original){
*(Uint16 *)source2 = replace;
}
if ((int) sourcePixel3 == original){
*(Uint16 *)source3 = replace;
}
}
break;
}
default:
case 4 : {
Uint8 * source1 = computeOffset(dst, x1, y);
Uint8 * source2 = computeOffset(dst, x1, y + 1);
Uint8 * source3 = computeOffset(dst, x1, y + 2);
Uint8 * source4 = computeOffset(dst, x1, y + 3);
for (int x = x2 - 1; x >= x1; source1 += bpp, source2 += bpp, source3 += bpp, source4 += bpp, x--) {
unsigned long sourcePixel = *(Uint16*) source1;
unsigned long sourcePixel2 = *(Uint16*) source2;
unsigned long sourcePixel3 = *(Uint16*) source3;
unsigned long sourcePixel4 = *(Uint16*) source4;
if ((int) sourcePixel == original){
*(Uint16 *)source1 = replace;
}
if ((int) sourcePixel2 == original){
*(Uint16 *)source2 = replace;
}
if ((int) sourcePixel3 == original){
*(Uint16 *)source3 = replace;
}
if ((int) sourcePixel4 == original){
*(Uint16 *)source4 = replace;
}
}
break;
}
}
}
*/
if (SDL_MUSTLOCK(dst)){
SDL_LockSurface(dst);
}
for (int y = y1; y < y2; y++) {
Uint8 * sourceLine = computeOffset(dst, x1, y);
for (int x = x2 - 1; x >= x1; sourceLine += bpp, x--) {
unsigned long sourcePixel = *(Uint16*) sourceLine;
if ((int) sourcePixel == original){
*(Uint16 *)sourceLine = replace;
}
}
}
if (SDL_MUSTLOCK(dst)){
SDL_UnlockSurface(dst);
}
}
static void paintown_draw_sprite_filter_ex16(SDL_Surface * dst, SDL_Surface * src, int dx, int dy, Bitmap::Filter * filter){
int x, y, w, h;
int x_dir = 1, y_dir = 1;
int dxbeg, dybeg;
int sxbeg, sybeg;
if (SDL_MUSTLOCK(dst)){
SDL_LockSurface(dst);
}
if (true /* dst->clip*/ ) {
int tmp;
tmp = dst->clip_rect.x - dx;
sxbeg = ((tmp < 0) ? 0 : tmp);
dxbeg = sxbeg + dx;
tmp = dst->clip_rect.x + dst->clip_rect.w - dx;
w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
if (w <= 0)
return;
tmp = dst->clip_rect.y - dy;
sybeg = ((tmp < 0) ? 0 : tmp);
dybeg = sybeg + dy;
tmp = dst->clip_rect.y + dst->clip_rect.h - dy;
h = ((tmp > src->h) ? src->h : tmp) - sybeg;
if (h <= 0)
return;
}
unsigned int mask = Bitmap::makeColor(255, 0, 255);
int bpp = src->format->BytesPerPixel;
for (y = 0; y < h; y++) {
Uint8 * sourceLine = computeOffset(src, sxbeg, sybeg + y);
Uint8 * destLine = computeOffset(dst, dxbeg, dybeg + y * y_dir);
for (x = w - 1; x >= 0; sourceLine += bpp, destLine += bpp * x_dir, x--) {
unsigned long sourcePixel = *(Uint16*) sourceLine;
if (!(sourcePixel == mask)){
*(Uint16 *)destLine = filter->filter(sourcePixel);
} else {
*(Uint16 *)destLine = mask;
}
}
}
if (SDL_MUSTLOCK(dst)){
SDL_UnlockSurface(dst);
}
}
static void paintown_draw_sprite_ex16(SDL_Surface * dst, SDL_Surface * src, int dx, int dy, int mode, int flip, Bitmap::Filter * filter){
int x, y, w, h;
int x_dir = 1, y_dir = 1;
int dxbeg, dybeg;
int sxbeg, sybeg;
/*
PAINTOWN_DLS_BLENDER lit_blender;
PAINTOWN_DTS_BLENDER trans_blender;
*/
/*
ASSERT(dst);
ASSERT(src);
*/
if (SDL_MUSTLOCK(src)){
SDL_LockSurface(src);
}
if (SDL_MUSTLOCK(dst)){
SDL_LockSurface(dst);
}
- if ( flip & Bitmap::SPRITE_V_FLIP ){
+ if ( flip & SPRITE_V_FLIP ){
y_dir = -1;
}
- if ( flip & Bitmap::SPRITE_H_FLIP ){
+ if ( flip & SPRITE_H_FLIP ){
x_dir = -1;
}
if (true /* dst->clip*/ ) {
int tmp;
tmp = dst->clip_rect.x - dx;
sxbeg = ((tmp < 0) ? 0 : tmp);
dxbeg = sxbeg + dx;
tmp = dst->clip_rect.x + dst->clip_rect.w - dx;
w = ((tmp > src->w) ? src->w : tmp) - sxbeg;
if (w <= 0)
return;
- if ( flip & Bitmap::SPRITE_H_FLIP ){
+ if ( flip & SPRITE_H_FLIP ){
/* use backward drawing onto dst */
sxbeg = src->w - (sxbeg + w);
dxbeg += w - 1;
}
tmp = dst->clip_rect.y - dy;
sybeg = ((tmp < 0) ? 0 : tmp);
dybeg = sybeg + dy;
tmp = dst->clip_rect.y + dst->clip_rect.h - dy;
h = ((tmp > src->h) ? src->h : tmp) - sybeg;
if (h <= 0)
return;
- if ( flip & Bitmap::SPRITE_V_FLIP ){
+ if ( flip & SPRITE_V_FLIP ){
/* use backward drawing onto dst */
sybeg = src->h - (sybeg + h);
dybeg += h - 1;
}
} else {
w = src->w;
h = src->h;
sxbeg = 0;
sybeg = 0;
dxbeg = dx;
- if ( flip & Bitmap::SPRITE_H_FLIP ){
+ if ( flip & SPRITE_H_FLIP ){
dxbeg = dx + w - 1;
}
dybeg = dy;
- if ( flip & Bitmap::SPRITE_V_FLIP ){
+ if ( flip & SPRITE_V_FLIP ){
dybeg = dy + h - 1;
}
}
/*
lit_blender = PAINTOWN_MAKE_DLS_BLENDER(0);
trans_blender = PAINTOWN_MAKE_DTS_BLENDER();
*/
#if 0
if (dst->id & (BMP_ID_VIDEO | BMP_ID_SYSTEM)) {
bmp_select(dst);
switch (mode){
case Bitmap::SPRITE_NORMAL : {
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
PAINTOWN_PUT_PIXEL(d, c);
}
}
}
break;
}
case Bitmap::SPRITE_LIT : {
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
c = PAINTOWN_DLSX_BLEND(lit_blender, c);
PAINTOWN_PUT_PIXEL(d, c);
}
}
}
break;
}
case Bitmap::SPRITE_TRANS : {
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
c = PAINTOWN_DTS_BLEND(trans_blender, PAINTOWN_GET_PIXEL(d), c);
PAINTOWN_PUT_PIXEL(d, c);
}
}
}
break;
}
}
#xendif
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
/* flipped if y_dir is -1 */
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
/* d is incremented by x_dir, -1 if flipped */
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
switch( mode ){
case Bitmap::SPRITE_NORMAL : break;
case Bitmap::SPRITE_LIT : {
c = PAINTOWN_DLSX_BLEND(lit_blender, c);
break;
}
case Bitmap::SPRITE_TRANS : {
c = PAINTOWN_DTS_BLEND(trans_blender, PAINTOWN_GET_PIXEL(d), c);
break;
}
}
PAINTOWN_PUT_PIXEL(d, c);
}
}
}
bmp_unwrite_line(dst);
}
else {
#endif
{
switch (mode){
- case Bitmap::SPRITE_NORMAL : {
+ case SPRITE_NORMAL : {
unsigned int mask = Bitmap::makeColor(255, 0, 255);
int bpp = src->format->BytesPerPixel;
for (y = 0; y < h; y++) {
Uint8 * sourceLine = computeOffset(src, sxbeg, sybeg + y);
Uint8 * destLine = computeOffset(dst, dxbeg, dybeg + y * y_dir);
for (x = w - 1; x >= 0; sourceLine += bpp, destLine += bpp * x_dir, x--) {
unsigned long sourcePixel = *(Uint16*) sourceLine;
if (!(sourcePixel == mask)){
// unsigned int destPixel = *(Uint16*) destLine;
// sourcePixel = globalBlend.currentBlender(destPixel, sourcePixel, globalBlend.alpha);
if (filter != NULL){
*(Uint16 *)destLine = filter->filter(sourcePixel);
} else {
*(Uint16 *)destLine = sourcePixel;
}
}
}
}
break;
}
- case Bitmap::SPRITE_LIT : {
+ case SPRITE_LIT : {
int bpp = src->format->BytesPerPixel;
int litColor = Bitmap::makeColor(globalBlend.red, globalBlend.green, globalBlend.blue);
unsigned int mask = Bitmap::makeColor(255, 0, 255);
for (y = 0; y < h; y++) {
Uint8 * sourceLine = computeOffset(src, sxbeg, sybeg + y);
Uint8 * destLine = computeOffset(dst, dxbeg, dybeg + y * y_dir);
for (x = w - 1; x >= 0; sourceLine += bpp, destLine += bpp * x_dir, x--) {
unsigned long sourcePixel = *(Uint16*) sourceLine;
if (!(sourcePixel == mask)){
// unsigned int destPixel = *(Uint16*) destLine;
if (filter != NULL){
sourcePixel = globalBlend.currentBlender(litColor, filter->filter(sourcePixel), globalBlend.alpha);
*(Uint16 *)destLine = sourcePixel;
} else {
sourcePixel = globalBlend.currentBlender(litColor, sourcePixel, globalBlend.alpha);
*(Uint16 *)destLine = sourcePixel;
}
}
}
}
break;
}
- case Bitmap::SPRITE_TRANS : {
+ case SPRITE_TRANS : {
int bpp = src->format->BytesPerPixel;
unsigned int mask = Bitmap::makeColor(255, 0, 255);
for (y = 0; y < h; y++) {
Uint8 * sourceLine = computeOffset(src, sxbeg, sybeg + y);
Uint8 * destLine = computeOffset(dst, dxbeg, dybeg + y * y_dir);
for (x = w - 1; x >= 0; sourceLine += bpp, destLine += bpp * x_dir, x--) {
unsigned long sourcePixel = *(Uint16*) sourceLine;
if (!(sourcePixel == mask)){
unsigned int destPixel = *(Uint16*) destLine;
if (filter != NULL){
sourcePixel = globalBlend.currentBlender(filter->filter(sourcePixel), destPixel, globalBlend.alpha);
*(Uint16 *)destLine = sourcePixel;
} else {
sourcePixel = globalBlend.currentBlender(sourcePixel, destPixel, globalBlend.alpha);
*(Uint16 *)destLine = sourcePixel;
}
}
}
}
break;
}
default : { break; }
}
#if 0
for (y = 0; y < h; y++) {
PAINTOWN_PIXEL_PTR s = PAINTOWN_OFFSET_PIXEL_PTR(src->line[sybeg + y], sxbeg);
PAINTOWN_PIXEL_PTR d = PAINTOWN_OFFSET_PIXEL_PTR(bmp_write_line(dst, dybeg + y * y_dir), dxbeg);
for (x = w - 1; x >= 0; PAINTOWN_INC_PIXEL_PTR(s), PAINTOWN_INC_PIXEL_PTR_EX(d,x_dir), x--) {
unsigned long c = PAINTOWN_GET_MEMORY_PIXEL(s);
if (!PAINTOWN_IS_SPRITE_MASK(src, c)) {
switch( mode ){
case Bitmap::SPRITE_NORMAL : break;
case Bitmap::SPRITE_LIT : {
c = PAINTOWN_DLSX_BLEND(lit_blender, c);
break;
}
case Bitmap::SPRITE_TRANS : {
c = PAINTOWN_DTS_BLEND(trans_blender, PAINTOWN_GET_PIXEL(d), c);
break;
}
}
PAINTOWN_PUT_MEMORY_PIXEL(d, c);
}
}
}
#endif
}
if (SDL_MUSTLOCK(src)){
SDL_UnlockSurface(src);
}
if (SDL_MUSTLOCK(dst)){
SDL_UnlockSurface(dst);
}
}
/* ultra special-case for drawing a light (like from a lamp).
* center of light is x,y and shines in a perfect isosolese triangle.
*/
static void paintown_light16(SDL_Surface * dst, const int x, const int y, int width, int height, const int start_y, const int focus_alpha, const int edge_alpha, const int focus_color, const int edge_color){
if (width > dst->w){
width = dst->w;
}
if (height > dst->h){
height = dst->h;
}
int dxbeg = x - width;
int x_dir = 1;
unsigned char * alphas = new unsigned char[width];
int * colors = new int[width];
for (int i = 0; i < width; i++){
alphas[i] = (unsigned char)((double)(edge_alpha - focus_alpha) * (double)i / (double)width + focus_alpha);
}
Util::blend_palette(colors, width, focus_color, edge_color);
if (SDL_MUSTLOCK(dst)){
SDL_LockSurface(dst);
}
int min_y, max_y, min_x, max_x;
min_y = dst->clip_rect.y;
max_y = dst->clip_rect.y + dst->clip_rect.h - 1;
min_x = dst->clip_rect.x;
max_x = dst->clip_rect.x + dst->clip_rect.w - 1;
int dybeg = y;
/* tan(theta) = y / x */
double xtan = (double) height / (double) width;
int bpp = dst->format->BytesPerPixel;
for (int sy = start_y; sy < height; sy++) {
if (dybeg + sy < min_y || dybeg + sy > max_y){
continue;
}
/* x = y / tan(theta) */
int top_width = (int)((double) sy / xtan);
if (top_width == 0){
continue;
}
dxbeg = x - top_width;
Uint8* line = computeOffset(dst, dxbeg, dybeg + y);
for (int sx = -top_width; sx <= top_width; line += x_dir * bpp, sx++) {
if (sx + x < min_x || sx + x > max_x){
continue;
}
unsigned long c = *(Uint16*) line;
/* TODO:
* converting to a double and calling fabs is overkill, just
* write an integer abs() function.
*/
int sx_abs = (int) fabs((double) sx);
int alphaUse = alphas[sx_abs];
int color = colors[sx_abs];
c = globalBlend.currentBlender(color, c, alphaUse);
*(Uint16*) line = c;
}
}
delete[] alphas;
delete[] colors;
if (SDL_MUSTLOCK(dst)){
SDL_UnlockSurface(dst);
}
}
+
+}
diff --git a/util/sdl/bitmap.h b/util/sdl/bitmap.h
index 93a11bab..1e5f8402 100644
--- a/util/sdl/bitmap.h
+++ b/util/sdl/bitmap.h
@@ -1,34 +1,36 @@
struct SDL_Surface;
+namespace Graphics{
struct BitmapData{
BitmapData():
surface(0),
clip_left(0),
clip_right(0),
clip_top(0),
clip_bottom(0){}
inline SDL_Surface * getSurface() const {
return surface;
}
inline void setClip(int left, int top, int right, int bottom) const {
clip_left = left;
clip_right = right;
clip_top = top;
clip_bottom = bottom;
}
bool isClipped(int x, int y) const {
return (x < clip_left ||
y < clip_top ||
x >= clip_right ||
y >= clip_bottom);
}
void setSurface(SDL_Surface * surface);
SDL_Surface * surface;
mutable int clip_left, clip_right;
mutable int clip_top, clip_bottom;
};
+}
diff --git a/util/trans-bitmap.h b/util/trans-bitmap.h
index 15bb33bf..dc6a6360 100644
--- a/util/trans-bitmap.h
+++ b/util/trans-bitmap.h
@@ -1,38 +1,42 @@
#ifndef _paintown_trans_bitmap_h
#define _paintown_trans_bitmap_h
#include "bitmap.h"
+namespace Graphics{
+
class TranslucentBitmap: public Bitmap {
public:
TranslucentBitmap(const Bitmap & b);
TranslucentBitmap();
virtual ~TranslucentBitmap();
virtual void putPixelNormal(int x, int y, int col) const;
virtual void rectangleFill(int x1, int y1, int x2, int y2, int color) const;
virtual void rectangle(int x1, int y1, int x2, int y2, int color) const;
virtual void fill(int color) const;
virtual void hLine( const int x1, const int y, const int x2, const int color ) const;
virtual void circleFill( int x, int y, int radius, int color ) const;
virtual void ellipse( int x, int y, int rx, int ry, int color ) const;
using Bitmap::draw;
virtual void draw(const int x, const int y, const Bitmap & where) const;
virtual void draw(const int x, const int y, Filter * filter, const Bitmap & where) const;
// virtual void draw(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, const Bitmap & where) const;
// virtual void draw(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, Filter * filter, const Bitmap & where) const;
using Bitmap::drawHFlip;
virtual void drawHFlip(const int x, const int y, const Bitmap & where) const;
virtual void drawHFlip(const int x, const int y, Filter * filter, const Bitmap & where) const;
// virtual void drawHFlip(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, const Bitmap & where) const;
// virtual void drawHFlip(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, Filter * filter, const Bitmap & where) const;
virtual void drawVFlip( const int x, const int y, const Bitmap & where ) const;
virtual void drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
virtual void drawHVFlip( const int x, const int y, const Bitmap & where ) const;
virtual void drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
};
+}
+
#endif

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jun 11, 11:27 AM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68750
Default Alt Text
(425 KB)

Event Timeline