Ejemplo n.º 1
0
/* Creates a memory bitmap.
 */
static ALLEGRO_BITMAP *_al_create_memory_bitmap(int w, int h)
{
   ALLEGRO_BITMAP *bitmap;
   int pitch;
   int format = al_get_new_bitmap_format();

   format = _al_get_real_pixel_format(al_get_current_display(), format);

   bitmap = al_calloc(1, sizeof *bitmap);
   bitmap->size = sizeof(*bitmap);

   pitch = w * al_get_pixel_size(format);

   bitmap->vt = NULL;
   bitmap->format = format;
   bitmap->flags = (al_get_new_bitmap_flags() | ALLEGRO_MEMORY_BITMAP) &
      ~ALLEGRO_VIDEO_BITMAP;
   bitmap->w = w;
   bitmap->h = h;
   bitmap->pitch = pitch;
   bitmap->display = NULL;
   bitmap->locked = false;
   bitmap->cl = bitmap->ct = 0;
   bitmap->cr_excl = w;
   bitmap->cb_excl = h;
   al_identity_transform(&bitmap->transform);
   bitmap->parent = NULL;
   bitmap->xofs = bitmap->yofs = 0;
   bitmap->memory = al_malloc(pitch * h);
   bitmap->preserve_texture = !(al_get_new_bitmap_flags() & ALLEGRO_NO_PRESERVE_TEXTURE);
   return bitmap;
}
Ejemplo n.º 2
0
Overlay::Overlay(renderer* parent) : parent(parent)
{
	{
		CoreSuspender suspend;
		//parent->zoom(df::zoom_commands::zoom_reset);
		good_viewscreen = false;
		ReadTileLocations();
		copy_from_inner(); 
	}

	front_mutex = al_create_mutex();

	int32_t flags = al_get_new_bitmap_flags();
	if(al_get_current_display() != NULL){
		al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_ALPHA_TEST);
	}
	front = al_create_bitmap(0,0);
	if(al_get_current_display() != NULL){
		al_set_new_bitmap_flags(al_get_bitmap_flags(al_get_backbuffer(al_get_current_display())));
	}
	back = al_create_bitmap(0,0);
	al_set_new_bitmap_flags(flags);

	Flip();
};
Ejemplo n.º 3
0
void _reload_loaded_bitmaps_delayed(void)
{
	int flags = al_get_new_bitmap_flags();
	int format = al_get_new_bitmap_format();

	for (size_t i = 0; i < loaded_bitmaps.size(); i++) {
		MBITMAP *m = loaded_bitmaps[i]->bitmap;
		if ((loaded_bitmaps[i]->flags & ALLEGRO_NO_PRESERVE_TEXTURE) && loaded_bitmaps[i]->delayed) {
			al_set_new_bitmap_flags(loaded_bitmaps[i]->flags);
			al_set_new_bitmap_format(loaded_bitmaps[i]->format);
			if (loaded_bitmaps[i]->load_type == LOAD_LOAD) {
				m->bitmap = my_load_bitmap(loaded_bitmaps[i]->load.filename.c_str());
				if (loaded_bitmaps[i]->load.redraw) {
					loaded_bitmaps[i]->load.redraw(m, loaded_bitmaps[i]->load.data);
				}
			}
			else { // create
				Recreate *d = &loaded_bitmaps[i]->recreate;
				m->bitmap = my_al_create_bitmap(d->w, d->h);
				if (d->func) { // recreate with func
					d->func(m, d->data);
				}
			}
			al_use_shader(NULL);
		}
	}

	al_set_new_bitmap_flags(flags);
	al_set_new_bitmap_format(format);
}
Ejemplo n.º 4
0
void Overlay::Flip()
{
    //do the starting timer stuff
    clock_t starttime = clock();
	
	al_lock_mutex(front_mutex);
	{
		al_unlock_bitmap(front);

		if(al_get_bitmap_width(front) != ssState.ScreenW
			|| al_get_bitmap_height(front) != ssState.ScreenH){
				al_destroy_bitmap(front);
				int32_t flags = al_get_new_bitmap_flags();
				if(al_get_current_display() != NULL){
					al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_ALPHA_TEST);
				}
				front = al_create_bitmap(ssState.ScreenW, ssState.ScreenH);
				al_set_new_bitmap_flags(flags);
		}
		
		al_set_target_bitmap(front);

		al_draw_bitmap(back, 0, 0, 0);

		front_data = al_lock_bitmap(front, 
			al_get_bitmap_format(front), ALLEGRO_LOCK_READONLY);
	}
	front_updated = true;
	al_unlock_mutex(front_mutex);

	if(al_get_bitmap_width(back) != ssState.ScreenW
		|| al_get_bitmap_height(back) != ssState.ScreenH){
			al_destroy_bitmap(back);
			int32_t flags = al_get_new_bitmap_flags();
			if(al_get_current_display() != NULL){
				al_set_new_bitmap_flags(al_get_bitmap_flags(al_get_backbuffer(al_get_current_display())));
			}
			back = al_create_bitmap(ssState.ScreenW, ssState.ScreenH);
			al_set_new_bitmap_flags(flags);
	}

	al_set_target_bitmap(back);

    //do the ending timer stuff
    clock_t donetime = clock();
	ssTimers.overlay_time = (donetime - starttime)*0.1 + ssTimers.overlay_time*0.9;
}
Ejemplo n.º 5
0
MBITMAP *m_create_alpha_bitmap(int w, int h, void (*create)(MBITMAP *bitmap, RecreateData *), RecreateData *data, void (*destroy)(MBITMAP *b), bool delayed) // check
{
	int f = al_get_new_bitmap_format();
	al_set_new_bitmap_format(ALPHA_FMT);
	ALLEGRO_BITMAP *bitmap;
	int flags = al_get_new_bitmap_flags();

	int new_flags = flags;

	if (config.getUseOnlyMemoryBitmaps()) {
		al_set_new_bitmap_flags(new_flags|ALLEGRO_MEMORY_BITMAP);
		bitmap = my_al_create_bitmap(w, h);
	}
	else {
		bitmap = my_al_create_bitmap(w, h);
	}

	al_set_new_bitmap_flags(flags);
	al_set_new_bitmap_format(f);

	MBITMAP *m = new_mbitmap(bitmap);

	if (create) {
		create(m, data);
	}

#if defined ALLEGRO_ANDROID || defined ALLEGRO_WINDOWS
	if (
#ifdef ALLEGRO_WINDOWS
			(al_get_display_flags(display) & ALLEGRO_DIRECT3D) &&
#endif
			(al_get_bitmap_flags(bitmap) & ALLEGRO_NO_PRESERVE_TEXTURE) &&
			!(al_get_bitmap_flags(bitmap) & ALLEGRO_MEMORY_BITMAP)
	) {
		LoadedBitmap *lb = new LoadedBitmap;
		null_lb(lb);
		lb->load_type = LOAD_CREATE;
		lb->flags = al_get_bitmap_flags(bitmap);
		lb->format = al_get_bitmap_format(bitmap);
		lb->destroy.func = destroy;
		lb->recreate.func = create;
		lb->recreate.data = data;
		lb->recreate.w = w;
		lb->recreate.h = h;
		lb->bitmap = m;
		lb->delayed = delayed;
		loaded_bitmaps.push_back(lb);
	}
	else {
#endif
	if (data) {
		delete data;
	}
#if defined ALLEGRO_ANDROID || defined ALLEGRO_WINDOWS
	}
#endif

	return m;
}
Ejemplo n.º 6
0
/* Run the FPS test. */
static void run(void)
{
   ALLEGRO_EVENT event;
   int frames = 0;
   double start;

   target = al_create_bitmap(W, H);
   al_set_target_bitmap(target);
   al_clear_to_color(al_map_rgba_f(1, 1, 0, 1));

   al_set_target_backbuffer(display);

   dx = 81;
   dy = 63;

   start = al_get_time();
   while (true) {
      /* Check for ESC key or close button event and quit in either case. */
      if (!al_is_event_queue_empty(queue)) {
         while (al_get_next_event(queue, &event)) {
            switch (event.type) {
               case ALLEGRO_EVENT_DISPLAY_CLOSE:
                  quit = true;
                  goto done;

               case ALLEGRO_EVENT_KEY_DOWN:
                  if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
                     quit = true;
                     goto done;
                  }
                  if (event.keyboard.keycode == ALLEGRO_KEY_SPACE) {
                      goto done;
                  }
                  break;
            }
         }
      }
      draw();
      print(0, 0, "FPS: %.1f", frames / (al_get_time() - start));
      if (al_get_new_bitmap_flags() & ALLEGRO_FORCE_LOCKING) {
         print(0, al_get_font_line_height(myfont), "using forced bitmap locking");
      }
      else {
         print(0, al_get_font_line_height(myfont), "drawing directly to bitmap");
      }
      print(0, al_get_font_line_height(myfont) * 2,
         "Press SPACE to toggle drawing method.");
      al_flip_display();
      frames++;
   }

done:

   al_destroy_bitmap(target);
}
Ejemplo n.º 7
0
/* Function: al_load_bitmap_font
 */
ALLEGRO_FONT *al_load_bitmap_font(const char *fname)
{
   int flags = 0;

   /* For backwards compatibility with the 5.0 branch. */
   if (al_get_new_bitmap_flags() & ALLEGRO_NO_PREMULTIPLIED_ALPHA) {
      flags |= ALLEGRO_NO_PREMULTIPLIED_ALPHA;
   }

   return _al_load_bitmap_font(fname, 0, flags);
}
Ejemplo n.º 8
0
/* The menu item owns the icon bitmap. It is converted to a memory bitmap
 * when set to make sure any system threads will be able to read the data. 
 */
static void set_item_icon(ALLEGRO_MENU_ITEM *item, ALLEGRO_BITMAP *icon)
{
   item->icon = icon;
   
   if (icon && al_get_bitmap_flags(item->icon) & ALLEGRO_VIDEO_BITMAP) {
      int old_flags = al_get_new_bitmap_flags();
      al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
      item->icon = al_clone_bitmap(icon);
      al_destroy_bitmap(icon);
      al_set_new_bitmap_flags(old_flags);
   }
}
Ejemplo n.º 9
0
/* Function: al_create_bitmap
 */
ALLEGRO_BITMAP *al_create_bitmap(int w, int h)
{
   ALLEGRO_BITMAP *bitmap;

   bitmap = _al_create_bitmap_params(al_get_current_display(), w, h,
      al_get_new_bitmap_format(), al_get_new_bitmap_flags());
   if (bitmap) {
      _al_register_destructor(_al_dtor_list, "bitmap", bitmap,
         (void (*)(void *))al_destroy_bitmap);
   }

   return bitmap;
}
Ejemplo n.º 10
0
bool Imgui_ImplA5_CreateDeviceObjects()
{
    ImGuiIO &io = ImGui::GetIO();

    // Build texture
    unsigned char *pixels;
    int width, height;
    io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);

    // Create texture
    int flags = al_get_new_bitmap_flags();
    int fmt = al_get_new_bitmap_format();
    al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP|ALLEGRO_MIN_LINEAR|ALLEGRO_MAG_LINEAR);
    al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE);
    ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
    al_set_new_bitmap_flags(flags);
    al_set_new_bitmap_format(fmt);
    if (!img) 
        return false;

    ALLEGRO_LOCKED_REGION *locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
    if (!locked_img) 
    {
        al_destroy_bitmap(img);
        return false;
    }
    memcpy(locked_img->data, pixels, sizeof(int)*width*height);
    al_unlock_bitmap(img);

    // Convert software texture to hardware texture.
    ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
    al_destroy_bitmap(img);
    if (!cloned_img) 
        return false;

    // Store our identifier
    io.Fonts->TexID = (void*)cloned_img;
    g_Texture = cloned_img;

    // Cleanup (don't clear the input data if you want to append new fonts later)
    io.Fonts->ClearInputData();
    io.Fonts->ClearTexData();

    // Create an invisible mouse cursor
    // Because al_hide_mouse_cursor() seems to mess up with the actual inputs..
    ALLEGRO_BITMAP* mouse_cursor = al_create_bitmap(8,8);
    g_MouseCursorInvisible = al_create_mouse_cursor(mouse_cursor, 0, 0);
    al_destroy_bitmap(mouse_cursor);

    return true;
}
Ejemplo n.º 11
0
ALLEGRO_BITMAP *Object::create_memory_bitmap()
{
	setBit(ER_BITMAP);
	setBit(ISMEM_BITMAP);
	
    int flags = al_get_new_bitmap_flags();
    al_set_new_bitmap_flags(flags | ALLEGRO_MEMORY_BITMAP);
	
	ALLEGRO_BITMAP *bmp;
    bmp = al_create_bitmap(w, h);
	
    al_set_new_bitmap_flags(flags);
	
    return bmp;
}
Ejemplo n.º 12
0
MBITMAP *create_trapezoid(int dir, int topw, int bottomw, int length, MCOLOR color)
{
	MBITMAP *b;

	color.a = 1.0f;
	
	m_push_target_bitmap();

	int flgs = al_get_new_bitmap_flags();
	al_set_new_bitmap_flags(flgs & ~ALLEGRO_NO_PRESERVE_TEXTURE);
	
	if (dir == DIRECTION_NORTH) {
		b = m_create_bitmap(bottomw, length); // check
	}
	else if (dir == DIRECTION_EAST) {
		b = m_create_bitmap(length, bottomw); // check
	}
	else if (dir == DIRECTION_SOUTH) {
		b = m_create_bitmap(bottomw, length); // check
	}
	else {
		b = m_create_bitmap(length, bottomw); // check
	}

	al_set_new_bitmap_flags(flgs);

	m_set_target_bitmap(b);
	m_clear(m_map_rgba(0, 0, 0, 0));

	float y = get_trap_peak(topw, bottomw, length);

	if (dir == DIRECTION_NORTH) {
		m_draw_triangle(bottomw/2, length+y-1, 0, 0, bottomw-1, 0, color);
	}
	else if (dir == DIRECTION_EAST) {
		m_draw_triangle(-y, bottomw/2, length-1, 0, length-1, bottomw-1, color);
	}
	else if (dir == DIRECTION_SOUTH) {
		m_draw_triangle(bottomw/2, -y, bottomw-1, length-1, 0, length-1, color);
	}
	else if (dir == DIRECTION_WEST) {
		m_draw_triangle(length+y-1, bottomw/2, 0, 0, 0, bottomw-1, color);
	}

	m_pop_target_bitmap();

	return b;
}
Ejemplo n.º 13
0
MBITMAP *m_load_bitmap(const char *name, bool force_memory, bool ok_to_fail)
{
	ALLEGRO_BITMAP *bitmap = 0;
	int flags = al_get_new_bitmap_flags();

	if (force_memory || config.getUseOnlyMemoryBitmaps()) {
		al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
	}
	else {
		al_set_new_bitmap_flags((flags & ~ALLEGRO_MEMORY_BITMAP));
	}

	bitmap = my_load_bitmap(name, ok_to_fail);

	al_set_new_bitmap_flags(flags);

	if (!bitmap) {
		return NULL;
	}

	MBITMAP *m = new_mbitmap(bitmap);

#if defined ALLEGRO_ANDROID || defined ALLEGRO_WINDOWS
	if (
#ifdef ALLEGRO_WINDOWS
			(al_get_display_flags(display) & ALLEGRO_DIRECT3D) &&
#endif
			(al_get_bitmap_flags(bitmap) & ALLEGRO_NO_PRESERVE_TEXTURE) &&
			!(al_get_bitmap_flags(bitmap) & ALLEGRO_MEMORY_BITMAP)
	) {
		LoadedBitmap *lb = new LoadedBitmap;
		null_lb(lb);
		lb->load_type = LOAD_LOAD;
		lb->flags = al_get_bitmap_flags(bitmap);
		lb->format = al_get_bitmap_format(bitmap);
		lb->load.filename = name;
		lb->load.redraw = NULL;
		lb->load.data = NULL;
		lb->bitmap = m;
		loaded_bitmaps.push_back(lb);
	}
#endif

	return m;
}
Ejemplo n.º 14
0
BigBitmap::BigBitmap(std::string bitmap_to_load, float sector_width, float sector_height) : region_size_w(sector_width), region_size_h(sector_height)
{
    ALLEGRO_BITMAP *restoreto =al_get_target_bitmap();

    orig_flags = al_get_new_bitmap_flags();
    al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_MAG_LINEAR | ALLEGRO_MIN_LINEAR);
    big_bitmap = al_load_bitmap(bitmap_to_load.c_str());

    if(big_bitmap == nullptr)
    {
        al_show_native_message_box(NULL, "Error", "Failed to load Image", bitmap_to_load.c_str(), NULL, ALLEGRO_MESSAGEBOX_ERROR);
    }

    orig_width = width = al_get_bitmap_width(big_bitmap);
    orig_height = height = al_get_bitmap_height(big_bitmap);
    w_regions = ceil(orig_width / region_size_w);
    h_regions = ceil(orig_height / region_size_h);

    float vector_size = w_regions+1 + h_regions+1;
    bitmaps.reserve(vector_size);

    al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP | ALLEGRO_MAG_LINEAR | ALLEGRO_MIN_LINEAR);

    for(int h = 0; h < h_regions; h++)
    {
        for(int w = 0; w < w_regions; w++)
        {
            bitmaps.push_back(al_create_bitmap(region_size_w, region_size_h));
            al_set_target_bitmap(bitmaps[bitmaps.size()-1]);
            al_clear_to_color(al_map_rgb(0,0,0));
            al_draw_bitmap_region(big_bitmap, w*region_size_w, h*region_size_h, region_size_w, region_size_h, 0, 0, 0);
            #ifdef _BBDEBUG
            std::string cont = "["+ std::to_string(h) +","+ std::to_string(w) +"]";
            al_draw_text(dgbf, al_map_rgb(255,0,0),region_size_w/2,region_size_h/2,ALLEGRO_ALIGN_CENTRE,cont.c_str());
            al_draw_rectangle(0,0,region_size_w, region_size_h, al_map_rgb(255,0,0),0);
            #endif // _BBDEBUG
        }
    }

    al_set_new_bitmap_flags(orig_flags);
    al_set_target_bitmap(restoreto);
}
Ejemplo n.º 15
0
MFONT *m_load_font(const char *name)
{
	ALLEGRO_FONT *f;

	int flags = al_get_new_bitmap_flags();
	al_set_new_bitmap_flags(flags & ~ALLEGRO_NO_PRESERVE_TEXTURE);

	f = al_load_font(name, 0, 0);
	if (f) {
		al_set_new_bitmap_flags(flags);
		return f;
	}

	debug_message("couldn't load font: using mem bitmaps");

	al_set_new_bitmap_flags(flags|ALLEGRO_MEMORY_BITMAP);
	f = al_load_font(name, 0, 0);
	al_set_new_bitmap_flags(flags);
	return f;
}
int main(void)
{
   if (!al_init()) {
      abort_example("Could not init Allegro.\n");
      return 1;
   }

   al_init_primitives_addon();
   al_install_keyboard();
   al_init_image_addon();
   al_init_font_addon();

   display = al_create_display(640, 480);
   if (!display) {
      abort_example("Error creating display\n");
      return 1;
   }

   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));

   myfont = al_load_font("data/font.tga", 0, 0);
   if (!myfont) {
      abort_example("font.tga not found\n");
      return 1;
   }

   while (!quit) {
      if (al_get_new_bitmap_flags() & ALLEGRO_FORCE_LOCKING)
         al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
      else
         al_set_new_bitmap_flags(ALLEGRO_FORCE_LOCKING);
      run();
   }

   al_destroy_event_queue(queue);  
   
   return 0;
}
Ejemplo n.º 17
0
static int allua_Bitmap_get_new_flags(lua_State * L)
{
   lua_pushinteger(L, al_get_new_bitmap_flags());
   return 1;
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
static ALLEGRO_BITMAP *do_create_bitmap(int w, int h)
{
   ALLEGRO_BITMAP *bitmap;
   ALLEGRO_BITMAP **back;
   ALLEGRO_SYSTEM *system = al_get_system_driver();
   ALLEGRO_DISPLAY *current_display = al_get_current_display();
   int64_t mul;

   /* Reject bitmaps where a calculation pixel_size*w*h would overflow
    * int.  Supporting such bitmaps would require a lot more work.
    */
   mul = 4 * (int64_t) w * (int64_t) h;
   if (mul > (int64_t) INT_MAX) {
      ALLEGRO_WARN("Rejecting %dx%d bitmap\n", w, h);
      return NULL;
   }

   if ((al_get_new_bitmap_flags() & ALLEGRO_MEMORY_BITMAP) ||
         (!current_display || !current_display->vt || current_display->vt->create_bitmap == NULL) ||
         (system->displays._size < 1)) {
      return _al_create_memory_bitmap(w, h);
   }

   /* Else it's a display bitmap */

   bitmap = current_display->vt->create_bitmap(current_display, w, h);
   if (!bitmap) {
      ALLEGRO_ERROR("failed to create display bitmap\n");
      return NULL;
   }

   /* XXX the ogl_display driver sets some of these variables. It's not clear
    * who should be responsible for setting what.
    * The pitch must be set by the driver.
    */
   bitmap->display = current_display;
   bitmap->w = w;
   bitmap->h = h;
   bitmap->locked = false;
   bitmap->cl = 0;
   bitmap->ct = 0;
   bitmap->cr_excl = w;
   bitmap->cb_excl = h;
   al_identity_transform(&bitmap->transform);
   bitmap->parent = NULL;
   bitmap->xofs = 0;
   bitmap->yofs = 0;
   bitmap->preserve_texture = !(al_get_new_bitmap_flags() & ALLEGRO_NO_PRESERVE_TEXTURE);

   ASSERT(bitmap->pitch >= w * al_get_pixel_size(bitmap->format));

   /* The display driver should have set the bitmap->memory field if
    * appropriate; video bitmaps may leave it NULL.
    */

   if (!bitmap->vt->upload_bitmap(bitmap)) {
      al_destroy_bitmap(bitmap);
      return NULL;
   }

   /* We keep a list of bitmaps depending on the current display so that we can
    * convert them to memory bimaps when the display is destroyed. */
   back = _al_vector_alloc_back(&current_display->bitmaps);
   *back = bitmap;

   return bitmap;
}
Ejemplo n.º 20
0
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;
	}