Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » How to make a resizable window in Allegro 5

This thread is locked; no one can reply to it. rss feed Print
How to make a resizable window in Allegro 5
DidaFM
Member #16,802
January 2018

Hello guys, this is my first post on this site so I hope I'm not making anything wrong.
Straight to the point:
I'm developing a simple game in C, that consists of zombies chasing humans, and is executed and played on the ubuntu console but I wanted to make another window with an actual dynamic interface. So what I did was create a separate file that reads the program and executes an allegro window to show it.
I already have it working perfectly, but I wanted the window to be resizable!! Problem is I was able to make it resizable but only the display, all of the contents (like the background and the zombies and humans) stay in the same place...

I use three functions in the document for the visualization of the world, one to create it (showworld_new), one to update it (showworld_update) and one to destroy it (showworld_destroy), which I then call on the main program.

If you could help me with any tips u have

#include "showworld.h"
#include <stdio.h>
#include <stdlib.h>
#include "allegro5/allegro.h"
#include "allegro5/allegro_font.h"
#include "allegro5/allegro_ttf.h"
#include "allegro5/allegro_image.h"
#include "allegro5/allegro_color.h"
#include "allegro5/allegro_primitives.h"

/* The implementation of SHOWWORLD type used in this simple text-based world
* visualization code. In this simple case, we only need to keep track of the
* world dimensions and of the function pointer which knows how to read an
* agent from the world data structure.
* */
struct showworld {
unsigned int xdim;
unsigned int ydim;
get_agent_info_at aginfo_func;
};

/* Variable for the canvas */
ALLEGRO_DISPLAY *display = NULL;

ALLEGRO_EVENT_QUEUE *event_queue;
ALLEGRO_EVENT event;

ALLEGRO_TIMEOUT timeout;

ALLEGRO_FONT *font1 = NULL;
ALLEGRO_FONT *font2 = NULL;

/* Variables of the drawings of the agents on the canvas*/
ALLEGRO_BITMAP *h_playable = NULL;
ALLEGRO_BITMAP *h_ai = NULL;
ALLEGRO_BITMAP *z_playable = NULL;
ALLEGRO_BITMAP *z_ai = NULL;
ALLEGRO_BITMAP *none = NULL;

int w_init, h_init, w_new, h_new;
int reason_w = 1, reason_h = 1;

/* Create a new display/visualization object for the simulation world.
*
* This function obeys the showworld_new() prototype defined in
* showworld.h. */
SHOWWORLD *showworld_new(
unsigned int xdim,
unsigned int ydim,
get_agent_info_at aginfo_func) {

al_init();
al_init_image_addon();
al_init_font_addon();
al_init_ttf_addon();

al_set_new_display_flags(ALLEGRO_WINDOWED);
al_set_new_display_flags(ALLEGRO_RESIZABLE);

SHOWWORLD *sw = NULL;
sw = malloc(sizeof(SHOWWORLD));
sw->xdim = xdim;
sw->ydim = ydim;
sw->aginfo_func = aginfo_func;

display = al_create_display((sw->xdim)*32, (sw->ydim)*32);

event_queue = al_create_event_queue();
al_register_event_source(event_queue, al_get_display_event_source(display));
event.type == ALLEGRO_EVENT_DISPLAY_RESIZE;
al_acknowledge_resize(display); //MY MAIN PROBLEM IS HERE, I DONT UNDERSTAND

font1 = al_load_font("uni0553.ttf",16,0);
font2 = al_load_font("uni0553.ttf",16,0);
al_clear_to_color(al_map_rgb(0,0,0));

w_init = (int *)((sw->xdim) * 32);
h_init = (int *)((sw->ydim) * 32);

w_new = al_get_display_width(display);
h_new = al_get_display_height(display);

if (w_init > w_new) {
reason_w = w_init/w_new;
} else {
reason_w = w_new/w_init;
}

if (h_init > h_new) {
reason_h = h_init/h_new;
} else {
reason_h = h_new/h_init;
}

printf("%d\n", h_new);
/* w_init = ((sw->xdim) * 32);
h_init = ((sw->ydim) * 32);

w_new = al_get_display_width(display);
h_new = al_get_display_width(display);

if (w_init > w_new) {
reason_w = w_init/w_new;
} else {
reason_w = w_new/w_init;
}

if (h_init > h_new) {
reason_h = h_init/h_new;
} else {
reason_h = h_new/h_init;
}

al_resize_display(display, w_init * reason_w, h_init * reason_h ); /*

/* int larg = xdim.innerWidth;
int alt = ydim.innerHeight;
display.setAttribute("width", larg);
display.setAttribute("height", alt);*/

/*if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
al_destroy_event_queue(event_queue);
al_destroy_display(display);
}*/
/*if (event.type == ALLEGRO_EVENT_DISPLAY_RESIZE) {
al_resize_display(display,(sw->xdim)+1,(sw->ydim)+1);
al_get_window_constraints(display,(sw->xdim),(sw->ydim),(sw->xdim)*100,(sw->xdim)*100);
al_acknowledge_resize(display);
}*/

return sw;

}

