void debugcrapo(u32 op, u32 op2) { bprintf("DBG: %08X %08X\n", op, op2); DrawConsole(); //SwapBottomBuffers(0); //ClearBottomBuffer(); }
void Loading_Draw(struct Game *game) { float fadeloop=0; while (fadeloop<256) { ALLEGRO_EVENT ev; al_wait_for_event(game->event_queue, &ev); if ((ev.type == ALLEGRO_EVENT_TIMER) && (ev.timer.source == game->timer)) { fadeloop+=10; } if (al_is_event_queue_empty(game->event_queue)) { al_draw_tinted_bitmap(game->loading.loading_bitmap,al_map_rgba_f(fadeloop/255.0,fadeloop/255.0,fadeloop/255.0,1),0,0,0); DrawConsole(game); al_flip_display(); } } al_draw_bitmap(game->loading.loading_bitmap,0,0,0); al_stop_timer(game->timer); PreloadGameState(game, &Progress); al_wait_for_vsync(); al_start_timer(game->timer); /* fadeloop=0; while (fadeloop<256) { ALLEGRO_EVENT ev; al_wait_for_event(game->event_queue, &ev); if ((ev.type == ALLEGRO_EVENT_TIMER) && (ev.timer.source == game->timer)) { fadeloop+=10; } if (al_is_event_queue_empty(game->event_queue)) { al_draw_bitmap(game->loading.loading_bitmap,0,0,0); al_draw_filled_rectangle(0, game->viewportHeight*0.985, game->viewportWidth, game->viewportHeight, al_map_rgba(255,255,255,255)); al_draw_filled_rectangle(0, 0, game->viewportWidth, game->viewportHeight, al_map_rgba_f(0,0,0,fadeloop/255.0)); DrawConsole(game); al_flip_display(); } } al_clear_to_color(al_map_rgb(0,0,0));*/ al_draw_bitmap(game->loading.image4,0,0,0); //DrawConsole(game); //al_flip_display(); LoadGameState(game); al_draw_bitmap(game->loading.image4,0,0,0); }
void Progress(struct Game *game, float p) { if (p<0.15) { draw(game,game->loading.image1); } else if (p<0.4) { draw(game,game->loading.image2); } else if (p<0.65) { draw(game,game->loading.image3); } else { draw(game,game->loading.image4); } if (game->debug) { printf("%f\n", p); fflush(stdout); } al_set_target_bitmap(al_get_backbuffer(game->display)); al_draw_bitmap(game->loading.loading_bitmap,0,0,0); al_draw_filled_rectangle(0, game->viewportHeight*0.985, p*game->viewportWidth, game->viewportHeight, al_map_rgba(255,255,255,255)); DrawConsole(game); al_flip_display(); }
// main console function: process keyboard input and draw console window ------ // PUBLIC void CON_ConsoleMain() { static bool_t init_prompt_drawn = false; // set number of currently visible console lines // (negative values allowed!) cur_vis_conlines = ConsoleHeight; unsigned int len_before = strlen( con_lines[ con_bottom ] ); // process console keyboard input if ( CheckConsoleInput() || !init_prompt_drawn ) { init_prompt_drawn = true; // draw console DrawConsole( len_before > strlen( con_lines[ con_bottom ] ) ); } }
void GLVideo::UpdateScreen (DCanvas *canvas) { if(palettechanged) { extern void UpdateShaderPalette(SDL_Color *colors); UpdateShaderPalette(newPalette); palettechanged = false; } SDL_GL_SwapBuffers(); // viewheight or viewwidth not the same as screen? if(screenw != realviewheight || screenh != realviewheight) glViewport(viewwindowx, screenh - (realviewheight + viewwindowy), realviewwidth, realviewheight); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // make textures transparent where they are black? glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0); // Switch to 3D glMatrixMode(GL_PROJECTION); glLoadIdentity(); float aspect = (float)realviewwidth/realviewheight; float fov = 70.0; gluPerspective(fov, aspect, 0.08f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Render doom level if(gamestate == GS_LEVEL && !automapactive) RenderWorld(); // Switch to 2D glDisable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0f, 1, 1, 0.0f, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if(gamestate == GS_LEVEL && !automapactive) { // Draw player weapon DrawScreenSprites(); // Draw crosshair DrawCrosshair(); } // Render menu/console/automap over whole screen if(screenw != realviewwidth || screenh != realviewheight) { glViewport(0, 0, screenw, screenh); } // Draw automap if(automapactive) RenderAutomap(); // Render view border extern void R_DrawViewBorder(); R_DrawViewBorder(); // Draw status bar if(gamestate == GS_LEVEL) if(screenw != realviewwidth || screenh != realviewheight) { glColor4f(0,1,0,1); glDisable(GL_TEXTURE_2D); extern int ST_X, ST_Y, ST_WIDTH, ST_HEIGHT; DrawQuad((float)ST_X/screenw, (float)ST_Y/screenh, (float)ST_WIDTH/screenw, (float)ST_HEIGHT/screenh); } // Draw status bar border // Draw player redscreen, berserk, pickup // DrawTint(); // Render the grayscale+colormap result to a texture extern void RenderToTexture(size_t screenw, size_t screenh); RenderToTexture(screenw, screenh); // Shader will convert this into RGB output extern void RenderedTextureToScreen(size_t screenw, size_t screenh); RenderedTextureToScreen(screenw, screenh); // Console DrawConsole(screenw, screenh); // Menu DrawMenu(); }
void BaseApp::Draw() { #ifdef _DEBUG //LogMsg("**********FRAME START"); #endif VariantList vList(Variant(0,0)); m_sig_render(&vList); if (GetFPSVisible()) { char stTemp[256]; sprintf(stTemp, "fps: %d - M: %.2f, T: %.2f A: %.2f F: %.2f", m_gameTimer.GetFPS(), (float(m_memUsed)/1024)/1024, (float(m_texMemUsed)/1024)/1024, float(GetAudioManager()->GetMemoryUsed()/1024)/ 1024, float(GetFreeMemory()/1024)/ 1024); #ifdef _IRR_STATIC_LIB_ int prims = 0; if (GetIrrlichtManager()->GetDriver()) { prims = GetIrrlichtManager()->GetDriver()->getPrimitiveCountDrawn(); } char stExtra[256]; sprintf(stExtra, " Prims: %d", prims); strcat(stTemp, stExtra); #endif #ifdef PLATFORM_FLASH char stExtra[256]; sprintf(stExtra, " Flash: %.2f", float(GetNativeMemoryUsed())/1024/1024); strcat(stTemp, stExtra); #endif if (GetFont(FONT_SMALL)->IsLoaded()) { GetFont(FONT_SMALL)->DrawScaled(3,3, stTemp, 0.7f); } } //draw the console messages? if (GetConsoleVisible()) { DrawConsole(); } switch (GetLastError()) { case ERROR_MEM: GetFont(FONT_SMALL)->DrawScaled(2,14, "LOW MEM!", 0.7f); break; case ERROR_SPACE: GetFont(FONT_SMALL)->DrawScaled(2,14, "LOW STORAGE SPACE!", 0.7f); break; case ERROR_NONE: break; } SetupOrtho(); g_globalBatcher.Flush(); }
static inline void HandleEvent(struct Game* game, ALLEGRO_EVENT* ev) { switch (ev->type) { case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING: PauseExecution(game); al_acknowledge_drawing_halt(game->display); break; case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING: al_acknowledge_drawing_resume(game->display); ReloadGamestates(game); ResumeExecution(game); break; case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT: if (game->config.autopause) { PrintConsole(game, "Focus lost, autopausing..."); PauseExecution(game); } break; case ALLEGRO_EVENT_DISPLAY_SWITCH_IN: if (game->config.autopause) { if (game->config.debug.enabled && game->config.debug.livereload) { ReloadCode(game); } ResumeExecution(game); } break; case ALLEGRO_EVENT_DISPLAY_RESIZE: PrintConsole(game, "Resize event: %dx%d", ev->display.width, ev->display.height); #ifdef LIBSUPERDERPY_IMGUI ImGui_ImplAllegro5_InvalidateDeviceObjects(); #endif al_acknowledge_resize(game->display); #ifdef LIBSUPERDERPY_IMGUI ImGui_ImplAllegro5_CreateDeviceObjects(); #endif // SetupViewport can be expensive, so don't do it when the resize event is already outdated or doesn't change anything if (((ev->display.width != game->_priv.window_width) || (ev->display.height != game->_priv.window_height)) && (ev->display.width == al_get_display_width(game->display)) && (ev->display.height == al_get_display_height(game->display))) { SetupViewport(game); } break; case ALLEGRO_EVENT_KEY_DOWN: #ifdef ALLEGRO_ANDROID if ((ev->keyboard.keycode == ALLEGRO_KEY_MENU) || (ev->keyboard.keycode == ALLEGRO_KEY_TILDE) || (ev->keyboard.keycode == ALLEGRO_KEY_BACKQUOTE)) { #else if ((ev->keyboard.keycode == ALLEGRO_KEY_TILDE) || (ev->keyboard.keycode == ALLEGRO_KEY_BACKQUOTE)) { #endif game->_priv.showconsole = !game->_priv.showconsole; if ((ev->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL) && (game->config.debug.enabled)) { game->_priv.showtimeline = game->_priv.showconsole; } } if (ev->keyboard.keycode == ALLEGRO_KEY_F12) { DrawGamestates(game); int flags = al_get_new_bitmap_flags(); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); ALLEGRO_BITMAP* bitmap = al_create_bitmap(al_get_display_width(game->display), al_get_display_height(game->display)); al_set_new_bitmap_flags(flags); ALLEGRO_BITMAP* target = al_get_target_bitmap(); al_set_target_bitmap(bitmap); al_draw_bitmap(al_get_backbuffer(game->display), 0, 0, 0); al_set_target_bitmap(target); PrintConsole(game, "Screenshot made! Storing..."); struct ScreenshotThreadData* data = malloc(sizeof(struct ScreenshotThreadData)); data->game = game; data->bitmap = bitmap; #ifndef LIBSUPERDERPY_SINGLE_THREAD al_run_detached_thread(ScreenshotThread, data); #else ScreenshotThread(data); #endif } break; default: break; } #ifdef MAEMO5 // on Maemo we get mouse events instead of touch ones, so we'll rewrite them by ourselves if ((ev->type == ALLEGRO_EVENT_MOUSE_AXES) || (ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) || (ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_UP)) { switch (ev->type) { case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: ev->type = ALLEGRO_EVENT_TOUCH_BEGIN; break; case ALLEGRO_EVENT_MOUSE_BUTTON_UP: ev->type = ALLEGRO_EVENT_TOUCH_END; break; case ALLEGRO_EVENT_MOUSE_AXES: ev->type = ALLEGRO_EVENT_TOUCH_MOVE; break; default: break; } ALLEGRO_DISPLAY* display = ev->mouse.display; float dx = ev->mouse.dx; float dy = ev->mouse.dy; float x = ev->mouse.x; float y = ev->mouse.y; double timestamp = ev->mouse.timestamp; ev->touch.display = display; ev->touch.dx = dx; ev->touch.dy = dy; ev->touch.id = 0; ev->touch.primary = true; ev->touch.source = (ALLEGRO_TOUCH_INPUT*)al_get_touch_input_event_source(); ev->touch.timestamp = timestamp; ev->touch.x = x; ev->touch.y = y; } #endif } static inline void HandleDebugEvent(struct Game* game, ALLEGRO_EVENT* ev) { switch (ev->type) { case ALLEGRO_EVENT_KEY_DOWN: switch (ev->keyboard.keycode) { case ALLEGRO_KEY_F1: if (!game->_priv.paused) { PauseExecution(game); } else { ReloadCode(game); ResumeExecution(game); } break; case ALLEGRO_KEY_F9: game->_priv.speed = ALLEGRO_BPS_TO_SECS(60.0); game->_priv.showconsole = true; PrintConsole(game, "DEBUG: Gameplay speed: 1.00x"); break; case ALLEGRO_KEY_F10: { double speed = ALLEGRO_BPS_TO_SECS(game->_priv.speed); // inverting speed -= 10; if (speed < 10) { speed = 10; } game->_priv.speed = ALLEGRO_BPS_TO_SECS(speed); game->_priv.showconsole = true; PrintConsole(game, "DEBUG: Gameplay speed: %.2fx", speed / 60.0); } break; case ALLEGRO_KEY_F11: { double speed = ALLEGRO_BPS_TO_SECS(game->_priv.speed); // inverting speed += 10; if (speed > 600) { speed = 600; } game->_priv.speed = ALLEGRO_BPS_TO_SECS(speed); game->_priv.showconsole = true; PrintConsole(game, "DEBUG: Gameplay speed: %.2fx", speed / 60.0); } break; } break; default: break; } } static inline bool MainloopEvents(struct Game* game) { do { ALLEGRO_EVENT ev; if (game->_priv.paused && !IS_EMSCRIPTEN) { // there's no frame flipping when paused, so avoid pointless busylooping al_wait_for_event(game->_priv.event_queue, &ev); } else if (!al_get_next_event(game->_priv.event_queue, &ev)) { break; } #ifdef LIBSUPERDERPY_IMGUI ImGui_ImplAllegro5_ProcessEvent(&ev); switch (ev.type) { case ALLEGRO_EVENT_KEY_CHAR: case ALLEGRO_EVENT_KEY_DOWN: case ALLEGRO_EVENT_KEY_UP: if (igGetIO()->WantCaptureKeyboard) { continue; } break; case ALLEGRO_EVENT_MOUSE_AXES: case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: case ALLEGRO_EVENT_MOUSE_BUTTON_UP: case ALLEGRO_EVENT_TOUCH_BEGIN: case ALLEGRO_EVENT_TOUCH_CANCEL: case ALLEGRO_EVENT_TOUCH_END: case ALLEGRO_EVENT_TOUCH_MOVE: if (igGetIO()->WantCaptureMouse) { continue; } break; default: break; } #endif if (game->_priv.params.handlers.event) { if ((*game->_priv.params.handlers.event)(game, &ev)) { continue; } } if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { EventGamestates(game, &ev); return false; } HandleEvent(game, &ev); if (game->config.debug.enabled) { HandleDebugEvent(game, &ev); } EventGamestates(game, &ev); } while (!al_is_event_queue_empty(game->_priv.event_queue)); return true; } static inline bool MainloopTick(struct Game* game) { if (game->_priv.paused) { return true; } struct Gamestate* tmp = game->_priv.gamestates; #ifdef __EMSCRIPTEN__ emscripten_pause_main_loop(); #endif game->_priv.loading.to_load = 0; game->_priv.loading.loaded = 0; game->_priv.loading.lock = true; game->loading.progress = 0; // TODO: support gamestate dependences/ordering while (tmp) { if (tmp->pending_stop) { PrintConsole(game, "Stopping gamestate \"%s\"...", tmp->name); game->_priv.current_gamestate = tmp; (*tmp->api->stop)(game, tmp->data); tmp->started = false; tmp->pending_stop = false; PrintConsole(game, "Gamestate \"%s\" stopped successfully.", tmp->name); } if (tmp->pending_load) { game->_priv.loading.to_load++; } tmp = tmp->next; } tmp = game->_priv.gamestates; while (tmp) { if (tmp->pending_unload) { #ifdef __EMSCRIPTEN__ al_detach_voice(game->audio.v); #endif PrintConsole(game, "Unloading gamestate \"%s\"...", tmp->name); tmp->loaded = false; tmp->pending_unload = false; game->_priv.current_gamestate = tmp; (*tmp->api->unload)(game, tmp->data); PrintConsole(game, "Gamestate \"%s\" unloaded successfully.", tmp->name); #ifdef __EMSCRIPTEN__ al_attach_mixer_to_voice(game->audio.mixer, game->audio.v); #endif } if (tmp->pending_load) { #ifdef __EMSCRIPTEN__ al_detach_voice(game->audio.v); #endif if (tmp->show_loading && game->_priv.loading.gamestate->open) { (*game->_priv.loading.gamestate->api->start)(game, game->_priv.loading.gamestate->data); } if (!tmp->api) { if (!OpenGamestate(game, tmp, true) || !LinkGamestate(game, tmp)) { tmp->pending_load = false; tmp->pending_start = false; continue; } } if (tmp->api) { PrintConsole(game, "Loading gamestate \"%s\"...", tmp->name); game->_priv.loading.progress = 0; game->_priv.loading.current = tmp; game->_priv.current_gamestate = tmp; struct GamestateLoadingThreadData data = {.game = game, .gamestate = tmp, .bitmap_flags = al_get_new_bitmap_flags()}; game->_priv.loading.in_progress = true; double time = al_get_time(); game->_priv.loading.time = time; CalculateProgress(game); if (tmp->show_loading) { game->loading.shown = true; DrawGamestates(game); DrawConsole(game); al_flip_display(); #ifdef __EMSCRIPTEN__ emscripten_sleep(0); #endif } #ifndef LIBSUPERDERPY_SINGLE_THREAD al_run_detached_thread(GamestateLoadingThread, &data); while (game->_priv.loading.in_progress) { double delta = al_get_time() - game->_priv.loading.time; game->time += delta; // TODO: ability to disable passing time during loading game->_priv.loading.time += delta; if (game->loading.shown && game->_priv.loading.gamestate->open) { (*game->_priv.loading.gamestate->api->logic)(game, game->_priv.loading.gamestate->data, delta); } DrawGamestates(game); if (game->_priv.texture_sync) { al_convert_memory_bitmaps(); game->_priv.texture_sync = false; al_signal_cond(game->_priv.texture_sync_cond); game->_priv.loading.time = al_get_time(); // TODO: rethink time management during loading } DrawConsole(game); al_flip_display(); if (game->_priv.bsod_sync) { al_set_target_bitmap(NULL); game->_priv.bsod_sync = false; al_signal_cond(game->_priv.bsod_cond); } al_lock_mutex(game->_priv.bsod_mutex); while (game->_priv.in_bsod) { al_wait_cond(game->_priv.bsod_cond, game->_priv.bsod_mutex); } al_unlock_mutex(game->_priv.bsod_mutex); } #else GamestateLoadingThread(&data); DrawGamestates(game); DrawConsole(game); al_flip_display(); #ifdef __EMSCRIPTEN__ emscripten_sleep(0); #endif al_convert_memory_bitmaps(); #endif al_set_new_bitmap_flags(data.bitmap_flags); ReloadShaders(game, false); if (tmp->api->post_load) { PrintConsole(game, "[%s] Post-loading...", tmp->name); tmp->api->post_load(game, tmp->data); } game->_priv.loading.progress++; CalculateProgress(game); PrintConsole(game, "Gamestate \"%s\" loaded successfully in %f seconds.", tmp->name, al_get_time() - time); game->_priv.loading.loaded++; DrawGamestates(game); DrawConsole(game); al_flip_display(); #ifdef __EMSCRIPTEN__ emscripten_sleep(0); #endif tmp->loaded = true; tmp->pending_load = false; } if (tmp->show_loading && game->_priv.loading.gamestate->open) { (*game->_priv.loading.gamestate->api->stop)(game, game->_priv.loading.gamestate->data); } tmp->show_loading = true; game->loading.shown = false; game->_priv.timestamp = al_get_time(); #ifdef __EMSCRIPTEN__ al_attach_mixer_to_voice(game->audio.mixer, game->audio.v); #endif } tmp = tmp->next; }
int main(int argc, char **argv){ signal(SIGSEGV, derp); srand(time(NULL)); al_set_org_name("Super Derpy"); al_set_app_name("Back to the Browser Wars"); #ifdef ALLEGRO_MACOSX char exe_path[MAXPATHLEN]; char link_path[MAXPATHLEN]; uint32_t size = sizeof(exe_path); _NSGetExecutablePath(exe_path, &size); realpath(exe_path, link_path); chdir(link_path); #endif if(!al_init()) { fprintf(stderr, "failed to initialize allegro!\n"); return -1; } struct Game game; InitConfig(&game); game._priv.fps_count.frames_done = 0; game._priv.fps_count.fps = 0; game._priv.fps_count.old_time = 0; game._priv.font_bsod = NULL; game._priv.console = NULL; game.config.fullscreen = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "fullscreen", "0")); game.config.music = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "music", "10")); game.config.voice = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "voice", "10")); game.config.fx = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "fx", "10")); game.config.debug = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "debug", "0")); game.config.width = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "width", "1280")); if (game.config.width<320) game.config.width=320; game.config.height = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "height", "720")); if (game.config.height<180) game.config.height=180; if(!al_init_image_addon()) { fprintf(stderr, "failed to initialize image addon!\n"); /*al_show_native_message_box(display, "Error", "Error", "Failed to initialize al_init_image_addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR);*/ return -1; } if(!al_init_acodec_addon()){ fprintf(stderr, "failed to initialize audio codecs!\n"); return -1; } if(!al_install_audio()){ fprintf(stderr, "failed to initialize audio!\n"); return -1; } if(!al_install_keyboard()){ fprintf(stderr, "failed to initialize keyboard!\n"); return -1; } if(!al_init_primitives_addon()){ fprintf(stderr, "failed to initialize primitives!\n"); return -1; } if(!al_install_mouse()) { fprintf(stderr, "failed to initialize the mouse!\n"); return -1; } al_init_font_addon(); if(!al_init_ttf_addon()){ fprintf(stderr, "failed to initialize fonts!\n"); return -1; } if (game.config.fullscreen) al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); else al_set_new_display_flags(ALLEGRO_WINDOWED); al_set_new_display_option(ALLEGRO_VSYNC, 2-atoi(GetConfigOptionDefault(&game, "SuperDerpy", "vsync", "1")), ALLEGRO_SUGGEST); al_set_new_display_option(ALLEGRO_OPENGL, atoi(GetConfigOptionDefault(&game, "SuperDerpy", "opengl", "1")), ALLEGRO_SUGGEST); #ifdef ALLEGRO_WINDOWS al_set_new_window_position(20, 40); // workaround nasty Windows bug with window being created off-screen #endif game.display = al_create_display(game.config.width, game.config.height); if(!game.display) { fprintf(stderr, "failed to create display!\n"); return -1; } SetupViewport(&game); PrintConsole(&game, "Viewport %dx%d", game.viewport.width, game.viewport.height); ALLEGRO_BITMAP *icon = al_load_bitmap(GetDataFilePath(&game, "icons/bttbw.png")); al_set_window_title(game.display, "Back to the Browser Wars"); al_set_display_icon(game.display, icon); al_destroy_bitmap(icon); if (game.config.fullscreen) al_hide_mouse_cursor(game.display); al_inhibit_screensaver(true); al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR); game._priv.gamestates = NULL; game._priv.event_queue = al_create_event_queue(); if(!game._priv.event_queue) { FatalError(&game, true, "Failed to create event queue."); al_destroy_display(game.display); return -1; } game.audio.v = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2); game.audio.mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); game.audio.fx = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); game.audio.music = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); game.audio.voice = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); al_attach_mixer_to_voice(game.audio.mixer, game.audio.v); al_attach_mixer_to_mixer(game.audio.fx, game.audio.mixer); al_attach_mixer_to_mixer(game.audio.music, game.audio.mixer); al_attach_mixer_to_mixer(game.audio.voice, game.audio.mixer); al_set_mixer_gain(game.audio.fx, game.config.fx/10.0); al_set_mixer_gain(game.audio.music, game.config.music/10.0); al_set_mixer_gain(game.audio.voice, game.config.voice/10.0); al_register_event_source(game._priv.event_queue, al_get_display_event_source(game.display)); al_register_event_source(game._priv.event_queue, al_get_mouse_event_source()); al_register_event_source(game._priv.event_queue, al_get_keyboard_event_source()); game._priv.showconsole = game.config.debug; al_clear_to_color(al_map_rgb(0,0,0)); game._priv.timer = al_create_timer(ALLEGRO_BPS_TO_SECS(60)); // logic timer if(!game._priv.timer) { FatalError(&game, true, "Failed to create logic timer."); return -1; } al_register_event_source(game._priv.event_queue, al_get_timer_event_source(game._priv.timer)); al_flip_display(); al_start_timer(game._priv.timer); setlocale(LC_NUMERIC, "C"); game.shuttingdown = false; game.restart = false; game.mediator.lives = 3; game.mediator.score = 0; game.mediator.modificator = 1; game.mediator.heart = CreateCharacter(&game, "heart"); RegisterSpritesheet(&game, game.mediator.heart, "heart"); RegisterSpritesheet(&game, game.mediator.heart, "blank"); LoadSpritesheets(&game, game.mediator.heart); SelectSpritesheet(&game, game.mediator.heart, "heart"); char* gamestate = strdup("dosowisko"); // FIXME: don't hardcore gamestate int c; while ((c = getopt (argc, argv, "l:s:")) != -1) switch (c) { case 'l': free(gamestate); gamestate = strdup("levelX"); gamestate[5] = optarg[0]; break; case 's': free(gamestate); gamestate = strdup(optarg); break; } LoadGamestate(&game, gamestate); game._priv.gamestates->showLoading = false; // we have only one gamestate right now StartGamestate(&game, gamestate); free(gamestate); char libname[1024] = {}; snprintf(libname, 1024, "libsuperderpy-%s-loading" LIBRARY_EXTENTION, "bttbw"); void *handle = dlopen(libname, RTLD_NOW); if (!handle) { FatalError(&game, true, "Error while initializing loading screen %s", dlerror()); exit(1); } else { #define GS_LOADINGERROR FatalError(&game, true, "Error on resolving loading symbol: %s", dlerror()); exit(1); if (!(game._priv.loading.Draw = dlsym(handle, "Draw"))) { GS_LOADINGERROR; } if (!(game._priv.loading.Load = dlsym(handle, "Load"))) { GS_LOADINGERROR; } if (!(game._priv.loading.Start = dlsym(handle, "Start"))) { GS_LOADINGERROR; } if (!(game._priv.loading.Stop = dlsym(handle, "Stop"))) { GS_LOADINGERROR; } if (!(game._priv.loading.Unload = dlsym(handle, "Unload"))) { GS_LOADINGERROR; } } game._priv.loading.data = (*game._priv.loading.Load)(&game); bool redraw = false; while(1) { ALLEGRO_EVENT ev; if (redraw && al_is_event_queue_empty(game._priv.event_queue)) { struct Gamestate *tmp = game._priv.gamestates; int toLoad = 0, loaded = 0; // FIXME: move to function // TODO: support dependences while (tmp) { if ((tmp->pending_start) && (tmp->started)) { PrintConsole(&game, "Stopping gamestate \"%s\"...", tmp->name); (*tmp->api.Gamestate_Stop)(&game, tmp->data); tmp->started = false; tmp->pending_start = false; } if ((tmp->pending_load) && (!tmp->loaded)) toLoad++; tmp=tmp->next; } tmp = game._priv.gamestates; // FIXME: move to function // TODO: support dependences double t = -1; while (tmp) { if ((tmp->pending_load) && (tmp->loaded)) { PrintConsole(&game, "Unloading gamestate \"%s\"...", tmp->name); al_stop_timer(game._priv.timer); tmp->loaded = false; tmp->pending_load = false; (*tmp->api.Gamestate_Unload)(&game, tmp->data); dlclose(tmp->handle); tmp->handle = NULL; al_start_timer(game._priv.timer); } else if ((tmp->pending_load) && (!tmp->loaded)) { PrintConsole(&game, "Loading gamestate \"%s\"...", tmp->name); al_stop_timer(game._priv.timer); // TODO: take proper game name char libname[1024]; snprintf(libname, 1024, "libsuperderpy-%s-%s" LIBRARY_EXTENTION, "bttbw", tmp->name); tmp->handle = dlopen(libname,RTLD_NOW); if (!tmp->handle) { //PrintConsole(&game, "Error while loading gamestate \"%s\": %s", tmp->name, dlerror()); FatalError(&game, false, "Error while loading gamestate \"%s\": %s", tmp->name, dlerror()); tmp->pending_load = false; tmp->pending_start = false; } else { #define GS_ERROR FatalError(&game, false, "Error on resolving gamestate symbol: %s", dlerror()); tmp->pending_load = false; tmp->pending_start = false; tmp=tmp->next; continue; if (!(tmp->api.Gamestate_Draw = dlsym(tmp->handle, "Gamestate_Draw"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Logic = dlsym(tmp->handle, "Gamestate_Logic"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Load = dlsym(tmp->handle, "Gamestate_Load"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Start = dlsym(tmp->handle, "Gamestate_Start"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Pause = dlsym(tmp->handle, "Gamestate_Pause"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Resume = dlsym(tmp->handle, "Gamestate_Resume"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Stop = dlsym(tmp->handle, "Gamestate_Stop"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Unload = dlsym(tmp->handle, "Gamestate_Unload"))) { GS_ERROR; } if (!(tmp->api.Gamestate_ProcessEvent = dlsym(tmp->handle, "Gamestate_ProcessEvent"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Reload = dlsym(tmp->handle, "Gamestate_Reload"))) { GS_ERROR; } if (!(tmp->api.Gamestate_ProgressCount = dlsym(tmp->handle, "Gamestate_ProgressCount"))) { GS_ERROR; } int p = 0; void progress(struct Game *game) { p++; DrawGamestates(game); float progress = ((p / (*(tmp->api.Gamestate_ProgressCount) ? (float)*(tmp->api.Gamestate_ProgressCount) : 1))/(float)toLoad)+(loaded/(float)toLoad); if (game->config.debug) PrintConsole(game, "[%s] Progress: %d% (%d/%d)", tmp->name, (int)(progress*100), p, *(tmp->api.Gamestate_ProgressCount)); if (tmp->showLoading) (*game->_priv.loading.Draw)(game, game->_priv.loading.data, progress); DrawConsole(game); if (al_get_time() - t >= 1/60.0) { al_flip_display(); } t = al_get_time(); } t = al_get_time(); // initially draw loading screen with empty bar DrawGamestates(&game); if (tmp->showLoading) { (*game._priv.loading.Draw)(&game, game._priv.loading.data, loaded/(float)toLoad); } DrawConsole(&game); if (al_get_time() - t >= 1/60.0) { al_flip_display(); } t = al_get_time(); tmp->data = (*tmp->api.Gamestate_Load)(&game, &progress); // feel free to replace "progress" with empty function if you want to compile with clang loaded++; tmp->loaded = true; tmp->pending_load = false; } al_start_timer(game._priv.timer); } tmp=tmp->next; } bool gameActive = false; tmp=game._priv.gamestates; while (tmp) { if ((tmp->pending_start) && (!tmp->started) && (tmp->loaded)) { PrintConsole(&game, "Starting gamestate \"%s\"...", tmp->name); al_stop_timer(game._priv.timer); (*tmp->api.Gamestate_Start)(&game, tmp->data); al_start_timer(game._priv.timer); tmp->started = true; tmp->pending_start = false; } if ((tmp->started) || (tmp->pending_start) || (tmp->pending_load)) gameActive = true; tmp=tmp->next; } if (!gameActive) { PrintConsole(&game, "No gamestates left, exiting..."); break; } DrawGamestates(&game); DrawConsole(&game); al_flip_display(); redraw = false; } else {
void GForce::RecordSample( long inCurTime ) { long intensity; float t; if ( &mPortA == mCurPort ) mCurPort = &mPortB; else mCurPort = &mPortA; // All the waveshape virtual machines are linked to our time index mT_MS = inCurTime - mT_MS_Base; mT = ( (float) inCurTime ) / 1000.0; // Don't bother doing mouse or kybd poll if sceeen saver mode is disabled if ( mScrnSaverDelay > 0 ) IdleMonitor(); ManageColorChanges(); ManageShapeChanges(); ManageFieldChanges(); ManageParticleChanges(); // Do the blur operation, a fcn of what's oqn the screen, and the current delta field if ( mCurPort == &mPortA ) mPortB.Fade( mPortA, mField -> GetField() ); else mPortA.Fade( mPortB, mField -> GetField() ); /* This redraws the image */ // Draw all the current particles DrawParticles( *mCurPort ); // Draw the current wave shape for the current music sample playing // If there's a morph going, drawing is a mix of both waves if ( mShapeTransTime > 0 ) { float morphPct = (float) ( mShapeTransEnd - mT_MS ) / ( (float) mShapeTransTime ); mWave -> Draw( mNum_S_Steps, *mCurPort, 1, mNextWave, morphPct ); } else mWave -> Draw( mNum_S_Steps, *mCurPort, 1, 0, 0 ); // If we're not currently drawing track text, check to see if we start new text if ( mTrackTextDur == 0 && mTrackTextPosMode ) { if ( mTrackTextStartFcn.Evaluate() > 0 ) StartTrackText(); } // If we already have a t.t. draw in progress, draw the text in the (full) foreground color if ( mTrackTextDur > 0 ) { // From 0 to 1, how far are we into the text display interval? t = ( mT - mTrackTextStartTime ) / mTrackTextDur; // Decrease the text intensity thru time intensity = 255 * ( 1.2 - .3*t ); if ( intensity > 255 ) intensity = 255; mCurPort -> SetTextColor( mPalette[ intensity ] ); mCurPort -> SetTrackTextFont(); mCurPort -> DrawText( mTrackTextPos.h, mTrackTextPos.v, mTrackText ); } // Draw the console text to the offscreen image. Then copy the image to the OS out port if ( mT_MS < mConsoleExpireTime ) { // To ensure the console text is readable, we erase it when we're done mCurPort -> SetTextMode( SRC_XOR ); mCurPort -> SetTextColor( mPalette[ 255 ] ); mCurPort -> SetConsoleFont(); DrawConsole(); DrawFrame(); mCurPort -> SetTextColor( mPalette[ 0 ] ); DrawConsole(); mCurPort -> SetTextMode( SRC_OR ); } else DrawFrame(); // We need to avoid text all bluring together so we overwrite the foreground text we just drew // with text of a lower intensity... if ( mTrackTextDur > 0 ) { // Is the text is about to expire? if not, continue drawing. if ( t <= 1 ) { intensity = 255.5 * pow( t, 1.5 ); mCurPort -> SetTextColor( mPalette[ intensity ] ); mCurPort -> SetTrackTextFont(); mCurPort -> DrawText( mTrackTextPos.h, mTrackTextPos.v, mTrackText ); } else { // The text's duration is up so turn the draw flag off mTrackTextDur = 0; } } // Maintain the frame rate mFrameCount++; if ( mT_MS - mFrameCountStart >= 1500 ) { mCurFrameRate = 10000 * mFrameCount / ( mT_MS - mFrameCountStart ); mFrameCountStart = mT_MS; mFrameCount = 0; } if ( mT_MS - mLastCursorUpdate > 3000 ) { mLastCursorUpdate = mT_MS; if ( IsFullscreen() ) EgOSUtils::HideCursor(); } }