mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-22 12:05:11 +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
|
SDL1_USED := 0
|
||||||
SDL2_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
|
# for now, it's either SDL+GL or DXGI+DirectX, so choose based on WAPI
|
||||||
ifeq ($(WINDOW_API),DXGI)
|
ifeq ($(WINDOW_API),DXGI)
|
||||||
DXBITS := `cat $(ENDIAN_BITWIDTH) | tr ' ' '\n' | tail -1`
|
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 = {}
|
gStateExtras = {}
|
||||||
for i=0,(MAX_PLAYERS-1) do
|
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 --
|
-- initialize actions --
|
||||||
------------------------
|
------------------------
|
||||||
|
|
|
@ -7,18 +7,122 @@
|
||||||
#include "pc/cheats.h"
|
#include "pc/cheats.h"
|
||||||
#include "pc/mod_list.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) {
|
void djui_panel_host_mods_create(struct DjuiBase* caller) {
|
||||||
f32 bodyHeight = 32 * gModTableLocal.entryCount + 64 * 1 + 16 * (gModTableLocal.entryCount + 1);
|
f32 bodyHeight = 32 * gModTableLocal.entryCount + 64 * 1 + 16 * (gModTableLocal.entryCount + 1);
|
||||||
|
|
||||||
|
mod_list_update_selectable();
|
||||||
|
|
||||||
struct DjuiBase* defaultBase = NULL;
|
struct DjuiBase* defaultBase = NULL;
|
||||||
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\M\\#1be700\\O\\#00b3ff\\D\\#ffef00\\S");
|
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);
|
struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
|
||||||
|
sModPanelBody = body;
|
||||||
{
|
{
|
||||||
for (int i = 0; i < gModTableLocal.entryCount; i++) {
|
for (int i = 0; i < gModTableLocal.entryCount; i++) {
|
||||||
struct ModListEntry* entry = &gModTableLocal.entries[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_type(&checkbox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||||
djui_base_set_size(&checkbox->base, 1.0f, 32);
|
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");
|
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;
|
defaultBase = &button1->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
panel->base.destroy = djui_panel_host_mods_destroy;
|
||||||
|
|
||||||
djui_panel_add(caller, &panel->base, defaultBase);
|
djui_panel_add(caller, &panel->base, defaultBase);
|
||||||
|
djui_panel_host_mods_description_create();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "mod_list.h"
|
#include "mod_list.h"
|
||||||
#include "pc/fs/fs.h"
|
#include "pc/fs/fs.h"
|
||||||
|
#include "pc/utils/misc.h"
|
||||||
#include "pc/debuglog.h"
|
#include "pc/debuglog.h"
|
||||||
|
|
||||||
#define MAX_SESSION_CHARS 7
|
#define MAX_SESSION_CHARS 7
|
||||||
|
@ -20,7 +21,6 @@ static bool acceptable_file(char* string) {
|
||||||
return (string != NULL && !strcmp(string, ".lua"));
|
return (string != NULL && !strcmp(string, ".lua"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void mod_list_delete_tmp(void) {
|
static void mod_list_delete_tmp(void) {
|
||||||
struct dirent* dir;
|
struct dirent* dir;
|
||||||
DIR* d = opendir(sTmpPath);
|
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->remoteIndex = remoteIndex;
|
||||||
entry->complete = false;
|
entry->complete = false;
|
||||||
entry->enabled = true;
|
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) {
|
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);
|
snprintf(entry->path, PATH_MAX - 1, "%s/%s", path, name);
|
||||||
entry->fp = fopen(entry->path, "rb");
|
entry->fp = fopen(entry->path, "rb");
|
||||||
|
|
||||||
|
extract_lua_fields(entry);
|
||||||
|
|
||||||
fseek(entry->fp, 0, SEEK_END);
|
fseek(entry->fp, 0, SEEK_END);
|
||||||
entry->size = ftell(entry->fp);
|
entry->size = ftell(entry->fp);
|
||||||
table->totalSize += entry->size;
|
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->complete = true;
|
||||||
entry->enabled = false;
|
entry->enabled = false;
|
||||||
|
entry->selectable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mod_table_clear(struct ModTable* table) {
|
void mod_table_clear(struct ModTable* table) {
|
||||||
|
@ -117,16 +161,34 @@ void mod_table_clear(struct ModTable* table) {
|
||||||
free(entry->name);
|
free(entry->name);
|
||||||
entry->name = NULL;
|
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) {
|
if (entry->fp != NULL) {
|
||||||
fclose(entry->fp);
|
fclose(entry->fp);
|
||||||
entry->fp = NULL;
|
entry->fp = NULL;
|
||||||
}
|
}
|
||||||
entry->size = 0;
|
entry->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table->entries != NULL) {
|
if (table->entries != NULL) {
|
||||||
free(table->entries);
|
free(table->entries);
|
||||||
table->entries = NULL;
|
table->entries = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
table->entryCount = 0;
|
table->entryCount = 0;
|
||||||
table->totalSize = 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));
|
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) {
|
static void mod_list_load_local(const char* path) {
|
||||||
if (!fs_sys_dir_exists(path)) { return; }
|
if (!fs_sys_dir_exists(path)) { return; }
|
||||||
struct ModTable* table = &gModTableLocal;
|
struct ModTable* table = &gModTableLocal;
|
||||||
|
@ -188,6 +296,8 @@ void mod_list_init(void) {
|
||||||
mod_table_clear(&gModTableLocal);
|
mod_table_clear(&gModTableLocal);
|
||||||
mod_list_load_local(userModPath);
|
mod_list_load_local(userModPath);
|
||||||
mod_list_load_local(MOD_PATH);
|
mod_list_load_local(MOD_PATH);
|
||||||
|
|
||||||
|
mod_list_update_selectable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mod_list_shutdown(void) {
|
void mod_list_shutdown(void) {
|
||||||
|
|
|
@ -17,9 +17,13 @@ struct ModListEntry {
|
||||||
size_t size;
|
size_t size;
|
||||||
u64 curOffset;
|
u64 curOffset;
|
||||||
u16 remoteIndex;
|
u16 remoteIndex;
|
||||||
|
char* displayName;
|
||||||
|
char* incompatible;
|
||||||
|
char* description;
|
||||||
bool tmp;
|
bool tmp;
|
||||||
bool complete;
|
bool complete;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
bool selectable;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(1)
|
#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_table_clear(struct ModTable* table);
|
||||||
void mod_list_alloc(struct ModTable* table, u16 count);
|
void mod_list_alloc(struct ModTable* table, u16 count);
|
||||||
|
|
||||||
|
void mod_list_update_selectable(void);
|
||||||
|
|
||||||
void mod_list_init(void);
|
void mod_list_init(void);
|
||||||
void mod_list_shutdown(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) {
|
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);
|
DISCORD_REQUIRE(result);
|
||||||
if (gNetworkType != NT_NONE) {
|
if (gNetworkType != NT_NONE) {
|
||||||
LOGFILE_ERROR(LFT_DISCORD, "Joined lobby when already connected somewhere!");
|
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);
|
network_init(NT_CLIENT);
|
||||||
|
|
||||||
gCurActivity.type = DiscordActivityType_Playing;
|
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.current_size = 2;
|
||||||
gCurActivity.party.size.max_size = lobby->capacity;
|
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) {
|
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);
|
//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 > 0);
|
||||||
assert(localId < MAX_PLAYERS);
|
assert(localId < MAX_PLAYERS);
|
||||||
gNetworkUserIds[localId] = (networkId == 0) ? gNetworkUserIds[0] : networkId;
|
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) {
|
void ns_discord_clear_id(u8 localId) {
|
||||||
if (localId == 0) { return; }
|
if (localId == 0) { return; }
|
||||||
assert(localId < MAX_PLAYERS);
|
assert(localId < MAX_PLAYERS);
|
||||||
gNetworkUserIds[localId] = 0;
|
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) {
|
void discord_network_init(int64_t lobbyId) {
|
||||||
|
@ -68,5 +68,5 @@ void discord_network_shutdown(void) {
|
||||||
app.lobbies->flush_network(app.lobbies);
|
app.lobbies->flush_network(app.lobbies);
|
||||||
if (gCurLobbyId == 0) { return; }
|
if (gCurLobbyId == 0) { return; }
|
||||||
app.lobbies->disconnect_network(app.lobbies, gCurLobbyId);
|
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);
|
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 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 secret: %s", lobby->secret);
|
||||||
LOGFILE_INFO(LFT_DISCORD, "Lobby capacity: %u", lobby->capacity);
|
LOGFILE_INFO(LFT_DISCORD, "Lobby capacity: %u", lobby->capacity);
|
||||||
LOGFILE_INFO(LFT_DISCORD, "Lobby locked: %d", lobby->locked);
|
LOGFILE_INFO(LFT_DISCORD, "Lobby locked: %d", lobby->locked);
|
||||||
|
|
||||||
gCurActivity.type = DiscordActivityType_Playing;
|
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.current_size = 1;
|
||||||
gCurActivity.party.size.max_size = MAX_PLAYERS;
|
gCurActivity.party.size.max_size = MAX_PLAYERS;
|
||||||
|
|
||||||
char secretJoin[128] = "";
|
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);
|
strcpy(gCurActivity.secrets.join, secretJoin);
|
||||||
|
|
||||||
isHosting = true;
|
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) {
|
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) {
|
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++;
|
gCurActivity.party.size.current_size++;
|
||||||
discord_activity_update(true);
|
discord_activity_update(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_member_update(UNUSED void* data, int64_t lobbyId, int64_t userId) {
|
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) {
|
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);
|
u8 localIndex = discord_user_id_to_local_index(userId);
|
||||||
if (localIndex != UNKNOWN_LOCAL_INDEX && gNetworkPlayers[localIndex].connected) {
|
if (localIndex != UNKNOWN_LOCAL_INDEX && gNetworkPlayers[localIndex].connected) {
|
||||||
network_player_disconnected(gNetworkPlayers[localIndex].globalIndex);
|
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);
|
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;
|
isHosting = false;
|
||||||
gCurLobbyId = 0;
|
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) {
|
static int socket_receive(SOCKET socket, struct sockaddr_in* rxAddr, u8* buffer, u16 bufferLength, u16* receiveLength, u8* localIndex) {
|
||||||
*receiveLength = 0;
|
*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);
|
int rc = recvfrom(socket, (char*)buffer, bufferLength, 0, (struct sockaddr*)rxAddr, &rxAddrSize);
|
||||||
|
|
||||||
for (int i = 1; i < MAX_PLAYERS; i++) {
|
for (int i = 1; i < MAX_PLAYERS; i++) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ SOCKET socket_initialize(void) {
|
||||||
|
|
||||||
// set non-blocking mode
|
// set non-blocking mode
|
||||||
int rc = fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
|
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);
|
LOG_ERROR("fcntl failed with error: %d", rc);
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ SOCKET socket_initialize(void) {
|
||||||
void socket_shutdown(SOCKET socket) {
|
void socket_shutdown(SOCKET socket) {
|
||||||
if (socket == INVALID_SOCKET) { return; }
|
if (socket == INVALID_SOCKET) { return; }
|
||||||
int rc = closesocket(socket);
|
int rc = closesocket(socket);
|
||||||
if (rc == SOCKET_ERROR) {
|
if (rc == (int)SOCKET_ERROR) {
|
||||||
LOG_ERROR("closesocket failed with error %d\n", SOCKET_LAST_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) {
|
u32 clock_elapsed_ticks(void) {
|
||||||
return (clock_elapsed_ns() * 3 / 100000000);
|
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
|
#ifndef UTILS_MISC_H
|
||||||
#define UTILS_MISC_H
|
#define UTILS_MISC_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
float smoothstep(float edge0, float edge1, float x);
|
float smoothstep(float edge0, float edge1, float x);
|
||||||
void update_all_mario_stars(void);
|
void update_all_mario_stars(void);
|
||||||
f32 clock_elapsed(void);
|
f32 clock_elapsed(void);
|
||||||
f64 clock_elapsed_f64(void);
|
f64 clock_elapsed_f64(void);
|
||||||
u32 clock_elapsed_ticks(void);
|
u32 clock_elapsed_ticks(void);
|
||||||
|
void file_get_line(char* buffer, size_t maxLength, FILE* fp);
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in a new issue