Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
31 KB
Referenced Files
None
Subscribers
None
diff --git a/util/init.cpp b/util/init.cpp
new file mode 100644
index 00000000..68d5fc1e
--- /dev/null
+++ b/util/init.cpp
@@ -0,0 +1,417 @@
+#ifdef USE_ALLEGRO
+#include <allegro.h>
+#ifdef ALLEGRO_WINDOWS
+#include <winalleg.h>
+#endif
+#endif
+
+#ifdef USE_SDL
+#include <SDL.h>
+#endif
+
+#ifndef WINDOWS
+#include <signal.h>
+#include <string.h>
+#endif
+
+/* don't be a boring tuna */
+// #warning you are ugly
+
+#include "globals.h"
+#include "init.h"
+#include "network/network.h"
+#include "util/thread.h"
+#include <time.h>
+
+#include <ostream>
+#include "util/dumb/include/dumb.h"
+#ifdef USE_ALLEGRO
+#include "util/dumb/include/aldumb.h"
+#include "util/loadpng/loadpng.h"
+#include "util/gif/algif.h"
+#endif
+#include "util/bitmap.h"
+#include "util/funcs.h"
+#include "util/file-system.h"
+#include "util/font.h"
+#include "util/sound.h"
+#include "configuration.h"
+#include "script/script.h"
+#include "util/music.h"
+#include "util/loading.h"
+
+#ifdef WII
+#include <fat.h>
+#endif
+
+using namespace std;
+
+volatile int Global::speed_counter = 0;
+
+/* enough seconds for 136 years */
+volatile unsigned int Global::second_counter = 0;
+
+/* the original engine was running at 90 ticks per second, but we dont
+ * need to render that fast, so TICS_PER_SECOND is really fps and
+ * LOGIC_MULTIPLIER will be used to adjust the speed counter to its
+ * original value.
+ */
+const int Global::TICS_PER_SECOND = 40;
+const double Global::LOGIC_MULTIPLIER = (double) 90 / (double) Global::TICS_PER_SECOND;
+
+
+#ifdef USE_ALLEGRO
+const int Global::WINDOWED = GFX_AUTODETECT_WINDOWED;
+const int Global::FULLSCREEN = GFX_AUTODETECT_FULLSCREEN;
+#else
+/* FIXME: use enums here or something */
+const int Global::WINDOWED = 0;
+const int Global::FULLSCREEN = 1;
+#endif
+
+/* game counter, controls FPS */
+static void inc_speed_counter(){
+ /* probably put input polling here, InputManager::poll() */
+ Global::speed_counter += 1;
+}
+#ifdef USE_ALLEGRO
+END_OF_FUNCTION( inc_speed_counter )
+#endif
+
+/* if you need to count seconds for some reason.. */
+static void inc_second_counter() {
+ Global::second_counter += 1;
+}
+#ifdef USE_ALLEGRO
+END_OF_FUNCTION( inc_second_counter )
+#endif
+
+#if !defined(WINDOWS) && !defined(WII) && !defined(MINPSPW) && !defined(NDS)
+static void handleSigSegV(int i, siginfo_t * sig, void * data){
+ const char * message = "Bug! Caught a memory violation. Shutting down..\n";
+ int dont_care = write(1, message, 48);
+ dont_care = dont_care;
+ // Global::shutdown_message = "Bug! Caught a memory violation. Shutting down..";
+ Bitmap::setGfxModeText();
+#ifdef USE_ALLEGRO
+ allegro_exit();
+#endif
+ /* write to a log file or something because sigsegv shouldn't
+ * normally happen.
+ */
+ exit(1);
+}
+#else
+#endif
+
+/* catch a socket being closed prematurely on unix */
+#if !defined(WINDOWS) && !defined(WII) && !defined(MINPSPW) && !defined(NDS)
+static void handleSigPipe( int i, siginfo_t * sig, void * data ){
+}
+
+/*
+static void handleSigUsr1( int i, siginfo_t * sig, void * data ){
+ pthread_exit( NULL );
+}
+*/
+#endif
+
+static void registerSignals(){
+#if !defined(WINDOWS) && !defined(WII) && !defined(MINPSPW) && !defined(NDS)
+ struct sigaction action;
+ memset( &action, 0, sizeof(struct sigaction) );
+ action.sa_sigaction = handleSigPipe;
+ sigaction( SIGPIPE, &action, NULL );
+
+ memset( &action, 0, sizeof(struct sigaction) );
+ action.sa_sigaction = handleSigSegV;
+ sigaction( SIGSEGV, &action, NULL );
+
+ /*
+ action.sa_sigaction = handleSigUsr1;
+ sigaction( SIGUSR1, &action, NULL );
+ */
+#endif
+}
+
+/* should probably call the janitor here or something */
+static void close_paintown(){
+ Music::pause();
+ Bitmap::setGfxModeText();
+#ifdef USE_ALLEGRO
+ allegro_exit();
+#endif
+ exit(0);
+}
+
+namespace Global{
+ extern int do_shutdown;
+}
+
+static void close_window(){
+ /* when do_shutdown is 1 the game will attempt to throw ShutdownException
+ * wherever it is. If the game is stuck or the code doesn't throw
+ * ShutdownException then when the user tries to close the window
+ * twice we just forcifully shutdown.
+ */
+ Global::do_shutdown += 1;
+ if (Global::do_shutdown == 2){
+ close_paintown();
+ }
+}
+#ifdef USE_ALLEGRO
+END_OF_FUNCTION(close_window)
+#endif
+
+#ifdef USE_ALLEGRO
+static void initSystem(ostream & out){
+ out << "Allegro version: " << ALLEGRO_VERSION_STR << endl;
+ out << "Allegro init: " <<allegro_init()<<endl;
+ out << "Install timer: " <<install_timer()<<endl;
+
+ /* png */
+ loadpng_init();
+ algif_init();
+
+ out<<"Install keyboard: "<<install_keyboard()<<endl;
+ /* do we need the mouse?? */
+ // out<<"Install mouse: "<<install_mouse()<<endl;
+ out<<"Install joystick: "<<install_joystick(JOY_TYPE_AUTODETECT)<<endl;
+ /* 16 bit color depth */
+ set_color_depth(16);
+
+ LOCK_VARIABLE( speed_counter );
+ LOCK_VARIABLE( second_counter );
+ LOCK_FUNCTION( (void *)inc_speed_counter );
+ LOCK_FUNCTION( (void *)inc_second_counter );
+ /* set up the timers */
+ out<<"Install game timer: "<< install_int_ex(inc_speed_counter, BPS_TO_TIMER(Global::TICS_PER_SECOND))<<endl;
+ out<<"Install second timer: "<<install_int_ex(inc_second_counter, BPS_TO_TIMER(1))<<endl;
+
+ /* keep running in the background */
+ set_display_switch_mode(SWITCH_BACKGROUND);
+
+ /* close window when the X is pressed */
+ LOCK_FUNCTION(close_window);
+ set_close_button_callback(close_window);
+}
+
+#endif
+#ifdef USE_SDL
+
+// static pthread_t events;
+
+struct TimerInfo{
+ TimerInfo(void (*x)(), int y):
+ tick(x), frequency(y){}
+
+ void (*tick)();
+ int frequency;
+};
+
+static void * do_timer(void * arg){
+ TimerInfo info = *(TimerInfo *) arg;
+ uint32_t delay = (uint32_t)(1000.0 / (double) info.frequency);
+
+ /* assuming SDL_GetTicks() starts at 0, this should last for about 50 days
+ * before overflowing. overflow should work out fine. Assuming activate occurs
+ * when the difference between now and ticks is at least 6, the following will happen.
+ * ticks now now-ticks
+ * 4294967294 4294967294 0
+ * 4294967294 4294967295 1
+ * 4294967294 0 2
+ * 4294967294 1 3
+ * 4294967294 2 4
+ * 4294967294 3 5
+ * 4294967294 4 6
+ * Activate
+ * 3 5 2
+ * 3 6 3
+ * 3 7 4
+ * 3 8 5
+ * 3 9 6
+ * Activate
+ *
+ * Can 'now' ever be much larger than 'ticks' due to overflow?
+ * It doesn't seem like it.
+ */
+ uint32_t ticks = SDL_GetTicks();
+
+ /* TODO: pass in some variable that tells this loop to quit */
+ while (true){
+ uint32_t now = SDL_GetTicks();
+ while (now - ticks >= delay){
+ // Global::debug(0) << "Tick!" << endl;
+ info.tick();
+ ticks += delay;
+ }
+ SDL_Delay(1);
+ }
+
+ delete (TimerInfo *) arg;
+
+ return NULL;
+}
+
+static Util::Thread::Id start_timer(void (*func)(), int frequency){
+ TimerInfo * speed = new TimerInfo(func, frequency);
+ /*
+ speed.tick = func;
+ speed.frequency = frequency;
+*/
+ Util::Thread::Id thread;
+ Util::Thread::createThread(&thread, NULL, (Util::Thread::ThreadFunction) do_timer, (void*) speed);
+ return thread;
+}
+
+#if 0
+static void * handleEvents(void * arg){
+ bool done = false;
+ while (!done){
+ SDL_Event event;
+ int ok = SDL_WaitEvent(&event);
+ if (ok){
+ switch (event.type){
+ case SDL_QUIT : {
+ done = true;
+ close_window();
+ break;
+ }
+ default : {
+ // Global::debug(0) << "Ignoring SDL event " << event.type << endl;
+ break;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+#endif
+
+/*
+static void doSDLQuit(){
+ SDL_Event quit;
+ quit.type = SDL_QUIT;
+ SDL_PushEvent(&quit);
+ Global::debug(0) << "Waiting for SDL event handler to finish" << endl;
+ pthread_join(events, NULL);
+ SDL_Quit();
+}
+*/
+
+static void initSystem(ostream & out){
+ out << "SDL Init: ";
+ int ok = SDL_Init(SDL_INIT_VIDEO |
+ SDL_INIT_AUDIO |
+ SDL_INIT_TIMER |
+ SDL_INIT_JOYSTICK |
+ SDL_INIT_NOPARACHUTE);
+ if (ok == 0){
+ out << "Ok" << endl;
+ } else {
+ out << "Failed (" << ok << ") - " << SDL_GetError() << endl;
+ exit(ok);
+ }
+
+ /* Just do SDL thread init
+#ifdef MINPSPW
+ pthread_init();
+#endif
+*/
+
+ start_timer(inc_speed_counter, Global::TICS_PER_SECOND);
+ start_timer(inc_second_counter, 1);
+
+ try{
+ SDL_Surface * icon = SDL_LoadBMP(Filesystem::find(Filesystem::RelativePath("menu/icon.bmp")).path().c_str());
+ if (icon != NULL){
+ SDL_WM_SetIcon(icon, NULL);
+ }
+ } catch (const Filesystem::NotFound & failed){
+ Global::debug(0) << "Could not find window icon: " << failed.getTrace() << endl;
+ }
+
+ SDL_WM_SetCaption("Paintown", NULL);
+
+ SDL_EnableUNICODE(1);
+ SDL_JoystickEventState(1);
+ SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+
+ atexit(SDL_Quit);
+ // atexit(doSDLQuit);
+}
+#endif
+
+bool Global::init(int gfx){
+
+ ostream & out = Global::debug( 0 );
+ out << "-- BEGIN init --" << endl;
+ out << "Data path is " << Util::getDataPath2().path() << endl;
+ out << "Paintown version " << Global::getVersionString() << endl;
+ out << "Build date " << __DATE__ << " " << __TIME__ << endl;
+
+#ifdef WII
+ fatInitDefault();
+#endif
+
+ /* do implementation specific setup */
+ initSystem(out);
+
+ dumb_register_stdfiles();
+
+ Sound::initialize();
+
+ Bitmap::SCALE_X = GFX_X;
+ Bitmap::SCALE_Y = GFX_Y;
+
+ Configuration::loadConfigurations();
+ const int sx = Configuration::getScreenWidth();
+ const int sy = Configuration::getScreenHeight();
+ if (gfx == -1){
+ gfx = Configuration::getFullscreen() ? Global::FULLSCREEN : Global::WINDOWED;
+ } else {
+ Configuration::setFullscreen(gfx == Global::FULLSCREEN);
+ }
+
+ /* set up the screen */
+ int gfxCode = Bitmap::setGraphicsMode(gfx, sx, sy);
+ if (gfxCode == 0){
+ out << "Set graphics mode: Ok" << endl;
+ } else {
+ out << "Set graphics mode: Failed! (" << gfxCode << ")" << endl;
+ return false;
+ }
+
+ /* music */
+ atexit(&dumb_exit);
+
+ out << "Initialize random number generator" << endl;
+ /* initialize random number generator */
+ srand(time(NULL));
+
+ registerSignals();
+
+#ifdef HAVE_NETWORKING
+ out << "Initialize network" << endl;
+ Network::init();
+ atexit(Network::closeAll);
+#endif
+
+ /* this mutex is used to show the loading screen while the game loads */
+ // Util::Thread::initializeLock(&Loader::loading_screen_mutex);
+
+ out << "-- END init --" << endl;
+
+ /*
+ const Font & font = Font::getDefaultFont();
+ // font.setSize(30, 30);
+ Bitmap temp(font.textLength("Loading") + 1, font.getHeight("Loading") + 1);
+ font.printf(0, 0, Bitmap::makeColor(255, 255, 255), temp, "Loading", 0);
+ temp.BlitToScreen(sx / 2, sy / 2);
+ */
+ Bitmap white(sx, sy);
+ white.fill(Bitmap::makeColor(255, 255, 255));
+ white.BlitToScreen();
+
+ return true;
+}
diff --git a/util/init.h b/util/init.h
new file mode 100644
index 00000000..0516b3a8
--- /dev/null
+++ b/util/init.h
@@ -0,0 +1,27 @@
+#ifndef _paintown_init_h
+#define _paintown_init_h
+
+/* global vars */
+
+#define GFX_X 640
+#define GFX_Y 480
+
+namespace Global{
+ extern volatile int speed_counter;
+ extern volatile unsigned int second_counter;
+
+ extern const double LOGIC_MULTIPLIER;
+ extern const int TICS_PER_SECOND;
+
+ extern const int WINDOWED;
+ extern const int FULLSCREEN;
+
+ bool init( int gfx );
+}
+
+/*
+#define GFX_X 320
+#define GFX_Y 240
+*/
+
+#endif
diff --git a/util/loading.cpp b/util/loading.cpp
index c9d08d3b..ff7d9457 100644
--- a/util/loading.cpp
+++ b/util/loading.cpp
@@ -1,529 +1,529 @@
-#include "util/bitmap.h"
-#include "util/trans-bitmap.h"
+#include "bitmap.h"
+#include "trans-bitmap.h"
#include <math.h>
#include <iostream>
#include "level/utils.h"
-#include "util/messages.h"
+#include "messages.h"
#include "loading.h"
-#include "util/file-system.h"
-#include "util/font.h"
-#include "util/funcs.h"
-#include "util/gradient.h"
-#include "util/thread.h"
+#include "file-system.h"
+#include "font.h"
+#include "funcs.h"
+#include "gradient.h"
+#include "thread.h"
#include "globals.h"
#include <vector>
-#include "util/thread.h"
-#include "util/message-queue.h"
+#include "thread.h"
+#include "message-queue.h"
#include "init.h"
using namespace std;
namespace Loader{
// Util::Thread::Lock loading_screen_mutex;
volatile bool done_loading = true;
typedef struct pair{
int x, y;
} ppair;
class Info{
public:
Info(){
Global::registerInfo(&messages);
}
bool transferMessages(Messages & box){
bool did = false;
while (messages.hasAny()){
const string & str = messages.get();
box.addMessage(str);
did = true;
}
return did;
}
~Info(){
Global::unregisterInfo(&messages);
}
private:
MessageQueue messages;
};
void * loadingScreenSimple1(void * arg);
#if 0
void startLoading(Util::Thread::Id * thread, void * arg, Kind kind){
bool create = false;
Util::Thread::acquireLock(&loading_screen_mutex);
create = done_loading;
done_loading = false;
Util::Thread::releaseLock(&loading_screen_mutex);
/* prevent multiple loading threads from being made */
if (create){
switch (kind){
case Default: Util::Thread::createThread(thread, NULL, (Util::Thread::ThreadFunction) loadingScreen, arg); break;
case SimpleCircle: Util::Thread::createThread(thread, NULL, (Util::Thread::ThreadFunction) loadingScreenSimple1, arg); break;
}
}
}
void stopLoading(Util::Thread::Id thread){
bool needJoin = false;
Util::Thread::acquireLock( &loading_screen_mutex );
needJoin = ! done_loading;
done_loading = true;
Util::Thread::releaseLock( &loading_screen_mutex );
if (needJoin){
Util::Thread::joinThread(thread);
}
}
#endif
static void setupBackground(const Bitmap & background, int load_x, int load_y, int load_width, int load_height, int infobox_x, int infobox_y, int infoWidth, int infoHeight, const Bitmap & infoBackground, const Bitmap & work){
background.Blit(load_x, load_y, load_width, load_height, 0, 0, work);
Font::getDefaultFont().printf( 400, 480 - Font::getDefaultFont().getHeight() * 5 / 2 - Font::getDefaultFont().getHeight(), Bitmap::makeColor( 192, 192, 192 ), background, "Paintown version %s", 0, Global::getVersionString().c_str());
Font::getDefaultFont().printf( 400, 480 - Font::getDefaultFont().getHeight() * 5 / 2, Bitmap::makeColor( 192, 192, 192 ), background, "Made by Jon Rafkind", 0 );
background.BlitToScreen();
background.Blit(infobox_x, infobox_y, infoWidth, infoHeight, 0, 0, infoBackground);
}
static vector<ppair> generateFontPixels(const Font & myFont, const string & message, int width, int height){
Bitmap letters(width, height);
letters.fill( Bitmap::MaskColor() );
myFont.printf( 0, 0, Bitmap::makeColor(255, 255, 255), letters, message.c_str(), 0 );
vector< ppair > pairs;
/* store every pixel we need to draw */
for ( int x = 0; x < letters.getWidth(); x++ ){
for ( int y = 0; y < letters.getHeight(); y++ ){
int pixel = letters.getPixel(x, y);
if (pixel != Bitmap::MaskColor()){
ppair p;
p.x = x;
p.y = y;
pairs.push_back( p );
}
}
}
return pairs;
}
/* shows time elapsed */
class TimeCounter{
public:
TimeCounter():
work(200, 40){
start = Global::second_counter;
last = 0;
}
void draw(int x, int y){
const Font & font = Font::getDefaultFont(24, 24);
if (Global::second_counter != last){
work.clear();
last = Global::second_counter;
font.printf(0, 0, Bitmap::makeColor(192, 192, 192), work, "Waiting.. %d", 0, last - start);
work.BlitAreaToScreen(x, y);
}
}
Bitmap work;
unsigned int start;
unsigned int last;
};
/* FIXME: get rid of this method */
#if 0
void * loadingScreen(void * arg){
int load_x = 80;
int load_y = 220;
const int infobox_width = 300;
const int infobox_height = 150;
Info info;
const Font & myFont = Font::getFont(Global::DEFAULT_FONT, 24, 24);
const Font & infoFont = Font::getFont(Global::DEFAULT_FONT, 24, 24);
Level::LevelInfo levelInfo;
if (arg != NULL){
levelInfo = *(Level::LevelInfo*) arg;
}
if (levelInfo.getPositionX() != -1){
load_x = levelInfo.getPositionX();
}
if (levelInfo.getPositionY() != -1){
load_y = levelInfo.getPositionY();
}
// const char * the_string = (arg != NULL) ? (const char *) arg : "Loading...";
int load_width = myFont.textLength(levelInfo.loadingMessage().c_str());
int load_height = myFont.getHeight(levelInfo.loadingMessage().c_str());
const int infobox_x = load_x;
const int infobox_y = load_y + load_height * 2;
Global::debug( 2 ) << "loading screen" << endl;
Bitmap work( load_width, load_height );
vector<ppair> pairs = generateFontPixels(myFont, levelInfo.loadingMessage(), load_width, load_height);
Messages infobox(infobox_width, infobox_height);
Bitmap infoWork(infobox_width, infobox_height);
Bitmap infoBackground(infobox_width, infobox_height);
const int MAX_COLOR = 200;
/* blend from dark grey to light red */
Effects::Gradient gradient(MAX_COLOR, Bitmap::makeColor(16, 16, 16), Bitmap::makeColor(192, 8, 8));
Global::speed_counter = 0;
if (levelInfo.getBackground() != 0){
setupBackground(*levelInfo.getBackground(), load_x, load_y, load_width, load_height, infobox_x, infobox_y, infoBackground.getWidth(), infoBackground.getHeight(), infoBackground, work);
} else {
setupBackground(Bitmap(levelInfo.loadingBackground().path()), load_x, load_y, load_width, load_height, infobox_x, infobox_y, infoBackground.getWidth(), infoBackground.getHeight(), infoBackground, work);
}
Util::ThreadBoolean quit(done_loading, loading_screen_mutex);
TimeCounter counter;
bool firstDraw = true;
while ( ! quit.get() ){
/* true if a logic loop has passed */
bool draw = firstDraw;
/* will be true if any new info messages appeared */
bool drawInfo = firstDraw;
firstDraw = false;
if ( Global::speed_counter > 0 ){
double think = Global::speed_counter;
Global::speed_counter = 0;
draw = true;
while ( think > 0 ){
gradient.backward();
think -= 1;
}
/* if no new messages appeared this will be false */
drawInfo = info.transferMessages(infobox);
} else {
Util::rest( 1 );
}
if (draw){
for ( vector< ppair >::iterator it = pairs.begin(); it != pairs.end(); it++ ){
int color = gradient.current(it->x);
work.putPixel(it->x, it->y, color);
}
// counter.draw(200, 100);
/* we might not have to draw the whole info box again if no new
* messages appeared.
*/
if (drawInfo){
infoBackground.Blit(infoWork);
/* cheesy hack to change the font size. the font
* should store the size and change it on its own
*/
Font::getFont(Global::DEFAULT_FONT, 13, 13);
infobox.draw(0, 0, infoWork, infoFont);
Font::getFont(Global::DEFAULT_FONT, 24, 24);
infoWork.BlitAreaToScreen(infobox_x, infobox_y);
}
/* work already contains the correct background */
// work.Blit( load_x, load_y, *Bitmap::Screen );
work.BlitAreaToScreen(load_x, load_y);
}
}
return NULL;
}
#endif
static void loadingScreen1(LoadingContext & context, const Level::LevelInfo & levelInfo){
int load_x = 80;
int load_y = 220;
const int infobox_width = 300;
const int infobox_height = 150;
Info info;
const Font & myFont = Font::getFont(Global::DEFAULT_FONT, 24, 24);
const Font & infoFont = Font::getFont(Global::DEFAULT_FONT, 24, 24);
if (levelInfo.getPositionX() != -1){
load_x = levelInfo.getPositionX();
}
if (levelInfo.getPositionY() != -1){
load_y = levelInfo.getPositionY();
}
// const char * the_string = (arg != NULL) ? (const char *) arg : "Loading...";
int load_width = myFont.textLength(levelInfo.loadingMessage().c_str());
int load_height = myFont.getHeight(levelInfo.loadingMessage().c_str());
const int infobox_x = load_x;
const int infobox_y = load_y + load_height * 2;
Global::debug(2) << "loading screen" << endl;
Bitmap work(load_width, load_height);
vector<ppair> pairs = generateFontPixels(myFont, levelInfo.loadingMessage(), load_width, load_height);
Messages infobox(infobox_width, infobox_height);
Bitmap infoWork(infobox_width, infobox_height);
Bitmap infoBackground(infobox_width, infobox_height);
const int MAX_COLOR = 200;
/* blend from dark grey to light red */
Effects::Gradient gradient(MAX_COLOR, Bitmap::makeColor(16, 16, 16), Bitmap::makeColor(192, 8, 8));
Global::speed_counter = 0;
if (levelInfo.getBackground() != 0){
setupBackground(*levelInfo.getBackground(), load_x, load_y, load_width, load_height, infobox_x, infobox_y, infoBackground.getWidth(), infoBackground.getHeight(), infoBackground, work);
} else {
setupBackground(Bitmap(levelInfo.loadingBackground().path()), load_x, load_y, load_width, load_height, infobox_x, infobox_y, infoBackground.getWidth(), infoBackground.getHeight(), infoBackground, work);
}
TimeCounter counter;
bool firstDraw = true;
while (! context.done()){
/* true if a logic loop has passed */
bool draw = firstDraw;
/* will be true if any new info messages appeared */
bool drawInfo = firstDraw;
firstDraw = false;
if ( Global::speed_counter > 0 ){
double think = Global::speed_counter;
Global::speed_counter = 0;
draw = true;
while ( think > 0 ){
gradient.backward();
think -= 1;
}
/* if no new messages appeared this will be false */
drawInfo = info.transferMessages(infobox);
} else {
Util::rest( 1 );
}
if (draw){
for ( vector< ppair >::iterator it = pairs.begin(); it != pairs.end(); it++ ){
int color = gradient.current(it->x);
work.putPixel(it->x, it->y, color);
}
// counter.draw(200, 100);
/* we might not have to draw the whole info box again if no new
* messages appeared.
*/
if (drawInfo){
infoBackground.Blit(infoWork);
/* cheesy hack to change the font size. the font
* should store the size and change it on its own
*/
Font::getFont(Global::DEFAULT_FONT, 13, 13);
infobox.draw(0, 0, infoWork, infoFont);
Font::getFont(Global::DEFAULT_FONT, 24, 24);
infoWork.BlitAreaToScreen(infobox_x, infobox_y);
}
/* work already contains the correct background */
// work.Blit( load_x, load_y, *Bitmap::Screen );
work.BlitAreaToScreen(load_x, load_y);
}
}
}
/* shows some circles rotating around a center point */
/* FIXME: get rid of this method */
#if 0
void * loadingScreenSimple1(void * arg){
Bitmap work(40, 40);
Bitmap original(40, 40);
original.BlitFromScreen(0, 0);
Util::ThreadBoolean quit(done_loading, loading_screen_mutex);
Global::speed_counter = 0;
int angle = 0;
int color1 = Bitmap::makeColor(0, 0, 0);
int color2 = Bitmap::makeColor(0x00, 0x99, 0xff);
int color3 = Bitmap::makeColor(0xff, 0x22, 0x33);
int color4 = Bitmap::makeColor(0x44, 0x77, 0x33);
/* the length of this array is the number of circles to show */
int colors[4] = {color1, color2, color3, color4};
Bitmap::transBlender(0, 0, 0, 64);
/* speed of rotation */
int speed = 7;
while (! quit.get()){
bool draw = false;
if (Global::speed_counter > 0){
double think = Global::speed_counter;
Global::speed_counter = 0;
draw = true;
while (think > 0){
angle += speed;
think -= 1;
}
} else {
Util::rest(1);
}
if (draw){
int max = sizeof(colors) / sizeof(int);
double middleX = work.getWidth() / 2;
double middleY = work.getHeight() / 2;
original.Blit(work);
for (int i = 0; i < max; i++){
double x = cos(Util::radians(angle + 360 / max * i)) * 15;
double y = sin(Util::radians(angle + 360 / max * i)) * 15;
/* ghost circle */
work.translucent().circleFill(middleX + x, middleY + y, 2, colors[i]);
x = cos(Util::radians(angle + speed + 360 / max * i)) * 15;
y = sin(Util::radians(angle + speed + 360 / max * i)) * 15;
/* real circle */
work.circleFill(middleX + x, middleY + y, 2, colors[i]);
}
work.BlitAreaToScreen(0, 0);
}
}
return NULL;
}
#endif
static void loadingScreenSimpleX1(LoadingContext & context, const Level::LevelInfo & levelInfo){
Bitmap work(40, 40);
Bitmap original(40, 40);
original.BlitFromScreen(0, 0);
Global::speed_counter = 0;
int angle = 0;
int color1 = Bitmap::makeColor(0, 0, 0);
int color2 = Bitmap::makeColor(0x00, 0x99, 0xff);
int color3 = Bitmap::makeColor(0xff, 0x22, 0x33);
int color4 = Bitmap::makeColor(0x44, 0x77, 0x33);
/* the length of this array is the number of circles to show */
int colors[4] = {color1, color2, color3, color4};
Bitmap::transBlender(0, 0, 0, 64);
/* speed of rotation */
int speed = 7;
while (! context.done()){
bool draw = false;
if (Global::speed_counter > 0){
double think = Global::speed_counter;
Global::speed_counter = 0;
draw = true;
while (think > 0){
angle += speed;
think -= 1;
}
} else {
Util::rest(1);
}
if (draw){
int max = sizeof(colors) / sizeof(int);
double middleX = work.getWidth() / 2;
double middleY = work.getHeight() / 2;
original.Blit(work);
for (int i = 0; i < max; i++){
double x = cos(Util::radians(angle + 360 / max * i)) * 15;
double y = sin(Util::radians(angle + 360 / max * i)) * 15;
/* ghost circle */
work.translucent().circleFill(middleX + x, middleY + y, 2, colors[i]);
x = cos(Util::radians(angle + speed + 360 / max * i)) * 15;
y = sin(Util::radians(angle + speed + 360 / max * i)) * 15;
/* real circle */
work.circleFill(middleX + x, middleY + y, 2, colors[i]);
}
work.BlitAreaToScreen(0, 0);
}
}
}
LoadingContext::LoadingContext():
finished(false){
Util::Thread::initializeLock(&lock);
}
LoadingContext::~LoadingContext(){
}
void LoadingContext::doLoad(){
this->load();
Util::Thread::acquireLock(&lock);
finished = true;
Util::Thread::releaseLock(&lock);
}
bool LoadingContext::done(){
bool ok = false;
Util::Thread::acquireLock(&lock);
ok = this->finished;
Util::Thread::releaseLock(&lock);
return ok;
}
void * LoadingContext::load_it(void * arg){
LoadingContext * context = (LoadingContext*) arg;
context->doLoad();
return NULL;
}
static void showLoadMessage(){
int screenX = 80;
int screenY = 50;
Bitmap work(110, 50);
work.BlitFromScreen(screenX, screenY);
Bitmap top(110, 50);
top.fill(Bitmap::makeColor(0, 0, 0));
Font::getDefaultFont(25, 25).printf(10, 5, Bitmap::makeColor(192, 192, 192), top, "Loading", 0);
Bitmap::transBlender(0, 0, 0, 200);
top.drawTrans(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/loading.h b/util/loading.h
index 0d648219..1c2b4cd7 100644
--- a/util/loading.h
+++ b/util/loading.h
@@ -1,44 +1,44 @@
#ifndef _paintown_loading_h
#define _paintown_loading_h
-#include "util/thread.h"
+#include "thread.h"
namespace Level{
class LevelInfo;
}
namespace Loader{
/* Kind of loader to show */
enum Kind{
Default,
SimpleCircle
};
class LoadingContext{
public:
LoadingContext();
virtual ~LoadingContext();
virtual void doLoad();
virtual void load() = 0;
virtual bool done();
static void * load_it(void * arg);
protected:
Util::Thread::Lock lock;
bool finished;
};
extern volatile bool done_loading;
// extern Util::Thread::Lock loading_screen_mutex;
/* deprecated, remove */
void startLoadingX(Util::Thread::Id * thread, void * arg = 0, Kind kind = Default);
void stopLoadingX(Util::Thread::Id thread);
void loadScreen(LoadingContext & context, const Level::LevelInfo & info, Kind kind = Default);
void * loadingScreen(void *);
}
#endif

File Metadata

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

Event Timeline