fixed button to play tape on score info page (not used yet)
[rocksndiamonds.git] / src / screens.c
index ae7b24b95238177bf74727d845a75c9dda1cfe7f..92a9466ca0053ae1eb96454d031ec07cabb9510c 100644 (file)
@@ -22,6 +22,7 @@
 #include "network.h"
 #include "init.h"
 #include "config.h"
+#include "api.h"
 
 
 #define DEBUG_JOYSTICKS                0
 #define SCREEN_CTRL_ID_NEXT_LEVEL2     3
 #define SCREEN_CTRL_ID_PREV_SCORE      4
 #define SCREEN_CTRL_ID_NEXT_SCORE      5
-#define SCREEN_CTRL_ID_FIRST_LEVEL     6
-#define SCREEN_CTRL_ID_LAST_LEVEL      7
-#define SCREEN_CTRL_ID_LEVEL_NUMBER    8
-#define SCREEN_CTRL_ID_PREV_PLAYER     9
-#define SCREEN_CTRL_ID_NEXT_PLAYER     10
-#define SCREEN_CTRL_ID_INSERT_SOLUTION 11
-#define SCREEN_CTRL_ID_PLAY_SOLUTION   12
-#define SCREEN_CTRL_ID_SWITCH_ECS_AGA  13
-#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE 14
-#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE 15
-#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE2        16
-#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2        17
-
-#define NUM_SCREEN_MENUBUTTONS         18
-
-#define SCREEN_CTRL_ID_SCROLL_UP       18
-#define SCREEN_CTRL_ID_SCROLL_DOWN     19
-#define SCREEN_CTRL_ID_SCROLL_VERTICAL 20
-#define SCREEN_CTRL_ID_NETWORK_SERVER  21
-
-#define NUM_SCREEN_GADGETS             22
+#define SCREEN_CTRL_ID_PLAY_TAPE       6
+#define SCREEN_CTRL_ID_FIRST_LEVEL     7
+#define SCREEN_CTRL_ID_LAST_LEVEL      8
+#define SCREEN_CTRL_ID_LEVEL_NUMBER    9
+#define SCREEN_CTRL_ID_PREV_PLAYER     10
+#define SCREEN_CTRL_ID_NEXT_PLAYER     11
+#define SCREEN_CTRL_ID_INSERT_SOLUTION 12
+#define SCREEN_CTRL_ID_PLAY_SOLUTION   13
+#define SCREEN_CTRL_ID_SWITCH_ECS_AGA  14
+#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE 15
+#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE 16
+#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE2        17
+#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2        18
+
+#define NUM_SCREEN_MENUBUTTONS         19
+
+#define SCREEN_CTRL_ID_SCROLL_UP       19
+#define SCREEN_CTRL_ID_SCROLL_DOWN     20
+#define SCREEN_CTRL_ID_SCROLL_VERTICAL 21
+#define SCREEN_CTRL_ID_NETWORK_SERVER  22
+
+#define NUM_SCREEN_GADGETS             23
 
 #define NUM_SCREEN_SCROLLBUTTONS       2
 #define NUM_SCREEN_SCROLLBARS          1
@@ -300,6 +302,7 @@ static void UnmapScreenTreeGadgets(void);
 
 static void UpdateScreenMenuGadgets(int, boolean);
 static void AdjustScoreInfoButtons_SelectScore(int, int, int);
+static void AdjustScoreInfoButtons_PlayTape(int, int, boolean);
 
 static boolean OfferUploadTapes(void);
 static void execOfferUploadTapes(void);
@@ -3959,412 +3962,6 @@ void HandleInfoScreen(int mx, int my, int dx, int dy, int button)
 }
 
 