/* Destroy a display/visualization object for the simulation world.
*
* This function obeys the showworld_destroy() prototype defined in
* showworld.h. */
void showworld_destroy(SHOWWORLD *sw) {

al_destroy_bitmap(h_playable);
al_destroy_bitmap(h_ai);
al_destroy_bitmap(z_playable);
al_destroy_bitmap(z_ai);
al_destroy_display(display);
al_destroy_event_queue(event_queue);
free(sw);
}

/* Update the simulation world display/visualization.
*
* This function obeys the showworld_update() prototype defined in
* showworld.h. */
void showworld_update(SHOWWORLD *sw, void *w) {

printf("%d\n", h_new);

/* Load the respective images of each type */
h_playable = al_load_bitmap("Human1.png");
h_ai = al_load_bitmap("Human2.png");
z_playable = al_load_bitmap("Zombie1.png");
z_ai = al_load_bitmap("Zombie2.png");
none = al_load_bitmap("Bg.png");

/* Cycle through all the rows */
for (unsigned int y = 0; y < sw->ydim; ++y) {

/* Cycle through all the columns for the current row */
for (unsigned int x = 0; x < sw->xdim; ++x) {

/* Get state of the world (in bit packed fashion) using the user
supplied function. */
unsigned int item = sw->aginfo_func(w, x, y);

/* Extract the agent type (2 bits). */
AGENT_TYPE ag_type = item & 0x3;
/* Extract whether the agent is playable (1 bit). */
unsigned char playable = (item >> 2) & 0x1;
/* Extract the agent ID (16 bits). */
unsigned short ag_id = (item >> 3) & 0xFFFF;

/* Determine the agent type. */
switch (ag_type) {

/* If no agent is present at (x,y), draw Bg. */
case None:
al_draw_bitmap(none, x*32*reason_w, y*32*reason_h, 0);
break;

/* If human agent present at (x,y) draw Human1 or Human2. */
case Human:
if (playable) {
/* Human1 for player-controlled human agent. */
al_draw_bitmap(h_playable, x*32*reason_w, y*32*reason_h, 0);
} else {
/* Human2 for AI-controlled human agent. */
al_draw_bitmap(h_ai, x*32*reason_w, y*32*reason_h, 0);
}
/* Print the agent ID in front of it's image. */
al_draw_textf(font1, al_map_rgb(255,255,255), x*32*reason_w, (y*32+10)*reason_h, 0, "%i", ag_id);
//printf("%02X ", ag_id);
break;

/* If zombie agent present at (x,y) draw Zombie1 or Zombie2. */
case Zombie:
if (playable) {
/* Zombie1 for player-controlled zombie agent. */
al_draw_bitmap(z_playable, x*32*reason_w, y*32*reason_h, 0);
} else {
/* Zombie2 for AI-controlled zombie agent. */
al_draw_bitmap(z_ai, x*32*reason_w, y*32*reason_h, 0);
}
/* Print the agent ID in front of the image. */
al_draw_textf(font1, al_map_rgb(200,0,0), x*32*reason_w, (y*32+10)*reason_h, 0, "%i", ag_id);
//printf("%02X ", ag_id);
break;

/* Print '?' if unknown type detected. This should never
happen. */
default:
al_draw_text(font1, al_map_rgb(255,255,255), x*32*reason_w, y*32*reason_h, 0, "?");

}
}

/* Print two newlines after each row. */
//printf("\n\n");

}
al_resize_display(display, w_init * reason_w, h_init * reason_h );
/* Print a newline after world is shown/updated. */
al_flip_display();
//printf("\n");

}

bamccaig
Member #7,536
July 2006
avatar

To make it easier to read your post please edit it (there is an icon with a pencil) and wrap the code in <code> tags (XHTML style). :)

I don't know of a good answer to your question, but that will help somebody that does. I think it's rare for games to be resizeable in this way precisely for this reason. It's difficult to scale all of the drawn content to fit the window properly. A robust job might have to detect certain "thresholds" and change the scale of content (e.g., text) to keep it usable. Most games just let you choose a "resolution" and then can either load content specifically made for that resolution, or possibly scale the content dynamically at the setting change to adjust. I think Allegro 4 used to support scaled drawing too so it's likely Allegro 5 supports it too, but the graphics will necessarily lose quality in the process.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Go to: