diff --git a/port/assets/menus/README.md b/port/assets/menus/README.md index 91332b25..34ddc305 100644 --- a/port/assets/menus/README.md +++ b/port/assets/menus/README.md @@ -167,7 +167,10 @@ The port's functions: `port quit game` quits; `port setting load` (on a spinner's `created`) shows its setting's value and `port setting save` (on its `deleted`) writes the value shown to `config.toml`, if it changed. Of the PC version's: `main menu quit game` quits, `profile set edit begin` -begins editing the first player profile, `mouse emit back event` and +begins editing the first player profile (with none it fails, and the main +menu's asks for a new one's name first, as `new game if no plyr profiles` +does, for its `` to make the profile, which the port's `new +campaign decision` then has Settings edit), `mouse emit back event` and `mouse emit x event` push B and X, `emit custom activation event` and `single prev cl item activated` run the screen's or the list's `custom_activation` handlers, and its back handlers go back. Its diff --git a/port/linux/game/menu_functions.c b/port/linux/game/menu_functions.c index 7f9cb55e..76622c83 100644 --- a/port/linux/game/menu_functions.c +++ b/port/linux/game/menu_functions.c @@ -8,8 +8,10 @@ calls them from PC_MENU_FUNCTION_BASE on): - "port quit game" (and the PC version's "main menu quit game") quits, as closing the window does; - the PC version's "profile set edit begin" begins editing the first player - profile, as its settings screens need, and fails with none (its handlers - then open the screens that make one); + profile, as its settings screens need, and fails with none: the main + menu's then asks for a new one's name, as the menu's other items do, and + its handlers open the screens that make the profile ("new campaign + decision", after which Settings' is the one being edited); - "gamespy screen init" hides the server browser's error and filter panels, and the title of the mode "mp type set mode" did not choose (Internet or LAN); @@ -68,6 +70,7 @@ their handlers open opens. #include "interface/event_manager.h" #include "interface/player_ui.h" #include "interface/ui_widget.h" +#include "interface/ui_widget_event_handler_functions.h" #include "main/main.h" #include "networking/network_game_manager.h" #include "saved games/player_profile.h" @@ -112,6 +115,7 @@ boolean ui_widget_port_dispatch_event(struct widget_instance *widget, short even void ui_widget_port_go_back(struct widget_instance *widget); short ui_widget_port_list_index(struct widget_instance *list_widget); boolean ui_widget_port_saved_game(char const **map_name, short *level, short *difficulty); +char const *ui_widget_event_handler_function_name(long function_index); short main_get_solo_level_from_name(char const *name); boolean player_name_clean(wchar_t *name, long count); short players_port_local_player_count(void); @@ -515,6 +519,53 @@ boolean pc_menu_profile_edit_begin(void) return TRUE; } +/* the game's own function of the name (as its tags name it), run for the +widget: for ours of a name of the game's, which do more than it */ +static boolean game_function(char const *name, struct widget_instance *widget, struct event_record *event, + boolean *widget_deleted) +{ + char const *function; + long index; + + for (index = 0; (function = ui_widget_event_handler_function_name(index)) != NULL; index++) + { + if (!strcmp(function, name)) + return ui_widget_event_handler_function_invoke(widget, event, (word)index, widget_deleted); + } + return FALSE; +} + +/* "profile set edit begin": Settings, the main menu's and a game's pause +menu's. With no profile, the main menu's asks for a new one's name, as the +menu's other items do ("new game if no plyr profiles"), and fails: the +screens its handler then opens make the profile and edit it +(new_profile_decision). Without the name asked, they made none, and showed +"new campaign decision" as failed. The pause menu's has no such screens, +and only fails. */ +static boolean profile_edit_begin(struct widget_instance *widget, struct event_record *event, + boolean *widget_deleted) +{ + if (pc_menu_profile_edit_begin()) + return TRUE; + /* (a press: the profile is made on its controller) */ + if (main_menu_is_active() && event && event->controller_index >= 0 && event->controller_index < 4) + game_function("new campaign chosen", widget, event, widget_deleted); + return FALSE; +} + +/* "new campaign decision" (the screen after a new profile's name, each of +the main menu's items having its own): the game's makes the profile, if the +name was entered. Settings' then begins editing it: the PC version's screens +open Settings with nothing more run, and its screen closes at once with no +profile being edited ("close if not editing profile"). */ +static boolean new_profile_decision(struct widget_instance *widget, struct event_record *event, + boolean *widget_deleted) +{ + if (!game_function("new campaign decision", widget, event, widget_deleted)) + return FALSE; + return strcmp(widget->name, "settings_creating_profile") || pc_menu_profile_edit_begin(); +} + /* ---------- the campaign */ /* the rows of its lists (main_menu/new_select/list_item_0 to 10) */ @@ -5338,7 +5389,11 @@ boolean pc_menu_event_function_invoke( } else if (!strcmp(name, "profile set edit begin")) { - return pc_menu_profile_edit_begin(); + return profile_edit_begin(widget, event, widget_deleted); + } + else if (!strcmp(name, "new campaign decision")) + { + return new_profile_decision(widget, event, widget_deleted); } /* (the press posted is the controller's that chose the button: a split screen player's LEAVE is theirs) */ diff --git a/port/linux/game/menu_tags.c b/port/linux/game/menu_tags.c index 5a1e5a7b..9a3ff838 100644 --- a/port/linux/game/menu_tags.c +++ b/port/linux/game/menu_tags.c @@ -384,6 +384,9 @@ static char const *const port_function_names[] = "port password init", "port password edit", "port password join", "port password back", /* (Gamepads' OK in a single-player campaign: pause_settings_patch) */ "port profile settings save", + /* (a new profile's screens: Settings' is then being edited, which the + Xbox's leaves to its own screens) */ + "new campaign decision", }; /* the PC version's game data functions that the Xbox's have not, from