1 /*
2  * PROPRIETARY INFORMATION.  This software is proprietary to POWDER
3  * Development, and is not to be reproduced, transmitted, or disclosed
4  * in any way without written permission.
5  *
6  * Produced by:	Jeff Lait
7  *
8  *      	POWDER Development
9  *
10  * NAME:        gfxengine.h ( POWDER Library, C++ )
11  *
12  * COMMENTS:
13  * 	Platform independent graphics engine.
14  * 	The mentioned tiles are the tile number in the resource files.
15  * 	The world consists of 32x32, 16x16 tiles.
16  */
17 
18 #ifndef __gfxengine_h__
19 #define __gfxengine_h__
20 
21 #include "glbdef.h"
22 #include "buf.h"
23 
24 // These are special symbols in our character set.  The SYMBOLSTRING
25 // version is "".
26 #define SYMBOL_HEART		'\200'
27 #define SYMBOLSTRING_HEART	"\200"
28 #define SYMBOL_MAGIC		'\201'
29 #define SYMBOLSTRING_MAGIC	"\201"
30 #define SYMBOL_LEFT		'\202'
31 #define SYMBOLSTRING_LEFT	"\202"
32 #define SYMBOL_RIGHT		'\203'
33 #define SYMBOLSTRING_RIGHT	"\203"
34 #define SYMBOL_UP		'\204'
35 #define SYMBOLSTRING_UP		"\204"
36 #define SYMBOL_DOWN		'\205'
37 #define SYMBOLSTRING_DOWN	"\205"
38 #define SYMBOL_NEXT		'\206'
39 #define SYMBOLSTRING_NEXT	"\206"
40 #define SYMBOL_DLEVEL		'\207'
41 #define SYMBOLSTRING_DLEVEL	"\207"
42 #define SYMBOL_AC		'\210'
43 #define SYMBOLSTRING_AC		"\210"
44 #define SYMBOL_TRIDUDE		'\211'
45 #define SYMBOLSTRING_TRIDUDE	"\211"
46 #define SYMBOL_CURSOR		'\212'
47 #define SYMBOLSTRING_CURSOR	"\212"
48 #define SYMBOL_UNIQUE		'\213'
49 #define SYMBOLSTRING_UNIQUE	"\213"
50 
51 // 230 in octal...
52 #define COLOURED_SYMBOLS	152
53 
54 #define SYMBOL_STRENGTH		'S'
55 #define SYMBOLSTRING_STRENGTH	"S"
56 #define SYMBOL_SMARTS		'I'
57 #define SYMBOLSTRING_SMARTS	"I"
58 #define SYMBOL_EXP		'X'
59 #define SYMBOLSTRING_EXP	"X"
60 
61 // Key defines.
62 #define GFX_KEYMODSHIFT		1
63 #define GFX_KEYMODCTRL		2
64 #define GFX_KEYMODALT		4
65 
66 enum GFX_Keydefine
67 {
68     GFX_KEYSTART = 256,
69     GFX_KEYUP,
70     GFX_KEYLEFT,
71     GFX_KEYRIGHT,
72     GFX_KEYDOWN,
73     GFX_KEYCTRLUP,
74     GFX_KEYCTRLLEFT,
75     GFX_KEYCTRLRIGHT,
76     GFX_KEYCTRLDOWN,
77     GFX_KEYPGUP,
78     GFX_KEYPGDOWN,
79     GFX_KEYLMB,
80     GFX_KEYMMB,
81     GFX_KEYRMB,
82     // We expect these to be contiguous.
83     GFX_KEYF1,
84     GFX_KEYF2,
85     GFX_KEYF3,
86     GFX_KEYF4,
87     GFX_KEYF5,
88     GFX_KEYF6,
89     GFX_KEYF7,
90     GFX_KEYF8,
91     GFX_KEYF9,
92     GFX_KEYF10,
93     GFX_KEYF11,
94     GFX_KEYF12,
95     GFX_KEYF13,
96     GFX_KEYF14,
97     GFX_KEYF15,
98     GFX_KEYLAST
99 };
100 
101 class MAP;
102 class MOB;
103 
104 // Global defines...
105 #define MAP_WIDTH	32
106 #define MAP_HEIGHT	32
107 
108 #define INVALID_TILEIDX		65535
109 
110 //
111 // Fake ham functions used by SDL code.
112 //
113 void hamfake_rebuildScreen();
114 void hamfake_awaitEvent();
115 
116 // Locks the screen for writing as a 240x160x16bit plane.
117 u16 *hamfake_lockScreen();
118 void hamfake_unlockScreen(u16 *screen);
119 
120 // For systems that support it, get a keypress.
121 int hamfake_peekKeyPress();
122 int hamfake_getKeyPress(bool onlyascii);
123 void hamfake_clearKeyboardBuffer();
124 void hamfake_insertKeyPress(int key);
125 int hamfake_getKeyModifiers();
126 
127 // Returns the current stylus/mouse location.
128 // Returned in terms of screen pixels
129 void hamfake_getstyluspos(int &x, int &y);
130 
131 // Returns if the stylus is currently pressed or not.
132 // If not pressed, you should not trust the pos!
133 bool hamfake_getstylusstate();
134 
135 // Returns if an extra tileset is present in the system
136 bool hamfake_extratileset();
137 
138 // Reboots the machine.
139 void hamfake_softReset();
140 
141 // Returns true if the external UI has demanded POWDER to shutdown.
142 bool hamfake_forceQuit();
143 
144 // External UI directions.
145 void hamfake_flushdir();
146 bool hamfake_externaldir(int &dx, int &dy);
147 
148 void hamfake_buttonreq(int mode,	// 0 move, 1 action, 2 spell, 3 del
149 					// 4 defaults
150 					// 5 Direction request.
151 					// 6 Unlock request
152 			int type = 0);	// action/spell value.
153 
154 // awaitShutdown is used by external UI to wait until POWDER has finsihed
155 // an emergency save & quit sparked by forceQuit.
156 // POWDER lets the ui know it is done with the postShutdown
157 void hamfake_awaitShutdown();
158 void hamfake_postShutdown();
159 
160 void hamfake_setinventorymode(bool invmode);
161 void hamfake_enableexternalactions(bool enable);
162 void hamfake_externalaction(int &iact, int &ispell);
163 bool hamfake_isunlocked();
164 
165 // Toggles full screen mode
166 void hamfake_setFullScreen(bool fullscreen);
167 bool hamfake_isFullScreen();
168 
169 // Controls sprites by their OAM numbers.
170 void hamfake_movesprite(int spriteno, int x, int y);
171 void hamfake_enablesprite(int spriteno, bool enabled);
172 
173 void hamfake_ReloadSpriteGfx(const u16 *data, int tileno, int numtile);
174 void hamfake_setTileSize(int tilewidth, int tileheight);
175 
176 void hamfake_LoadSpritePal(void *data, int bytes);
177 
178 #ifdef HAS_DISKIO
179 FILE *hamfake_fopen(const char *path, const char *mode);
180 bool hamfake_fatvalid();
181 #endif
182 
183 void gfx_init();
184 
185 void gfx_setmode(int mode);
186 
187 // This finds a free tile block of the given size...
188 u16 gfx_findFreeTile(int size);
189 
190 // These lock the tile, returning an index to be used in the map.
191 // Failure returns -1.  unlockTile frees it for further use.
192 // The actual tile allocated is passed back in result - that is the
193 // value that should be used in the free!
194 u16 gfx_lockTile(TILE_NAMES tile, TILE_NAMES *result);
195 void gfx_unlockTile(TILE_NAMES tile);
196 
197 // Ensures the tile is locked at least given number.  The idea is that one
198 // intends to leave a stale lock pointer, but don't want the stale
199 // pointer to accumulate over time.
200 void gfx_forceLockTile(TILE_NAMES tile, int mincount = 1);
201 
202 // These lock character tiles which are on the same tile array
203 // as the other tiles.
204 // The actual tile allocated is passed back in result - that is the
205 // value that should be used in the free!
206 u16 gfx_lockCharTile(u8 c, u8 *result);
207 u16 gfx_lockColourCharTile(u8 c, COLOUR_NAMES colour, u8 *result);
208 void gfx_unlockCharTile(u8 c);
209 
210 // Looking up a tile will find the tile idx for the given name.
211 // It will not lock it.  This can be used for refresh, etc.
212 // If it returns the invalid index, the tile doesn't exist and the
213 // generic should be used.
214 u16 gfx_lookupTile(TILE_NAMES tile);
215 
216 // This returns the number of unused tiles.
217 int gfx_getNumFreeTiles();
218 
219 // Note these all work with TILE_NAMES, NOT the tile index.
220 void gfx_refreshtiles();
221 void gfx_settile(int tx, int ty, int tileno);
222 // This sets the overlay tile.
223 void gfx_setoverlay(int tx, int ty, int tileno);
224 int gfx_getoverlay(int tx, int ty);
225 // This sets the mob layer tiles
226 void gfx_setmoblayer(int tx, int ty, int tileno);
227 int gfx_getmoblayer(int tx, int ty);
228 
229 // These set tiles using absolute coordinates starting from top left
230 // of the screen.  The screen is thus 17x12.
231 // These do NOT use, or set, the tile caches, so refreshtiles will
232 // undo them.
233 void gfx_setabstile(int tx, int ty, int tileno);
234 void gfx_setabsoverlay(int tx, int ty, int tileno);
235 void gfx_setabsmob(int tx, int ty, int tileno);
236 
237 // This clears the given line of any text.
238 void gfx_cleartextline(int y, int startx=0);
239 
240 // This prints the text on the screen relative coords x/y, which
241 // are in text coords, screen is 30x20.
242 void gfx_printtext(int x, int y, const char *text);
gfx_printtext(int x,int y,BUF buf)243 inline void gfx_printtext(int x, int y, BUF buf)
244 { gfx_printtext(x, y, buf.buffer()); }
245 
246 // This writes a character into a mode 3 buffer.
247 // x & y are pixel level offsets.
248 void gfx_printcharraw(int x, int y, char c);
249 void gfx_printcolourcharraw(int x, int y, char c);
250 
251 // This also works in screen coords, writing a single character.
252 void gfx_printchar(int x, int y, char c);
253 
254 // Remaps the character to a coloured character.
255 // Each coloured character has its own unique tile!
256 void gfx_printcolourchar(int x, int y, char c, COLOUR_NAMES colour);
257 
258 // Returns the current center of the viewport in tiles
259 void gfx_getscrollcenter(int &cx, int &cy);
260 
261 // This scrolls so tx/ty is the center tile in the viewport.
262 void gfx_scrollcenter(int tx, int ty);
263 
264 // Adjust the pixel level scroll by the given number of pixels
265 // on the given layer.
266 void gfx_nudgecenter(int px, int py);
267 
268 // This returns true if we are on a new frame, and then resets
269 // its new frame counter.
270 int gfx_isnewframe();
271 
272 // This returns the current frame number.
273 int gfx_getframecount();
274 
275 void gfx_displayminimap(MAP *level);
276 void gfx_hideminimap();
277 
278 void gfx_showinventory(MOB *mob);
279 void gfx_hideinventory();
280 void gfx_getinvcursor(int &ix, int &iy);
281 void gfx_setinvcursor(int ix, int iy, bool onlyslots);
282 
283 // Find the palette entry which most closely matches the given RGB.
284 int gfx_lookupcolor(int r, int g, int b);
285 int gfx_lookupcolor(int r, int g, int b, const u16 *palette);
286 // Find the palette entry for the given predefine.
287 int gfx_lookupcolor(COLOUR_NAMES color);
288 
289 void gfx_updatespritegreytable();
290 const u8 *gfx_getspritegreytable();
291 
292 // Pauses for the given number of vertical retraces.
293 void gfx_sleep(int vcycles);
294 
295 // Displays a null terminated list.
296 // ylen is the maximum y to write to.
297 // Select will be vaguely centered and will have >< around it.
298 void gfx_displaylist(int x, int y, int ylen, const char **list, int select);
299 
300 // Null terminated list which is prompted at x & y.  Returns -1
301 // if cancelled, otherwise, index into list.
302 // If the any button is set, it will select with R & L.  In this case,
303 // aorb is set to the appropraite BUTTON_ value.
304 // Actually, it only selects with R&L if disable paging is set, otherwise
305 // those are pageup/pagedown.  SELECT, on the other hand, is enabled
306 // with anykey.
307 // If an action bar is specified, it will become *live* and one can
308 // drag stuff too and from it.
309 int gfx_selectmenu(int x, int y, const char **menu, int &aorb, int def=0,
310 		    bool anykey = false, bool disablepaging = false,
311 		    const u8 *menuactions = 0,
312 		    u8 *actionstrip = 0);
313 
314 // Queries with on screen menu to confirm choice with yes/no prompt
315 // yes returns true, no false.
316 bool gfx_yesnomenu(const char *buf, bool defchoice = true);
317 inline bool gfx_yesnomenu(BUF buf, bool defchoice = true)
318 { return gfx_yesnomenu(buf.buffer(), defchoice); }
319 
320 // This takes a long list which it displays 30 chars at a time,
321 // allowing the user to scroll as necessary.
322 // Any key ends it. (and clears it)
323 void gfx_displayinfotext(const char *text);
gfx_displayinfotext(BUF buf)324 inline void gfx_displayinfotext(BUF buf)
325 { gfx_displayinfotext(buf.buffer()); }
326 
327 // These routines allow you to dynamically create a long section of text.
328 // Each line can be greater than 30 chars and will word wrap properly.
329 // Nothing will be shown until the gfx_pager_display, at which
330 // point it will all be displayed in a scrollable view until
331 // a key is hit.  At that point, the temporary structures will
332 // all be wiped.
333 void
334 gfx_pager_addtext(const char *text);
335 void
336 gfx_pager_addtext(BUF buf);
337 
338 // Adds a single line to the pager.  Forces this to start
339 // a new line, adds a new line afterwards.  If text is over 30 chars,
340 // it is truncated.
341 void
342 gfx_pager_addsingleline(const char *text);
343 
344 void
345 gfx_pager_newline();
346 
347 void
348 gfx_pager_reset();
349 
350 // Adds a --- separator and a new line afterwards.
351 void
352 gfx_pager_separator();
353 
354 // Sets the width of the pager, does not get auto reset so be careful
355 void
356 gfx_pager_setwidth(int width);
357 
358 // Saves the pager data to a text file.  Also resets the pager.
359 void
360 gfx_pager_savetofile(const char *name);
gfx_pager_savetofile(BUF buf)361 inline void gfx_pager_savetofile(BUF buf) { gfx_pager_savetofile(buf.buffer()); }
362 
363 // The given y value is the initial center of the text.
364 void
365 gfx_pager_display(int centery = 0);
366 
367 // Returns true if a tile was selected, false if cancelled.
368 // tx & ty should start off at initial selection position.
369 // if quickselect is true, it will return immediately on the first
370 // movement key.  The bool in this case will be false until a or
371 // b is pressed.  aorb will be set to 0 if a pressed, 1 if b.
372 // Stylus is set to true if stylus used to do selection.
373 bool gfx_selecttile(int &tx, int &ty, bool quickselect=false, int *quickold=0,
374 		    int *aorb = 0, bool *stylus = 0);
375 
376 // Assumes inventory currently displayed.  selectx & selecty are
377 // starting location to select from.  Returns true if user chose
378 // a new slot, false if they aborted.
379 bool gfx_selectinventory(int &selectx, int &selecty);
380 
381 // Returns true if not cancelled.
382 // If dz is set, the user decided up or down.
383 // If nothing is set, they decided themselves.
384 // Otherwise, we have a standard direction.
385 bool gfx_selectdirection(int tx, int ty, int &dx, int &dy, int &dz);
386 
387 // This copies the given mini tile on top of the given destination tile
388 // in graphics memory.
389 void gfx_copytiledata(TILE_NAMES desttile, MINI_NAMES minitile, bool ismale);
390 
391 // This only works ontop of the last dest tile to be written to.
392 void gfx_compositetile(ITEMSLOT_NAMES dstslot, MINI_NAMES minitile, bool ismale);
393 
394 // Allocates a tile and returns the contents, extracting from our
395 // graphics tile list.  Requires an explicit tileset as we don't
396 // want to end up with non-power of 2 suddenly.
397 // The result must be free()d
398 u8 *gfx_extractsprite(int tileset, SPRITE_NAMES tile);
399 u8 *gfx_extractlargesprite(SPRITE_NAMES tile, int grey, SPRITE_NAMES overlay);
400 
401 void gfx_switchfonts(int newfont);
402 int gfx_getfont();
403 
404 // We support two tile sets that external UIs can swap between at their
405 // leisure
406 void gfx_settilesetmode(int mode, int tileset);
407 int gfx_gettilesetmode(int mode);
408 void gfx_tilesetmode(int mode);
409 
410 // These affect/refer to the current set for the current mode.
411 void gfx_switchtilesets(int newtileset);
412 int gfx_gettileset();
413 int gfx_gettilewidth();
414 int gfx_gettileheight();
415 
416 // Cooridinates are in GBA space.
417 void gfx_drawcursor(int x, int y);
418 void gfx_cursortile(SPRITE_NAMES tile);
419 void gfx_removecursor();
420 
421 // Note that you cannot mix sprite and dungeon tiles.  You need to
422 // use one system or the other.
423 void gfx_spritetile(int spriteno, SPRITE_NAMES tile);
424 
425 // The sprite will be greyd out according to the grey variable.
426 // grey of 0 means entirely grey scale, 256 means full colour.
427 // greying starts from the top of the tile.
428 // The overlay tile will then be comped on top.
429 void gfx_spritetile_grey(int spriteno, SPRITE_NAMES tile, int grey, SPRITE_NAMES overlay);
430 
431 // Loads a sprite from the dungeon tileset, note you cannot mix
432 // with normal sprites!
433 void gfx_spritefromdungeon(int spriteno, TILE_NAMES tile);
434 // Switches whether we are in dungeon or sprite mode
435 void gfx_spritemode(bool usesprites);
436 
437 #endif
438