#include "init.h"
#include "config.h"
+
+#define DEBUG_JOYSTICKS 0
+
+
/* screens on the info screen */
#define INFO_MODE_MAIN 0
#define INFO_MODE_TITLE 1
static void HandleSetupScreen_Generic(int, int, int, int, int);
static void HandleSetupScreen_Input(int, int, int, int, int);
static void CustomizeKeyboard(int);
-static void CalibrateJoystick(int);
+static void ConfigureJoystick(int);
static void execSetupGame(void);
static void execSetupGraphics(void);
static void execSetupSound(void);
LoadLevel(level_nr);
LoadScore(level_nr);
+ SaveLevelSetup_SeriesInfo();
+
// set this after "ChangeViewportPropertiesIfNeeded()" (which may reset it)
SetDrawDeactivationMask(REDRAW_NONE);
SetDrawBackgroundMask(REDRAW_FIELD);
LoadTape(level_nr);
DrawCompleteVideoDisplay();
+ SaveLevelSetup_SeriesInfo();
+
/* needed because DrawPreviewLevelInitial() takes some time */
BackToFront();
/* SyncDisplay(); */
DrawTextF(xstart1, ystart2, font_header, "Version");
DrawTextF(xstart2, ystart2, font_text, getProgramVersionString());
+ if (!strEqual(getProgramVersionString(), getProgramRealVersionString()))
+ {
+ ystart2 += ystep;
+ DrawTextF(xstart1, ystart2, font_header, "Version (real)");
+ DrawTextF(xstart2, ystart2, font_text, getProgramRealVersionString());
+ }
+
ystart2 += ystep;
DrawTextF(xstart1, ystart2, font_header, "Platform");
DrawTextF(xstart2, ystart2, font_text, PLATFORM_STRING);
{
{ TYPE_SWITCH, NULL, "Player:" },
{ TYPE_SWITCH, NULL, "Device:" },
- { TYPE_ENTER_MENU, NULL, "" },
+ { TYPE_SWITCH, NULL, "" },
{ TYPE_EMPTY, NULL, "" },
{ TYPE_EMPTY, NULL, "" },
{ TYPE_EMPTY, NULL, "" },
{
Event event;
- NextEvent(&event);
+ WaitEvent(&event);
switch (event.type)
{
static int getSetupValueFont(int type, void *value)
{
- if (type & TYPE_KEY)
+ if (type & TYPE_GHOSTED)
+ return FONT_OPTION_OFF;
+ else if (type & TYPE_KEY)
return (type & TYPE_QUERY ? FONT_INPUT_1_ACTIVE : FONT_VALUE_1);
else if (type & TYPE_STRING)
return FONT_VALUE_2;
ToggleFullscreenOrChangeWindowScalingIfNeeded();
}
+static struct TokenInfo *getSetupInfoFinal(struct TokenInfo *setup_info_orig)
+{
+ static struct TokenInfo *setup_info_hide = NULL;
+ int list_size = 0;
+ int list_pos = 0;
+ int i;
+
+ /* determine maximum list size of target list */
+ while (setup_info_orig[list_size++].type != 0);
+
+ /* free, allocate and clear memory for target list */
+ checked_free(setup_info_hide);
+ setup_info_hide = checked_calloc(list_size * sizeof(struct TokenInfo));
+
+ /* copy setup info list without setup entries marked as hidden */
+ for (i = 0; setup_info_orig[i].type != 0; i++)
+ if (!hideSetupEntry(setup_info_orig[i].value))
+ setup_info_hide[list_pos++] = setup_info_orig[i];
+
+ return setup_info_hide;
+}
+
static void DrawSetupScreen_Generic()
{
int fade_mask = REDRAW_FIELD;
title_string = "Setup Shortcuts";
}
+ /* use modified setup info without setup entries marked as hidden */
+ setup_info = getSetupInfoFinal(setup_info);
+
DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, title_string);
// determine maximal number of setup entries that can be displayed on screen
char *text;
} custom[] =
{
- { &custom_key.left, "Joystick Left" },
- { &custom_key.right, "Joystick Right" },
- { &custom_key.up, "Joystick Up" },
- { &custom_key.down, "Joystick Down" },
- { &custom_key.snap, "Button 1" },
- { &custom_key.drop, "Button 2" }
+ { &custom_key.left, "Axis/Pad Left" },
+ { &custom_key.right, "Axis/Pad Right" },
+ { &custom_key.up, "Axis/Pad Up" },
+ { &custom_key.down, "Axis/Pad Down" },
+ { &custom_key.snap, "Button 1/A/X" },
+ { &custom_key.drop, "Button 2/B/Y" }
};
static char *joystick_name[MAX_PLAYERS] =
{
int font_nr = (joystick_active ? FONT_VALUE_1 : FONT_VALUE_OLD);
DrawText(mSX + 8 * 32, mSY + 3 * 32, text, font_nr);
- DrawText(mSX + 32, mSY + 4 * 32, "Calibrate", text_font_nr);
+ DrawText(mSX + 32, mSY + 4 * 32, "Configure", text_font_nr);
}
else
{
if (dx && choice == 0)
x = (dx < 0 ? 10 : 12);
else if ((dx && choice == 1) ||
- (dx == +1 && choice == 2) ||
(dx == -1 && choice == pos_end))
button = MB_MENU_CHOICE;
else if (dy)
else if (y == 2)
{
if (setup.input[input_player_nr].use_joystick)
- CalibrateJoystick(input_player_nr);
+ ConfigureJoystick(input_player_nr);
else
CustomizeKeyboard(input_player_nr);
}
{
Event event;
- NextEvent(&event);
+ WaitEvent(&event);
switch (event.type)
{
DrawSetupScreen_Input();
}
-static boolean CalibrateJoystickMain(int player_nr)
+/* game controller mapping generator by Gabriel Jacobo <gabomdq@gmail.com> */
+
+#define MARKER_BUTTON 1
+#define MARKER_AXIS_X 2
+#define MARKER_AXIS_Y 3
+
+static boolean ConfigureJoystickMapButtonsAndAxes(SDL_Joystick *joystick)
{
- int new_joystick_xleft = JOYSTICK_XMIDDLE;
- int new_joystick_xright = JOYSTICK_XMIDDLE;
- int new_joystick_yupper = JOYSTICK_YMIDDLE;
- int new_joystick_ylower = JOYSTICK_YMIDDLE;
- int new_joystick_xmiddle, new_joystick_ymiddle;
+#if defined(TARGET_SDL2)
+ static boolean bitmaps_initialized = FALSE;
+ boolean screen_initialized = FALSE;
+ static Bitmap *controller, *button, *axis_x, *axis_y;
+ char *name;
+ boolean success = TRUE;
+ boolean done = FALSE, next = FALSE;
+ Event event;
+ int alpha = 200, alpha_step = -1;
+ int alpha_ticks = 0;
+ char mapping[4096], temp[4096];
+ int font_name = FONT_TEXT_1;
+ int font_info = FONT_REQUEST;
+ int ystep1 = getFontHeight(font_name) + 2;
+ int ystep2 = getFontHeight(font_info) + 2;
+ int i, j;
- char *device_name = setup.input[player_nr].joy.device_name;
- int joystick_nr = getJoystickNrFromDeviceName(device_name);
- boolean joystick_active = CheckJoystickOpened(joystick_nr);
+ struct
+ {
+ int x, y;
+ int marker;
+ char *field;
+ int axis, button, hat, hat_value;
+ char mapping[4096];
+ }
+ *step, *prev_step, steps[] =
+ {
+ { 356, 155, MARKER_BUTTON, "a", },
+ { 396, 122, MARKER_BUTTON, "b", },
+ { 320, 125, MARKER_BUTTON, "x", },
+ { 358, 95, MARKER_BUTTON, "y", },
+ { 162, 125, MARKER_BUTTON, "back", },
+ { 216, 125, MARKER_BUTTON, "guide", },
+ { 271, 125, MARKER_BUTTON, "start", },
+ { 110, 200, MARKER_BUTTON, "dpleft", },
+ { 146, 228, MARKER_BUTTON, "dpdown", },
+ { 178, 200, MARKER_BUTTON, "dpright", },
+ { 146, 172, MARKER_BUTTON, "dpup", },
+ { 50, 40, MARKER_BUTTON, "leftshoulder", },
+ { 88, -10, MARKER_AXIS_Y, "lefttrigger", },
+ { 382, 40, MARKER_BUTTON, "rightshoulder", },
+ { 346, -10, MARKER_AXIS_Y, "righttrigger", },
+ { 73, 141, MARKER_BUTTON, "leftstick", },
+ { 282, 210, MARKER_BUTTON, "rightstick", },
+ { 73, 141, MARKER_AXIS_X, "leftx", },
+ { 73, 141, MARKER_AXIS_Y, "lefty", },
+ { 282, 210, MARKER_AXIS_X, "rightx", },
+ { 282, 210, MARKER_AXIS_Y, "righty", },
+ };
- int x, y, last_x, last_y, xpos = 8, ypos = 3;
- boolean check[3][3];
- int check_remaining = 3 * 3;
- int joy_x, joy_y;
- int joy_value;
- int result = -1;
+ unsigned int event_frame_delay = 0;
+ unsigned int event_frame_delay_value = GAME_FRAME_DELAY;
- if (joystick.status == JOYSTICK_NOT_AVAILABLE)
- return FALSE;
+ ResetDelayCounter(&event_frame_delay);
- if (!joystick_active || !setup.input[player_nr].use_joystick)
- return FALSE;
+ if (!bitmaps_initialized)
+ {
+ controller = LoadCustomImage("joystick/controller.png");
+ button = LoadCustomImage("joystick/button.png");
+ axis_x = LoadCustomImage("joystick/axis_x.png");
+ axis_y = LoadCustomImage("joystick/axis_y.png");
- FadeSetEnterMenu();
- FadeOut(REDRAW_FIELD);
+ bitmaps_initialized = TRUE;
+ }
- ClearField();
+ name = getFormattedJoystickName(SDL_JoystickName(joystick));
+
+#if DEBUG_JOYSTICKS
+ /* print info about the joystick we are watching */
+ Error(ERR_DEBUG, "watching joystick %d: (%s)\n",
+ SDL_JoystickInstanceID(joystick), name);
+ Error(ERR_DEBUG, "joystick has %d axes, %d hats, %d balls, and %d buttons\n",
+ SDL_JoystickNumAxes(joystick), SDL_JoystickNumHats(joystick),
+ SDL_JoystickNumBalls(joystick), SDL_JoystickNumButtons(joystick));
+#endif
+
+ /* initialize mapping with GUID and name */
+ SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), temp, sizeof(temp));
+
+ snprintf(mapping, sizeof(mapping), "%s,%s,platform:%s,",
+ temp, name, SDL_GetPlatform());
- for (y = 0; y < 3; y++)
+ /* loop through all steps (buttons and axes), getting joystick events */
+ for (i = 0; i < SDL_arraysize(steps) && !done;)
{
- for (x = 0; x < 3; x++)
+ Bitmap *marker = button; /* initialize with reliable default value */
+
+ step = &steps[i];
+ strcpy(step->mapping, mapping);
+ step->axis = -1;
+ step->button = -1;
+ step->hat = -1;
+ step->hat_value = -1;
+
+ marker = (step->marker == MARKER_BUTTON ? button :
+ step->marker == MARKER_AXIS_X ? axis_x :
+ step->marker == MARKER_AXIS_Y ? axis_y : marker);
+
+ next = FALSE;
+
+ while (!done && !next)
{
- DrawFixedGraphic(xpos + x - 1, ypos + y - 1, IMG_MENU_CALIBRATE_BLUE, 0);
- check[x][y] = FALSE;
- }
- }
+ alpha += alpha_step * (int)(SDL_GetTicks() - alpha_ticks) / 5;
+ alpha_ticks = SDL_GetTicks();
- DrawTextSCentered(mSY - SY + 6 * 32, FONT_TITLE_1, "Rotate joystick");
- DrawTextSCentered(mSY - SY + 7 * 32, FONT_TITLE_1, "in all directions");
- DrawTextSCentered(mSY - SY + 9 * 32, FONT_TITLE_1, "if all balls");
- DrawTextSCentered(mSY - SY + 10 * 32, FONT_TITLE_1, "are marked,");
- DrawTextSCentered(mSY - SY + 11 * 32, FONT_TITLE_1, "center joystick");
- DrawTextSCentered(mSY - SY + 12 * 32, FONT_TITLE_1, "and");
- DrawTextSCentered(mSY - SY + 13 * 32, FONT_TITLE_1, "press any button!");
+ if (alpha >= 255)
+ {
+ alpha = 255;
+ alpha_step = -1;
+ }
+ else if (alpha < 128)
+ {
+ alpha = 127;
+ alpha_step = 1;
+ }
- joy_value = JoystickExt(joystick_nr, TRUE);
- last_x = (joy_value & JOY_LEFT ? -1 : joy_value & JOY_RIGHT ? +1 : 0);
- last_y = (joy_value & JOY_UP ? -1 : joy_value & JOY_DOWN ? +1 : 0);
+ int controller_x = SX + (SXSIZE - controller->width) / 2;
+ int controller_y = SY + ystep2;
- /* eventually uncalibrated center position (joystick could be uncentered) */
- if (!ReadJoystick(joystick_nr, &joy_x, &joy_y, NULL, NULL))
- return FALSE;
+ int marker_x = controller_x + step->x;
+ int marker_y = controller_y + step->y;
- new_joystick_xmiddle = joy_x;
- new_joystick_ymiddle = joy_y;
+ int ystart1 = mSY - 2 * SY + controller_y + controller->height;
+ int ystart2 = ystart1 + ystep1 + ystep2;
- DrawFixedGraphic(xpos + last_x, ypos + last_y, IMG_MENU_CALIBRATE_RED, 0);
+ ClearField();
- FadeIn(REDRAW_FIELD);
+ DrawTextSCentered(ystart1, font_name, name);
+
+ DrawTextSCentered(ystart2 + 0 * ystep2, font_info,
+ "Press buttons and move axes on");
+ DrawTextSCentered(ystart2 + 1 * ystep2, font_info,
+ "your controller when indicated.");
+ DrawTextSCentered(ystart2 + 2 * ystep2, font_info,
+ "(Your controller may look different.)");
+
+#if defined(PLATFORM_ANDROID)
+ DrawTextSCentered(ystart2 + 4 * ystep2, font_info,
+ "To correct a mistake,");
+ DrawTextSCentered(ystart2 + 5 * ystep2, font_info,
+ "press the 'back' button.");
+ DrawTextSCentered(ystart2 + 6 * ystep2, font_info,
+ "To skip a button or axis,");
+ DrawTextSCentered(ystart2 + 7 * ystep2, font_info,
+ "press the 'menu' button.");
+#else
+ DrawTextSCentered(ystart2 + 4 * ystep2, font_info,
+ "To correct a mistake,");
+ DrawTextSCentered(ystart2 + 5 * ystep2, font_info,
+ "press the 'backspace' key.");
+ DrawTextSCentered(ystart2 + 6 * ystep2, font_info,
+ "To skip a button or axis,");
+ DrawTextSCentered(ystart2 + 7 * ystep2, font_info,
+ "press the 'return' key.");
+
+ DrawTextSCentered(ystart2 + 8 * ystep2, font_info,
+ "To exit, press the 'escape' key.");
+#endif
- /* wait for potentially still pressed button to be released */
- while (JoystickExt(joystick_nr, TRUE) & JOY_BUTTON);
+ BlitBitmapMasked(controller, drawto, 0, 0,
+ controller->width, controller->height,
+ controller_x, controller_y);
- while (result < 0)
- {
- if (PendingEvent()) /* got event */
- {
- Event event;
+ SDL_SetSurfaceAlphaMod(marker->surface_masked, alpha);
- NextEvent(&event);
+ BlitBitmapMasked(marker, drawto, 0, 0,
+ marker->width, marker->height,
+ marker_x, marker_y);
- switch (event.type)
+ if (!screen_initialized)
+ FadeIn(REDRAW_FIELD);
+ else
+ BackToFront();
+
+ screen_initialized = TRUE;
+
+ while (NextValidEvent(&event))
{
- case EVENT_KEYPRESS:
- switch (GetEventKey((KeyEvent *)&event, TRUE))
- {
- case KSYM_Return:
- if (check_remaining == 0)
- result = 1;
+ switch (event.type)
+ {
+ case SDL_JOYAXISMOTION:
+ if (event.jaxis.value > 20000 ||
+ event.jaxis.value < -20000)
+ {
+ for (j = 0; j < i; j++)
+ if (steps[j].axis == event.jaxis.axis)
+ break;
+
+ if (j == i)
+ {
+ if (step->marker != MARKER_AXIS_X &&
+ step->marker != MARKER_AXIS_Y)
+ break;
+
+ step->axis = event.jaxis.axis;
+ strcat(mapping, step->field);
+ snprintf(temp, sizeof(temp), ":a%u,", event.jaxis.axis);
+ strcat(mapping, temp);
+ i++;
+ next = TRUE;
+ }
+ }
+
+ break;
+
+ case SDL_JOYHATMOTION:
+ /* ignore centering; we're probably just coming back
+ to the center from the previous item we set */
+ if (event.jhat.value == SDL_HAT_CENTERED)
break;
- case KSYM_Escape:
- FadeSkipNextFadeIn();
- result = 0;
+ for (j = 0; j < i; j++)
+ if (steps[j].hat == event.jhat.hat &&
+ steps[j].hat_value == event.jhat.value)
+ break;
+
+ if (j == i)
+ {
+ step->hat = event.jhat.hat;
+ step->hat_value = event.jhat.value;
+ strcat(mapping, step->field);
+ snprintf(temp, sizeof(temp), ":h%u.%u,",
+ event.jhat.hat, event.jhat.value );
+ strcat(mapping, temp);
+ i++;
+ next = TRUE;
+ }
+
+ break;
+
+ case SDL_JOYBALLMOTION:
+ break;
+
+ case SDL_JOYBUTTONUP:
+ for (j = 0; j < i; j++)
+ if (steps[j].button == event.jbutton.button)
+ break;
+
+ if (j == i)
+ {
+ step->button = event.jbutton.button;
+ strcat(mapping, step->field);
+ snprintf(temp, sizeof(temp), ":b%u,", event.jbutton.button);
+ strcat(mapping, temp);
+ i++;
+ next = TRUE;
+ }
+
+ break;
+
+ case SDL_FINGERDOWN:
+ case SDL_MOUSEBUTTONDOWN:
+ /* skip this step */
+ i++;
+ next = TRUE;
+
+ break;
+
+ case SDL_KEYDOWN:
+ if (event.key.keysym.sym == KSYM_BackSpace ||
+ event.key.keysym.sym == KSYM_Back)
+ {
+ if (i == 0)
+ {
+ /* leave screen */
+ success = FALSE;
+ done = TRUE;
+ }
+
+ /* undo this step */
+ prev_step = &steps[i - 1];
+ strcpy(mapping, prev_step->mapping);
+ i--;
+ next = TRUE;
+
break;
+ }
+
+ if (event.key.keysym.sym == KSYM_space ||
+ event.key.keysym.sym == KSYM_Return ||
+ event.key.keysym.sym == KSYM_Menu)
+ {
+ /* skip this step */
+ i++;
+ next = TRUE;
- default:
break;
- }
- break;
+ }
- case EVENT_KEYRELEASE:
- key_joystick_mapping = 0;
- break;
+ if (event.key.keysym.sym == KSYM_Escape)
+ {
+ /* leave screen */
+ success = FALSE;
+ done = TRUE;
+ }
- default:
- HandleOtherEvents(&event);
+ break;
+
+ case SDL_QUIT:
+ program.exit_function(0);
+ break;
+
+ default:
+ break;
+ }
+
+ // do not handle events for longer than standard frame delay period
+ if (DelayReached(&event_frame_delay, event_frame_delay_value))
break;
}
}
+ }
- if (!ReadJoystick(joystick_nr, &joy_x, &joy_y, NULL, NULL))
- return FALSE;
+ if (success)
+ {
+#if DEBUG_JOYSTICKS
+ Error(ERR_DEBUG, "New game controller mapping:\n\n%s\n\n", mapping);
+#endif
- new_joystick_xleft = MIN(new_joystick_xleft, joy_x);
- new_joystick_xright = MAX(new_joystick_xright, joy_x);
- new_joystick_yupper = MIN(new_joystick_yupper, joy_y);
- new_joystick_ylower = MAX(new_joystick_ylower, joy_y);
+ // activate mapping for this game
+ SDL_GameControllerAddMapping(mapping);
- setup.input[player_nr].joy.xleft = new_joystick_xleft;
- setup.input[player_nr].joy.yupper = new_joystick_yupper;
- setup.input[player_nr].joy.xright = new_joystick_xright;
- setup.input[player_nr].joy.ylower = new_joystick_ylower;
- setup.input[player_nr].joy.xmiddle = new_joystick_xmiddle;
- setup.input[player_nr].joy.ymiddle = new_joystick_ymiddle;
+ // save mapping to personal mappings
+ SaveSetup_AddGameControllerMapping(mapping);
+ }
- CheckJoystickData();
+ /* wait until the last pending event was removed from event queue */
+ while (NextValidEvent(&event));
- joy_value = JoystickExt(joystick_nr, TRUE);
+ return success;
+#else
+ return TRUE;
+#endif
+}
- if (joy_value & JOY_BUTTON && check_remaining == 0)
- result = 1;
+static int ConfigureJoystickMain(int player_nr)
+{
+ char *device_name = setup.input[player_nr].joy.device_name;
+ int joystick_nr = getJoystickNrFromDeviceName(device_name);
+ boolean joystick_active = CheckJoystickOpened(joystick_nr);
+ int success = FALSE;
+ int i;
- x = (joy_value & JOY_LEFT ? -1 : joy_value & JOY_RIGHT ? +1 : 0);
- y = (joy_value & JOY_UP ? -1 : joy_value & JOY_DOWN ? +1 : 0);
+ if (joystick.status == JOYSTICK_NOT_AVAILABLE)
+ return JOYSTICK_NOT_AVAILABLE;
- if (x != last_x || y != last_y)
- {
- DrawFixedGraphic(xpos + last_x, ypos + last_y,
- IMG_MENU_CALIBRATE_YELLOW, 0);
- DrawFixedGraphic(xpos + x, ypos + y,
- IMG_MENU_CALIBRATE_RED, 0);
+ if (!joystick_active || !setup.input[player_nr].use_joystick)
+ return JOYSTICK_NOT_AVAILABLE;
- last_x = x;
- last_y = y;
+ FadeSetEnterMenu();
+ FadeOut(REDRAW_FIELD);
- if (check_remaining > 0 && !check[x+1][y+1])
- {
- check[x+1][y+1] = TRUE;
- check_remaining--;
- }
- }
+ // close all joystick devices (potentially opened as game controllers)
+ for (i = 0; i < SDL_NumJoysticks(); i++)
+ SDLCloseJoystick(i);
- BackToFront();
- }
+ // open joystick device as plain joystick to configure as game controller
+ SDL_Joystick *joystick = SDL_JoystickOpen(joystick_nr);
- /* calibrated center position (joystick should now be centered) */
- if (!ReadJoystick(joystick_nr, &joy_x, &joy_y, NULL, NULL))
+ // as the joystick was successfully opened before, this should not happen
+ if (joystick == NULL)
return FALSE;
- new_joystick_xmiddle = joy_x;
- new_joystick_ymiddle = joy_y;
+ // create new game controller mapping (buttons and axes) for joystick device
+ success = ConfigureJoystickMapButtonsAndAxes(joystick);
- /* wait until the last pressed button was released */
- while (JoystickExt(joystick_nr, TRUE) & JOY_BUTTON)
- {
- if (PendingEvent()) /* got event */
- {
- Event event;
+ // close joystick (and maybe re-open as configured game controller later)
+ SDL_JoystickClose(joystick);
- NextEvent(&event);
- HandleOtherEvents(&event);
+ // re-open all joystick devices (potentially as game controllers)
+ for (i = 0; i < SDL_NumJoysticks(); i++)
+ SDLOpenJoystick(i);
- BackToFront();
- }
- }
+ // clear all joystick input actions for all joystick devices
+ SDLClearJoystickState();
- return TRUE;
+ return (success ? JOYSTICK_CONFIGURED : JOYSTICK_NOT_CONFIGURED);
}
-void CalibrateJoystick(int player_nr)
+void ConfigureJoystick(int player_nr)
{
- if (!CalibrateJoystickMain(player_nr))
+ boolean state = ConfigureJoystickMain(player_nr);
+
+ if (state != JOYSTICK_NOT_CONFIGURED)
{
+ boolean success = (state == JOYSTICK_CONFIGURED);
+ char *message = (success ? " IS CONFIGURED! " : " NOT AVAILABLE! ");
char *device_name = setup.input[player_nr].joy.device_name;
int nr = getJoystickNrFromDeviceName(device_name) + 1;
int xpos = mSX - SX;
int ypos = mSY - SY;
+ unsigned int wait_frame_delay = 0;
+ unsigned int wait_frame_delay_value = 2000;
+
+ ResetDelayCounter(&wait_frame_delay);
ClearField();
DrawTextF(xpos + 16, ypos + 6 * 32, FONT_TITLE_1, " JOYSTICK %d ", nr);
- DrawTextF(xpos + 16, ypos + 7 * 32, FONT_TITLE_1, " NOT AVAILABLE! ");
- BackToFront();
+ DrawTextF(xpos + 16, ypos + 7 * 32, FONT_TITLE_1, message);
- Delay(2000); /* show error message for a short time */
+ while (!DelayReached(&wait_frame_delay, wait_frame_delay_value))
+ BackToFront();
ClearEventQueue();
}