-// ============================================================================
-// rename player API functions
-// ============================================================================
-
-struct ApiRenamePlayerThreadData
-{
-  char *player_name;
-  char *player_uuid;
-};
-
-static void *CreateThreadData_ApiRenamePlayer(void)
-{
-  struct ApiRenamePlayerThreadData *data =
-    checked_malloc(sizeof(struct ApiRenamePlayerThreadData));
-
-  data->player_name = getStringCopy(setup.player_name);
-  data->player_uuid = getStringCopy(setup.player_uuid);
-
-  return data;
-}
-
-static void FreeThreadData_ApiRenamePlayer(void *data_raw)
-{
-  struct ApiRenamePlayerThreadData *data = data_raw;
-
-  checked_free(data->player_name);
-  checked_free(data->player_uuid);
-  checked_free(data);
-}
-
-static boolean SetRequest_ApiRenamePlayer(struct HttpRequest *request,
-                                         void *data_raw)
-{
-  struct ApiRenamePlayerThreadData *data = data_raw;
-  char *player_name_raw = data->player_name;
-  char *player_uuid_raw = data->player_uuid;
-
-  request->hostname = setup.api_server_hostname;
-  request->port     = API_SERVER_PORT;
-  request->method   = API_SERVER_METHOD;
-  request->uri      = API_SERVER_URI_RENAME;
-
-  char *player_name = getEscapedJSON(player_name_raw);
-  char *player_uuid = getEscapedJSON(player_uuid_raw);
-
-  snprintf(request->body, MAX_HTTP_BODY_SIZE,
-          "{\n"
-          "%s"
-          "  \"game_version\":         \"%s\",\n"
-          "  \"game_platform\":        \"%s\",\n"
-          "  \"name\":                 \"%s\",\n"
-          "  \"uuid\":                 \"%s\"\n"
-          "}\n",
-          getPasswordJSON(setup.api_server_password),
-          getProgramRealVersionString(),
-          getProgramPlatformString(),
-          player_name,
-          player_uuid);
-
-  checked_free(player_name);
-  checked_free(player_uuid);
-
-  ConvertHttpRequestBodyToServerEncoding(request);
-
-  return TRUE;
-}
-
-static void HandleResponse_ApiRenamePlayer(struct HttpResponse *response,
-                                          void *data_raw)
-{
-  // nothing to do here
-}
-
-#if defined(PLATFORM_EMSCRIPTEN)
-static void Emscripten_ApiRenamePlayer_Loaded(unsigned handle, void *data_raw,
-                                             void *buffer, unsigned int size)
-{
-  struct HttpResponse *response = GetHttpResponseFromBuffer(buffer, size);
-
-  if (response != NULL)
-  {
-    HandleResponse_ApiRenamePlayer(response, data_raw);
-
-    checked_free(response);
-  }
-  else
-  {
-    Error("server response too large to handle (%d bytes)", size);
-  }
-
-  FreeThreadData_ApiRenamePlayer(data_raw);
-}
-
-static void Emscripten_ApiRenamePlayer_Failed(unsigned handle, void *data_raw,
-                                             int code, const char *status)
-{
-  Error("server failed to handle request: %d %s", code, status);
-
-  FreeThreadData_ApiRenamePlayer(data_raw);
-}
-
-static void Emscripten_ApiRenamePlayer_Progress(unsigned handle, void *data_raw,
-                                               int bytes, int size)
-{
-  // nothing to do here
-}
-
-static void Emscripten_ApiRenamePlayer_HttpRequest(struct HttpRequest *request,
-                                                  void *data_raw)
-{
-  if (!SetRequest_ApiRenamePlayer(request, data_raw))
-  {
-    FreeThreadData_ApiRenamePlayer(data_raw);
-
-    return;
-  }
-
-  emscripten_async_wget2_data(request->uri,
-                             request->method,
-                             request->body,
-                             data_raw,
-                             TRUE,
-                             Emscripten_ApiRenamePlayer_Loaded,
-                             Emscripten_ApiRenamePlayer_Failed,
-                             Emscripten_ApiRenamePlayer_Progress);
-}
-
-#else
-
-static void ApiRenamePlayer_HttpRequestExt(struct HttpRequest *request,
-                                          struct HttpResponse *response,
-                                          void *data_raw)
-{
-  if (!SetRequest_ApiRenamePlayer(request, data_raw))
-    return;
-
-  if (!DoHttpRequest(request, response))
-  {
-    Error("HTTP request failed: %s", GetHttpError());
-
-    return;
-  }
-
-  if (!HTTP_SUCCESS(response->status_code))
-  {
-    Error("server failed to handle request: %d %s",
-         response->status_code,
-         response->status_text);
-
-    return;
-  }
-
-  HandleResponse_ApiRenamePlayer(response, data_raw);
-}
-
-static void ApiRenamePlayer_HttpRequest(struct HttpRequest *request,
-                                   struct HttpResponse *response,
-                                   void *data_raw)
-{
-  ApiRenamePlayer_HttpRequestExt(request, response, data_raw);
-
-  FreeThreadData_ApiRenamePlayer(data_raw);
-}
-#endif
-
-static int ApiRenamePlayerThread(void *data_raw)
-{
-  struct HttpRequest *request = checked_calloc(sizeof(struct HttpRequest));
-  struct HttpResponse *response = checked_calloc(sizeof(struct HttpResponse));
-
-  program.api_thread_count++;
-
-#if defined(PLATFORM_EMSCRIPTEN)
-  Emscripten_ApiRenamePlayer_HttpRequest(request, data_raw);
-#else
-  ApiRenamePlayer_HttpRequest(request, response, data_raw);
-#endif
-
-  program.api_thread_count--;
-
-  checked_free(request);
-  checked_free(response);
-
-  return 0;
-}
-
-static void ApiRenamePlayerAsThread(void)
-{
-  struct ApiRenamePlayerThreadData *data = CreateThreadData_ApiRenamePlayer();
-
-  ExecuteAsThread(ApiRenamePlayerThread,
-                 "ApiRenamePlayer", data,
-                 "rename player on server");
-}
-
-
-// ============================================================================
-// reset player UUID API functions
-// ============================================================================
-
-struct ApiResetUUIDThreadData
-{
-  char *player_name;
-  char *player_uuid_old;
-  char *player_uuid_new;
-};
-
-static void *CreateThreadData_ApiResetUUID(char *uuid_new)
-{
-  struct ApiResetUUIDThreadData *data =
-    checked_malloc(sizeof(struct ApiResetUUIDThreadData));
-
-  data->player_name     = getStringCopy(setup.player_name);
-  data->player_uuid_old = getStringCopy(setup.player_uuid);
-  data->player_uuid_new = getStringCopy(uuid_new);
-
-  return data;
-}
-
-static void FreeThreadData_ApiResetUUID(void *data_raw)
-{
-  struct ApiResetUUIDThreadData *data = data_raw;
-
-  checked_free(data->player_name);
-  checked_free(data->player_uuid_old);
-  checked_free(data->player_uuid_new);
-  checked_free(data);
-}
-
-static boolean SetRequest_ApiResetUUID(struct HttpRequest *request,
-                                      void *data_raw)
-{
-  struct ApiResetUUIDThreadData *data = data_raw;
-  char *player_name_raw = data->player_name;
-  char *player_uuid_old_raw = data->player_uuid_old;
-  char *player_uuid_new_raw = data->player_uuid_new;
-
-  request->hostname = setup.api_server_hostname;
-  request->port     = API_SERVER_PORT;
-  request->method   = API_SERVER_METHOD;
-  request->uri      = API_SERVER_URI_RESETUUID;
-
-  char *player_name = getEscapedJSON(player_name_raw);
-  char *player_uuid_old = getEscapedJSON(player_uuid_old_raw);
-  char *player_uuid_new = getEscapedJSON(player_uuid_new_raw);
-
-  snprintf(request->body, MAX_HTTP_BODY_SIZE,
-          "{\n"
-          "%s"
-          "  \"game_version\":         \"%s\",\n"
-          "  \"game_platform\":        \"%s\",\n"
-          "  \"name\":                 \"%s\",\n"
-          "  \"uuid_old\":             \"%s\",\n"
-          "  \"uuid_new\":             \"%s\"\n"
-          "}\n",
-          getPasswordJSON(setup.api_server_password),
-          getProgramRealVersionString(),
-          getProgramPlatformString(),
-          player_name,
-          player_uuid_old,
-          player_uuid_new);
-
-  checked_free(player_name);
-  checked_free(player_uuid_old);
-  checked_free(player_uuid_new);
-
-  ConvertHttpRequestBodyToServerEncoding(request);
-
-  return TRUE;
-}
-
-static void HandleResponse_ApiResetUUID(struct HttpResponse *response,
-                                       void *data_raw)
-{
-  struct ApiResetUUIDThreadData *data = data_raw;
-
-  // upgrade player UUID in server setup file
-  setup.player_uuid = getStringCopy(data->player_uuid_new);
-  setup.player_version = 2;
-
-  SaveSetup_ServerSetup();
-}
-
-#if defined(PLATFORM_EMSCRIPTEN)
-static void Emscripten_ApiResetUUID_Loaded(unsigned handle, void *data_raw,
-                                          void *buffer, unsigned int size)
-{
-  struct HttpResponse *response = GetHttpResponseFromBuffer(buffer, size);
-
-  if (response != NULL)
-  {
-    HandleResponse_ApiResetUUID(response, data_raw);
-
-    checked_free(response);
-  }
-  else
-  {
-    Error("server response too large to handle (%d bytes)", size);
-  }
-
-  FreeThreadData_ApiResetUUID(data_raw);
-}
-
-static void Emscripten_ApiResetUUID_Failed(unsigned handle, void *data_raw,
-                                          int code, const char *status)
-{
-  Error("server failed to handle request: %d %s", code, status);
-
-  FreeThreadData_ApiResetUUID(data_raw);
-}
-
-static void Emscripten_ApiResetUUID_Progress(unsigned handle, void *data_raw,
-                                            int bytes, int size)
-{
-  // nothing to do here
-}
-
-static void Emscripten_ApiResetUUID_HttpRequest(struct HttpRequest *request,
-                                               void *data_raw)
-{
-  if (!SetRequest_ApiResetUUID(request, data_raw))
-  {
-    FreeThreadData_ApiResetUUID(data_raw);
-
-    return;
-  }
-
-  emscripten_async_wget2_data(request->uri,
-                             request->method,
-                             request->body,
-                             data_raw,
-                             TRUE,
-                             Emscripten_ApiResetUUID_Loaded,
-                             Emscripten_ApiResetUUID_Failed,
-                             Emscripten_ApiResetUUID_Progress);
-}
-
-#else
-
-static void ApiResetUUID_HttpRequestExt(struct HttpRequest *request,
-                                       struct HttpResponse *response,
-                                       void *data_raw)
-{
-  if (!SetRequest_ApiResetUUID(request, data_raw))
-    return;
-
-  if (!DoHttpRequest(request, response))
-  {
-    Error("HTTP request failed: %s", GetHttpError());
-
-    return;
-  }
-
-  if (!HTTP_SUCCESS(response->status_code))
-  {
-    Error("server failed to handle request: %d %s",
-         response->status_code,
-         response->status_text);
-
-    return;
-  }
-
-  HandleResponse_ApiResetUUID(response, data_raw);
-}
-
-static void ApiResetUUID_HttpRequest(struct HttpRequest *request,
-                                    struct HttpResponse *response,
-                                    void *data_raw)
-{
-  ApiResetUUID_HttpRequestExt(request, response, data_raw);
-
-  FreeThreadData_ApiResetUUID(data_raw);
-}
-#endif
-
-static int ApiResetUUIDThread(void *data_raw)
-{
-  struct HttpRequest *request = checked_calloc(sizeof(struct HttpRequest));
-  struct HttpResponse *response = checked_calloc(sizeof(struct HttpResponse));
-
-  program.api_thread_count++;
-
-#if defined(PLATFORM_EMSCRIPTEN)
-  Emscripten_ApiResetUUID_HttpRequest(request, data_raw);
-#else
-  ApiResetUUID_HttpRequest(request, response, data_raw);
-#endif
-
-  program.api_thread_count--;
-
-  checked_free(request);
-  checked_free(response);
-
-  return 0;
-}
-
-static void ApiResetUUIDAsThread(char *uuid_new)
-{
-  struct ApiResetUUIDThreadData *data = CreateThreadData_ApiResetUUID(uuid_new);
-
-  ExecuteAsThread(ApiResetUUIDThread,
-                 "ApiResetUUID", data,
-                 "reset UUID on server");
-}
-
-
 // ============================================================================
 // type name functions
 // ============================================================================
