aboutsummaryrefslogtreecommitdiff
path: root/engines/glk/glk_api.h
blob: e54cd3c0427b2e9886b02ba8e80ee954a44984d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#ifndef GLK_GLK_API_H
#define GLK_GLK_API_H

#include "glk/glk.h"
#include "glk/glk_types.h"
#include "glk/blorb.h"
#include "glk/sound.h"
#include "glk/time.h"
#include "glk/windows.h"

namespace Glk {

class GlkAPI;

typedef void (GlkAPI::*GlkFunction)();

struct gidispatch_function_struct {
	uint32 id;
	const char *name;
	GlkFunction fnptr;
};
typedef gidispatch_function_struct gidispatch_function_t;


/**
 * Implements the GLK interface
 */
class GlkAPI : public GlkEngine {
private:
	bool _gliFirstEvent;
	unsigned char _charTolowerTable[256];
	unsigned char _charToupperTable[256];

	gidispatch_rock_t(*gli_register_obj)(void *obj, uint objclass);
	void(*gli_unregister_obj)(void *obj, uint objclass, gidispatch_rock_t objrock);
	gidispatch_rock_t(*gli_register_arr)(void *array, uint len, char *typecode);
	void(*gli_unregister_arr)(void *array, uint len, char *typecode, gidispatch_rock_t objrock);
public:
	/**
	 * Constructor
	 */
	GlkAPI(OSystem *syst, const GlkGameDescription &gameDesc);
	virtual ~GlkAPI() {}

	void glk_exit(void);
	void glk_set_interrupt_handler(void(*func)(void));
	void glk_tick(void);

	uint glk_gestalt(uint id, uint val);
	uint glk_gestalt_ext(uint id, uint val, uint *arr, uint arrlen);

	unsigned char glk_char_to_lower(unsigned char ch);
	unsigned char glk_char_to_upper(unsigned char ch);

	/**
	 * Get the root window of the window hierarchy
	 */
	winid_t glk_window_get_root(void) const;

	/**
	 * Open a new window
	 */
	winid_t glk_window_open(winid_t split, uint method, uint size,
	                        uint wintype, uint rock = 0) const;

	void glk_window_close(winid_t win, stream_result_t *result = nullptr);
	void glk_window_get_size(winid_t win, uint *width, uint *height);
	void glk_window_set_arrangement(winid_t win, uint method,
	                                uint size, winid_t keyWin);
	void glk_window_get_arrangement(winid_t win, uint *method,
	                                uint *size, winid_t *keyWin);
	winid_t glk_window_iterate(winid_t win, uint *rock = 0);
	uint glk_window_get_rock(winid_t win);
	uint glk_window_get_type(winid_t win);
	winid_t glk_window_get_parent(winid_t win);
	winid_t glk_window_get_sibling(winid_t win);
	void glk_window_clear(winid_t win);
	void glk_window_move_cursor(winid_t win, uint xpos, uint ypos);

	strid_t glk_window_get_stream(winid_t win);
	void glk_window_set_echo_stream(winid_t win, strid_t str);
	strid_t glk_window_get_echo_stream(winid_t win);
	void glk_set_window(winid_t win);

	strid_t glk_stream_open_file(frefid_t fileref, FileMode fmode, uint rock = 0);
	strid_t glk_stream_open_memory(char *buf, uint buflen, FileMode fmode, uint rock = 0);
	void glk_stream_close(strid_t str, stream_result_t *result = nullptr);
	strid_t glk_stream_iterate(strid_t str, uint *rockptr) const;
	uint glk_stream_get_rock(strid_t str) const;
	void glk_stream_set_position(strid_t str, int pos, uint seekMode);
	uint glk_stream_get_position(strid_t str) const;
	void glk_stream_set_current(strid_t str);
	strid_t glk_stream_get_current(void);

	void glk_put_char(unsigned char ch);
	void glk_put_char_stream(strid_t str, unsigned char ch);
	void glk_put_string(const char *s);
	void glk_put_string_stream(strid_t str, const char *s);
	void glk_put_buffer(const char *buf, uint len);
	void glk_put_buffer_stream(strid_t str, const char *buf, uint len);
	void glk_set_style(uint styl);
	void glk_set_style_stream(strid_t str, uint styl);

	int glk_get_char_stream(strid_t str);
	uint glk_get_line_stream(strid_t str, char *buf, uint len);
	uint glk_get_buffer_stream(strid_t str, char *buf, uint len);

	void glk_stylehint_set(uint wintype, uint styl, uint hint,
	                       int val);
	void glk_stylehint_clear(uint wintype, uint style, uint hint);
	uint glk_style_distinguish(winid_t win, uint style1, uint style2);
	bool glk_style_measure(winid_t win, uint style, uint hint, uint *result);

