void display(void) { int shift=0; glPushAttrib(GL_ALL_ATTRIB_BITS); glClearColor (0.8, 0.8, 0.8, 1.0); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); screen_box(0,wh-ww/10,ww/10); glColor3f(1.0, 0.0, 0.0); screen_box(ww/10,wh-ww/10,ww/10); glColor3f(0.0, 1.0, 0.0); screen_box(ww/5,wh-ww/10,ww/10); glColor3f(0.0, 0.0, 1.0); screen_box(3*ww/10,wh-ww/10,ww/10); glColor3f(1.0, 1.0, 0.0); screen_box(2*ww/5,wh-ww/10,ww/10); glColor3f(0.0, 0.0, 0.0); screen_box(ww/10+ww/40,wh-ww/10+ww/40,ww/20); glBegin(GL_LINES); glVertex2i(wh/40,wh-ww/20); glVertex2i(wh/40+ww/20,wh-ww/20); glEnd(); glBegin(GL_TRIANGLES); glVertex2i(ww/5+ww/40,wh-ww/10+ww/40); glVertex2i(ww/5+ww/20,wh-ww/40); glVertex2i(ww/5+3*ww/40,wh-ww/10+ww/40); glEnd(); glPointSize(3.0); glBegin(GL_POINTS); glVertex2i(3*ww/10+ww/20, wh-ww/20); glEnd(); glRasterPos2i(2*ww/5,wh-ww/20); glutBitmapCharacter(GLUT_BITMAP_9_BY_15, 'A'); shift=glutBitmapWidth(GLUT_BITMAP_9_BY_15, 'A'); glRasterPos2i(2*ww/5+shift,wh-ww/20); glutBitmapCharacter(GLUT_BITMAP_9_BY_15, 'B'); shift+=glutBitmapWidth(GLUT_BITMAP_9_BY_15, 'B'); glRasterPos2i(2*ww/5+shift,wh-ww/20); glutBitmapCharacter(GLUT_BITMAP_9_BY_15, 'C'); glFlush(); glPopAttrib(); }
void game_loop (GAME *game) { if (!game) return; ALLEGRO_KEYBOARD_STATE keyboard_state; ALLEGRO_EVENT event; ALLEGRO_FONT *font = al_load_font ("data/fixed_font.tga", 0, 0); SCENE *scene; SPRITE_ACTOR *actor; LIST_ITEM *item; AABB_COLLISIONS collisions; aabb_init_collisions (&collisions); AABB_COLLISIONS portal_collisions; aabb_init_collisions (&portal_collisions); AABB_COLLISIONS npc_collisions; aabb_init_collisions (&npc_collisions); int i = 0; bool redraw = true; float times[NTIMES] = {0}; double frame_time, current_time, new_time, mean_frame_time; double fixed_dt = 1.0 / FPS, dt; double curfps = 0.0; current_time = al_get_time (); al_start_timer (game->timer); float fadeout_duration = 0; float fadein_duration = 0; SCENE_PORTAL *dest_portal = NULL; char *arrow_path = get_resource_path_str ("data/ui/smallarrow_down.png"); ALLEGRO_BITMAP *sel_arrow = al_load_bitmap (arrow_path); while (game->running) { scene = game->current_scene; actor = game->current_actor; if (redraw) { al_clear_depth_buffer (0); tiled_draw_map_back (scene->map, game->screen.tint, game->screen.position.x, game->screen.position.y, game->screen.width, game->screen.height, 0, 0, 0); al_draw_textf (font, al_map_rgba_f (0.9, 0, 0, 1), 5, 5, 0, "FPS: %.2f", curfps); al_set_render_state (ALLEGRO_ALPHA_TEST, true); al_set_render_state (ALLEGRO_DEPTH_TEST, true); al_set_render_state (ALLEGRO_DEPTH_FUNCTION, ALLEGRO_RENDER_GREATER); al_hold_bitmap_drawing (true); sprite_draw (actor, &game->screen); item = _al_list_front (scene->npcs); while (item) { SPRITE_ACTOR *npc_actor = (SPRITE_ACTOR *)_al_list_item_data (item); sprite_draw (npc_actor, &game->screen); item = _al_list_next (scene->npcs, item); } al_hold_bitmap_drawing (false); al_set_render_state (ALLEGRO_DEPTH_TEST, false); al_set_render_state (ALLEGRO_ALPHA_TEST, false); if (false) { item = _al_list_front (portal_collisions.boxes); while (item) { BOX *box = _al_list_item_data (item); box_draw (*box, game->screen.position, al_map_rgb_f (1, 0, 0)); item = _al_list_next (portal_collisions.boxes, item); } aabb_draw (scene->portal_tree, &game->screen, al_map_rgb_f (0, 0, 1)); } tiled_draw_map_fore (scene->map, game->screen.tint, game->screen.position.x, game->screen.position.y, game->screen.width, game->screen.height, 0, 0, 0); if (game->current_npc) { float dx = game->current_npc->actor.box.center.x - game->screen.position.x; float dy = game->current_npc->actor.box.center.y - game->screen.position.y; dx -= al_get_bitmap_width (sel_arrow) * 0.5f; dy -= game->current_npc->actor.box.extent.y * 3.0f; al_draw_bitmap (sel_arrow, dx, dy, 0); } ui_draw (game->ui, &game->screen); if (game->force_vsync) al_wait_for_vsync (); al_flip_display (); redraw = false; } al_wait_for_event (game->event_queue, &event); switch (event.type) { case ALLEGRO_EVENT_TIMER: new_time = al_get_time (); frame_time = new_time - current_time; current_time = new_time; times[i] = frame_time; i = (i + 1) % NTIMES; mean_frame_time = 0.0; for (int j = 0; j < NTIMES; j++) mean_frame_time += times[j]; mean_frame_time /= NTIMES; curfps = 1.0 / mean_frame_time; dt = mean_frame_time / fixed_dt; if (fadeout_duration > 0.0f) { float fadef = fadeout_duration / TRANS_TIME; game->screen.tint = al_map_rgba_f (fadef, fadef, fadef, 1.0); fadeout_duration -= mean_frame_time; if (fadeout_duration <= 0.0f) { fadein_duration = TRANS_TIME; fadeout_duration = 0.0f; game_enter_portal (game, dest_portal); } } if (fadein_duration > 0.0f) { float fadef = 1.0 - fadein_duration / TRANS_TIME; game->screen.tint = al_map_rgba_f (fadef, fadef, fadef, 1.0); fadein_duration -= mean_frame_time; if (fadein_duration <= 0.0f) { game->paused = false; fadein_duration = 0.0f; } } if (game->paused) { redraw = true; break; } al_get_keyboard_state (&keyboard_state); if (al_key_down (&keyboard_state, ALLEGRO_KEY_ESCAPE)) { game->running = false; continue; } if (al_key_down (&keyboard_state, ALLEGRO_KEY_ENTER)) { ui_show_dialog (game->ui, NULL, NULL); } if (al_key_down (&keyboard_state, ALLEGRO_KEY_RIGHT)) { actor->event->move_right (actor, dt); } if (al_key_down (&keyboard_state, ALLEGRO_KEY_LEFT)) { actor->event->move_left (actor, dt); } if (al_key_down (&keyboard_state, ALLEGRO_KEY_UP)) { actor->event->move_up (actor, dt); } if (al_key_down (&keyboard_state, ALLEGRO_KEY_DOWN)) { actor->event->move_down (actor, dt); } BOX box = actor->box; box.center.x += actor->movement.x * dt; box.center.y += actor->movement.y * dt; aabb_collide_fill_cache (scene->collision_tree, &box, &collisions); if (scene->collision_tree->num_collisions > 0) { item = _al_list_front (collisions.boxes); while (item) { if (box_lateral (*(BOX *)_al_list_item_data (item), actor->box)) actor->movement.x = 0; else actor->movement.y = 0; item = _al_list_next (collisions.boxes, item); } } aabb_collide_fill_cache (scene->portal_tree, &box, &portal_collisions); if (scene->portal_tree->num_collisions > 0) { item = _al_list_front (portal_collisions.boxes); while (item) { BOX *colbox = _al_list_item_data (item); TILED_OBJECT *obj = colbox->data; SCENE_PORTAL *portal = scene_get_portal (game->scenes, obj->name); if (portal && portal->destiny_portal) { dest_portal = scene_get_portal (game->scenes, portal->destiny_portal); if (dest_portal) { fadeout_duration = TRANS_TIME; game->paused = true; actor->movement = (VECTOR2D){0, 0}; ui_show_dialog_cstr (game->ui, "Speaker:", "Entering portal."); break; } } item = _al_list_next (portal_collisions.boxes, item); } } box = screen_box (&game->screen); game->current_npc = NULL; item = _al_list_front (scene->npcs); float max_dist = 0; while (item) { SPRITE_NPC *npc = _al_list_item_data (item); float dist = vsqdistance (npc->actor.box.center, game->current_actor->box.center); if (dist < 128.0f * 128.0f && dist > max_dist) { game->current_npc = npc; max_dist = dist; } item = _al_list_next (scene->npcs, item); } //aabb_collide_fill_cache (scene->npc_tree, &box, &npc_collisions); //if (scene->npc_tree->num_collisions > 0) { // item = _al_list_front (npc_collisions.boxes); // float max_dist = 0; // while (item) { // BOX *colbox = _al_list_item_data (item); // SPRITE_NPC *npc = colbox->data; // float dist = vsqdistance (npc->actor.box.center, game->current_actor->box.center); // if (dist < 128.0f * 128.0f && dist > max_dist) { // game->current_npc = npc; // max_dist = dist; // } // item = _al_list_next (npc_collisions.boxes, item); // } //} screen_update (&game->screen, actor->position, scene->map, dt); sprite_update (actor, dt, mean_frame_time); item = _al_list_front (scene->npcs); while (item) { SPRITE_ACTOR *npc_actor = (SPRITE_ACTOR *)_al_list_item_data (item); sprite_update (npc_actor, dt, mean_frame_time); item = _al_list_next (scene->npcs, item); } redraw = true; break; case ALLEGRO_EVENT_DISPLAY_CLOSE: game->running = false; break; default: fprintf (stderr, "Unsupported event received: %d\n", event.type); break; } } aabb_free_collisions (&collisions); aabb_free_collisions (&portal_collisions); aabb_free_collisions (&npc_collisions); }