FANDOM


Below is the full text to winGL.h from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/winGL.h#line123]], for example.

The latest source code for vanilla NetHack is at Source code.


The NetHack General Public License applies to screenshots, source code and other content from NetHack.
1.    /* Copyright (C) 2002 Andrew Apted <ajapted@users.sourceforge.net> */
2.    /* NetHack may be freely redistributed.  See license for details.  */
3.    
4.    /*
5.     * SDL/GL window port for NetHack & Slash'EM.
6.     *
7.     * This file contains the common definitions.
8.     */
9.    
10.   #ifndef WINGL_H
11.   #define WINGL_H
12.   
13.   #ifdef GL_GRAPHICS
14.   extern struct window_procs sdlgl_hardw_procs;
15.   #endif
16.   
17.   #ifdef SDL_GRAPHICS
18.   extern struct window_procs sdlgl_softw_procs;
19.   #endif
20.   
21.   extern void FDECL(Sdlgl_parse_options, (char *, int, int));
22.   
23.   #ifdef VANILLA_GLHACK
24.   #define GLHACK_VER_HEX  0x110
25.   #define GLHACK_VER_STR  "1.1"
26.   #define SDLGL_PROGRAM  "glHack"
27.   #define SDLGL_ICON     "glHack"
28.   #define SDLGL_ENV_VAR  "GLHACKOPTIONS"
29.   #else
30.   #define SDLGL_PROGRAM  "Slash'EM SDL/GL"
31.   #define SDLGL_ICON     "Slash'EM"
32.   #define SDLGL_ENV_VAR  "SLASHEMGLOPTIONS"
33.   #endif
34.   
35.   
36.   /* ------------ internal definitions from here on ---------- */
37.   
38.   #ifdef WINGL_INTERNAL
39.   
40.   /* sanity check the defines */
41.   #ifndef USE_TILES
42.   #error USE_TILES not defined
43.   #endif
44.   #ifndef CLIPPING
45.   #error CLIPPING not defined
46.   #endif
47.   #ifdef CHANGE_COLOR
48.   #error CHANGE_COLOR defined
49.   #endif
50.   #ifdef OVERLAY
51.   #error OVERLAY defined
52.   #endif
53.   #ifdef MICRO
54.   #error MICRO defined
55.   #endif
56.   
57.   /* N.H uses compress/uncompress, conflicting with ZLIB headers */
58.   #undef compress
59.   #undef uncompress
60.   
61.   /* certain N.H #defines conflict with the SDL header files */
62.   #undef red
63.   #undef green
64.   #undef blue
65.   
66.   /* From tile.c */
67.   extern short glyph2tile[];
68.   
69.   /* extra includes we need */
70.   
71.   #include <SDL/SDL.h>
72.   #include <png.h>
73.   #include <assert.h>
74.   
75.   #ifdef GL_GRAPHICS
76.   #include <GL/gl.h>
77.   #else
78.   typedef unsigned int GLuint;
79.   #endif
80.   
81.   #define E extern
82.   
83.   /* inlining */
84.   #ifdef GH_INLINE 
85.   /* keep current definition (from Makefile) */
86.   #elif defined(__GNUC__)
87.   #define GH_INLINE  __inline__
88.   #elif defined(_MSC_VER)
89.   #define GH_INLINE  __inline
90.   #else
91.   #define GH_INLINE  /* nothing */
92.   #endif
93.   
94.   /* character munging macros for CTRL and ALT/META */
95.   #ifndef C
96.   #define C(c)   (0x1f & (c))
97.   #endif
98.   #ifndef M
99.   #define M(c)   (0x80 | (c))
100.  #endif
101.  
102.  
103.  /*
104.   *  GL_MAIN
105.   */
106.  
107.  extern int sdlgl_initialized;
108.  extern int sdlgl_software;
109.  
110.  extern SDL_Surface *sdlgl_surf;
111.  
112.  struct MenuItem
113.  {
114.    /* link in list */
115.    struct MenuItem *next;
116.    
117.    /* stuff given by add_menu().  The string is copied */
118.    int glyph;
119.    anything identifier;
120.    char accelerator;
121.    char groupacc;
122.    int attr;
123.    char *str;
124.    
125.    /* whether or not this item is selected.  When 0, the `count' field
126.     * will be ignored.
127.     */
128.    int selected;
129.    
130.    /* count given by user.  -1 when no count given */
131.    int count;
132.  };
133.  
134.  struct TextItem
135.  {
136.    /* link in list */
137.    struct TextItem *next;
138.    
139.    /* stuff given by putstr().  The string is copied */
140.    int attr;
141.    char *str;
142.  
143.    /* alignment position (used for reformatting) */
144.    int align;
145.  };
146.  
147.  #define POSKEY_ALLOW_REPEAT   0x0001
148.  #define POSKEY_DO_SCROLLBACK  0x0002
149.  
150.  /* Note: routines that are in the interface table (sdlgl_procs) begin
151.   * with a capital `S'.  Everything else has a lowercase `s'.
152.   */
153.  E void FDECL(Sdlgl_init_nhwindows, (int *, char **));
154.  E void NDECL(Sdlgl_get_nh_event) ;
155.  E void FDECL(Sdlgl_exit_nhwindows, (const char *));
156.  E void FDECL(Sdlgl_suspend_nhwindows, (const char *));
157.  E void NDECL(Sdlgl_resume_nhwindows);
158.  E void NDECL(Sdlgl_update_inventory);
159.  E void NDECL(Sdlgl_mark_synch);
160.  E void NDECL(Sdlgl_wait_synch);
161.  E void FDECL(Sdlgl_raw_print, (const char *));
162.  E void FDECL(Sdlgl_raw_print_bold, (const char *));
163.  E int NDECL(Sdlgl_nhgetch);
164.  E int FDECL(Sdlgl_nh_poskey, (int *, int *, int *));
165.  E void NDECL(Sdlgl_nhbell);
166.  E void FDECL(Sdlgl_number_pad, (int));
167.  E void NDECL(Sdlgl_delay_output);
168.  
169.  E void VDECL(sdlgl_warning, (const char *, ...)) PRINTF_F(1,2);
170.  E void VDECL(sdlgl_error, (const char *, ...)) PRINTF_F(1,2);
171.  E void VDECL(sdlgl_hangup, (const char *, ...)) PRINTF_F(1,2);
172.  
173.  E void FDECL(sdlgl_sleep, (int));
174.  E int NDECL(sdlgl_get_time);
175.  E int FDECL(sdlgl_get_poskey, (int, int *, int *, int *));
176.  E int FDECL(sdlgl_get_key, (int));
177.  
178.  
179.  /*
180.   * GL_OPT
181.   */
182.  
183.  #define DEF_SDLGL_WIDTH   800
184.  #define DEF_SDLGL_HEIGHT  600
185.  #define DEF_SDLGL_DEPTH   16
186.  
187.  #define MIN_SDLGL_WIDTH   640
188.  #define MIN_SDLGL_HEIGHT  400
189.  #define MAX_SDLGL_WIDTH   2048
190.  #define MAX_SDLGL_HEIGHT  1536
191.  
192.  extern int sdlgl_width;
193.  extern int sdlgl_height;
194.  extern int sdlgl_depth;
195.  
196.  #define DEF_SDLGL_WINDOWED   0
197.  #define DEF_SDLGL_JAILSIZE   35
198.  #define DEF_SDLGL_KEYREPEAT  2  /* always */
199.  
200.  #define DEF_SDLGL_PREVSTEP   1
201.  #define MAX_SDLGL_PREVSTEP   20
202.  
203.  #define DEF_TILE_HEIGHT      32
204.  #define DEF_FONTSIZ_MAP      14
205.  #define DEF_FONTSIZ_TEXT     20
206.  #define DEF_VARY_MSGCOUNT    3
207.  #define DEF_SCROLL_MARGIN    3
208.  
209.  /* sdlgl_def_zoom can take on this value (text-mode view) */
210.  #define TEXT_ZOOM  -1
211.  
212.  extern int sdlgl_windowed;
213.  extern int sdlgl_jail_size;
214.  extern int sdlgl_def_zoom;
215.  extern int sdlgl_key_repeat;
216.  extern int sdlgl_alt_prev;
217.  extern int sdlgl_prev_step;
218.  extern int sdlgl_msg_dim;
219.  extern int sdlgl_reformat;
220.  extern int sdlgl_shrink_wrap;
221.  extern int sdlgl_flipping;
222.  extern int sdlgl_jump_scroll;
223.  extern int sdlgl_invis_fx;
224.  extern int sdlgl_gamma;
225.  
226.  E void FDECL(sdlgl_parse_cmdline_options, (int *, char **));
227.  E void NDECL(sdlgl_validate_wincap_options);
228.  E void NDECL(sdlgl_validate_gl_options);
229.  E void FDECL(Sdlgl_preference_update, (const char *));
230.  
231.  
232.  /*
233.   * GL_CONF
234.   */
235.  
236.  /* (nothing here yet) */
237.  
238.  
239.  /*
240.   * GL_ROLE
241.   */
242.  
243.  E void NDECL(Sdlgl_player_selection);
244.  
245.  
246.  /*
247.   * GL_UNIT
248.   */
249.  
250.  extern int sdlgl_tex_max;
251.  
252.  typedef unsigned int rgbcol_t;
253.  
254.  #define RGB_MAKE(r,g,b)  (((r) << 16) + ((g) << 8) + (b))
255.   
256.  #define RGB_RED(rgb)  ((rgb >> 16) & 0xFF)
257.  #define RGB_GRN(rgb)  ((rgb >>  8) & 0xFF)
258.  #define RGB_BLU(rgb)  ((rgb      ) & 0xFF)
259.  
260.  struct GraphicUnit
261.  {
262.    /* texture used */
263.    GLuint tex_id;
264.  
265.    /* texture coords */
266.    float tx1, ty1, tx2, ty2;
267.      
268.    /* screen coordinates */
269.    short x, y, w, h;
270.  
271.    /* rendering pass (lower ones are drawn first) */
272.    short pass;
273.  
274.    /* image color */
275.    rgbcol_t color;
276.  
277.    /* translucency, range is 0.0 - 1.0 */
278.    float trans;
279.  };
280.  
281.  E void NDECL(sdlgl_unit_startup);
282.  E void NDECL(sdlgl_unit_shutdown);
283.  
284.  E void FDECL(sdlgl_begin_units, (int, int));
285.  E void FDECL(sdlgl_add_unit, (GLuint,float,float,float,float,
286.        short,short,short,short,short,rgbcol_t,float));
287.  E void NDECL(sdlgl_finish_units);
288.  
289.  E void FDECL(sdlgl_hw_make_screenshot, (const char *));
290.  
291.  
292.  /*
293.   * GL_TILE
294.   */
295.  
296.  typedef unsigned short tileidx_t;
297.  typedef unsigned short tilecol_t;
298.  typedef unsigned short tileflags_t;
299.  
300.  #define TILE_EMPTY  0x7FFF
301.  
302.  #define TILE_F_FLIPX    0x0001  /* horizontally flip the fg */
303.  #define TILE_F_TRANS50  0x0010  /* draw fg 50% translucent */
304.  
305.  struct TilePair
306.  {
307.    /* What tiles to draw at each location.  Any of these can be
308.     * TILE_EMPTY.  BG contains the actual background (usually a floor,
309.     * maybe water).  MG is for dungeon parts (walls, stairs, sinks,
310.     * traps, and so forth).  FG contains everything else: objects,
311.     * monsters, zaps and swallows.
312.     */
313.   
314.    tileidx_t fg;
315.    tileidx_t mg;  /* mid-ground */
316.  
317.    union
318.    {
319.      tilecol_t col;
320.      tileidx_t bg;
321.    }
322.    u;
323.  
324.    tileflags_t flags;
325.  };
326.  
327.  struct FontCache;
328.  
329.  struct TileSet
330.  {
331.    /* total number of tiles in the set */
332.    int tile_num;
333.  
334.    /* size of each tile */
335.    int tile_w, tile_h;
336.  
337.    /* overlap size.  Only non-zero for the pseudo 3D tileset.  lap_skew
338.     * is the difference (of horizontal pixels) between to rows.
339.     */
340.    int lap_w, lap_h;
341.    int lap_skew;
342.  
343.    /* number of tiles horizontal/vertical that fit in each 256x256
344.     * image (or whatever size the 3D card supports).  Tiles are packed
345.     * from left->right, bottom->top.  For software mode, the tiles are
346.     * all packed in a single surface.
347.     */
348.    int pack_w, pack_h;
349.  
350.    /* number of 256x256 images */
351.    int tex_num;
352.  
353.    /* the GL texture ids.  Unused in software mode */
354.    GLuint *tex_ids;
355.  
356.    /* for GL, the size of all textures in the array.  Usually these
357.     * will be the same as sdlgl_tex_max, but when sdlgl_tex_max is high
358.     * (like 1024) and the tileset is small (like the fonts), then the
359.     * size can be reduced to save memory.
360.     */
361.    int tex_size_w, tex_size_h;
362.  
363.    /* which tiles have alpha parts.  Valid for both GL and software
364.     * rendering.
365.     */
366.    unsigned char *has_alpha;
367.  
368.    /* for Software mode, this surface contains the tiles.  When using
369.     * large tilesets (32x32 and 48x64), surf_small contains the
370.     * shrunk-down version (otherwise it is NULL).
371.     */
372.    SDL_Surface *surf;
373.    SDL_Surface *surf_small;
374.  
375.    /* when using the Isometric tileset in software mode, these contain
376.     * some extra tiles to draw the map borders.  (Needed since the
377.     * dirty matrix code doesn't support drawing diagonal lines).
378.     */
379.    SDL_Surface *borders;
380.    SDL_Surface *borders_small;
381.  
382.    /* fonts are normally bright white.  For software mode, we need to
383.     * colorise them, and this is done by the font cache.  This is
384.     * unused in GL mode.
385.     */
386.    struct FontCache *font_cache;
387.  };
388.  
389.  struct ExtraShape
390.  {
391.    /* type of extra shape */
392.    enum ShapeType
393.    {
394.      SHAPE_None = 0,
395.      SHAPE_Heart,
396.      SHAPE_Ridden
397.    }
398.    type;
399.   
400.    /* position of shape, in terms of whole tiles */
401.    short x, y;
402.    
403.    /* type-dependent parameters.
404.     * For SHAPE_Heart and SHAPE_Ridden, par1 means "on_left".
405.     */
406.    int par1, par2;
407.  };
408.  
409.  struct TileWindow
410.  {
411.    /* types of tiles drawn in this window */
412.    struct TileSet *set;
413.  
414.    /* width and height of this window (in tiles).  Can be larger than
415.     * the screen.
416.     */
417.    int total_w, total_h;
418.  
419.    /* on-screen position of window (in pixels).  All values are 0 when
420.     * the window is unmapped.  Mapped windows are drawn in order of
421.     * their depth value (lower depths are drawn first).
422.     */
423.    int scr_x, scr_y, scr_w, scr_h, scr_depth;
424.  
425.    /* private field -- index of window in mapped array */
426.    int mapped_idx;
427.   
428.    /* text window ? */
429.    int is_text;
430.  
431.    /* this is the map window ? */
432.    int is_map;
433.  
434.    /* does the window have see-through parts ?  This is normally false.
435.     * Only used for text on the tombstone currently.  When true, lower
436.     * windows don't get clipped against this one, and _no_ background
437.     * is drawn.
438.     */
439.    int see_through;
440.  
441.    /* for see-through windows, whether to blend in the text (needed for
442.     * the RIP image).
443.     */
444.    int is_blended;
445.  
446.    /* background color.  When the tiles don't take up all of the
447.     * window's area, this color fills in the unused portions.  Also
448.     * used for text background.
449.     */
450.    rgbcol_t background;
451.  
452.    /* used for panning.  The values represent an offset (in screen
453.     * pixels) into the array.  Larger pan_x values shift the tiles
454.     * further left.  Larger pan_y values shift the tiles further
455.     * downwards.  (negative values are useful too).
456.     */
457.    int pan_x, pan_y;
458.    
459.    /* used for zooming.  The values represent the displayed size of
460.     * each tile (in screen pixels).  For NHW_MAP windows using the
461.     * pseudo 3D tileset, scale_w/h *ignore* the overlap portion of the
462.     * tiles (i.e. they give the stepping distance), and scale_full_w/h
463.     * give the size of the full tile.  For all tilesets except the
464.     * pseudo 3D one, the full_* values equal the plain values.
465.     */
466.    int scale_w, scale_h;
467.    int scale_full_w, scale_full_h;
468.    int scale_skew;
469.  
470.    /* the position (in terms of tiles) where to draw a cursor.
471.     * Negative values mean that no cursor should be drawn.
472.     */
473.    int curs_x, curs_y, curs_w;
474.   
475.    /* cursor type: 1 for block, 0 for outline */
476.    int curs_block;
477.     
478.    /* cursor color */
479.    rgbcol_t curs_color;
480.  
481.    /* the array of tile indexes.  Order is left->right, bottom->top.
482.     * For text windows, the values are characters (the charset is IBM
483.     * cp437, i.e. standard CGA/VGA), and the color field is used.  For
484.     * the MAP window, the `bg' field in the TilePair is used as the
485.     * background tile.
486.     *
487.     * The color field contains the foreground in the least significant
488.     * 8 bits, background in the most significant 8 bits.  Both are
489.     * indices into sdlgl_text_colors[].  NOTE: background color not
490.     * actually used yet (if ever).
491.     */
492.    struct TilePair *tiles;
493.  
494.    /* set of extra shapes to draw */
495.    struct ExtraShape *extra_shapes;
496.    int extra_max;
497.    int extra_num;
498.  
499.    /* used for the map window to draw a border around it */
500.    int has_border;
501.  };
502.  
503.  extern struct TileSet *sdlgl_tiles;
504.  
505.  E void NDECL(sdlgl_tile_startup);
506.  E void NDECL(sdlgl_tile_shutdown);
507.  E void NDECL(sdlgl_tile_load_rest);
508.  E void NDECL(sdlgl_start_logo);
509.  E int NDECL(sdlgl_iterate_logo);
510.  E int FDECL(sdlgl_display_RIP, (int));
511.  E void NDECL(sdlgl_dismiss_RIP);
512.  
513.  E struct TileWindow *FDECL(sdlgl_new_tilewin,
514.      (struct TileSet *, int, int, int, int));
515.  E void FDECL(sdlgl_map_tilewin,
516.      (struct TileWindow *, int, int, int, int, int));
517.  E void FDECL(sdlgl_unmap_tilewin, (struct TileWindow *));
518.  E void FDECL(sdlgl_free_tilewin, (struct TileWindow *));
519.  E void FDECL(sdlgl_change_tileset, (struct TileWindow *,
520.        struct TileSet *, int));
521.  E void NDECL(sdlgl_flush);
522.  
523.  E void FDECL(sdlgl_add_extrashape, (struct TileWindow *,
524.        enum ShapeType, short, short, int, int));
525.  E void FDECL(sdlgl_remove_extrashapes, (struct TileWindow *,
526.        short, short));
527.  E int FDECL(sdlgl_test_tile_visible, (int, int, int, int, int));
528.  E void FDECL(sdlgl_set_start_depth, (int));
529.  
530.  E void FDECL(sdlgl_store_char, (struct TileWindow *, int, int,
531.        char, rgbcol_t));
532.  E int FDECL(sdlgl_store_str, (struct TileWindow *, int, int,
533.        const char *, int, rgbcol_t));
534.  E void FDECL(sdlgl_store_tile, (struct TileWindow *, int, int,
535.        tileidx_t, tileidx_t, tileidx_t, tileflags_t));
536.  E void FDECL(sdlgl_blank_area, (struct TileWindow *, int, int, int, int));
537.  E void FDECL(sdlgl_copy_area, (struct TileWindow *, int, int,
538.        int, int, int, int));
539.  E void FDECL(sdlgl_transfer_area, (struct TileWindow *, int, int,
540.        int, int, struct TileWindow *, int, int));
541.  E void FDECL(sdlgl_transfer_line, (struct TileWindow *, int, int,
542.        int, struct TilePair *, int));
543.  E void FDECL(sdlgl_set_scale, (struct TileWindow *, int));
544.  E void FDECL(sdlgl_set_cursor, (struct TileWindow *, int, int, int));
545.  
546.  
547.  /*
548.   * GL_IMAGE
549.   */
550.  
551.  extern unsigned char pet_mark_bits[8];
552.  extern unsigned char ridden_mark_bits[8];
553.  
554.  extern char tile_16_face_dirs[1000];
555.  extern char tile_32_face_dirs[1000];
556.  
557.  extern SDL_Cursor *sdlgl_cursor_main;
558.  extern SDL_Cursor *sdlgl_cursor_left;
559.  extern SDL_Cursor *sdlgl_cursor_right;
560.  extern SDL_Cursor *sdlgl_cursor_up;
561.  extern SDL_Cursor *sdlgl_cursor_down;
562.  extern SDL_Cursor *sdlgl_cursor_hand;
563.  extern SDL_Cursor *sdlgl_cursor_cross;
564.  
565.  extern unsigned char sdlgl_gamma_table[256];
566.  
567.  #define GAMMA(n)    (sdlgl_gamma_table[n])
568.  #define GAMMA_F(n)  ((float)GAMMA(n) / 255.0)
569.  
570.  E int FDECL(sdlgl_quantize_tile_size, (int));
571.  E int FDECL(sdlgl_mon_tile_face_dir, (tileidx_t));
572.  E void NDECL(sdlgl_generate_gamma_table);
573.  E void NDECL(sdlgl_init_mouse_cursors);
574.  E void NDECL(sdlgl_free_mouse_cursors);
575.  
576.  E void FDECL(sdlgl_load_face_dirs, (const char *, char *));
577.  E unsigned char * FDECL(sdlgl_load_png_file, (const char*, int*, int*));
578.  E int FDECL(sdlgl_save_ppm_file, (const char *, const unsigned char *,
579.        int, int));
580.  
581.  
582.  /*
583.   * GL_FONT
584.   */
585.  
586.  #define CHAR_2_TILE(ch)  ((tileidx_t)(unsigned char)(ch))
587.  #define TILE_2_CHAR(t)   ((unsigned char)(t))
588.  
589.  #define TXT_MAKE(r,g,b)  ((r)*25 + (g)*5 + (b))
590.  
591.  #define TXT_GET_R(txt)   (((txt) / 25) % 5)
592.  #define TXT_GET_G(txt)   (((txt) / 5)  % 5)
593.  #define TXT_GET_B(txt)   (((txt)    )  % 5)
594.  
595.  #define BLACK      TXT_MAKE(0,0,0)
596.  #define D_GREY     TXT_MAKE(1,1,1)
597.  #define GREY       TXT_MAKE(2,2,2)
598.  #define L_GREY     TXT_MAKE(3,3,3)
599.  #define WHITE      TXT_MAKE(4,4,4)
600.  
601.  #define RED        TXT_MAKE(3,0,0)
602.  #define BROWN      TXT_MAKE(3,2,0)
603.  #define GREEN      TXT_MAKE(0,3,0)
604.  #define CYAN       TXT_MAKE(0,3,3)
605.  #define BLUE       TXT_MAKE(0,0,3)
606.  #define MAGENTA    TXT_MAKE(3,0,3)
607.  
608.  #define B_RED      TXT_MAKE(4,0,0)
609.  #define B_YELLOW   TXT_MAKE(4,4,0)
610.  #define B_ORANGE   TXT_MAKE(4,3,0)
611.  #define B_GREEN    TXT_MAKE(0,4,0)
612.  #define B_CYAN     TXT_MAKE(0,4,4)
613.  #define B_BLUE     TXT_MAKE(0,0,4)
614.  #define B_MAGENTA  TXT_MAKE(4,0,4)
615.  
616.  #define TILECOL_UNUSED  0x7EEE
617.  
618.  struct FontCache
619.  {
620.    /* cache size (total number of characters on surface) */
621.    int char_num;
622.  
623.    SDL_Surface *char_surf;
624.  
625.    /* how the characters are packed in the surface */
626.    int pack_w, pack_h;
627.  
628.    /* what color each character in the cache currently is.  Initially
629.     * all values are TILECOL_UNUSED.
630.     */
631.    tilecol_t *what_cols;
632.  };
633.  
634.  #define FONTCACHE_SIZE    512
635.  #define FONTCACHE_PACK_W  32
636.  
637.  /* this hash function has been carefully chosen so that the two most
638.   * used colors (L_GREY and GREY) have no collisions.
639.   */
640.  #define FONTCACHE_HASH(ch,col)  (int) \
641.      (TXT_GET_R(col) * 41 + TXT_GET_G(col) * 31 + \
642.       TXT_GET_B(col) * 23 + 2 * (unsigned int) ch)
643.  
644.  extern tilecol_t termcolor_to_tilecol[CLR_MAX];
645.  
646.  /* colors used for text.  Index 0 guaranteed to be black */
647.  extern rgbcol_t sdlgl_text_colors[256];
648.  
649.  extern struct TileSet *sdlgl_font_8;  /* 8x8 (rip) font */
650.  
651.  extern struct TileSet *sdlgl_font_map;
652.  extern struct TileSet *sdlgl_font_text;
653.  extern struct TileSet *sdlgl_font_menu;
654.  extern struct TileSet *sdlgl_font_message;
655.  extern struct TileSet *sdlgl_font_status;
656.  
657.  E void NDECL(sdlgl_font_startup);
658.  E void NDECL(sdlgl_font_shutdown);
659.  E int FDECL(sdlgl_quantize_font, (int));
660.  E struct TileSet *FDECL(sdlgl_next_narrower_font, (int));
661.  
662.  
663.  /*
664.   * GL_HARDW / GL_SOFTW
665.   *
666.   * (Rendering API)
667.   */
668.  struct rendering_procs
669.  {
670.    void NDECL((*rend_startup));
671.    void NDECL((*rend_shutdown));
672.    struct TileSet *FDECL((*load_tileset),
673.        (const char *, int, int, int, int, int *, int *));
674.    void FDECL((*free_tileset), (struct TileSet *));
675.    void NDECL((*create_extra_graphics));
676.    void NDECL((*free_extra_shapes));
677.  
678.    void FDECL((*enable_clipper), (int, int, int, int));
679.    void NDECL((*disable_clipper));
680.    void NDECL((*blit_frame));
681.  
682.    void FDECL((*draw_background), (int, int, int, int, rgbcol_t,
683.        int, int));
684.    void FDECL((*draw_extra_shape), (struct TileWindow *,
685.        struct ExtraShape *));
686.    void FDECL((*draw_cursor), (struct TileWindow *));
687.    void FDECL((*begin_tile_draw), (int, int));
688.    void FDECL((*draw_tile), (struct TileWindow *, int, int,
689.        int, int, tileidx_t, tilecol_t, tileflags_t, short));
690.    void NDECL((*finish_tile_draw));
691.    void FDECL((*draw_border), (struct TileWindow *, rgbcol_t));
692.  
693.    void FDECL((*start_fading), (int, int));
694.    void FDECL((*draw_fading), (float));
695.    void NDECL((*finish_fading));
696.    void FDECL((*make_screenshot), (const char *));
697.  
698.    void FDECL((*set_pan), (struct TileWindow *, int, int));
699.    void FDECL((*set_new_pos), (struct TileWindow *, int, int, int, int));
700.    void FDECL((*mark_dirty), (int, int, int, int, int));
701.  };
702.  
703.  extern struct rendering_procs sdlgl_rend_procs;
704.  
705.  #ifdef GL_GRAPHICS
706.  extern struct rendering_procs sdlgl_hardw_rend_procs;
707.  #endif
708.  
709.  #ifdef SDL_GRAPHICS
710.  extern struct rendering_procs sdlgl_softw_rend_procs;
711.  #endif
712.  
713.  #define sdlgl_rend_startup  (*sdlgl_rend_procs.rend_startup)
714.  #define sdlgl_rend_shutdown (*sdlgl_rend_procs.rend_shutdown)
715.  #define sdlgl_load_tileset  (*sdlgl_rend_procs.load_tileset)
716.  #define sdlgl_free_tileset  (*sdlgl_rend_procs.free_tileset)
717.  #define sdlgl_create_extra_graphics (*sdlgl_rend_procs.create_extra_graphics)
718.  #define sdlgl_free_extra_shapes (*sdlgl_rend_procs.free_extra_shapes)
719.  #define sdlgl_enable_clipper   (*sdlgl_rend_procs.enable_clipper)
720.  #define sdlgl_disable_clipper  (*sdlgl_rend_procs.disable_clipper)
721.  #define sdlgl_blit_frame  (*sdlgl_rend_procs.blit_frame)
722.  #define sdlgl_draw_background  (*sdlgl_rend_procs.draw_background)
723.  #define sdlgl_draw_extra_shape (*sdlgl_rend_procs.draw_extra_shape)
724.  #define sdlgl_draw_cursor      (*sdlgl_rend_procs.draw_cursor)
725.  #define sdlgl_begin_tile_draw  (*sdlgl_rend_procs.begin_tile_draw)
726.  #define sdlgl_draw_tile        (*sdlgl_rend_procs.draw_tile)
727.  #define sdlgl_finish_tile_draw (*sdlgl_rend_procs.finish_tile_draw)
728.  #define sdlgl_draw_border   (*sdlgl_rend_procs.draw_border)
729.  #define sdlgl_start_fading  (*sdlgl_rend_procs.start_fading)
730.  #define sdlgl_draw_fading   (*sdlgl_rend_procs.draw_fading)
731.  #define sdlgl_finish_fading (*sdlgl_rend_procs.finish_fading)
732.  #define sdlgl_make_screenshot (*sdlgl_rend_procs.make_screenshot)
733.  #define sdlgl_set_pan       (*sdlgl_rend_procs.set_pan)
734.  #define sdlgl_set_new_pos   (*sdlgl_rend_procs.set_new_pos)
735.  #define sdlgl_mark_dirty    (*sdlgl_rend_procs.mark_dirty)
736.  
737.  #ifdef GL_GRAPHICS
738.  E GLuint FDECL(sdlgl_send_graphic_RGBA, (unsigned char *, int, int));
739.  #endif
740.  
741.  
742.  /*
743.   * GL_RENDU
744.   */
745.  
746.  #define TRANS_PIX  255  /* 8 bit transparent pixel */
747.  
748.  extern rgbcol_t sdlgl_palette[256];
749.  
750.  #define DIRTY_SIZE   64
751.  #define CLEAN_CELL   0x7F
752.  
753.  struct DirtyMatrix
754.  {
755.    /* pixel size that matrix covers (screen size) */
756.    int pw, ph;
757.  
758.    /* matrix size (in cells), enough to cover the screen */
759.    int cw, ch;
760.  
761.    /* cell matrix.  Each cell is either CLEAN_CELL, or the depth of the
762.     * window that became dirty somewhere inside the cell.  If multiple
763.     * windows get dirty in the same cell, the *lowest* depth is
764.     * remembered.  
765.     *
766.     * Note: using a high value of CLEAN_CELL is a nice trick,
767.     *       simplifying the marking and testing code.
768.     */
769.    unsigned char *cells;
770.  
771.    /* rectangles used to update screen.  Worst case scenario is
772.     * slightly over half the total number of cells.
773.     */
774.    int max_rects;
775.  
776.    SDL_Rect *updaters;
777.  };
778.  
779.  E void FDECL(sdlgl_set_surface_colors, (SDL_Surface *));
780.  E SDL_Surface *FDECL(sdlgl_RGBA_to_truecolor, (unsigned char *,
781.          int, int));
782.  E SDL_Surface *FDECL(sdlgl_RGBA_to_palettised, (unsigned char *,
783.          int, int));
784.  E SDL_Surface *FDECL(sdlgl_shrink_surface, (SDL_Surface *));
785.  E void FDECL(sdlgl_sw_create_has_alpha, (struct TileSet *));
786.  
787.  E void FDECL(sdlgl_create_font_cache, (struct TileSet *));
788.  E void FDECL(sdlgl_free_font_cache, (struct TileSet *));
789.  E void FDECL(sdlgl_font_cache_lookup, (struct TileSet *, tileidx_t,
790.          tilecol_t, int *, int *));
791.  
792.  E struct DirtyMatrix *FDECL(sdlgl_create_dirty_matrix, (int, int));
793.  E void FDECL(sdlgl_free_dirty_matrix, (struct DirtyMatrix *));
794.  E void FDECL(sdlgl_dirty_matrix_clear, (struct DirtyMatrix *));
795.  E void FDECL(sdlgl_dirty_matrix_add, (struct DirtyMatrix *, int, int,
796.        int, int, int));
797.  E int FDECL(sdlgl_dirty_matrix_test, (struct DirtyMatrix *, int, int,
798.        int, int, int));
799.  E int FDECL(sdlgl_dirty_matrix_to_updaters, (struct DirtyMatrix *));
800.  E void FDECL(sdlgl_dirty_matrix_blit, (struct DirtyMatrix *, 
801.        SDL_Surface *, SDL_Rect *, SDL_Rect *, Uint32, int));
802.  
803.  
804.  /*
805.   * GL_WIN
806.   */
807.  
808.  #define MAXWIN  20
809.  
810.  /* active NHW_TEXT/NHW_MENU window, otherwise WIN_ERR */
811.  extern int sdlgl_top_win;
812.  
813.  /* active NHW_MAP window, otherwise WIN_ERR */
814.  extern int sdlgl_map_win;
815.  
816.  #define MIN_MESSAGE  2
817.  #define MAX_MESSAGE  8
818.  
819.  #define MIN_HISTORY  10
820.  #define MAX_HISTORY  200   /* max history saved on message window */
821.  
822.  typedef unsigned short glyphidx_t;
823.  
824.  struct GlyphPair
825.  {
826.    /* background and foreground glyphs.  One or both may be NO_GLYPH.
827.     * FG is only for objects/monsters/etc, and BG is only for dungeon
828.     * glyphs (CMAP).
829.     */
830.    glyphidx_t bg, fg;
831.  };
832.  
833.  #define MENU_NONE_COL  RGB_MAKE(48, 48, 48)
834.  #define MENU_ONE_COL   RGB_MAKE(16, 32, 48)
835.  #define MENU_ANY_COL   RGB_MAKE(0,  0,  48)
836.  #define TEXT_BACK_COL  RGB_MAKE(0,  0,  48)
837.  #define PREV_BACK_COL  RGB_MAKE(48, 24,  0)
838.  
839.  #define BORDER_COL     RGB_MAKE(0,  0,  96)
840.  #define CURSOR_COL     RGB_MAKE(192, 0, 0)
841.  #define OUTLINE_COL    RGB_MAKE(255, 255, 255)
842.  
843.  
844.  struct MouseLocation
845.  {
846.    /* what the action should be at the current location.  This also
847.     * indicates what the mouse cursor should look like.  When the mouse
848.     * is outside the window (or when focus has been lost), then the
849.     * MACT_AWAY value is used.
850.     */
851.    enum MouseLocAction
852.    {
853.      MACT_NORMAL = 0,
854.      MACT_AWAY,
855.      MACT_UP, MACT_DOWN, MACT_LEFT, MACT_RIGHT,
856.      MACT_HAND, MACT_CROSS
857.    }
858.    action;
859.  
860.    /* pixel position of mouse cursor.  The coordinates are GL style
861.     * (i.e. y goes from the bottom up).
862.     */
863.    int x, y;
864.    
865.    /* the window that the mouse pointer is currently over.  Will be
866.     * WIN_ERR when not sitting over any window, e.g. a gap, or when the
867.     * focus has been lost.
868.     */
869.    int window;
870.  };
871.  
872.  extern struct MouseLocation sdlgl_mouseloc;
873.  
874.  
875.  struct TextWindow
876.  {
877.    /* type (one of NHW_XXX) */
878.    int type;
879.  
880.    /* for NHW_MENU types: whether this window is being used as an
881.     * actual menu or just for text.  Will be -1 until the
882.     * distinguishing call (start_menu | putstr) has been made.
883.     */
884.    int is_menu;
885.  
886.    /* is this window (NHW_TEXT type) used for the RIP message ? */
887.    int is_rip;
888.    int how_died;
889.    
890.    /* linked list of menu items.  Only valid when is_menu == 1.  Note
891.     * that this list goes upwards from the bottom of the window (not
892.     * top-down, as you might expect).
893.     */
894.    struct MenuItem *items;
895.    
896.    /* linked list of text items.  Only valid when type is NHW_TEXT, or
897.     * NHW_MENU and is_menu == 0.  This one also goes upwards.
898.     */
899.    struct TextItem *lines;
900.    
901.    /* computed width & height of the menu or text window.  For menus
902.     * (is_menu == 1), it's only valid after the end_menu() interface
903.     * routine has been called.  For text items, it is computed when
904.     * displayed.
905.     */
906.    int calc_w, calc_h;
907.  
908.    /* for menu/text windows, the number of tiles that completely fit on
909.     * the screen at any one time.  For small windows, this'll be the
910.     * same as calc_w/h.  Also valid for NHW_MESSAGE/STATUS windows.
911.     */
912.    int show_w, show_h;
913.  
914.    /* based on a tile window.  This is NULL while the window is
915.     * unmapped (i.e. display_nhwindow hasn't been called).
916.     */
917.    struct TileWindow *base;
918.  
919.    /* only valid for NHW_MAP windows, and then only when mapped.
920.     * Stores a record of all the glyphs on the map.  The size is
921.     * exactly the same as in the `base' field.
922.     */
923.    struct GlyphPair *glyphs;
924.   
925.    /* tile coordinates for the "focus", which (for NHW_MAP windows) is
926.     * the tile that controls where the jail is (usually the focus is
927.     * where the player tile is).
928.     *
929.     * For other window types, this is the tile to show at the bottom
930.     * left corner of the window.
931.     */
932.    int focus_x, focus_y;
933.  
934.    /* panning values for NHW_MAP windows.  Remembers the pan state of
935.     * graphical tiles when the text-mode view is active.
936.     */
937.    int map_px, map_py;
938.   
939.    /* the JAIL...  This is an rectangular area that is meant to be kept
940.     * at the middle of the screen.  The player can move freely within
941.     * the jail without the map window panning -- when the player moves
942.     * outside of the jail, the map window will usually pan.
943.     *
944.     * The jail is mostly implicit (size calc'd from sdlgl_jail_size).
945.     * Here is the offset (in pixels) from center of screen to jail's
946.     * center.  The jail is allowed to be uncentered on the screen,
947.     * though it should auto-correct itself, i.e. move closer to the
948.     * center instead of panning.  The jail (in pixel terms) must always
949.     * fit on the screen.  Hence when jail size is 100%, these offsets
950.     * are always zero.
951.     *
952.     * The jail is not used when in text-mode view (determined by
953.     * base->is_text), as we assume the whole map fits on the screen.
954.     */
955.    int jail_x, jail_y;
956.   
957.    /* current zoom factor.  Only used with NHW_MAP windows.
958.     * The value is the pixel height that the tiles are rendered at, so
959.     * higher values mean larger tiles.  The allowable sizes depends on
960.     * what tileset is being used and whether we are using GL or
961.     * Software rendering.  Not used when in text-mode view (i.e.
962.     * base->is_text is set) as we assume the whole map fits on the
963.     * screen.  Invariant: zoom_h != TEXT_ZOOM.
964.     */
965.    int zoom_h;
966.  
967.    /* For NHW_MAP windows, this field remembers which direction the
968.     * player was travelling in.  Used for the tile flipping option.
969.     */
970.    int player_dx;
971.    int player_dy;
972.  
973.    /* the current write position (in terms of tiles).  Must always be
974.     * inside the tile window area.  Order same as tiles: left->right,
975.     * bottom->top.
976.     */
977.    int write_x, write_y;
978.  
979.    /* whether we show a cursor at the current write position.  Also
980.     * used for NHW_MAP windows for cursor on player.
981.     */
982.    int write_cursor;
983.  
984.    /* current writing color */
985.    tilecol_t write_col;
986.  
987.    /* current filling color (for clear_screen, etc) */
988.    tilecol_t fill_col;
989.  
990.    /* for NHW_MESSAGE windows: number of "fresh" lines, i.e. lines that
991.     * have been written onto the message window since clear_nhwindow()
992.     * or the last do_more().  Initial state is 0, meaning "blank".
993.     * After a [More] it is also 0.  As soon as this value becomes the
994.     * same as the `show_h' field, that's when we display the more text
995.     * and wait for a key.
996.     *
997.     * Note: Other routines that use the MESSAGE window (e.g. getlin)
998.     * should also call sdlgl_more() when this value is non-zero.
999.     */
1000.   int fresh_lines;
1001. 
1002.   /* for NHW_MESSAGE windows: true if the next putstr() should be
1003.    * placed on a new line, even if it fits on the previous one.
1004.    */
1005.   int want_new_line;
1006.  
1007.   /* for NHW_MESSAGE windows: this field is for the scroll-back
1008.    * capability (^P).  The tile window is normally unmapped, silently
1009.    * recording lines that scroll off the screen (except empty lines).
1010.    * Clearing the msg window is equivalent to fully scrolling it up.
1011.    */
1012.   struct TileWindow *scrollback;
1013. 
1014.   /* when true, scrolled-off lines are copied to the scrollback
1015.    * buffer.  This is disabled when routines that take over the
1016.    * message window (get_ext_cmd, etc) are active.
1017.    */
1018.   int scrollback_enable;
1019.  
1020.   /* this is 0 if the scrollback window is unmapped.  This value only
1021.    * used in the `alt_prev' mode, and signifies how many lines back we
1022.    * are showing.
1023.    */
1024.   int scrollback_pos;
1025. 
1026.   /* number of non-blank lines currently in the scrollback window.
1027.    * Used to limit the scrollback to readable stuff.
1028.    */
1029.   int scrollback_size;
1030. 
1031.   /* for NHW_MESSAGE windows, these fields handle the message_menu()
1032.    * hack.  When dismiss_more is non-zero, it is a character that can
1033.    * be used to accept the single choice while [MORE] is displayed
1034.    * (setting the more_ch).
1035.    */
1036.   int dismiss_more;
1037.   int more_ch;
1038. 
1039.   /* for NHW_MESSAGE windows, this will be set when the user pressed
1040.    * the Escape key to dismiss the more.  It should be cleared before
1041.    * every turn, and when certain interface functions are called
1042.    * (message_menu, etc).  It is used to prevent further [MORE]
1043.    * prompts (the TTY version also stops further output to the message
1044.    * window, but I'd prefer to see them).
1045.    */
1046.   int more_escaped;
1047. };
1048. 
1049. extern struct TextWindow *text_wins[MAXWIN];
1050. 
1051. E winid FDECL(Sdlgl_create_nhwindow, (int));
1052. E void FDECL(Sdlgl_clear_nhwindow, (winid));
1053. E void FDECL(Sdlgl_display_nhwindow, (winid, BOOLEAN_P));
1054. E void FDECL(Sdlgl_dismiss_nhwindow, (winid));
1055. E void FDECL(Sdlgl_destroy_nhwindow, (winid));
1056. E void FDECL(Sdlgl_curs, (winid,int,int));
1057. E void FDECL(Sdlgl_putstr, (winid, int, const char *));
1058. E void FDECL(Sdlgl_outrip, (winid,int));
1059. E int NDECL(Sdlgl_doprev_message);
1060. 
1061. E void NDECL(sdlgl_win_startup);
1062. E void NDECL(sdlgl_win_shutdown);
1063. E void FDECL(sdlgl_more, (struct TextWindow *));
1064. E void FDECL(sdlgl_adjust_scrollback, (struct TextWindow *, int));
1065. E void NDECL(sdlgl_remove_scrollback);
1066. E void FDECL(sdlgl_pan_window, (int, int, int));
1067. E tilecol_t FDECL(sdlgl_attr_to_tilecol, (int attr));
1068. E void FDECL(sdlgl_update_mouse_location, (int));
1069. 
1070. E int FDECL(sdlgl_internal_key_handler, (SDL_keysym *, int));
1071. E int FDECL(sdlgl_internal_button_handler, (SDL_MouseButtonEvent *));
1072. E void FDECL(sdlgl_internal_motion_handler, (SDL_MouseMotionEvent *));
1073. 
1074. 
1075. /*
1076.  * GL_MENU
1077.  */
1078. 
1079. E void FDECL(Sdlgl_start_menu, (winid));
1080. E void FDECL(Sdlgl_add_menu, (winid,int,const ANY_P *,
1081.     CHAR_P,CHAR_P,int,const char *, BOOLEAN_P));
1082. E void FDECL(Sdlgl_end_menu, (winid, const char *));
1083. E int FDECL(Sdlgl_select_menu, (winid, int, MENU_ITEM_P **));
1084. E char FDECL(Sdlgl_message_menu, (CHAR_P,int,const char *));
1085. E char FDECL(Sdlgl_yn_function, (const char *, const char *, CHAR_P));
1086. 
1087. E void FDECL(sdlgl_clear_menu_items, (struct TextWindow *));
1088. E int FDECL(sdlgl_process_menu_window, (int, struct TextWindow *, int));
1089. 
1090. 
1091. /*
1092.  * GL_TEXT
1093.  */
1094. 
1095. E void FDECL(Sdlgl_display_file, (const char *, BOOLEAN_P));
1096. 
1097. E void FDECL(sdlgl_clear_text_items, (struct TextWindow *));
1098. E void FDECL(sdlgl_insert_text_item, (struct TextWindow *,
1099.     struct TextItem *, int, int, const char *));
1100. E void FDECL(sdlgl_process_text_window, (int, struct TextWindow *));
1101. 
1102. 
1103. /*
1104.  * GL_MAP
1105.  */
1106. 
1107. #if defined(VANILLA_GLHACK)
1108. #define NUM_MON_TILES  393
1109. #else
1110. #define NUM_MON_TILES  603
1111. #endif
1112. 
1113. /* extra floor tiles */
1114. #if defined(VANILLA_GLHACK)
1115. #define FLOOR_TILES  1057
1116. #else
1117. #define FLOOR_TILES  1367
1118. #endif
1119. 
1120. #define Fl_Mine     (FLOOR_TILES + 0)
1121. #define Fl_Sokoban  (FLOOR_TILES + 1)
1122. #define Fl_Knox     Fl_Sokoban
1123. #define Fl_Tower    (FLOOR_TILES + 2)
1124. #define Fl_Hell     (FLOOR_TILES + 3)
1125. #define Fl_Quest    (FLOOR_TILES + 4)
1126. #define Fl_Astral   (FLOOR_TILES + 5)
1127. #define Fl_Rogue    (FLOOR_TILES + 6)
1128. #define Fl_Caves    Fl_Rogue
1129. #define Fl_Beach    (FLOOR_TILES + 7)
1130. 
1131. E void FDECL(Sdlgl_cliparound, (int, int));
1132. E void FDECL(Sdlgl_update_positionbar, (char *));
1133. E void FDECL(Sdlgl_print_glyph, (winid,XCHAR_P,XCHAR_P,int));
1134. 
1135. E void FDECL(sdlgl_create_map, (struct TextWindow *, int, int));
1136. E void FDECL(sdlgl_zoom_map, (int));
1137. E int FDECL(sdlgl_quantize_zoom, (int));
1138. E int NDECL(sdlgl_cursor_visible);
1139. E void NDECL(sdlgl_center_screen_on_player);
1140. E void NDECL(sdlgl_toggle_text_view);
1141. E int FDECL(sdlgl_find_click, (int, int *, int *));
1142. E void FDECL(sdlgl_pan_map_window, (int, int));
1143. 
1144. 
1145. /*
1146.  * GL_EMUL
1147.  */
1148. 
1149. E void NDECL(sdlgl_emul_startup);
1150. E void NDECL(sdlgl_emul_shutdown);
1151. E void NDECL(Sdlgl_start_screen);
1152. E void NDECL(Sdlgl_end_screen);
1153. E void NDECL(Sdlgl_askname);
1154. E void FDECL(Sdlgl_getlin, (const char *,char *));
1155. E int NDECL(Sdlgl_get_ext_cmd);
1156. 
1157. E struct TextWindow *FDECL(sdlgl_new_textwin, (int));
1158. E void FDECL(sdlgl_free_textwin, (struct TextWindow *));
1159. E void FDECL(sdlgl_putc, (struct TextWindow *, int));
1160. E void FDECL(sdlgl_puts, (struct TextWindow *, const char *));
1161. E void FDECL(sdlgl_puts_nolf, (struct TextWindow *, const char *));
1162. E void FDECL(sdlgl_gotoxy, (struct TextWindow *, int, int));
1163. E void FDECL(sdlgl_home, (struct TextWindow *));
1164. E void FDECL(sdlgl_backsp, (struct TextWindow *));
1165. E void FDECL(sdlgl_clear, (struct TextWindow *));
1166. E void FDECL(sdlgl_clear_end, (struct TextWindow *));
1167. E void FDECL(sdlgl_clear_eos, (struct TextWindow *));
1168. E void FDECL(sdlgl_enable_cursor, (struct TextWindow *, int));
1169. 
1170. 
1171. /*
1172.  * GL_STAT
1173.  */
1174. E void FDECL(sdlgl_write_status, (struct TextWindow *win));
1175. E void FDECL(sdlgl_update_status, (int));
1176. 
1177. 
1178. #undef E
1179. 
1180. #endif /* WINGL_INTERNAL */
1181. #endif /* WINGL_H */
1182. /*winGL.c*/

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.