X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Flibgame%2Fsystem.c;h=c1abb8a41ab1d11d7d43f34f5c128dea14694e99;hp=15e86a4afbc7084012132acac0f133577914085f;hb=HEAD;hpb=c38790fcee093efb156366bb4a02dbde55085ca4 diff --git a/src/libgame/system.c b/src/libgame/system.c index 15e86a4a..c1abb8a4 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -4,7 +4,7 @@ // (c) 1995-2014 by Artsoft Entertainment // Holger Schemel // info@artsoft.org -// http://www.artsoft.org/ +// https://www.artsoft.org/ // ---------------------------------------------------------------------------- // system.c // ============================================================================ @@ -40,6 +40,7 @@ struct OverlayInfo overlay; struct ArtworkInfo artwork; struct JoystickInfo joystick; struct SetupInfo setup; +struct UserInfo user; LevelDirTree *leveldir_first_all = NULL; LevelDirTree *leveldir_first = NULL; @@ -57,6 +58,7 @@ int button_status = MB_NOT_PRESSED; boolean motion_status = FALSE; int wheel_steps = DEFAULT_WHEEL_STEPS; boolean keyrepeat_status = TRUE; +boolean textinput_status = FALSE; int redraw_mask = REDRAW_NONE; @@ -67,22 +69,23 @@ int FrameCounter = 0; // init/close functions // ============================================================================ -void InitProgramInfo(char *argv0, char *config_filename, char *userdata_subdir, - char *program_title, char *icon_title, +void InitProgramInfo(char *command_filename, + char *config_filename, char *userdata_subdir, + char *program_basename, char *program_title, char *icon_filename, char *cookie_prefix, char *program_version_string, int program_version) { - program.command_basepath = getBasePath(argv0); - program.command_basename = getBaseName(argv0); + program.command_basepath = getBasePath(command_filename); + program.command_basename = getBaseName(command_filename); program.config_filename = config_filename; program.userdata_subdir = userdata_subdir; - program.userdata_path = getUserGameDataDir(); + program.userdata_path = getMainUserGameDataDir(); + program.program_basename = program_basename; program.program_title = program_title; program.window_title = "(undefined)"; - program.icon_title = icon_title; program.icon_filename = icon_filename; @@ -96,10 +99,10 @@ void InitProgramInfo(char *argv0, char *config_filename, char *userdata_subdir, program.version_string = program_version_string; - program.log_filename[LOG_OUT_ID] = getLogFilename(LOG_OUT_BASENAME); - program.log_filename[LOG_ERR_ID] = getLogFilename(LOG_ERR_BASENAME); - program.log_file[LOG_OUT_ID] = program.log_file_default[LOG_OUT_ID] = stdout; - program.log_file[LOG_ERR_ID] = program.log_file_default[LOG_ERR_ID] = stderr; + program.log_filename = getLogFilename(getLogBasename(program_basename)); + program.log_file = program.log_file_default = stdout; + + program.api_thread_count = 0; program.headless = FALSE; } @@ -113,38 +116,20 @@ void InitNetworkInfo(boolean enabled, boolean connected, boolean serveronly, network.server_host = server_host; network.server_port = server_port; + + network.server_thread = NULL; + network.is_server_thread = FALSE; } void InitRuntimeInfo() { +#if defined(HAS_TOUCH_DEVICE) + runtime.uses_touch_device = TRUE; +#else runtime.uses_touch_device = FALSE; -} - -void InitScoresInfo(void) -{ - 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."); - } - } #endif - free(global_scores_dir); + runtime.use_api_server = setup.use_api_server; } void SetWindowTitle(void) @@ -178,22 +163,24 @@ void InitExitFunction(void (*exit_function)(int)) void InitPlatformDependentStuff(void) { + InitEmscriptenFilesystem(); + // this is initialized in GetOptions(), but may already be used before options.verbose = TRUE; - OpenLogFiles(); + OpenLogFile(); 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(); } void ClosePlatformDependentStuff(void) { - CloseLogFiles(); + CloseLogFile(); } void InitGfxFieldInfo(int sx, int sy, int sxsize, int sysize, @@ -285,7 +272,7 @@ void InitGfxClipRegion(boolean enabled, int x, int y, int width, int height) gfx.clip_height = height; } -void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(void)) +void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(boolean)) { gfx.draw_busy_anim_function = draw_busy_anim_function; } @@ -300,11 +287,16 @@ void InitGfxDrawGlobalBorderFunction(void (*draw_global_border_function)(int)) gfx.draw_global_border_function = draw_global_border_function; } -void InitGfxDrawTileCursorFunction(void (*draw_tile_cursor_function)(int)) +void InitGfxDrawTileCursorFunction(void (*draw_tile_cursor_function)(int, int)) { gfx.draw_tile_cursor_function = draw_tile_cursor_function; } +void InitGfxDrawEnvelopeRequestFunction(void (*draw_envelope_request_function)(int)) +{ + gfx.draw_envelope_request_function = draw_envelope_request_function; +} + void InitGfxCustomArtworkInfo(void) { gfx.override_level_graphics = FALSE; @@ -317,8 +309,12 @@ void InitGfxCustomArtworkInfo(void) void InitGfxOtherSettings(void) { gfx.cursor_mode = CURSOR_DEFAULT; - gfx.mouse_x = 0; - gfx.mouse_y = 0; + 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) @@ -336,34 +332,41 @@ void InitTileCursorInfo(void) tile_cursor.sx = 0; tile_cursor.sy = 0; + + tile_cursor.xsn_debug = FALSE; } 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; @@ -450,7 +453,8 @@ void SetDrawBackgroundMask(int draw_background_mask) gfx.draw_background_mask = draw_background_mask; } -static void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask) +void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask, + int x, int y, int width, int height) { if (background_bitmap_tile != NULL) gfx.background_bitmap_mask |= mask; @@ -461,40 +465,19 @@ static void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask) return; if (mask == REDRAW_ALL) - BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0, + BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, + x, y, width, height, 0, 0, video.width, video.height); else if (mask == REDRAW_FIELD) - BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0, + BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, + x, y, width, height, gfx.real_sx, gfx.real_sy, gfx.full_sxsize, gfx.full_sysize); else if (mask == REDRAW_DOOR_1) - BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0, + BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, + x, y, width, height, gfx.dx, gfx.dy, gfx.dxsize, gfx.dysize); } -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 !!! - 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 !!! - 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 !!! - SetBackgroundBitmap(background_bitmap_tile, REDRAW_DOOR_1); -} - // ============================================================================ // video functions @@ -567,14 +550,15 @@ void InitVideoBuffer(int width, int height, int depth, boolean fullscreen) video.window_scaling_available = WINDOW_SCALING_STATUS; - video.frame_delay = 0; - video.frame_delay_value = GAME_FRAME_DELAY; + video.frame_counter = 0; + video.frame_delay.count = 0; + video.frame_delay.value = GAME_FRAME_DELAY; video.shifted_up = FALSE; video.shifted_up_pos = 0; video.shifted_up_pos_last = 0; - video.shifted_up_delay = 0; - video.shifted_up_delay_value = ONE_SECOND_DELAY / 4; + video.shifted_up_delay.count = 0; + video.shifted_up_delay.value = ONE_SECOND_DELAY / 4; SDLInitVideoBuffer(fullscreen); @@ -615,9 +599,22 @@ void FreeBitmap(Bitmap *bitmap) free(bitmap); } +void ResetBitmapAlpha(Bitmap *bitmap) +{ + bitmap->alpha[0][0] = -1; + bitmap->alpha[0][1] = -1; + bitmap->alpha[1][0] = -1; + bitmap->alpha[1][1] = -1; + bitmap->alpha_next_blit = -1; +} + Bitmap *CreateBitmapStruct(void) { - return checked_calloc(sizeof(Bitmap)); + Bitmap *new_bitmap = checked_calloc(sizeof(Bitmap)); + + ResetBitmapAlpha(new_bitmap); + + return new_bitmap; } Bitmap *CreateBitmap(int width, int height, int depth) @@ -690,8 +687,7 @@ void SetRedrawMaskFromArea(int x, int y, int width, int height) redraw_mask = REDRAW_ALL; } -static boolean CheckDrawingArea(int x, int y, int width, int height, - int draw_mask) +static boolean CheckDrawingArea(int x, int y, int draw_mask) { if (draw_mask == REDRAW_NONE) return FALSE; @@ -725,15 +721,15 @@ boolean DrawingDeactivatedField(void) return FALSE; } -boolean DrawingDeactivated(int x, int y, int width, int height) +boolean DrawingDeactivated(int x, int y) { - return CheckDrawingArea(x, y, width, height, gfx.draw_deactivation_mask); + return CheckDrawingArea(x, y, gfx.draw_deactivation_mask); } boolean DrawingOnBackground(int x, int y) { - return (CheckDrawingArea(x, y, 1, 1, gfx.background_bitmap_mask) && - CheckDrawingArea(x, y, 1, 1, gfx.draw_background_mask)); + return (CheckDrawingArea(x, y, gfx.background_bitmap_mask) && + CheckDrawingArea(x, y, gfx.draw_background_mask)); } static boolean InClippedRectangle(Bitmap *bitmap, int *x, int *y, @@ -789,6 +785,12 @@ static boolean InClippedRectangle(Bitmap *bitmap, int *x, int *y, return TRUE; } +void SetBitmapAlphaNextBlit(Bitmap *bitmap, int alpha) +{ + // set alpha value for next blitting of bitmap + bitmap->alpha_next_blit = alpha; +} + void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap, int src_x, int src_y, int width, int height, int dst_x, int dst_y) @@ -802,7 +804,7 @@ void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap, if (src_bitmap == NULL || dst_bitmap == NULL) return; - if (DrawingDeactivated(dst_x, dst_y, width, height)) + if (DrawingDeactivated(dst_x, dst_y)) return; if (!InClippedRectangle(src_bitmap, &src_x, &src_y, &width, &height, FALSE) || @@ -906,7 +908,10 @@ void FadeRectangle(int x, int y, int width, int height, void FillRectangle(Bitmap *bitmap, int x, int y, int width, int height, Pixel color) { - if (DrawingDeactivated(x, y, width, height)) + if (program.headless) + return; + + if (DrawingDeactivated(x, y)) return; if (!InClippedRectangle(bitmap, &x, &y, &width, &height, TRUE)) @@ -933,7 +938,7 @@ void BlitBitmapMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap, int src_x, int src_y, int width, int height, int dst_x, int dst_y) { - if (DrawingDeactivated(dst_x, dst_y, width, height)) + if (DrawingDeactivated(dst_x, dst_y)) return; sysCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height, @@ -1009,12 +1014,6 @@ void BlitToScreenMasked(Bitmap *bitmap, BlitTextureMasked(bitmap, src_x, src_y, width, height, dst_x, dst_y); } -void DrawSimpleBlackLine(Bitmap *bitmap, int from_x, int from_y, - int to_x, int to_y) -{ - SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, BLACK_PIXEL); -} - void DrawSimpleWhiteLine(Bitmap *bitmap, int from_x, int from_y, int to_x, int to_y) { @@ -1083,15 +1082,6 @@ Pixel GetPixelFromRGB(Bitmap *bitmap, unsigned int color_r, return SDL_MapRGB(bitmap->surface->format, color_r, color_g, color_b); } -Pixel GetPixelFromRGBcompact(Bitmap *bitmap, unsigned int color) -{ - unsigned int color_r = (color >> 16) & 0xff; - unsigned int color_g = (color >> 8) & 0xff; - unsigned int color_b = (color >> 0) & 0xff; - - return GetPixelFromRGB(bitmap, color_r, color_g, color_b); -} - void KeyboardAutoRepeatOn(void) { keyrepeat_status = TRUE; @@ -1109,12 +1099,12 @@ boolean SetVideoMode(boolean fullscreen) void SetVideoFrameDelay(unsigned int frame_delay_value) { - video.frame_delay_value = frame_delay_value; + video.frame_delay.value = frame_delay_value; } unsigned int GetVideoFrameDelay(void) { - return video.frame_delay_value; + return video.frame_delay.value; } boolean ChangeVideoModeIfNeeded(boolean fullscreen) @@ -1144,10 +1134,10 @@ Bitmap *LoadCustomImage(char *basename) 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; } @@ -1159,7 +1149,8 @@ void ReloadCustomImage(Bitmap *bitmap, char *basename) if (filename == NULL) // (should never happen) { - Error(ERR_WARN, "ReloadCustomImage(): cannot find file '%s'", basename); + Warn("ReloadCustomImage(): cannot find file '%s'", basename); + return; } @@ -1174,16 +1165,19 @@ void ReloadCustomImage(Bitmap *bitmap, char *basename) 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; } @@ -1191,7 +1185,7 @@ void ReloadCustomImage(Bitmap *bitmap, char *basename) 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); } @@ -1200,14 +1194,31 @@ void ReCreateGameTileSizeBitmap(Bitmap **bitmaps) { 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; } @@ -1216,10 +1227,10 @@ void ReCreateGameTileSizeBitmap(Bitmap **bitmaps) 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, @@ -1369,9 +1380,33 @@ static void CreateScaledBitmaps(Bitmap **bitmaps, int zoom_factor, 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_GAME] = bitmaps[IMG_BITMAP_STANDARD]; + 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 + { + // 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; @@ -1391,6 +1426,12 @@ static void CreateScaledBitmaps(Bitmap **bitmaps, int zoom_factor, 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(); @@ -1406,12 +1447,18 @@ void CreateBitmapWithSmallBitmaps(Bitmap **bitmaps, int zoom_factor, 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) @@ -1552,6 +1599,7 @@ void SetMouseCursor(int mode) 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); @@ -1559,13 +1607,39 @@ void SetMouseCursor(int mode) 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); } @@ -1615,6 +1689,11 @@ void SetAudioMode(boolean enabled) // event functions // ============================================================================ +void InitEventFilter(EventFilter filter_function) +{ + SDL_SetEventFilter(filter_function, NULL); +} + boolean PendingEvent(void) { return (SDL_PollEvent(NULL) ? TRUE : FALSE); @@ -1630,13 +1709,18 @@ void PeekEvent(Event *event) SDL_PeepEvents(event, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT); } +void PumpEvents(void) +{ + SDL_PumpEvents(); +} + void CheckQuitEvent(void) { if (SDL_QuitRequested()) program.exit_function(0); } -Key GetEventKey(KeyEvent *event, boolean with_modifiers) +Key GetEventKey(KeyEvent *event) { // key up/down events in SDL2 do not return text characters anymore return event->keysym.sym; @@ -1650,7 +1734,7 @@ KeyMod HandleKeyModState(Key key, int key_status) { KeyMod new_modifier = KMOD_None; - switch(key) + switch (key) { case KSYM_Shift_L: new_modifier = KMOD_Shift_L; @@ -1707,13 +1791,15 @@ KeyMod GetKeyModStateFromEvents(void) void StartTextInput(int x, int y, int width, int height) { + textinput_status = TRUE; + #if defined(HAS_SCREEN_KEYBOARD) SDL_StartTextInput(); if (y + height > SCREEN_KEYBOARD_POS(video.height)) { video.shifted_up_pos = y + height - SCREEN_KEYBOARD_POS(video.height); - video.shifted_up_delay = SDL_GetTicks(); + video.shifted_up_delay.count = SDL_GetTicks(); video.shifted_up = TRUE; } #endif @@ -1721,13 +1807,15 @@ void StartTextInput(int x, int y, int width, int height) void StopTextInput(void) { + textinput_status = FALSE; + #if defined(HAS_SCREEN_KEYBOARD) SDL_StopTextInput(); if (video.shifted_up) { video.shifted_up_pos = 0; - video.shifted_up_delay = SDL_GetTicks(); + video.shifted_up_delay.count = SDL_GetTicks(); video.shifted_up = FALSE; } #endif @@ -1747,6 +1835,24 @@ void PushUserEvent(int code, int value1, int value2) SDL_PushEvent((SDL_Event *)&event); } +boolean PendingEscapeKeyEvent(void) +{ + if (PendingEvent()) + { + Event event; + + // check if any key press event is pending + if (SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_KEYDOWN) != 1) + return FALSE; + + // check if pressed key is "Escape" key + if (event.key.keysym.sym == KSYM_Escape) + return TRUE; + } + + return FALSE; +} + // ============================================================================ // joystick functions @@ -1782,3 +1888,45 @@ void ClearJoystickState(void) { SDLClearJoystickState(); } + + +// ============================================================================ +// Emscripten functions +// ============================================================================ + +void InitEmscriptenFilesystem(void) +{ +#if defined(PLATFORM_EMSCRIPTEN) + EM_ASM + ({ + dir = UTF8ToString($0); + + Module.sync_done = 0; + + FS.mkdir(dir); // create persistent data directory + FS.mount(IDBFS, {}, dir); // mount with IDBFS filesystem type + FS.syncfs(true, function(err) // sync persistent data into memory + { + assert(!err); + Module.sync_done = 1; + }); + }, PERSISTENT_DIRECTORY); + + // 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 +}