@@ -5775,8 +5372,12 @@ static void DrawScoreInfo_Content(int entry_nr)
   int xstart2 = mSX - SX + 13 * xstep;
   int select_x = SX + xstart1;
   int select_y1, select_y2;
+  int play_x, play_y;
+  int play_height = screen_gadget[SCREEN_CTRL_ID_PLAY_TAPE]->height;
+  boolean play_visible = (entry->id != -1);
   int font_width = getFontWidth(font_text);
   int font_height = getFontHeight(font_text);
+  int tape_date_width  = getTextWidth(entry->tape_date, font_text);
   int pad_left = xstart2;
   int pad_right = MENU_SCREEN_INFO_SPACE_RIGHT;
   int max_chars_per_line = (SXSIZE - pad_left - pad_right) / font_width;
@@ -5846,6 +5447,9 @@ static void DrawScoreInfo_Content(int entry_nr)
 
   ystart += ystep_line;
 
+  play_x = SX + xstart2 + tape_date_width + font_width;
+  play_y = SY + ystart + (font_height - play_height) / 2;
+
   DrawTextF(xstart1, ystart, font_head, "Tape Date");
   DrawTextF(xstart2, ystart, font_text, entry->tape_date);
   ystart += ystep_line;
@@ -5869,6 +5473,7 @@ static void DrawScoreInfo_Content(int entry_nr)
   DrawTextSCentered(ybottom, font_foot, "Press any key or button to go back");
 
   AdjustScoreInfoButtons_SelectScore(select_x, select_y1, select_y2);
+  AdjustScoreInfoButtons_PlayTape(play_x, play_y, play_visible);
 }
 
 static void DrawScoreInfo(int entry_nr)
@@ -5909,6 +5514,10 @@ static void HandleScoreInfo_SelectScore(int step, int direction)
   }
 }
 
+static void HandleScoreInfo_PlayTape(void)
+{
+}
+
 void HandleScoreInfo(int mx, int my, int dx, int dy, int button)
 {
   boolean button_action = (button == MB_MENU_LEAVE || button == MB_MENU_CHOICE);
@@ -9808,6 +9417,14 @@ static struct
     GD_EVENT_PRESSED | GD_EVENT_REPEATED,
     FALSE, "next score"
   },
+  {
+    IMG_MENU_BUTTON_PLAY_TAPE, IMG_MENU_BUTTON_PLAY_TAPE,
+    &menu.scores.button.play_tape, NULL,
+    SCREEN_CTRL_ID_PLAY_TAPE,
+    SCREEN_MASK_SCORES_INFO,
+    GD_EVENT_RELEASED,
+    FALSE, "play tape"
+  },
   {
     IMG_MENU_BUTTON_FIRST_LEVEL, IMG_MENU_BUTTON_FIRST_LEVEL_ACTIVE,
     &menu.main.button.first_level, NULL,
@@ -10381,6 +9998,19 @@ static void AdjustScoreInfoButtons_SelectScore(int x, int y1, int y2)
     ModifyGadget(gi_2, GDI_X, x, GDI_Y, y2, GDI_END);
 }
 
