1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef GLK_GLK_API_H
24 #define GLK_GLK_API_H
25 
26 #include "glk/glk.h"
27 #include "glk/glk_types.h"
28 #include "glk/blorb.h"
29 #include "glk/sound.h"
30 #include "glk/time.h"
31 #include "glk/windows.h"
32 
33 namespace Glk {
34 
35 class GlkAPI;
36 
37 typedef void (GlkAPI::*GlkFunction)();
38 
39 struct gidispatch_function_struct {
40 	uint32 id;
41 	const char *name;
42 	GlkFunction fnptr;
43 };
44 typedef gidispatch_function_struct gidispatch_function_t;
45 
46 
47 /**
48  * Implements the GLK interface
49  */
50 class GlkAPI : public GlkEngine {
51 private:
52 	bool _gliFirstEvent;
53 	unsigned char _charTolowerTable[256];
54 	unsigned char _charToupperTable[256];
55 public:
56 	/**
57 	 * Constructor
58 	 */
59 	GlkAPI(OSystem *syst, const GlkGameDescription &gameDesc);
~GlkAPI()60 	~GlkAPI() override {}
61 
62 	void glk_exit(void);
63 	void glk_set_interrupt_handler(void(*func)(void));
64 	void glk_tick(void);
65 
66 	uint glk_gestalt(uint id, uint val);
67 	uint glk_gestalt_ext(uint id, uint val, uint *arr, uint arrlen);
68 
69 	unsigned char glk_char_to_lower(unsigned char ch);
70 	unsigned char glk_char_to_upper(unsigned char ch);
71 
72 	/**
73 	 * Get the root window of the window hierarchy
74 	 */
75 	winid_t glk_window_get_root(void) const;
76 
77 	/**
78 	 * Open a new window
79 	 */
80 	winid_t glk_window_open(winid_t split, uint method, uint size,
81 	                        uint wintype, uint rock = 0) const;
82 
83 	void glk_window_close(winid_t win, stream_result_t *result = nullptr);
84 	void glk_window_get_size(winid_t win, uint *width, uint *height);
85 	void glk_window_set_arrangement(winid_t win, uint method,
86 	                                uint size, winid_t keyWin);
87 	void glk_window_get_arrangement(winid_t win, uint *method,
88 	                                uint *size, winid_t *keyWin);
89 	winid_t glk_window_iterate(winid_t win, uint *rock = 0);
90 	uint glk_window_get_rock(winid_t win);
91 	uint glk_window_get_type(winid_t win);
92 	winid_t glk_window_get_parent(winid_t win);
93 	winid_t glk_window_get_sibling(winid_t win);
94 	void glk_window_clear(winid_t win);
95 	void glk_window_move_cursor(winid_t win, uint xpos, uint ypos);
96 
97 	strid_t glk_window_get_stream(winid_t win);
98 	void glk_window_set_echo_stream(winid_t win, strid_t str);
99 	strid_t glk_window_get_echo_stream(winid_t win);
100 	void glk_set_window(winid_t win);
101 
102 	strid_t glk_stream_open_file(frefid_t fileref, FileMode fmode, uint rock = 0);
103 	strid_t glk_stream_open_memory(char *buf, uint buflen, FileMode fmode, uint rock = 0);
104 	void glk_stream_close(strid_t str, stream_result_t *result = nullptr);
105 	strid_t glk_stream_iterate(strid_t str, uint *rockptr) const;
106 	uint glk_stream_get_rock(strid_t str) const;
107 	void glk_stream_set_position(strid_t str, int pos, uint seekMode);
108 	uint glk_stream_get_position(strid_t str) const;
109 	void glk_stream_set_current(strid_t str);
110 	strid_t glk_stream_get_current(void);
111 
112 	void glk_put_char(unsigned char ch);
113 	void glk_put_char_stream(strid_t str, unsigned char ch);
114 	void glk_put_string(const char *s);
115 	void glk_put_string_stream(strid_t str, const char *s);
116 	void glk_put_buffer(const char *buf, uint len);
117 	void glk_put_buffer_stream(strid_t str, const char *buf, uint len);
118 	void glk_set_style(uint styl);
119 	void glk_set_style_stream(strid_t str, uint styl);
120 
121 	int glk_get_char_stream(strid_t str);
122 	uint glk_get_line_stream(strid_t str, char *buf, uint len);
123 	uint glk_get_buffer_stream(strid_t str, char *buf, uint len);
124 
125 	void glk_stylehint_set(uint wintype, uint styl, uint hint,
126 	                       int val);
127 	void glk_stylehint_clear(uint wintype, uint style, uint hint);
128 	uint glk_style_distinguish(winid_t win, uint style1, uint style2);
129 	bool glk_style_measure(winid_t win, uint style, uint hint, uint *result);
130 
131 	frefid_t glk_fileref_create_temp(uint usage, uint rock = 0);
132 	frefid_t glk_fileref_create_by_name(uint usage, const char *name, uint rock = 0);
133 	frefid_t glk_fileref_create_by_prompt(uint usage, FileMode fmode, uint rock = 0);
134 	frefid_t glk_fileref_create_from_fileref(uint usage, frefid_t fref, uint rock = 0);
135 	void glk_fileref_destroy(frefid_t fref);
136 	frefid_t glk_fileref_iterate(frefid_t fref, uint *rockptr);
137 	uint glk_fileref_get_rock(frefid_t fref);
138 	void glk_fileref_delete_file(frefid_t fref);
139 	uint glk_fileref_does_file_exist(frefid_t fref);
140 
141 	void glk_select(event_t *event);
142 	void glk_select_poll(event_t *event);
143 
144 	void glk_request_timer_events(uint millisecs);
145 
146 	void glk_request_line_event(winid_t win, char *buf, uint maxlen,
147 	                            uint initlen);
148 	void glk_request_char_event(winid_t win);
149 	void glk_request_mouse_event(winid_t win);
150 
151 	void glk_cancel_line_event(winid_t win, event_t *event);
152 	void glk_cancel_char_event(winid_t win);
153 	void glk_cancel_mouse_event(winid_t win);
154 
155 #ifdef GLK_MODULE_LINE_ECHO
156 	void glk_set_echo_line_event(winid_t win, uint val);
157 #endif /* GLK_MODULE_LINE_ECHO */
158 
159 #ifdef GLK_MODULE_LINE_TERMINATORS
160 	void glk_set_terminators_line_event(winid_t win, const uint32 *keycodes, uint count);
161 #endif /* GLK_MODULE_LINE_TERMINATORS */
162 
163 	/** \addtogroup Unicode
164 	 *  @{
165 	 */
166 
167 	uint glk_buffer_to_lower_case_uni(uint32 *buf, uint len, uint numchars);
168 	uint glk_buffer_to_upper_case_uni(uint32 *buf, uint len, uint numchars);
169 	uint glk_buffer_to_title_case_uni(uint32 *buf, uint len, uint numchars, uint lowerrest);
170 
171 	void glk_put_char_uni(uint32 ch);
172 	void glk_put_string_uni(const uint32 *s);
173 	void glk_put_buffer_uni(const uint32 *buf, uint len);
174 	void glk_put_char_stream_uni(strid_t str, uint32 ch);
175 	void glk_put_string_stream_uni(strid_t str, const uint32 *s);
176 	void glk_put_buffer_stream_uni(strid_t str, const uint32 *buf, uint len);
177 
178 	int glk_get_char_stream_uni(strid_t str);
179 	uint glk_get_buffer_stream_uni(strid_t str, uint32 *buf, uint len);
180 	uint glk_get_line_stream_uni(strid_t str, uint32 *buf, uint len);
181 
182 	strid_t glk_stream_open_file_uni(frefid_t fileref, FileMode fmode, uint rock = 0);
183 	strid_t glk_stream_open_memory_uni(uint32 *buf, uint buflen, FileMode fmode, uint rock = 0);
184 
185 	void glk_request_char_event_uni(winid_t win);
186 	void glk_request_line_event_uni(winid_t win, uint32 *buf, uint maxlen, uint initlen);
187 
188 	/** @}*/
189 
190 #ifdef GLK_MODULE_UNICODE_NORM
191 
192 	uint glk_buffer_canon_decompose_uni(uint32 *buf, uint len, uint numchars);
193 	uint glk_buffer_canon_normalize_uni(uint32 *buf, uint len, uint numchars);
194 
195 #endif /* GLK_MODULE_UNICODE_NORM */
196 
197 #ifdef GLK_MODULE_IMAGE
198 
199 	bool glk_image_draw(winid_t win, uint image, int val1, int val2);
200 	bool glk_image_draw_scaled(winid_t win, uint image,
201 		int val1, int val2, uint width, uint height);
202 	bool glk_image_draw(winid_t win, const Graphics::Surface &image, uint transColor = (uint)-1,
203 		int xp = 0, int yp = 0);
204 	bool glk_image_draw_scaled(winid_t win, const Graphics::Surface &image, uint transColor,
205 		int xp, int yp, uint width, uint height);
206 	bool glk_image_draw(winid_t win, const Common::String &image, int val1, int val2);
207 	bool glk_image_draw_scaled(winid_t win, const Common::String &image,
208 		int val1, int val2, uint width, uint height);
209 
210 	bool glk_image_get_info(uint image, uint *width, uint *height);
211 	bool glk_image_get_info(const Common::String &name, uint *width, uint *height);
212 
213 	void glk_window_flow_break(winid_t win);
214 
215 	void glk_window_erase_rect(winid_t win,
216 	                           int left, int top, uint width, uint height);
217 	void glk_window_fill_rect(winid_t win, uint color,
218 	                          int left, int top, uint width, uint height);
219 	void glk_window_set_background_color(winid_t win, uint color);
220 
221 #endif /* GLK_MODULE_IMAGE */
222 
223 #ifdef GLK_MODULE_SOUND
224 
225 	schanid_t glk_schannel_create(uint rock = 0);
226 	void glk_schannel_destroy(schanid_t chan);
227 	schanid_t glk_schannel_iterate(schanid_t chan, uint *rockptr);
228 	uint glk_schannel_get_rock(schanid_t chan);
229 
230 	uint glk_schannel_play(schanid_t chan, uint snd);
231 	uint glk_schannel_play_ext(schanid_t chan, uint snd, uint repeats,
232 	                             uint notify);
233 	void glk_schannel_stop(schanid_t chan);
234 	void glk_schannel_set_volume(schanid_t chan, uint vol);
235 
236 	void glk_sound_load_hint(uint snd, uint flag);
237 
238 #ifdef GLK_MODULE_SOUND2
239 	/* Note that this section is nested inside the #ifdef GLK_MODULE_SOUND.
240 	GLK_MODULE_SOUND must be defined if GLK_MODULE_SOUND2 is. */
241 
242 	schanid_t glk_schannel_create_ext(uint rock, uint volume);
243 	uint glk_schannel_play_multi(schanid_t *chanarray, uint chancount,
244 	                               uint *sndarray, uint soundcount, uint notify);
245 	void glk_schannel_pause(schanid_t chan);
246 	void glk_schannel_unpause(schanid_t chan);
247 	void glk_schannel_set_volume_ext(schanid_t chan, uint vol,
248 	                                 uint duration, uint notify);
249 
250 #endif /* GLK_MODULE_SOUND2 */
251 #endif /* GLK_MODULE_SOUND */
252 
253 #ifdef GLK_MODULE_HYPERLINKS
254 
255 	void glk_set_hyperlink(uint linkval);
256 	void glk_set_hyperlink_stream(strid_t str, uint linkval);
257 	void glk_request_hyperlink_event(winid_t win);
258 	void glk_cancel_hyperlink_event(winid_t win);
259 
260 #endif /* GLK_MODULE_HYPERLINKS */
261 
262 #ifdef GLK_MODULE_DATETIME
263 
264 	void glk_current_time(glktimeval_t *time);
265 	int glk_current_simple_time(uint factor);
266 	void glk_time_to_date_utc(const glktimeval_t *time, glkdate_t *date);
267 	void glk_time_to_date_local(const glktimeval_t *time, glkdate_t *date);
268 	void glk_simple_time_to_date_utc(int time, uint factor, glkdate_t *date);
269 	void glk_simple_time_to_date_local(int time, uint factor, glkdate_t *date);
270 	void glk_date_to_time_utc(const glkdate_t *date, glktimeval_t *time);
271 	void glk_date_to_time_local(const glkdate_t *date, glktimeval_t *time);
272 	int glk_date_to_simple_time_utc(const glkdate_t *date, uint factor);
273 	int glk_date_to_simple_time_local(const glkdate_t *date, uint factor);
274 
275 #endif /* GLK_MODULE_DATETIME */
276 
277 	/* XXX non-official Glk functions that may or may not exist */
278 #define GARGLK 1
279 
280 	const char *garglk_fileref_get_name(frefid_t fref) const;
281 
282 	void garglk_set_program_name(const char *name);
283 	void garglk_set_program_info(const char *info);
284 	void garglk_set_story_name(const char *name);
285 	void garglk_set_story_title(const char *title);
286 	void garglk_set_config(const char *name);
287 
288 	/**
289 	 * Removes the specified string from the end of the output buffer, if
290 	 * indeed it is there.
291 	 */
292 	void garglk_unput_string(const char *str);
293 
294 	/**
295 	 * Removes the specified string from the end of the output buffer, if
296 	 * indeed it is there.
297 	 */
298 	void garglk_unput_string_uni(const uint32 *str);
299 
300 	void garglk_set_zcolors(uint fg, uint bg);
301 	void garglk_set_zcolors_stream(strid_t str, uint fg, uint bg);
302 	void garglk_set_reversevideo(uint reverse);
303 	void garglk_set_reversevideo_stream(strid_t str, uint reverse);
304 
305 	void garglk_window_get_cursor(winid_t win, uint *xpos, uint *ypos);
306 	void garglk_window_get_cursor_current(uint *xpos, uint *ypos);
307 
308 	/* dispa methods */
309 
310 	void gidispatch_set_object_registry(gidispatch_rock_t(*regi)(void *obj, uint objclass),
311 		void(*unregi)(void *obj, uint objclass, gidispatch_rock_t objrock));
312 
313 	void gidispatch_set_retained_registry(gidispatch_rock_t(*regi)(void *array, uint len, const char *typecode),
314 		void(*unregi)(void *array, uint len, const char *typecode, gidispatch_rock_t objrock));
315 
316 	uint32 gidispatch_count_classes() const;
317 	const gidispatch_intconst_t *gidispatch_get_class(uint32 index) const;
318 	uint32 gidispatch_count_intconst() const;
319 	const gidispatch_intconst_t *gidispatch_get_intconst(uint32 index) const;
320 	const char *gidispatch_prototype(uint32 funcnum) const;
321 	void gidispatch_call(uint32 funcnum, uint32 numargs, gluniversal_t *arglist);
322 	gidispatch_rock_t gidispatch_get_objrock(void *obj, uint objclass);
323 };
324 
325 } // End of namespace Glk
326 
327 #endif
328