	frefid_t glk_fileref_create_temp(uint usage, uint rock = 0);
	frefid_t glk_fileref_create_by_name(uint usage, const char *name, uint rock = 0);
	frefid_t glk_fileref_create_by_prompt(uint usage, FileMode fmode, uint rock = 0);
	frefid_t glk_fileref_create_from_fileref(uint usage, frefid_t fref, uint rock = 0);
	void glk_fileref_destroy(frefid_t fref);
	frefid_t glk_fileref_iterate(frefid_t fref, uint *rockptr);
	uint glk_fileref_get_rock(frefid_t fref);
	void glk_fileref_delete_file(frefid_t fref);
	uint glk_fileref_does_file_exist(frefid_t fref);

	void glk_select(event_t *event);
	void glk_select_poll(event_t *event);

	void glk_request_timer_events(uint millisecs);

	void glk_request_line_event(winid_t win, char *buf, uint maxlen,
	                            uint initlen);
	void glk_request_char_event(winid_t win);
	void glk_request_mouse_event(winid_t win);

	void glk_cancel_line_event(winid_t win, event_t *event);
	void glk_cancel_char_event(winid_t win);
	void glk_cancel_mouse_event(winid_t win);

#ifdef GLK_MODULE_LINE_ECHO
	void glk_set_echo_line_event(winid_t win, uint val);
#endif /* GLK_MODULE_LINE_ECHO */

#ifdef GLK_MODULE_LINE_TERMINATORS
	void glk_set_terminators_line_event(winid_t win, const uint32 *keycodes, uint count);
#endif /* GLK_MODULE_LINE_TERMINATORS */

	/** \addtogroup Unicode
	 *  @{
	 */

	uint glk_buffer_to_lower_case_uni(uint32 *buf, uint len, uint numchars);
	uint glk_buffer_to_upper_case_uni(uint32 *buf, uint len, uint numchars);
	uint glk_buffer_to_title_case_uni(uint32 *buf, uint len, uint numchars, uint lowerrest);

	void glk_put_char_uni(uint32 ch);
	void glk_put_string_uni(const uint32 *s);
	void glk_put_buffer_uni(const uint32 *buf, uint len);
	void glk_put_char_stream_uni(strid_t str, uint32 ch);
	void glk_put_string_stream_uni(strid_t str, const uint32 *s);
	void glk_put_buffer_stream_uni(strid_t str, const uint32 *buf, uint len);

	int glk_get_char_stream_uni(strid_t str);
	uint glk_get_buffer_stream_uni(strid_t str, uint32 *buf, uint len);
	uint glk_get_line_stream_uni(strid_t str, uint32 *buf, uint len);

	strid_t glk_stream_open_file_uni(frefid_t fileref, FileMode fmode, uint rock = 0);
	strid_t glk_stream_open_memory_uni(uint32 *buf, uint buflen, FileMode fmode, uint rock = 0);

	void glk_request_char_event_uni(winid_t win);
	void glk_request_line_event_uni(winid_t win, uint32 *buf, uint maxlen, uint initlen);

	/** @}*/

#ifdef GLK_MODULE_UNICODE_NORM

	uint glk_buffer_canon_decompose_uni(uint32 *buf, uint len, uint numchars);
	uint glk_buffer_canon_normalize_uni(uint32 *buf, uint len, uint numchars);

#endif /* GLK_MODULE_UNICODE_NORM */

#ifdef GLK_MODULE_IMAGE

	bool glk_image_draw(winid_t win, uint image, int val1, int val2);
	bool glk_image_draw_scaled(winid_t win, uint image,
	                             int val1, int val2, uint width, uint height);
	bool glk_image_get_info(uint image, uint *width, uint *height);

	void glk_window_flow_break(winid_t win);

	void glk_window_erase_rect(winid_t win,
	                           int left, int top, uint width, uint height);
	void glk_window_fill_rect(winid_t win, uint color,
	                          int left, int top, uint width, uint height);
	void glk_window_set_background_color(winid_t win, uint color);

#endif /* GLK_MODULE_IMAGE */

#ifdef GLK_MODULE_SOUND

	schanid_t glk_schannel_create(uint rock = 0);
	void glk_schannel_destroy(schanid_t chan);
	schanid_t glk_schannel_iterate(schanid_t chan, uint *rockptr);
	uint glk_schannel_get_rock(schanid_t chan);

