Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
64 KB
Referenced Files
None
Subscribers
None
diff --git a/util/bitmap.cpp b/util/bitmap.cpp
index f52a364a..7d24ad3f 100644
--- a/util/bitmap.cpp
+++ b/util/bitmap.cpp
@@ -1,483 +1,483 @@
#include "funcs.h"
#include "bitmap.h"
#include "trans-bitmap.h"
#include "stretch-bitmap.h"
#include "lit_bitmap.h"
#include <string>
#include <stdio.h>
#include <math.h>
namespace Graphics{
static Bitmap * Screen = NULL;
/* bitmaps that should always be resized to the dimensions of the screen */
static std::vector<Bitmap*> needResize;
-const std::string screenParameter = "screen";
+Util::Parameter<Bitmap*> screenParameter;
/* implementation independant definitions can go here */
Bitmap * Bitmap::temporary_bitmap = NULL;
Bitmap * Bitmap::temporary_bitmap2 = NULL;
int SCALE_X = 0;
int SCALE_Y = 0;
const int Bitmap::MODE_TRANS = 0;
const int Bitmap::MODE_SOLID = 1;
const int SPRITE_NO_FLIP = 0;
const int SPRITE_V_FLIP = 1;
const int SPRITE_H_FLIP = 2;
const int SPRITE_NORMAL = 1;
const int SPRITE_LIT = 2;
const int SPRITE_TRANS = 3;
static inline int max(int a, int b){
return a > b ? a : b;
}
void initializeExtraStuff();
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;
}
}
}
}
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;
}
}
Bitmap & Bitmap::operator=(const Bitmap & copy){
path = copy.getPath();
setData(copy.getData());
return *this;
}
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);
}
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 */
#if 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;
}
}
}
#endif
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, Color 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 Graphics::Color color ) const{
this->hLine(x1, y, x2, color);
}
void Bitmap::equilateralTriangle(int x, int y, int angle, int size, Color 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++){
Color 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 = 0, y1 = 0, x2 = 0, y2 = 0;
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 ){
Color mask = 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(const Color & color){
bit8MaskColor = color;
}
Color 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);
}
//! min (borrowed from allegro)
static inline int Min(int x, int y){ return (((x) < (y)) ? (x) : (y)); }
//! max (borrowed from allegro)
static inline int Max(int x, int y){ return (((x) > (y)) ? (x) : (y)); }
//! mid (borrowed from allegro)
static inline int Mid(int x,int y,int z){ return (Max((x), Min((y), (z)))); }
void Bitmap::roundRect(int radius, int x1, int y1, int x2, int y2, Color color) const {
const int width = x2 - x1;
const int height = y2 - y1;
radius = Mid(0, radius, Min((x1+width - x1)/2, (y1+height - y1)/2));
line(x1+radius, y1, x1+width-radius, y1, color);
line(x1+radius, y1+height, x1+width-radius,y1+height, color);
line(x1, y1+radius,x1, y1+height-radius, color);
line(x1+width, y1+radius,x1+width, y1+height-radius, color);
double quarterTurn = Util::pi / 2;
double quadrant1 = 0;
/* signs are flipped because the coordinate system is reflected over the y-axis */
double quadrant2 = -Util::pi / 2;
double quadrant3 = Util::pi;
double quadrant4 = -3 * Util::pi / 2;
/* upper right. draw from 90 to 0 */
arc(x1+radius + (width - radius *2), y1 + radius, quadrant1, quadrant1 + quarterTurn, radius, color);
/* upper left. draw from 180 to 270 */
arc(x1 + radius, y1 + radius, quadrant2, quadrant2 + quarterTurn, radius, color);
/* lower left. draw from 180 to 270 */
arc(x1 + radius, y1 + height - radius, quadrant3, quadrant3 + quarterTurn, radius, color);
/* lower right. draw from 0 to 270 */
arc(x1+width-radius, y1+height-radius, quadrant4, quadrant4 + quarterTurn, radius, color);
}
void Bitmap::roundRectFill(int radius, int x1, int y1, int x2, int y2, Graphics::Color color) const {
const int width = x2 - x1;
const int height = y2 - y1;
radius = Mid(0, radius, Min((x1+width - x1)/2, (y1+height - y1)/2));
double quarterTurn = Util::pi / 2;
double quadrant1 = 0;
/* signs are flipped because the coordinate system is reflected over the y-axis */
double quadrant2 = -Util::pi / 2;
double quadrant3 = Util::pi;
double quadrant4 = -3 * Util::pi / 2;
/* upper right. draw from 90 to 0 */
arcFilled(x1+radius + (width - radius *2), y1 + radius, quadrant1, quadrant1 + quarterTurn, radius, color);
/* upper left. draw from 180 to 270 */
arcFilled(x1 + radius, y1 + radius, quadrant2, quadrant2 + quarterTurn, radius, color);
/* lower left. draw from 180 to 270 */
arcFilled(x1 + radius, y1 + height - radius, quadrant3, quadrant3 + quarterTurn, radius, color);
/* lower right. draw from 0 to 270 */
arcFilled(x1+width-radius, y1+height-radius, quadrant4, quadrant4 + quarterTurn, radius, color);
rectangleFill(x1+radius + 1, y1, x2-radius - 1, y1+radius - 1, color);
rectangleFill(x1, y1+radius, x2, y2-radius, color);
rectangleFill(x1+radius + 1, y2-radius + 1, x2-radius - 1, y2, color);
}
int Bitmap::getScreenWidth(){
if (Screen != 0){
return Screen->getWidth();
}
return 0;
}
int Bitmap::getScreenHeight(){
if (Screen != 0){
return Screen->getHeight();
}
return 0;
}
void Bitmap::clear() const {
fill(makeColor(0, 0, 0));
}
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());
}
}
Color darken(Color 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(Color color) const {
Bitmap::applyTrans(color);
}
int StretchedBitmap::getWidth() const {
return width;
}
int StretchedBitmap::getHeight() const {
return height;
}
void blend_palette(Color * pal, int mp, Color startColor, Color endColor){
/*
ASSERT(pal);
ASSERT(mp != 0);
*/
int sc_r = Graphics::getRed(startColor);
int sc_g = Graphics::getGreen(startColor);
int sc_b = Graphics::getBlue(startColor);
int ec_r = Graphics::getRed(endColor);
int ec_g = Graphics::getGreen(endColor);
int ec_b = Graphics::getBlue(endColor);
for ( int q = 0; q < mp; q++ ) {
float j = (float)( q + 1 ) / (float)( mp );
int f_r = (int)( 0.5 + (float)( sc_r ) + (float)( ec_r-sc_r ) * j );
int f_g = (int)( 0.5 + (float)( sc_g ) + (float)( ec_g-sc_g ) * j );
int f_b = (int)( 0.5 + (float)( sc_b ) + (float)( ec_b-sc_b ) * j );
pal[q] = Graphics::makeColor( f_r, f_g, f_b );
}
}
}
#ifdef USE_ALLEGRO
#include "allegro/bitmap.cpp"
#endif
#ifdef USE_SDL
#include "sdl/bitmap.cpp"
#endif
#ifdef USE_ALLEGRO5
#include "allegro5/bitmap.cpp"
#endif
diff --git a/util/bitmap.h b/util/bitmap.h
index e84e35fd..92aa4802 100644
--- a/util/bitmap.h
+++ b/util/bitmap.h
@@ -1,431 +1,433 @@
#ifndef _paintown_bitmap_h_
#define _paintown_bitmap_h_
#include "exceptions/exception.h"
#include "pointer.h"
+#include "parameter.h"
#include <string>
#include <vector>
#include <iostream>
#ifdef USE_ALLEGRO
#include "allegro/bitmap.h"
#endif
#ifdef USE_SDL
#include "sdl/bitmap.h"
#endif
#ifdef USE_ALLEGRO5
#include "allegro5/bitmap.h"
#endif
namespace Graphics{
class TranslucentBitmap;
+class Bitmap;
-extern const std::string screenParameter;
+extern Util::Parameter<Bitmap*> screenParameter;
extern const int SPRITE_NORMAL;
extern const int SPRITE_LIT;
extern const int SPRITE_TRANS;
extern const int SPRITE_NO_FLIP;
extern const int SPRITE_V_FLIP;
extern const int SPRITE_H_FLIP;
extern int SCALE_X;
extern int SCALE_Y;
class BitmapException: public Exception::Base {
public:
BitmapException(const std::string & file, int line, const std::string & reason):
Base(file, line),
reason(reason){
}
BitmapException(const BitmapException & copy):
Base(copy),
reason(copy.reason){
}
virtual void throwSelf() const {
throw *this;
}
virtual ~BitmapException() throw () {
}
protected:
virtual const std::string getReason() const {
return reason;
}
std::string reason;
};
/* create a color from components */
Color makeColor(int r, int g, int b);
Color darken(Color color, double factor);
void hsvToRGB( float h, float s, float v, int * r, int * g, int * b );
int setGfxModeText();
int setGfxModeFullscreen( int x, int y );
int setGfxModeWindowed( int x, int y );
int setGraphicsMode(int mode, int width, int height);
/* get color components */
int getRed(Color x);
int getBlue(Color x);
int getGreen(Color x);
Color MaskColor();
class Bitmap{
private:
/* these constructors don't really matter, get rid of them at some point */
Bitmap( const Bitmap & copy, int sx, int sy, double accuracy );
Bitmap( const char * load_file, int sx, int sy, double accuracy );
public:
/* equivalent to a GPU shader */
class Filter{
public:
virtual Color filter(Color pixel) const = 0;
virtual ~Filter(){
}
};
/* default constructor makes 10x10 bitmap */
Bitmap();
Bitmap( int x, int y );
Bitmap( const char * load_file );
Bitmap(const char * data, int length);
Bitmap( const std::string & load_file );
Bitmap( const char * load_file, int sx, int sy );
/* 4/24/2010: remove this at some point */
#ifdef USE_ALLEGRO
explicit Bitmap( BITMAP * who, bool deep_copy = false );
#endif
#ifdef USE_SDL
explicit Bitmap(SDL_Surface * who, bool deep_copy = false );
#endif
#ifdef USE_ALLEGRO5
explicit Bitmap(ALLEGRO_BITMAP * who, bool deep_copy = false );
#endif
Bitmap( const Bitmap & copy, bool deep_copy = false );
Bitmap( const Bitmap & copy, int sx, int sy );
Bitmap( const Bitmap & copy, int x, int y, int width, int height );
virtual ~Bitmap();
virtual TranslucentBitmap translucent() const;
virtual void save( const std::string & str ) const;
Bitmap & operator=( const Bitmap & );
virtual void load( const std::string & str );
virtual int getWidth() const;
virtual int getHeight() const;
/*
inline const int getWidth() const{
return getBitmap()->w;
}
inline const int getHeight() const{
return getBitmap()->h;
}
*/
/*
inline const int getWidth() const{
return my_bitmap->w;
}
inline const int getHeight() const{
return my_bitmap->h;
}
*/
static Bitmap memoryPCX(unsigned char * const data, const int length, const bool mask = true);
void detach();
/* replace all pixels that have value `original' with `replaced' */
void replaceColor(const Color & original, const Color & replaced);
void set8BitMaskColor(const Color & color);
Color get8BitMaskColor();
static void transBlender( int r, int g, int b, int a );
static void multiplyBlender( int r, int g, int b, int a );
static void dissolveBlender( int r, int g, int b, int a );
static void addBlender( int r, int g, int b, int a );
static void burnBlender( int r, int g, int b, int a );
static void colorBlender( int r, int g, int b, int a );
static void differenceBlender( int r, int g, int b, int a );
static void dodgeBlender( int r, int g, int b, int a );
static void hueBlender( int r, int g, int b, int a );
static void luminanceBlender( int r, int g, int b, int a );
static void invertBlender( int r, int g, int b, int a );
static void screenBlender( int r, int g, int b, int a );
/* for testing */
static void setFakeGraphicsMode(int width, int height);
/* clean up any remaining state */
static void shutdown();
static void drawingMode( int type );
virtual Color blendColor(const Color & input) const;
/* sets the blend state. try not to use these function unless
* absolutely necessary.
*/
virtual void startDrawing() const;
virtual void endDrawing() const;
void acquire();
void release();
void updateOnResize();
void resize(const int width, const int height);
void debugSelf() const;
/* convert to a grey scale version */
virtual Bitmap greyScale();
virtual void triangle( int x1, int y1, int x2, int y2, int x3, int y3, Color color ) const;
/* draws an equilateral triangle centered at (x,y) pointing at `angle'
* where each side has `size' pixels using the color.
*/
virtual void equilateralTriangle(int x, int y, int angle, int size, Color color) const;
virtual void ellipse( int x, int y, int rx, int ry, Color color ) const;
virtual void ellipseFill( int x, int y, int rx, int ry, Color color ) const;
virtual void light(int x, int y, int width, int height, int start_y, int focus_alpha, int edge_alpha, int focus_color, Color edge_color) const;
virtual void applyTrans(const Color color) const;
virtual void border( int min, int max, Color color ) const;
virtual void rectangle( int x1, int y1, int x2, int y2, Color color ) const;
virtual void rectangleFill( int x1, int y1, int x2, int y2, Color color ) const;
virtual void circleFill( int x, int y, int radius, Color color ) const;
virtual void circle( int x, int y, int radius, Color color ) const;
virtual void line( const int x1, const int y1, const int x2, const int y2, const Color color ) const;
virtual void floodfill( const int x, const int y, const Color color ) const;
virtual void horizontalLine( const int x1, const int y, const int x2, const Color color ) const;
virtual void hLine( const int x1, const int y, const int x2, const Color color ) const;
virtual void vLine( const int y1, const int x, const int y2, const Color color ) const;
virtual void polygon( const int * verts, const int nverts, const Color color ) const;
virtual void arc(const int x, const int y, const double ang1, const double ang2, const int radius, const Color color ) const;
virtual void arcFilled(const int x, const int y, const double ang1, const double ang2, const int radius, const Color color ) const;
virtual void draw(const int x, const int y, const Bitmap & where) const;
virtual void draw(const int x, const int y, Filter * filter, const Bitmap & where) const;
virtual void draw(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, const Bitmap & where) const;
virtual void draw(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, Filter * filter, const Bitmap & where) const;
virtual void drawCharacter( const int x, const int y, const int color, const int background, const Bitmap & where ) const;
/* flip horizontally */
virtual void drawHFlip(const int x, const int y, const Bitmap & where) const;
virtual void drawHFlip(const int x, const int y, Filter * filter, const Bitmap & where) const;
virtual void drawHFlip(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, const Bitmap & where) const;
virtual void drawHFlip(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, Filter * filter, const Bitmap & where) const;
/* flip vertically */
virtual void drawVFlip( const int x, const int y, const Bitmap & where ) const;
virtual void drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
/* flip horizontal and vertical */
virtual void drawHVFlip( const int x, const int y, const Bitmap & where ) const;
virtual void drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
// virtual void drawTrans( const int x, const int y, const Bitmap & where ) const;
// virtual void drawTrans( const int x, const int y, Filter * filter, const Bitmap & where ) const;
// virtual void drawTransHFlip( const int x, const int y, const Bitmap & where ) const;
// virtual void drawTransHFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
// virtual void drawTransVFlip( const int x, const int y, const Bitmap & where ) const;
// virtual void drawTransVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
// virtual void drawTransHVFlip( const int x, const int y, const Bitmap & where ) const;
// virtual void drawTransHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const;
virtual void drawMask( const int x, const int y, const Bitmap & where );
virtual void drawStretched( const int x, const int y, const int new_width, const int new_height, const Bitmap & who ) const;
virtual void drawRotate( const int x, const int y, const int angle, const Bitmap & where );
virtual void drawPivot( const int centerX, const int centerY, const int x, const int y, const int angle, const Bitmap & where );
virtual void drawPivot( const int centerX, const int centerY, const int x, const int y, const int angle, const double scale, const Bitmap & where );
virtual void Stretch( const Bitmap & where ) const;
virtual void Stretch( const Bitmap & where, const int sourceX, const int sourceY, const int sourceWidth, const int sourceHeight, const int destX, const int destY, const int destWidth, const int destHeight ) const;
virtual void StretchBy2( const Bitmap & where );
virtual void StretchBy4( const Bitmap & where );
virtual void Blit( const std::string & xpath ) const;
virtual void Blit( const Bitmap & where ) const;
virtual void Blit( const int x, const int y, const Bitmap & where ) const;
virtual void Blit( const int mx, const int my, const int wx, const int wy, const Bitmap & where ) const;
virtual void Blit( const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where ) const;
virtual void BlitMasked( const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where ) const;
virtual void BlitToScreen() const;
virtual void BlitAreaToScreen(const int upper_left_x, const int upper_left_y) const;
virtual void BlitToScreen(const int upper_left_x, const int upper_left_y) const;
virtual void BlitFromScreen(const int x, const int y) const;
void roundRect(int radius, int x1, int y1, int x2, int y2, Color color) const;
void roundRectFill(int radius, int x1, int y1, int x2, int y2, Graphics::Color color) const;
/* returned a scaled version of this bitmap of the given dimensions */
virtual Bitmap scaleTo(const int width, const int height) const;
/* try to call Global::getScreenWidth/Height() instead of these directly */
static int getScreenWidth();
static int getScreenHeight();
virtual void fill(Color color) const;
virtual void clear() const;
inline void clearToMask() const{
this->fill(MaskColor());
}
bool getError();
inline const Util::ReferenceCount<BitmapData> & getData() const {
return data;
}
inline Util::ReferenceCount<BitmapData> getData(){
return data;
}
void setData(Util::ReferenceCount<BitmapData> data){
this->data = data;
}
virtual void readLine( std::vector<Color> & vec, int y );
Color getPixel( const int x, const int y ) const;
/* lock video bitmap to memory */
void lock() const;
void lock(int x, int y, int width, int height) const;
void unlock() const;
/* true if the point is within the bounds of the bitmap */
bool inRange(int x, int y) const;
/* uses _putpixel16 underneath which ignores translucent behavior */
void putPixel( int x, int y, Color col ) const;
/* respects the current trans mode */
virtual void putPixelNormal(int x, int y, Color col) const;
/*
inline int getPixel( int x, int y ) const{
if ( x >= 0 && x < my_bitmap->w && y >= 0 && y <= my_bitmap->h )
return _getpixel16( my_bitmap, x, y );
return -1;
}
inline void putPixel( int x, int y, int col ) const{
if ( x >= 0 && x < my_bitmap->w && y >= 0 && y <= my_bitmap->h )
_putpixel16( my_bitmap, x, y, col );
}
*/
void setClipRect( int x1, int y1, int x2, int y2 ) const;
void getClipRect( int & x1, int & y1, int & x2, int & y2 ) const;
inline const std::string & getPath() const{
return path;
}
/* produce a temporary bitmap that is not guaranteed to be preserved
* after your function returns. do *not* hold references to this bitmap
* and if you make a temporary bitmap, do *not* call functions that
* might also make temporary bitmaps.
*/
static Bitmap temporaryBitmap(int w, int h);
static Bitmap temporaryBitmap2(int w, int h);
/* call this method to delete all temporary bitmaps.
* don't call this unless you know what you are doing
*/
static void cleanupTemporaryBitmaps();
static double getScale();
/*
* Convert color values between the HSV and RGB color spaces. The RGB values
* range from 0 to 255, hue is from 0 to 360, and saturation and value are
* from 0 to 1.
*/
static void rgbToHSV(int r, int g, int b, float * h, float * s, float * v);
/* convert cymk to rgb. values should be in the range 0-255 */
static void cymkToRGB(int c, int y, int m, int k, int * r, int * g, int * b);
/* Add two RGB16 colors together
* r = c1.r + c2.r
* g = c1.g + c2.g
* b = c1.b + c2.b
*/
static int addColor( int color1, int color2 );
/*
inline static int makeColor( int r, int g, int b ){
return makecol16( r, g, b );
}
*/
// static const int MaskColor = MASK_COLOR_16;
static const int MODE_TRANS;
static const int MODE_SOLID;
#ifdef USE_ALLEGRO5
void convertToVideo();
#endif
protected:
/* release a reference count, and possibly destroy data */
// void releaseInternalBitmap();
/* really destroy private data */
// void destroyPrivateData();
/*
inline void setBitmap( BITMAP * bitmap ){
if ( bitmap == NULL ){
std::cout << "*FATAL* Setting null bitmap" << std::endl;
}
_my_bitmap = bitmap;
}
*/
void internalLoadFile( const char * load_file );
/* implementation specific data */
Util::ReferenceCount<BitmapData> data;
// int * own;
bool mustResize;
// bool own;
bool error;
std::string path;
static Bitmap * temporary_bitmap;
static Bitmap * temporary_bitmap2;
Color bit8MaskColor;
/* only used by allegro5 for now */
int width, height;
};
/* creates a bitmap that can be used as a buffer for the screen.
* on opengl/allegro5 systems this will return the current backbuffer
*/
Bitmap getScreenBuffer();
void blend_palette(Color * pal, int mp, Color sc, Color ec);
// bool sameColors(Color color1, Color color2);
}
#endif
diff --git a/util/events.cpp b/util/events.cpp
index 8bf4266c..c6a80c2f 100644
--- a/util/events.cpp
+++ b/util/events.cpp
@@ -1,492 +1,490 @@
#ifdef USE_SDL
#include <SDL.h>
#endif
#ifdef USE_ALLEGRO5
#include <allegro5/allegro.h>
#endif
#include <vector>
#include "bitmap.h"
#include "events.h"
#include "exceptions/shutdown_exception.h"
#include "configuration.h"
#include "debug.h"
#include "funcs.h"
#include "thread.h"
#include "init.h"
#include "parameter.h"
#include "input/keyboard.h"
#include "input/joystick.h"
#include "input/input-manager.h"
-template <class Value> typename Util::Parameter<Value>::container Util::Parameter<Value>::stacks;
-
namespace Util{
EventManager::EventManager():
bufferKeys(false){
#ifdef USE_ALLEGRO5
queue = al_create_event_queue();
if (al_is_keyboard_installed()){
al_register_event_source(queue, al_get_keyboard_event_source());
}
if (Graphics::the_display != NULL){
al_register_event_source(queue, al_get_display_event_source(Graphics::the_display));
}
#endif
}
#ifdef USE_SDL
static void handleKeyDown(Keyboard & keyboard, const SDL_Event & event){
keyboard.press(event.key.keysym.sym, event.key.keysym.unicode);
}
static void handleKeyUp(Keyboard & keyboard, const SDL_Event & event){
keyboard.release(event.key.keysym.sym);
}
static void handleJoystickButtonUp(Joystick * joystick, const SDL_Event & event){
int device = event.jbutton.which;
int button = event.jbutton.button;
if (device == joystick->getDeviceId()){
joystick->releaseButton(button);
}
}
static void handleJoystickHat(Joystick * joystick, const SDL_Event & event){
int device = event.jhat.which;
int motion = event.jhat.value;
/* should up/down control left/right -- flip these values? */
#if WII
const int axis_up_down = 0;
const int axis_left_right = 1;
const int up = 1;
const int down = -1;
const int left = -1;
const int right = 1;
#else
const int axis_up_down = 1;
const int axis_left_right = 0;
const int up = -1;
const int down = 1;
const int left = -1;
const int right = 1;
#endif
switch (motion){
case SDL_HAT_CENTERED: break;
case SDL_HAT_UP: joystick->axisMotion(axis_up_down, up); break;
case SDL_HAT_DOWN: joystick->axisMotion(axis_up_down, down); break;
case SDL_HAT_RIGHT: joystick->axisMotion(axis_left_right, right); break;
case SDL_HAT_LEFT: joystick->axisMotion(axis_left_right, left); break;
default: break;
}
}
static void handleJoystickButtonDown(Joystick * joystick, const SDL_Event & event){
int device = event.jbutton.which;
int button = event.jbutton.button;
if (device == joystick->getDeviceId()){
joystick->pressButton(button);
}
}
static void handleJoystickAxis(Joystick * joystick, const SDL_Event & event){
int device = event.jaxis.which;
int axis = event.jaxis.axis;
int value = event.jaxis.value;
if (device == joystick->getDeviceId()){
joystick->axisMotion(axis, value);
}
}
void EventManager::runSDL(Keyboard & keyboard, Joystick * joystick){
keyboard.poll();
if (joystick){
joystick->poll();
}
SDL_Event event;
while (SDL_PollEvent(&event) == 1){
switch (event.type){
case SDL_QUIT : {
dispatch(CloseWindow);
break;
}
case SDL_KEYDOWN : {
handleKeyDown(keyboard, event);
// dispatch(Key, event.key.keysym.sym);
break;
}
case SDL_KEYUP : {
handleKeyUp(keyboard, event);
break;
}
case SDL_JOYBUTTONDOWN: {
if (joystick != NULL){
handleJoystickButtonDown(joystick, event);
}
break;
}
case SDL_JOYHATMOTION : {
if (joystick != NULL){
handleJoystickHat(joystick, event);
}
break;
}
case SDL_JOYBUTTONUP: {
if (joystick != NULL){
handleJoystickButtonUp(joystick, event);
}
break;
}
case SDL_JOYAXISMOTION: {
if (joystick != NULL){
handleJoystickAxis(joystick, event);
}
break;
}
case SDL_VIDEORESIZE : {
int width = event.resize.w;
int height = event.resize.h;
/* to keep the perspective correct
* 640/480 = 1.33333
*/
double ratio = (double) GFX_X / (double) GFX_Y;
if (width > height){
height = (int)((double) width / ratio);
} else {
width = (int)((double) height * ratio);
}
dispatch(ResizeScreen, width, height);
break;
}
default : {
break;
}
}
}
}
#endif
#ifdef USE_ALLEGRO
void EventManager::runAllegro(Keyboard & keyboard, Joystick * joystick){
keyboard.poll();
}
#endif
#ifdef USE_ALLEGRO5
static void handleKeyDown(Keyboard & keyboard, const ALLEGRO_EVENT & event){
keyboard.press(event.keyboard.keycode, event.keyboard.unichar);
}
static void handleKeyUp(Keyboard & keyboard, const ALLEGRO_EVENT & event){
keyboard.release(event.keyboard.keycode);
}
static void handleResize(const ALLEGRO_EVENT & event){
double width = event.display.width;
double height = event.display.height;
if (width < GFX_X){
width = GFX_X;
}
if (height < GFX_Y){
height = GFX_Y;
}
/* to keep the perspective correct
* 640/480 = 1.33333
*/
double ratio = (double) GFX_X / (double) GFX_Y;
if (width > height){
height = width / ratio;
} else {
width = height * ratio;
}
ALLEGRO_DISPLAY * display = event.display.source;
al_acknowledge_resize(display);
al_resize_display(display, (int) width, (int) height);
ALLEGRO_TRANSFORM transformation;
al_identity_transform(&transformation);
// al_scale_transform(&transformation, (double) al_get_display_width(display) / (double) GFX_X, (double) al_get_display_height(display) / (double) GFX_Y);
al_scale_transform(&transformation, (double) width / (double) GFX_X, (double) height / (double) GFX_Y);
al_set_target_bitmap(Graphics::getScreenBuffer().getData()->getBitmap());
al_use_transform(&transformation);
}
void EventManager::runAllegro5(Keyboard & keyboard, Joystick * joystick){
keyboard.poll();
ALLEGRO_EVENT event;
while (al_get_next_event(queue, &event)){
switch (event.type){
/*
case ALLEGRO_EVENT_KEY_DOWN: {
Global::debug(0) << "Key down " << event.keyboard.keycode << std::endl;
handleKeyDown(keyboard, event);
break;
}
*/
case ALLEGRO_EVENT_DISPLAY_RESIZE: {
handleResize(event);
break;
}
case ALLEGRO_EVENT_KEY_UP: {
handleKeyUp(keyboard, event);
break;
}
case ALLEGRO_EVENT_KEY_CHAR : {
// Global::debug(0) << "Key char " << event.keyboard.keycode << " unicode " << event.keyboard.unichar << std::endl;
handleKeyDown(keyboard, event);
break;
}
}
}
/*
if (joystick){
joystick->poll();
}
SDL_Event event;
while (SDL_PollEvent(&event) == 1){
switch (event.type){
case SDL_QUIT : {
dispatch(CloseWindow);
break;
}
case SDL_KEYDOWN : {
handleKeyDown(keyboard, event);
// dispatch(Key, event.key.keysym.sym);
break;
}
case SDL_KEYUP : {
handleKeyUp(keyboard, event);
break;
}
case SDL_JOYBUTTONDOWN: {
if (joystick != NULL){
handleJoystickButtonDown(joystick, event);
}
break;
}
case SDL_JOYHATMOTION : {
if (joystick != NULL){
handleJoystickHat(joystick, event);
}
break;
}
case SDL_JOYBUTTONUP: {
if (joystick != NULL){
handleJoystickButtonUp(joystick, event);
}
break;
}
case SDL_JOYAXISMOTION: {
if (joystick != NULL){
handleJoystickAxis(joystick, event);
}
break;
}
case SDL_VIDEORESIZE : {
int width = event.resize.w;
int height = event.resize.h;
/ * to keep the perspective correct
* 640/480 = 1.33333
* /
if (width > height){
height = (int)((double) width / 1.3333333333);
} else {
width = (int)((double) height * 1.3333333333);
}
dispatch(ResizeScreen, width, height);
break;
}
default : {
break;
}
}
}
*/
}
#endif
void EventManager::run(Keyboard & keyboard, Joystick * joystick){
#ifdef USE_SDL
runSDL(keyboard, joystick);
#elif USE_ALLEGRO
runAllegro(keyboard, joystick);
#elif USE_ALLEGRO5
runAllegro5(keyboard, joystick);
#endif
}
/* kill the program if the user requests */
void EventManager::waitForThread(WaitThread & thread){
// Keyboard dummy;
while (!thread.isRunning()){
try{
/* input manager will run the event manager */
InputManager::poll();
// run(dummy);
} catch (const ShutdownException & death){
thread.kill();
throw death;
}
Util::rest(10);
}
}
EventManager::~EventManager(){
#ifdef USE_ALLEGRO5
al_destroy_event_queue(queue);
#endif
}
void EventManager::enableKeyBuffer(){
bufferKeys = true;
}
void EventManager::disableKeyBuffer(){
bufferKeys = false;
}
void EventManager::dispatch(Event type, int arg1){
switch (type){
case Key : {
if (bufferKeys){
keys.push_back(KeyType(arg1));
}
break;
}
default : {
break;
}
}
}
void EventManager::dispatch(Event type, int arg1, int arg2){
switch (type){
case ResizeScreen : {
Global::debug(1) << "Resizing screen to " << arg1 << ", " << arg2 << std::endl;
if (Graphics::setGraphicsMode(0, arg1, arg2) == 0){
Configuration::setScreenWidth(arg1);
Configuration::setScreenHeight(arg2);
}
break;
}
default : break;
}
}
void EventManager::dispatch(Event type){
switch (type){
case CloseWindow : {
throw ShutdownException();
}
default : break;
}
}
class LoopDone: public std::exception {
public:
LoopDone(){
}
~LoopDone() throw () {
}
};
Logic::~Logic(){
}
Draw::Draw():
frames(0),
second_counter(Global::second_counter),
fps(0){
}
Draw::~Draw(){
}
double Draw::getFps() const {
return fps;
}
void Draw::updateFrames(){
if (second_counter != Global::second_counter){
int difference = Global::second_counter - second_counter;
double alpha = 0.2;
/* unlikely, but just in case */
if (difference == 0){
difference = 1;
}
fps = (alpha * fps) + ((1 - alpha) * (double) frames / difference);
// fps[fps_index] = (double) frames / (double) difference;
// fps_index = (fps_index+1) % max_fps_index;
second_counter = Global::second_counter;
frames = 0;
}
frames += 1;
}
static void doStandardLoop(Logic & logic, Draw & draw){
- const Graphics::Bitmap & screen = *Parameter<Graphics::Bitmap*>::current(Graphics::screenParameter);
+ const Graphics::Bitmap & screen = *Graphics::screenParameter.current();
Global::speed_counter4 = 0;
double runCounter = 0;
try{
while (!logic.done()){
if (Global::speed_counter4 > 0){
// Global::debug(0) << "Speed counter " << Global::speed_counter4 << std::endl;
runCounter += logic.ticks(Global::speed_counter4);
Global::speed_counter4 = 0;
bool need_draw = false;
while (runCounter >= 1.0){
need_draw = true;
InputManager::poll();
runCounter -= 1;
logic.run();
if (Global::shutdown()){
throw ShutdownException();
}
if (logic.done()){
/* quit the loop immediately */
throw LoopDone();
}
}
if (need_draw){
draw.updateFrames();
draw.draw(screen);
}
}
while (Global::speed_counter4 == 0){
/* if the fps is limited then don't keep redrawing */
if (Global::rateLimit){
rest(1);
} else {
draw.updateFrames();
draw.draw(screen);
}
}
}
} catch (const LoopDone & done){
}
}
void standardLoop(Logic & logic, Draw & draw){
/* if a screen already exists (because we have nested standardLoops) then
* leave this parameter alone, otherwise set a new parameter.
*/
/*
if (Parameter<Graphics::Bitmap*>::current() == NULL){
doStandardLoop(logic, draw);
} else {
doStandardLoop(logic, draw);
}
*/
doStandardLoop(logic, draw);
}
}
diff --git a/util/loading.cpp b/util/loading.cpp
index 84af28c8..c0dc45c6 100644
--- a/util/loading.cpp
+++ b/util/loading.cpp
@@ -1,496 +1,496 @@
#include "bitmap.h"
#include "trans-bitmap.h"
#include <math.h>
#include <iostream>
/* FIXME: get rid of this dependancy */
#include "paintown-engine/level/utils.h"
#include "messages.h"
#include "loading.h"
#include "file-system.h"
#include "font.h"
#include "funcs.h"
#include "gradient.h"
#include "parameter.h"
#include "thread.h"
#include "globals.h"
#include <vector>
#include "thread.h"
#include "message-queue.h"
#include "init.h"
#include "events.h"
using namespace std;
namespace Loader{
volatile bool done_loading = true;
typedef struct pair{
int x, y;
} ppair;
class Info{
public:
Info(){
Global::registerInfo(&messages);
}
bool transferMessages(Messages & box){
bool did = false;
while (messages.hasAny()){
const string & str = messages.get();
box.addMessage(str);
did = true;
}
return did;
}
~Info(){
Global::unregisterInfo(&messages);
}
private:
MessageQueue messages;
};
void * loadingScreenSimple1(void * arg);
static void setupBackground(const Graphics::Bitmap & background, int load_x, int load_y, int load_width, int load_height, int infobox_x, int infobox_y, int infoWidth, int infoHeight, const Graphics::Bitmap & infoBackground){
Font::getDefaultFont().printf( 400, 480 - Font::getDefaultFont().getHeight() * 5 / 2 - Font::getDefaultFont().getHeight(), Graphics::makeColor( 192, 192, 192 ), background, "Paintown version %s", 0, Global::getVersionString().c_str());
Font::getDefaultFont().printf( 400, 480 - Font::getDefaultFont().getHeight() * 5 / 2, Graphics::makeColor( 192, 192, 192 ), background, "Made by Jon Rafkind", 0 );
background.BlitToScreen();
background.Blit(infobox_x, infobox_y, infoWidth, infoHeight, 0, 0, infoBackground);
}
/* converts a bitmap with some text on it into a sequence of points */
static vector<ppair> generateFontPixels(const Font & myFont, const string & message, int width, int height){
Graphics::Bitmap letters(width, height);
letters.fill(Graphics::MaskColor());
myFont.printf(0, 0, Graphics::makeColor(255, 255, 255), letters, message.c_str(), 0);
vector<ppair> pairs;
/* store every pixel we need to draw */
letters.lock();
for (int x = 0; x < letters.getWidth(); x++){
for (int y = 0; y < letters.getHeight(); y++){
Graphics::Color pixel = letters.getPixel(x, y);
if (pixel != Graphics::MaskColor()){
ppair p;
p.x = x;
p.y = y;
pairs.push_back(p);
}
}
}
letters.unlock();
// Graphics::resetDisplay();
return pairs;
}
/* shows time elapsed */
class TimeCounter{
public:
TimeCounter():
work(200, 40){
start = Global::second_counter;
last = 0;
}
void draw(int x, int y){
const Font & font = Font::getDefaultFont(24, 24);
if (Global::second_counter != last){
work.clear();
last = Global::second_counter;
font.printf(0, 0, Graphics::makeColor(192, 192, 192), work, "Waiting.. %d", 0, last - start);
work.BlitAreaToScreen(x, y);
}
}
Graphics::Bitmap work;
unsigned int start;
unsigned int last;
};
static void loadingScreen1(LoadingContext & context, const Level::LevelInfo & levelInfo){
int load_x = 80;
int load_y = 220;
const int infobox_width = 300;
const int infobox_height = 150;
const Font & myFont = Font::getFont(Global::DEFAULT_FONT, 24, 24);
if (levelInfo.getPositionX() != -1){
load_x = levelInfo.getPositionX();
}
if (levelInfo.getPositionY() != -1){
load_y = levelInfo.getPositionY();
}
// const char * the_string = (arg != NULL) ? (const char *) arg : "Loading...";
int load_width = myFont.textLength(levelInfo.loadingMessage().c_str());
int load_height = myFont.getHeight(levelInfo.loadingMessage().c_str());
Global::debug(2) << "loading screen" << endl;
Messages infobox(infobox_width, infobox_height);
const int MAX_COLOR = 200;
/* blend from dark grey to light red */
Effects::Gradient gradient(MAX_COLOR, Graphics::makeColor(16, 16, 16), Graphics::makeColor(192, 8, 8));
TimeCounter counter;
struct State{
bool drawInfo;
};
class Logic: public Util::Logic {
public:
Logic(LoadingContext & context, State & state, Effects::Gradient & gradient, Messages & infoBox):
context(context),
state(state),
gradient(gradient),
infobox(infoBox){
}
LoadingContext & context;
State & state;
Effects::Gradient & gradient;
Info info;
Messages & infobox;
void run(){
gradient.backward();
state.drawInfo = info.transferMessages(infobox) || state.drawInfo;
}
double ticks(double system){
return system;
}
bool done(){
return context.done();
}
};
class Draw: public Util::Draw {
public:
Draw(const Level::LevelInfo & levelInfo, State & state, Messages & infobox, Effects::Gradient & gradient, int load_width, int load_height, int infobox_width, int infobox_height, int load_x, int load_y):
gradient(gradient),
state(state),
infobox(infobox),
- infoWork(*Util::Parameter<Graphics::Bitmap*>::current(Graphics::screenParameter), load_x, load_y + load_height * 2, infobox_width, infobox_height),
+ infoWork(*Graphics::screenParameter.current(), load_x, load_y + load_height * 2, infobox_width, infobox_height),
infoBackground(infobox_width, infobox_height),
infobox_x(load_x),
infobox_y(load_y + load_height * 2),
load_x(load_x),
load_y(load_y),
load_width(load_width),
load_height(load_height){
const Font & myFont = Font::getFont(Global::DEFAULT_FONT, 24, 24);
pairs = generateFontPixels(myFont, levelInfo.loadingMessage(), load_width, load_height);
if (levelInfo.getBackground() != 0){
setupBackground(*levelInfo.getBackground(), load_x, load_y, load_width, load_height, infobox_x, infobox_y, infoBackground.getWidth(), infoBackground.getHeight(), infoBackground);
} else {
setupBackground(Graphics::Bitmap(levelInfo.loadingBackground().path()), load_x, load_y, load_width, load_height, infobox_x, infobox_y, infoBackground.getWidth(), infoBackground.getHeight(), infoBackground);
}
}
Effects::Gradient & gradient;
State & state;
Messages & infobox;
Graphics::Bitmap infoWork;
Graphics::Bitmap infoBackground;
vector<ppair> pairs;
const int infobox_x;
const int infobox_y;
const int load_x;
const int load_y;
const int load_width;
const int load_height;
void draw(const Graphics::Bitmap & screen){
Graphics::Bitmap work(screen, load_x, load_y, load_width, load_height);
work.lock();
for (vector< ppair >::iterator it = pairs.begin(); it != pairs.end(); it++){
Graphics::Color color = gradient.current(it->x);
work.putPixel(it->x, it->y, color);
}
work.unlock();
if (state.drawInfo){
infoBackground.Blit(infoWork);
const Font & infoFont = Font::getFont(Global::DEFAULT_FONT, 24, 24);
/* cheesy hack to change the font size. the font
* should store the size and change it on its own
*/
Font::getFont(Global::DEFAULT_FONT, 13, 13);
infobox.draw(0, 0, infoWork, infoFont);
Font::getFont(Global::DEFAULT_FONT, 24, 24);
infoWork.BlitAreaToScreen(infobox_x, infobox_y);
// infoWork.BlitToScreen();
state.drawInfo = false;
}
/* work already contains the correct background */
// work.Blit( load_x, load_y, *Bitmap::Screen );
// work.BlitToScreen();
work.BlitAreaToScreen(load_x, load_y);
}
};
State state;
state.drawInfo = true;
Logic logic(context, state, gradient, infobox);
Draw draw(levelInfo, state, infobox, gradient, load_width, load_height, infobox_width, infobox_height, load_x, load_y);
Util::standardLoop(logic, draw);
#if 0
while (! context.done()){
/* true if a logic loop has passed */
bool draw = firstDraw;
/* will be true if any new info messages appeared */
bool drawInfo = firstDraw;
firstDraw = false;
if ( Global::speed_counter > 0 ){
double think = Global::speed_counter;
Global::speed_counter = 0;
draw = true;
while ( think > 0 ){
gradient.backward();
think -= 1;
}
/* if no new messages appeared this will be false */
drawInfo = info.transferMessages(infobox);
} else {
Util::rest( 1 );
}
if (draw){
for ( vector< ppair >::iterator it = pairs.begin(); it != pairs.end(); it++ ){
int color = gradient.current(it->x);
work.putPixel(it->x, it->y, color);
}
// counter.draw(200, 100);
/* we might not have to draw the whole info box again if no new
* messages appeared.
*/
if (drawInfo){
infoBackground.Blit(infoWork);
/* cheesy hack to change the font size. the font
* should store the size and change it on its own
*/
Font::getFont(Global::DEFAULT_FONT, 13, 13);
infobox.draw(0, 0, infoWork, infoFont);
Font::getFont(Global::DEFAULT_FONT, 24, 24);
infoWork.BlitAreaToScreen(infobox_x, infobox_y);
}
/* work already contains the correct background */
// work.Blit( load_x, load_y, *Bitmap::Screen );
work.BlitAreaToScreen(load_x, load_y);
}
}
#endif
}
static void loadingScreenSimpleX1(LoadingContext & context, const Level::LevelInfo & levelInfo){
class Logic: public Util::Logic {
public:
Logic(LoadingContext & context, int & angle, int speed):
context(context),
speed(speed),
angle(angle){
}
LoadingContext & context;
/* speed of rotation */
const int speed;
int & angle;
double ticks(double system){
return system / 2;
}
bool done(){
return context.done();
}
void run(){
angle += speed * 2;
}
};
class Draw: public Util::Draw {
public:
Draw(int & angle, const int speed):
original(40, 40),
angle(angle),
speed(speed){
original.BlitFromScreen(0, 0);
color1 = Graphics::makeColor(0, 0, 0);
color2 = Graphics::makeColor(0x00, 0x99, 0xff);
color3 = Graphics::makeColor(0xff, 0x22, 0x33);
color4 = Graphics::makeColor(0x44, 0x77, 0x33);
colors[0] = color1;
colors[1] = color2;
colors[2] = color3;
colors[3] = color4;
Graphics::Bitmap::transBlender(0, 0, 0, 64);
}
Graphics::Bitmap original;
int & angle;
const int speed;
Graphics::Color color1;
Graphics::Color color2;
Graphics::Color color3;
Graphics::Color color4;
/* the length of this array is the number of circles to show */
Graphics::Color colors[4];
~Draw(){
}
void draw(const Graphics::Bitmap & screen){
Graphics::Bitmap work(screen, 0, 0, 40, 40);
int max = sizeof(colors) / sizeof(int);
double middleX = work.getWidth() / 2;
double middleY = work.getHeight() / 2;
original.Blit(work);
for (int i = 0; i < max; i++){
double x = cos(Util::radians(angle + 360 / max * i)) * 15;
double y = sin(Util::radians(angle + 360 / max * i)) * 15;
/* ghost circle */
work.translucent().circleFill(middleX + x, middleY + y, 2, colors[i]);
x = cos(Util::radians(angle + speed + 360 / max * i)) * 15;
y = sin(Util::radians(angle + speed + 360 / max * i)) * 15;
/* real circle */
work.circleFill(middleX + x, middleY + y, 2, colors[i]);
}
work.BlitAreaToScreen(0, 0);
}
};
int angle = 0;
int speed = 7;
Logic logic(context, angle, speed);
Draw draw(angle, speed);
Util::standardLoop(logic, draw);
#if 0
while (! context.done()){
bool draw = false;
if (Global::speed_counter > 0){
double think = Global::speed_counter;
Global::speed_counter = 0;
draw = true;
while (think > 0){
angle += speed;
think -= 1;
}
} else {
Util::rest(1);
}
if (draw){
int max = sizeof(colors) / sizeof(int);
double middleX = work.getWidth() / 2;
double middleY = work.getHeight() / 2;
original.Blit(work);
for (int i = 0; i < max; i++){
double x = cos(Util::radians(angle + 360 / max * i)) * 15;
double y = sin(Util::radians(angle + 360 / max * i)) * 15;
/* ghost circle */
work.translucent().circleFill(middleX + x, middleY + y, 2, colors[i]);
x = cos(Util::radians(angle + speed + 360 / max * i)) * 15;
y = sin(Util::radians(angle + speed + 360 / max * i)) * 15;
/* real circle */
work.circleFill(middleX + x, middleY + y, 2, colors[i]);
}
work.BlitAreaToScreen(0, 0);
}
}
#endif
}
LoadingContext::LoadingContext():
finished(false){
Util::Thread::initializeLock(&lock);
}
LoadingContext::~LoadingContext(){
}
void LoadingContext::doLoad(){
this->load();
Util::Thread::acquireLock(&lock);
finished = true;
Util::Thread::releaseLock(&lock);
}
bool LoadingContext::done(){
bool ok = false;
Util::Thread::acquireLock(&lock);
ok = this->finished;
Util::Thread::releaseLock(&lock);
return ok;
}
void * LoadingContext::load_it(void * arg){
LoadingContext * context = (LoadingContext*) arg;
context->doLoad();
return NULL;
}
static void showLoadMessage(){
int screenX = 80;
int screenY = 50;
Graphics::Bitmap work(110, 50);
work.BlitFromScreen(screenX, screenY);
Graphics::Bitmap top(110, 50);
top.fill(Graphics::makeColor(0, 0, 0));
Font::getDefaultFont(25, 25).printf(10, 5, Graphics::makeColor(192, 192, 192), top, "Loading", 0);
Graphics::Bitmap::transBlender(0, 0, 0, 200);
top.translucent().draw(0, 0, work);
work.BlitAreaToScreen(screenX, screenY);
}
void loadScreen(LoadingContext & context, const Level::LevelInfo & info, Kind kind){
Util::Thread::Id loadingThread;
bool created = Util::Thread::createThread(&loadingThread, NULL, (Util::Thread::ThreadFunction) LoadingContext::load_it, &context);
if (!created){
Global::debug(0) << "Could not create loading thread. Loading will occur in the main thread" << endl;
showLoadMessage();
LoadingContext::load_it(&context);
// throw LoadException(__FILE__, __LINE__, "Could not create loader thread");
} else {
switch (kind){
case Default: loadingScreen1(context, info); break;
case SimpleCircle: loadingScreenSimpleX1(context, info); break;
default: loadingScreen1(context, info); break;
}
Util::Thread::joinThread(loadingThread);
}
}
}
diff --git a/util/parameter.h b/util/parameter.h
index 6d45df63..54da76e5 100644
--- a/util/parameter.h
+++ b/util/parameter.h
@@ -1,77 +1,76 @@
#ifndef _paintown_parameter_h
#define _paintown_parameter_h
/* parameters are to be used to control the dynamic extent of values. values
* can be pushed onto the current extent and are automatically popped off
* upon function return.
* this is similar to 'parameters' in Racket.
*
* This class is not thread safe.
*/
-#include <map>
#include <vector>
-#include <string>
+#include "pointer.h"
namespace Util{
/* the static variable `stack' has to be defined somewhere. use this syntax to define it
* template <class Value> typename Util::Parameter<Value>::container Util::Parameter<Value>::stacks;
*/
template <class Value>
class Parameter{
public:
/* push a new value on the stack */
- Parameter(const Value & what, const std::string & name):
- items(0),
- name(name){
+ Parameter(Parameter & parent, const Value & what):
+ stack(parent.stack),
+ items(0){
push(what);
}
- Parameter(const std::string & name):
- items(0),
- name(name){
+ Parameter(Parameter & parent):
+ stack(parent.stack),
+ items(0){
+ }
+
+ Parameter():
+ items(0){
+ stack = new std::vector<Value>();
}
/* pop last value */
- ~Parameter(){
- std::vector<Value> & stack = stacks[name];
+ virtual ~Parameter(){
for (int i = 0; i < items; i++){
- if (stack.size() > 0){
- stack.pop_back();
+ if (stack->size() > 0){
+ stack->pop_back();
}
}
}
void push(const Value & what){
- std::vector<Value> & stack = stacks[name];
items += 1;
- stack.push_back(what);
+ stack->push_back(what);
}
/* get the current value */
- static Value current(const std::string & name){
- std::vector<Value> & stack = stacks[name];
- if (stack.size() > 0){
- return stack.back();
+ Value current(){
+ if (stack->size() > 0){
+ return stack->back();
}
return Value();
}
- typedef std::map<const std::string, std::vector<Value> > container;
- static container stacks;
+ ReferenceCount<std::vector<Value> > stack;
protected:
/* number of things pushed onto the stack by this object. note this is
* not the number of items on the stack because if there are multiple
* parameter objects then each one could have pushed 1 object on. thus
* the stack will have 2 things in it but each parameter will have an
* 'items' count of 1.
*/
int items;
- std::string name;
};
}
#endif

File Metadata

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

Event Timeline