+static void AdjustScoreInfoButtons_PlayTape(int x, int y, boolean visible)
+{
+  struct GadgetInfo *gi = screen_gadget[SCREEN_CTRL_ID_PLAY_TAPE];
+  struct MenuPosInfo *pos = menubutton_info[SCREEN_CTRL_ID_PLAY_TAPE].pos;
+
+  // set gadget position dynamically, pre-defined or off-screen
+  int xx = (visible ? (pos->x == -1 ? x : pos->x) : POS_OFFSCREEN);
+  int yy = (visible ? (pos->y == -1 ? y : pos->y) : POS_OFFSCREEN);
+
+  ModifyGadget(gi, GDI_X, xx, GDI_Y, yy, GDI_END);
+  MapGadget(gi);       // (needed if deactivated on last score page)
+}
+
 static void HandleScreenGadgets(struct GadgetInfo *gi)
 {
   int id = gi->custom_id;
@@ -10415,6 +10045,10 @@ static void HandleScreenGadgets(struct GadgetInfo *gi)
       HandleScoreInfo_SelectScore(step, +1);
       break;
 
+    case SCREEN_CTRL_ID_PLAY_TAPE:
+      HandleScoreInfo_PlayTape();
+      break;
+
     case SCREEN_CTRL_ID_FIRST_LEVEL:
       HandleMainMenu_SelectLevel(MAX_LEVELS, -1, NO_DIRECT_LEVEL_SELECT);
       break;