Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
172 KB
Referenced Files
None
Subscribers
None
diff --git a/util/allegro/bitmap.cpp b/util/allegro/bitmap.cpp
index 45d4aa7c..05be6226 100644
--- a/util/allegro/bitmap.cpp
+++ b/util/allegro/bitmap.cpp
@@ -1,1797 +1,1791 @@
/* 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
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 );
}
-
-int Bitmap::darken( int color, double factor ){
- int r = (int)((double)::getr16( color ) / factor);
- int g = (int)((double)::getg16( color ) / factor);
- int b = (int)((double)::getb16( color ) / factor);
- return makeColor( 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);
// ::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);
}
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);
// ::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);
// ::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);
}
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);
}
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);
}
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);
}
/*
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
/* 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_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 ){
y_dir = -1;
}
if ( flip & Bitmap::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 ){
/* 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 ){
/* 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 ){
dxbeg = dx + w - 1;
}
dybeg = dy;
if ( flip & Bitmap::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: {
if (filter){
c = filter->filter(c);
}
break;
}
case Bitmap::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 : {
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 : {
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 : {
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 : {
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 ){
y_dir = -1;
}
if ( flip & Bitmap::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 ){
/* 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 ){
/* 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 ){
dxbeg = dx + w - 1;
}
dybeg = dy;
if ( flip & Bitmap::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 : {
if (filter){
c = PAINTOWN_DLSX_BLEND(lit_blender, filter->filter(c));
} else {
c = PAINTOWN_DLSX_BLEND(lit_blender, c);
}
break;
}
case Bitmap::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 : {
if (filter){
c = PAINTOWN_DLSX_BLEND(lit_blender, filter->filter(c));
} else {
c = PAINTOWN_DLSX_BLEND(lit_blender, c);
}
break;
}
case Bitmap::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 8ddd6188..4f501b21 100644
--- a/util/allegro5/bitmap.cpp
+++ b/util/allegro5/bitmap.cpp
@@ -1,186 +1,599 @@
#include <sstream>
#include <allegro5/allegro_memfile.h>
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;
+
+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(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);
+ 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){
- al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_RGB_565);
+ initializeExtraStuff();
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 {
+ /* TODO */
+}
+
+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 {
+ /* TODO */
+}
+
+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 {
+ /* TODO */
+}
+
+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/allegro5/sound.cpp b/util/allegro5/sound.cpp
index 70cf475a..db9a65fa 100644
--- a/util/allegro5/sound.cpp
+++ b/util/allegro5/sound.cpp
@@ -1 +1,74 @@
#include "../sound.h"
+
+Sound::Sound():
+own(NULL){
+}
+
+/* create from wav file (riff header + pcm) */
+Sound::Sound(const char * data, int length):
+own(NULL){
+ /* TODO */
+ /*
+ SDL_RWops * ops = SDL_RWFromConstMem(data, length);
+ this->data.chunk = Mix_LoadWAV_RW(ops, 1);
+ */
+ own = new int;
+ *own = 1;
+}
+
+/* load from path */
+Sound::Sound(const std::string & path) throw (LoadException):
+own(NULL){
+ /* TODO */
+ /*
+ data.chunk = Mix_LoadWAV(path.c_str());
+ if (!data.chunk){
+ printf("Can't load sound %s\n", path.c_str());
+ // throw LoadException("Could not load sound " + path);
+ } else {
+ own = new int;
+ *own = 1;
+ }
+ */
+}
+
+
+void Sound::initialize(){
+ /* TODO */
+}
+
+void Sound::uninitialize(){
+ /* TODO */
+}
+
+void Sound::play(){
+ /* TODO */
+}
+
+void Sound::play(double volume, int pan){
+ /* TODO */
+}
+
+void Sound::playLoop(){
+ /* TODO */
+}
+
+void Sound::stop(){
+ /* TODO */
+}
+
+void Sound::destroy(){
+ if (own){
+ *own -= 1;
+ if ( *own == 0 ){
+ delete own;
+ /* TODO */
+ /*
+ if (data.chunk != NULL){
+ Mix_FreeChunk(data.chunk);
+ }
+ */
+ own = NULL;
+ }
+ }
+}
diff --git a/util/bitmap.cpp b/util/bitmap.cpp
index 1c9b2908..d3648965 100644
--- a/util/bitmap.cpp
+++ b/util/bitmap.cpp
@@ -1,357 +1,373 @@
/*
#ifdef USE_ALLEGRO
#include <allegro.h>
#endif
*/
#include "funcs.h"
#include "bitmap.h"
#include "trans-bitmap.h"
#include "lit_bitmap.h"
#include <string>
#include <math.h>
/* 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 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
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);
}
diff --git a/util/input/allegro5/keyboard.cpp b/util/input/allegro5/keyboard.cpp
index 723389e4..6a81982a 100644
--- a/util/input/allegro5/keyboard.cpp
+++ b/util/input/allegro5/keyboard.cpp
@@ -1,134 +1,159 @@
#include "../keyboard.h"
#include <allegro5/keycodes.h>
const int Keyboard::Key_A = ALLEGRO_KEY_A;
const int Keyboard::Key_B = ALLEGRO_KEY_B;
const int Keyboard::Key_C = ALLEGRO_KEY_C;
const int Keyboard::Key_D = ALLEGRO_KEY_D;
const int Keyboard::Key_E = ALLEGRO_KEY_E;
const int Keyboard::Key_F = ALLEGRO_KEY_F;
const int Keyboard::Key_G = ALLEGRO_KEY_G;
const int Keyboard::Key_H = ALLEGRO_KEY_H;
const int Keyboard::Key_I = ALLEGRO_KEY_I;
const int Keyboard::Key_J = ALLEGRO_KEY_J;
const int Keyboard::Key_K = ALLEGRO_KEY_K;
const int Keyboard::Key_L = ALLEGRO_KEY_L;
const int Keyboard::Key_M = ALLEGRO_KEY_M;
const int Keyboard::Key_N = ALLEGRO_KEY_N;
const int Keyboard::Key_O = ALLEGRO_KEY_O;
const int Keyboard::Key_P = ALLEGRO_KEY_P;
const int Keyboard::Key_Q = ALLEGRO_KEY_Q;
const int Keyboard::Key_R = ALLEGRO_KEY_R;
const int Keyboard::Key_S = ALLEGRO_KEY_S;
const int Keyboard::Key_T = ALLEGRO_KEY_T;
const int Keyboard::Key_U = ALLEGRO_KEY_U;
const int Keyboard::Key_V = ALLEGRO_KEY_V;
const int Keyboard::Key_W = ALLEGRO_KEY_W;
const int Keyboard::Key_X = ALLEGRO_KEY_X;
const int Keyboard::Key_Y = ALLEGRO_KEY_Y;
const int Keyboard::Key_Z = ALLEGRO_KEY_Z;
const int Keyboard::Key_0 = ALLEGRO_KEY_0;
const int Keyboard::Key_1 = ALLEGRO_KEY_1;
const int Keyboard::Key_2 = ALLEGRO_KEY_2;
const int Keyboard::Key_3 = ALLEGRO_KEY_3;
const int Keyboard::Key_4 = ALLEGRO_KEY_4;
const int Keyboard::Key_5 = ALLEGRO_KEY_5;
const int Keyboard::Key_6 = ALLEGRO_KEY_6;
const int Keyboard::Key_7 = ALLEGRO_KEY_7;
const int Keyboard::Key_8 = ALLEGRO_KEY_8;
const int Keyboard::Key_9 = ALLEGRO_KEY_9;
const int Keyboard::Key_0_PAD = ALLEGRO_KEY_PAD_0;
const int Keyboard::Key_1_PAD = ALLEGRO_KEY_PAD_1;
const int Keyboard::Key_2_PAD = ALLEGRO_KEY_PAD_2;
const int Keyboard::Key_3_PAD = ALLEGRO_KEY_PAD_3;
const int Keyboard::Key_4_PAD = ALLEGRO_KEY_PAD_4;
const int Keyboard::Key_5_PAD = ALLEGRO_KEY_PAD_5;
const int Keyboard::Key_6_PAD = ALLEGRO_KEY_PAD_6;
const int Keyboard::Key_7_PAD = ALLEGRO_KEY_PAD_7;
const int Keyboard::Key_8_PAD = ALLEGRO_KEY_PAD_8;
const int Keyboard::Key_9_PAD = ALLEGRO_KEY_PAD_9;
const int Keyboard::Key_F1 = ALLEGRO_KEY_F1;
const int Keyboard::Key_F2 = ALLEGRO_KEY_F2;
const int Keyboard::Key_F3 = ALLEGRO_KEY_F3;
const int Keyboard::Key_F4 = ALLEGRO_KEY_F4;
const int Keyboard::Key_F5 = ALLEGRO_KEY_F5;
const int Keyboard::Key_F6 = ALLEGRO_KEY_F6;
const int Keyboard::Key_F7 = ALLEGRO_KEY_F7;
const int Keyboard::Key_F8 = ALLEGRO_KEY_F8;
const int Keyboard::Key_F9 = ALLEGRO_KEY_F9;
const int Keyboard::Key_F10 = ALLEGRO_KEY_F10;
const int Keyboard::Key_F11 = ALLEGRO_KEY_F11;
const int Keyboard::Key_F12 = ALLEGRO_KEY_F12;
const int Keyboard::Key_ESC = ALLEGRO_KEY_ESCAPE;
const int Keyboard::Key_TILDE = ALLEGRO_KEY_TILDE;
const int Keyboard::Key_MINUS = ALLEGRO_KEY_MINUS;
const int Keyboard::Key_EQUALS = ALLEGRO_KEY_EQUALS;
const int Keyboard::Key_BACKSPACE = ALLEGRO_KEY_BACKSPACE;
const int Keyboard::Key_TAB = ALLEGRO_KEY_TAB;
const int Keyboard::Key_OPENBRACE = ALLEGRO_KEY_OPENBRACE;
const int Keyboard::Key_CLOSEBRACE = ALLEGRO_KEY_CLOSEBRACE;
const int Keyboard::Key_ENTER = ALLEGRO_KEY_ENTER;
const int Keyboard::Key_COLON = ALLEGRO_KEY_SEMICOLON2;
const int Keyboard::Key_QUOTE = ALLEGRO_KEY_QUOTE;
const int Keyboard::Key_BACKSLASH = ALLEGRO_KEY_BACKSLASH;
const int Keyboard::Key_BACKSLASH2 = ALLEGRO_KEY_BACKSLASH2;
const int Keyboard::Key_COMMA = ALLEGRO_KEY_COMMA;
const int Keyboard::Key_STOP = ALLEGRO_KEY_FULLSTOP;
const int Keyboard::Key_SLASH = ALLEGRO_KEY_SLASH;
const int Keyboard::Key_SPACE = ALLEGRO_KEY_SPACE;
const int Keyboard::Key_INSERT = ALLEGRO_KEY_INSERT;
const int Keyboard::Key_DEL = ALLEGRO_KEY_DELETE;
const int Keyboard::Key_HOME = ALLEGRO_KEY_HOME;
const int Keyboard::Key_END = ALLEGRO_KEY_END;
const int Keyboard::Key_PGUP = ALLEGRO_KEY_PGUP;
const int Keyboard::Key_PGDN = ALLEGRO_KEY_PGDN;
const int Keyboard::Key_LEFT = ALLEGRO_KEY_LEFT;
const int Keyboard::Key_RIGHT = ALLEGRO_KEY_RIGHT;
const int Keyboard::Key_UP = ALLEGRO_KEY_UP;
const int Keyboard::Key_DOWN = ALLEGRO_KEY_DOWN;
const int Keyboard::Key_SLASH_PAD = ALLEGRO_KEY_PAD_SLASH;
const int Keyboard::Key_ASTERISK = ALLEGRO_KEY_PAD_ASTERISK;
const int Keyboard::Key_MINUS_PAD = ALLEGRO_KEY_PAD_MINUS;
const int Keyboard::Key_PLUS_PAD = ALLEGRO_KEY_PAD_PLUS;
const int Keyboard::Key_DEL_PAD = ALLEGRO_KEY_PAD_DELETE;
const int Keyboard::Key_ENTER_PAD = ALLEGRO_KEY_PAD_ENTER;
const int Keyboard::Key_PRTSCR = ALLEGRO_KEY_PRINTSCREEN;
const int Keyboard::Key_PAUSE = ALLEGRO_KEY_PAUSE;
const int Keyboard::Key_ABNT_C1 = ALLEGRO_KEY_ABNT_C1;
const int Keyboard::Key_YEN = ALLEGRO_KEY_YEN;
const int Keyboard::Key_KANA = ALLEGRO_KEY_KANA;
const int Keyboard::Key_CONVERT = ALLEGRO_KEY_CONVERT;
const int Keyboard::Key_NOCONVERT = ALLEGRO_KEY_NOCONVERT;
const int Keyboard::Key_AT = ALLEGRO_KEY_AT;
const int Keyboard::Key_CIRCUMFLEX = ALLEGRO_KEY_CIRCUMFLEX;
const int Keyboard::Key_COLON2 = ALLEGRO_KEY_COLON2;
const int Keyboard::Key_KANJI = ALLEGRO_KEY_KANJI;
const int Keyboard::Key_EQUALS_PAD = ALLEGRO_KEY_PAD_EQUALS;
const int Keyboard::Key_BACKQUOTE = ALLEGRO_KEY_BACKQUOTE;
const int Keyboard::Key_SEMICOLON = ALLEGRO_KEY_SEMICOLON;
const int Keyboard::Key_COMMAND = ALLEGRO_KEY_COMMAND;
/*
const int Keyboard::Key_UNKNOWN1 = ALLEGRO_KEY_UNKNOWN1;
const int Keyboard::Key_UNKNOWN2 = ALLEGRO_KEY_UNKNOWN2;
const int Keyboard::Key_UNKNOWN3 = ALLEGRO_KEY_UNKNOWN3;
const int Keyboard::Key_UNKNOWN4 = ALLEGRO_KEY_UNKNOWN4;
const int Keyboard::Key_UNKNOWN5 = ALLEGRO_KEY_UNKNOWN5;
const int Keyboard::Key_UNKNOWN6 = ALLEGRO_KEY_UNKNOWN6;
const int Keyboard::Key_UNKNOWN7 = ALLEGRO_KEY_UNKNOWN7;
const int Keyboard::Key_UNKNOWN8 = ALLEGRO_KEY_UNKNOWN8;
*/
const int Keyboard::Key_MODIFIERS = ALLEGRO_KEY_MODIFIERS;
const int Keyboard::Key_LSHIFT = ALLEGRO_KEY_LSHIFT;
const int Keyboard::Key_RSHIFT = ALLEGRO_KEY_RSHIFT;
const int Keyboard::Key_LCONTROL = ALLEGRO_KEY_LCTRL;
const int Keyboard::Key_RCONTROL = ALLEGRO_KEY_RCTRL;
const int Keyboard::Key_ALT = ALLEGRO_KEY_ALT;
const int Keyboard::Key_ALTGR = ALLEGRO_KEY_ALTGR;
const int Keyboard::Key_LWIN = ALLEGRO_KEY_LWIN;
const int Keyboard::Key_RWIN = ALLEGRO_KEY_RWIN;
const int Keyboard::Key_MENU = ALLEGRO_KEY_MENU;
const int Keyboard::Key_SCRLOCK = ALLEGRO_KEY_SCROLLLOCK;
const int Keyboard::Key_NUMLOCK = ALLEGRO_KEY_NUMLOCK;
const int Keyboard::Key_CAPSLOCK = ALLEGRO_KEY_CAPSLOCK;
+
+Keyboard::Keyboard():
+enableBuffer(false){
+}
+
+void Keyboard::disableKeyRepeat(){
+ /* TODO */
+}
+
+void Keyboard::enableKeyRepeat(){
+ /* TODO */
+}
+
+void Keyboard::readKeys(std::vector<int> & all_keys){
+ /* TODO */
+}
+
+bool Keyboard::keypressed(){
+ /* TODO */
+ return false;
+}
+
+void Keyboard::clear(){
+ /* TODO */
+}
diff --git a/util/music-player.cpp b/util/music-player.cpp
index 61909a69..0bfe1e62 100644
--- a/util/music-player.cpp
+++ b/util/music-player.cpp
@@ -1,441 +1,519 @@
#ifdef USE_ALLEGRO
#include <allegro.h>
#endif
#include "music-player.h"
#include "globals.h"
#include "util/debug.h"
#include <iostream>
#include "configuration.h"
#include "sound.h"
#include "dumb/include/dumb.h"
#include "gme/Music_Emu.h"
#ifdef USE_ALLEGRO
#include "dumb/include/aldumb.h"
#include "ogg/logg.h"
#ifdef _WIN32
/* what do we need winalleg for?
* reason: ...
*/
#include <winalleg.h>
#endif
#endif
#ifdef USE_SDL
#include "sdl/mixer/SDL_mixer.h"
#endif
#include "exceptions/exception.h"
#include <sstream>
namespace Util{
class MusicException: public Exception::Base {
public:
MusicException(const std::string & file, int line, const std::string & reason):
Exception::Base(file, line),
reason(reason){
}
MusicException(const MusicException & copy):
Exception::Base(copy),
reason(copy.reason){
}
virtual ~MusicException() throw(){
}
protected:
virtual const std::string getReason() const {
return reason;
}
virtual Exception::Base * copy() const {
return new MusicException(*this);
}
std::string reason;
};
static double scaleVolume(double start){
return start;
}
MusicPlayer::MusicPlayer():
volume(1.0){
}
MusicPlayer::~MusicPlayer(){
}
static const char * typeToExtension( int i ){
switch (i){
case 0 : return ".xm";
case 1 : return ".s3m";
case 2 : return ".it";
case 3 : return ".mod";
default : return "";
}
}
DUH * DumbPlayer::loadDumbFile(const char * path){
DUH * what;
for (int i = 0; i < 4; i++){
/* the order of trying xm/s3m/it/mod matters because mod could be
* confused with one of the other formats, so load it last.
*/
switch (i){
case 0 : {
what = dumb_load_xm_quick(path);
break;
}
case 1 : {
what = dumb_load_s3m_quick(path);
break;
}
case 2 : {
what = dumb_load_it_quick(path);
break;
}
case 3 : {
what = dumb_load_mod_quick(path);
break;
}
}
if (what != NULL){
Global::debug(0) << "Loaded " << path << " type " << typeToExtension(i) << "(" << i << ")" << std::endl;
return what;
}
}
return NULL;
}
#ifdef USE_ALLEGRO
DumbPlayer::DumbPlayer(const char * path){
music_file = loadDumbFile(path);
if (music_file != NULL){
int buf = 1 << 11;
player = al_start_duh(music_file, 2, 0, scaleVolume(volume), buf, Sound::FREQUENCY);
} else {
std::ostringstream error;
error << "Could not DUMB file load " << path;
throw MusicException(__FILE__, __LINE__, error.str());
}
}
void DumbPlayer::play(){
al_resume_duh(this->player);
}
void DumbPlayer::poll(){
if (al_poll_duh(this->player) != 0){
}
}
void DumbPlayer::pause(){
al_pause_duh(this->player);
}
void DumbPlayer::setVolume(double volume){
this->volume = volume;
al_duh_set_volume(player, scaleVolume(volume));
}
DumbPlayer::~DumbPlayer(){
al_stop_duh(player);
unload_duh(music_file);
}
static const int GME_BUFFER_SIZE = 1 << 11;
GMEPlayer::GMEPlayer(const char * path){
gme_err_t fail = gme_open_file(path, &emulator, Sound::FREQUENCY);
if (fail != NULL){
Global::debug(0) << "GME load error for " << path << ": " << fail << std::endl;
throw MusicException(__FILE__, __LINE__, "Could not load GME file");
}
emulator->start_track(0);
Global::debug(0) << "Loaded GME file " << path << std::endl;
stream = play_audio_stream(GME_BUFFER_SIZE, 16, 1, Sound::FREQUENCY, 255, 128);
voice_set_priority(stream->voice, 255);
}
void GMEPlayer::play(){
voice_start(stream->voice);
}
void GMEPlayer::poll(){
short * buffer = (short*) get_audio_stream_buffer(stream);
if (buffer){
/* size in 16-bit samples is buffer size * channels */
emulator->play(GME_BUFFER_SIZE * 2, buffer);
if (emulator->track_ended()){
gme_info_t * info;
gme_track_info(emulator, &info, 0);
int intro = info->intro_length;
emulator->start_track(0);
// Global::debug(0) << "Seeking " << intro << "ms. Track length " << info->length << "ms" << std::endl;
/* skip past the intro if there is a loop */
if (info->loop_length != 0){
emulator->seek(intro);
}
}
/* allegro wants unsigned data but gme produces signed so to convert
* signed samples to unsigned samples we have to raise each value
* by half the maximum value of a short (0xffff+1)/2 = 0x8000
*/
for (int i = 0; i < GME_BUFFER_SIZE * 2; i++){
buffer[i] *= volume;
buffer[i] += 0x8000;
}
free_audio_stream_buffer(stream);
}
}
void GMEPlayer::pause(){
voice_stop(stream->voice);
}
void GMEPlayer::setVolume(double volume){
this->volume = volume;
}
GMEPlayer::~GMEPlayer(){
delete emulator;
stop_audio_stream(stream);
}
#ifdef HAVE_OGG
OggPlayer::OggPlayer(const char * path){
stream = logg_get_stream(path, scaleVolume(volume) * 255, 128, 1);
if (stream == NULL){
throw MusicException(__FILE__, __LINE__, "Could not load ogg file");
}
}
void OggPlayer::play(){
}
void OggPlayer::poll(){
logg_update_stream(stream);
}
void OggPlayer::pause(){
}
void OggPlayer::setVolume(double volume){
}
OggPlayer::~OggPlayer(){
logg_destroy_stream(stream);
}
#endif /* OGG */
#endif /* ALlEGRO */
#ifdef USE_SDL
DumbPlayer::DumbPlayer(const char * path){
music_file = loadDumbFile(path);
if (music_file == NULL){
std::ostringstream error;
error << "Could not load DUMB file " << path;
throw MusicException(__FILE__, __LINE__, error.str());
}
int n_channels = 2;
int position = 0;
renderer = duh_start_sigrenderer(music_file, 0, n_channels, position);
if (!renderer){
Global::debug(0) << "Could not create renderer" << std::endl;
throw Exception::Base(__FILE__, __LINE__);
}
}
void DumbPlayer::render(Uint8 * stream, int length){
double delta = 65536.0 / Sound::FREQUENCY;
/* a frame is 32 bits, 16 bit samples with 2 channels = 2 * 16,
* so we have to divide the number of 'dumb samples' by the
* size of each frame, 32 bits = 4 bytes
*/
/* FIXME: use global music volume to scale the output here */
int n = duh_render(renderer, 16, 0, volume, delta, length / 4, stream);
if (n == 0){
Global::debug(0) << "Sound finished?" << std::endl;
}
/*
short large = 0;
for (int i = 0; i < length / 2; i++){
short z = ((short *) stream)[i];
if (z < 0){
z = -z;
}
if (z > large){
large = z;
}
}
Global::debug(0) << "Largest amplitude " << large << std::endl;
*/
}
struct DumbPlayerInfo{
MusicPlayer * who;
};
void DumbPlayer::mixer(void * player_, Uint8 * stream, int length){
DumbPlayerInfo * info = (DumbPlayerInfo *) player_;
DumbPlayer * player = (DumbPlayer *) info->who;
player->render(stream, length);
}
void DumbPlayer::pause(){
Mix_HookMusic(NULL, NULL);
}
void DumbPlayer::play(){
DumbPlayerInfo * me = new DumbPlayerInfo;
me->who = this;
Mix_HookMusic(mixer, me);
}
void DumbPlayer::poll(){
}
/* volume should be in the range 0.0 to 1.0 */
void DumbPlayer::setVolume(double volume){
this->volume = volume;
/* Mix_VolumeMusic only handles volume for formats it handles natively.
* for custom formats (like all these players) we have to handle volume
* ourselves.
*/
// Mix_VolumeMusic(MIX_MAX_VOLUME * volume);
}
DumbPlayer::~DumbPlayer(){
DumbPlayerInfo * info = (DumbPlayerInfo*) Mix_GetMusicHookData();
Mix_HookMusic(NULL, NULL);
if (info != NULL){
delete info;
}
/* I'm pretty sure if we get this far then there is no chance
* that our mixer function will still be active.
*/
duh_end_sigrenderer(renderer);
unload_duh(music_file);
}
struct GMEInfo{
GMEPlayer * player;
};
GMEPlayer::GMEPlayer(const char * path){
gme_err_t fail = gme_open_file(path, &emulator, Sound::FREQUENCY);
if (fail != NULL){
Global::debug(0) << "GME load error for " << path << ": " << fail << std::endl;
throw MusicException(__FILE__, __LINE__, "Could not load GME file");
}
emulator->start_track(0);
Global::debug(0) << "Loaded GME file " << path << std::endl;
}
void GMEPlayer::mixer(void * arg, Uint8 * stream, int length){
GMEInfo * info = (GMEInfo*) arg;
info->player->render(stream, length);
}
void GMEPlayer::render(Uint8 * stream, int length){
/* length/2 to convert bytes to short */
emulator->play(length / 2, (short*) stream);
/* scale for volume */
for (int i = 0; i < length / 2; i++){
short & sample = ((short *) stream)[i];
sample *= volume;
}
/*
short large = 0;
short small = 0;
for (int i = 0; i < length / 2; i++){
// ((short *) stream)[i] *= 2;
short z = ((short *) stream)[i];
if (z < small){
small = z;
}
if (z > large){
large = z;
}
}
Global::debug(0) << "Largest " << large << " Smallest " << small << std::endl;
*/
}
void GMEPlayer::play(){
GMEInfo * me = new GMEInfo;
me->player = this;
Mix_HookMusic(mixer, me);
}
void GMEPlayer::poll(){
}
void GMEPlayer::pause(){
}
void GMEPlayer::setVolume(double volume){
this->volume = volume;
// Mix_VolumeMusic(volume * MIX_MAX_VOLUME);
}
GMEPlayer::~GMEPlayer(){
GMEInfo * info = (GMEInfo*) Mix_GetMusicHookData();
Mix_HookMusic(NULL, NULL);
if (info != NULL){
delete info;
}
delete emulator;
}
#ifdef HAVE_OGG
OggPlayer::OggPlayer(const char * path){
music = Mix_LoadMUS(path);
if (music == NULL){
throw MusicException(__FILE__, __LINE__, "Could not load OGG file");
}
}
void OggPlayer::play(){
Mix_PlayMusic(music, -1);
}
void OggPlayer::poll(){
}
void OggPlayer::pause(){
Mix_PauseMusic();
}
void OggPlayer::setVolume(double volume){
this->volume = volume;
Mix_VolumeMusic(volume * MIX_MAX_VOLUME);
}
OggPlayer::~OggPlayer(){
Mix_FreeMusic(music);
}
#endif /* OGG */
#endif /* SDL */
+#ifdef USE_ALLEGRO5
+GMEPlayer::GMEPlayer(const char * path){
+ /* TODO */
+}
+
+void GMEPlayer::play(){
+ /* TODO */
+}
+
+void GMEPlayer::poll(){
+ /* TODO */
+}
+
+void GMEPlayer::pause(){
+ /* TODO */
+}
+
+void GMEPlayer::setVolume(double volume){
+ /* TODO */
+}
+
+GMEPlayer::~GMEPlayer(){
+ /* TODO */
+}
+
+#ifdef HAVE_OGG
+OggPlayer::OggPlayer(const char * path){
+ /* TODO */
+}
+
+void OggPlayer::play(){
+ /* TODO */
+}
+
+void OggPlayer::poll(){
+ /* TODO */
+}
+
+void OggPlayer::pause(){
+ /* TODO */
+}
+
+void OggPlayer::setVolume(double volume){
+ /* TODO */
+}
+
+OggPlayer::~OggPlayer(){
+ /* TODO */
+}
+
+#endif
+
+DumbPlayer::DumbPlayer(const char * path){
+ /* TODO */
+}
+
+void DumbPlayer::play(){
+ /* TODO */
+}
+
+void DumbPlayer::poll(){
+ /* TODO */
+}
+
+void DumbPlayer::pause(){
+ /* TODO */
+}
+
+void DumbPlayer::setVolume(double volume){
+ /* TODO */
+}
+
+DumbPlayer::~DumbPlayer(){
+ /* TODO */
+}
+
+#endif
+
}
diff --git a/util/sdl/bitmap.cpp b/util/sdl/bitmap.cpp
index 298aa85f..2171b1b4 100644
--- a/util/sdl/bitmap.cpp
+++ b/util/sdl/bitmap.cpp
@@ -1,1886 +1,1882 @@
#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>
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;
}
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
}
}
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;
}
}
// 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;
}
}
}
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);
/*
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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;
}
}
}
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;
}
}
}
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);
}
*/
-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);
-}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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 ){
y_dir = -1;
}
if ( flip & Bitmap::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 ){
/* 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 ){
/* 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 ){
dxbeg = dx + w - 1;
}
dybeg = dy;
if ( flip & Bitmap::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 : {
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 : {
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 : {
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);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jun 11, 11:32 AM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68782
Default Alt Text
(172 KB)

Event Timeline