static void draw(float x, float y) { float w = 300; float line_height = 25; float pad = 20; float h = Profiler::get_instance()->timer.size()*line_height + pad*2; PROFILE_TIMER_TIME_T duration = 0.0; int i=0; char time[32]; al_draw_filled_rounded_rectangle(x, y, x+w, y+h, 8, 8, bg_color); //if (!font) return; std::vector<profile_timer_class *>::iterator it = Profiler::get_instance()->timer.begin(); for ( ; it != get_instance()->timer.end(); ++it) { duration = (*it)->stop_time - (*it)->start_time; al_draw_filled_rectangle(x, y+pad+line_height*i+15, x+duration*10000, y+pad+line_height*i+20, al_color_name("orange")); al_draw_text(font, font_color, x+pad, y+pad+line_height*i, 0, (*it)->name); sprintf(time, "%f", duration*100); al_draw_text(font, font_color, x+pad+200, y+pad+line_height*i, 0, time); i++; } al_draw_line(x+ALLEGRO_BPS_TO_SECS(60)*10000, y, x+ALLEGRO_BPS_TO_SECS(60)*10000, y+h, limit_bar_color, 1.0); al_draw_line(x+ALLEGRO_BPS_TO_SECS(72)*10000, y, x+ALLEGRO_BPS_TO_SECS(72)*10000, y+h, limit_bar_color, 1.0); }
bool Framework::initialize(std::string config_filename) { if (initialized) return initialized; if (!al_init()) std::cerr << "al_init() failed" << std::endl; ALLEGRO_PATH *resource_path = al_get_standard_path(ALLEGRO_RESOURCES_PATH); al_change_directory(al_path_cstr(resource_path, ALLEGRO_NATIVE_PATH_SEP)); al_destroy_path(resource_path); if (!al_install_mouse()) std::cerr << "al_install_mouse() failed" << std::endl; if (!al_install_keyboard()) std::cerr << "al_install_keyboard() failed" << std::endl; if (!al_install_joystick()) std::cerr << "al_install_joystick() failed" << std::endl; if (!al_install_audio()) std::cerr << "al_install_audio() failed" << std::endl; if (!al_init_native_dialog_addon()) std::cerr << "al_init_native_dialog_addon() failed" << std::endl; if (!al_init_primitives_addon()) std::cerr << "al_init_primitives_addon() failed" << std::endl; if (!al_init_image_addon()) std::cerr << "al_init_image_addon() failed" << std::endl; if (!al_init_font_addon()) std::cerr << "al_init_font_addon() failed" << std::endl; if (!al_init_ttf_addon()) std::cerr << "al_init_ttf_addon() failed" << std::endl; if (!al_init_acodec_addon()) std::cerr << "al_init_acodec_addon() failed" << std::endl; if (!al_reserve_samples(32)) std::cerr << "al_reserve_samples() failed" << std::endl; srand(time(NULL)); primary_timer = al_create_timer(ALLEGRO_BPS_TO_SECS(60)); al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR); // al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR | ALLEGRO_MIPMAP); builtin_font = al_create_builtin_font(); event_queue = al_create_event_queue(); al_register_event_source(event_queue, al_get_keyboard_event_source()); al_register_event_source(event_queue, al_get_mouse_event_source()); al_register_event_source(event_queue, al_get_joystick_event_source()); al_register_event_source(event_queue, al_get_timer_event_source(primary_timer)); al_register_event_source(event_queue, al_get_joystick_event_source()); al_register_event_source(event_queue, al_get_default_menu_event_source()); if (al_get_num_joysticks()) joystick = al_get_joystick(0); // make this better eventually else std::cerr << "no joystick(s) detected" << std::endl; instance = new Framework(config_filename); Attributes::create_datatype_definition( AllegroColorAttributeDatatype::IDENTIFIER, AllegroColorAttributeDatatype::to_val_func, AllegroColorAttributeDatatype::to_str_func ); initialized = true; return true; }
int main(void) { ALLEGRO_DISPLAY *display; ALLEGRO_BITMAP* bkg; ALLEGRO_COLOR black; ALLEGRO_EVENT_QUEUE *queue; // Initialize Allegro 5 and addons if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_init_image_addon(); al_init_font_addon(); al_init_primitives_addon(); // Create a window to display things on: 640x480 pixels display = al_create_display(ScreenW, ScreenH); if (!display) { abort_example("Error creating display.\n"); return 1; } // Install the keyboard handler if (!al_install_keyboard()) { abort_example("Error installing keyboard.\n"); return 1; } if (!al_install_mouse()) { abort_example("Error installing mouse.\n"); return 1; } // Load a font Font = al_load_font("data/fixed_font.tga", 0, 0); if (!Font) { abort_example("Error loading \"data/fixed_font.tga\".\n"); return 1; } solid_white = al_map_rgba_f(1, 1, 1, 1); bkg = al_load_bitmap("data/bkg.png"); Texture = al_load_bitmap("data/texture.tga"); // Make and set some color to draw with black = al_map_rgba_f(0.0, 0.0, 0.0, 1.0); // Start the event queue to handle keyboard input and our timer queue = al_create_event_queue(); al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); al_register_event_source(queue, al_get_mouse_event_source()); al_set_window_title(display, "Primitives Example"); { int refresh_rate = 60; int frames_done = 0; double time_diff = al_get_time(); double fixed_timestep = 1.0f / refresh_rate; double real_time = al_get_time(); double game_time = al_get_time(); int ii; int cur_screen = 0; bool done = false; int clip = 0; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *timer_queue; int old; timer = al_create_timer(ALLEGRO_BPS_TO_SECS(refresh_rate)); al_start_timer(timer); timer_queue = al_create_event_queue(); al_register_event_source(timer_queue, al_get_timer_event_source(timer)); old = al_get_new_bitmap_flags(); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); Buffer = al_create_bitmap(ScreenW, ScreenH); al_set_new_bitmap_flags(old); al_identity_transform(&Identity); Screens[0] = LowPrimitives; Screens[1] = IndexedPrimitives; Screens[2] = HighPrimitives; Screens[3] = TransformationsPrimitives; Screens[4] = FilledPrimitives; Screens[5] = IndexedFilledPrimitives; Screens[6] = HighFilledPrimitives; Screens[7] = TexturePrimitives; Screens[8] = FilledTexturePrimitives; Screens[9] = CustomVertexFormatPrimitives; ScreenName[0] = "Low Level Primitives"; ScreenName[1] = "Indexed Primitives"; ScreenName[2] = "High Level Primitives"; ScreenName[3] = "Transformations"; ScreenName[4] = "Low Level Filled Primitives"; ScreenName[5] = "Indexed Filled Primitives"; ScreenName[6] = "High Level Filled Primitives"; ScreenName[7] = "Textured Primitives"; ScreenName[8] = "Filled Textured Primitives"; ScreenName[9] = "Custom Vertex Format"; for (ii = 0; ii < NUM_SCREENS; ii++) Screens[ii](INIT); while (!done) { double frame_duration = al_get_time() - real_time; al_rest(fixed_timestep - frame_duration); //rest at least fixed_dt frame_duration = al_get_time() - real_time; real_time = al_get_time(); if (real_time - game_time > frame_duration) { //eliminate excess overflow game_time += fixed_timestep * floor((real_time - game_time) / fixed_timestep); } while (real_time - game_time >= 0) { ALLEGRO_EVENT key_event; double start_time = al_get_time(); game_time += fixed_timestep; Screens[cur_screen](LOGIC); while (al_get_next_event(queue, &key_event)) { switch (key_event.type) { case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: { cur_screen++; if (cur_screen >= NUM_SCREENS) { cur_screen = 0; } break; } case ALLEGRO_EVENT_DISPLAY_CLOSE: { done = true; break; } case ALLEGRO_EVENT_KEY_CHAR: { switch (key_event.keyboard.keycode) { case ALLEGRO_KEY_ESCAPE: { done = true; break; } case ALLEGRO_KEY_S: { Soft = !Soft; time_diff = al_get_time(); frames_done = 0; break; } case ALLEGRO_KEY_C: { clip = !clip; time_diff = al_get_time(); frames_done = 0; break; } case ALLEGRO_KEY_L: { Blend = !Blend; time_diff = al_get_time(); frames_done = 0; break; } case ALLEGRO_KEY_B: { Background = !Background; time_diff = al_get_time(); frames_done = 0; break; } case ALLEGRO_KEY_LEFT: { Speed -= ROTATE_SPEED; break; } case ALLEGRO_KEY_RIGHT: { Speed += ROTATE_SPEED; break; } case ALLEGRO_KEY_PGUP: { Thickness += 0.5f; if (Thickness < 1.0f) Thickness = 1.0f; break; } case ALLEGRO_KEY_PGDN: { Thickness -= 0.5f; if (Thickness < 1.0f) Thickness = 0.0f; break; } case ALLEGRO_KEY_UP: { cur_screen++; if (cur_screen >= NUM_SCREENS) { cur_screen = 0; } break; } case ALLEGRO_KEY_SPACE: { Speed = 0; break; } case ALLEGRO_KEY_DOWN: { cur_screen--; if (cur_screen < 0) { cur_screen = NUM_SCREENS - 1; } break; } } } } } if (al_get_time() - start_time >= fixed_timestep) { //break if we start taking too long break; } } al_clear_to_color(black); if (Soft == 1) { al_set_target_bitmap(Buffer); al_clear_to_color(black); } if (Background && bkg) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_draw_scaled_bitmap(bkg, 0, 0, al_get_bitmap_width(bkg), al_get_bitmap_height(bkg), 0, 0, ScreenW, ScreenH, 0); } if (clip == 1) { al_set_clipping_rectangle(ScreenW / 2, ScreenH / 2, ScreenW / 2, ScreenH / 2); } Screens[cur_screen](DRAW); al_set_clipping_rectangle(0, 0, ScreenW, ScreenH); if (Soft == 1) { al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_set_target_backbuffer(display); al_draw_bitmap(Buffer, 0, 0, 0); } al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(Font, solid_white, ScreenW / 2, ScreenH - 20, ALLEGRO_ALIGN_CENTRE, "%s", ScreenName[cur_screen]); al_draw_textf(Font, solid_white, 0, 0, 0, "FPS: %f", (float)frames_done / (al_get_time() - time_diff)); al_draw_textf(Font, solid_white, 0, 20, 0, "Change Screen (Up/Down). Esc to Quit."); al_draw_textf(Font, solid_white, 0, 40, 0, "Rotation (Left/Right/Space): %f", Speed); al_draw_textf(Font, solid_white, 0, 60, 0, "Thickness (PgUp/PgDown): %f", Thickness); al_draw_textf(Font, solid_white, 0, 80, 0, "Software (S): %d", Soft); al_draw_textf(Font, solid_white, 0, 100, 0, "Blending (L): %d", Blend); al_draw_textf(Font, solid_white, 0, 120, 0, "Background (B): %d", Background); al_draw_textf(Font, solid_white, 0, 140, 0, "Clip (C): %d", clip); al_flip_display(); frames_done++; } } return 0; }
void GameEngine::initialise() { if (!al_init()) { THROW_GAME_EXCEPTION(EXCEP_ALLEG_ENGINE_FAILED); } if (!al_init_font_addon()) { THROW_GAME_EXCEPTION(EXCEP_ALLEG_FONT_FAILED); } if (!al_init_image_addon()) { THROW_GAME_EXCEPTION(EXCEP_ALLEG_IMAGE_FAILED); } if (!al_install_keyboard()) { THROW_GAME_EXCEPTION(EXCEP_ALLEG_KEYBOARD_FAILED); } if (!al_install_mouse()) { THROW_GAME_EXCEPTION(EXCEP_ALLEG_MOUSE_FAILED); } //Temporary Display Options al_set_new_display_flags(ALLEGRO_OPENGL); al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST); al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST); al_set_new_display_option(ALLEGRO_RENDER_METHOD, 1, ALLEGRO_SUGGEST); al_set_new_display_option(ALLEGRO_VSYNC, 2, ALLEGRO_REQUIRE); al_set_new_display_option(ALLEGRO_CAN_DRAW_INTO_BITMAP, 1, ALLEGRO_SUGGEST); int originalDisplayFlags = al_get_new_display_flags(); int displayFlags = 0; if (m_Config->getFullscreen()) { displayFlags = displayFlags | ALLEGRO_FULLSCREEN_WINDOW | ALLEGRO_NOFRAME; } al_set_new_display_flags(displayFlags); al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR | ALLEGRO_VIDEO_BITMAP); if (m_Config->getResolutionWidth() < 0 || m_Config->getResolutionHeight() < 0) { ALLEGRO_DISPLAY_MODE largest_display_mode; al_get_display_mode(al_get_num_display_modes() - 1, &largest_display_mode); m_Config->setResolutionWidth(largest_display_mode.width); m_Config->setResolutionHeight(largest_display_mode.height); //std::cout << m_Config->getResolutionWidth() << " " << m_Config->getResolutionHeight() << endl; } m_Display = al_create_display(m_Config->getResolutionWidth(), m_Config->getResolutionHeight()); if (!m_Display) { THROW_GAME_EXCEPTION(EXCEP_ALLEG_DISPLAY_FAILED); } al_set_new_display_flags(originalDisplayFlags); m_RedrawTimer = al_create_timer(ALLEGRO_BPS_TO_SECS(m_Config->getFrameSpeed())); if (!m_RedrawTimer) { THROW_GAME_EXCEPTION(EXCEP_ALLEG_TIMER_FAILED); } m_EventQueue = al_create_event_queue(); if (!m_EventQueue) { THROW_GAME_EXCEPTION(EXCEP_ALLEG_EQUEUE_FAILED); } al_register_event_source(m_EventQueue, al_get_display_event_source(m_Display)); al_register_event_source(m_EventQueue, al_get_timer_event_source(m_RedrawTimer)); al_register_event_source(m_EventQueue, al_get_keyboard_event_source()); }
int main(int argc, char **argv) { if (!al_init()) { printf("failed to initialize allegro!\n"); return -1; } if (!al_init_image_addon()) { printf("failed to initialize image I/O addon!\n"); return -1; } if (!al_init_primitives_addon()) { printf("failed to initialize primitives addon!\n"); return -1; } ALLEGRO_DISPLAY *display = al_create_display(arena_width, arena_height); if (!display) { printf("failed to create display!\n"); return -1; } if (!al_install_keyboard()) { printf("failed to install keyboard!\n"); return -1; } bad_guy_timer = al_create_timer(ALLEGRO_BPS_TO_SECS(100)); if (!bad_guy_timer) { printf("failed to create timer!\n"); return -1; } al_start_timer(bad_guy_timer); black = al_color_name("black"); hero_x = arena_width / 4; hero_y = arena_height / 4; hero_bitmap = al_load_bitmap("hero.png"); bad_guy_x = bad_guy_starting_x; bad_guy_y = bad_guy_starting_y; bad_guy_color = al_color_name("red"); while (!al_key_down(keyboard_state, ALLEGRO_KEY_ESCAPE)) { al_get_keyboard_state(keyboard_state); while (al_get_timer_count(bad_guy_timer) > bad_guy_count) { if (al_key_down(keyboard_state, ALLEGRO_KEY_LEFT) && hero_x > hero_half_size) { hero_x -= hero_speed; } if (al_key_down(keyboard_state, ALLEGRO_KEY_RIGHT) && hero_x < arena_width - hero_half_size) { hero_x += hero_speed; } if (al_key_down(keyboard_state, ALLEGRO_KEY_UP) && hero_y > hero_half_size) { hero_y -= hero_speed; } if (al_key_down(keyboard_state, ALLEGRO_KEY_DOWN) && hero_y < arena_height - hero_half_size) { hero_y += hero_speed; } // Some trigonometry to move toward the hero double bad_guy_angle = atan2(hero_y - bad_guy_y, hero_x - bad_guy_x); bad_guy_x += bad_guy_speed * cos(bad_guy_angle); bad_guy_y += bad_guy_speed * sin(bad_guy_angle); bad_guy_speed += bad_guy_acceleration; // Reset bad guy when he hits the hero if (abs(hero_x - bad_guy_x) < bad_guy_half_size && abs(hero_y - bad_guy_y) < bad_guy_half_size) { bad_guy_x = bad_guy_starting_x; bad_guy_y = bad_guy_starting_y; bad_guy_speed = bad_guy_starting_speed; } al_add_timer_count(bad_guy_timer, -1); } al_clear_to_color(black); al_draw_bitmap(hero_bitmap, hero_x - hero_half_size, hero_y - hero_half_size, 0); al_draw_filled_circle(bad_guy_x, bad_guy_y, bad_guy_half_size, bad_guy_color); al_flip_display(); } return 0; }
bool initialize () { ALLEGRO_BITMAP *temp_color_bitmap; ALLEGRO_BITMAP *temp_mask_bitmap; global.quit = false; al_set_app_name ("Super Battle Thor II"); if (!al_init ()) { fputs ("Error: Could not start allegro.\n", stderr); return false; } al_set_new_display_option (ALLEGRO_VSYNC, 1, ALLEGRO_SUGGEST); al_set_new_display_flags (ALLEGRO_GENERATE_EXPOSE_EVENTS); global.display = al_create_display (256, 192); if (!global.display) { fputs ("Error: Allegro could not create a display of 256x192 pixels.\n", stderr); return false; } if (!al_install_keyboard ()) { fputs ("Allegro could not initialize the keyboard system.\n", stderr); return false; } global.timer = al_create_timer (ALLEGRO_BPS_TO_SECS (60)); if (!global.timer) { fputs ("Allegro could not create a 60hrz timer.\n", stderr); return false; } global.queue = al_create_event_queue (); if (!global.queue) { fputs ("Allegro could not create an event queue.\n", stderr); return false; } al_register_event_source (global.queue, al_get_keyboard_event_source ()); al_register_event_source (global.queue, al_get_display_event_source (global.display)); al_register_event_source (global.queue, al_get_timer_event_source (global.timer)); if (!al_init_image_addon ()) { fputs ("Allegro could not initialize the image loading system.\n", stderr); return false; } if (!al_install_audio ()) { fputs ("Allegro could not initialize the audio system.\n", stderr); return false; } al_reserve_samples (16); if (!al_init_acodec_addon ()) { fputs ("Allegro could not initialize the audio file loading system.\n", stderr); return false; } al_init_font_addon (); /* load files */ global.path = al_get_standard_path (ALLEGRO_PROGRAM_PATH); al_append_path_component (global.path, "media"); al_set_path_filename (global.path, "proggy_tiny.png"); global.programing_font = al_load_bitmap_font (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.programing_font) { fputs ("Allegro could not load proggy_tiny.png.\n", stderr); return false; } al_set_path_filename (global.path, "mjollnir.png"); global.sprite_bitmap[SPRITE_THOR] = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sprite_bitmap[SPRITE_THOR]) { fputs ("Allegro could not load mjollnir.png.\n", stderr); return false; } al_set_path_filename (global.path, "arrows.png"); global.arrow_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.arrow_bitmap) { fputs ("Allegro could not load arrows.png.\n", stderr); return false; } al_set_path_filename (global.path, "background_1_2_3_4.jpg"); global.backgrounds[BACKGROUND_1] = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.backgrounds[BACKGROUND_1]) { fputs ("Allegro could not load background_1_2_3_4.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "background_5.jpg"); global.backgrounds[BACKGROUND_5] = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.backgrounds[BACKGROUND_5]) { fputs ("Allegro could not load background_5.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "background_6.jpg"); global.backgrounds[BACKGROUND_6] = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.backgrounds[BACKGROUND_6]) { fputs ("Allegro could not load background_6.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "title_screen.jpg"); global.backgrounds[BACKGROUND_TITLE] = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.backgrounds[BACKGROUND_TITLE]) { fputs ("Allegro could not load title_screen.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "game_over.jpg"); global.backgrounds[BACKGROUND_GAME_OVER] = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.backgrounds[BACKGROUND_GAME_OVER]) { fputs ("Allegro could not load game_over.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "you_win.jpg"); global.backgrounds[BACKGROUND_YOU_WIN] = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.backgrounds[BACKGROUND_YOU_WIN]) { fputs ("Allegro could not load you_win.jpg.\n", stderr); return false; } global.backgrounds[BACKGROUND_BLACK] = al_create_bitmap (256, 192); if (!global.backgrounds[BACKGROUND_BLACK]) { fputs ("Allegro could not make a 256x192 bitmap :o", stderr); return false; } al_set_target_bitmap (global.backgrounds[BACKGROUND_BLACK]); al_clear_to_color (al_map_rgb (0, 0, 0)); al_set_target_backbuffer (global.display); /* start copy paste code here becasue I'm lazy */ /*------------------------------------------------------------------------*/ al_set_path_filename (global.path, "0-thor.jpg"); temp_color_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_color_bitmap) { fputs ("Allegro could not load 0-thor.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "0-thor_mask.jpg"); temp_mask_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_mask_bitmap) { fputs ("Allegro could not load 0-thor_mask.jpg.\n", stderr); return false; } global.sprite_bitmap[SPRITE_THOR] = make_from_mask (temp_color_bitmap, temp_mask_bitmap); al_destroy_bitmap (temp_color_bitmap); al_destroy_bitmap (temp_mask_bitmap); /*------------------------------------------------------------------------*/ al_set_path_filename (global.path, "1-giant.jpg"); temp_color_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_color_bitmap) { fputs ("Allegro could not load 1-giant.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "1-giant_mask.jpg"); temp_mask_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_mask_bitmap) { fputs ("Allegro could not load 1-giant_mask.jpg.\n", stderr); return false; } global.sprite_bitmap[SPRITE_GIANT] = make_from_mask (temp_color_bitmap, temp_mask_bitmap); al_destroy_bitmap (temp_color_bitmap); al_destroy_bitmap (temp_mask_bitmap); /*------------------------------------------------------------------------*/ al_set_path_filename (global.path, "2-nidhogg.jpg"); temp_color_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_color_bitmap) { fputs ("Allegro could not load 2-nidhogg.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "2-nidhogg_mask.jpg"); temp_mask_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_mask_bitmap) { fputs ("Allegro could not load 2-nidhogg_mask.jpg.\n", stderr); return false; } global.sprite_bitmap[SPRITE_NIDHOGG] = make_from_mask (temp_color_bitmap, temp_mask_bitmap); al_destroy_bitmap (temp_color_bitmap); al_destroy_bitmap (temp_mask_bitmap); /*------------------------------------------------------------------------*/ al_set_path_filename (global.path, "3-ran.jpg"); temp_color_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_color_bitmap) { fputs ("Allegro could not load 3-ran.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "3-ran_mask.jpg"); temp_mask_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_mask_bitmap) { fputs ("Allegro could not load 3-ran_mask.jpg.\n", stderr); return false; } global.sprite_bitmap[SPRITE_RAN] = make_from_mask (temp_color_bitmap, temp_mask_bitmap); al_destroy_bitmap (temp_color_bitmap); al_destroy_bitmap (temp_mask_bitmap); /*------------------------------------------------------------------------*/ al_set_path_filename (global.path, "4-grendel.jpg"); temp_color_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_color_bitmap) { fputs ("Allegro could not load 4-grendel.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "4-grendel_mask.jpg"); temp_mask_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_mask_bitmap) { fputs ("Allegro could not load 4-grendel_mask.jpg.\n", stderr); return false; } global.sprite_bitmap[SPRITE_GRENDEL] = make_from_mask (temp_color_bitmap, temp_mask_bitmap); al_destroy_bitmap (temp_color_bitmap); al_destroy_bitmap (temp_mask_bitmap); /*------------------------------------------------------------------------*/ al_set_path_filename (global.path, "5-fafnir.jpg"); temp_color_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_color_bitmap) { fputs ("Allegro could not load 5-fafnir.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "5-fafnir_mask.jpg"); temp_mask_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_mask_bitmap) { fputs ("Allegro could not load 5-fafnir_mask.jpg.\n", stderr); return false; } global.sprite_bitmap[SPRITE_FAFNIR] = make_from_mask (temp_color_bitmap, temp_mask_bitmap); al_destroy_bitmap (temp_color_bitmap); al_destroy_bitmap (temp_mask_bitmap); /*------------------------------------------------------------------------*/ al_set_path_filename (global.path, "6-loki.jpg"); temp_color_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_color_bitmap) { fputs ("Allegro could not load 6-loki.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "6-loki_mask.jpg"); temp_mask_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_mask_bitmap) { fputs ("Allegro could not load 6-loki_mask.jpg.\n", stderr); return false; } global.sprite_bitmap[SPRITE_LOKI] = make_from_mask (temp_color_bitmap, temp_mask_bitmap); al_destroy_bitmap (temp_color_bitmap); al_destroy_bitmap (temp_mask_bitmap); /*------------------------------------------------------------------------*/ al_set_path_filename (global.path, "7-fenrir.jpg"); temp_color_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_color_bitmap) { fputs ("Allegro could not load 7-fenrir.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "7-fenrir_mask.jpg"); temp_mask_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_mask_bitmap) { fputs ("Allegro could not load 7-fenrir_mask.jpg.\n", stderr); return false; } global.sprite_bitmap[SPRITE_FENRIR] = make_from_mask (temp_color_bitmap, temp_mask_bitmap); al_destroy_bitmap (temp_color_bitmap); al_destroy_bitmap (temp_mask_bitmap); /*------------------------------------------------------------------------*/ al_set_path_filename (global.path, "fight.jpg"); temp_color_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_color_bitmap) { fputs ("Allegro could not load fight.jpg.\n", stderr); return false; } al_set_path_filename (global.path, "fight_mask.jpg"); temp_mask_bitmap = al_load_bitmap (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!temp_mask_bitmap) { fputs ("Allegro could not load fight_mask.jpg.\n", stderr); return false; } global.sprite_bitmap[SPRITE_FIGHT] = make_from_mask (temp_color_bitmap, temp_mask_bitmap); al_destroy_bitmap (temp_color_bitmap); al_destroy_bitmap (temp_mask_bitmap); /*------------------------------------------------------------------------*/ /* loading sounds here (still copy paste) */ al_set_path_filename (global.path, "titlescreen_loop.ogg"); global.sounds[SOUND_TITLESCREEN_LOOP] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_TITLESCREEN_LOOP]) { fputs ("Allegro could not load titlescreen_loop.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "begin_battle.ogg"); global.sounds[SOUND_BEGIN_BATTLE] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_BEGIN_BATTLE]) { fputs ("Allegro could not load begin_battle.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "battle_loop.ogg"); global.sounds[SOUND_BATTLE_LOOP] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_BATTLE_LOOP]) { fputs ("Allegro could not load battle_loop.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "dragon_loop.ogg"); global.sounds[SOUND_DRAGON_LOOP] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_DRAGON_LOOP]) { fputs ("Allegro could not load dragon_loop.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "hit_1.ogg"); global.sounds[SOUND_HIT_1] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_HIT_1]) { fputs ("Allegro could not load hit_1.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "hit_2.ogg"); global.sounds[SOUND_HIT_2] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_HIT_2]) { fputs ("Allegro could not load hit_2.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "laugh_1.ogg"); global.sounds[SOUND_LAUGH_1] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_LAUGH_1]) { fputs ("Allegro could not load laugh_1.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "laugh_2.ogg"); global.sounds[SOUND_LAUGH_2] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_LAUGH_2]) { fputs ("Allegro could not load laugh_2.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "laugh_3.ogg"); global.sounds[SOUND_LAUGH_3] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_LAUGH_3]) { fputs ("Allegro could not load laugh_3.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "laugh_4.ogg"); global.sounds[SOUND_LAUGH_4] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_LAUGH_4]) { fputs ("Allegro could not load laugh_4.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "laugh_5.ogg"); global.sounds[SOUND_LAUGH_5] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_LAUGH_5]) { fputs ("Allegro could not load laugh_5.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "laugh_6.ogg"); global.sounds[SOUND_LAUGH_6] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_LAUGH_6]) { fputs ("Allegro could not load laugh_6.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "killed_baddie.ogg"); global.sounds[SOUND_KILLED_BADDIE] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_KILLED_BADDIE]) { fputs ("Allegro could not load killed_baddie.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "got_hit.ogg"); global.sounds[SOUND_GOT_HIT] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_GOT_HIT]) { fputs ("Allegro could not load got_hit.ogg.\n", stderr); return false; } al_set_path_filename (global.path, "you_are_dead.ogg"); global.sounds[SOUND_YOU_ARE_DEAD] = al_load_sample (al_path_cstr (global.path, ALLEGRO_NATIVE_PATH_SEP)); if (!global.sounds[SOUND_YOU_ARE_DEAD]) { fputs ("Allegro could not you_are_dead.ogg.\n", stderr); return false; } global.music = NULL; al_destroy_path (global.path); return true; }
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 {
/* this code is sick */ static void init_music() { float vol, val; char *p; int i; if (!al_is_audio_installed()) return; /* sine waves (one straight and one with oscillator sync) for the bass */ sine = create_sample_u8(22050, 64); p = (char *)al_get_sample_data(sine); for (i=0; i<64; i++) { *p = 128 + (sin((float)i * M_PI / 32.0) + sin((float)i * M_PI / 12.0)) * 8.0; p++; } /* square wave for melody #1 */ square = create_sample_u8(22050, 64); p = (char *)al_get_sample_data(square); for (i=0; i<64; i++) { *p = (i < 32) ? 120 : 136; p++; } /* saw wave for melody #2 */ saw = create_sample_u8(22050, 64); p = (char *)al_get_sample_data(saw); for (i=0; i<64; i++) { *p = 120 + (i*4 & 255) / 16; p++; } /* bass drum */ bd = create_sample_u8(22050, 1024); p = (char *)al_get_sample_data(bd); for (i=0; i<1024; i++) { vol = (float)(1024-i) / 16.0; *p = 128 + (sin((float)i / 48.0) + sin((float)i / 32.0)) * vol; p++; } /* snare drum */ snare = create_sample_u8(22050, 3072); p = (char *)al_get_sample_data(snare); val = 0; for (i=0; i<3072; i++) { vol = (float)(3072-i) / 24.0; val = (val * 0.9) + (RAND * 0.1); *p = 128 + val * vol; p++; } /* hihat */ hihat = create_sample_u8(22050, 1024); p = (char *)al_get_sample_data(hihat); for (i=0; i<1024; i++) { vol = (float)(1024-i) / 192.0; *p = 128 + (sin((float)i / 4.2) + RAND) * vol; p++; } /* start up the player */ for (i=0; i<256; i++) freq_table[i] = (int)(350.0 * pow(2.0, (float)i/12.0)); for (i=0; i<NUM_PARTS; i++) { part_pos[i] = part_ptr[i]; part_time[i] = 0; } part_voice[0] = al_create_sample_instance(sine); part_voice[1] = al_create_sample_instance(square); part_voice[2] = al_create_sample_instance(saw); part_voice[3] = al_create_sample_instance(bd); al_attach_sample_instance_to_mixer(part_voice[0], al_get_default_mixer()); al_attach_sample_instance_to_mixer(part_voice[1], al_get_default_mixer()); al_attach_sample_instance_to_mixer(part_voice[2], al_get_default_mixer()); al_attach_sample_instance_to_mixer(part_voice[3], al_get_default_mixer()); al_set_sample_instance_playmode(part_voice[0], ALLEGRO_PLAYMODE_LOOP); al_set_sample_instance_playmode(part_voice[1], ALLEGRO_PLAYMODE_LOOP); al_set_sample_instance_playmode(part_voice[2], ALLEGRO_PLAYMODE_LOOP); al_set_sample_instance_playmode(part_voice[3], ALLEGRO_PLAYMODE_ONCE); al_set_sample_instance_gain(part_voice[0], 192/255.0); al_set_sample_instance_gain(part_voice[1], 192/255.0); al_set_sample_instance_gain(part_voice[2], 192/255.0); al_set_sample_instance_gain(part_voice[3], 255/255.0); al_set_sample_instance_pan(part_voice[0], PAN(128)); al_set_sample_instance_pan(part_voice[1], PAN(224)); al_set_sample_instance_pan(part_voice[2], PAN(32)); al_set_sample_instance_pan(part_voice[3], PAN(128)); music_timer = al_install_timer(ALLEGRO_BPS_TO_SECS(22)); }