Added coop settings to saved config file

Saves and loads last join IP/port attempt
Made host's port configurable in config file
Made host's save slot configurable in config file
Made host's player interaction setting configurable in config file

Indicated when the client was trying to connect on the join menu.
Fixed join menu display error where the port would disappear
This commit is contained in:
MysterD 2020-09-06 10:31:41 -07:00
parent 51940d6a82
commit bed036bcfb
10 changed files with 97 additions and 34 deletions

View file

@ -635,7 +635,7 @@ u32 determine_knockback_action(struct MarioState *m, UNUSED s32 arg) {
m->forwardVel = mag; m->forwardVel = mag;
if (sign > 0 && terrainIndex == 1) { mag *= -1.0f; } if (sign > 0 && terrainIndex == 1) { mag *= -1.0f; }
m->vel[0] = mag * sins(angleToObject); m->vel[0] = mag * sins(angleToObject);
m->vel[1] = abs(mag); m->vel[1] = (mag < 0) ? -mag : mag;
m->vel[2] = mag * coss(angleToObject); m->vel[2] = mag * coss(angleToObject);
} }
@ -1150,14 +1150,14 @@ static u8 resolve_player_collision(struct MarioState* m, struct MarioState* m2)
f32 marioRelY = localTorso[1] - remoteTorso[1]; f32 marioRelY = localTorso[1] - remoteTorso[1];
if (marioRelY < 0) { marioRelY = -marioRelY; } if (marioRelY < 0) { marioRelY = -marioRelY; }
if (marioRelY >= extentY) { return; } if (marioRelY >= extentY) { return FALSE; }
f32 marioRelX = localTorso[0] - remoteTorso[0]; f32 marioRelX = localTorso[0] - remoteTorso[0];
f32 marioRelZ = localTorso[2] - remoteTorso[2]; f32 marioRelZ = localTorso[2] - remoteTorso[2];
f32 marioDist = sqrtf(sqr(marioRelX) + sqr(marioRelZ)); f32 marioDist = sqrtf(sqr(marioRelX) + sqr(marioRelZ));
if (marioDist >= radius) { return; } if (marioDist >= radius) { return FALSE; }
// bounce // bounce
u32 interaction = determine_interaction(m, m2->marioObj); u32 interaction = determine_interaction(m, m2->marioObj);

View file

@ -22,8 +22,6 @@
#include "text_strings.h" #include "text_strings.h"
#include "game/ingame_menu.h" #include "game/ingame_menu.h"
#include "pc/controller/controller_keyboard.h"
#include "pc/network/network.h"
#include "eu_translation.h" #include "eu_translation.h"
#ifdef VERSION_EU #ifdef VERSION_EU
@ -31,6 +29,11 @@
#define LANGUAGE_FUNCTION sLanguageMode #define LANGUAGE_FUNCTION sLanguageMode
#endif #endif
#include <stdio.h>
#include "pc/configfile.h"
#include "pc/controller/controller_keyboard.h"
#include "pc/network/network.h"
/** /**
* @file file_select.c * @file file_select.c
* This file implements how the file select and it's menus render and function. * This file implements how the file select and it's menus render and function.
@ -404,8 +407,12 @@ void join_server_as_client(void) {
char delims[] = { ' ' }; char delims[] = { ' ' };
// copy input
char buffer[MAX_TEXT_INPUT] = { 0 };
strncpy(buffer, gTextInput, MAX_TEXT_INPUT);
char* text = buffer;
// trim whitespace // trim whitespace
char* text = textInput;
while (*text == ' ') { text++; } while (*text == ' ') { text++; }
// grab IP // grab IP
@ -414,16 +421,23 @@ void join_server_as_client(void) {
exit_join_to_network_menu(); exit_join_to_network_menu();
return; return;
} }
strncpy(configJoinIp, ip, MAX_CONFIG_STRING);
// grab port // grab port
char* port = strtok(NULL, delims); char* port = strtok(NULL, delims);
if (port != NULL && atoi(port) == 0) { if (port != NULL) {
exit_join_to_network_menu(); unsigned int intPort = atoi(port);
return; if (intPort == 0) {
exit_join_to_network_menu();
return;
}
configJoinPort = intPort;
} else {
configJoinPort = DEFAULT_PORT;
} }
keyboard_stop_text_input(); keyboard_stop_text_input();
network_init(NT_CLIENT, textInput, port); network_init(NT_CLIENT, configJoinIp, configJoinPort);
} }
void joined_server_as_client(s16 fileIndex) { void joined_server_as_client(s16 fileIndex) {
@ -467,7 +481,16 @@ void check_network_mode_menu_clicked_buttons(struct Object* networkModeButton) {
play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs); play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs);
sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_GROWING; sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_GROWING;
sSelectedButtonID = buttonID; sSelectedButtonID = buttonID;
// start input
keyboard_start_text_input(TIM_IP, keyboard_exit_join_to_network_menu, join_server_as_client); keyboard_start_text_input(TIM_IP, keyboard_exit_join_to_network_menu, join_server_as_client);
// fill in config ip/port
static u8 openedJoinMenu = FALSE;
if (!openedJoinMenu && strlen(configJoinIp) > 0) {
if (configJoinPort == 0) { configJoinPort = DEFAULT_PORT; }
sprintf(gTextInput, "%s %d", configJoinIp, configJoinPort);
}
} }
sCurrentMenuLevel = MENU_LAYER_SUBMENU; sCurrentMenuLevel = MENU_LAYER_SUBMENU;
@ -494,8 +517,8 @@ void print_network_mode_menu_strings(void) {
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
#define TEXT_HOST 0x11,0x18,0x1C,0x1D,0xFF #define TEXT_HOST 0x11,0x18,0x1C,0x1D,0xFF
#define TEXT_JOIN 0x13,0x18,0x12,0x17,0xFF #define TEXT_JOIN 0x13,0x18,0x12,0x17,0xFF
static unsigned char textNetworkModes[][5] = { { TEXT_HOST }, { TEXT_JOIN } }; static unsigned char textNetworkModes[][5] = { { TEXT_HOST }, { TEXT_JOIN } };
// Print network mode names // Print network mode names
@ -535,9 +558,12 @@ void print_join_mode_menu_strings(void) {
// Print level name // Print level name
print_generic_ascii_string(JOIN_LEVEL_NAME_X, 191 - (12 * 0), "Type or paste the host's IP."); print_generic_ascii_string(JOIN_LEVEL_NAME_X, 191 - (12 * 0), "Type or paste the host's IP.");
print_generic_ascii_string(JOIN_LEVEL_NAME_X, 191 - (12 * 2), textInput); print_generic_ascii_string(JOIN_LEVEL_NAME_X, 191 - (12 * 2), gTextInput);
if (strlen(textInput) > 0) { // Print status
if (networkType == NT_CLIENT) {
print_generic_ascii_string(JOIN_LEVEL_NAME_X, 191 - (12 * 14), "Connecting...");
} else if (strlen(gTextInput) > 0) {
print_generic_ascii_string(JOIN_LEVEL_NAME_X, 191 - (12 * 14), "Press (ENTER) to join."); print_generic_ascii_string(JOIN_LEVEL_NAME_X, 191 - (12 * 14), "Press (ENTER) to join.");
} }
@ -1304,7 +1330,8 @@ void check_sound_mode_menu_clicked_buttons(struct Object *soundModeButton) {
void load_main_menu_save_file(struct Object *fileButton, s32 fileNum) { void load_main_menu_save_file(struct Object *fileButton, s32 fileNum) {
if (fileButton->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) { if (fileButton->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) {
sSelectedFileNum = fileNum; sSelectedFileNum = fileNum;
network_init(NT_SERVER, "", NETWORK_DEFAULT_PORT); configHostSaveSlot = fileNum;
network_init(NT_SERVER, "", configHostPort);
} }
} }
@ -3092,7 +3119,7 @@ s32 lvl_init_menu_values_and_cursor_pos(UNUSED s32 arg, UNUSED s32 unused) {
// immediately jump in // immediately jump in
if (networkType == NT_SERVER) { if (networkType == NT_SERVER) {
sSelectedFileNum = 1; sSelectedFileNum = configHostSaveSlot;
} }
//! no return value //! no return value

View file

@ -57,12 +57,12 @@ void parse_cli_opts(int argc, char* argv[]) {
else if (strcmp(argv[i], "--server") == 0 && (i + 1) < argc) { // Host server else if (strcmp(argv[i], "--server") == 0 && (i + 1) < argc) { // Host server
gCLIOpts.Network = NT_SERVER; gCLIOpts.Network = NT_SERVER;
arg_string("--server <port>", argv[++i], gCLIOpts.NetworkPort, PORT_MAX_LEN); arg_uint("--server <port>", argv[++i], &gCLIOpts.NetworkPort);
} else if (strcmp(argv[i], "--client") == 0 && (i + 2) < argc) { // Join server } else if (strcmp(argv[i], "--client") == 0 && (i + 2) < argc) { // Join server
gCLIOpts.Network = NT_CLIENT; gCLIOpts.Network = NT_CLIENT;
arg_string("--client <ip>", argv[++i], gCLIOpts.JoinIp, IP_MAX_LEN); arg_string("--client <ip>", argv[++i], gCLIOpts.JoinIp, IP_MAX_LEN);
arg_string("--client <port>", argv[++i], gCLIOpts.NetworkPort, PORT_MAX_LEN); arg_uint("--client <port>", argv[++i], &gCLIOpts.NetworkPort);
} else if (strcmp(argv[i], "--cheats") == 0) // Enable cheats menu } else if (strcmp(argv[i], "--cheats") == 0) // Enable cheats menu
Cheats.EnableCheats = true; Cheats.EnableCheats = true;

View file

@ -17,7 +17,7 @@ struct PCCLIOptions {
unsigned int FullScreen; unsigned int FullScreen;
enum NetworkType Network; enum NetworkType Network;
char JoinIp[IP_MAX_LEN]; char JoinIp[IP_MAX_LEN];
char NetworkPort[PORT_MAX_LEN]; unsigned int NetworkPort;
unsigned int PoolSize; unsigned int PoolSize;
char ConfigFile[SYS_MAX_PATH]; char ConfigFile[SYS_MAX_PATH];
char SavePath[SYS_MAX_PATH]; char SavePath[SYS_MAX_PATH];

View file

@ -21,6 +21,7 @@ enum ConfigOptionType {
CONFIG_TYPE_UINT, CONFIG_TYPE_UINT,
CONFIG_TYPE_FLOAT, CONFIG_TYPE_FLOAT,
CONFIG_TYPE_BIND, CONFIG_TYPE_BIND,
CONFIG_TYPE_STRING,
}; };
struct ConfigOption { struct ConfigOption {
@ -29,7 +30,8 @@ struct ConfigOption {
union { union {
bool *boolValue; bool *boolValue;
unsigned int *uintValue; unsigned int *uintValue;
float *floatValue; float* floatValue;
char* stringValue;
}; };
}; };
@ -83,7 +85,7 @@ unsigned int configCameraAggr = 0;
unsigned int configCameraPan = 0; unsigned int configCameraPan = 0;
unsigned int configCameraDegrade = 50; // 0 - 100% unsigned int configCameraDegrade = 50; // 0 - 100%
bool configCameraInvertX = false; bool configCameraInvertX = false;
bool configCameraInvertY = false; bool configCameraInvertY = true;
bool configEnableCamera = true; bool configEnableCamera = true;
bool configCameraAnalog = true; bool configCameraAnalog = true;
bool configCameraMouse = false; bool configCameraMouse = false;
@ -93,6 +95,12 @@ bool configHUD = true;
#ifdef DISCORDRPC #ifdef DISCORDRPC
bool configDiscordRPC = true; bool configDiscordRPC = true;
#endif #endif
// coop-specific
char configJoinIp[MAX_CONFIG_STRING] = "";
unsigned int configJoinPort = DEFAULT_PORT;
unsigned int configHostPort = DEFAULT_PORT;
unsigned int configHostSaveSlot = 1;
unsigned int configPlayerInteraction = 1;
static const struct ConfigOption options[] = { static const struct ConfigOption options[] = {
{.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configWindow.fullscreen}, {.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configWindow.fullscreen},
@ -141,6 +149,12 @@ static const struct ConfigOption options[] = {
#ifdef DISCORDRPC #ifdef DISCORDRPC
{.name = "discordrpc_enable", .type = CONFIG_TYPE_BOOL, .boolValue = &configDiscordRPC}, {.name = "discordrpc_enable", .type = CONFIG_TYPE_BOOL, .boolValue = &configDiscordRPC},
#endif #endif
// coop-specific
{.name = "coop_join_ip", .type = CONFIG_TYPE_STRING, .stringValue = (char*)&configJoinIp},
{.name = "coop_join_port", .type = CONFIG_TYPE_UINT , .uintValue = &configJoinPort},
{.name = "coop_host_port", .type = CONFIG_TYPE_UINT , .uintValue = &configHostPort},
{.name = "coop_host_save_slot", .type = CONFIG_TYPE_UINT , .uintValue = &configHostSaveSlot},
{.name = "coop_player_interaction", .type = CONFIG_TYPE_UINT , .uintValue = &configPlayerInteraction},
}; };
// Reads an entire line from a file (excluding the newline character) and returns an allocated string // Reads an entire line from a file (excluding the newline character) and returns an allocated string
@ -281,6 +295,10 @@ void configfile_load(const char *filename) {
case CONFIG_TYPE_FLOAT: case CONFIG_TYPE_FLOAT:
sscanf(tokens[1], "%f", option->floatValue); sscanf(tokens[1], "%f", option->floatValue);
break; break;
case CONFIG_TYPE_STRING:
memset(option->stringValue, '\0', MAX_CONFIG_STRING);
strncpy(option->stringValue, tokens[1], MAX_CONFIG_STRING);
break;
default: default:
assert(0); // bad type assert(0); // bad type
} }
@ -328,6 +346,9 @@ void configfile_save(const char *filename) {
fprintf(file, "%04x ", option->uintValue[i]); fprintf(file, "%04x ", option->uintValue[i]);
fprintf(file, "\n"); fprintf(file, "\n");
break; break;
case CONFIG_TYPE_STRING:
fprintf(file, "%s %s\n", option->name, option->stringValue);
break;
default: default:
assert(0); // unknown type assert(0); // unknown type
} }

View file

@ -7,6 +7,9 @@
#define MAX_BINDS 3 #define MAX_BINDS 3
#define MAX_VOLUME 127 #define MAX_VOLUME 127
#define MAX_CONFIG_STRING 64
#define DEFAULT_PORT 7777
typedef struct { typedef struct {
unsigned int x, y, w, h; unsigned int x, y, w, h;
@ -59,6 +62,11 @@ extern bool configSkipIntro;
#ifdef DISCORDRPC #ifdef DISCORDRPC
extern bool configDiscordRPC; extern bool configDiscordRPC;
#endif #endif
extern char configJoinIp[];
extern unsigned int configJoinPort;
extern unsigned int configHostPort;
extern unsigned int configHostSaveSlot;
extern unsigned int configPlayerInteraction;
void configfile_load(const char *filename); void configfile_load(const char *filename);
void configfile_save(const char *filename); void configfile_save(const char *filename);

View file

@ -29,7 +29,7 @@ static int num_keybinds = 0;
static u32 keyboard_lastkey = VK_INVALID; static u32 keyboard_lastkey = VK_INVALID;
char textInput[MAX_TEXT_INPUT]; char gTextInput[MAX_TEXT_INPUT];
static bool inTextInput = false; static bool inTextInput = false;
u8 held_ctrl, held_shift, held_alt; u8 held_ctrl, held_shift, held_alt;
@ -77,7 +77,7 @@ bool keyboard_on_key_down(int scancode) {
// perform text-input-specific actions // perform text-input-specific actions
switch (scancode) { switch (scancode) {
case SCANCODE_BACKSPACE: case SCANCODE_BACKSPACE:
textInput[max(strlen(textInput) - 1, 0)] = '\0'; gTextInput[max(strlen(gTextInput) - 1, 0)] = '\0';
break; break;
case SCANCODE_ESCAPE: case SCANCODE_ESCAPE:
if (textInputOnEscape != NULL) { textInputOnEscape(); } if (textInputOnEscape != NULL) { textInputOnEscape(); }
@ -129,7 +129,7 @@ char* keyboard_start_text_input(enum TextInputMode inInputMode, void (*onEscape)
textInputOnEnter = onEnter; textInputOnEnter = onEnter;
// clear buffer // clear buffer
for (int i = 0; i < MAX_TEXT_INPUT; i++) { textInput[i] = '\0'; } for (int i = 0; i < MAX_TEXT_INPUT; i++) { gTextInput[i] = '\0'; }
// clear held-value for modifiers // clear held-value for modifiers
held_ctrl = 0; held_ctrl = 0;
@ -182,14 +182,14 @@ void keyboard_on_text_input(char* text) {
// sanity check input // sanity check input
if (text == NULL) { return; } if (text == NULL) { return; }
int i = strlen(textInput); int i = strlen(gTextInput);
while (*text != '\0') { while (*text != '\0') {
// make sure we don't overrun the buffer // make sure we don't overrun the buffer
if (i >= MAX_TEXT_INPUT) { break; } if (i >= MAX_TEXT_INPUT) { break; }
// copy over character if we're allowed to input it // copy over character if we're allowed to input it
if (keyboard_allow_character_input(*text)) { if (keyboard_allow_character_input(*text)) {
textInput[i++] = *text; gTextInput[i++] = *text;
} }
text++; text++;

View file

@ -11,7 +11,7 @@ extern "C" {
#endif #endif
#define MAX_TEXT_INPUT 256 #define MAX_TEXT_INPUT 256
extern char textInput[]; extern char gTextInput[];
enum TextInputMode { enum TextInputMode {
TIM_IP, TIM_IP,

View file

@ -3,6 +3,7 @@
#include "object_fields.h" #include "object_fields.h"
#include "object_constants.h" #include "object_constants.h"
#include "socket/socket.h" #include "socket/socket.h"
#include "pc/configfile.h"
enum NetworkType networkType; enum NetworkType networkType;
static SOCKET gSocket; static SOCKET gSocket;
@ -16,12 +17,19 @@ struct ServerSettings gServerSettings = {
.playerInteractions = PLAYER_INTERACTIONS_SOLID, .playerInteractions = PLAYER_INTERACTIONS_SOLID,
}; };
void network_init(enum NetworkType inNetworkType, char* ip, char* port) { void network_init(enum NetworkType inNetworkType, char* ip, unsigned int port) {
networkType = inNetworkType; networkType = inNetworkType;
if (networkType == NT_NONE) { return; } if (networkType == NT_NONE) { return; }
if (port == NULL) {
port = NETWORK_DEFAULT_PORT; // sanity check port
if (port == 0) {
port = (networkType == NT_CLIENT) ? configJoinPort : configHostPort;
if (port == 0) { port = DEFAULT_PORT; }
}
if (networkType == NT_SERVER) {
gServerSettings.playerInteractions = configPlayerInteraction;
} }
// Create a receiver socket to receive datagrams // Create a receiver socket to receive datagrams
@ -30,12 +38,12 @@ void network_init(enum NetworkType inNetworkType, char* ip, char* port) {
// Bind the socket to any address and the specified port. // Bind the socket to any address and the specified port.
if (networkType == NT_SERVER) { if (networkType == NT_SERVER) {
int rc = socket_bind(gSocket, atoi(port)); int rc = socket_bind(gSocket, port);
if (rc != NO_ERROR) { return; } if (rc != NO_ERROR) { return; }
} else { } else {
// Save the port to send to // Save the port to send to
txAddr.sin_family = AF_INET; txAddr.sin_family = AF_INET;
txAddr.sin_port = htons(atoi(port)); txAddr.sin_port = htons(port);
txAddr.sin_addr.s_addr = inet_addr(ip); txAddr.sin_addr.s_addr = inet_addr(ip);
} }

View file

@ -14,7 +14,6 @@
#define MAX_SYNC_OBJECT_FIELDS 64 #define MAX_SYNC_OBJECT_FIELDS 64
#define PACKET_LENGTH 1024 #define PACKET_LENGTH 1024
#define NETWORKTYPESTR (networkType == NT_CLIENT ? "Client" : "Server") #define NETWORKTYPESTR (networkType == NT_CLIENT ? "Client" : "Server")
#define NETWORK_DEFAULT_PORT "7777"
enum PacketType { enum PacketType {
PACKET_ACK, PACKET_ACK,
@ -82,7 +81,7 @@ extern bool networkLevelLoaded;
extern struct ServerSettings gServerSettings; extern struct ServerSettings gServerSettings;
void network_init(enum NetworkType inNetworkType, char* ip, char* port); void network_init(enum NetworkType inNetworkType, char* ip, unsigned int port);
void network_on_init_level(void); void network_on_init_level(void);
void network_on_loaded_level(void); void network_on_loaded_level(void);