mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 05:25:14 +00:00
Reading headers from lua files
Fix up warnings on Linux Disabled mod checkboxes when an incompatible one is enabled Display descriptions when hovering over a mod
This commit is contained in:
parent
0aa8cd0e35
commit
809dfd6373
13 changed files with 292 additions and 21 deletions
3
Makefile
3
Makefile
|
@ -557,6 +557,9 @@ BACKEND_LDFLAG0S :=
|
|||
SDL1_USED := 0
|
||||
SDL2_USED := 0
|
||||
|
||||
# suppress warnings
|
||||
BACKEND_CFLAGS += -Wno-format-truncation
|
||||
|
||||
# for now, it's either SDL+GL or DXGI+DirectX, so choose based on WAPI
|
||||
ifeq ($(WINDOW_API),DXGI)
|
||||
DXBITS := `cat $(ENDIAN_BITWIDTH) | tr ' ' '\n' | tail -1`
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
-- name: Character Movesets
|
||||
-- incompatible: moveset
|
||||
-- description: Gives each character unique abilities and stats.
|
||||
|
||||
gStateExtras = {}
|
||||
for i=0,(MAX_PLAYERS-1) do
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
-- name: Extended Moveset
|
||||
-- incompatible: moveset
|
||||
-- description: Adds various new moves from games like Sunshine and Odyssey without replacing any existing ones.\n\nOriginal author: TheGag96
|
||||
|
||||
------------------------
|
||||
-- initialize actions --
|
||||
------------------------
|
||||
|
|
|
@ -7,18 +7,122 @@
|
|||
#include "pc/cheats.h"
|
||||
#include "pc/mod_list.h"
|
||||
|
||||
static struct DjuiFlowLayout* sModPanelBody = NULL;
|
||||
static struct DjuiThreePanel* sDescriptionPanel = NULL;
|
||||
static struct DjuiText* sTooltip = NULL;
|
||||
|
||||
static void djui_panel_host_mods_description_create() {
|
||||
f32 bodyHeight = 600;
|
||||
|
||||
struct DjuiThreePanel* panel = djui_three_panel_create(&gDjuiRoot->base, 64, bodyHeight, 0);
|
||||
djui_base_set_alignment(&panel->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_CENTER);
|
||||
djui_base_set_size_type(&panel->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(&panel->base, DJUI_DEFAULT_PANEL_WIDTH, 1.0f);
|
||||
djui_base_set_color(&panel->base, 0, 0, 0, 240);
|
||||
djui_base_set_border_color(&panel->base, 0, 0, 0, 200);
|
||||
djui_base_set_border_width(&panel->base, 8);
|
||||
djui_base_set_padding(&panel->base, 16, 16, 16, 16);
|
||||
{
|
||||
struct DjuiFlowLayout* body = djui_flow_layout_create(&panel->base);
|
||||
djui_base_set_alignment(&body->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
|
||||
djui_base_set_size_type(&body->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(&body->base, 1.0f, 1.0f);
|
||||
djui_base_set_color(&body->base, 0, 0, 0, 0);
|
||||
djui_flow_layout_set_margin(body, 16);
|
||||
djui_flow_layout_set_flow_direction(body, DJUI_FLOW_DIR_DOWN);
|
||||
|
||||
struct DjuiText* description = djui_text_create(&panel->base, "");
|
||||
djui_base_set_size_type(&description->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(&description->base, 1.0f, 1.0f);
|
||||
djui_base_set_color(&description->base, 222, 222, 222, 255);
|
||||
djui_text_set_alignment(description, DJUI_HALIGN_LEFT, DJUI_VALIGN_CENTER);
|
||||
sTooltip = description;
|
||||
}
|
||||
sDescriptionPanel = panel;
|
||||
}
|
||||
|
||||
static void djui_mod_checkbox_set_style(struct DjuiBase* base) {
|
||||
struct DjuiCheckbox* checkbox = (struct DjuiCheckbox*)base;
|
||||
int val = base->enabled ? 200 : 100;
|
||||
djui_base_set_border_color(&checkbox->rect->base, 173, 173, 173, 255);
|
||||
djui_base_set_color(&checkbox->rect->base, 0, 0, 0, 0);
|
||||
djui_base_set_color(&checkbox->text->base, val, val, val, 255);
|
||||
djui_base_set_color(&checkbox->rectValue->base, val, val, val, 255);
|
||||
}
|
||||
|
||||
static void djui_mod_checkbox_on_hover(struct DjuiBase* base) {
|
||||
struct DjuiCheckbox* checkbox = (struct DjuiCheckbox*)base;
|
||||
djui_base_set_border_color(&checkbox->rect->base, 0, 120, 215, 255);
|
||||
djui_base_set_color(&checkbox->text->base, 229, 241, 251, 255);
|
||||
djui_base_set_color(&checkbox->rectValue->base, 229, 241, 251, 255);
|
||||
|
||||
char* description = "";
|
||||
if (base->tag >= 0 && base->tag < gModTableLocal.entryCount) {
|
||||
char* d = gModTableLocal.entries[base->tag].description;
|
||||
if (d != NULL) {
|
||||
description = gModTableLocal.entries[base->tag].description;
|
||||
}
|
||||
}
|
||||
djui_text_set_text(sTooltip, description);
|
||||
}
|
||||
|
||||
static void djui_mod_checkbox_on_click(UNUSED struct DjuiBase* base) {
|
||||
mod_list_update_selectable();
|
||||
|
||||
u16 index = 0;
|
||||
struct DjuiBaseChild* node = sModPanelBody->base.child;
|
||||
while (node != NULL) {
|
||||
if (index >= gModTableLocal.entryCount) { break; }
|
||||
struct ModListEntry* entry = &gModTableLocal.entries[index];
|
||||
|
||||
djui_base_set_enabled(node->base, entry->selectable);
|
||||
djui_mod_checkbox_set_style(node->base);
|
||||
|
||||
// iterate
|
||||
index++;
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void djui_mod_checkbox_on_hover_end(struct DjuiBase* base) {
|
||||
struct DjuiCheckbox* checkbox = (struct DjuiCheckbox*)base;
|
||||
djui_base_set_border_color(&checkbox->rect->base, 173, 173, 173, 255);
|
||||
djui_base_set_color(&checkbox->rect->base, 0, 0, 0, 0);
|
||||
djui_base_set_color(&checkbox->text->base, 200, 200, 200, 255);
|
||||
djui_base_set_color(&checkbox->rectValue->base, 200, 200, 200, 255);
|
||||
djui_text_set_text(sTooltip, "");
|
||||
}
|
||||
|
||||
static void djui_panel_host_mods_destroy(struct DjuiBase* base) {
|
||||
struct DjuiThreePanel* threePanel = (struct DjuiThreePanel*)base;
|
||||
free(threePanel);
|
||||
|
||||
if (sDescriptionPanel != NULL) {
|
||||
djui_base_destroy(&sDescriptionPanel->base);
|
||||
sDescriptionPanel = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void djui_panel_host_mods_create(struct DjuiBase* caller) {
|
||||
f32 bodyHeight = 32 * gModTableLocal.entryCount + 64 * 1 + 16 * (gModTableLocal.entryCount + 1);
|
||||
|
||||
mod_list_update_selectable();
|
||||
|
||||
struct DjuiBase* defaultBase = NULL;
|
||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\M\\#1be700\\O\\#00b3ff\\D\\#ffef00\\S");
|
||||
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||
sModPanelBody = body;
|
||||
{
|
||||
for (int i = 0; i < gModTableLocal.entryCount; i++) {
|
||||
struct ModListEntry* entry = &gModTableLocal.entries[i];
|
||||
struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, entry->name, &entry->enabled);
|
||||
struct DjuiCheckbox* checkbox = djui_checkbox_create(&body->base, entry->displayName ? entry->displayName : entry->name, &entry->enabled);
|
||||
checkbox->base.tag = i;
|
||||
djui_base_set_size_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&checkbox->base, 1.0f, 32);
|
||||
djui_base_set_enabled(&checkbox->base, entry->selectable);
|
||||
djui_mod_checkbox_set_style(&checkbox->base);
|
||||
djui_interactable_hook_hover(&checkbox->base, djui_mod_checkbox_on_hover, djui_mod_checkbox_on_hover_end);
|
||||
djui_interactable_hook_click(&checkbox->base, djui_mod_checkbox_on_click);
|
||||
}
|
||||
|
||||
struct DjuiButton* button1 = djui_button_create(&body->base, "Back");
|
||||
|
@ -29,5 +133,8 @@ void djui_panel_host_mods_create(struct DjuiBase* caller) {
|
|||
defaultBase = &button1->base;
|
||||
}
|
||||
|
||||
panel->base.destroy = djui_panel_host_mods_destroy;
|
||||
|
||||
djui_panel_add(caller, &panel->base, defaultBase);
|
||||
djui_panel_host_mods_description_create();
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <unistd.h>
|
||||
#include "mod_list.h"
|
||||
#include "pc/fs/fs.h"
|
||||
#include "pc/utils/misc.h"
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
#define MAX_SESSION_CHARS 7
|
||||
|
@ -20,7 +21,6 @@ static bool acceptable_file(char* string) {
|
|||
return (string != NULL && !strcmp(string, ".lua"));
|
||||
}
|
||||
|
||||
|
||||
static void mod_list_delete_tmp(void) {
|
||||
struct dirent* dir;
|
||||
DIR* d = opendir(sTmpPath);
|
||||
|
@ -86,7 +86,48 @@ void mod_list_add_tmp(u16 index, u16 remoteIndex, char* name, size_t size) {
|
|||
entry->remoteIndex = remoteIndex;
|
||||
entry->complete = false;
|
||||
entry->enabled = true;
|
||||
entry->selectable = false;
|
||||
}
|
||||
|
||||
static char* extract_lua_field(char* fieldName, char* buffer) {
|
||||
size_t length = strlen(fieldName);
|
||||
if (strncmp(fieldName, buffer, length) == 0) {
|
||||
char* s = &buffer[length];
|
||||
while (*s == ' ' || *s == '\t') { s++; }
|
||||
return s;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void extract_lua_fields(struct ModListEntry* entry) {
|
||||
FILE* f = entry->fp;
|
||||
char buffer[512] = { 0 };
|
||||
|
||||
entry->displayName = NULL;
|
||||
entry->incompatible = NULL;
|
||||
entry->description = NULL;
|
||||
|
||||
while (!feof(f)) {
|
||||
file_get_line(buffer, 512, f);
|
||||
|
||||
// no longer in header
|
||||
if (buffer[0] != '-' || buffer[1] != '-') {
|
||||
return;
|
||||
}
|
||||
|
||||
// extract the field
|
||||
char* extracted = NULL;
|
||||
if (entry->displayName == NULL && (extracted = extract_lua_field("-- name:", buffer))) {
|
||||
entry->displayName = calloc(33, sizeof(char));
|
||||
snprintf(entry->displayName, 32, "%s", extracted);
|
||||
} else if (entry->incompatible == NULL && (extracted = extract_lua_field("-- incompatible:", buffer))) {
|
||||
entry->incompatible = calloc(257, sizeof(char));
|
||||
snprintf(entry->incompatible, 256, "%s", extracted);
|
||||
} else if (entry->description == NULL && (extracted = extract_lua_field("-- description:", buffer))) {
|
||||
entry->description = calloc(513, sizeof(char));
|
||||
snprintf(entry->description, 512, "%s", extracted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_list_add_local(u16 index, const char* path, char* name) {
|
||||
|
@ -101,6 +142,8 @@ static void mod_list_add_local(u16 index, const char* path, char* name) {
|
|||
snprintf(entry->path, PATH_MAX - 1, "%s/%s", path, name);
|
||||
entry->fp = fopen(entry->path, "rb");
|
||||
|
||||
extract_lua_fields(entry);
|
||||
|
||||
fseek(entry->fp, 0, SEEK_END);
|
||||
entry->size = ftell(entry->fp);
|
||||
table->totalSize += entry->size;
|
||||
|
@ -108,6 +151,7 @@ static void mod_list_add_local(u16 index, const char* path, char* name) {
|
|||
|
||||
entry->complete = true;
|
||||
entry->enabled = false;
|
||||
entry->selectable = true;
|
||||
}
|
||||
|
||||
void mod_table_clear(struct ModTable* table) {
|
||||
|
@ -117,16 +161,34 @@ void mod_table_clear(struct ModTable* table) {
|
|||
free(entry->name);
|
||||
entry->name = NULL;
|
||||
}
|
||||
|
||||
if (entry->displayName != NULL) {
|
||||
free(entry->displayName);
|
||||
entry->displayName = NULL;
|
||||
}
|
||||
|
||||
if (entry->incompatible != NULL) {
|
||||
free(entry->incompatible);
|
||||
entry->incompatible = NULL;
|
||||
}
|
||||
|
||||
if (entry->description != NULL) {
|
||||
free(entry->description);
|
||||
entry->description = NULL;
|
||||
}
|
||||
|
||||
if (entry->fp != NULL) {
|
||||
fclose(entry->fp);
|
||||
entry->fp = NULL;
|
||||
}
|
||||
entry->size = 0;
|
||||
}
|
||||
|
||||
if (table->entries != NULL) {
|
||||
free(table->entries);
|
||||
table->entries = NULL;
|
||||
}
|
||||
|
||||
table->entryCount = 0;
|
||||
table->totalSize = 0;
|
||||
}
|
||||
|
@ -137,6 +199,52 @@ void mod_list_alloc(struct ModTable* table, u16 count) {
|
|||
table->entries = (struct ModListEntry*)calloc(count, sizeof(struct ModListEntry));
|
||||
}
|
||||
|
||||
static bool mod_list_incompatible_match(struct ModListEntry* a, struct ModListEntry* b) {
|
||||
if (a->incompatible == NULL || b->incompatible == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char* ai = a->incompatible;
|
||||
char* bi = b->incompatible;
|
||||
char* atoken = NULL;
|
||||
char* btoken = NULL;
|
||||
|
||||
while ((atoken = strtok(ai, " "))) {
|
||||
while((btoken = strtok(bi, " "))) {
|
||||
if (!strcmp(atoken, btoken)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void mod_list_update_selectable(void) {
|
||||
// reset selectable value
|
||||
for (int i = 0; i < gModTableLocal.entryCount; i++) {
|
||||
struct ModListEntry* entry = &gModTableLocal.entries[i];
|
||||
entry->selectable = true;
|
||||
}
|
||||
|
||||
// figure out which ones to deselect
|
||||
for (int i = 0; i < gModTableLocal.entryCount; i++) {
|
||||
struct ModListEntry* entry = &gModTableLocal.entries[i];
|
||||
if (entry->enabled) { continue; }
|
||||
|
||||
for (int j = 0; j < gModTableLocal.entryCount; j++) {
|
||||
if (j == i) { continue; }
|
||||
struct ModListEntry* entry2 = &gModTableLocal.entries[j];
|
||||
if (!entry2->enabled) { continue; }
|
||||
|
||||
if (mod_list_incompatible_match(entry, entry2)) {
|
||||
entry->selectable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_list_load_local(const char* path) {
|
||||
if (!fs_sys_dir_exists(path)) { return; }
|
||||
struct ModTable* table = &gModTableLocal;
|
||||
|
@ -188,6 +296,8 @@ void mod_list_init(void) {
|
|||
mod_table_clear(&gModTableLocal);
|
||||
mod_list_load_local(userModPath);
|
||||
mod_list_load_local(MOD_PATH);
|
||||
|
||||
mod_list_update_selectable();
|
||||
}
|
||||
|
||||
void mod_list_shutdown(void) {
|
||||
|
|
|
@ -17,9 +17,13 @@ struct ModListEntry {
|
|||
size_t size;
|
||||
u64 curOffset;
|
||||
u16 remoteIndex;
|
||||
char* displayName;
|
||||
char* incompatible;
|
||||
char* description;
|
||||
bool tmp;
|
||||
bool complete;
|
||||
bool enabled;
|
||||
bool selectable;
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
|
@ -37,6 +41,8 @@ void mod_list_add_tmp(u16 index, u16 remoteIndex, char* name, size_t size);
|
|||
void mod_table_clear(struct ModTable* table);
|
||||
void mod_list_alloc(struct ModTable* table, u16 count);
|
||||
|
||||
void mod_list_update_selectable(void);
|
||||
|
||||
void mod_list_init(void);
|
||||
void mod_list_shutdown(void);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ static void on_activity_update_callback(UNUSED void* data, enum EDiscordResult r
|
|||
}
|
||||
|
||||
static void on_activity_join_callback(UNUSED void* data, enum EDiscordResult result, struct DiscordLobby* lobby) {
|
||||
LOGFILE_INFO(LFT_DISCORD, "> on_activity_join_callback returned %d, lobby %lld, owner %lld", result, lobby->id, lobby->owner_id);
|
||||
LOGFILE_INFO(LFT_DISCORD, "> on_activity_join_callback returned %d, lobby %ld, owner %ld", result, lobby->id, lobby->owner_id);
|
||||
DISCORD_REQUIRE(result);
|
||||
if (gNetworkType != NT_NONE) {
|
||||
LOGFILE_ERROR(LFT_DISCORD, "Joined lobby when already connected somewhere!");
|
||||
|
@ -25,7 +25,7 @@ static void on_activity_join_callback(UNUSED void* data, enum EDiscordResult res
|
|||
network_init(NT_CLIENT);
|
||||
|
||||
gCurActivity.type = DiscordActivityType_Playing;
|
||||
snprintf(gCurActivity.party.id, 128, "%lld", lobby->id);
|
||||
snprintf(gCurActivity.party.id, 128, "%ld", lobby->id);
|
||||
gCurActivity.party.size.current_size = 2;
|
||||
gCurActivity.party.size.max_size = lobby->capacity;
|
||||
|
||||
|
@ -57,7 +57,7 @@ static void on_activity_join_request_callback(UNUSED void* data, enum EDiscordRe
|
|||
}
|
||||
|
||||
static void on_activity_join_request(UNUSED void* data, struct DiscordUser* user) {
|
||||
LOGFILE_INFO(LFT_DISCORD, "> on_activity_join_request from %lld", user->id);
|
||||
LOGFILE_INFO(LFT_DISCORD, "> on_activity_join_request from %ld", user->id);
|
||||
//app.activities->send_request_reply(app.activities, user->id, DiscordActivityJoinRequestReply_Yes, NULL, on_activity_join_request_callback);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,14 +48,14 @@ void ns_discord_save_id(u8 localId, s64 networkId) {
|
|||
assert(localId > 0);
|
||||
assert(localId < MAX_PLAYERS);
|
||||
gNetworkUserIds[localId] = (networkId == 0) ? gNetworkUserIds[0] : networkId;
|
||||
LOGFILE_INFO(LFT_DISCORD, "saved user id %d == %lld", localId, gNetworkUserIds[localId]);
|
||||
LOGFILE_INFO(LFT_DISCORD, "saved user id %d == %ld", localId, gNetworkUserIds[localId]);
|
||||
}
|
||||
|
||||
void ns_discord_clear_id(u8 localId) {
|
||||
if (localId == 0) { return; }
|
||||
assert(localId < MAX_PLAYERS);
|
||||
gNetworkUserIds[localId] = 0;
|
||||
LOGFILE_INFO(LFT_DISCORD, "cleared user id %d == %lld", localId, gNetworkUserIds[localId]);
|
||||
LOGFILE_INFO(LFT_DISCORD, "cleared user id %d == %ld", localId, gNetworkUserIds[localId]);
|
||||
}
|
||||
|
||||
void discord_network_init(int64_t lobbyId) {
|
||||
|
@ -68,5 +68,5 @@ void discord_network_shutdown(void) {
|
|||
app.lobbies->flush_network(app.lobbies);
|
||||
if (gCurLobbyId == 0) { return; }
|
||||
app.lobbies->disconnect_network(app.lobbies, gCurLobbyId);
|
||||
LOGFILE_INFO(LFT_DISCORD, "shutdown network, lobby = %lld", gCurLobbyId);
|
||||
LOGFILE_INFO(LFT_DISCORD, "shutdown network, lobby = %ld", gCurLobbyId);
|
||||
}
|
|
@ -35,20 +35,20 @@ static void on_lobby_create_callback(UNUSED void* data, enum EDiscordResult resu
|
|||
}
|
||||
|
||||
DISCORD_REQUIRE(result);
|
||||
LOGFILE_INFO(LFT_DISCORD, "Lobby id: %lld", lobby->id);
|
||||
LOGFILE_INFO(LFT_DISCORD, "Lobby id: %ld", lobby->id);
|
||||
LOGFILE_INFO(LFT_DISCORD, "Lobby type: %u", lobby->type);
|
||||
LOGFILE_INFO(LFT_DISCORD, "Lobby owner id: %lld", lobby->owner_id);
|
||||
LOGFILE_INFO(LFT_DISCORD, "Lobby owner id: %ld", lobby->owner_id);
|
||||
LOGFILE_INFO(LFT_DISCORD, "Lobby secret: %s", lobby->secret);
|
||||
LOGFILE_INFO(LFT_DISCORD, "Lobby capacity: %u", lobby->capacity);
|
||||
LOGFILE_INFO(LFT_DISCORD, "Lobby locked: %d", lobby->locked);
|
||||
|
||||
gCurActivity.type = DiscordActivityType_Playing;
|
||||
snprintf(gCurActivity.party.id, 128, "%lld", lobby->id);
|
||||
snprintf(gCurActivity.party.id, 128, "%ld", lobby->id);
|
||||
gCurActivity.party.size.current_size = 1;
|
||||
gCurActivity.party.size.max_size = MAX_PLAYERS;
|
||||
|
||||
char secretJoin[128] = "";
|
||||
snprintf(secretJoin, 128, "%lld:%s", lobby->id, lobby->secret);
|
||||
snprintf(secretJoin, 128, "%ld:%s", lobby->id, lobby->secret);
|
||||
strcpy(gCurActivity.secrets.join, secretJoin);
|
||||
|
||||
isHosting = true;
|
||||
|
@ -59,21 +59,21 @@ static void on_lobby_create_callback(UNUSED void* data, enum EDiscordResult resu
|
|||
}
|
||||
|
||||
static void on_lobby_update(UNUSED void* data, int64_t lobbyId) {
|
||||
LOGFILE_INFO(LFT_DISCORD, "> on_lobby_update id: %lld", lobbyId);
|
||||
LOGFILE_INFO(LFT_DISCORD, "> on_lobby_update id: %ld", lobbyId);
|
||||
}
|
||||
|
||||
static void on_member_connect(UNUSED void* data, int64_t lobbyId, int64_t userId) {
|
||||
LOGFILE_INFO(LFT_DISCORD, "> on_member_connect lobby: %lld, user: %lld", lobbyId, userId);
|
||||
LOGFILE_INFO(LFT_DISCORD, "> on_member_connect lobby: %ld, user: %ld", lobbyId, userId);
|
||||
gCurActivity.party.size.current_size++;
|
||||
discord_activity_update(true);
|
||||
}
|
||||
|
||||
static void on_member_update(UNUSED void* data, int64_t lobbyId, int64_t userId) {
|
||||
LOGFILE_INFO(LFT_DISCORD, "> on_member_update lobby: %lld, user: %lld", lobbyId, userId);
|
||||
LOGFILE_INFO(LFT_DISCORD, "> on_member_update lobby: %ld, user: %ld", lobbyId, userId);
|
||||
}
|
||||
|
||||
static void on_member_disconnect(UNUSED void* data, int64_t lobbyId, int64_t userId) {
|
||||
LOGFILE_INFO(LFT_DISCORD, "> on_member_disconnect lobby: %lld, user: %lld", lobbyId, userId);
|
||||
LOGFILE_INFO(LFT_DISCORD, "> on_member_disconnect lobby: %ld, user: %ld", lobbyId, userId);
|
||||
u8 localIndex = discord_user_id_to_local_index(userId);
|
||||
if (localIndex != UNKNOWN_LOCAL_INDEX && gNetworkPlayers[localIndex].connected) {
|
||||
network_player_disconnected(gNetworkPlayers[localIndex].globalIndex);
|
||||
|
@ -108,7 +108,7 @@ void discord_lobby_leave(void) {
|
|||
app.lobbies->disconnect_lobby(app.lobbies, gCurLobbyId, NULL, on_lobby_leave_callback);
|
||||
}
|
||||
|
||||
LOGFILE_INFO(LFT_DISCORD, "left lobby %lld", gCurLobbyId);
|
||||
LOGFILE_INFO(LFT_DISCORD, "left lobby %ld", gCurLobbyId);
|
||||
|
||||
isHosting = false;
|
||||
gCurLobbyId = 0;
|
||||
|
|
|
@ -36,7 +36,7 @@ static int socket_send(SOCKET socket, struct sockaddr_in* addr, u8* buffer, u16
|
|||
static int socket_receive(SOCKET socket, struct sockaddr_in* rxAddr, u8* buffer, u16 bufferLength, u16* receiveLength, u8* localIndex) {
|
||||
*receiveLength = 0;
|
||||
|
||||
int rxAddrSize = sizeof(struct sockaddr_in);
|
||||
unsigned int rxAddrSize = sizeof(struct sockaddr_in);
|
||||
int rc = recvfrom(socket, (char*)buffer, bufferLength, 0, (struct sockaddr*)rxAddr, &rxAddrSize);
|
||||
|
||||
for (int i = 1; i < MAX_PLAYERS; i++) {
|
||||
|
|
|
@ -13,7 +13,7 @@ SOCKET socket_initialize(void) {
|
|||
|
||||
// set non-blocking mode
|
||||
int rc = fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
|
||||
if (rc == INVALID_SOCKET) {
|
||||
if (rc == (int)INVALID_SOCKET) {
|
||||
LOG_ERROR("fcntl failed with error: %d", rc);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ SOCKET socket_initialize(void) {
|
|||
void socket_shutdown(SOCKET socket) {
|
||||
if (socket == INVALID_SOCKET) { return; }
|
||||
int rc = closesocket(socket);
|
||||
if (rc == SOCKET_ERROR) {
|
||||
if (rc == (int)SOCKET_ERROR) {
|
||||
LOG_ERROR("closesocket failed with error %d\n", SOCKET_LAST_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,3 +78,38 @@ f64 clock_elapsed_f64(void) {
|
|||
u32 clock_elapsed_ticks(void) {
|
||||
return (clock_elapsed_ns() * 3 / 100000000);
|
||||
}
|
||||
|
||||
void file_get_line(char* buffer, size_t maxLength, FILE* fp) {
|
||||
char* initial = buffer;
|
||||
|
||||
char c = fgetc(fp);
|
||||
while (!feof(fp) && c != '\n') {
|
||||
// make sure it's printable
|
||||
if (c < ' ' || c > '~') { goto next_get; }
|
||||
|
||||
// parse new line escape code
|
||||
if (c == '\\') {
|
||||
c = fgetc(fp);
|
||||
if (feof(fp)) { break; }
|
||||
if (c == 'n') {
|
||||
if ((size_t)(buffer - initial) < (maxLength - 1)) {
|
||||
*buffer++ = '\n';
|
||||
}
|
||||
goto next_get;
|
||||
}
|
||||
}
|
||||
|
||||
// found new line
|
||||
if (c == '\n') { break; }
|
||||
|
||||
// append to buffer
|
||||
if ((size_t)(buffer - initial) < (maxLength - 1)) {
|
||||
*buffer++ = c;
|
||||
}
|
||||
|
||||
next_get:
|
||||
c = fgetc(fp);
|
||||
}
|
||||
|
||||
*buffer = '\0';
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
#ifndef UTILS_MISC_H
|
||||
#define UTILS_MISC_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
float smoothstep(float edge0, float edge1, float x);
|
||||
void update_all_mario_stars(void);
|
||||
f32 clock_elapsed(void);
|
||||
f64 clock_elapsed_f64(void);
|
||||
u32 clock_elapsed_ticks(void);
|
||||
void file_get_line(char* buffer, size_t maxLength, FILE* fp);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue