#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
static void UnmapScreenTreeGadgets(void);
static void UpdateScreenMenuGadgets(int, boolean);
-static void AdjustScoreInfoButtons(int, int, int);
+static void AdjustScoreInfoButtons_SelectScore(int, int, int);
+static void AdjustScoreInfoButtons_PlayTape(int, int, boolean);
static boolean OfferUploadTapes(void);
static void execOfferUploadTapes(void);
}
-// ============================================================================
-// 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
// ============================================================================
int ybottom = mSY - SY + SYSIZE - menu.bottom_spacing[GAME_MODE_SCOREINFO];
int xstart1 = mSX - SX + 2 * xstep;
int xstart2 = mSX - SX + 13 * xstep;
- int button_x = SX + xstart1;
- int button_y1, button_y2;
+ 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;
TRUE, FALSE, FALSE);
ystart += ystep_para + (lines > 0 ? lines - 1 : 0) * font_height;
- button_y1 = SY + ystart;
+ select_y1 = SY + ystart;
ystart += graphic_info[IMG_MENU_BUTTON_PREV_SCORE].height;
DrawTextF(xstart1, ystart, font_head, "Rank");
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;
TRUE, FALSE, FALSE);
ystart += ystep_line;
- button_y2 = SY + ystart;
+ select_y2 = SY + ystart;
DrawTextSCentered(ybottom, font_foot, "Press any key or button to go back");
- AdjustScoreInfoButtons(button_x, button_y1, button_y2);
+ AdjustScoreInfoButtons_SelectScore(select_x, select_y1, select_y2);
+ AdjustScoreInfoButtons_PlayTape(play_x, play_y, play_visible);
}
static void DrawScoreInfo(int entry_nr)
}
}
+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);
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,
boolean is_touch_button = menubutton_info[i].is_touch_button;
boolean is_check_button = menubutton_info[i].check_value != NULL;
boolean is_score_button = (screen_mask & SCREEN_MASK_SCORES_INFO);
+ boolean has_gfx_pressed = (menubutton_info[i].gfx_pressed ==
+ menubutton_info[i].gfx_unpressed);
Bitmap *gd_bitmap_unpressed, *gd_bitmap_pressed;
int gfx_unpressed, gfx_pressed;
int x, y, width, height;
gd_x2a = gd_x2;
gd_y2a = gd_y2;
- if (is_touch_button)
+ if (has_gfx_pressed)
{
gd_x2 += graphic_info[gfx_pressed].pressed_xoffset;
gd_y2 += graphic_info[gfx_pressed].pressed_yoffset;
UnmapScreenGadgets();
}
-static void AdjustScoreInfoButtons(int x, int y1, int y2)
+static void AdjustScoreInfoButtons_SelectScore(int x, int y1, int y2)
{
struct GadgetInfo *gi_1 = screen_gadget[SCREEN_CTRL_ID_PREV_SCORE];
struct GadgetInfo *gi_2 = screen_gadget[SCREEN_CTRL_ID_NEXT_SCORE];
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;
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;