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;
if (sign > 0 && terrainIndex == 1) { mag *= -1.0f; }
m->vel[0] = mag * sins(angleToObject);
m->vel[1] = abs(mag);
m->vel[1] = (mag < 0) ? -mag : mag;
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];
if (marioRelY < 0) { marioRelY = -marioRelY; }
if (marioRelY >= extentY) { return; }
if (marioRelY >= extentY) { return FALSE; }
f32 marioRelX = localTorso[0] - remoteTorso[0];
f32 marioRelZ = localTorso[2] - remoteTorso[2];
f32 marioDist = sqrtf(sqr(marioRelX) + sqr(marioRelZ));
if (marioDist >= radius) { return; }
if (marioDist >= radius) { return FALSE; }
// bounce
u32 interaction = determine_interaction(m, m2->marioObj);

View file

@ -22,8 +22,6 @@
#include "text_strings.h"
#include "game/ingame_menu.h"
#include "pc/controller/controller_keyboard.h"
#include "pc/network/network.h"
#include "eu_translation.h"
#ifdef VERSION_EU
@ -31,6 +29,11 @@
#define LANGUAGE_FUNCTION sLanguageMode
#endif
#include <stdio.h>
#include "pc/configfile.h"
#include "pc/controller/controller_keyboard.h"
#include "pc/network/network.h"
/**
* @file file_select.c
* 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[] = { ' ' };
// copy input
char buffer[MAX_TEXT_INPUT] = { 0 };
strncpy(buffer, gTextInput, MAX_TEXT_INPUT);
char* text = buffer;
// trim whitespace
char* text = textInput;
while (*text == ' ') { text++; }
// grab IP
@ -414,16 +421,23 @@ void join_server_as_client(void) {
exit_join_to_network_menu();
return;
}
strncpy(configJoinIp, ip, MAX_CONFIG_STRING);
// grab port
char* port = strtok(NULL, delims);
if (port != NULL && atoi(port) == 0) {
exit_join_to_network_menu();
return;
if (port != NULL) {
unsigned int intPort = atoi(port);
if (intPort == 0) {
exit_join_to_network_menu();
return;
}
configJoinPort = intPort;
} else {
configJoinPort = DEFAULT_PORT;
}
keyboard_stop_text_input();
network_init(NT_CLIENT, textInput, port);
network_init(NT_CLIENT, configJoinIp, configJoinPort);
}
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);
sMainMenuButtons[buttonID]->oMenuButtonState = MENU_BUTTON_STATE_GROWING;
sSelectedButtonID = buttonID;
// start input
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;
@ -494,8 +517,8 @@ void print_network_mode_menu_strings(void) {
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
#define TEXT_HOST 0x11,0x18,0x1C,0x1D,0xFF
#define TEXT_JOIN 0x13,0x18,0x12,0x17,0xFF
#define TEXT_HOST 0x11,0x18,0x1C,0x1D,0xFF
#define TEXT_JOIN 0x13,0x18,0x12,0x17,0xFF
static unsigned char textNetworkModes[][5] = { { TEXT_HOST }, { TEXT_JOIN } };
// Print network mode names
@ -535,9 +558,12 @@ void print_join_mode_menu_strings(void) {
// 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 * 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.");
}
@ -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) {
if (fileButton->oMenuButtonState == MENU_BUTTON_STATE_FULLSCREEN) {
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
if (networkType == NT_SERVER) {
sSelectedFileNum = 1;
sSelectedFileNum = configHostSaveSlot;
}
//! 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
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
gCLIOpts.Network = NT_CLIENT;
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
Cheats.EnableCheats = true;

View file

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

View file

@ -21,6 +21,7 @@ enum ConfigOptionType {
CONFIG_TYPE_UINT,
CONFIG_TYPE_FLOAT,
CONFIG_TYPE_BIND,
CONFIG_TYPE_STRING,
};
struct ConfigOption {
@ -29,7 +30,8 @@ struct ConfigOption {
union {
bool *boolValue;
unsigned int *uintValue;
float *floatValue;
float* floatValue;
char* stringValue;
};
};
@ -83,7 +85,7 @@ unsigned int configCameraAggr = 0;
unsigned int configCameraPan = 0;
unsigned int configCameraDegrade = 50; // 0 - 100%
bool configCameraInvertX = false;
bool configCameraInvertY = false;
bool configCameraInvertY = true;
bool configEnableCamera = true;
bool configCameraAnalog = true;
bool configCameraMouse = false;
@ -93,6 +95,12 @@ bool configHUD = true;
#ifdef DISCORDRPC
bool configDiscordRPC = true;
#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[] = {
{.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configWindow.fullscreen},
@ -141,6 +149,12 @@ static const struct ConfigOption options[] = {
#ifdef DISCORDRPC
{.name = "discordrpc_enable", .type = CONFIG_TYPE_BOOL, .boolValue = &configDiscordRPC},
#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
@ -281,6 +295,10 @@ void configfile_load(const char *filename) {
case CONFIG_TYPE_FLOAT:
sscanf(tokens[1], "%f", option->floatValue);
break;
case CONFIG_TYPE_STRING:
memset(option->stringValue, '\0', MAX_CONFIG_STRING);
strncpy(option->stringValue, tokens[1], MAX_CONFIG_STRING);
break;
default:
assert(0); // bad type
}
@ -328,6 +346,9 @@ void configfile_save(const char *filename) {
fprintf(file, "%04x ", option->uintValue[i]);
fprintf(file, "\n");
break;
case CONFIG_TYPE_STRING:
fprintf(file, "%s %s\n", option->name, option->stringValue);
break;
default:
assert(0); // unknown type
}

View file

@ -7,6 +7,9 @@
#define MAX_BINDS 3
#define MAX_VOLUME 127
#define MAX_CONFIG_STRING 64
#define DEFAULT_PORT 7777
typedef struct {
unsigned int x, y, w, h;
@ -59,6 +62,11 @@ extern bool configSkipIntro;
#ifdef DISCORDRPC
extern bool configDiscordRPC;
#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_save(const char *filename);

View file

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

View file

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

View file

@ -3,6 +3,7 @@
#include "object_fields.h"
#include "object_constants.h"
#include "socket/socket.h"
#include "pc/configfile.h"
enum NetworkType networkType;
static SOCKET gSocket;
@ -16,12 +17,19 @@ struct ServerSettings gServerSettings = {
.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;
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
@ -30,12 +38,12 @@ void network_init(enum NetworkType inNetworkType, char* ip, char* port) {
// Bind the socket to any address and the specified port.
if (networkType == NT_SERVER) {
int rc = socket_bind(gSocket, atoi(port));
int rc = socket_bind(gSocket, port);
if (rc != NO_ERROR) { return; }
} else {
// Save the port to send to
txAddr.sin_family = AF_INET;
txAddr.sin_port = htons(atoi(port));
txAddr.sin_port = htons(port);
txAddr.sin_addr.s_addr = inet_addr(ip);
}

View file

@ -14,7 +14,6 @@
#define MAX_SYNC_OBJECT_FIELDS 64
#define PACKET_LENGTH 1024
#define NETWORKTYPESTR (networkType == NT_CLIENT ? "Client" : "Server")
#define NETWORK_DEFAULT_PORT "7777"
enum PacketType {
PACKET_ACK,
@ -82,7 +81,7 @@ extern bool networkLevelLoaded;
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_loaded_level(void);