Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
50 KB
Referenced Files
None
Subscribers
None
diff --git a/util/allegro5/bitmap.cpp b/util/allegro5/bitmap.cpp
index 7673ceee..08614799 100644
--- a/util/allegro5/bitmap.cpp
+++ b/util/allegro5/bitmap.cpp
@@ -1,1112 +1,1120 @@
#include <sstream>
#include <allegro5/allegro5.h>
#include <allegro5/allegro_memfile.h>
#include <allegro5/allegro_primitives.h>
#include "util/debug.h"
#include "util/thread.h"
namespace Graphics{
/* it doesnt look like we need to pack colors into 16-bit values */
#if 0
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];
}
#endif
enum BlendingType{
Translucent,
Add,
Difference,
Multiply
};
struct BlendingData{
BlendingData():
red(0), green(0), blue(0), alpha(0), type(Translucent){
}
int red, green, blue, alpha;
BlendingType type;
};
static BlendingData globalBlend;
/* must be a pointer so it can be created dynamically after allegro init */
// Util::Thread::LockObject * allegroLock;
Color makeColorAlpha(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha){
return al_map_rgba(red, blue, green, alpha);
}
Color MaskColor(){
static Color mask = makeColorAlpha(0, 0, 0, 0);
return mask;
}
Color getBlendColor(){
return makeColorAlpha(255, 255, 255, globalBlend.alpha);
}
Color doTransBlend(const Color & color, int alpha){
unsigned char red, green, blue;
al_unmap_rgb(color, &red, &green, &blue);
return makeColorAlpha(red, green, blue, alpha);
/*
red *= alpha_f;
green *= alpha_f;
blue *= alpha_f;
return al_map_rgb_f(red, green, blue);
*/
}
Color transBlendColor(const Color & color){
return doTransBlend(color, globalBlend.alpha);
}
class Blender{
public:
Blender(){
}
virtual ~Blender(){
/* default is to draw the source and ignore the destination */
al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
}
};
class MaskedBlender: public Blender {
public:
MaskedBlender(){
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
}
};
class TransBlender: public Blender {
public:
TransBlender(){
switch (globalBlend.type){
case Translucent: al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); break;
case Add: al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); break;
case Multiply: al_set_blender(ALLEGRO_DEST_MINUS_SRC, ALLEGRO_ONE, ALLEGRO_ONE); break;
case Difference: al_set_blender(ALLEGRO_DEST_MINUS_SRC, ALLEGRO_ONE, ALLEGRO_ONE); break;
}
}
};
static const int WINDOWED = 0;
static const int FULLSCREEN = 1;
static Bitmap * Scaler = NULL;
Bitmap::Bitmap():
own(NULL),
mustResize(false),
bit8MaskColor(makeColor(0, 0, 0)){
/* TODO */
}
Bitmap::Bitmap( const char * load_file ):
own(NULL),
mustResize(false),
bit8MaskColor(makeColor(0, 0, 0)){
internalLoadFile(load_file);
}
Bitmap::Bitmap( const std::string & load_file ):
own(NULL),
mustResize(false),
bit8MaskColor(makeColor(0, 0, 0)){
internalLoadFile(load_file.c_str());
}
Bitmap::Bitmap(ALLEGRO_BITMAP * who, bool deep_copy):
own(NULL),
mustResize(false),
bit8MaskColor(makeColor(0, 0, 0)){
if (deep_copy){
ALLEGRO_BITMAP * clone = al_clone_bitmap(who);
setData(new BitmapData(clone));
own = new int;
*own = 1;
} else {
setData(new BitmapData(who));
}
}
Bitmap::Bitmap(int width, int height):
own(NULL),
mustResize(false),
bit8MaskColor(makeColor(0, 0, 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());
}
setData(new BitmapData(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());
setData(new BitmapData(clone));
own = new int;
*own = 1;
} else {
setData(copy.getData());
own = copy.own;
if (own){
*own += 1;
}
}
}
void Bitmap::convertToVideo(){
ALLEGRO_BITMAP * original = getData()->getBitmap();
ALLEGRO_BITMAP * copy = al_clone_bitmap(original);
if (copy == NULL){
throw BitmapException(__FILE__, __LINE__, "Could not create video bitmap");
}
releaseInternalBitmap();
getData()->setBitmap(copy);
own = new int;
*own = 1;
}
void changeTarget(const Bitmap & from, const Bitmap & who){
al_set_target_bitmap(who.getData()->getBitmap());
if ((al_get_bitmap_flags(who.getData()->getBitmap()) & ALLEGRO_VIDEO_BITMAP) &&
(al_get_bitmap_flags(from.getData()->getBitmap()) & ALLEGRO_MEMORY_BITMAP)){
((Bitmap&) from).convertToVideo();
if (&from == &who){
al_set_target_bitmap(who.getData()->getBitmap());
}
}
}
void changeTarget(const Bitmap * from, const Bitmap & who){
changeTarget(*from, who);
}
void changeTarget(const Bitmap & from, const Bitmap * who){
changeTarget(from, *who);
}
void changeTarget(const Bitmap * from, const Bitmap * who){
changeTarget(*from, *who);
}
enum Format{
PNG,
GIF,
};
void dumpColor(const Color & color){
unsigned char red, green, blue, alpha;
al_unmap_rgba(color, &red, &green, &blue, &alpha);
Global::debug(0) << "red " << (int) red << " green " << (int) green << " blue " << (int) blue << " alpha " << (int) alpha << std::endl;
}
Bitmap Bitmap::memoryPCX(unsigned char * const data, const int length, const bool mask){
ALLEGRO_FILE * memory = al_open_memfile((void *) data, length, "r");
ALLEGRO_BITMAP * pcx = al_load_bitmap_f(memory, ".pcx");
al_fclose(memory);
// dumpColor(al_get_pixel(pcx, 0, 0));
Bitmap out(pcx);
out.set8BitMaskColor(makeColorAlpha(255, 255, 255, 255));
return out;
}
static bool isVideoBitmap(ALLEGRO_BITMAP * bitmap){
return (al_get_bitmap_flags(bitmap) & ALLEGRO_VIDEO_BITMAP) &&
!(al_get_bitmap_flags(bitmap) & ALLEGRO_MEMORY_BITMAP);
}
void Bitmap::replaceColor(Color original, Color replaced){
changeTarget(this, this);
if (isVideoBitmap(getData()->getBitmap())){
al_lock_bitmap(getData()->getBitmap(), ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE);
}
for (int x = 0; x < getWidth(); x++){
for (int y = 0; y < getHeight(); y++){
Color pixel = getPixel(x, y);
if (pixel == original){
al_put_pixel(x, y, replaced);
}
}
}
if (isVideoBitmap(getData()->getBitmap())){
al_unlock_bitmap(getData()->getBitmap());
}
}
static ALLEGRO_BITMAP * memoryGIF(const char * data, int length){
ALLEGRO_FILE * memory = al_open_memfile((void *) data, length, "r");
al_fclose(memory);
/* FIXME: get gif addon for a5 */
#if 0
RGB * palette = NULL;
/* algif will close the packfile for us in both error and success cases */
BITMAP * gif = load_gif_packfile(pack, palette);
if (!gif){
al_fclose(memory);
// pack_fclose(pack);
ostringstream out;
out <<"Could not load gif from memory: " << (void*) data << " length " << length;
throw LoadException(__FILE__, __LINE__, out.str());
}
BITMAP * out = create_bitmap(gif->w, gif->h);
blit(gif, out, 0, 0, 0, 0, gif->w, gif->h);
destroy_bitmap(gif);
// pack_fclose(pack);
#endif
ALLEGRO_BITMAP * out = NULL;
return out;
}
void Bitmap::internalLoadFile(const char * path){
this->path = path;
ALLEGRO_BITMAP * loaded = al_load_bitmap(path);
if (loaded == NULL){
std::ostringstream out;
out << "Could not load file '" << path << "'";
throw BitmapException(__FILE__, __LINE__, out.str());
}
al_convert_mask_to_alpha(loaded, al_map_rgb(255, 0, 255));
setData(new BitmapData(loaded));
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(makeColor(0, 0, 0)){
Format type = GIF;
setData(new BitmapData(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);
setData(new BitmapData(sub));
own = new int;
*own = 1;
}
int Bitmap::getWidth() const {
if (getData()->getBitmap() != NULL){
return al_get_bitmap_width(getData()->getBitmap());
}
return 0;
}
int getRed(Color color){
unsigned char red, green, blue;
al_unmap_rgb(color, &red, &green, &blue);
return red;
}
int getGreen(Color color){
unsigned char red, green, blue;
al_unmap_rgb(color, &red, &green, &blue);
return green;
}
int getBlue(Color color){
unsigned char red, green, blue;
al_unmap_rgb(color, &red, &green, &blue);
return blue;
}
Color makeColor(int red, int blue, int green){
return al_map_rgb(red, blue, green);
}
int Bitmap::getHeight() const {
if (getData()->getBitmap() != NULL){
return al_get_bitmap_height(getData()->getBitmap());
}
return 0;
}
void initializeExtraStuff(){
// al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_RGB_565);
// allegroLock = new Util::Thread::LockObject();
}
int setGraphicsMode(int mode, int width, int height){
initializeExtraStuff();
switch (mode){
case FULLSCREEN: {
al_set_new_display_flags(ALLEGRO_FULLSCREEN);
break;
}
case WINDOWED: {
al_set_new_display_flags(ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE);
break;
}
default: break;
}
ALLEGRO_DISPLAY * display = al_create_display(width, height);
if (display == NULL){
std::ostringstream out;
out << "Could not create display with dimensions " << width << ", " << height;
throw BitmapException(__FILE__, __LINE__, out.str());
}
Screen = new Bitmap(al_get_backbuffer(display));
/* dont destroy the backbuffer */
Screen->getData()->setDestroy(false);
Scaler = new Bitmap(width, height);
/* default drawing mode */
al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
return 0;
}
void Bitmap::lock() const {
al_lock_bitmap(getData()->getBitmap(), ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE);
}
void Bitmap::lock(int x, int y, int width, int height) const {
al_lock_bitmap_region(getData()->getBitmap(), x, y, width, height, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE);
}
void Bitmap::unlock() const {
al_unlock_bitmap(getData()->getBitmap());
}
Color Bitmap::getPixel(const int x, const int y) const {
changeTarget(this, this);
return al_get_pixel(getData()->getBitmap(), x, y);
}
void Bitmap::putPixel(int x, int y, Color pixel) const {
changeTarget(this, this);
al_put_pixel(x, y, pixel);
}
void Bitmap::putPixelNormal(int x, int y, Color col) const {
putPixel(x, y, col);
}
void Bitmap::fill(Color color) const {
changeTarget(this, this);
al_clear_to_color(color);
}
void Bitmap::startDrawing() const {
}
void Bitmap::endDrawing() const {
}
void TranslucentBitmap::startDrawing() const {
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
}
void TranslucentBitmap::endDrawing() const {
al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
}
Color Bitmap::blendColor(const Color & input) const {
return input;
}
Color TranslucentBitmap::blendColor(const Color & color) const {
unsigned char red, green, blue;
unsigned char alpha = globalBlend.alpha;
al_unmap_rgb(color, &red, &green, &blue);
return makeColorAlpha(red, green, blue, alpha);
}
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 ){
changeTarget(this, where);
MaskedBlender blender;
al_draw_rotated_bitmap(getData()->getBitmap(), getWidth() / 2, getHeight() / 2, x, y, Util::radians(angle), ALLEGRO_FLIP_HORIZONTAL);
}
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 {
/* FIXME */
changeTarget(this, who);
MaskedBlender blender;
al_draw_scaled_bitmap(getData()->getBitmap(), 0, 0, getWidth(), getHeight(), x, y, new_width, new_height, 0);
#if 0
ALLEGRO_TRANSFORM save;
al_copy_transform(&save, al_get_current_transform());
ALLEGRO_TRANSFORM stretch;
al_identity_transform(&stretch);
// al_translate_transform(&stretch, x / ((double) new_width / getWidth()), y / ((double) new_height / getHeight()));
al_scale_transform(&stretch, (double) new_width / getWidth(), (double) new_height / getHeight());
al_translate_transform(&stretch, x, y);
// al_translate_transform(&stretch, -x / ((double) new_width / getWidth()), -y / ((double) (new_height / getHeight())));
al_use_transform(&stretch);
/* any source pixels with an alpha value of 0 will be masked */
// al_draw_bitmap(getData().getBitmap(), x, y, 0);
al_draw_bitmap(getData().getBitmap(), 0, 0, 0);
al_use_transform(&save);
#endif
}
void Bitmap::Blit(const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where) const {
// double start = al_get_time();
// changeTarget(this, where);
// al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
/*
if (&where != Screen){
al_draw_bitmap(getData().getBitmap(), wx, wy, 0);
}
*/
/* FIXME: deal with mx, my, width, height */
changeTarget(this, where);
Bitmap part(*this, mx, my, width, height);
// al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
al_draw_bitmap(part.getData()->getBitmap(), wx, wy, 0);
/*
double end = al_get_time();
Global::debug(0) << "Draw in " << (end - start) << " seconds" << std::endl;
*/
}
void Bitmap::drawHFlip(const int x, const int y, const Bitmap & where) const {
changeTarget(this, where);
MaskedBlender blender;
/* any source pixels with an alpha value of 0 will be masked */
al_draw_bitmap(getData()->getBitmap(), x, y, ALLEGRO_FLIP_HORIZONTAL);
}
void Bitmap::drawHFlip(const int x, const int y, Filter * filter, const Bitmap & where) const {
/* FIXME: deal with filter */
changeTarget(this, where);
MaskedBlender blender;
/* any source pixels with an alpha value of 0 will be masked */
al_draw_bitmap(getData()->getBitmap(), x, y, ALLEGRO_FLIP_HORIZONTAL);
}
void Bitmap::drawVFlip( const int x, const int y, const Bitmap & where ) const {
changeTarget(this, where);
MaskedBlender blender;
/* any source pixels with an alpha value of 0 will be masked */
al_draw_bitmap(getData()->getBitmap(), x, y, ALLEGRO_FLIP_VERTICAL);
}
void Bitmap::drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
/* FIXME: deal with filter */
changeTarget(this, where);
MaskedBlender blender;
/* any source pixels with an alpha value of 0 will be masked */
al_draw_bitmap(getData()->getBitmap(), x, y, ALLEGRO_FLIP_VERTICAL);
}
void Bitmap::drawHVFlip( const int x, const int y, const Bitmap & where ) const {
changeTarget(this, where);
MaskedBlender blender;
/* any source pixels with an alpha value of 0 will be masked */
al_draw_bitmap(getData()->getBitmap(), x, y, ALLEGRO_FLIP_VERTICAL | ALLEGRO_FLIP_HORIZONTAL);
}
void Bitmap::drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
/* FIXME: deal with filter */
changeTarget(this, where);
MaskedBlender blender;
/* any source pixels with an alpha value of 0 will be masked */
al_draw_bitmap(getData()->getBitmap(), x, y, ALLEGRO_FLIP_VERTICAL | ALLEGRO_FLIP_HORIZONTAL);
}
void Bitmap::BlitMasked(const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where) const {
/* TODO */
}
void Bitmap::BlitToScreen(const int upper_left_x, const int upper_left_y) const {
#if 0
if (getWidth() != Screen->getWidth() || getHeight() != Screen->getHeight()){
/*
this->Blit( upper_left_x, upper_left_y, *Buffer );
Buffer->Stretch(*Scaler);
Scaler->Blit(0, 0, 0, 0, *Screen);
*/
this->Stretch(*Scaler, 0, 0, getWidth(), getHeight(), upper_left_x, upper_left_y, Scaler->getWidth(), Scaler->getHeight());
Scaler->Blit(0, 0, 0, 0, *Screen);
} else {
this->Blit(upper_left_x, upper_left_y, *Screen);
}
#endif
/*
if (&where == Screen){
al_flip_display();
}
*/
changeTarget(this, Screen);
+ if (getData()->getBitmap() != Screen->getData()->getBitmap()){
+ Blit(*Screen);
+ }
al_flip_display();
}
void Bitmap::BlitAreaToScreen(const int upper_left_x, const int upper_left_y) const {
changeTarget(this, Screen);
+ /*
+ if (getData()->getBitmap() != Screen->getData()->getBitmap()){
+ Blit(upper_left_y, upper_left_y, *Screen);
+ }
+ */
al_flip_display();
}
void Bitmap::draw(const int x, const int y, const Bitmap & where) const {
// TransBlender blender;
changeTarget(this, where);
MaskedBlender blender;
/* any source pixels with an alpha value of 0 will be masked */
al_draw_bitmap(getData()->getBitmap(), x, y, 0);
}
void Bitmap::draw(const int x, const int y, Filter * filter, const Bitmap & where) const {
/* FIXME */
changeTarget(this, where);
MaskedBlender blender;
/* any source pixels with an alpha value of 0 will be masked */
al_draw_bitmap(getData()->getBitmap(), x, y, 0);
}
void Bitmap::hLine(const int x1, const int y, const int x2, const Color color) const {
line(x1, y, x2, y, color);
}
void Bitmap::vLine(const int y1, const int x, const int y2, const Color color) const {
line(x, y1, x, y2, color);
}
void Bitmap::arc(const int x, const int y, const double ang1, const double ang2, const int radius, const Color color ) const {
changeTarget(this, this);
al_draw_arc(x, y, radius, ang1 - Util::pi/2, ang2 - ang1, color, 1);
}
void TranslucentBitmap::arc(const int x, const int y, const double ang1, const double ang2, const int radius, const Color color ) const {
TransBlender blender;
Bitmap::arc(x, y, ang1, ang2, radius, transBlendColor(color));
/*
changeTarget(this);
al_draw_arc(x, y, radius, ang1 + S_PI/2, ang2 - ang1, doTransBlend(color, globalBlend.alpha), 0);
*/
}
/* from http://www.allegro.cc/forums/thread/605684/892721#target */
void al_draw_filled_pieslice(float cx, float cy, float r, float start_theta,
float delta_theta, ALLEGRO_COLOR color){
ALLEGRO_VERTEX vertex_cache[ALLEGRO_VERTEX_CACHE_SIZE];
int num_segments, ii;
num_segments = fabs(delta_theta / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * sqrtf(r));
if (num_segments < 2)
return;
if (num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) {
num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1;
}
al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, r, r, start_theta, delta_theta, 0, num_segments);
vertex_cache[0].x = cx; vertex_cache[0].y = cy;
for (ii = 0; ii < num_segments + 1; ii++) {
vertex_cache[ii].color = color;
vertex_cache[ii].z = 0;
}
al_draw_prim(vertex_cache, NULL, NULL, 0, num_segments + 1, ALLEGRO_PRIM_TRIANGLE_FAN);
// al_draw_prim(vertex_cache, NULL, NULL, 0, 3, ALLEGRO_PRIM_TRIANGLE_FAN);
}
void Bitmap::arcFilled(const int x, const int y, const double ang1, const double ang2, const int radius, const Color color ) const {
changeTarget(this, this);
al_draw_filled_pieslice(x, y, radius, ang1 - Util::pi/2, ang2 - ang1, color);
}
void TranslucentBitmap::arcFilled(const int x, const int y, const double ang1, const double ang2, const int radius, const Color color ) const {
TransBlender blender;
Bitmap::arcFilled(x, y, ang1, ang2, radius, transBlendColor(color));
}
void Bitmap::floodfill( const int x, const int y, const Color color ) const {
/* TODO */
}
void Bitmap::line(const int x1, const int y1, const int x2, const int y2, const Color color) const {
al_draw_line(x1, y1, x2, y2, color, 1.5);
}
void TranslucentBitmap::line(const int x1, const int y1, const int x2, const int y2, const Color color) const {
TransBlender blender;
Bitmap::line(x1, y1, x2, y2, transBlendColor(color));
}
void Bitmap::circleFill(int x, int y, int radius, Color color) const {
changeTarget(this, this);
al_draw_filled_circle(x, y, radius, color);
}
void Bitmap::circle(int x, int y, int radius, Color color) const {
changeTarget(this, this);
al_draw_circle(x, y, radius, color, 0);
}
void Bitmap::rectangle( int x1, int y1, int x2, int y2, Color color ) const {
changeTarget(this, this);
al_draw_rectangle(x1, y1, x2, y2, color, 0);
}
void Bitmap::rectangleFill( int x1, int y1, int x2, int y2, Color color ) const {
changeTarget(this, this);
al_draw_filled_rectangle(x1 - 0.5, y1 - 0.5, x2 + 0.5, y2 + 0.5, color);
}
void Bitmap::triangle( int x1, int y1, int x2, int y2, int x3, int y3, Color color ) const {
changeTarget(this, this);
al_draw_filled_triangle(x1, y1, x2, y2, x3, y3, color);
}
void Bitmap::polygon( const int * verts, const int nverts, const Color color ) const {
/* TODO */
}
void Bitmap::ellipse( int x, int y, int rx, int ry, Color color ) const {
changeTarget(this, this);
al_draw_ellipse(x, y, rx, ry, color, 0);
}
void Bitmap::ellipseFill( int x, int y, int rx, int ry, Color color ) const {
changeTarget(this, this);
al_draw_filled_ellipse(x, y, rx, ry, color);
}
void Bitmap::applyTrans(const Color color) const {
TransBlender blender;
changeTarget(this, this);
al_draw_filled_rectangle(0, 0, getWidth(), getHeight(), transBlendColor(color));
}
void Bitmap::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 {
/* 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<Color> & line, int y){
/* TODO */
}
void TranslucentBitmap::draw(const int x, const int y, const Bitmap & where) const {
changeTarget(this, where);
TransBlender blender;
al_draw_tinted_bitmap(getData()->getBitmap(), getBlendColor(), 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 {
changeTarget(this, where);
TransBlender blender;
al_draw_tinted_bitmap(getData()->getBitmap(), getBlendColor(), x, y, 0);
}
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 Color color ) const {
/* TODO */
}
void TranslucentBitmap::circleFill(int x, int y, int radius, Color color) const {
TransBlender blender;
Bitmap::circleFill(x, y, radius, doTransBlend(color, globalBlend.alpha));
}
void TranslucentBitmap::putPixelNormal(int x, int y, Color color) const {
TransBlender blender;
Bitmap::putPixelNormal(x, y, doTransBlend(color, globalBlend.alpha));
}
void TranslucentBitmap::rectangle( int x1, int y1, int x2, int y2, Color color ) const {
TransBlender blender;
Bitmap::rectangle(x1, y1, x2, y2, doTransBlend(color, globalBlend.alpha));
}
void TranslucentBitmap::rectangleFill(int x1, int y1, int x2, int y2, Color color) const {
TransBlender blender;
Bitmap::rectangleFill(x1, y1, x2, y2, doTransBlend(color, globalBlend.alpha));
}
void TranslucentBitmap::ellipse( int x, int y, int rx, int ry, Color color ) const {
TransBlender blender;
Bitmap::ellipse(x, y, rx, ry, doTransBlend(color, globalBlend.alpha));
}
Bitmap & Bitmap::operator=(const Bitmap & copy){
releaseInternalBitmap();
path = copy.getPath();
setData(copy.getData());
// 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(){
/*
if (al_get_target_bitmap() == getData()->getBitmap()){
al_set_target_bitmap(NULL);
}
al_destroy_bitmap(getData()->getBitmap());
*/
}
int setGfxModeFullscreen(int x, int y){
return setGraphicsMode(FULLSCREEN, x, y);
}
int setGfxModeWindowed( int x, int y ){
return setGraphicsMode(WINDOWED, x, y);
}
int setGfxModeText(){
/* TODO */
return 0;
}
bool Bitmap::getError(){
/* TODO */
return false;
}
void Bitmap::transBlender(int r, int g, int b, int a){
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
globalBlend.type = Translucent;
}
void Bitmap::addBlender(int r, int g, int b, int a){
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
globalBlend.type = Add;
}
void Bitmap::differenceBlender( int r, int g, int b, int a ){
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
globalBlend.type = Difference;
}
void Bitmap::multiplyBlender( int r, int g, int b, int a ){
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
globalBlend.type = Multiply;
}
void Bitmap::drawingMode(int type){
/* TODO */
}
void Bitmap::shutdown(){
delete Screen;
Screen = NULL;
// delete allegroLock;
// allegroLock = NULL;
/*
delete Scaler;
Scaler = NULL;
delete Buffer;
Buffer = NULL;
*/
}
StretchedBitmap::StretchedBitmap(int width, int height, const Bitmap & parent):
Bitmap(parent, 0, 0, parent.getWidth(), parent.getHeight()),
width(width),
height(height),
where(parent){
scale_x = (double) parent.getWidth() / width;
scale_y = (double) parent.getHeight() / height;
al_set_target_bitmap(parent.getData()->getBitmap());
ALLEGRO_TRANSFORM transform;
al_identity_transform(&transform);
if (al_get_current_transform() != NULL){
al_copy_transform(&transform, al_get_current_transform());
}
al_scale_transform(&transform, scale_x, scale_y);
al_set_target_bitmap(getData()->getBitmap());
al_use_transform(&transform);
}
void StretchedBitmap::start(){
#if 0
ALLEGRO_TRANSFORM transform;
changeTarget(this, this);
al_copy_transform(&transform, al_get_current_transform());
// al_identity_transform(&transform);
// al_scale_transform(&transform, Bitmap::getWidth() / width, Bitmap::getHeight() / height);
al_scale_transform(&transform, scale_x, scale_y);
al_use_transform(&transform);
#endif
}
void StretchedBitmap::finish(){
#if 0
ALLEGRO_TRANSFORM transform;
changeTarget(this, this);
al_copy_transform(&transform, al_get_current_transform());
/* apply the inverse transform */
al_scale_transform(&transform, 1.0/scale_x, 1.0/scale_y);
// al_identity_transform(&transform);
al_use_transform(&transform);
#endif
}
TranslatedBitmap::TranslatedBitmap(int x, int y, const Bitmap & where):
Bitmap(where),
x(x),
y(y){
ALLEGRO_TRANSFORM transform;
changeTarget(this, where);
al_identity_transform(&transform);
if (al_get_current_transform() != NULL){
al_copy_transform(&transform, al_get_current_transform());
}
al_translate_transform(&transform, x, y);
al_use_transform(&transform);
}
void TranslatedBitmap::BlitToScreen() const {
Bitmap::BlitToScreen();
}
TranslatedBitmap::~TranslatedBitmap(){
ALLEGRO_TRANSFORM transform;
al_copy_transform(&transform, al_get_current_transform());
al_translate_transform(&transform, -x, -y);
al_use_transform(&transform);
}
Bitmap getScreenBuffer(){
return *Screen;
}
void resetDisplay(){
// al_set_target_bitmap(Screen->getData().getBitmap());
// changeTarget(Screen);
}
RestoreState::RestoreState(){
al_store_state(&state, ALLEGRO_STATE_ALL);
}
RestoreState::~RestoreState(){
al_restore_state(&state);
}
}
static bool sameColor(Graphics::Color color1, Graphics::Color color2){
unsigned char r1, g1, b1, a1;
unsigned char r2, g2, b2, a2;
al_unmap_rgba(color1, &r1, &g1, &b1, &a1);
al_unmap_rgba(color2, &r2, &g2, &b2, &a2);
return r1 == r2 &&
g1 == g2 &&
b1 == b2 &&
a1 == a2;
}
static uint32_t quantify(const ALLEGRO_COLOR & color){
unsigned char red, green, blue, alpha;
al_unmap_rgba(color, &red, &green, &blue, &alpha);
return (red << 24) |
(green << 16) |
(blue << 8) |
alpha;
}
bool operator<(const ALLEGRO_COLOR color1, const ALLEGRO_COLOR color2){
return quantify(color1) < quantify(color2);
}
bool operator!=(const ALLEGRO_COLOR color1, const ALLEGRO_COLOR color2){
return !(color1 == color2);
}
bool operator==(const ALLEGRO_COLOR color1, const ALLEGRO_COLOR color2){
return sameColor(color1, color2);
}
diff --git a/util/loading.cpp b/util/loading.cpp
index 9422f8c1..39d40049 100644
--- a/util/loading.cpp
+++ b/util/loading.cpp
@@ -1,500 +1,498 @@
#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;
Graphics::resetDisplay();
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(), 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);
Graphics::resetDisplay();
#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);
}
}
}

File Metadata

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

Event Timeline