// (c) 1995-2014 by Artsoft Entertainment
// Holger Schemel
// info@artsoft.org
-// http://www.artsoft.org/
+// https://www.artsoft.org/
// ----------------------------------------------------------------------------
// screens.c
// ============================================================================
// (should also match corresponding entries in src/conf_gfx.c)
#define SETUP_MODE_MAIN 0
#define SETUP_MODE_GAME 1
-#define SETUP_MODE_EDITOR 2
-#define SETUP_MODE_GRAPHICS 3
-#define SETUP_MODE_SOUND 4
-#define SETUP_MODE_ARTWORK 5
-#define SETUP_MODE_INPUT 6
-#define SETUP_MODE_TOUCH 7
-#define SETUP_MODE_SHORTCUTS 8
-#define SETUP_MODE_SHORTCUTS_1 9
-#define SETUP_MODE_SHORTCUTS_2 10
-#define SETUP_MODE_SHORTCUTS_3 11
-#define SETUP_MODE_SHORTCUTS_4 12
-#define SETUP_MODE_SHORTCUTS_5 13
+#define SETUP_MODE_ENGINES 2
+#define SETUP_MODE_EDITOR 3
+#define SETUP_MODE_GRAPHICS 4
+#define SETUP_MODE_SOUND 5
+#define SETUP_MODE_ARTWORK 6
+#define SETUP_MODE_INPUT 7
+#define SETUP_MODE_TOUCH 8
+#define SETUP_MODE_SHORTCUTS 9
+#define SETUP_MODE_SHORTCUTS_1 10
+#define SETUP_MODE_SHORTCUTS_2 11
+#define SETUP_MODE_SHORTCUTS_3 12
+#define SETUP_MODE_SHORTCUTS_4 13
+#define SETUP_MODE_SHORTCUTS_5 14
// sub-screens on the setup screen (generic)
-#define SETUP_MODE_CHOOSE_ARTWORK 14
-#define SETUP_MODE_CHOOSE_OTHER 15
+#define SETUP_MODE_CHOOSE_ARTWORK 15
+#define SETUP_MODE_CHOOSE_OTHER 16
// sub-screens on the setup screen (specific)
-#define SETUP_MODE_CHOOSE_GAME_SPEED 16
-#define SETUP_MODE_CHOOSE_SCROLL_DELAY 17
-#define SETUP_MODE_CHOOSE_SNAPSHOT_MODE 18
-#define SETUP_MODE_CHOOSE_WINDOW_SIZE 19
-#define SETUP_MODE_CHOOSE_SCALING_TYPE 20
-#define SETUP_MODE_CHOOSE_RENDERING 21
-#define SETUP_MODE_CHOOSE_VSYNC 22
-#define SETUP_MODE_CHOOSE_GRAPHICS 23
-#define SETUP_MODE_CHOOSE_SOUNDS 24
-#define SETUP_MODE_CHOOSE_MUSIC 25
-#define SETUP_MODE_CHOOSE_VOLUME_SIMPLE 26
-#define SETUP_MODE_CHOOSE_VOLUME_LOOPS 27
-#define SETUP_MODE_CHOOSE_VOLUME_MUSIC 28
-#define SETUP_MODE_CHOOSE_TOUCH_CONTROL 29
-#define SETUP_MODE_CHOOSE_MOVE_DISTANCE 30
-#define SETUP_MODE_CHOOSE_DROP_DISTANCE 31
-#define SETUP_MODE_CHOOSE_TRANSPARENCY 32
-#define SETUP_MODE_CHOOSE_GRID_XSIZE_0 33
-#define SETUP_MODE_CHOOSE_GRID_YSIZE_0 34
-#define SETUP_MODE_CHOOSE_GRID_XSIZE_1 35
-#define SETUP_MODE_CHOOSE_GRID_YSIZE_1 36
-#define SETUP_MODE_CONFIG_VIRT_BUTTONS 37
-
-#define MAX_SETUP_MODES 38
+#define SETUP_MODE_CHOOSE_GAME_SPEED 17
+#define SETUP_MODE_CHOOSE_SCROLL_DELAY 18
+#define SETUP_MODE_CHOOSE_SNAPSHOT_MODE 19
+#define SETUP_MODE_CHOOSE_WINDOW_SIZE 20
+#define SETUP_MODE_CHOOSE_SCALING_TYPE 21
+#define SETUP_MODE_CHOOSE_RENDERING 22
+#define SETUP_MODE_CHOOSE_VSYNC 23
+#define SETUP_MODE_CHOOSE_GRAPHICS 24
+#define SETUP_MODE_CHOOSE_SOUNDS 25
+#define SETUP_MODE_CHOOSE_MUSIC 26
+#define SETUP_MODE_CHOOSE_VOLUME_SIMPLE 27
+#define SETUP_MODE_CHOOSE_VOLUME_LOOPS 28
+#define SETUP_MODE_CHOOSE_VOLUME_MUSIC 29
+#define SETUP_MODE_CHOOSE_TOUCH_CONTROL 30
+#define SETUP_MODE_CHOOSE_MOVE_DISTANCE 31
+#define SETUP_MODE_CHOOSE_DROP_DISTANCE 32
+#define SETUP_MODE_CHOOSE_TRANSPARENCY 33
+#define SETUP_MODE_CHOOSE_GRID_XSIZE_0 34
+#define SETUP_MODE_CHOOSE_GRID_YSIZE_0 35
+#define SETUP_MODE_CHOOSE_GRID_XSIZE_1 36
+#define SETUP_MODE_CHOOSE_GRID_YSIZE_1 37
+#define SETUP_MODE_CONFIG_VIRT_BUTTONS 38
+
+#define MAX_SETUP_MODES 39
#define MAX_MENU_MODES MAX(MAX_INFO_MODES, MAX_SETUP_MODES)
// setup screen titles
#define STR_SETUP_MAIN "Setup"
#define STR_SETUP_GAME "Game & Menu"
+#define STR_SETUP_ENGINES "Game Engines"
#define STR_SETUP_EDITOR "Editor"
#define STR_SETUP_GRAPHICS "Graphics"
#define STR_SETUP_SOUND "Sound & Music"
#define STR_SETUP_CHOOSE_GRID_XSIZE_1 "Horiz. Buttons"
#define STR_SETUP_CHOOSE_GRID_YSIZE_1 "Vert. Buttons"
+// other screen text constants
+#define STR_CHOOSE_TREE_EDIT "Edit"
+#define MENU_CHOOSE_TREE_FONT(x) (FONT_TEXT_1 + (x))
+
// for input setup functions
#define SETUPINPUT_SCREEN_POS_START 0
#define SETUPINPUT_SCREEN_POS_EMPTY1 3
#define MENU_SCREEN_START_XPOS 1
#define MENU_SCREEN_START_YPOS 2
#define MENU_SCREEN_VALUE_XPOS (SCR_FIELDX - 3)
+#define MENU_SCREEN_TEXT2_XPOS (SCR_FIELDX - 2)
#define MENU_SCREEN_MAX_XPOS (SCR_FIELDX - 1)
#define MENU_TITLE1_YPOS 8
#define MENU_TITLE2_YPOS 46
#define SCREEN_CTRL_ID_NEXT_PLAYER 6
#define SCREEN_CTRL_ID_INSERT_SOLUTION 7
#define SCREEN_CTRL_ID_PLAY_SOLUTION 8
-#define SCREEN_CTRL_ID_SCROLL_UP 9
-#define SCREEN_CTRL_ID_SCROLL_DOWN 10
-#define SCREEN_CTRL_ID_SCROLL_VERTICAL 11
-#define SCREEN_CTRL_ID_NETWORK_SERVER 12
-
-#define NUM_SCREEN_GADGETS 13
-
-#define NUM_SCREEN_MENUBUTTONS 9
+#define SCREEN_CTRL_ID_SWITCH_ECS_AGA 9
+#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE 10
+#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE 11
+#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE2 12
+#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2 13
+#define SCREEN_CTRL_ID_SCROLL_UP 14
+#define SCREEN_CTRL_ID_SCROLL_DOWN 15
+#define SCREEN_CTRL_ID_SCROLL_VERTICAL 16
+#define SCREEN_CTRL_ID_NETWORK_SERVER 17
+
+#define NUM_SCREEN_GADGETS 18
+
+#define NUM_SCREEN_MENUBUTTONS 14
#define NUM_SCREEN_SCROLLBUTTONS 2
#define NUM_SCREEN_SCROLLBARS 1
#define NUM_SCREEN_TEXTINPUT 1
#define SCREEN_MASK_MAIN (1 << 0)
#define SCREEN_MASK_MAIN_HAS_SOLUTION (1 << 1)
#define SCREEN_MASK_INPUT (1 << 2)
+#define SCREEN_MASK_TOUCH (1 << 3)
+#define SCREEN_MASK_TOUCH2 (1 << 4)
// graphic position and size values for buttons and scrollbars
#define SC_MENUBUTTON_XSIZE TILEX
static void ConfigureJoystick(int);
static void ConfigureVirtualButtons(void);
static void execSetupGame(void);
+static void execSetupEngines(void);
static void execSetupGraphics(void);
static void execSetupSound(void);
static void execSetupTouch(void);
static void execSetupArtwork(void);
static void HandleChooseTree(int, int, int, int, int, TreeInfo **);
+static void DrawChoosePlayerName(void);
static void DrawChooseLevelSet(void);
static void DrawChooseLevelNr(void);
static void DrawInfoScreen(void);
static void DrawSetupScreen(void);
+static void DrawTypeName(void);
static void DrawInfoScreen_NotAvailable(char *, char *);
static void DrawInfoScreen_HelpAnim(int, int, boolean);
static void DisableVsyncIfNeeded(void);
static void MapScreenMenuGadgets(int);
+static void UnmapScreenMenuGadgets(int);
static void MapScreenGadgets(int);
static void MapScreenTreeGadgets(TreeInfo *);
static TreeInfo *grid_sizes[2][2] = { { NULL, NULL }, { NULL, NULL } };
static TreeInfo *grid_size_current[2][2] = { { NULL, NULL }, { NULL, NULL } };
+static TreeInfo *player_name = NULL;
+static TreeInfo *player_name_current = NULL;
+
static TreeInfo *level_number = NULL;
static TreeInfo *level_number_current = NULL;
#define DRAW_MODE(s) ((s) >= GAME_MODE_MAIN && \
(s) <= GAME_MODE_SETUP ? (s) : \
(s) == GAME_MODE_PSEUDO_TYPENAME ? \
- GAME_MODE_MAIN : GAME_MODE_DEFAULT)
+ GAME_MODE_MAIN : \
+ (s) == GAME_MODE_PSEUDO_TYPENAMES ? \
+ GAME_MODE_NAMES : GAME_MODE_DEFAULT)
// (there are no draw offset definitions needed for INFO_MODE_TITLE)
#define DRAW_MODE_INFO(i) ((i) >= INFO_MODE_TITLE && \
static char *main_text_title_2 = NULL;
static char *main_text_title_3 = NULL;
+extern char debug_xsn_mode[];
+
struct MainControlInfo
{
int nr;
int sound_local = base + nr;
#if 0
- printf("::: %d, %d, %d: %d ['%s'], %d ['%s']\n",
- nr, initial, is_image,
- sound_global, getSoundListEntry(sound_global)->filename,
- sound_local, getSoundListEntry(sound_local)->filename);
+ Debug("screens:getTitleSound", "%d, %d, %d: %d ['%s'], %d ['%s']",
+ nr, initial, is_image,
+ sound_global, getSoundListEntry(sound_global)->filename,
+ sound_local, getSoundListEntry(sound_local)->filename);
#endif
if (!strEqual(getSoundListEntry(sound_local)->filename, UNDEFINED_FILENAME))
int music_local = base + nr;
#if 0
- printf("::: %d, %d, %d: %d ['%s'], %d ['%s']\n",
- nr, initial, is_image,
- music_global, getMusicListEntry(music_global)->filename,
- music_local, getMusicListEntry(music_local)->filename);
+ Debug("screens:getTitleMusic", "%d, %d, %d: %d ['%s'], %d ['%s']",
+ nr, initial, is_image,
+ music_global, getMusicListEntry(music_global)->filename,
+ music_local, getMusicListEntry(music_local)->filename);
#endif
if (!strEqual(getMusicListEntry(music_local)->filename, UNDEFINED_FILENAME))
ti.fade_delay = tmi.fade_delay;
ti.post_delay = tmi.post_delay;
ti.auto_delay = tmi.auto_delay;
+ ti.auto_delay_unit = tmi.auto_delay_unit;
return ti;
}
int rect_y = ALIGNED_TEXT_YPOS(rect);
#if 0
- printf("::: insideTextPosRect: (%d, %d), (%d, %d) [%d, %d] (%d, %d) => %d\n",
- x, y, rect_x, rect_y, rect->x, rect->y, rect->width, rect->height,
- (x >= rect_x && x < rect_x + rect->width &&
- y >= rect_y && y < rect_y + rect->height));
+ Debug("screens:insideTextPosRect",
+ "(%d, %d), (%d, %d) [%d, %d] (%d, %d) => %d",
+ x, y, rect_x, rect_y, rect->x, rect->y, rect->width, rect->height,
+ (x >= rect_x && x < rect_x + rect->width &&
+ y >= rect_y && y < rect_y + rect->height));
#endif
return (x >= rect_x && x < rect_x + rect->width &&
drawCursorExt(0, ypos, active, -1);
}
+static int getChooseTreeEditFont(boolean active)
+{
+ return (active ? FONT_MENU_2_ACTIVE : FONT_MENU_2);
+}
+
+static int getChooseTreeEditXPos(int pos)
+{
+ boolean has_scrollbar = screen_gadget[SCREEN_CTRL_ID_SCROLL_VERTICAL]->mapped;
+ int xoffset = (has_scrollbar ? -1 : 0);
+ int xpos = MENU_SCREEN_TEXT2_XPOS + xoffset;
+ int sx = amSX + xpos * TILEX;
+ int font_nr = getChooseTreeEditFont(FALSE);
+ int width = getTextWidth(STR_CHOOSE_TREE_EDIT, font_nr);
+
+ return (pos == POS_RIGHT ? sx + width - 1 : sx);
+}
+
+static int getChooseTreeEditYPos(int ypos_raw)
+{
+ int ypos = MENU_SCREEN_START_YPOS + ypos_raw;
+ int sy = amSY + ypos * TILEY;
+
+ return sy;
+}
+
+static void drawChooseTreeEdit(int ypos_raw, boolean active)
+{
+ int sx = getChooseTreeEditXPos(POS_LEFT);
+ int sy = getChooseTreeEditYPos(ypos_raw);
+ int font_nr = getChooseTreeEditFont(active);
+
+ DrawText(sx, sy, STR_CHOOSE_TREE_EDIT, font_nr);
+}
+
static void DrawHeadline(void)
{
DrawTextSCentered(MENU_TITLE1_YPOS, FONT_TITLE_1, main_text_title_1);
return;
}
- // needed if last screen was the setup screen and fullscreen state changed
- // (moved to "execSetupGraphics()" to change fullscreen state directly)
- // ToggleFullscreenOrChangeWindowScalingIfNeeded();
-
// leveldir_current may be invalid (level group, parent link)
if (!validLevelSeries(leveldir_current))
leveldir_current = getFirstValidTreeInfoEntry(leveldir_last_valid);
if (leveldir_current->node_parent->node_group->cl_first == -1)
{
int num_leveldirs = numTreeInfoInGroup(leveldir_current);
- int leveldir_pos = posTreeInfo(leveldir_current);
+ int leveldir_pos = getPosFromTreeInfo(leveldir_current);
int num_page_entries = MIN(num_leveldirs, NUM_MENU_ENTRIES_ON_SCREEN);
int cl_first, cl_cursor;
}
}
+static unsigned int getAutoDelayCounter(struct TitleFadingInfo *fi)
+{
+ boolean use_frame_counter = (fi->auto_delay_unit == AUTO_DELAY_UNIT_FRAMES);
+
+ return (use_frame_counter ? video.frame_counter : Counter());
+}
+
+static boolean TitleAutoDelayReached(unsigned int *counter_var,
+ struct TitleFadingInfo *fi)
+{
+ return DelayReachedExt(counter_var, fi->auto_delay, getAutoDelayCounter(fi));
+}
+
+static void ResetTitleAutoDelay(unsigned int *counter_var,
+ struct TitleFadingInfo *fi)
+{
+ *counter_var = getAutoDelayCounter(fi);
+}
+
void HandleTitleScreen(int mx, int my, int dx, int dy, int button)
{
static unsigned int title_delay = 0;
FadeIn(REDRAW_ALL);
- DelayReached(&title_delay, 0); // reset delay counter
+ ResetTitleAutoDelay(&title_delay, &fading);
return;
}
- if (fading.auto_delay > 0 && DelayReached(&title_delay, fading.auto_delay))
+ if (fading.auto_delay > 0 && TitleAutoDelayReached(&title_delay, &fading))
button = MB_MENU_CHOICE;
if (button == MB_MENU_LEAVE)
FadeIn(REDRAW_ALL);
- DelayReached(&title_delay, 0); // reset delay counter
+ ResetTitleAutoDelay(&title_delay, &fading);
}
else
{
static boolean button_pressed_last = FALSE;
boolean button_pressed = FALSE;
int pos = choice;
- int i;
+ int i = 0; // needed to prevent compiler warning due to bad code below
if (button == MB_MENU_INITIALIZE)
{
}
else
{
- SetGameStatus(GAME_MODE_PSEUDO_TYPENAME);
+ if (setup.multiple_users)
+ {
+ CloseDoor(DOOR_CLOSE_2);
- HandleTypeName(strlen(setup.player_name), 0);
+ SetGameStatus(GAME_MODE_NAMES);
+
+ DrawChoosePlayerName();
+ }
+ else
+ {
+ SetGameStatus(GAME_MODE_PSEUDO_TYPENAME);
+
+ DrawTypeName();
+ }
}
}
else if (pos == MAIN_CONTROL_LEVELS)
static int num_page_entries_all_last[NUM_SPECIAL_GFX_ARGS][MAX_MENU_MODES];
static int choice_stores[NUM_SPECIAL_GFX_ARGS][MAX_MENU_MODES];
static int first_entry_stores[NUM_SPECIAL_GFX_ARGS][MAX_MENU_MODES];
+ boolean has_scrollbar = screen_gadget[SCREEN_CTRL_ID_SCROLL_VERTICAL]->mapped;
+ int mx_scrollbar = screen_gadget[SCREEN_CTRL_ID_SCROLL_VERTICAL]->x;
+ int mx_right_border = (has_scrollbar ? mx_scrollbar : SX + SXSIZE);
int *num_page_entries_last = num_page_entries_all_last[game_status];
int *choice_store = choice_stores[game_status];
int *first_entry_store = first_entry_stores[game_status];
if (!anyScrollbarGadgetActive() &&
IN_VIS_MENU(x, y) &&
- mx < screen_gadget[SCREEN_CTRL_ID_SCROLL_VERTICAL]->x &&
+ mx < mx_right_border &&
y >= 0 && y < num_page_entries)
{
if (button)
}
DrawTextF(xstart1, ystart, font_head, "Platform");
- DrawTextF(xstart2, ystart, font_text, PLATFORM_STRING);
+ DrawTextF(xstart2, ystart, font_text, "%s (%s)",
+ PLATFORM_STRING,
+ PLATFORM_XX_BIT_STRING);
ystart += ystep_line;
DrawTextF(xstart1, ystart, font_head, "Target");
DrawTextF(xstart1, ystart, font_head, "Source date");
DrawTextF(xstart2, ystart, font_text, getSourceDateString());
+ ystart += ystep_line;
+
+ DrawTextF(xstart1, ystart, font_head, "Commit hash");
+ DrawTextF(xstart2, ystart, font_text, getSourceHashString());
ystart += ystep_para;
DrawTextF(xstart1, ystart, font_head, "Library");
DrawTextF(xstart3, ystart, font_head, "Used");
ystart += ystep_head;
- driver_name = getStringCopyNStatic(SDL_GetVideoDriver(0), driver_name_len);
+ driver_name =
+ getStringCopyNStatic(SDLGetRendererName(), driver_name_len);
- DrawTextF(xstart1, ystart, font_text, "SDL_VideoDriver");
+ DrawTextF(xstart1, ystart, font_text, "Render Driver");
+ DrawTextF(xstart2, ystart, font_text, "%s", setup.system.sdl_renderdriver);
+ DrawTextF(xstart3, ystart, font_text, "%s", driver_name);
+ ystart += ystep_line;
+
+ driver_name =
+ getStringCopyNStatic(SDL_GetCurrentVideoDriver(), driver_name_len);
+
+ DrawTextF(xstart1, ystart, font_text, "Video Driver");
DrawTextF(xstart2, ystart, font_text, "%s", setup.system.sdl_videodriver);
DrawTextF(xstart3, ystart, font_text, "%s", driver_name);
ystart += ystep_line;
- driver_name = getStringCopyNStatic(SDL_GetAudioDriver(0), driver_name_len);
+ driver_name =
+ getStringCopyNStatic(SDL_GetCurrentAudioDriver(), driver_name_len);
- DrawTextF(xstart1, ystart, font_text, "SDL_AudioDriver");
+ DrawTextF(xstart1, ystart, font_text, "Audio Driver");
DrawTextF(xstart2, ystart, font_text, "%s", setup.system.sdl_audiodriver);
DrawTextF(xstart3, ystart, font_text, "%s", driver_name);
// type name functions
// ============================================================================
-void HandleTypeName(int newxpos, Key key)
+static TreeInfo *type_name_node = NULL;
+static char type_name_last[MAX_PLAYER_NAME_LEN + 1] = { 0 };
+static int type_name_nr = 0;
+
+static int getPlayerNameColor(char *name)
+{
+ return (strEqual(name, EMPTY_PLAYER_NAME) ? FC_BLUE : FC_RED);
+}
+
+static void drawTypeNameText(char *name, struct TextPosInfo *pos,
+ boolean active)
+{
+ char text[MAX_PLAYER_NAME_LEN + 2] = { 0 };
+ boolean multiple_users = (game_status == GAME_MODE_PSEUDO_TYPENAMES);
+ int sx = (multiple_users ? amSX + pos->x : mSX + ALIGNED_TEXT_XPOS(pos));
+ int sy = (multiple_users ? amSY + pos->y : mSY + ALIGNED_TEXT_YPOS(pos));
+ int font_nr = (active ? FONT_ACTIVE(pos->font) : pos->font);
+ int font_width = getFontWidth(font_nr);
+
+ DrawBackgroundForFont(sx, sy, pos->width, pos->height, font_nr);
+
+ sprintf(text, "%s%c", name, (active ? '_' : '\0'));
+
+ pos->width = strlen(text) * font_width;
+ sx = (multiple_users ? amSX + pos->x : mSX + ALIGNED_TEXT_XPOS(pos));
+
+ DrawText(sx, sy, text, font_nr);
+}
+
+static void getTypeNameValues(char *name, struct TextPosInfo *pos, int *xpos)
{
- static char last_player_name[MAX_PLAYER_NAME_LEN + 1];
struct MainControlInfo *mci = getMainControlInfo(MAIN_CONTROL_NAME);
- struct TextPosInfo *pos = mci->pos_input;
- int startx = mSX + ALIGNED_TEXT_XPOS(pos);
- int starty = mSY + ALIGNED_TEXT_YPOS(pos);
+
+ *pos = *mci->pos_input;
+
+ if (game_status == GAME_MODE_PSEUDO_TYPENAMES)
+ {
+ TreeInfo *ti = player_name_current;
+ int first_entry = ti->cl_first;
+ int entry_pos = first_entry + ti->cl_cursor;
+ TreeInfo *node_first = getTreeInfoFirstGroupEntry(ti);
+ int xpos = MENU_SCREEN_START_XPOS;
+ int ypos = MENU_SCREEN_START_YPOS + ti->cl_cursor;
+
+ type_name_node = getTreeInfoFromPos(node_first, entry_pos);
+ type_name_nr = entry_pos;
+
+ strcpy(name, type_name_node->name);
+
+ pos->x = xpos * 32;
+ pos->y = ypos * 32;
+ pos->width = MAX_PLAYER_NAME_LEN * 32;
+ }
+ else
+ {
+ type_name_nr = user.nr;
+
+ strcpy(name, setup.player_name);
+ }
+
+ strcpy(type_name_last, name);
+
+ if (strEqual(name, EMPTY_PLAYER_NAME))
+ strcpy(name, "");
+
+ *xpos = strlen(name);
+}
+
+static void setTypeNameValues_Name(char *name, struct TextPosInfo *pos)
+{
+ // change name of edited user in global list of user names
+ setString(&global.user_names[type_name_nr], name);
+
+ if (game_status == GAME_MODE_PSEUDO_TYPENAMES)
+ {
+ TreeInfo *node = type_name_node;
+
+ // change name of edited user in local menu tree structure
+ setString(&node->name, name);
+ setString(&node->name_sorting, name);
+
+ node->color = getPlayerNameColor(name);
+ pos->font = MENU_CHOOSE_TREE_FONT(node->color);
+ }
+}
+
+static void setTypeNameValues(char *name, struct TextPosInfo *pos,
+ boolean changed)
+{
+ boolean reset_setup = strEqual(name, "");
+ boolean remove_user = strEqual(name, EMPTY_PLAYER_NAME);
+ boolean create_user = strEqual(type_name_last, EMPTY_PLAYER_NAME);
+
+ if (!changed)
+ strcpy(name, type_name_last);
+
+ if (strEqual(name, ""))
+ strcpy(name, EMPTY_PLAYER_NAME);
+
+ setTypeNameValues_Name(name, pos);
+
+ // if player name not changed, no further action required
+ if (strEqual(name, type_name_last))
+ return;
+
+ // redraw player name before (possibly) opening request dialogs
+ drawTypeNameText(name, pos, FALSE);
+
+ int last_user_nr = user.nr;
+
+ if (game_status == GAME_MODE_PSEUDO_TYPENAMES)
+ {
+ // save setup of currently active user (may differ from edited user)
+ SaveSetup();
+
+ // temporarily change active user to edited user
+ user.nr = type_name_nr;
+
+ // load setup of edited user (unless creating user with current setup)
+ if (!create_user ||
+ !Request("Use current setup values for the new player?", REQ_ASK))
+ LoadSetup();
+ }
+
+ char *setup_filename = getSetupFilename();
+ boolean setup_exists = fileExists(setup_filename);
+
+ // change name of edited user in setup structure
+ strcpy(setup.player_name, name);
+
+ // save setup of edited user
+ SaveSetup();
+
+ if (game_status == GAME_MODE_PSEUDO_TYPENAMES || reset_setup)
+ {
+ if (reset_setup)
+ {
+ if (Request("Reset setup values for this player?", REQ_ASK))
+ {
+ // remove setup config file
+ unlink(setup_filename);
+
+ // set player name to default player name
+ LoadSetup();
+
+ // update player name used by name typing functions
+ strcpy(name, setup.player_name);
+
+ setTypeNameValues_Name(name, pos);
+ }
+ }
+ else if (remove_user && type_name_nr != 0)
+ {
+ if (Request("Remove settings and tapes for deleted player?", REQ_ASK))
+ {
+ char *user_dir = getUserGameDataDir();
+ char *user_dir_removed =
+ getStringCat3WithSeparator(user_dir, "REMOVED",
+ getCurrentTimestamp(), ".");
+
+ if (rename(user_dir, user_dir_removed) != 0)
+ Request("Removing settings and tapes failed!", REQ_CONFIRM);
+
+ checked_free(user_dir_removed);
+ }
+ }
+ else if (create_user && type_name_nr != 0 && !setup_exists)
+ {
+ if (Request("Create empty level set for the new player?", REQ_ASK))
+ {
+ char *levelset_subdir = getNewUserLevelSubdir();
+
+ if (CreateUserLevelSet(levelset_subdir, name, name, 100, FALSE))
+ {
+ AddUserLevelSetToLevelInfo(levelset_subdir);
+
+ LevelDirTree *leveldir_current_last = leveldir_current;
+
+ leveldir_current = getTreeInfoFromIdentifier(leveldir_first,
+ levelset_subdir);
+
+ // set level number of newly created level set to default value
+ LoadLevelSetup_SeriesInfo();
+
+ // set newly created level set as current level set for new user
+ SaveLevelSetup_LastSeries();
+ SaveLevelSetup_SeriesInfo();
+
+ leveldir_current = leveldir_current_last;
+ }
+ else
+ {
+ Request("Creating new level set failed!", REQ_CONFIRM);
+ }
+ }
+ }
+
+ // restore currently active user
+ user.nr = last_user_nr;
+
+ // restore setup of currently active user
+ LoadSetup();
+
+ // restore last level set of currently active user
+ LoadLevelSetup_LastSeries();
+ LoadLevelSetup_SeriesInfo();
+ }
+}
+
+static void HandleTypeNameExt(boolean initialize, Key key)
+{
+ static struct TextPosInfo pos_name = { 0 };
+ static char name[MAX_PLAYER_NAME_LEN + 1] = { 0 };
static int xpos = 0;
- int font_nr = pos->font;
- int font_active_nr = FONT_ACTIVE(font_nr);
- int font_width = getFontWidth(font_active_nr);
+ struct TextPosInfo *pos = &pos_name;
char key_char = getValidConfigValueChar(getCharFromKey(key));
boolean is_valid_key_char = (key_char != 0 && (key_char != ' ' || xpos > 0));
- boolean is_active = TRUE;
+ boolean active = TRUE;
- DrawBackgroundForFont(startx,starty, pos->width, pos->height, font_active_nr);
-
- if (newxpos)
+ if (initialize)
{
- strcpy(last_player_name, setup.player_name);
+ getTypeNameValues(name, pos, &xpos);
- xpos = newxpos;
+ int sx = mSX + ALIGNED_TEXT_XPOS(pos);
+ int sy = mSY + ALIGNED_TEXT_YPOS(pos);
- StartTextInput(startx, starty, pos->width, pos->height);
+ StartTextInput(sx, sy, pos->width, pos->height);
}
else if (is_valid_key_char && xpos < MAX_PLAYER_NAME_LEN)
{
- setup.player_name[xpos] = key_char;
- setup.player_name[xpos + 1] = 0;
+ name[xpos] = key_char;
+ name[xpos + 1] = 0;
xpos++;
}
{
xpos--;
- setup.player_name[xpos] = 0;
+ name[xpos] = 0;
}
- else if (key == KSYM_Return && xpos > 0)
+ else if (key == KSYM_Return)
{
- SaveSetup();
-
- is_active = FALSE;
+ setTypeNameValues(name, pos, TRUE);
- SetGameStatus(GAME_MODE_MAIN);
+ active = FALSE;
}
else if (key == KSYM_Escape)
{
- strcpy(setup.player_name, last_player_name);
-
- is_active = FALSE;
+ setTypeNameValues(name, pos, FALSE);
- SetGameStatus(GAME_MODE_MAIN);
+ active = FALSE;
}
- if (is_active)
- {
- pos->width = (strlen(setup.player_name) + 1) * font_width;
- startx = mSX + ALIGNED_TEXT_XPOS(pos);
+ drawTypeNameText(name, pos, active);
- DrawText(startx, starty, setup.player_name, font_active_nr);
- DrawText(startx + xpos * font_width, starty, "_", font_active_nr);
- }
- else
+ if (!active)
{
- pos->width = strlen(setup.player_name) * font_width;
- startx = mSX + ALIGNED_TEXT_XPOS(pos);
+ StopTextInput();
- DrawText(startx, starty, setup.player_name, font_nr);
+ SetGameStatus(game_status_last_screen);
- StopTextInput();
+ if (game_status == GAME_MODE_MAIN)
+ InitializeMainControls();
}
}
+static void DrawTypeName(void)
+{
+ HandleTypeNameExt(TRUE, 0);
+}
+
+void HandleTypeName(Key key)
+{
+ HandleTypeNameExt(FALSE, key);
+}
+
// ============================================================================
// tree menu functions
int num_entries = numTreeInfoInGroup(ti);
boolean scrollbar_needed = (num_entries > NUM_MENU_ENTRIES_ON_SCREEN);
- int text_width = max_text_size * getFontWidth(FONT_TEXT_1);
+ int font_nr = MENU_CHOOSE_TREE_FONT(FC_RED);
+ int text_width = max_text_size * getFontWidth(font_nr);
int button_width = SC_MENUBUTTON_XSIZE;
int scrollbar_xpos = SC_SCROLLBAR_XPOS + menu.scrollbar_xoffset;
int screen_width = (scrollbar_needed ? scrollbar_xpos : SXSIZE);
int num_entries = numTreeInfoInGroup(ti);
int num_page_entries = MIN(num_entries, NUM_MENU_ENTRIES_ON_SCREEN);
- int font_height = getFontHeight(FONT_TEXT_1);
+ int font_nr = MENU_CHOOSE_TREE_FONT(FC_RED);
+ int font_height = getFontHeight(font_nr);
int text_height = font_height * num_page_entries;
int page_height = font_height * NUM_MENU_ENTRIES_ON_SCREEN;
int align = menu.list_setup[SETUP_MODE_CHOOSE_OTHER].valign;
// needed if different viewport properties defined for choosing level (set)
ChangeViewportPropertiesIfNeeded();
- if (game_status == GAME_MODE_LEVELNR)
+ if (game_status == GAME_MODE_NAMES)
+ SetMainBackgroundImage(IMG_BACKGROUND_NAMES);
+ else if (game_status == GAME_MODE_LEVELNR)
SetMainBackgroundImage(IMG_BACKGROUND_LEVELNR);
else if (game_status == GAME_MODE_LEVELS)
SetMainBackgroundImage(IMG_BACKGROUND_LEVELS);
OpenDoor(GetDoorState() | DOOR_NO_DELAY | DOOR_FORCE_REDRAW);
- HandleChooseTree(0, 0, 0, 0, MB_MENU_INITIALIZE, ti_ptr);
MapScreenTreeGadgets(*ti_ptr);
+ HandleChooseTree(0, 0, 0, 0, MB_MENU_INITIALIZE, ti_ptr);
DrawMaskedBorder(fade_mask);
boolean scrollbar_needed = (num_entries > NUM_MENU_ENTRIES_ON_SCREEN);
int scrollbar_xpos = SC_SCROLLBAR_XPOS + menu.scrollbar_xoffset;
int screen_width = (scrollbar_needed ? scrollbar_xpos : SXSIZE);
- int font_nr = FONT_TEXT_1;
- int font_xoffset = getFontBitmapInfo(font_nr)->draw_xoffset;
int i;
char *title_string = NULL;
int yoffset_sets = MENU_TITLE1_YPOS;
{
TreeInfo *node, *node_first;
int entry_pos = first_entry + i;
+
+ node_first = getTreeInfoFirstGroupEntry(ti);
+ node = getTreeInfoFromPos(node_first, entry_pos);
+
+ int font_nr = MENU_CHOOSE_TREE_FONT(node->color);
+ int font_xoffset = getFontBitmapInfo(font_nr)->draw_xoffset;
int xpos = MENU_SCREEN_START_XPOS;
int ypos = MENU_SCREEN_START_YPOS + i;
int startx = amSX + xpos * 32;
int max_buffer_len = max_text_size / getFontWidth(font_nr);
char buffer[max_buffer_len + 1];
- node_first = getTreeInfoFirstGroupEntry(ti);
- node = getTreeInfoFromPos(node_first, entry_pos);
-
strncpy(buffer, node->name, max_buffer_len);
buffer[max_buffer_len] = '\0';
- DrawText(startx, starty, buffer, font_nr + node->color);
+ DrawText(startx, starty, buffer, font_nr);
if (node->parent_link)
initCursor(i, IMG_MENU_BUTTON_LEAVE_MENU);
initCursor(i, IMG_MENU_BUTTON_ENTER_MENU);
else
initCursor(i, IMG_MENU_BUTTON);
+
+ if (game_status == GAME_MODE_NAMES)
+ drawChooseTreeEdit(i, FALSE);
}
redraw_mask |= REDRAW_FIELD;
TreeInfo **ti_ptr)
{
TreeInfo *ti = *ti_ptr;
+ boolean has_scrollbar = screen_gadget[SCREEN_CTRL_ID_SCROLL_VERTICAL]->mapped;
+ int mx_scrollbar = screen_gadget[SCREEN_CTRL_ID_SCROLL_VERTICAL]->x;
+ int mx_right_border = (has_scrollbar ? mx_scrollbar : SX + SXSIZE);
+ int sx1_edit_name = getChooseTreeEditXPos(POS_LEFT);
+ int sx2_edit_name = getChooseTreeEditXPos(POS_RIGHT);
int x = 0;
int y = ti->cl_cursor;
int step = (button == 1 ? 1 : button == 2 ? 5 : 10);
if (button == MB_MENU_INITIALIZE)
{
int num_entries = numTreeInfoInGroup(ti);
- int entry_pos = posTreeInfo(ti);
+ int entry_pos = getPosFromTreeInfo(ti);
align_xoffset = getAlignXOffsetFromTreeInfo(ti);
align_yoffset = getAlignYOffsetFromTreeInfo(ti);
{
x = (mx - amSX) / 32;
y = (my - amSY) / 32 - MENU_SCREEN_START_YPOS;
+
+ if (game_status == GAME_MODE_NAMES)
+ drawChooseTreeEdit(ti->cl_cursor, FALSE);
}
else if (dx || dy) // keyboard or scrollbar/scrollbutton input
{
if (!anyScrollbarGadgetActive() &&
IN_VIS_MENU(x, y) &&
- mx < screen_gadget[SCREEN_CTRL_ID_SCROLL_VERTICAL]->x &&
+ mx < mx_right_border &&
y >= 0 && y < num_page_entries)
{
if (button)
{
+ if (game_status == GAME_MODE_NAMES)
+ {
+ if (mx >= sx1_edit_name && mx <= sx2_edit_name)
+ drawChooseTreeEdit(y, TRUE);
+ }
+
if (y != ti->cl_cursor)
{
PlaySound(SND_MENU_ITEM_ACTIVATING);
HandleMainMenu_SelectLevel(0, 0, new_level_nr);
}
+ else if (game_status == GAME_MODE_NAMES)
+ {
+ if (mx >= sx1_edit_name && mx <= sx2_edit_name)
+ {
+ SetGameStatus(GAME_MODE_PSEUDO_TYPENAMES);
+
+ DrawTypeName();
+
+ return;
+ }
+
+ // change active user to selected user
+ user.nr = entry_pos;
+
+ // save number of new active user
+ SaveUserSetup();
+
+ // load setup of new active user
+ LoadSetup();
+
+ // load last level set of new active user
+ LoadLevelSetup_LastSeries();
+ LoadLevelSetup_SeriesInfo();
+
+ TapeErase();
+
+ ToggleFullscreenIfNeeded();
+ ChangeWindowScalingIfNeeded();
+
+ ChangeCurrentArtworkIfNeeded(ARTWORK_TYPE_GRAPHICS);
+ ChangeCurrentArtworkIfNeeded(ARTWORK_TYPE_SOUNDS);
+ ChangeCurrentArtworkIfNeeded(ARTWORK_TYPE_MUSIC);
+ }
SetGameStatus(GAME_MODE_MAIN);
}
}
+void DrawChoosePlayerName(void)
+{
+ int i;
+
+ FadeMenuSoundsAndMusic();
+
+ if (player_name != NULL)
+ {
+ freeTreeInfo(player_name);
+
+ player_name = NULL;
+ }
+
+ for (i = 0; i < MAX_PLAYER_NAMES; i++)
+ {
+ TreeInfo *ti = newTreeInfo_setDefaults(TREE_TYPE_PLAYER_NAME);
+ char identifier[32], name[MAX_PLAYER_NAME_LEN + 1];
+ int value = i;
+
+ ti->node_top = &player_name;
+ ti->sort_priority = 10000 + value;
+ ti->color = getPlayerNameColor(global.user_names[i]);
+
+ snprintf(identifier, sizeof(identifier), "%d", value);
+ snprintf(name, sizeof(name), "%s", global.user_names[i]);
+
+ setString(&ti->identifier, identifier);
+ setString(&ti->name, name);
+ setString(&ti->name_sorting, name);
+
+ pushTreeInfo(&player_name, ti);
+ }
+
+ // sort player entries by player number
+ sortTreeInfo(&player_name);
+
+ // set current player entry to selected player entry
+ player_name_current =
+ getTreeInfoFromIdentifier(player_name, i_to_a(user.nr));
+
+ // if that fails, set current player name to first available name
+ if (player_name_current == NULL)
+ player_name_current = player_name;
+
+ DrawChooseTree(&player_name_current);
+
+ PlayMenuSoundsAndMusic();
+}
+
+void HandleChoosePlayerName(int mx, int my, int dx, int dy, int button)
+{
+ HandleChooseTree(mx, my, dx, dy, button, &player_name_current);
+}
+
void DrawChooseLevelSet(void)
{
FadeMenuSoundsAndMusic();
for (i = leveldir_current->first_level; i <= leveldir_current->last_level;i++)
{
TreeInfo *ti = newTreeInfo_setDefaults(TREE_TYPE_LEVEL_NR);
- char identifier[32], name[32];
+ char identifier[32], name[64];
int value = i;
// temporarily load level info to get level name
FadeSound(SND_BACKGROUND_SCORES);
- if (game_status_last_screen == GAME_MODE_PLAYING &&
+ if (button == MB_MENU_CHOICE &&
+ game_status_last_screen == GAME_MODE_PLAYING &&
setup.auto_play_next_level && setup.increment_levels &&
level_nr < leveldir_current->last_level &&
!network_playing)
DrawSetupScreen();
}
+static void execSetupEngines(void)
+{
+ setup_mode = SETUP_MODE_ENGINES;
+
+ DrawSetupScreen();
+}
+
static void execSetupEditor(void)
{
setup_mode = SETUP_MODE_EDITOR;
if (setup_mode == SETUP_MODE_CHOOSE_WINDOW_SIZE)
execSetupGraphics_setWindowSizes(FALSE);
+ // update "setup.vsync_mode" from list selection
+ // (in this case, vsync mode was changed on setup screen)
+ if (setup_mode == SETUP_MODE_CHOOSE_VSYNC)
+ execSetupGraphics_setVsyncModes(FALSE);
+
// update list selection from "setup.window_scaling_percent"
// (window scaling may have changed by resizing the window)
execSetupGraphics_setWindowSizes(TRUE);
+ // update list selection from "setup.vsync_mode"
+ // (vsync_mode may have changed by re-creating the renderer)
+ execSetupGraphics_setVsyncModes(TRUE);
+
execSetupGraphics_setScalingTypes();
execSetupGraphics_setRenderingModes();
- execSetupGraphics_setVsyncModes(FALSE);
setup_mode = SETUP_MODE_GRAPHICS;
ModifyGameSpeedIfNeeded();
// window scaling may have changed at this point
- ToggleFullscreenOrChangeWindowScalingIfNeeded();
+ ChangeWindowScalingIfNeeded();
// window scaling quality may have changed at this point
if (!strEqual(setup.window_scaling_quality, video.window_scaling_quality))
// screen rendering mode may have changed at this point
SDLSetScreenRenderingMode(setup.screen_rendering_mode);
+ int setup_vsync_mode = VSYNC_MODE_STR_TO_INT(setup.vsync_mode);
+ int video_vsync_mode = video.vsync_mode;
+
// screen vsync mode may have changed at this point
- SDLSetScreenVsyncMode(setup.vsync_mode);
+ ChangeVsyncModeIfNeeded();
+
+ // check if setting vsync mode to selected value failed
+ if (setup_vsync_mode != video_vsync_mode &&
+ setup_vsync_mode != video.vsync_mode)
+ {
+ // changing vsync mode to selected value failed -- reset displayed value
+ execSetupGraphics_setVsyncModes(TRUE);
+
+ Request("Setting VSync failed!", REQ_CONFIRM);
+
+ DrawSetupScreen();
+ }
}
static void execSetupChooseWindowSize(void)
static void execSetupArtwork(void)
{
#if 0
- printf("::: '%s', '%s', '%s'\n",
- artwork.gfx_current->subdir,
- artwork.gfx_current->fullpath,
- artwork.gfx_current->basepath);
+ Debug("screens:execSetupArtwork", "'%s', '%s', '%s'",
+ artwork.gfx_current->subdir,
+ artwork.gfx_current->fullpath,
+ artwork.gfx_current->basepath);
#endif
setup.graphics_set = artwork.gfx_current->identifier;
{ &setup.touch.grid_ysize[1], &grid_size_text[1][1] },
{ &setup.internal.menu_game, execSetupGame },
+ { &setup.internal.menu_engines, execSetupEngines },
{ &setup.internal.menu_editor, execSetupEditor },
{ &setup.internal.menu_graphics, execSetupGraphics },
{ &setup.internal.menu_sound, execSetupSound },
static struct TokenInfo setup_info_main[] =
{
{ TYPE_ENTER_MENU, execSetupGame, STR_SETUP_GAME },
+ { TYPE_ENTER_MENU, execSetupEngines, STR_SETUP_ENGINES },
{ TYPE_ENTER_MENU, execSetupEditor, STR_SETUP_EDITOR },
{ TYPE_ENTER_MENU, execSetupGraphics, STR_SETUP_GRAPHICS },
{ TYPE_ENTER_MENU, execSetupSound, STR_SETUP_SOUND },
{ TYPE_PLAYER, &setup.network_player_nr,"Preferred Network Player:" },
{ TYPE_TEXT_INPUT, execGadgetNetworkServer, "Network Server Hostname:" },
{ TYPE_STRING, &network_server_text, "" },
+ { TYPE_SWITCH, &setup.multiple_users, "Multiple Users/Teams:" },
{ TYPE_YES_NO, &setup.input_on_focus, "Only Move Focussed Player:" },
{ TYPE_SWITCH, &setup.time_limit, "Time Limit:" },
{ TYPE_SWITCH, &setup.handicap, "Handicap:" },
{ 0, NULL, NULL }
};
+static struct TokenInfo setup_info_engines[] =
+{
+ { TYPE_HEADLINE, NULL, "Emerald Mine" },
+ { TYPE_SWITCH, &setup.forced_scroll_delay, "Scroll Delay:" },
+ { TYPE_ECS_AGA, &setup.prefer_aga_graphics, "Amiga Graphics Chipset:" },
+ { TYPE_SWITCH, &setup.prefer_lowpass_sounds,"Low-Pass Filter Sounds:" },
+ { TYPE_SWITCH, &setup.prefer_extra_panel_items,"Show Dynamite and Keys:" },
+ { TYPE_EMPTY, NULL, "" },
+ { TYPE_HEADLINE, NULL, "Supaplex" },
+ { TYPE_SWITCH, &setup.sp_show_border_elements, "Border Elements:" },
+ { TYPE_EMPTY, NULL, "" },
+ { TYPE_LEAVE_MENU, execSetupMain, "Back" },
+
+ { 0, NULL, NULL }
+};
+
static struct TokenInfo setup_info_editor[] =
{
#if 0
{ TYPE_SWITCH, &setup.quick_doors, "Quick Menu Doors:" },
{ TYPE_SWITCH, &setup.show_titlescreen,"Show Title Screens:" },
{ TYPE_SWITCH, &setup.toons, "Show Menu Animations:" },
- { TYPE_ECS_AGA, &setup.prefer_aga_graphics,"EMC graphics preference:" },
- { TYPE_SWITCH, &setup.sp_show_border_elements,"Supaplex Border Elements:" },
{ TYPE_SWITCH, &setup.small_game_graphics, "Small Game Graphics:" },
+ { TYPE_YES_NO_AUTO, &setup.debug.xsn_mode, debug_xsn_mode },
{ TYPE_EMPTY, NULL, "" },
{ TYPE_LEAVE_MENU, execSetupMain, "Back" },
if (startx + font_xoffset < text_startx + text_width + text_font_xoffset)
{
+ // when using narrow font, left-shifting text "auto" not needed
+ if (type & TYPE_YES_NO_AUTO)
+ xpos += 1;
+
xpos += 1;
startx = mSX + xpos * 32;
// fullscreen state may have changed at this point
if (si->value == &setup.fullscreen)
- ToggleFullscreenOrChangeWindowScalingIfNeeded();
+ ToggleFullscreenIfNeeded();
// network mode may have changed at this point
if (si->value == &setup.network_mode)
setup_info = setup_info_game;
title_string = STR_SETUP_GAME;
}
+ else if (setup_mode == SETUP_MODE_ENGINES)
+ {
+ setup_info = setup_info_engines;
+ title_string = STR_SETUP_ENGINES;
+ }
else if (setup_mode == SETUP_MODE_EDITOR)
{
setup_info = setup_info_editor;
Event event;
int alpha = 200, alpha_step = -1;
int alpha_ticks = 0;
- char mapping[4096], temp[4096];
+ char mapping[4096], temp[256];
int font_name = MENU_SETUP_FONT_TITLE;
int font_info = MENU_SETUP_FONT_TEXT;
int spacing_name = menu.line_spacing_setup[SETUP_MODE_INPUT];
#if DEBUG_JOYSTICKS
// print info about the joystick we are watching
- Error(ERR_DEBUG, "watching joystick %d: (%s)\n",
+ Debug("joystick", "watching joystick %d: (%s)",
SDL_JoystickInstanceID(joystick), name);
- Error(ERR_DEBUG, "joystick has %d axes, %d hats, %d balls, and %d buttons\n",
+ Debug("joystick", "joystick has %d axes, %d hats, %d balls, and %d buttons",
SDL_JoystickNumAxes(joystick), SDL_JoystickNumHats(joystick),
SDL_JoystickNumBalls(joystick), SDL_JoystickNumButtons(joystick));
#endif
if (success)
{
#if DEBUG_JOYSTICKS
- Error(ERR_DEBUG, "New game controller mapping:\n\n%s\n\n", mapping);
+ Debug("joystick", "New game controller mapping:\n\n%s\n\n", mapping);
#endif
// activate mapping for this game
DrawSetupScreen_Input();
}
+static void MapScreenMenuGadgets_OverlayTouchButtons(int y)
+{
+ if (y < video.screen_height / 3)
+ {
+ // remap touch gadgets to access upper part of the screen
+ UnmapScreenMenuGadgets(SCREEN_MASK_TOUCH);
+ MapScreenMenuGadgets(SCREEN_MASK_TOUCH2);
+ }
+ else if (y > 2 * video.screen_height / 3)
+ {
+ // remap touch gadgets to access lower part of the screen
+ MapScreenMenuGadgets(SCREEN_MASK_TOUCH);
+ UnmapScreenMenuGadgets(SCREEN_MASK_TOUCH2);
+ }
+}
+
static boolean ConfigureVirtualButtonsMain(void)
{
static char *customize_step_text[] =
CHAR_GRID_BUTTON_SNAP,
CHAR_GRID_BUTTON_DROP
};
+ enum
+ {
+ ACTION_NONE,
+ ACTION_ESCAPE,
+ ACTION_BACK,
+ ACTION_NEXT
+ };
int font_nr = FONT_INPUT_1_ACTIVE;
int font_height = getFontHeight(font_nr);
int ypos1 = SYSIZE / 2 - font_height * 2;
overlay.grid_button_highlight = grid_button[step_nr];
+ UnmapAllGadgets();
+
FadeSetEnterMenu();
FadeOut(REDRAW_FIELD);
SetOverlayShowGrid(TRUE);
+ // map gadgets for setup touch buttons menu screen
+ MapScreenMenuGadgets(SCREEN_MASK_TOUCH);
+
while (!finished)
{
Event event;
while (NextValidEvent(&event))
{
+ int action = ACTION_NONE;
+
+ // ---------- handle events and set the resulting action ----------
+
switch (event.type)
{
+ case EVENT_USER:
+ {
+ UserEvent *user = (UserEvent *)&event;
+ int id = user->value1;
+
+ action = (id == SCREEN_CTRL_ID_TOUCH_PREV_PAGE ||
+ id == SCREEN_CTRL_ID_TOUCH_PREV_PAGE2 ? ACTION_BACK :
+ id == SCREEN_CTRL_ID_TOUCH_NEXT_PAGE ||
+ id == SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2 ? ACTION_NEXT :
+ ACTION_NONE);
+ }
+ break;
+
case EVENT_KEYPRESS:
{
Key key = GetEventKey((KeyEvent *)&event, FALSE);
- // press 'Escape' to abort and keep the old key bindings
- if (key == KSYM_Escape)
- {
- for (x = 0; x < MAX_GRID_XSIZE; x++)
- for (y = 0; y < MAX_GRID_YSIZE; y++)
- overlay.grid_button[x][y] = grid_button_old[x][y];
-
- FadeSkipNextFadeIn();
-
- finished = TRUE;
-
- break;
- }
-
- // press 'Enter' to keep the existing key binding
- if (key == KSYM_Return ||
- key == KSYM_Menu ||
- key == KSYM_space)
- {
- step_nr++;
- }
- else if (key == KSYM_BackSpace ||
- key == KSYM_Back)
- {
- if (step_nr == 0)
- {
- FadeSkipNextFadeIn();
-
- finished = TRUE;
-
- break;
- }
-
- step_nr--;
- }
- else
- {
- break;
- }
-
- // all virtual buttons configured
- if (step_nr == 6)
- {
- finished = TRUE;
- success = TRUE;
-
- break;
- }
-
- for (x = 0; x < MAX_GRID_XSIZE; x++)
- for (y = 0; y < MAX_GRID_YSIZE; y++)
- grid_button_tmp[x][y] = overlay.grid_button[x][y];
-
- overlay.grid_button_highlight = grid_button[step_nr];
-
- // query next virtual button
-
- ClearField();
-
- DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, "Virtual Buttons");
- DrawTextSCentered(ypos1, font_nr, "Select tiles to");
- DrawTextSCentered(ypos2, font_nr, customize_step_text[step_nr]);
+ action = (key == KSYM_Escape ? ACTION_ESCAPE :
+ key == KSYM_BackSpace ||
+ key == KSYM_Back ? ACTION_BACK :
+ key == KSYM_Return ||
+ key == KSYM_Menu ||
+ key == KSYM_space ? ACTION_NEXT :
+ ACTION_NONE);
}
break;
{
ButtonEvent *button = (ButtonEvent *)&event;
+ motion_status = FALSE;
+
+ if (button->type == EVENT_BUTTONPRESS)
+ button_status = button->button;
+ else
+ button_status = MB_RELEASED;
+
+ if (HandleGadgets(button->x, button->y, button_status))
+ {
+ // do not handle this button event anymore
+ break;
+ }
+
button->x += video.screen_xoffset;
button->y += video.screen_yoffset;
if (button->type == EVENT_BUTTONPRESS)
{
- button_status = button->button;
-
grid_button_draw =
(overlay.grid_button[x][y] != grid_button[step_nr] ?
grid_button[step_nr] : CHAR_GRID_BUTTON_NONE);
set_grid_button = TRUE;
}
- else
- {
- button_status = MB_RELEASED;
- }
+
+ MapScreenMenuGadgets_OverlayTouchButtons(button->y);
}
break;
{
MotionEvent *motion = (MotionEvent *)&event;
+ motion_status = TRUE;
+
+ if (HandleGadgets(motion->x, motion->y, button_status))
+ {
+ // do not handle this button event anymore
+ break;
+ }
+
motion->x += video.screen_xoffset;
motion->y += video.screen_yoffset;
y = motion->y * overlay.grid_ysize / video.screen_height;
set_grid_button = TRUE;
+
+ MapScreenMenuGadgets_OverlayTouchButtons(motion->y);
}
break;
break;
}
+ // ---------- perform action set by handling events ----------
+
+ if (action == ACTION_ESCAPE)
+ {
+ // abort and restore the old key bindings
+
+ for (x = 0; x < MAX_GRID_XSIZE; x++)
+ for (y = 0; y < MAX_GRID_YSIZE; y++)
+ overlay.grid_button[x][y] = grid_button_old[x][y];
+
+ FadeSkipNextFadeIn();
+
+ finished = TRUE;
+ }
+ else if (action == ACTION_BACK)
+ {
+ // keep the configured key bindings and go to previous page
+
+ step_nr--;
+
+ if (step_nr < 0)
+ {
+ FadeSkipNextFadeIn();
+
+ finished = TRUE;
+ }
+ }
+ else if (action == ACTION_NEXT)
+ {
+ // keep the configured key bindings and go to next page
+
+ step_nr++;
+
+ // all virtual buttons configured
+ if (step_nr == 6)
+ {
+ finished = TRUE;
+ success = TRUE;
+ }
+ }
+
+ if (action != ACTION_NONE && !finished)
+ {
+ for (x = 0; x < MAX_GRID_XSIZE; x++)
+ for (y = 0; y < MAX_GRID_YSIZE; y++)
+ grid_button_tmp[x][y] = overlay.grid_button[x][y];
+
+ overlay.grid_button_highlight = grid_button[step_nr];
+
+ // configure next virtual button
+
+ ClearField();
+
+ DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, "Virtual Buttons");
+ DrawTextSCentered(ypos1, font_nr, "Select tiles to");
+ DrawTextSCentered(ypos2, font_nr, customize_step_text[step_nr]);
+ }
+
if (set_grid_button)
{
overlay.grid_button[x][y] =
{
boolean success = ConfigureVirtualButtonsMain();
+ UnmapScreenMenuGadgets(SCREEN_MASK_TOUCH |
+ SCREEN_MASK_TOUCH2);
+
if (success)
{
int font_nr = FONT_TITLE_1;
GameActions(); // main game loop
if (tape.auto_play && !tape.playing)
- AutoPlayTape(); // continue automatically playing next tape
+ AutoPlayTapes(); // continue automatically playing next tape
}
// ---------- new screen button stuff --------------------------------------
-static void getScreenMenuButtonPos(int *x, int *y, int gadget_id)
-{
- switch (gadget_id)
- {
- case SCREEN_CTRL_ID_PREV_LEVEL:
- *x = mSX + GDI_ACTIVE_POS(menu.main.button.prev_level.x);
- *y = mSY + GDI_ACTIVE_POS(menu.main.button.prev_level.y);
- break;
-
- case SCREEN_CTRL_ID_NEXT_LEVEL:
- *x = mSX + GDI_ACTIVE_POS(menu.main.button.next_level.x);
- *y = mSY + GDI_ACTIVE_POS(menu.main.button.next_level.y);
- break;
-
- case SCREEN_CTRL_ID_FIRST_LEVEL:
- *x = mSX + GDI_ACTIVE_POS(menu.main.button.first_level.x);
- *y = mSY + GDI_ACTIVE_POS(menu.main.button.first_level.y);
- break;
-
- case SCREEN_CTRL_ID_LAST_LEVEL:
- *x = mSX + GDI_ACTIVE_POS(menu.main.button.last_level.x);
- *y = mSY + GDI_ACTIVE_POS(menu.main.button.last_level.y);
- break;
-
- case SCREEN_CTRL_ID_LEVEL_NUMBER:
- *x = mSX + GDI_ACTIVE_POS(menu.main.button.level_number.x);
- *y = mSY + GDI_ACTIVE_POS(menu.main.button.level_number.y);
- break;
-
- case SCREEN_CTRL_ID_PREV_PLAYER:
- *x = mSX + TILEX * 10;
- *y = mSY + TILEY * MENU_SCREEN_START_YPOS;
- break;
-
- case SCREEN_CTRL_ID_NEXT_PLAYER:
- *x = mSX + TILEX * 12;
- *y = mSY + TILEY * MENU_SCREEN_START_YPOS;
- break;
-
- case SCREEN_CTRL_ID_INSERT_SOLUTION:
- *x = mSX + GDI_ACTIVE_POS(menu.main.button.insert_solution.x);
- *y = mSY + GDI_ACTIVE_POS(menu.main.button.insert_solution.y);
- break;
-
- case SCREEN_CTRL_ID_PLAY_SOLUTION:
- *x = mSX + GDI_ACTIVE_POS(menu.main.button.play_solution.x);
- *y = mSY + GDI_ACTIVE_POS(menu.main.button.play_solution.y);
- break;
-
- default:
- Error(ERR_EXIT, "unknown gadget ID %d", gadget_id);
- }
-}
-
static struct
{
int gfx_unpressed, gfx_pressed;
- void (*get_gadget_position)(int *, int *, int);
+ struct MenuPosInfo *pos;
+ boolean *check_value;
int gadget_id;
int screen_mask;
unsigned int event_mask;
+ boolean is_touch_button;
char *infotext;
} menubutton_info[NUM_SCREEN_MENUBUTTONS] =
{
{
IMG_MENU_BUTTON_PREV_LEVEL, IMG_MENU_BUTTON_PREV_LEVEL_ACTIVE,
- getScreenMenuButtonPos,
+ &menu.main.button.prev_level, NULL,
SCREEN_CTRL_ID_PREV_LEVEL,
SCREEN_MASK_MAIN,
GD_EVENT_PRESSED | GD_EVENT_REPEATED,
- "previous level"
+ FALSE, "previous level"
},
{
IMG_MENU_BUTTON_NEXT_LEVEL, IMG_MENU_BUTTON_NEXT_LEVEL_ACTIVE,
- getScreenMenuButtonPos,
+ &menu.main.button.next_level, NULL,
SCREEN_CTRL_ID_NEXT_LEVEL,
SCREEN_MASK_MAIN,
GD_EVENT_PRESSED | GD_EVENT_REPEATED,
- "next level"
+ FALSE, "next level"
},
{
IMG_MENU_BUTTON_FIRST_LEVEL, IMG_MENU_BUTTON_FIRST_LEVEL_ACTIVE,
- getScreenMenuButtonPos,
+ &menu.main.button.first_level, NULL,
SCREEN_CTRL_ID_FIRST_LEVEL,
SCREEN_MASK_MAIN,
GD_EVENT_RELEASED,
- "first level"
+ FALSE, "first level"
},
{
IMG_MENU_BUTTON_LAST_LEVEL, IMG_MENU_BUTTON_LAST_LEVEL_ACTIVE,
- getScreenMenuButtonPos,
+ &menu.main.button.last_level, NULL,
SCREEN_CTRL_ID_LAST_LEVEL,
SCREEN_MASK_MAIN,
GD_EVENT_RELEASED,
- "last level"
+ FALSE, "last level"
},
{
IMG_MENU_BUTTON_LEVEL_NUMBER, IMG_MENU_BUTTON_LEVEL_NUMBER_ACTIVE,
- getScreenMenuButtonPos,
+ &menu.main.button.level_number, NULL,
SCREEN_CTRL_ID_LEVEL_NUMBER,
SCREEN_MASK_MAIN,
GD_EVENT_RELEASED,
- "level number"
+ FALSE, "level number"
},
{
IMG_MENU_BUTTON_LEFT, IMG_MENU_BUTTON_LEFT_ACTIVE,
- getScreenMenuButtonPos,
+ &menu.setup.button.prev_player, NULL,
SCREEN_CTRL_ID_PREV_PLAYER,
SCREEN_MASK_INPUT,
GD_EVENT_PRESSED | GD_EVENT_REPEATED,
- "previous player"
+ FALSE, "previous player"
},
{
IMG_MENU_BUTTON_RIGHT, IMG_MENU_BUTTON_RIGHT_ACTIVE,
- getScreenMenuButtonPos,
+ &menu.setup.button.next_player, NULL,
SCREEN_CTRL_ID_NEXT_PLAYER,
SCREEN_MASK_INPUT,
GD_EVENT_PRESSED | GD_EVENT_REPEATED,
- "next player"
+ FALSE, "next player"
},
{
IMG_MENU_BUTTON_INSERT_SOLUTION, IMG_MENU_BUTTON_INSERT_SOLUTION_ACTIVE,
- getScreenMenuButtonPos,
+ &menu.main.button.insert_solution, NULL,
SCREEN_CTRL_ID_INSERT_SOLUTION,
SCREEN_MASK_MAIN_HAS_SOLUTION,
GD_EVENT_RELEASED,
- "insert solution tape"
+ FALSE, "insert solution tape"
},
{
IMG_MENU_BUTTON_PLAY_SOLUTION, IMG_MENU_BUTTON_PLAY_SOLUTION_ACTIVE,
- getScreenMenuButtonPos,
+ &menu.main.button.play_solution, NULL,
SCREEN_CTRL_ID_PLAY_SOLUTION,
SCREEN_MASK_MAIN_HAS_SOLUTION,
GD_EVENT_RELEASED,
- "play solution tape"
+ FALSE, "play solution tape"
+ },
+ {
+ IMG_MENU_BUTTON_SWITCH_ECS_AGA, IMG_MENU_BUTTON_SWITCH_ECS_AGA_ACTIVE,
+ &menu.main.button.switch_ecs_aga, &setup.prefer_aga_graphics,
+ SCREEN_CTRL_ID_SWITCH_ECS_AGA,
+ SCREEN_MASK_MAIN,
+ GD_EVENT_RELEASED | GD_EVENT_OFF_BORDERS,
+ FALSE, "switch ECS/AGA chipset"
+ },
+ {
+ IMG_MENU_BUTTON_TOUCH_BACK, IMG_MENU_BUTTON_TOUCH_BACK,
+ &menu.setup.button.touch_back, NULL,
+ SCREEN_CTRL_ID_TOUCH_PREV_PAGE,
+ SCREEN_MASK_TOUCH,
+ GD_EVENT_RELEASED,
+ TRUE, "previous page"
+ },
+ {
+ IMG_MENU_BUTTON_TOUCH_NEXT, IMG_MENU_BUTTON_TOUCH_NEXT,
+ &menu.setup.button.touch_next, NULL,
+ SCREEN_CTRL_ID_TOUCH_NEXT_PAGE,
+ SCREEN_MASK_TOUCH,
+ GD_EVENT_RELEASED,
+ TRUE, "next page"
+ },
+ {
+ IMG_MENU_BUTTON_TOUCH_BACK2, IMG_MENU_BUTTON_TOUCH_BACK2,
+ &menu.setup.button.touch_back2, NULL,
+ SCREEN_CTRL_ID_TOUCH_PREV_PAGE2,
+ SCREEN_MASK_TOUCH2,
+ GD_EVENT_RELEASED,
+ TRUE, "previous page"
+ },
+ {
+ IMG_MENU_BUTTON_TOUCH_NEXT2, IMG_MENU_BUTTON_TOUCH_NEXT2,
+ &menu.setup.button.touch_next2, NULL,
+ SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2,
+ SCREEN_MASK_TOUCH2,
+ GD_EVENT_RELEASED,
+ TRUE, "next page"
},
};
for (i = 0; i < NUM_SCREEN_MENUBUTTONS; i++)
{
+ struct MenuPosInfo *pos = menubutton_info[i].pos;
+ boolean is_touch_button = menubutton_info[i].is_touch_button;
+ boolean is_check_button = menubutton_info[i].check_value != NULL;
Bitmap *gd_bitmap_unpressed, *gd_bitmap_pressed;
int gfx_unpressed, gfx_pressed;
int x, y, width, height;
int gd_x1, gd_x2, gd_y1, gd_y2;
+ int gd_x1a, gd_x2a, gd_y1a, gd_y2a;
int id = menubutton_info[i].gadget_id;
+ int type = GD_TYPE_NORMAL_BUTTON;
+ boolean checked = FALSE;
event_mask = menubutton_info[i].event_mask;
- menubutton_info[i].get_gadget_position(&x, &y, id);
+ x = (is_touch_button ? pos->x : mSX + GDI_ACTIVE_POS(pos->x));
+ y = (is_touch_button ? pos->y : mSY + GDI_ACTIVE_POS(pos->y));
width = graphic_info[menubutton_info[i].gfx_pressed].width;
height = graphic_info[menubutton_info[i].gfx_pressed].height;
gd_y1 = graphic_info[gfx_unpressed].src_y;
gd_x2 = graphic_info[gfx_pressed].src_x;
gd_y2 = graphic_info[gfx_pressed].src_y;
+ gd_x1a = gd_x1;
+ gd_y1a = gd_y1;
+ gd_x2a = gd_x2;
+ gd_y2a = gd_y2;
+
+ if (is_touch_button)
+ {
+ gd_x2 += graphic_info[gfx_pressed].pressed_xoffset;
+ gd_y2 += graphic_info[gfx_pressed].pressed_yoffset;
+ }
+
+ if (is_check_button)
+ {
+ gd_x1a += graphic_info[gfx_unpressed].active_xoffset;
+ gd_y1a += graphic_info[gfx_unpressed].active_yoffset;
+ gd_x2a += graphic_info[gfx_pressed].active_xoffset;
+ gd_y2a += graphic_info[gfx_pressed].active_yoffset;
+
+ type = GD_TYPE_CHECK_BUTTON;
+ checked = *menubutton_info[i].check_value;
+ }
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_Y, y,
GDI_WIDTH, width,
GDI_HEIGHT, height,
- GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
+ GDI_TYPE, type,
GDI_STATE, GD_BUTTON_UNPRESSED,
+ GDI_CHECKED, checked,
GDI_DESIGN_UNPRESSED, gd_bitmap_unpressed, gd_x1, gd_y1,
GDI_DESIGN_PRESSED, gd_bitmap_pressed, gd_x2, gd_y2,
+ GDI_ALT_DESIGN_UNPRESSED, gd_bitmap_unpressed, gd_x1a, gd_y1a,
+ GDI_ALT_DESIGN_PRESSED, gd_bitmap_pressed, gd_x2a, gd_y2a,
GDI_DIRECT_DRAW, FALSE,
+ GDI_OVERLAY_TOUCH_BUTTON, is_touch_button,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_ACTION, HandleScreenGadgets,
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
screen_gadget[id] = gi;
}
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
screen_gadget[id] = gi;
}
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
screen_gadget[id] = gi;
}
GDI_END);
if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Fail("cannot create gadget");
screen_gadget[id] = gi;
}
FreeGadget(screen_gadget[i]);
}
-void MapScreenMenuGadgets(int screen_mask)
+static void MapScreenMenuGadgets(int screen_mask)
{
int i;
}
}
-void UpdateScreenMenuGadgets(int screen_mask, boolean map_gadgets)
+static void UpdateScreenMenuGadgets(int screen_mask, boolean map_gadgets)
{
if (map_gadgets)
MapScreenMenuGadgets(screen_mask);
UnmapScreenMenuGadgets(screen_mask);
}
-void MapScreenGadgets(int num_entries)
+static void MapScreenGadgets(int num_entries)
{
int i;
MapGadget(screen_gadget[scrollbar_info[i].gadget_id]);
}
-void MapScreenTreeGadgets(TreeInfo *ti)
+static void MapScreenTreeGadgets(TreeInfo *ti)
{
MapScreenGadgets(numTreeInfoInGroup(ti));
}
PlaySolutionTape();
break;
+ case SCREEN_CTRL_ID_SWITCH_ECS_AGA:
+ setup.prefer_aga_graphics = !setup.prefer_aga_graphics;
+ DrawMainMenu();
+ break;
+
+ case SCREEN_CTRL_ID_TOUCH_PREV_PAGE:
+ case SCREEN_CTRL_ID_TOUCH_NEXT_PAGE:
+ case SCREEN_CTRL_ID_TOUCH_PREV_PAGE2:
+ case SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2:
+ PushUserEvent(USEREVENT_GADGET_PRESSED, id, 0);
+ break;
+
case SCREEN_CTRL_ID_SCROLL_UP:
- if (game_status == GAME_MODE_LEVELS)
+ if (game_status == GAME_MODE_NAMES)
+ HandleChoosePlayerName(0,0, 0, -1 * SCROLL_LINE, MB_MENU_MARK);
+ else if (game_status == GAME_MODE_LEVELS)
HandleChooseLevelSet(0,0, 0, -1 * SCROLL_LINE, MB_MENU_MARK);
else if (game_status == GAME_MODE_LEVELNR)
HandleChooseLevelNr(0,0, 0, -1 * SCROLL_LINE, MB_MENU_MARK);
break;
case SCREEN_CTRL_ID_SCROLL_DOWN:
- if (game_status == GAME_MODE_LEVELS)
+ if (game_status == GAME_MODE_NAMES)
+ HandleChoosePlayerName(0,0, 0, +1 * SCROLL_LINE, MB_MENU_MARK);
+ else if (game_status == GAME_MODE_LEVELS)
HandleChooseLevelSet(0,0, 0, +1 * SCROLL_LINE, MB_MENU_MARK);
else if (game_status == GAME_MODE_LEVELNR)
HandleChooseLevelNr(0,0, 0, +1 * SCROLL_LINE, MB_MENU_MARK);
break;
case SCREEN_CTRL_ID_SCROLL_VERTICAL:
- if (game_status == GAME_MODE_LEVELS)
+ if (game_status == GAME_MODE_NAMES)
+ HandleChoosePlayerName(0,0,999,gi->event.item_position,MB_MENU_INITIALIZE);
+ else if (game_status == GAME_MODE_LEVELS)
HandleChooseLevelSet(0,0,999,gi->event.item_position,MB_MENU_INITIALIZE);
else if (game_status == GAME_MODE_LEVELNR)
HandleChooseLevelNr(0,0,999,gi->event.item_position,MB_MENU_INITIALIZE);