fixed using delay counter for Android
[rocksndiamonds.git] / src / libgame / system.c
index a2f7ebeccd7d199716400db3fbeb14363f8fdbb4..5916fdcc63176373ffb2809e43cdb216d8853311 100644 (file)
@@ -103,26 +103,9 @@ void InitProgramInfo(char *argv0, char *config_filename, char *userdata_subdir,
   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.headless = FALSE;
-
-#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;
-    });
-  );
+  program.api_thread_count = 0;
 
-  // wait for persistent data to be synchronized to memory
-  while (emscripten_run_script_int("Module.sync_done") == 0)
-    Delay(20);
-#endif
+  program.headless = FALSE;
 }
 
 void InitNetworkInfo(boolean enabled, boolean connected, boolean serveronly,
@@ -146,33 +129,8 @@ void InitRuntimeInfo()
 #else
   runtime.uses_touch_device = FALSE;
 #endif
-}
-
-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)
-    {
-      Debug("internal:path", "Using global, multi-user scores directory '%s'.",
-           global_scores_dir);
-      Debug("internal:path", "Remove to enable single-user scores directory.");
-      Debug("internal:path", "(This enables multipe score entries per user.)");
-    }
-    else
-    {
-      Debug("internal:path", "Using private, single-user scores directory.");
-    }
-  }
-#endif
 
-  free(global_scores_dir);
+  runtime.use_api_server = setup.use_api_server;
 }
 
 void SetWindowTitle(void)
@@ -206,6 +164,8 @@ void InitExitFunction(void (*exit_function)(int))
 
 void InitPlatformDependentStuff(void)
 {
+  InitEmscriptenFilesystem();
+
   // this is initialized in GetOptions(), but may already be used before
   options.verbose = TRUE;
 
@@ -313,7 +273,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;
 }
@@ -607,14 +567,14 @@ void InitVideoBuffer(int width, int height, int depth, boolean fullscreen)
   video.window_scaling_available = WINDOW_SCALING_STATUS;
 
   video.frame_counter = 0;
-  video.frame_delay = 0;
-  video.frame_delay_value = GAME_FRAME_DELAY;
+  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);
 
@@ -946,6 +906,9 @@ 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 (program.headless)
+    return;
+
   if (DrawingDeactivated(x, y, width, height))
     return;
 
@@ -1149,12 +1112,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)
@@ -1235,7 +1198,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);
 }
@@ -1244,14 +1207,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;
   }
@@ -1260,10 +1240,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,
@@ -1413,9 +1393,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;
 
@@ -1435,6 +1439,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();
@@ -1450,12 +1460,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)
@@ -1796,7 +1812,7 @@ void StartTextInput(int x, int y, int width, int height)
   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
@@ -1812,7 +1828,7 @@ void StopTextInput(void)
   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
@@ -1832,6 +1848,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
@@ -1867,3 +1901,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
+}