	uint glk_schannel_play(schanid_t chan, uint snd);
	uint glk_schannel_play_ext(schanid_t chan, uint snd, uint repeats,
	                             uint notify);
	void glk_schannel_stop(schanid_t chan);
	void glk_schannel_set_volume(schanid_t chan, uint vol);

	void glk_sound_load_hint(uint snd, uint flag);

#ifdef GLK_MODULE_SOUND2
	/* Note that this section is nested inside the #ifdef GLK_MODULE_SOUND.
	GLK_MODULE_SOUND must be defined if GLK_MODULE_SOUND2 is. */

	schanid_t glk_schannel_create_ext(uint rock, uint volume);
	uint glk_schannel_play_multi(schanid_t *chanarray, uint chancount,
	                               uint *sndarray, uint soundcount, uint notify);
	void glk_schannel_pause(schanid_t chan);
	void glk_schannel_unpause(schanid_t chan);
	void glk_schannel_set_volume_ext(schanid_t chan, uint vol,
	                                 uint duration, uint notify);

#endif /* GLK_MODULE_SOUND2 */
#endif /* GLK_MODULE_SOUND */

#ifdef GLK_MODULE_HYPERLINKS

	void glk_set_hyperlink(uint linkval);
	void glk_set_hyperlink_stream(strid_t str, uint linkval);
	void glk_request_hyperlink_event(winid_t win);
	void glk_cancel_hyperlink_event(winid_t win);

#endif /* GLK_MODULE_HYPERLINKS */

#ifdef GLK_MODULE_DATETIME

	void glk_current_time(glktimeval_t *time);
	int glk_current_simple_time(uint factor);
	void glk_time_to_date_utc(const glktimeval_t *time, glkdate_t *date);
	void glk_time_to_date_local(const glktimeval_t *time, glkdate_t *date);
	void glk_simple_time_to_date_utc(int time, uint factor, glkdate_t *date);
	void glk_simple_time_to_date_local(int time, uint factor, glkdate_t *date);
	void glk_date_to_time_utc(const glkdate_t *date, glktimeval_t *time);
	void glk_date_to_time_local(const glkdate_t *date, glktimeval_t *time);
	int glk_date_to_simple_time_utc(const glkdate_t *date, uint factor);
	int glk_date_to_simple_time_local(const glkdate_t *date, uint factor);

#endif /* GLK_MODULE_DATETIME */

	/* XXX non-official Glk functions that may or may not exist */
#define GARGLK 1

	const char *garglk_fileref_get_name(frefid_t fref) const;

	void garglk_set_program_name(const char *name);
	void garglk_set_program_info(const char *info);
	void garglk_set_story_name(const char *name);
	void garglk_set_story_title(const char *title);
	void garglk_set_config(const char *name);

	/**
	 * Removes the specified string from the end of the output buffer, if
	 * indeed it is there.
	 */
	void garglk_unput_string(const char *str);

	/**
	 * Removes the specified string from the end of the output buffer, if
	 * indeed it is there.
	 */
	void garglk_unput_string_uni(const uint32 *str);

	void garglk_set_zcolors(uint fg, uint bg);
	void garglk_set_zcolors_stream(strid_t str, uint fg, uint bg);
	void garglk_set_reversevideo(uint reverse);
	void garglk_set_reversevideo_stream(strid_t str, uint reverse);

	void garglk_window_get_cursor(winid_t win, uint *xpos, uint *ypos);
	void garglk_window_get_cursor_current(uint *xpos, uint *ypos);

	/* dispa methods */

	void gidispatch_set_object_registry(gidispatch_rock_t(*regi)(void *obj, uint objclass),
		void(*unregi)(void *obj, uint objclass, gidispatch_rock_t objrock));

	void gidispatch_set_retained_registry(gidispatch_rock_t(*regi)(void *array, uint len, char *typecode),
		void(*unregi)(void *array, uint len, char *typecode, gidispatch_rock_t objrock));

	uint32 gidispatch_count_classes() const;
	const gidispatch_intconst_t *gidispatch_get_class(uint32 index) const;
	uint32 gidispatch_count_intconst() const;
	const gidispatch_intconst_t *gidispatch_get_intconst(uint32 index) const;
	uint32 gidispatch_count_functions() const;
	gidispatch_function_t *gidispatch_get_function(uint32 index) const;
	gidispatch_function_t *gidispatch_get_function_by_id(uint32 id) const;
	const char *gidispatch_prototype(uint32 funcnum) const;
	void gidispatch_call(uint32 funcnum, uint32 numargs, gluniversal_t *arglist);
	gidispatch_rock_t gidispatch_get_objrock(void *obj, uint objclass);
};

} // End of namespace Glk

#endif