// (c) 1995-2014 by Artsoft Entertainment
// Holger Schemel
// info@artsoft.org
-// http://www.artsoft.org/
+// https://www.artsoft.org/
// ----------------------------------------------------------------------------
// system.c
// ============================================================================
#include "joystick.h"
#include "misc.h"
-#define ENABLE_UNUSED_CODE 0 /* currently unused functions */
+#define ENABLE_UNUSED_CODE 0 // currently unused functions
-/* ========================================================================= */
-/* exported variables */
-/* ========================================================================= */
+// ============================================================================
+// exported variables
+// ============================================================================
struct ProgramInfo program;
struct NetworkInfo network;
+struct RuntimeInfo runtime;
struct OptionInfo options;
struct VideoSystemInfo video;
struct AudioSystemInfo audio;
struct ArtworkInfo artwork;
struct JoystickInfo joystick;
struct SetupInfo setup;
+struct UserInfo user;
LevelDirTree *leveldir_first_all = NULL;
LevelDirTree *leveldir_first = NULL;
int button_status = MB_NOT_PRESSED;
boolean motion_status = FALSE;
int wheel_steps = DEFAULT_WHEEL_STEPS;
-#if defined(TARGET_SDL2)
boolean keyrepeat_status = TRUE;
-#endif
+boolean textinput_status = FALSE;
int redraw_mask = REDRAW_NONE;
int FrameCounter = 0;
-/* ========================================================================= */
-/* init/close functions */
-/* ========================================================================= */
+// ============================================================================
+// init/close functions
+// ============================================================================
void InitProgramInfo(char *argv0, char *config_filename, char *userdata_subdir,
char *program_title, char *icon_title,
program.config_filename = config_filename;
program.userdata_subdir = userdata_subdir;
- program.userdata_path = getUserGameDataDir();
+ program.userdata_path = getMainUserGameDataDir();
program.program_title = program_title;
program.window_title = "(undefined)";
network.server_host = server_host;
network.server_port = server_port;
+
+ network.server_thread = NULL;
+ network.is_server_thread = FALSE;
}
-void InitScoresInfo()
+void InitRuntimeInfo()
{
- char *global_scores_dir = getPath2(getCommonDataDir(), SCORES_DIRECTORY);
-
- program.global_scores = directoryExists(global_scores_dir);
- program.many_scores_per_name = !program.global_scores;
-
-#if 0
- if (options.debug)
- {
- if (program.global_scores)
- {
- Error(ERR_DEBUG, "Using global, multi-user scores directory '%s'.",
- global_scores_dir);
- Error(ERR_DEBUG, "Remove to enable single-user scores directory.");
- Error(ERR_DEBUG, "(This enables multipe score entries per user.)");
- }
- else
- {
- Error(ERR_DEBUG, "Using private, single-user scores directory.");
- }
- }
+#if defined(HAS_TOUCH_DEVICE)
+ runtime.uses_touch_device = TRUE;
+#else
+ runtime.uses_touch_device = FALSE;
#endif
- free(global_scores_dir);
+ runtime.use_api_server = setup.use_api_server;
}
-void SetWindowTitle()
+void SetWindowTitle(void)
{
program.window_title = program.window_title_function();
{
program.exit_function = exit_function;
- /* set signal handlers to custom exit function */
+ // set signal handlers to custom exit function
// signal(SIGINT, exit_function);
signal(SIGTERM, exit_function);
- /* set exit function to automatically cleanup SDL stuff after exit() */
+ // set exit function to automatically cleanup SDL stuff after exit()
atexit(SDL_Quit);
}
void InitPlatformDependentStuff(void)
{
+ InitEmscriptenFilesystem();
+
// this is initialized in GetOptions(), but may already be used before
options.verbose = TRUE;
OpenLogFiles();
-#if defined(TARGET_SDL2)
- int sdl_init_flags = SDL_INIT_EVENTS | SDL_INIT_NOPARACHUTE;
-#else
- int sdl_init_flags = SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE;
-#endif
+ int sdl_init_flags = SDL_INIT_EVENTS | SDL_INIT_NOPARACHUTE;
if (SDL_Init(sdl_init_flags) < 0)
- Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
+ Fail("SDL_Init() failed: %s", SDL_GetError());
SDLNet_Init();
}
gfx.field_save_buffer = field_save_buffer;
- SetDrawDeactivationMask(REDRAW_NONE); /* do not deactivate drawing */
- SetDrawBackgroundMask(REDRAW_NONE); /* deactivate masked drawing */
+ SetDrawDeactivationMask(REDRAW_NONE); // do not deactivate drawing
+ SetDrawBackgroundMask(REDRAW_NONE); // deactivate masked drawing
}
void InitGfxTileSizeInfo(int game_tile_size, int standard_tile_size)
{
ReCreateBitmap(&gfx.background_bitmap, win_xsize, win_ysize);
-#if defined(TARGET_SDL2)
ReCreateBitmap(&gfx.final_screen_bitmap, win_xsize, win_ysize);
-#endif
ReCreateBitmap(&gfx.fade_bitmap_backup, win_xsize, win_ysize);
ReCreateBitmap(&gfx.fade_bitmap_source, win_xsize, win_ysize);
void InitGfxScrollbufferInfo(int scrollbuffer_width, int scrollbuffer_height)
{
- /* currently only used by MSDOS code to alloc VRAM buffer, if available */
- /* 2009-03-24: also (temporarily?) used for overlapping blit workaround */
+ // currently only used by MSDOS code to alloc VRAM buffer, if available
+ // 2009-03-24: also (temporarily?) used for overlapping blit workaround
gfx.scrollbuffer_width = scrollbuffer_width;
gfx.scrollbuffer_height = scrollbuffer_height;
}
gfx.draw_tile_cursor_function = draw_tile_cursor_function;
}
-void InitGfxCustomArtworkInfo()
+void InitGfxCustomArtworkInfo(void)
{
gfx.override_level_graphics = FALSE;
gfx.override_level_sounds = FALSE;
gfx.draw_init_text = TRUE;
}
-void InitGfxOtherSettings()
+void InitGfxOtherSettings(void)
{
gfx.cursor_mode = CURSOR_DEFAULT;
+ gfx.cursor_mode_override = CURSOR_UNDEFINED;
+ gfx.cursor_mode_final = gfx.cursor_mode;
+
+ // prevent initially displaying custom mouse cursor in upper left corner
+ gfx.mouse_x = POS_OFFSCREEN;
+ gfx.mouse_y = POS_OFFSCREEN;
}
-void InitTileCursorInfo()
+void InitTileCursorInfo(void)
{
tile_cursor.enabled = FALSE;
tile_cursor.active = FALSE;
tile_cursor.sx = 0;
tile_cursor.sy = 0;
+
+ tile_cursor.xsn_debug = FALSE;
}
-void InitOverlayInfo()
+void InitOverlayInfo(void)
{
- int nr = GRID_ACTIVE_NR();
- int x, y;
-
overlay.enabled = FALSE;
overlay.active = FALSE;
overlay.show_grid = FALSE;
- overlay.grid_xsize = setup.touch.grid_xsize[nr];
- overlay.grid_ysize = setup.touch.grid_ysize[nr];
-
- for (x = 0; x < MAX_GRID_XSIZE; x++)
- for (y = 0; y < MAX_GRID_YSIZE; y++)
- overlay.grid_button[x][y] = setup.touch.grid_button[nr][x][y];
-
overlay.grid_button_highlight = CHAR_GRID_BUTTON_NONE;
overlay.grid_button_action = JOY_NO_ACTION;
+ SetOverlayGridSizeAndButtons();
+
#if defined(USE_TOUCH_INPUT_OVERLAY)
if (strEqual(setup.touch.control_type, TOUCH_CONTROL_VIRTUAL_BUTTONS))
overlay.enabled = TRUE;
#endif
}
+void SetOverlayGridSizeAndButtons(void)
+{
+ int nr = GRID_ACTIVE_NR();
+ int x, y;
+
+ overlay.grid_xsize = setup.touch.grid_xsize[nr];
+ overlay.grid_ysize = setup.touch.grid_ysize[nr];
+
+ for (x = 0; x < MAX_GRID_XSIZE; x++)
+ for (y = 0; y < MAX_GRID_YSIZE; y++)
+ overlay.grid_button[x][y] = setup.touch.grid_button[nr][x][y];
+}
+
void SetTileCursorEnabled(boolean enabled)
{
tile_cursor.enabled = enabled;
SetOverlayEnabled(TRUE);
}
-boolean GetOverlayActive()
+boolean GetOverlayEnabled(void)
+{
+ return overlay.enabled;
+}
+
+boolean GetOverlayActive(void)
{
return overlay.active;
}
gfx.draw_deactivation_mask = draw_deactivation_mask;
}
-int GetDrawDeactivationMask()
+int GetDrawDeactivationMask(void)
{
return gfx.draw_deactivation_mask;
}
gfx.draw_background_mask = draw_background_mask;
}
-void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
+static void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
{
if (background_bitmap_tile != NULL)
gfx.background_bitmap_mask |= mask;
else
gfx.background_bitmap_mask &= ~mask;
- if (background_bitmap_tile == NULL) /* empty background requested */
+ if (background_bitmap_tile == NULL) // empty background requested
return;
if (mask == REDRAW_ALL)
void SetWindowBackgroundBitmap(Bitmap *background_bitmap_tile)
{
- /* remove every mask before setting mask for window */
- /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
- SetBackgroundBitmap(NULL, 0xffff); /* !!! FIX THIS !!! */
+ // remove every mask before setting mask for window
+ // (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!)
+ SetBackgroundBitmap(NULL, 0xffff); // !!! FIX THIS !!!
SetBackgroundBitmap(background_bitmap_tile, REDRAW_ALL);
}
void SetMainBackgroundBitmap(Bitmap *background_bitmap_tile)
{
- /* remove window area mask before setting mask for main area */
- /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
- SetBackgroundBitmap(NULL, REDRAW_ALL); /* !!! FIX THIS !!! */
+ // remove window area mask before setting mask for main area
+ // (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!)
+ SetBackgroundBitmap(NULL, REDRAW_ALL); // !!! FIX THIS !!!
SetBackgroundBitmap(background_bitmap_tile, REDRAW_FIELD);
}
void SetDoorBackgroundBitmap(Bitmap *background_bitmap_tile)
{
- /* remove window area mask before setting mask for door area */
- /* (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!) */
- SetBackgroundBitmap(NULL, REDRAW_ALL); /* !!! FIX THIS !!! */
+ // remove window area mask before setting mask for door area
+ // (!!! TO BE FIXED: The whole REDRAW_* system really sucks! !!!)
+ SetBackgroundBitmap(NULL, REDRAW_ALL); // !!! FIX THIS !!!
SetBackgroundBitmap(background_bitmap_tile, REDRAW_DOOR_1);
}
-/* ========================================================================= */
-/* video functions */
-/* ========================================================================= */
+// ============================================================================
+// video functions
+// ============================================================================
-inline static int GetRealDepth(int depth)
+static int GetRealDepth(int depth)
{
return (depth == DEFAULT_DEPTH ? video.default_depth : depth);
}
-inline static void sysFillRectangle(Bitmap *bitmap, int x, int y,
- int width, int height, Pixel color)
+static void sysFillRectangle(Bitmap *bitmap, int x, int y,
+ int width, int height, Pixel color)
{
SDLFillRectangle(bitmap, x, y, width, height, color);
SetRedrawMaskFromArea(x, y, width, height);
}
-inline static void sysCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
- int src_x, int src_y, int width, int height,
- int dst_x, int dst_y, int mask_mode)
+static void sysCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
+ int src_x, int src_y, int width, int height,
+ int dst_x, int dst_y, int mask_mode)
{
SDLCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
dst_x, dst_y, mask_mode);
return;
SDLInitVideoDisplay();
-#if defined(TARGET_SDL2)
SDLSetDisplaySize();
-#endif
}
void CloseVideoDisplay(void)
video.window_scaling_available = WINDOW_SCALING_STATUS;
+ video.frame_counter = 0;
video.frame_delay = 0;
video.frame_delay_value = GAME_FRAME_DELAY;
drawto = backbuffer;
}
-inline static void FreeBitmapPointers(Bitmap *bitmap)
+static void FreeBitmapPointers(Bitmap *bitmap)
{
if (bitmap == NULL)
return;
bitmap->source_filename = NULL;
}
-inline static void TransferBitmapPointers(Bitmap *src_bitmap,
- Bitmap *dst_bitmap)
+static void TransferBitmapPointers(Bitmap *src_bitmap,
+ Bitmap *dst_bitmap)
{
if (src_bitmap == NULL || dst_bitmap == NULL)
return;
Bitmap *CreateBitmap(int width, int height, int depth)
{
Bitmap *new_bitmap = CreateBitmapStruct();
- int real_width = MAX(1, width); /* prevent zero bitmap width */
- int real_height = MAX(1, height); /* prevent zero bitmap height */
+ int real_width = MAX(1, width); // prevent zero bitmap width
+ int real_height = MAX(1, height); // prevent zero bitmap height
int real_depth = GetRealDepth(depth);
SDLCreateBitmapContent(new_bitmap, real_width, real_height, real_depth);
{
if (*bitmap != NULL)
{
- /* if new bitmap size fits into old one, no need to re-create it */
+ // if new bitmap size fits into old one, no need to re-create it
if (width <= (*bitmap)->width &&
height <= (*bitmap)->height)
return;
- /* else adjust size so that old and new bitmap size fit into it */
+ // else adjust size so that old and new bitmap size fit into it
width = MAX(width, (*bitmap)->width);
height = MAX(height, (*bitmap)->height);
}
}
}
-void CloseWindow(DrawWindow *window)
+#if 0
+static void CloseWindow(DrawWindow *window)
{
}
+#endif
void SetRedrawMaskFromArea(int x, int y, int width, int height)
{
redraw_mask = REDRAW_ALL;
}
-inline static boolean CheckDrawingArea(int x, int y, int width, int height,
- int draw_mask)
+static boolean CheckDrawingArea(int x, int y, int width, int height,
+ int draw_mask)
{
if (draw_mask == REDRAW_NONE)
return FALSE;
return FALSE;
}
-boolean DrawingDeactivatedField()
+boolean DrawingDeactivatedField(void)
{
if (program.headless)
return TRUE;
{
int clip_x, clip_y, clip_width, clip_height;
- if (gfx.clipping_enabled && is_dest) /* only clip destination bitmap */
+ if (gfx.clipping_enabled && is_dest) // only clip destination bitmap
{
clip_x = MIN(MAX(0, gfx.clip_x), bitmap->width);
clip_y = MIN(MAX(0, gfx.clip_y), bitmap->height);
clip_height = bitmap->height;
}
- /* skip if rectangle completely outside bitmap */
+ // skip if rectangle completely outside bitmap
if (*x + *width <= clip_x ||
*y + *height <= clip_y ||
*y >= clip_y + clip_height)
return FALSE;
- /* clip if rectangle overlaps bitmap */
+ // clip if rectangle overlaps bitmap
if (*x < clip_x)
{
!InClippedRectangle(dst_bitmap, &dst_x, &dst_y, &width, &height, TRUE))
return;
- /* source x/y might need adjustment if destination x/y was clipped top/left */
+ // source x/y might need adjustment if destination x/y was clipped top/left
src_x += dst_x - dst_x_unclipped;
src_y += dst_y - dst_y_unclipped;
-#if defined(TARGET_SDL2)
- /* !!! 2013-12-11: An "old friend" is back. Same bug in SDL2 2.0.1 !!! */
- /* !!! 2009-03-30: Fixed by using self-compiled, patched SDL.dll !!! */
+ // !!! 2013-12-11: An "old friend" is back. Same bug in SDL2 2.0.1 !!!
+ // !!! 2009-03-30: Fixed by using self-compiled, patched SDL.dll !!!
/* (This bug still exists in the actual (as of 2009-06-15) version 1.2.13,
but is already fixed in SVN and should therefore finally be fixed with
the next official SDL release, which is probably version 1.2.14.) */
- /* !!! 2009-03-24: It seems that this problem still exists in 1.2.12 !!! */
+ // !!! 2009-03-24: It seems that this problem still exists in 1.2.12 !!!
if (src_bitmap == dst_bitmap)
{
- /* needed when blitting directly to same bitmap -- should not be needed with
- recent SDL libraries, but apparently does not work in 1.2.11 directly */
+ // needed when blitting directly to same bitmap -- should not be needed with
+ // recent SDL libraries, but apparently does not work in 1.2.11 directly
static Bitmap *tmp_bitmap = NULL;
static int tmp_bitmap_xsize = 0;
static int tmp_bitmap_ysize = 0;
- /* start with largest static bitmaps for initial bitmap size ... */
+ // start with largest static bitmaps for initial bitmap size ...
if (tmp_bitmap_xsize == 0 && tmp_bitmap_ysize == 0)
{
tmp_bitmap_xsize = MAX(gfx.win_xsize, gfx.scrollbuffer_width);
tmp_bitmap_ysize = MAX(gfx.win_ysize, gfx.scrollbuffer_height);
}
- /* ... and allow for later re-adjustments due to custom artwork bitmaps */
+ // ... and allow for later re-adjustments due to custom artwork bitmaps
if (src_bitmap->width > tmp_bitmap_xsize ||
src_bitmap->height > tmp_bitmap_ysize)
{
return;
}
-#endif
sysCopyArea(src_bitmap, dst_bitmap,
src_x, src_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
int fade_mode, int fade_delay, int post_delay,
void (*draw_border_function)(void))
{
- /* (use destination bitmap "backbuffer" -- "bitmap_cross" may be undefined) */
+ // (use destination bitmap "backbuffer" -- "bitmap_cross" may be undefined)
if (!InClippedRectangle(backbuffer, &x, &y, &width, &height, TRUE))
return;
{
if (DrawingOnBackground(dst_x, dst_y))
{
- /* draw background */
+ // draw background
BlitBitmap(gfx.background_bitmap, dst_bitmap, dst_x, dst_y, width, height,
dst_x, dst_y);
- /* draw foreground */
+ // draw foreground
BlitBitmapMasked(src_bitmap, dst_bitmap, src_x, src_y, width, height,
dst_x, dst_y);
}
SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, WHITE_PIXEL);
}
-void DrawLine(Bitmap *bitmap, int from_x, int from_y,
- int to_x, int to_y, Pixel pixel, int line_width)
+static void DrawLine(Bitmap *bitmap, int from_x, int from_y,
+ int to_x, int to_y, Pixel pixel, int line_width)
{
int x, y;
void KeyboardAutoRepeatOn(void)
{
-#if defined(TARGET_SDL2)
keyrepeat_status = TRUE;
-#else
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2,
- SDL_DEFAULT_REPEAT_INTERVAL / 2);
- SDL_EnableUNICODE(1);
-#endif
}
void KeyboardAutoRepeatOff(void)
{
-#if defined(TARGET_SDL2)
keyrepeat_status = FALSE;
-#else
- SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
- SDL_EnableUNICODE(0);
-#endif
}
boolean SetVideoMode(boolean fullscreen)
video.frame_delay_value = frame_delay_value;
}
-unsigned int GetVideoFrameDelay()
+unsigned int GetVideoFrameDelay(void)
{
return video.frame_delay_value;
}
Bitmap *new_bitmap;
if (filename == NULL)
- Error(ERR_EXIT, "LoadCustomImage(): cannot find file '%s'", basename);
+ Fail("LoadCustomImage(): cannot find file '%s'", basename);
if ((new_bitmap = LoadImage(filename)) == NULL)
- Error(ERR_EXIT, "LoadImage('%s') failed: %s", basename, GetError());
+ Fail("LoadImage('%s') failed", basename);
return new_bitmap;
}
char *filename = getCustomImageFilename(basename);
Bitmap *new_bitmap;
- if (filename == NULL) /* (should never happen) */
+ if (filename == NULL) // (should never happen)
{
- Error(ERR_WARN, "ReloadCustomImage(): cannot find file '%s'", basename);
+ Warn("ReloadCustomImage(): cannot find file '%s'", basename);
+
return;
}
if (strEqual(filename, bitmap->source_filename))
{
- /* The old and new image are the same (have the same filename and path).
- This usually means that this image does not exist in this graphic set
- and a fallback to the existing image is done. */
+ // The old and new image are the same (have the same filename and path).
+ // This usually means that this image does not exist in this graphic set
+ // and a fallback to the existing image is done.
return;
}
if ((new_bitmap = LoadImage(filename)) == NULL)
{
- Error(ERR_WARN, "LoadImage('%s') failed: %s", basename, GetError());
+ Warn("LoadImage('%s') failed", basename);
+
return;
}
if (bitmap->width != new_bitmap->width ||
bitmap->height != new_bitmap->height)
{
- Error(ERR_WARN, "ReloadCustomImage: new image '%s' has wrong dimensions",
+ Warn("ReloadCustomImage: new image '%s' has wrong dimensions",
filename);
+
FreeBitmap(new_bitmap);
+
return;
}
free(new_bitmap);
}
-static Bitmap *ZoomBitmap(Bitmap *src_bitmap, int zoom_width, int zoom_height)
+Bitmap *ZoomBitmap(Bitmap *src_bitmap, int zoom_width, int zoom_height)
{
return SDLZoomBitmap(src_bitmap, zoom_width, zoom_height);
}
{
if (bitmaps[IMG_BITMAP_CUSTOM])
{
- FreeBitmap(bitmaps[IMG_BITMAP_CUSTOM]);
+ // check if original sized bitmap points to custom sized bitmap
+ if (bitmaps[IMG_BITMAP_PTR_ORIGINAL] == bitmaps[IMG_BITMAP_CUSTOM])
+ {
+ SDLFreeBitmapTextures(bitmaps[IMG_BITMAP_PTR_ORIGINAL]);
+
+ // keep pointer of previous custom size bitmap
+ bitmaps[IMG_BITMAP_OTHER] = bitmaps[IMG_BITMAP_CUSTOM];
+
+ // set original bitmap pointer to scaled original bitmap of other size
+ bitmaps[IMG_BITMAP_PTR_ORIGINAL] = bitmaps[IMG_BITMAP_OTHER];
+
+ SDLCreateBitmapTextures(bitmaps[IMG_BITMAP_PTR_ORIGINAL]);
+ }
+ else
+ {
+ FreeBitmap(bitmaps[IMG_BITMAP_CUSTOM]);
+ }
bitmaps[IMG_BITMAP_CUSTOM] = NULL;
}
if (gfx.game_tile_size == gfx.standard_tile_size)
{
- bitmaps[IMG_BITMAP_GAME] = bitmaps[IMG_BITMAP_STANDARD];
+ // set game bitmap pointer to standard sized bitmap (already existing)
+ bitmaps[IMG_BITMAP_PTR_GAME] = bitmaps[IMG_BITMAP_STANDARD];
return;
}
int width = bitmap->width * gfx.game_tile_size / gfx.standard_tile_size;;
int height = bitmap->height * gfx.game_tile_size / gfx.standard_tile_size;;
- Bitmap *bitmap_new = ZoomBitmap(bitmap, width, height);
+ bitmaps[IMG_BITMAP_CUSTOM] = ZoomBitmap(bitmap, width, height);
- bitmaps[IMG_BITMAP_CUSTOM] = bitmap_new;
- bitmaps[IMG_BITMAP_GAME] = bitmap_new;
+ // set game bitmap pointer to custom sized bitmap (newly created)
+ bitmaps[IMG_BITMAP_PTR_GAME] = bitmaps[IMG_BITMAP_CUSTOM];
}
static void CreateScaledBitmaps(Bitmap **bitmaps, int zoom_factor,
old_width = old_bitmap->width;
old_height = old_bitmap->height;
- /* calculate new image dimensions for final image size */
+ // calculate new image dimensions for final image size
width_final = old_width * zoom_factor;
height_final = old_height * zoom_factor;
- /* get image with final size (this might require scaling up) */
- /* ("final" size may result in non-standard tile size image) */
+ // get image with final size (this might require scaling up)
+ // ("final" size may result in non-standard tile size image)
if (zoom_factor != 1)
tmp_bitmap_final = ZoomBitmap(old_bitmap, width_final, height_final);
else
if (create_small_bitmaps)
{
- /* check if we have a non-gameplay tile size image */
+ // check if we have a non-gameplay tile size image
if (tile_size != gfx.game_tile_size)
{
- /* get image with gameplay tile size */
+ // get image with gameplay tile size
width_0 = width_final * gfx.game_tile_size / tile_size;
height_0 = height_final * gfx.game_tile_size / tile_size;
UPDATE_BUSY_STATE();
}
- /* check if we have a non-standard tile size image */
+ // check if we have a non-standard tile size image
if (tile_size != gfx.standard_tile_size)
{
- /* get image with standard tile size */
+ // get image with standard tile size
width_1 = width_final * gfx.standard_tile_size / tile_size;
height_1 = height_final * gfx.standard_tile_size / tile_size;
UPDATE_BUSY_STATE();
}
- /* calculate new image dimensions for small images */
+ // calculate new image dimensions for small images
width_2 = width_1 / 2;
height_2 = height_1 / 2;
width_4 = width_1 / 4;
width_32 = width_1 / 32;
height_32 = height_1 / 32;
- /* get image with 1/2 of normal size (for use in the level editor) */
+ // get image with 1/2 of normal size (for use in the level editor)
if (width_2 == old_width)
tmp_bitmap_2 = old_bitmap;
else
UPDATE_BUSY_STATE();
- /* get image with 1/4 of normal size (for use in the level editor) */
+ // get image with 1/4 of normal size (for use in the level editor)
if (width_4 == old_width)
tmp_bitmap_4 = old_bitmap;
else
UPDATE_BUSY_STATE();
- /* get image with 1/8 of normal size (for use on the preview screen) */
+ // get image with 1/8 of normal size (for use on the preview screen)
if (width_8 == old_width)
tmp_bitmap_8 = old_bitmap;
else
UPDATE_BUSY_STATE();
- /* get image with 1/16 of normal size (for use on the preview screen) */
+ // get image with 1/16 of normal size (for use on the preview screen)
if (width_16 == old_width)
tmp_bitmap_16 = old_bitmap;
else
UPDATE_BUSY_STATE();
- /* get image with 1/32 of normal size (for use on the preview screen) */
+ // get image with 1/32 of normal size (for use on the preview screen)
if (width_32 == old_width)
tmp_bitmap_32 = old_bitmap;
else
bitmaps[IMG_BITMAP_CUSTOM] = tmp_bitmap_0;
if (bitmaps[IMG_BITMAP_CUSTOM])
- bitmaps[IMG_BITMAP_GAME] = bitmaps[IMG_BITMAP_CUSTOM];
+ bitmaps[IMG_BITMAP_PTR_GAME] = bitmaps[IMG_BITMAP_CUSTOM];
+ else
+ bitmaps[IMG_BITMAP_PTR_GAME] = bitmaps[IMG_BITMAP_STANDARD];
+
+ // store the "final" (up-scaled) original bitmap, if not already stored
+
+ int tmp_bitmap_final_nr = -1;
+
+ for (i = 0; i < NUM_IMG_BITMAPS; i++)
+ if (bitmaps[i] == tmp_bitmap_final)
+ tmp_bitmap_final_nr = i;
+
+ if (tmp_bitmap_final_nr == -1) // scaled original bitmap not stored
+ {
+ // store pointer of scaled original bitmap (not used for any other size)
+ bitmaps[IMG_BITMAP_OTHER] = tmp_bitmap_final;
+
+ // set original bitmap pointer to scaled original bitmap of other size
+ bitmaps[IMG_BITMAP_PTR_ORIGINAL] = bitmaps[IMG_BITMAP_OTHER];
+ }
else
- bitmaps[IMG_BITMAP_GAME] = bitmaps[IMG_BITMAP_STANDARD];
+ {
+ // set original bitmap pointer to corresponding sized bitmap
+ bitmaps[IMG_BITMAP_PTR_ORIGINAL] = bitmaps[tmp_bitmap_final_nr];
+ }
+
+ // free the "old" (unscaled) original bitmap, if not already stored
boolean free_old_bitmap = TRUE;
free_old_bitmap = FALSE;
if (free_old_bitmap)
+ {
+ // copy image filename from old to new standard sized bitmap
+ bitmaps[IMG_BITMAP_STANDARD]->source_filename =
+ getStringCopy(old_bitmap->source_filename);
+
FreeBitmap(old_bitmap);
+ }
}
else
{
bitmaps[IMG_BITMAP_32x32] = tmp_bitmap_1;
+
+ // set original bitmap pointer to corresponding sized bitmap
+ bitmaps[IMG_BITMAP_PTR_ORIGINAL] = bitmaps[IMG_BITMAP_32x32];
+
+ if (old_bitmap != tmp_bitmap_1)
+ FreeBitmap(old_bitmap);
}
UPDATE_BUSY_STATE();
void CreateBitmapTextures(Bitmap **bitmaps)
{
- SDLCreateBitmapTextures(bitmaps[IMG_BITMAP_STANDARD]);
+ if (bitmaps[IMG_BITMAP_PTR_ORIGINAL] != NULL)
+ SDLCreateBitmapTextures(bitmaps[IMG_BITMAP_PTR_ORIGINAL]);
+ else
+ SDLCreateBitmapTextures(bitmaps[IMG_BITMAP_STANDARD]);
}
void FreeBitmapTextures(Bitmap **bitmaps)
{
- SDLFreeBitmapTextures(bitmaps[IMG_BITMAP_STANDARD]);
+ if (bitmaps[IMG_BITMAP_PTR_ORIGINAL] != NULL)
+ SDLFreeBitmapTextures(bitmaps[IMG_BITMAP_PTR_ORIGINAL]);
+ else
+ SDLFreeBitmapTextures(bitmaps[IMG_BITMAP_STANDARD]);
}
void ScaleBitmap(Bitmap **bitmaps, int zoom_factor)
}
-/* ------------------------------------------------------------------------- */
-/* mouse pointer functions */
-/* ------------------------------------------------------------------------- */
+// ----------------------------------------------------------------------------
+// mouse pointer functions
+// ----------------------------------------------------------------------------
#define USE_ONE_PIXEL_PLAYFIELD_MOUSEPOINTER 0
-/* XPM image definitions */
+// XPM image definitions
static const char *cursor_image_none[] =
{
- /* width height num_colors chars_per_pixel */
+ // width height num_colors chars_per_pixel
" 16 16 3 1",
- /* colors */
+ // colors
"X c #000000",
". c #ffffff",
" c None",
- /* pixels */
+ // pixels
" ",
" ",
" ",
" ",
" ",
- /* hot spot */
+ // hot spot
"0,0"
};
#if USE_ONE_PIXEL_PLAYFIELD_MOUSEPOINTER
static const char *cursor_image_dot[] =
{
- /* width height num_colors chars_per_pixel */
+ // width height num_colors chars_per_pixel
" 16 16 3 1",
- /* colors */
+ // colors
"X c #000000",
". c #ffffff",
" c None",
- /* pixels */
+ // pixels
" X ",
"X.X ",
" X ",
" ",
" ",
- /* hot spot */
+ // hot spot
"1,1"
};
static const char **cursor_image_playfield = cursor_image_dot;
#else
-/* some people complained about a "white dot" on the screen and thought it
- was a graphical error... OK, let's just remove the whole pointer :-) */
+// some people complained about a "white dot" on the screen and thought it
+// was a graphical error... OK, let's just remove the whole pointer :-)
static const char **cursor_image_playfield = cursor_image_none;
#endif
static struct MouseCursorInfo *cursor_none = NULL;
static struct MouseCursorInfo *cursor_playfield = NULL;
struct MouseCursorInfo *cursor_new;
+ int mode_final = mode;
if (cursor_none == NULL)
cursor_none = get_cursor_from_image(cursor_image_none);
if (cursor_playfield == NULL)
cursor_playfield = get_cursor_from_image(cursor_image_playfield);
- cursor_new = (mode == CURSOR_DEFAULT ? NULL :
- mode == CURSOR_NONE ? cursor_none :
- mode == CURSOR_PLAYFIELD ? cursor_playfield : NULL);
+ if (gfx.cursor_mode_override != CURSOR_UNDEFINED)
+ mode_final = gfx.cursor_mode_override;
+
+ cursor_new = (mode_final == CURSOR_DEFAULT ? NULL :
+ mode_final == CURSOR_NONE ? cursor_none :
+ mode_final == CURSOR_PLAYFIELD ? cursor_playfield : NULL);
SDLSetMouseCursor(cursor_new);
gfx.cursor_mode = mode;
+ gfx.cursor_mode_final = mode_final;
+}
+
+void UpdateRawMousePosition(int mouse_x, int mouse_y)
+{
+ // mouse events do not contain logical screen size corrections yet
+ SDLCorrectRawMousePosition(&mouse_x, &mouse_y);
+
+ mouse_x -= video.screen_xoffset;
+ mouse_y -= video.screen_yoffset;
+
+ gfx.mouse_x = mouse_x;
+ gfx.mouse_y = mouse_y;
+}
+
+void UpdateMousePosition(void)
+{
+ int mouse_x, mouse_y;
+
+ SDL_PumpEvents();
+ SDL_GetMouseState(&mouse_x, &mouse_y);
+
+ UpdateRawMousePosition(mouse_x, mouse_y);
}
-/* ========================================================================= */
-/* audio functions */
-/* ========================================================================= */
+// ============================================================================
+// audio functions
+// ============================================================================
void OpenAudio(void)
{
- /* always start with reliable default values */
+ // always start with reliable default values
audio.sound_available = FALSE;
audio.music_available = FALSE;
audio.loops_available = FALSE;
}
-/* ========================================================================= */
-/* event functions */
-/* ========================================================================= */
+// ============================================================================
+// event functions
+// ============================================================================
+
+void InitEventFilter(EventFilter filter_function)
+{
+ SDL_SetEventFilter(filter_function, NULL);
+}
boolean PendingEvent(void)
{
void PeekEvent(Event *event)
{
-#if defined(TARGET_SDL2)
SDL_PeepEvents(event, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
-#else
- SDL_PeepEvents(event, 1, SDL_PEEKEVENT, SDL_ALLEVENTS);
-#endif
+}
+
+void PumpEvents(void)
+{
+ SDL_PumpEvents();
}
void CheckQuitEvent(void)
Key GetEventKey(KeyEvent *event, boolean with_modifiers)
{
-#if defined(TARGET_SDL2)
- /* key up/down events in SDL2 do not return text characters anymore */
+ // key up/down events in SDL2 do not return text characters anymore
return event->keysym.sym;
-#else
-
-#if ENABLE_UNUSED_CODE
- printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
- (int)event->keysym.unicode,
- (int)event->keysym.sym,
- (int)SDL_GetModState());
-#endif
-
- if (with_modifiers &&
- event->keysym.unicode > 0x0000 &&
- event->keysym.unicode < 0x2000)
- return event->keysym.unicode;
- else
- return event->keysym.sym;
-
-#endif
}
KeyMod HandleKeyModState(Key key, int key_status)
{
static KeyMod current_modifiers = KMOD_None;
- if (key != KSYM_UNDEFINED) /* new key => check for modifier key change */
+ if (key != KSYM_UNDEFINED) // new key => check for modifier key change
{
KeyMod new_modifier = KMOD_None;
- switch(key)
+ switch (key)
{
case KSYM_Shift_L:
new_modifier = KMOD_Shift_L;
return current_modifiers;
}
-KeyMod GetKeyModState()
+KeyMod GetKeyModState(void)
{
return (KeyMod)SDL_GetModState();
}
-KeyMod GetKeyModStateFromEvents()
+KeyMod GetKeyModStateFromEvents(void)
{
/* always use key modifier state as tracked from key events (this is needed
if the modifier key event was injected into the event queue, but the key
void StartTextInput(int x, int y, int width, int height)
{
-#if defined(TARGET_SDL2)
+ textinput_status = TRUE;
+
#if defined(HAS_SCREEN_KEYBOARD)
SDL_StartTextInput();
video.shifted_up = TRUE;
}
#endif
-#endif
}
-void StopTextInput()
+void StopTextInput(void)
{
-#if defined(TARGET_SDL2)
+ textinput_status = FALSE;
+
#if defined(HAS_SCREEN_KEYBOARD)
SDL_StopTextInput();
video.shifted_up = FALSE;
}
#endif
-#endif
}
-boolean CheckCloseWindowEvent(ClientMessageEvent *event)
+void PushUserEvent(int code, int value1, int value2)
{
- if (event->type != EVENT_CLIENTMESSAGE)
- return FALSE;
+ UserEvent event;
+
+ SDL_memset(&event, 0, sizeof(event));
- return TRUE; /* the only possible message here is SDL_QUIT */
+ event.type = EVENT_USER;
+ event.code = code;
+ event.value1 = value1;
+ event.value2 = value2;
+
+ SDL_PushEvent((SDL_Event *)&event);
}
-/* ========================================================================= */
-/* joystick functions */
-/* ========================================================================= */
+// ============================================================================
+// joystick functions
+// ============================================================================
-void InitJoysticks()
+void InitJoysticks(void)
{
int i;
#if defined(NO_JOYSTICK)
- return; /* joysticks generally deactivated by compile-time directive */
+ return; // joysticks generally deactivated by compile-time directive
#endif
- /* always start with reliable default values */
+ // always start with reliable default values
joystick.status = JOYSTICK_NOT_AVAILABLE;
for (i = 0; i < MAX_PLAYERS; i++)
- joystick.nr[i] = -1; /* no joystick configured */
+ joystick.nr[i] = -1; // no joystick configured
SDLInitJoysticks();
}
return SDLCheckJoystickOpened(nr);
}
-void ClearJoystickState()
+void ClearJoystickState(void)
{
SDLClearJoystickState();
}
+
+
+// ============================================================================
+// Emscripten functions
+// ============================================================================
+
+void InitEmscriptenFilesystem(void)
+{
+#if defined(PLATFORM_EMSCRIPTEN)
+ EM_ASM
+ (
+ Module.sync_done = 0;
+
+ FS.mkdir('/persistent'); // create persistent data directory
+ FS.mount(IDBFS, {}, '/persistent'); // mount with IDBFS filesystem type
+ FS.syncfs(true, function(err) // sync persistent data into memory
+ {
+ assert(!err);
+ Module.sync_done = 1;
+ });
+ );
+
+ // wait for persistent data to be synchronized to memory
+ while (emscripten_run_script_int("Module.sync_done") == 0)
+ Delay(20);
+#endif
+}
+
+void SyncEmscriptenFilesystem(void)
+{
+#if defined(PLATFORM_EMSCRIPTEN)
+ EM_ASM
+ (
+ FS.syncfs(function(err)
+ {
+ assert(!err);
+ });
+ );
+#endif
+}