LibGame  v0.4.0
The LG Game Engine - Copyright (C) 2024 ETMSoftware
libgame.h
1 /*
2  * LibGame - Copyright (C) Emmanuel Thomas-Maurin 2011-2024
3  * All rights reserved
4  *
5  * LibGame is a SDL2/OpenGL ES 2.0 2D/3D minimalist game engine, which doesn't
6  * attempt to do *everything* but does only certain things and does them *well*,
7  * while not preventing you from doing other things (huh ?)
8  *
9  * This version supports both Linux Desktop and Android (with NDK).
10  */
11 
12 #ifndef LIBGAME_H
13 #define LIBGAME_H
14 
15 #ifndef _GNU_SOURCE
16  #define _GNU_SOURCE
17 #endif
18 #ifndef _ISOC11_SOURCE
19  #define _ISOC11_SOURCE
20 #endif
21 
22 #define LIBGAME_NAME "LibGame"
23 #define LIBGAME_V_NUM "0.4.0"
24 #define LIBGAME_COPYRIGHT_STR "Copyright (C) Emmanuel Thomas-Maurin 2012-2024 - All rights reserved"
25 
26 #define LIBGAME_WEBSITE "https://www.etmsoftware.com" /*"https://www.aetm-games.com"*/
27 #define LIBGAME_DOWNLOAD_WEBSITE LIBGAME_WEBSITE "/download.php"
28 #define LIBGAME_SUPPORT_WEBSITE LIBGAME_WEBSITE "/help.php"
29 #define LIBGAME_SUPPORT_EMAIL "[email protected]" /*"[email protected]"*/
30 
31 #if !defined(ANDROID_V) && !defined(WIN32_V)
32  #define LINUX_V
33 #endif
34 
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdio.h>
38 #include <stdint.h>
39 #include <math.h>
40 #include <errno.h>
41 #include <time.h>
42 #include <unistd.h>
43 #include <sys/stat.h>
44 #include <sys/time.h>
45 #include <byteswap.h>
46 #include <stdalign.h>
47 #ifndef WIN32_V /* Linux and Android versions */
48  #include <grp.h>
49  #include <pwd.h>
50  #include <signal.h>
51 #else
52  #include <direct.h>
53 #endif
54 
55 #ifdef ANDROID_V
56  #include <jni.h>
57  #include <android/log.h>
58 #endif
59 
60 #ifndef WIN32_V /* Linux and Android versions */
61  #include <SDL.h>
62  #include <SDL_image.h>
63  #include <SDL_mixer.h>
64  #include <SDL_ttf.h>
65  #include <SDL_syswm.h>
66  #ifdef LINUX_V
67  #include <SDL_mouse.h>
68  #endif
69 #else /* Not tested */
70  #include <SDL.h>
71  #include <SDL2/SDL_image.h>
72  #include <SDL2/SDL_mixer.h>
73  #include <SDL2/SDL_ttf.h>
74  #include <SDL_mouse.h>
75  #include <SDL_syswm.h>
76 #endif
77 
78 #include <GLES2/gl2.h>
79 #include <GLES2/gl2ext.h>
80 
81 /* Logging stuff for libetm - must appear before #include libetm.h */
82 #define LIBETM_VERBOSE_OUTPUT
83 /*#define LIBETM_DEBUG_OUTPUT*/
84 
85 /* LIBETM_DEBUG_OUTPUT implies LIBETM_VERBOSE_OUTPUT */
86 #ifdef LIBETM_DEBUG_OUTPUT
87  #ifndef LIBETM_VERBOSE_OUTPUT
88  #define LIBETM_VERBOSE_OUTPUT
89  #endif
90 #endif
91 
92 /*
93  * === Need sth to easily switch on/off GL debugging ===
94  * CHECK_GL_E and CHECK_GL_E_2 are defined in lg_shader_progs.h
95  */
96 //#define GL_DEBUG
97 #ifdef GL_DEBUG
98  #
99 #else
100  #
101 #endif
102 
103 #ifdef ANDROID_V
104  #include "../extra_libs/libetm-0.5.1/libetm.h"
105 #else
106  #ifndef WIN32_V /* Linux version */
107  #include <libetm/libetm.h>
108  #else
109  #include "../extra_libs/libetm-0.5.1/libetm.h"
110  #endif
111 #endif
112 
113 #ifndef ANDROID_V
114  #undef INFO_ERR
115  #define INFO_ERR INFO_ERR2
116 #endif
117 
118 /* Logging stuff for libgame */
119 #define VERBOSE_OUTPUT
120 /*#define DEBUG_OUTPUT*/
121 
122 /* DEBUG_OUTPUT implies VERBOSE_OUTPUT */
123 #ifdef DEBUG_OUTPUT
124  #ifndef VERBOSE_OUTPUT
125  #define VERBOSE_OUTPUT
126  #endif
127 #endif
128 
129 //#define FUNC2(...) FUNC1(hello, __VA_ARGS__)
130 
131 #define TMPSTR_SIZE ((4 * 1024) - 1) /* = 4 KiB - 1 */
132 #define FILE_NAME_MAXLEN TMPSTR_SIZE
133 
134 #ifdef LIBGAME_COMPILE_TIME
135  #include "../extra_libs/math_3d.h"
136  #include "../extra_libs/stb_image.h"
137 #else
138  #include <libgame/extra_libs/math_3d.h>
139  #include <libgame/extra_libs/stb_image.h>
140 #endif
141 
142 /* What order for header files ? */
143 /* "lg_env_instance.h" is included after typedef of LG_Env */
144 #include "lg_vbo.h"
145 #include "lg_shader_progs.h"
146 #include "lg_vertex.h"
147 #include "lg_gr_func.h"
148 #include "lg_textures.h"
149 #include "lg_dds_loader.h"
150 #include "lg_astc_loader.h"
151 #include "lg_linked_list.h"
152 #include "lg_sprites.h"
153 #include "lg_background.h"
154 #include "lg_wins.h"
155 #include "lg_keyboard.h"
156 #include "lg_mouse.h"
157 #include "lg_touchscreen.h"
158 #include "lg_audio.h"
159 #include "lg_dirs_stuff.h"
160 #include "lg_quaternions.h"
161 #include "lg_misc.h"
162 #include "lg_ui.h"
163 #include "lg_3d_primitives.h"
164 #include "lg_opengl_2d.h"
165 #include "lg_mesh.h"
166 #include "lg_camera.h"
167 #include "lg_obj_parser.h"
168 #include "lg_light.h"
169 #include "lg_scene_graph.h"
170 #include "lg_scene.h"
171 #include "lg_collision_detect.h"
172 #include "lg_admob.h"
173 #include "lg_vao_gl_ext.h"
174 #include "lg_cubemap.h"
175 #include "lg_error.h"
176 #include "lg_file_ops.h"
177 #include "lg_android_assets.h"
178 #include "lg_render.h"
179 #include "lg_terrain.h"
180 #include "lg_perlin_noise.h"
181 #include "lg_landscape.h"
182 
183 typedef enum {
184  LG_OK = LIBETM_LASTERRORCODE + 1,
185  LG_ERROR,
186  LG_INIT_ERROR,
187  LG_EXTRA_LIB_INIT_ERROR,
188  LG_OPENGL_ERROR,
189  LG_GLSL_ERROR,
190  LG_CREATE_FILE_ERROR,
191  LG_OPEN_FILE_ERROR,
192  LG_SAVE_FILE_ERROR,
193  LG_READ_FROM_FILE_ERROR,
194  LG_WRITE_TO_FILE_ERROR,
195  LG_FILE_ACCESS_ERROR,
196  LG_READ_FROM_FILE_EOF,
197  LG_EOF,
198  LG_OOM,
199  LG_INVALID_PTR,
200  /* Unix signals */
201  LG_BUSERR, /* SIGBUS Bus error (bad memory access) */
202  LG_FPE, /* SIGFPE Floating-point exception */
203  LG_ILL, /* SIGILL Illegal Instruction */
204  LG_SEGFAULT, /* SIGSEGV Invalid memory reference */
205  /* Must really be the last one */
206  LG_LASTERRORCODE
207 } lg_error_code;
208 
209 typedef enum {
210  LG_CONTINUE = LG_LASTERRORCODE + 1,
211  LG_CANCEL,
212  LG_QUIT,
213  LG_WON,
214  LG_LOST,
215  LG_LASTRETURNCODE
216 } lg_return_code;
217 
218 /*
219  * WIN_LOGICAL_W and WIN_LOGICAL_H must be defined in app
220  * 16/9 or (on new mobiles) 18/9 ?
221  * #define WIN_LOGICAL_W 1000
222  * #define WIN_LOGICAL_H 500
223  * On Android, we *always* want/use landscape orientation
224  */
225 #define LG_WIN_WIDTH_MIN 800
226 #define LG_WIN_HEIGHT_MIN 400
227 
228 #define LG_WIN_D_HEIGHT_HACK 2 /* DIRTY HACK: We want the whole win to be visible */
229 
230 /* Requested bit-depth */
231 #define LG_REQUESTED_RED_SIZE 5
232 #define LG_REQUESTED_GREEN_SIZE 6
233 #define LG_REQUESTED_BLUE_SIZE 5
234 #define LG_REQUESTED_ALPHA_SIZE 0
235 #define LG_REQUESTED_DEPTH_SIZE 16
236 #define LG_REQUESTED_STENCIL_SIZE 8
237 
238 /*
239  * === LibGame environnement struct ===
240  * This is also a spec that the code is supposed to implement
241  * (should be like that for all comments.)
242  *
243  * === Libgame coord sys = SDL coord sys (y axis goes down) != OpenGL coord sys (y axis goes up) ===
244  * - SDL uses int's in [0 - win_w] x [0 - win_h] with origin at top left corner
245  * - OpenGL uses float's in [-1.0f, 1.0f] x [-1.0f, 1.0f] with origin at center
246  * - OpenGL win uses int's in [0 - gl_win w] x [0 - gl_win h] with origin at bottom left corner
247  * (-> glViewport() and glScissor() coord sys is (0, 0) = bottom-left, in pixels)
248  *
249  * ==============================================================================================
250  * Anyways, to avoid endless confusion, make sure to always mention coord sys in func definition
251  * ==============================================================================================
252  */
253 typedef struct {
254  /*
255  * SDL display mode stuff
256  */
257  int sdl_display;
258  SDL_DisplayMode sdl_display_mode;
259  int sdl_convert_surf_format; /* For all SDL_ConvertSurfaceFormat() ops */
260  int sdl_create_rgb_surf_bitdepth; /* For all SDL_CreateRGBSurface() ops */
261  int r_size, g_size, b_size, a_size;
262  uint32_t r_mask, g_mask, b_mask, a_mask; /* SDL interprets each pixel as a 32-bit integer */
263  /*
264  * Screen dims
265  */
266  int screen_w;
267  int screen_h;
268  /*
269  * OpenGL ES 2.0 stuff
270  */
271  SDL_Window *gl_win; /* Top SDL/GL win */
272  SDL_GLContext gl_context;
273  /*
274  * Top win dims are virtual/logical dims in fullscreen mode.
275  * In fullscreen mode, we compute an optimal viewport_rect (with letterboxing)
276  * and use scaling, keeping the same aspect ratio (like SDL2 with render logical size set).
277  * In windowed mode, viewport_rect and gl_win rect have the same size.
278  */
279  int top_win_logical_w; /* In fullscreen mode, logical w */
280  int top_win_logical_h; /* In fullscreen mode, logical h */
281  Rec2Di viewport_rect; /* THE DEFAULT VIEWPORT, COMPUTED DURING INIT, MUST *NOT* BE MODIFIED AFTERWARDS */
282  zboolean fullscreen; /* Should always be set to TRUE on Android ? Seems it's expected from SDL */
283  float fullscreen_scale; /* MIN(scale_x, scale_y), to keep aspect ratio */
284  /*
285  * Texture max values
286  */
287  int max_combined_texture_image_units;
288  int max_texture_size;
289  int max_cubemap_texture_size;
290  /*
291  * Background
292  */
293  GLuint lg_backgroud_tex_id;
294  LG_Color_u bg_color; /* Always set after a call to lg_clear_bg() */
295  int bg_shift_x; /* Not sure what the purpose was exactly */
296  int bg_shift_y; /* Not sure what the purpose was exactly */
297  /*
298  * App stuff
299  */
300  char *app_name;
301  char *app_cmd;
302  char *org_name_android; /* Android-specific */
303  char *app_name_android; /* Android-specific */
304  char *assets_dir; /* App data dir on Linux, app assets on Android */
305  char *app_wr_dir; /* App home dir on Linux, app-specific writable persistent dir on Android */
306  char *vbo_cache;
307  char *obj_cache;
308  /*
309  * Mouse support
310  */
311  zboolean enable_mouse;
312  /*
313  * OpenGL ES extensions support
314  */
315  zboolean oes_vao_extension;
316  void (*glGenVertexArraysOES)(GLsizei, GLuint *);
317  void (*glBindVertexArrayOES)(GLuint);
318  void (*glDeleteVertexArraysOES)(GLsizei, const GLuint *);
319  void (*glIsVertexArrayOES)(GLuint);
320  zboolean oes_element_index_uint_extension;
321  zboolean ext_texcompr_s3tc_extension;
322  zboolean oes_texcompr_etc1_rgb8_extension;
323  zboolean khr_texcompr_astc_ldr_extension;
324  //zboolean khr_texcompr_astc_hdr_extension;
325  //zboolean ext_texcompr_astc_decode_mode_extension;
326  // NEW: any good ?
327  LG_ErrorContext last_error_context;
328  // NEW: any good ?
329  float luminosity_k;
330  LG_Sound **sounds; /* Unused so far */
331  //
332  zboolean fonts_loaded;
333 } LG_Env;
334 
335 #include "lg_env_instance.h"
336 
337 #define GAME_FONT1 "DejaVuSans-Bold.ttf"
338 #define GAME_FONT2 "PAPYRUS.ttf"
339 #define GAME_FONT3 "intelone-mono-font-family-bold.ttf"
340 
341 /* (From: https://cloford.com/resources/charcodes/utf-8_arrows.htm) */
342 #define LEFT_ARROW_LIGHT_UTF8 "\u2190" /* Light leftwards arrow */
343 #define RIGHT_ARROW_LIGHT_UTF8 "\u2192" /* Light rightwards arrow */
344 #define UP_ARROW_LIGHT_UTF8 "\u2191" /* Light upwards arrow */
345 #define DOWN_ARROW_LIGHT_UTF8 "\u2193" /* Light downwards arrow */
346 
347 /* (From: https://cloford.com/resources/charcodes/utf-8_dingbats.htm) */
348 #define UTF8_RW_ROUNDED_ARROW "\u279c" /* Rounded rightwards arrow */
349 
350 int lg_init(int, int, const char *, const char *, const char *, const char *, const char *, const char *, const char *);
351 
353 
355 
356 void lg_reset_viewport();
357 
358 void lg_enable_mouse();
359 
360 void lg_disable_mouse();
361 
363 
364 int lg_load_fonts();
365 
366 void lg_quit(int);
367 
368 void lg_swap_fb();
369 
370 void lg_show_lib_info();
371 
372 void lg_show_sys_info();
373 
374 void lg_show_extra_sys_info(SDL_Window *);
375 
376 zboolean sdl2_is_installed();
377 
378 /* Must be freed afterwards with l_str_free() */
379 char *lg_get_sdl_win_flags(SDL_Window *);
380 
381 #endif /* LIBGAME_H */
lg_load_fonts
int lg_load_fonts()
Definition: libgame.c:802
lg_reset_viewport
void lg_reset_viewport()
Definition: libgame.c:760
lg_show_sys_info
void lg_show_sys_info()
Definition: libgame.c:959
LG_Sound
Definition: lg_audio.h:40
LG_Env
Definition: libgame.h:253
lg_enable_mouse
void lg_enable_mouse()
Definition: libgame.c:769
lg_swap_fb
void lg_swap_fb()
Definition: libgame.c:927
lg_get_default_viewport
Rec2Di lg_get_default_viewport()
Definition: libgame.c:742
LG_Color_u
Definition: lg_vertex.h:91
lg_set_new_viewport
void lg_set_new_viewport(Rec2Di viewport)
Definition: libgame.c:752
lg_init
int lg_init(int win_w, int win_h, const char *win_title, const char *app_name, const char *app_cmd, const char *org_name_android, const char *app_name_android, const char *assets_dir, const char *app_wr_dir)
Definition: libgame.c:51
lg_show_extra_sys_info
void lg_show_extra_sys_info(SDL_Window *w)
Definition: libgame.c:1056
lg_get_sdl_win_flags
char * lg_get_sdl_win_flags(SDL_Window *w)
Definition: libgame.c:1131
sdl2_is_installed
zboolean sdl2_is_installed()
Definition: libgame.c:1115
lg_quit
void lg_quit(int exit_code)
Definition: libgame.c:840
LG_ErrorContext
Definition: lg_error.h:40
lg_list_opengl_extensions
void lg_list_opengl_extensions()
Definition: libgame.c:785
lg_disable_mouse
void lg_disable_mouse()
Definition: libgame.c:777
lg_show_lib_info
void lg_show_lib_info()
Definition: libgame.c:935
Rec2Di
Definition: lg_gr_func.h:47