Skip to content

Instantly share code, notes, and snippets.

@takkaria
Last active August 29, 2015 14:22
Show Gist options
  • Save takkaria/1cc7ac38330a30691c19 to your computer and use it in GitHub Desktop.
Save takkaria/1cc7ac38330a30691c19 to your computer and use it in GitHub Desktop.
Some thoughts on the building blocks of better Angband tile handling

Here I propose two new modules (panel and grafgrid) along with some changes to z-term, that will help build new graphics handling without duplication and while keeping the logic of graphics handling cross-platform. This is not an exhaustive list of steps but could form a barebone structure to develop further.

The two new modules handle all the hard work of panel tracking and efficient redraws, so that all the frontend has to do, much like z-term, is draw the right things when it's told to. Both new modules should be relatively easy to build using unit tests.

The upshot of this is that we draw the graphics to a separate canvas to the term display, and then blit them onto the final display surface one after the other, perhaps double-buffering if appropriate.

TO RESOLVE:

  • if we are to transition for separate graphic files per tile, then maybe we should include a module for managing that, too. but the current attr/char method is locked in for now, until the above system works on all current graphics-supporting platforms (lol), because until z-term no longer needs to handle graphics the 0x80 offset + tileset method has to remain.

Changes to z-term

z-term should by default have no bg colour - should be transparent. bg colour only set on draw. This means a graphics grid can be drawn underneath and the text will overlay it.

New panel module

The frontend creates a panel.

Panels are logical displays of a given area of the dungeon. They are simply structures of (x,y,wid,hgt). The frontend creates a panel. A specified function is called when the panel changes, and another when a grid inside it changes.

The panel manager (panels_*) keeps track of all these panels and the contents of these panels are considered 'onscreen'.

This is functionality that already exists but in a way thoroughly entwined with other code, and when split out cleanly will probably be a net code reduction.

struct panel {
	struct cave *c; ??

	int x;
	int y;
	int wid;
	int hgt;
};

struct panel *panel_create(void);
void panel_set_size(struct panel *p, int y, int x, int wid, int hgt);
void panel_onpanelchange(struct panel *p, *(void)(struct panel *, void *user));
void panel_ongridchange(struct panel *p, *(void)(struct panel *, struct loc));
void panel_destroy(struct panel *p);

void panels_contain(int y, int x);

TO RESOLVE:

  • Should this be set on a particular struct cave *?

New grafgrid module

The frontend creates a grafgrid. grafgrids track a panel.

Grafgrids subscribe to map updates in the panel area, and when grids change, they first send a 'clear' event, followed by one or more 'draw' events. When multiple draw events are sent, tiles are to be drawn on top of each other. This is similar functionality to the 'transparency' layer in z-term, except more than two tiles can be layered.

The benefit of this approach is that like z-term, redraw improvements and graphic logic for multiple platforms is shared.

struct grafgrid *grafgrid_new(struct panel *);
void grafgrid_ongridclear(drawtile);
void grafgrid_ongridchange(cleartile);
void grafgrid_destroy(struct grafgrid *);

void drawtile(struct grafgrid *, struct loc, [some specification of tile id]);
void cleartile(struct grafgrid *, struct loc)

TO RESOLVE:

  • can extend in future to draw graphic effects on tiles
  • should these events include spell effects? (yes)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment