From 05999a9ae8a07996b712232ba46bdd3dce10f446 Mon Sep 17 00:00:00 2001 From: MysterD Date: Thu, 20 Jan 2022 21:46:22 -0800 Subject: [PATCH 1/8] Added key/bind names to controls menu --- build-windows-visual-studio/sm64ex.vcxproj | 4 +- .../sm64ex.vcxproj.filters | 6 + developer/sdl1.sh | 1 + src/pc/controller/controller_bind_mapping.c | 151 ++++++++++++++++++ src/pc/controller/controller_bind_mapping.h | 8 + src/pc/controller/controller_sdl.h | 4 + src/pc/controller/controller_sdl1.c | 3 - src/pc/controller/controller_sdl2.c | 3 - src/pc/djui/djui_bind.c | 17 +- src/pc/djui/djui_panel_controls.c | 4 +- src/pc/gfx/gfx_direct3d11.cpp | 6 + src/pc/gfx/gfx_direct3d12.cpp | 6 + src/pc/gfx/gfx_sdl1.c | 78 +-------- src/pc/gfx/gfx_sdl2.c | 79 +-------- 14 files changed, 201 insertions(+), 169 deletions(-) create mode 100644 developer/sdl1.sh create mode 100644 src/pc/controller/controller_bind_mapping.c create mode 100644 src/pc/controller/controller_bind_mapping.h diff --git a/build-windows-visual-studio/sm64ex.vcxproj b/build-windows-visual-studio/sm64ex.vcxproj index ead60679..05f69d36 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj +++ b/build-windows-visual-studio/sm64ex.vcxproj @@ -89,7 +89,7 @@ Level3 true - _DEBUG;_CONSOLE;WINSOCK;DEBUG;CAPI_SDL2;WAPI_SDL2;RAPI_GL;F3DEX_GBI_2;_LANGUAGE_C;BETTERCAMERA;VERSION_US;EXT_OPTIONS_MENU;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WINSOCK;DEBUG;CAPI_SDL2;WAPI_SDL2;RAPI_GL;F3DEX_GBI_2;_LANGUAGE_C;BETTERCAMERA;VERSION_US;EXT_OPTIONS_MENU;HAVE_SDL2;%(PreprocessorDefinitions) true @@ -3936,6 +3936,7 @@ + @@ -4394,6 +4395,7 @@ + diff --git a/build-windows-visual-studio/sm64ex.vcxproj.filters b/build-windows-visual-studio/sm64ex.vcxproj.filters index ad3260ae..f7e38ee8 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj.filters +++ b/build-windows-visual-studio/sm64ex.vcxproj.filters @@ -15288,6 +15288,9 @@ Source Files\src\pc\network\packets + + Source Files\src\pc\controller + @@ -16387,5 +16390,8 @@ Header Files\actors + + Source Files\src\pc\controller + \ No newline at end of file diff --git a/developer/sdl1.sh b/developer/sdl1.sh new file mode 100644 index 00000000..b83c4046 --- /dev/null +++ b/developer/sdl1.sh @@ -0,0 +1 @@ +make RENDER_API=GL WINDOW_API=SDL1 AUDIO_API=SDL1 CONTROLLER_API=SDL1 BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1 DEVELOPMENT=1 && ./build/us_pc/sm64.us.f3dex2e.exe diff --git a/src/pc/controller/controller_bind_mapping.c b/src/pc/controller/controller_bind_mapping.c new file mode 100644 index 00000000..3f322d78 --- /dev/null +++ b/src/pc/controller/controller_bind_mapping.c @@ -0,0 +1,151 @@ +#ifdef HAVE_SDL2 +#include +#else +#include +#endif + +#include "controller_bind_mapping.h" +#include "controller_api.h" +#include "controller_sdl.h" + +static int inverted_scancode_table[512]; +static SDL_Scancode bind_to_sdl_scancode[512] = { 0 }; + +const SDL_Scancode windows_scancode_table[] = { + /* 0 1 2 3 4 5 6 7 */ + /* 8 9 A B C D E F */ + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_ESCAPE, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6, /* 0 */ + SDL_SCANCODE_7, SDL_SCANCODE_8, SDL_SCANCODE_9, SDL_SCANCODE_0, SDL_SCANCODE_MINUS, SDL_SCANCODE_EQUALS, SDL_SCANCODE_BACKSPACE, SDL_SCANCODE_TAB, /* 0 */ + + SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_E, SDL_SCANCODE_R, SDL_SCANCODE_T, SDL_SCANCODE_Y, SDL_SCANCODE_U, SDL_SCANCODE_I, /* 1 */ + SDL_SCANCODE_O, SDL_SCANCODE_P, SDL_SCANCODE_LEFTBRACKET, SDL_SCANCODE_RIGHTBRACKET, SDL_SCANCODE_RETURN, SDL_SCANCODE_LCTRL, SDL_SCANCODE_A, SDL_SCANCODE_S, /* 1 */ + + SDL_SCANCODE_D, SDL_SCANCODE_F, SDL_SCANCODE_G, SDL_SCANCODE_H, SDL_SCANCODE_J, SDL_SCANCODE_K, SDL_SCANCODE_L, SDL_SCANCODE_SEMICOLON, /* 2 */ + SDL_SCANCODE_APOSTROPHE, SDL_SCANCODE_GRAVE, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_BACKSLASH, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_C, SDL_SCANCODE_V, /* 2 */ + + SDL_SCANCODE_B, SDL_SCANCODE_N, SDL_SCANCODE_M, SDL_SCANCODE_COMMA, SDL_SCANCODE_PERIOD, SDL_SCANCODE_SLASH, SDL_SCANCODE_RSHIFT, SDL_SCANCODE_PRINTSCREEN,/* 3 */ + SDL_SCANCODE_LALT, SDL_SCANCODE_SPACE, SDL_SCANCODE_CAPSLOCK, SDL_SCANCODE_F1, SDL_SCANCODE_F2, SDL_SCANCODE_F3, SDL_SCANCODE_F4, SDL_SCANCODE_F5, /* 3 */ + + SDL_SCANCODE_F6, SDL_SCANCODE_F7, SDL_SCANCODE_F8, SDL_SCANCODE_F9, SDL_SCANCODE_F10, SDL_SCANCODE_NUMLOCKCLEAR, SDL_SCANCODE_SCROLLLOCK, SDL_SCANCODE_HOME, /* 4 */ + SDL_SCANCODE_UP, SDL_SCANCODE_PAGEUP, SDL_SCANCODE_KP_MINUS, SDL_SCANCODE_LEFT, SDL_SCANCODE_KP_5, SDL_SCANCODE_RIGHT, SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_END, /* 4 */ + + SDL_SCANCODE_DOWN, SDL_SCANCODE_PAGEDOWN, SDL_SCANCODE_INSERT, SDL_SCANCODE_DELETE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_NONUSBACKSLASH, SDL_SCANCODE_F11, /* 5 */ + SDL_SCANCODE_F12, SDL_SCANCODE_PAUSE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_LGUI, SDL_SCANCODE_RGUI, SDL_SCANCODE_APPLICATION, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 5 */ + + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_F13, SDL_SCANCODE_F14, SDL_SCANCODE_F15, SDL_SCANCODE_F16, /* 6 */ + SDL_SCANCODE_F17, SDL_SCANCODE_F18, SDL_SCANCODE_F19, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 6 */ + + SDL_SCANCODE_INTERNATIONAL2, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL1, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 7 */ + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL4, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL5, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL3, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN /* 7 */ +}; + +const SDL_Scancode scancode_rmapping_extended[][2] = { + {SDL_SCANCODE_KP_ENTER, SDL_SCANCODE_RETURN}, + {SDL_SCANCODE_RALT, SDL_SCANCODE_LALT}, + {SDL_SCANCODE_RCTRL, SDL_SCANCODE_LCTRL}, + {SDL_SCANCODE_KP_DIVIDE, SDL_SCANCODE_SLASH}, + //{SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_CAPSLOCK} +}; + +const SDL_Scancode scancode_rmapping_nonextended[][2] = { + {SDL_SCANCODE_KP_7, SDL_SCANCODE_HOME}, + {SDL_SCANCODE_KP_8, SDL_SCANCODE_UP}, + {SDL_SCANCODE_KP_9, SDL_SCANCODE_PAGEUP}, + {SDL_SCANCODE_KP_4, SDL_SCANCODE_LEFT}, + {SDL_SCANCODE_KP_6, SDL_SCANCODE_RIGHT}, + {SDL_SCANCODE_KP_1, SDL_SCANCODE_END}, + {SDL_SCANCODE_KP_2, SDL_SCANCODE_DOWN}, + {SDL_SCANCODE_KP_3, SDL_SCANCODE_PAGEDOWN}, + {SDL_SCANCODE_KP_0, SDL_SCANCODE_INSERT}, + {SDL_SCANCODE_KP_PERIOD, SDL_SCANCODE_DELETE}, + {SDL_SCANCODE_KP_MULTIPLY, SDL_SCANCODE_PRINTSCREEN} +}; + +void controller_bind_init(void) { + for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDL_Scancode); i++) { + inverted_scancode_table[windows_scancode_table[i]] = i; + } + + for (size_t i = 0; i < sizeof(scancode_rmapping_extended) / sizeof(scancode_rmapping_extended[0]); i++) { + inverted_scancode_table[scancode_rmapping_extended[i][0]] = inverted_scancode_table[scancode_rmapping_extended[i][1]] + 0x100; + } + + for (size_t i = 0; i < sizeof(scancode_rmapping_nonextended) / sizeof(scancode_rmapping_nonextended[0]); i++) { + inverted_scancode_table[scancode_rmapping_nonextended[i][0]] = inverted_scancode_table[scancode_rmapping_nonextended[i][1]]; + inverted_scancode_table[scancode_rmapping_nonextended[i][1]] += 0x100; + } + + for (size_t i = 0; i < 512; i++) { + if (inverted_scancode_table[i] >= 512) { continue; } + bind_to_sdl_scancode[inverted_scancode_table[i]] = i; + } + +} + +int translate_sdl_scancode(int scancode) { + if (scancode < 512) { + return inverted_scancode_table[scancode]; + } + else { + return 0; + } +} + +const char* translate_bind_to_name(int bind) { + static char name[11] = { 0 }; + sprintf(name, "%04X", bind); + + if (bind == VK_INVALID) { return ""; } + + // mouse + if (bind >= VK_BASE_SDL_MOUSE) { + int mouse_button = (bind - VK_BASE_SDL_MOUSE); + if (mouse_button == 1) { return "L Mouse"; } + if (mouse_button == 2) { return "M Mouse"; } + if (mouse_button == 3) { return "R Mouse"; } + snprintf(name, 8, "Mouse %d", bind - VK_BASE_SDL_MOUSE); + return name; + } + + // gamepad + if (bind >= VK_BASE_SDL_GAMEPAD) { + int gamepad_button = (bind - VK_BASE_SDL_GAMEPAD); + switch (gamepad_button) { + case 0: return "[A]"; + case 1: return "[B]"; + case 2: return "[X]"; + case 3: return "[Y]"; + case 4: return "[Back]"; + case 5: return "[Guide]"; + case 6: return "[Start]"; + case 7: return "[L Stick]"; + case 8: return "[R Stick]"; + case 9: return "[L Bump]"; + case 10: return "[R Bump]"; + case 11: return "[DPAD Up]"; + case 12: return "[DPAD Down]"; + case 13: return "[DPAD Left]"; + case 14: return "[DPAD Right]"; + case 0x1A: return "[L Trig]"; + case 0x1B: return "[R Trig]"; + default: return name; + } + } + + // keyboard + if (bind >= 512) { return name; } + + SDL_Scancode sc = bind_to_sdl_scancode[bind]; + if (sc == 0) { return name; } + +#ifdef HAVE_SDL2 + const char* sname = SDL_GetScancodeName(sc); + if (strlen(sname) <= 9) { return sname; } + + char* space = strchr(sname, ' '); + if (space == NULL) { return sname; } + + sprintf_s(name, 10, "%c%s", sname[0], (space + 1)); +#endif + return name; +} diff --git a/src/pc/controller/controller_bind_mapping.h b/src/pc/controller/controller_bind_mapping.h new file mode 100644 index 00000000..fee0bf52 --- /dev/null +++ b/src/pc/controller/controller_bind_mapping.h @@ -0,0 +1,8 @@ +#ifndef CONTROLLER_BIND_MAPPING_H +#define CONTROLLER_BIND_MAPPING_H + +void controller_bind_init(void); +int translate_sdl_scancode(int scancode); +const char* translate_bind_to_name(int bind); + +#endif \ No newline at end of file diff --git a/src/pc/controller/controller_sdl.h b/src/pc/controller/controller_sdl.h index d858af6c..ea4ad0fc 100644 --- a/src/pc/controller/controller_sdl.h +++ b/src/pc/controller/controller_sdl.h @@ -5,6 +5,10 @@ #define VK_BASE_SDL_GAMEPAD 0x1000 +// mouse buttons are also in the controller namespace (why), just offset 0x100 +#define VK_OFS_SDL_MOUSE 0x0100 +#define VK_BASE_SDL_MOUSE (VK_BASE_SDL_GAMEPAD + VK_OFS_SDL_MOUSE) + extern struct ControllerAPI controller_sdl; void controller_sdl_read_mouse_window(void); diff --git a/src/pc/controller/controller_sdl1.c b/src/pc/controller/controller_sdl1.c index d332e707..33c935e2 100644 --- a/src/pc/controller/controller_sdl1.c +++ b/src/pc/controller/controller_sdl1.c @@ -26,9 +26,6 @@ #include "pc/djui/djui.h" -// mouse buttons are also in the controller namespace (why), just offset 0x100 -#define VK_OFS_SDL_MOUSE 0x0100 -#define VK_BASE_SDL_MOUSE (VK_BASE_SDL_GAMEPAD + VK_OFS_SDL_MOUSE) #define MAX_JOYBINDS 32 #define MAX_MOUSEBUTTONS 8 // arbitrary #define MAX_JOYBUTTONS 32 // arbitrary; includes virtual keys for triggers diff --git a/src/pc/controller/controller_sdl2.c b/src/pc/controller/controller_sdl2.c index 75ec306a..a06b72e1 100644 --- a/src/pc/controller/controller_sdl2.c +++ b/src/pc/controller/controller_sdl2.c @@ -26,9 +26,6 @@ #include "pc/djui/djui.h" -// mouse buttons are also in the controller namespace (why), just offset 0x100 -#define VK_OFS_SDL_MOUSE 0x0100 -#define VK_BASE_SDL_MOUSE (VK_BASE_SDL_GAMEPAD + VK_OFS_SDL_MOUSE) #define MAX_JOYBINDS 32 #define MAX_MOUSEBUTTONS 8 // arbitrary #define MAX_JOYBUTTONS 32 // arbitrary; includes virtual keys for triggers diff --git a/src/pc/djui/djui_bind.c b/src/pc/djui/djui_bind.c index bbbaf006..71eda6e8 100644 --- a/src/pc/djui/djui_bind.c +++ b/src/pc/djui/djui_bind.c @@ -2,6 +2,7 @@ #include #include "djui.h" #include "src/pc/controller/controller_api.h" +#include "src/pc/controller/controller_bind_mapping.h" #include "audio_defines.h" #include "audio/external.h" @@ -32,11 +33,7 @@ static void djui_bind_button_on_bind(struct DjuiBase* caller) { // set key bind->configKey[button->base.tag] = key; - char keyStr[5] = { 0 }; - if (key != VK_INVALID) { - sprintf(keyStr, "%04x", key); - } - djui_text_set_text(button->text, keyStr); + djui_text_set_text(button->text, translate_bind_to_name(key)); djui_interactable_set_binding(NULL); play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs); controller_reconfigure(); @@ -55,7 +52,7 @@ struct DjuiBind* djui_bind_create(struct DjuiBase* parent, const char* message, djui_base_init(parent, base, NULL, djui_bind_destroy); djui_base_set_size_type(&bind->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); - djui_base_set_size(&bind->base, 1.0f, 32); + djui_base_set_size(&bind->base, 1.0f, 28); djui_base_set_color(&bind->base, 0, 0, 0, 0); struct DjuiText* text = djui_text_create(&bind->base, message); @@ -70,17 +67,13 @@ struct DjuiBind* djui_bind_create(struct DjuiBase* parent, const char* message, struct DjuiRect* rect = djui_rect_create(&bind->base); djui_base_set_alignment(&rect->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_CENTER); djui_base_set_size_type(&rect->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE); - djui_base_set_size(&rect->base, 0.7f, 1.0f); + djui_base_set_size(&rect->base, 0.8f, 1.0f); djui_base_set_color(&rect->base, 0, 0, 0, 0); bind->rect = rect; for (int i = 0; i < MAX_BINDS; i++) { unsigned int key = configKey[i]; - char keyStr[5] = { 0 }; - if (key != VK_INVALID) { - sprintf(keyStr, "%04x", key); - } - struct DjuiButton* button = djui_button_create(&rect->base, keyStr); + struct DjuiButton* button = djui_button_create(&rect->base, translate_bind_to_name(key)); djui_base_set_size_type(&button->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE); djui_base_set_size(&button->base, 0.33f, 1.0f); button->base.tag = i; diff --git a/src/pc/djui/djui_panel_controls.c b/src/pc/djui/djui_panel_controls.c index a3520a99..7b04739e 100644 --- a/src/pc/djui/djui_panel_controls.c +++ b/src/pc/djui/djui_panel_controls.c @@ -8,7 +8,7 @@ void djui_panel_controls_value_change(UNUSED struct DjuiBase* caller) { } void djui_panel_controls_create(struct DjuiBase* caller) { - f32 bindBodyHeight = 32 * 12 + 1 * 11; + f32 bindBodyHeight = 32 * 11 + 1 * 10; f32 bodyHeight = bindBodyHeight + 16 * 3 + 32 * 2 + 64; struct DjuiBase* defaultBase = NULL; @@ -32,7 +32,7 @@ void djui_panel_controls_create(struct DjuiBase* caller) { djui_bind_create(&bindBody->base, "C Left", configKeyCLeft); djui_bind_create(&bindBody->base, "C Right", configKeyCRight); djui_bind_create(&bindBody->base, "Chat", configKeyChat); - djui_bind_create(&bindBody->base, "Player List", configKeyPlayerList); + djui_bind_create(&bindBody->base, "Players", configKeyPlayerList); defaultBase = &bind1->buttons[0]->base; } diff --git a/src/pc/gfx/gfx_direct3d11.cpp b/src/pc/gfx/gfx_direct3d11.cpp index d27524b7..2a9d974a 100644 --- a/src/pc/gfx/gfx_direct3d11.cpp +++ b/src/pc/gfx/gfx_direct3d11.cpp @@ -22,6 +22,10 @@ #include "gfx_rendering_api.h" #include "gfx_direct3d_common.h" +extern "C" { + #include "src/pc/controller/controller_bind_mapping.h" +} + #define DECLARE_GFX_DXGI_FUNCTIONS #include "gfx_dxgi.h" @@ -303,6 +307,8 @@ static void gfx_d3d11_init(void) { gfx_dxgi_get_h_wnd(), "Failed to create per-draw constant buffer."); d3d.context->PSSetConstantBuffers(1, 1, d3d.per_draw_cb.GetAddressOf()); + + controller_bind_init(); } diff --git a/src/pc/gfx/gfx_direct3d12.cpp b/src/pc/gfx/gfx_direct3d12.cpp index 2a31043b..fb3acf11 100644 --- a/src/pc/gfx/gfx_direct3d12.cpp +++ b/src/pc/gfx/gfx_direct3d12.cpp @@ -37,6 +37,10 @@ #include "gfx_rendering_api.h" #include "gfx_direct3d_common.h" +extern "C" { + #include "src/pc/controller/controller_bind_mapping.h" +} + #include "gfx_screen_config.h" #define DEBUG_D3D 0 @@ -866,6 +870,8 @@ static void gfx_direct3d12_init(void ) { CD3DX12_RANGE read_range(0, 0); // Read not possible from CPU ThrowIfFailed(d3d.vertex_buffer->Map(0, &read_range, &d3d.mapped_vbuf_address)); } + + controller_bind_init(); } static void gfx_direct3d12_end_frame(void) { diff --git a/src/pc/gfx/gfx_sdl1.c b/src/pc/gfx/gfx_sdl1.c index 436ae729..da046283 100644 --- a/src/pc/gfx/gfx_sdl1.c +++ b/src/pc/gfx/gfx_sdl1.c @@ -19,6 +19,7 @@ #include "../platform.h" #include "src/pc/controller/controller_keyboard.h" +#include "src/pc/controller/controller_bind_mapping.h" // TODO: figure out if this shit even works #ifdef VERSION_EU @@ -27,8 +28,6 @@ # define FRAMERATE 30 #endif -static int inverted_scancode_table[512]; - static kb_callback_t kb_key_down = NULL; static kb_callback_t kb_key_up = NULL; static void (*kb_all_keys_up)(void) = NULL; @@ -43,56 +42,6 @@ static int desktop_bpp = 24; static int window_w = 0; static int window_h = 0; -const SDLKey windows_scancode_table[] = { - /* 0 1 2 3 4 5 6 7 */ - /* 8 9 A B C D E F */ - SDLK_UNKNOWN, SDLK_ESCAPE, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, /* 0 */ - SDLK_7, SDLK_8, SDLK_9, SDLK_0, SDLK_MINUS, SDLK_EQUALS, SDLK_BACKSPACE, SDLK_TAB, /* 0 */ - - SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, SDLK_i, /* 1 */ - SDLK_o, SDLK_p, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, SDLK_RETURN, SDLK_LCTRL, SDLK_a, SDLK_s, /* 1 */ - - SDLK_d, SDLK_f, SDLK_g, SDLK_h, SDLK_j, SDLK_k, SDLK_l, SDLK_SEMICOLON, /* 2 */ - SDLK_UNKNOWN, SDLK_BACKQUOTE, SDLK_LSHIFT, SDLK_BACKSLASH, SDLK_z, SDLK_x, SDLK_c, SDLK_v, /* 2 */ - - SDLK_b, SDLK_n, SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH, SDLK_RSHIFT, SDLK_PRINT, /* 3 */ - SDLK_LALT, SDLK_SPACE, SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, /* 3 */ - - SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCK, SDLK_SCROLLOCK, SDLK_HOME, /* 4 */ - SDLK_UP, SDLK_PAGEUP, SDLK_KP_MINUS, SDLK_LEFT, SDLK_KP5, SDLK_RIGHT, SDLK_KP_PLUS, SDLK_END, /* 4 */ - - SDLK_DOWN, SDLK_PAGEDOWN, SDLK_INSERT, SDLK_DELETE, SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_F11, /* 5 */ - SDLK_F12, SDLK_PAUSE, SDLK_UNKNOWN, SDLK_LSUPER, SDLK_RSUPER, SDLK_MODE, SDLK_UNKNOWN, SDLK_UNKNOWN, /* 5 */ - - SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_F13, SDLK_F14, SDLK_F15, SDLK_UNKNOWN, /* 6 */ - SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_UNKNOWN, /* 6 */ - - SDLK_WORLD_2, SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_WORLD_1, SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_UNKNOWN, SDLK_UNKNOWN, /* 7 */ - SDLK_UNKNOWN, SDLK_WORLD_4, SDLK_UNKNOWN, SDLK_WORLD_5, SDLK_UNKNOWN, SDLK_WORLD_3, SDLK_UNKNOWN, SDLK_UNKNOWN /* 7 */ -}; - -const SDLKey scancode_rmapping_extended[][2] = { - { SDLK_KP_ENTER, SDLK_RETURN }, - { SDLK_RALT, SDLK_LALT }, - { SDLK_RCTRL, SDLK_LCTRL }, - { SDLK_KP_DIVIDE, SDLK_SLASH }, - //{ SDLK_KPPLUS, SDLK_CAPSLOCK } -}; - -const SDLKey scancode_rmapping_nonextended[][2] = { - { SDLK_KP7, SDLK_HOME }, - { SDLK_KP8, SDLK_UP }, - { SDLK_KP9, SDLK_PAGEUP }, - { SDLK_KP4, SDLK_LEFT }, - { SDLK_KP6, SDLK_RIGHT }, - { SDLK_KP1, SDLK_END }, - { SDLK_KP2, SDLK_DOWN }, - { SDLK_KP3, SDLK_PAGEDOWN }, - { SDLK_KP0, SDLK_INSERT }, - { SDLK_KP_PERIOD, SDLK_DELETE }, - { SDLK_KP_MULTIPLY, SDLK_PRINT } -}; - static void gfx_sdl_set_mode(void) { if (configWindow.exiting_fullscreen) configWindow.exiting_fullscreen = false; @@ -160,18 +109,7 @@ static void gfx_sdl_init(const char *window_title) { SDL_ShowCursor(0); } - for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDLKey); i++) { - inverted_scancode_table[windows_scancode_table[i]] = i; - } - - for (size_t i = 0; i < sizeof(scancode_rmapping_extended) / sizeof(scancode_rmapping_extended[0]); i++) { - inverted_scancode_table[scancode_rmapping_extended[i][0]] = inverted_scancode_table[scancode_rmapping_extended[i][1]] + 0x100; - } - - for (size_t i = 0; i < sizeof(scancode_rmapping_nonextended) / sizeof(scancode_rmapping_nonextended[0]); i++) { - inverted_scancode_table[scancode_rmapping_nonextended[i][0]] = inverted_scancode_table[scancode_rmapping_nonextended[i][1]]; - inverted_scancode_table[scancode_rmapping_nonextended[i][1]] += 0x100; - } + controller_bind_init(); } static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) { @@ -183,22 +121,14 @@ static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) { if (height) *height = window_h; } -static int translate_scancode(int scancode) { - if (scancode < 512) { - return inverted_scancode_table[scancode]; - } else { - return 0; - } -} - static void gfx_sdl_onkeydown(int scancode) { if (kb_key_down) - kb_key_down(translate_scancode(scancode)); + kb_key_down(translate_bind_to_name(scancode)); } static void gfx_sdl_onkeyup(int scancode) { if (kb_key_up) - kb_key_up(translate_scancode(scancode)); + kb_key_up(translate_bind_to_name(scancode)); } static void gfx_sdl_handle_events(void) { diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c index cf8f71e4..646dd287 100644 --- a/src/pc/gfx/gfx_sdl2.c +++ b/src/pc/gfx/gfx_sdl2.c @@ -34,7 +34,8 @@ #include "../cliopts.h" #include "src/pc/controller/controller_keyboard.h" - +#include "src/pc/controller/controller_sdl.h" +#include "src/pc/controller/controller_bind_mapping.h" #include "pc/utils/misc.h" // TODO: figure out if this shit even works @@ -49,63 +50,12 @@ static f64 sFrameTargetTime = 0; static SDL_Window *wnd; static SDL_GLContext ctx = NULL; -static int inverted_scancode_table[512]; static kb_callback_t kb_key_down = NULL; static kb_callback_t kb_key_up = NULL; static void (*kb_all_keys_up)(void) = NULL; static void (*kb_text_input)(char*) = NULL; -const SDL_Scancode windows_scancode_table[] = { - /* 0 1 2 3 4 5 6 7 */ - /* 8 9 A B C D E F */ - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_ESCAPE, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6, /* 0 */ - SDL_SCANCODE_7, SDL_SCANCODE_8, SDL_SCANCODE_9, SDL_SCANCODE_0, SDL_SCANCODE_MINUS, SDL_SCANCODE_EQUALS, SDL_SCANCODE_BACKSPACE, SDL_SCANCODE_TAB, /* 0 */ - - SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_E, SDL_SCANCODE_R, SDL_SCANCODE_T, SDL_SCANCODE_Y, SDL_SCANCODE_U, SDL_SCANCODE_I, /* 1 */ - SDL_SCANCODE_O, SDL_SCANCODE_P, SDL_SCANCODE_LEFTBRACKET, SDL_SCANCODE_RIGHTBRACKET, SDL_SCANCODE_RETURN, SDL_SCANCODE_LCTRL, SDL_SCANCODE_A, SDL_SCANCODE_S, /* 1 */ - - SDL_SCANCODE_D, SDL_SCANCODE_F, SDL_SCANCODE_G, SDL_SCANCODE_H, SDL_SCANCODE_J, SDL_SCANCODE_K, SDL_SCANCODE_L, SDL_SCANCODE_SEMICOLON, /* 2 */ - SDL_SCANCODE_APOSTROPHE, SDL_SCANCODE_GRAVE, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_BACKSLASH, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_C, SDL_SCANCODE_V, /* 2 */ - - SDL_SCANCODE_B, SDL_SCANCODE_N, SDL_SCANCODE_M, SDL_SCANCODE_COMMA, SDL_SCANCODE_PERIOD, SDL_SCANCODE_SLASH, SDL_SCANCODE_RSHIFT, SDL_SCANCODE_PRINTSCREEN,/* 3 */ - SDL_SCANCODE_LALT, SDL_SCANCODE_SPACE, SDL_SCANCODE_CAPSLOCK, SDL_SCANCODE_F1, SDL_SCANCODE_F2, SDL_SCANCODE_F3, SDL_SCANCODE_F4, SDL_SCANCODE_F5, /* 3 */ - - SDL_SCANCODE_F6, SDL_SCANCODE_F7, SDL_SCANCODE_F8, SDL_SCANCODE_F9, SDL_SCANCODE_F10, SDL_SCANCODE_NUMLOCKCLEAR, SDL_SCANCODE_SCROLLLOCK, SDL_SCANCODE_HOME, /* 4 */ - SDL_SCANCODE_UP, SDL_SCANCODE_PAGEUP, SDL_SCANCODE_KP_MINUS, SDL_SCANCODE_LEFT, SDL_SCANCODE_KP_5, SDL_SCANCODE_RIGHT, SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_END, /* 4 */ - - SDL_SCANCODE_DOWN, SDL_SCANCODE_PAGEDOWN, SDL_SCANCODE_INSERT, SDL_SCANCODE_DELETE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_NONUSBACKSLASH, SDL_SCANCODE_F11, /* 5 */ - SDL_SCANCODE_F12, SDL_SCANCODE_PAUSE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_LGUI, SDL_SCANCODE_RGUI, SDL_SCANCODE_APPLICATION, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 5 */ - - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_F13, SDL_SCANCODE_F14, SDL_SCANCODE_F15, SDL_SCANCODE_F16, /* 6 */ - SDL_SCANCODE_F17, SDL_SCANCODE_F18, SDL_SCANCODE_F19, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 6 */ - - SDL_SCANCODE_INTERNATIONAL2, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL1, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 7 */ - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL4, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL5, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL3, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN /* 7 */ -}; - -const SDL_Scancode scancode_rmapping_extended[][2] = { - {SDL_SCANCODE_KP_ENTER, SDL_SCANCODE_RETURN}, - {SDL_SCANCODE_RALT, SDL_SCANCODE_LALT}, - {SDL_SCANCODE_RCTRL, SDL_SCANCODE_LCTRL}, - {SDL_SCANCODE_KP_DIVIDE, SDL_SCANCODE_SLASH}, - //{SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_CAPSLOCK} -}; - -const SDL_Scancode scancode_rmapping_nonextended[][2] = { - {SDL_SCANCODE_KP_7, SDL_SCANCODE_HOME}, - {SDL_SCANCODE_KP_8, SDL_SCANCODE_UP}, - {SDL_SCANCODE_KP_9, SDL_SCANCODE_PAGEUP}, - {SDL_SCANCODE_KP_4, SDL_SCANCODE_LEFT}, - {SDL_SCANCODE_KP_6, SDL_SCANCODE_RIGHT}, - {SDL_SCANCODE_KP_1, SDL_SCANCODE_END}, - {SDL_SCANCODE_KP_2, SDL_SCANCODE_DOWN}, - {SDL_SCANCODE_KP_3, SDL_SCANCODE_PAGEDOWN}, - {SDL_SCANCODE_KP_0, SDL_SCANCODE_INSERT}, - {SDL_SCANCODE_KP_PERIOD, SDL_SCANCODE_DELETE}, - {SDL_SCANCODE_KP_MULTIPLY, SDL_SCANCODE_PRINTSCREEN} -}; - #define IS_FULLSCREEN() ((SDL_GetWindowFlags(wnd) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) int test_vsync(void) { @@ -211,18 +161,7 @@ static void gfx_sdl_init(const char *window_title) { SDL_ShowCursor(SDL_DISABLE); } - for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDL_Scancode); i++) { - inverted_scancode_table[windows_scancode_table[i]] = i; - } - - for (size_t i = 0; i < sizeof(scancode_rmapping_extended) / sizeof(scancode_rmapping_extended[0]); i++) { - inverted_scancode_table[scancode_rmapping_extended[i][0]] = inverted_scancode_table[scancode_rmapping_extended[i][1]] + 0x100; - } - - for (size_t i = 0; i < sizeof(scancode_rmapping_nonextended) / sizeof(scancode_rmapping_nonextended[0]); i++) { - inverted_scancode_table[scancode_rmapping_nonextended[i][0]] = inverted_scancode_table[scancode_rmapping_nonextended[i][1]]; - inverted_scancode_table[scancode_rmapping_nonextended[i][1]] += 0x100; - } + controller_bind_init(); } static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) { @@ -236,17 +175,9 @@ static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) { if (height) *height = h; } -static int translate_scancode(int scancode) { - if (scancode < 512) { - return inverted_scancode_table[scancode]; - } else { - return 0; - } -} - static void gfx_sdl_onkeydown(int scancode) { if (kb_key_down) - kb_key_down(translate_scancode(scancode)); + kb_key_down(translate_sdl_scancode(scancode)); const Uint8 *state = SDL_GetKeyboardState(NULL); @@ -258,7 +189,7 @@ static void gfx_sdl_onkeydown(int scancode) { static void gfx_sdl_onkeyup(int scancode) { if (kb_key_up) - kb_key_up(translate_scancode(scancode)); + kb_key_up(translate_sdl_scancode(scancode)); } static void gfx_sdl_handle_events(void) { From 8837dcc023ed849b3dd00bcd08dc9897a41774ad Mon Sep 17 00:00:00 2001 From: MysterD Date: Thu, 20 Jan 2022 21:52:14 -0800 Subject: [PATCH 2/8] Removed server enforcement of unique player palettes --- src/pc/network/network_player.c | 16 ---------------- src/pc/network/network_player.h | 1 - src/pc/network/packets/packet_join.c | 3 --- 3 files changed, 20 deletions(-) diff --git a/src/pc/network/network_player.c b/src/pc/network/network_player.c index 0c22863e..11d25797 100644 --- a/src/pc/network/network_player.c +++ b/src/pc/network/network_player.c @@ -25,22 +25,6 @@ void network_player_update_model(u8 localIndex) { m->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[m->character->modelId]; } -u8 network_player_unique_palette(u8 palette) { - u16 iterations = 0; - retry_palette: - for (int i = 0; i < MAX_PLAYERS; i++) { - if (!gNetworkPlayers[i].connected) { continue; } - if (gNetworkPlayers[i].paletteIndex == palette) { - palette = (palette + 1) % gNumPlayerColors; - if (iterations++ >= gNumPlayerColors) { - return palette; - } - goto retry_palette; - } - } - return palette; -} - bool network_player_any_connected(void) { for (int i = 1; i < MAX_PLAYERS; i++) { if (gNetworkPlayers[i].connected) { return true; } diff --git a/src/pc/network/network_player.h b/src/pc/network/network_player.h index d27927da..3ea716ce 100644 --- a/src/pc/network/network_player.h +++ b/src/pc/network/network_player.h @@ -48,7 +48,6 @@ extern struct NetworkPlayer* gNetworkPlayerServer; void network_player_init(void); void network_player_update_model(u8 localIndex); -u8 network_player_unique_palette(u8 palette); bool network_player_any_connected(void); u8 network_player_connected_count(void); struct NetworkPlayer* network_player_from_global_index(u8 globalIndex); diff --git a/src/pc/network/packets/packet_join.c b/src/pc/network/packets/packet_join.c index 62fe90ff..bbd2e0d1 100644 --- a/src/pc/network/packets/packet_join.c +++ b/src/pc/network/packets/packet_join.c @@ -61,9 +61,6 @@ void network_receive_join_request(struct Packet* p) { void network_send_join(struct Packet* joinRequestPacket) { SOFT_ASSERT(gNetworkType == NT_SERVER); - // make palette unique - sJoinRequestPlayerPalette = network_player_unique_palette(sJoinRequestPlayerPalette); - // do connection event joinRequestPacket->localIndex = network_player_connected(NPT_CLIENT, joinRequestPacket->localIndex, sJoinRequestPlayerModel, sJoinRequestPlayerPalette, sJoinRequestPlayerName); if (joinRequestPacket->localIndex == UNKNOWN_LOCAL_INDEX) { From f45ae4a115e809f2c7e7f884deedeff9555cfa9e Mon Sep 17 00:00:00 2001 From: MysterD Date: Thu, 20 Jan 2022 22:23:29 -0800 Subject: [PATCH 3/8] Allow players to change name/model/palette while connected --- src/pc/djui/djui_panel_options.c | 17 +++---- src/pc/djui/djui_panel_player.c | 8 ++++ src/pc/network/network_player.h | 2 +- src/pc/network/packets/packet.c | 2 + src/pc/network/packets/packet.h | 6 +++ .../network/packets/packet_player_settings.c | 45 +++++++++++++++++++ 6 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 src/pc/network/packets/packet_player_settings.c diff --git a/src/pc/djui/djui_panel_options.c b/src/pc/djui/djui_panel_options.c index 52a33560..8d745d30 100644 --- a/src/pc/djui/djui_panel_options.c +++ b/src/pc/djui/djui_panel_options.c @@ -8,22 +8,17 @@ void djui_panel_options_back(struct DjuiBase* caller) { } void djui_panel_options_create(struct DjuiBase* caller) { - f32 bodyHeight = 64 * 5 + 16 * 4; - if (gNetworkType == NT_NONE) { - bodyHeight += 64 + 16; - } + f32 bodyHeight = 64 * 6 + 16 * 5; struct DjuiBase* defaultBase = NULL; struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\O\\#1be700\\P\\#00b3ff\\T\\#ffef00\\I\\#ff0800\\O\\#1be700\\N\\#00b3ff\\S"); struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel); { - if (gNetworkType == NT_NONE) { - struct DjuiButton* button1 = djui_button_create(&body->base, "Player"); - djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); - djui_base_set_size(&button1->base, 1.0f, 64); - djui_interactable_hook_click(&button1->base, djui_panel_player_create); - defaultBase = &button1->base; - } + struct DjuiButton* button1 = djui_button_create(&body->base, "Player"); + djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&button1->base, 1.0f, 64); + djui_interactable_hook_click(&button1->base, djui_panel_player_create); + defaultBase = &button1->base; struct DjuiButton* button2 = djui_button_create(&body->base, "Camera"); djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); diff --git a/src/pc/djui/djui_panel_player.c b/src/pc/djui/djui_panel_player.c index 25944a5b..d0a22f8e 100644 --- a/src/pc/djui/djui_panel_player.c +++ b/src/pc/djui/djui_panel_player.c @@ -33,6 +33,10 @@ static void djui_panel_player_name_on_focus_end(struct DjuiBase* caller) { } snprintf(configPlayerName, 20, "%s", inputbox1->buffer); djui_inputbox_set_text_color(inputbox1, 0, 0, 0, 255); + + if (gNetworkType != NT_NONE) { + network_send_player_settings(); + } } void djui_panel_player_value_changed(UNUSED struct DjuiBase* caller) { @@ -40,6 +44,10 @@ void djui_panel_player_value_changed(UNUSED struct DjuiBase* caller) { gNetworkPlayers[0].modelIndex = configPlayerModel; gNetworkPlayers[0].paletteIndex = configPlayerPalette; network_player_update_model(0); + + if (gNetworkType != NT_NONE) { + network_send_player_settings(); + } } void djui_panel_player_create(struct DjuiBase* caller) { diff --git a/src/pc/network/network_player.h b/src/pc/network/network_player.h index 3ea716ce..158bd63c 100644 --- a/src/pc/network/network_player.h +++ b/src/pc/network/network_player.h @@ -37,7 +37,7 @@ struct NetworkPlayer { u8 modelIndex; u8 paletteIndex; bool localLevelMatch; - char name[MAX_PLAYER_STRING]; + char name[MAX_PLAYER_STRING+1]; u16 rxSeqIds[MAX_RX_SEQ_IDS]; u32 rxPacketHash[MAX_RX_SEQ_IDS]; }; diff --git a/src/pc/network/packets/packet.c b/src/pc/network/packets/packet.c index c9955664..b15edbe8 100644 --- a/src/pc/network/packets/packet.c +++ b/src/pc/network/packets/packet.c @@ -76,6 +76,8 @@ void packet_process(struct Packet* p) { case PACKET_LEVEL_AREA_INFORM: network_receive_level_area_inform(p); break; case PACKET_LEVEL_RESPAWN_INFO: network_receive_level_respawn_info(p); break; + case PACKET_PLAYER_SETTINGS: network_receive_player_settings(p); break; + // custom case PACKET_CUSTOM: network_receive_custom(p); break; default: LOG_ERROR("received unknown packet: %d", p->buffer[0]); diff --git a/src/pc/network/packets/packet.h b/src/pc/network/packets/packet.h index d5c3c035..2d611936 100644 --- a/src/pc/network/packets/packet.h +++ b/src/pc/network/packets/packet.h @@ -52,6 +52,8 @@ enum PacketType { PACKET_LEVEL_AREA_INFORM, PACKET_LEVEL_RESPAWN_INFO, + PACKET_PLAYER_SETTINGS, + /// PACKET_CUSTOM = 255, }; @@ -275,4 +277,8 @@ void network_receive_reservation_release(struct Packet* p); void network_send_debug_sync(void); void network_receive_debug_sync(struct Packet* p); +// packet_player_settings.c +void network_send_player_settings(void); +void network_receive_player_settings(struct Packet* p); + #endif diff --git a/src/pc/network/packets/packet_player_settings.c b/src/pc/network/packets/packet_player_settings.c new file mode 100644 index 00000000..979c7455 --- /dev/null +++ b/src/pc/network/packets/packet_player_settings.c @@ -0,0 +1,45 @@ +#include +#include "../network.h" +#include "pc/debuglog.h" + +void network_send_player_settings(void) { + char playerName[MAX_PLAYER_STRING+1] = { 0 }; + snprintf(playerName, MAX_PLAYER_STRING, "%s", configPlayerName); + + struct Packet p; + packet_init(&p, PACKET_PLAYER_SETTINGS, true, PLMT_NONE); + packet_write(&p, &gNetworkPlayers[0].globalIndex, sizeof(u8)); + packet_write(&p, playerName, MAX_PLAYER_STRING * sizeof(u8)); + packet_write(&p, &configPlayerModel, sizeof(u8)); + packet_write(&p, &configPlayerPalette, sizeof(u8)); + + if (gNetworkPlayerLocal != NULL) { + snprintf(gNetworkPlayerLocal->name, MAX_PLAYER_STRING, "%s", playerName); + } + + network_send(&p); +} + +void network_receive_player_settings(struct Packet* p) { + u8 globalId; + char playerName[MAX_PLAYER_STRING+1] = { 0 }; + u8 playerModel; + u8 playerPalette; + + packet_read(p, &globalId, sizeof(u8)); + packet_read(p, &playerName, MAX_PLAYER_STRING * sizeof(u8)); + packet_read(p, &playerModel, sizeof(u8)); + packet_read(p, &playerPalette, sizeof(u8)); + + if (globalId == gNetworkPlayers[0].globalIndex || globalId > MAX_PLAYERS) { + LOG_ERROR("Received player settings from improper player."); + return; + } + + struct NetworkPlayer* np = network_player_from_global_index(globalId); + snprintf(np->name, MAX_PLAYER_STRING, "%s", playerName); + np->modelIndex = playerModel; + np->paletteIndex = playerPalette; + + network_player_update_model(np->localIndex); +} From 101a6400e08178a578919d42ce42d57f23582d7b Mon Sep 17 00:00:00 2001 From: MysterD Date: Thu, 20 Jan 2022 23:35:38 -0800 Subject: [PATCH 4/8] Added define guards around controller bind mappings --- src/pc/controller/controller_bind_mapping.c | 3 +++ src/pc/controller/controller_bind_mapping.h | 2 ++ src/pc/djui/djui_bind.c | 8 ++++++++ 3 files changed, 13 insertions(+) diff --git a/src/pc/controller/controller_bind_mapping.c b/src/pc/controller/controller_bind_mapping.c index 3f322d78..ab058efe 100644 --- a/src/pc/controller/controller_bind_mapping.c +++ b/src/pc/controller/controller_bind_mapping.c @@ -8,6 +8,8 @@ #include "controller_api.h" #include "controller_sdl.h" +#if defined(CAPI_SDL1) || defined(CAPI_SDL2) + static int inverted_scancode_table[512]; static SDL_Scancode bind_to_sdl_scancode[512] = { 0 }; @@ -149,3 +151,4 @@ const char* translate_bind_to_name(int bind) { #endif return name; } +#endif diff --git a/src/pc/controller/controller_bind_mapping.h b/src/pc/controller/controller_bind_mapping.h index fee0bf52..211172e0 100644 --- a/src/pc/controller/controller_bind_mapping.h +++ b/src/pc/controller/controller_bind_mapping.h @@ -1,8 +1,10 @@ #ifndef CONTROLLER_BIND_MAPPING_H #define CONTROLLER_BIND_MAPPING_H +#if defined(CAPI_SDL1) || defined(CAPI_SDL2) void controller_bind_init(void); int translate_sdl_scancode(int scancode); const char* translate_bind_to_name(int bind); +#endif #endif \ No newline at end of file diff --git a/src/pc/djui/djui_bind.c b/src/pc/djui/djui_bind.c index 71eda6e8..7640dd08 100644 --- a/src/pc/djui/djui_bind.c +++ b/src/pc/djui/djui_bind.c @@ -33,7 +33,11 @@ static void djui_bind_button_on_bind(struct DjuiBase* caller) { // set key bind->configKey[button->base.tag] = key; +#if defined(CAPI_SDL1) || defined(CAPI_SDL2) djui_text_set_text(button->text, translate_bind_to_name(key)); +#else + djui_text_set_text(button->text, "???"); +#endif djui_interactable_set_binding(NULL); play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs); controller_reconfigure(); @@ -72,8 +76,12 @@ struct DjuiBind* djui_bind_create(struct DjuiBase* parent, const char* message, bind->rect = rect; for (int i = 0; i < MAX_BINDS; i++) { +#if defined(CAPI_SDL1) || defined(CAPI_SDL2) unsigned int key = configKey[i]; struct DjuiButton* button = djui_button_create(&rect->base, translate_bind_to_name(key)); +#else + struct DjuiButton* button = djui_button_create(&rect->base, "???"); +#endif djui_base_set_size_type(&button->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE); djui_base_set_size(&button->base, 0.33f, 1.0f); button->base.tag = i; From 6a447c10f47d5aaf053ca9cad5eed46ba9065028 Mon Sep 17 00:00:00 2001 From: MysterD Date: Fri, 21 Jan 2022 00:56:54 -0800 Subject: [PATCH 5/8] Added ability to exit course, exiting out of the painting --- src/game/ingame_menu.c | 14 +++++++++----- src/game/level_update.c | 18 +++++++++++++++--- src/game/level_update.h | 1 + 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 7378e965..477adfab 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -2493,6 +2493,9 @@ void render_pause_camera_options(s16 x, s16 y, s8 *index, s16 xIndex) { #endif void render_pause_course_options(s16 x, s16 y, s8 *index, s16 yIndex) { + u8 TEXT_EXIT_TO_CASTLE[15] = { DIALOG_CHAR_TERMINATOR }; + str_ascii_to_dialog("EXIT TO CASTLE", TEXT_EXIT_TO_CASTLE, 15); + #ifdef VERSION_EU u8 textContinue[][10] = { { TEXT_CONTINUE }, @@ -2519,16 +2522,17 @@ void render_pause_course_options(s16 x, s16 y, s8 *index, s16 yIndex) { u8 textCameraAngleR[] = { TEXT_CAMERA_ANGLE_R }; #endif - handle_menu_scrolling(MENU_SCROLL_VERTICAL, index, 1, 3); + handle_menu_scrolling(MENU_SCROLL_VERTICAL, index, 1, 4); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); print_generic_string(x + 10, y - 2, textContinue); print_generic_string(x + 10, y - 17, textExitCourse); + print_generic_string(x + 10, y - 32, TEXT_EXIT_TO_CASTLE); - if (index[0] != 3) { - print_generic_string(x + 10, y - 33, textCameraAngleR); + if (index[0] != 4) { + print_generic_string(x + 10, y - 47, textCameraAngleR); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); create_dl_translation_matrix(MENU_MTX_PUSH, x - X_VAL8, (y - ((index[0] - 1) * yIndex)) - Y_VAL8, 0); @@ -2537,7 +2541,7 @@ void render_pause_course_options(s16 x, s16 y, s8 *index, s16 yIndex) { gSPDisplayList(gDisplayListHead++, dl_draw_triangle); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); } else { - render_pause_camera_options(x - 42, y - 42, &gDialogCameraAngleIndex, 110); + render_pause_camera_options(x - 42, y - 57, &gDialogCameraAngleIndex, 110); } } @@ -2775,7 +2779,7 @@ s16 render_pause_courses_and_castle(void) { gDialogBoxState = DIALOG_STATE_OPENING; gMenuMode = -1; - if (gDialogLineNum == 2) { + if (gDialogLineNum == 2 || gDialogLineNum == 3) { num = gDialogLineNum; } else { num = 1; diff --git a/src/game/level_update.c b/src/game/level_update.c index 2641b100..9a10e5a1 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -826,6 +826,15 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) { play_sound(SOUND_MENU_BOWSER_LAUGH, gDefaultSoundArgs); break; + case WARP_OP_EXIT: + sSourceWarpNodeId = WARP_NODE_WARP_FLOOR; + if (area_get_warp_node(sSourceWarpNodeId) == NULL) { + sSourceWarpNodeId = WARP_NODE_DEATH; + } + sDelayedWarpTimer = 20; + play_transition(WARP_TRANSITION_FADE_INTO_CIRCLE, 0x14, 0x00, 0x00, 0x00); + break; + case WARP_OP_WARP_FLOOR: sSourceWarpNodeId = WARP_NODE_WARP_FLOOR; if (area_get_warp_node(sSourceWarpNodeId) == NULL) { @@ -1127,6 +1136,9 @@ s32 play_mode_paused(void) { gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN; set_play_mode(PLAY_MODE_NORMAL); } else if (gPauseScreenMode == 2) { + level_trigger_warp(&gMarioStates[0], WARP_OP_EXIT); + set_play_mode(PLAY_MODE_NORMAL); + } else if (gPauseScreenMode == 3) { // Exit level if (gDebugLevelSelect) { fade_into_special_warp(-9, 1); @@ -1136,12 +1148,12 @@ s32 play_mode_paused(void) { gSavedCourseNum = COURSE_NONE; } set_play_mode(PLAY_MODE_CHANGE_LEVEL); - } else if (gPauseScreenMode == 3) { - // We should only be getting "int 3" to here + } /* else if (gPauseScreenMode == 4) { + // We should only be getting "int 4" to here initiate_warp(LEVEL_CASTLE, 1, 0x1F, 0); fade_into_special_warp(0, 0); game_exit(); - } + }*/ gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN; return 0; diff --git a/src/game/level_update.h b/src/game/level_update.h index bdff2e12..3ae895d1 100644 --- a/src/game/level_update.h +++ b/src/game/level_update.h @@ -27,6 +27,7 @@ #define WARP_OP_CREDITS_NEXT 0x18 #define WARP_OP_DEMO_END 0x19 #define WARP_OP_FORCE_SYNC 0x20 +#define WARP_OP_EXIT 0x21 #define WARP_OP_TRIGGERS_LEVEL_SELECT 0x10 From 777b9287e6fc89d43040abcef7020793571d3aca Mon Sep 17 00:00:00 2001 From: MysterD Date: Fri, 21 Jan 2022 18:24:53 -0800 Subject: [PATCH 6/8] Notify players where other players go with a popup --- build-windows-visual-studio/sm64ex.vcxproj | 4 + .../sm64ex.vcxproj.filters | 12 ++ src/game/level_info.c | 136 ++++++++++++++++++ src/game/level_info.h | 8 ++ src/pc/djui/djui_panel_playerlist.c | 133 +---------------- src/pc/network/network_player.c | 72 ++++------ src/pc/network/network_player.h | 1 + src/pc/network/packets/packet_change_area.c | 10 +- src/pc/network/packets/packet_change_level.c | 10 +- .../packets/packet_level_area_inform.c | 9 +- .../network/packets/packet_network_players.c | 5 +- src/pc/network/packets/packet_player.c | 2 +- 12 files changed, 201 insertions(+), 201 deletions(-) create mode 100644 src/game/level_info.c create mode 100644 src/game/level_info.h diff --git a/build-windows-visual-studio/sm64ex.vcxproj b/build-windows-visual-studio/sm64ex.vcxproj index 05f69d36..f1935d02 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj +++ b/build-windows-visual-studio/sm64ex.vcxproj @@ -3863,6 +3863,7 @@ + @@ -3963,6 +3964,7 @@ + @@ -4394,6 +4396,7 @@ + @@ -4416,6 +4419,7 @@ + diff --git a/build-windows-visual-studio/sm64ex.vcxproj.filters b/build-windows-visual-studio/sm64ex.vcxproj.filters index f7e38ee8..a9e0055d 100644 --- a/build-windows-visual-studio/sm64ex.vcxproj.filters +++ b/build-windows-visual-studio/sm64ex.vcxproj.filters @@ -15291,6 +15291,12 @@ Source Files\src\pc\controller + + Source Files\src\pc\djui\panel + + + Source Files\src\game + @@ -16393,5 +16399,11 @@ Source Files\src\pc\controller + + Source Files\src\pc\djui\panel + + + Source Files\src\game + \ No newline at end of file diff --git a/src/game/level_info.c b/src/game/level_info.c new file mode 100644 index 00000000..51e40dd8 --- /dev/null +++ b/src/game/level_info.c @@ -0,0 +1,136 @@ +#include +#include +#include "types.h" +#include "level_info.h" +#include "game/memory.h" + +extern u8 seg2_course_name_table[]; + +static const char charset[0xFF + 1] = { + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 7 + ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f', // 15 + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 23 + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 31 + 'w', 'x', 'y', 'z', ' ', ' ', ' ', ' ', // 39 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 49 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 55 + ' ', ' ', ' ', ' ', ' ', ' ', '\'', ' ', // 63 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 71 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 79 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 87 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 95 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 103 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ',', // 111 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 119 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 127 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 135 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 143 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 151 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', // 159 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 167 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 175 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 183 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 192 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 199 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 207 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 215 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 223 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 231 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 239 + ' ', ' ', '!', ' ', ' ', ' ', ' ', ' ', // 247 + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' // 255 +}; + +static void convert_string(const u8* str, char* output) { + s32 strPos = 0; + bool capitalizeChar = true; + + while (str[strPos] != 0xFF) { + if (str[strPos] < 0xFF) { + output[strPos] = charset[str[strPos]]; + + // if the char is a letter we can capatalize it + if (capitalizeChar && 0x0A <= str[strPos] && str[strPos] <= 0x23) { + output[strPos] -= ('a' - 'A'); + capitalizeChar = false; + } + + } + else { + output[strPos] = ' '; + } + + // decide if the next character should be capitalized + switch (output[strPos]) { + case ' ': + //if (str[strPos] != 158) + //fprintf(stdout, "Unknown Character (%i)\n", str[strPos]); // inform that an unknown char was found + case '-': + capitalizeChar = true; + break; + default: + capitalizeChar = false; + break; + } + + strPos++; + } + + output[strPos] = '\0'; +} + +const char* get_level_name(s16 courseNum, s16 levelNum, s16 areaIndex) { + static char stage[188]; + // overrides for castle locations + if (courseNum == 0 && levelNum == 16) { + strcpy(stage, "Castle Grounds"); + return stage; + } + if (courseNum == 0 && levelNum == 6) { + if (areaIndex == 1) { + strcpy(stage, "Castle Main Floor"); + return stage; + } + else if (areaIndex == 2) { + strcpy(stage, "Castle Upper Floor"); + return stage; + } + else if (areaIndex == 3) { + strcpy(stage, "Castle Basement"); + return stage; + } + } + if (courseNum == 0 && levelNum == 26) { + strcpy(stage, "Castle Courtyard"); + return stage; + } + + // If we are in in Course 0 we are in the castle which doesn't have a string + if (courseNum) { + void** courseNameTbl; + +#ifndef VERSION_EU + courseNameTbl = segmented_to_virtual(seg2_course_name_table); +#else + switch (gInGameLanguage) { + case LANGUAGE_ENGLISH: + courseNameTbl = segmented_to_virtual(course_name_table_eu_en); + break; + case LANGUAGE_FRENCH: + courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); + break; + case LANGUAGE_GERMAN: + courseNameTbl = segmented_to_virtual(course_name_table_eu_de); + break; + } +#endif + u8* courseName = segmented_to_virtual(courseNameTbl[courseNum - 1]); + + convert_string(&courseName[3], stage); + } + else { + strcpy(stage, "Peach's Castle"); + } + + return stage; +} diff --git a/src/game/level_info.h b/src/game/level_info.h new file mode 100644 index 00000000..2c81e5ad --- /dev/null +++ b/src/game/level_info.h @@ -0,0 +1,8 @@ +#ifndef LEVEL_INFO_H +#define LEVEL_INFO_H + +#include + +const char* get_level_name(s16 courseNum, s16 levelNum, s16 areaIndex); + +#endif // LEVEL_INFO_H diff --git a/src/pc/djui/djui_panel_playerlist.c b/src/pc/djui/djui_panel_playerlist.c index 9bfd38f0..345cd166 100644 --- a/src/pc/djui/djui_panel_playerlist.c +++ b/src/pc/djui/djui_panel_playerlist.c @@ -1,5 +1,6 @@ #include +#include "game/level_info.h" #include "pc/network/network.h" #include "djui.h" #include "djui_panel_playerlist.h" @@ -14,148 +15,18 @@ static struct DjuiImage* djuiImages[MAX_PLAYERS] = { 0 }; static struct DjuiText* djuiTextNames[MAX_PLAYERS] = { 0 }; static struct DjuiText* djuiTextLocations[MAX_PLAYERS] = { 0 }; -extern u8 seg2_course_name_table[]; -extern u8 seg2_act_name_table[]; - -static char stage[188]; -static char act[188]; - -static const char charset[0xFF + 1] = { - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 7 - ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f', // 15 - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 23 - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 31 - 'w', 'x', 'y', 'z', ' ', ' ', ' ', ' ', // 39 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 49 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 55 - ' ', ' ', ' ', ' ', ' ', ' ', '\'', ' ', // 63 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 71 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 79 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 87 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 95 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 103 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ',', // 111 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 119 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 127 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 135 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 143 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 151 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', // 159 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 167 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 175 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 183 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 192 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 199 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 207 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 215 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 223 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 231 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 239 - ' ', ' ', '!', ' ', ' ', ' ', ' ', ' ', // 247 - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' // 255 -}; - -static void convert_string(const u8* str, char* output) { - s32 strPos = 0; - bool capitalizeChar = true; - - while (str[strPos] != 0xFF) { - if (str[strPos] < 0xFF) { - output[strPos] = charset[str[strPos]]; - - // if the char is a letter we can capatalize it - if (capitalizeChar && 0x0A <= str[strPos] && str[strPos] <= 0x23) { - output[strPos] -= ('a' - 'A'); - capitalizeChar = false; - } - - } - else { - output[strPos] = ' '; - } - - // decide if the next character should be capitalized - switch (output[strPos]) { - case ' ': - //if (str[strPos] != 158) - //fprintf(stdout, "Unknown Character (%i)\n", str[strPos]); // inform that an unknown char was found - case '-': - capitalizeChar = true; - break; - default: - capitalizeChar = false; - break; - } - - strPos++; - } - - output[strPos] = '\0'; -} - -static void set_details(s16 courseNum, s16 levelNum, s16 areaIndex) { - // overrides for castle locations - if (courseNum == 0 && levelNum == 16) { - strcpy(stage, "Castle Grounds"); - return; - } - if (courseNum == 0 && levelNum == 6) { - if (areaIndex == 1) { - strcpy(stage, "Castle Main Floor"); - return; - } else if (areaIndex == 2) { - strcpy(stage, "Castle Upper Floor"); - return; - } else if (areaIndex == 3) { - strcpy(stage, "Castle Basement"); - return; - } - } - if (courseNum == 0 && levelNum == 26) { - strcpy(stage, "Castle Courtyard"); - return; - } - - // If we are in in Course 0 we are in the castle which doesn't have a string - if (courseNum) { - void** courseNameTbl; - -#ifndef VERSION_EU - courseNameTbl = segmented_to_virtual(seg2_course_name_table); -#else - switch (gInGameLanguage) { - case LANGUAGE_ENGLISH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_en); - break; - case LANGUAGE_FRENCH: - courseNameTbl = segmented_to_virtual(course_name_table_eu_fr); - break; - case LANGUAGE_GERMAN: - courseNameTbl = segmented_to_virtual(course_name_table_eu_de); - break; - } -#endif - u8* courseName = segmented_to_virtual(courseNameTbl[courseNum - 1]); - - convert_string(&courseName[3], stage); - } else { - strcpy(stage, "Peach's Castle"); - } -} - static void playerlist_update_row(u8 i, struct NetworkPlayer* np) { u8 charIndex = np->modelIndex; if (charIndex >= CT_MAX) { charIndex = 0; } djuiImages[i]->texture = gCharacters[charIndex].hudHeadTexture; - set_details(np->currCourseNum, np->currLevelNum, np->currAreaIndex); djui_base_set_visible(&djuiRow[i]->base, np->connected); u8* rgb = get_player_color(np->paletteIndex, 0); djui_base_set_color(&djuiTextNames[i]->base, rgb[0], rgb[1], rgb[2], 255); djui_text_set_text(djuiTextNames[i], np->name); - djui_text_set_text(djuiTextLocations[i], stage); + djui_text_set_text(djuiTextLocations[i], get_level_name(np->currCourseNum, np->currLevelNum, np->currAreaIndex)); } void djui_panel_playerlist_on_render_pre(UNUSED struct DjuiBase* base, UNUSED bool* skipRender) { diff --git a/src/pc/network/network_player.c b/src/pc/network/network_player.c index 11d25797..b57c837c 100644 --- a/src/pc/network/network_player.c +++ b/src/pc/network/network_player.c @@ -6,6 +6,7 @@ #include "pc/debuglog.h" #include "pc/utils/misc.h" #include "game/area.h" +#include "game/level_info.h" struct NetworkPlayer gNetworkPlayers[MAX_PLAYERS] = { 0 }; struct NetworkPlayer* gNetworkPlayerLocal = NULL; @@ -95,43 +96,9 @@ struct NetworkPlayer* get_network_player_smallest_global(void) { return smallest; } -static void network_player_update_level_popup(void) { - static s16 sCachedCourseNum = 0; - static s16 sCachedActStarNum = 0; - static s16 sCachedLevelNum = 0; - - bool inBonusCourse = (gCurrCourseNum >= 16); - bool allowPopup = (sCachedCourseNum == gCurrCourseNum) - && (sCachedActStarNum == gCurrActStarNum) - && (sCachedLevelNum == gCurrLevelNum) - && (gCurrActStarNum != 99) // suppress popup for credits sequence - && (inBonusCourse || gCurrActStarNum != 0); // suppress popup for star selection - - sCachedCourseNum = gCurrCourseNum; - sCachedActStarNum = gCurrActStarNum; - sCachedLevelNum = gCurrLevelNum; - - for (int i = 1; i < MAX_PLAYERS; i++) { - struct NetworkPlayer* np = &gNetworkPlayers[i]; - if (!np->connected) { continue; } - bool localLevelMatch = (np->currCourseNum == gCurrCourseNum && np->currActNum == gCurrActStarNum && np->currLevelNum == gCurrLevelNum); - if (np->localLevelMatch != localLevelMatch) { - np->localLevelMatch = localLevelMatch; - - if (!allowPopup) { continue; } - u8* rgb = get_player_color(np->paletteIndex, 0); - char popupMsg[128] = { 0 }; - snprintf(popupMsg, 128, "\\#%02x%02x%02x\\%s\\#dcdcdc\\ %s this level.", rgb[0], rgb[1], rgb[2], np->name, localLevelMatch ? "entered" : "left"); - djui_popup_create(popupMsg, 1); - } - } -} - void network_player_update(void) { if (!network_player_any_connected()) { return; } - network_player_update_level_popup(); - #ifndef DEVELOPMENT if (gNetworkType == NT_SERVER) { for (int i = 1; i < MAX_PLAYERS; i++) { @@ -187,10 +154,7 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 mode np->currLevelAreaSeqId = 0; extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex; - np->currCourseNum = gCurrCourseNum; - np->currActNum = gCurrActStarNum; - np->currLevelNum = gCurrLevelNum; - np->currAreaIndex = gCurrAreaIndex; + network_player_update_course_level(np, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex); np->currLevelSyncValid = false; np->currAreaSyncValid = false; np->modelIndex = modelIndex; @@ -236,10 +200,7 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 mode np->connected = true; np->currLevelAreaSeqId = 0; if (gNetworkType == NT_SERVER && !np->currAreaSyncValid) { - np->currCourseNum = 0; - np->currActNum = 0; - np->currLevelNum = 16; - np->currAreaIndex = 1; + network_player_update_course_level(np, 0, 0, 16, 1); np->currLevelSyncValid = false; np->currAreaSyncValid = false; } @@ -264,7 +225,7 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 mode // display popup u8* rgb = get_player_color(np->paletteIndex, 0); char popupMsg[128] = { 0 }; - snprintf(popupMsg, 128, "\\#%02x%02x%02x\\%s\\#dcdcdc\\ connected.", rgb[0], rgb[1], rgb[2], np->name); + snprintf(popupMsg, 128, "\\#%02x%02x%02x\\%s\\#dcdcdc\\ connected", rgb[0], rgb[1], rgb[2], np->name); djui_popup_create(popupMsg, 1); } LOG_INFO("player connected, local %d, global %d", i, np->globalIndex); @@ -311,7 +272,7 @@ u8 network_player_disconnected(u8 globalIndex) { // display popup u8* rgb = get_player_color(np->paletteIndex, 0); char popupMsg[128] = { 0 }; - snprintf(popupMsg, 128, "\\#%02x%02x%02x\\%s\\#dcdcdc\\ disconnected.", rgb[0], rgb[1], rgb[2], np->name); + snprintf(popupMsg, 128, "\\#%02x%02x%02x\\%s\\#dcdcdc\\ disconnected", rgb[0], rgb[1], rgb[2], np->name); djui_popup_create(popupMsg, 1); packet_ordered_clear(globalIndex); @@ -321,6 +282,27 @@ u8 network_player_disconnected(u8 globalIndex) { return UNKNOWN_GLOBAL_INDEX; } +void network_player_update_course_level(struct NetworkPlayer* np, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { + // display popup + if (np->currCourseNum != courseNum && np->localIndex != 0) { + u8* rgb = get_player_color(np->paletteIndex, 0); + char popupMsg[128] = { 0 }; + if (np->currCourseNum == gNetworkPlayerLocal->currCourseNum && gNetworkPlayerLocal->currCourseNum != 0) { + snprintf(popupMsg, 128, "\\#%02x%02x%02x\\%s\\#dcdcdc\\ left this level", rgb[0], rgb[1], rgb[2], np->name); + } else if (courseNum == gNetworkPlayerLocal->currCourseNum && gNetworkPlayerLocal->currCourseNum != 0) { + snprintf(popupMsg, 128, "\\#%02x%02x%02x\\%s\\#dcdcdc\\ entered this level", rgb[0], rgb[1], rgb[2], np->name); + } else { + snprintf(popupMsg, 128, "\\#%02x%02x%02x\\%s\\#dcdcdc\\ entered\n%s", rgb[0], rgb[1], rgb[2], np->name, get_level_name(courseNum, levelNum, areaIndex)); + } + djui_popup_create(popupMsg, 1); + } + + np->currCourseNum = courseNum; + np->currActNum = actNum; + np->currLevelNum = levelNum; + np->currAreaIndex = areaIndex; +} + void network_player_shutdown(void) { gNetworkPlayerLocal = NULL; gNetworkPlayerServer = NULL; @@ -330,6 +312,6 @@ void network_player_shutdown(void) { gNetworkSystem->clear_id(i); } - djui_popup_create("\\#ffa0a0\\Error:\\#dcdcdc\\ network shutdown.", 1); + djui_popup_create("\\#ffa0a0\\Error:\\#dcdcdc\\ network shutdown", 1); LOG_INFO("cleared all network players"); } diff --git a/src/pc/network/network_player.h b/src/pc/network/network_player.h index 158bd63c..ac10964e 100644 --- a/src/pc/network/network_player.h +++ b/src/pc/network/network_player.h @@ -57,6 +57,7 @@ struct NetworkPlayer* get_network_player_smallest_global(void); void network_player_update(void); u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 modelIndex, u8 paletteIndex, char* name); u8 network_player_disconnected(u8 globalIndex); +void network_player_update_course_level(struct NetworkPlayer* np, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex); void network_player_shutdown(void); #endif diff --git a/src/pc/network/packets/packet_change_area.c b/src/pc/network/packets/packet_change_area.c index 93cb5ff7..1f60a6d6 100644 --- a/src/pc/network/packets/packet_change_area.c +++ b/src/pc/network/packets/packet_change_area.c @@ -7,10 +7,7 @@ static void player_changed_area(struct NetworkPlayer* np, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { // set NetworkPlayer variables - np->currCourseNum = courseNum; - np->currActNum = actNum; - np->currLevelNum = levelNum; - np->currAreaIndex = areaIndex; + network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); np->currAreaSyncValid = false; reservation_area_change(np); @@ -56,10 +53,7 @@ void network_send_change_area(void) { network_send_to(gNetworkPlayerServer->localIndex, &p); struct NetworkPlayer* np = gNetworkPlayerLocal; - np->currCourseNum = gCurrCourseNum; - np->currActNum = gCurrActStarNum; - np->currLevelNum = gCurrLevelNum; - np->currAreaIndex = gCurrAreaIndex; + network_player_update_course_level(np, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex); np->currAreaSyncValid = false; LOG_INFO("tx change area"); diff --git a/src/pc/network/packets/packet_change_level.c b/src/pc/network/packets/packet_change_level.c index 1673a67a..f5186296 100644 --- a/src/pc/network/packets/packet_change_level.c +++ b/src/pc/network/packets/packet_change_level.c @@ -7,10 +7,7 @@ static void player_changed_level(struct NetworkPlayer* np, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { // set NetworkPlayer variables - np->currCourseNum = courseNum; - np->currActNum = actNum; - np->currLevelNum = levelNum; - np->currAreaIndex = areaIndex; + network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); np->currLevelSyncValid = false; np->currAreaSyncValid = false; reservation_area_change(np); @@ -62,10 +59,7 @@ void network_send_change_level(void) { network_send_to(gNetworkPlayerServer->localIndex, &p); struct NetworkPlayer* np = gNetworkPlayerLocal; - np->currCourseNum = gCurrCourseNum; - np->currActNum = gCurrActStarNum; - np->currLevelNum = gCurrLevelNum; - np->currAreaIndex = gCurrAreaIndex; + network_player_update_course_level(np, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex); np->currAreaSyncValid = false; np->currLevelSyncValid = false; diff --git a/src/pc/network/packets/packet_level_area_inform.c b/src/pc/network/packets/packet_level_area_inform.c index a67c0ae5..c3bbb002 100644 --- a/src/pc/network/packets/packet_level_area_inform.c +++ b/src/pc/network/packets/packet_level_area_inform.c @@ -4,6 +4,10 @@ //#define DISABLE_MODULE_LOG 1 #include "pc/debuglog.h" +#include "pc/djui/djui.h" +#include "game/level_info.h" +#include "game/mario_misc.h" + static u16 sLevelAreaInformSeq[MAX_PLAYERS][MAX_PLAYERS] = { 0 }; void network_send_level_area_inform(struct NetworkPlayer* np) { @@ -64,10 +68,7 @@ void network_receive_level_area_inform(struct Packet* p) { } sLevelAreaInformSeq[0][globalIndex] = seq; - np->currCourseNum = courseNum; - np->currActNum = actNum; - np->currLevelNum = levelNum; - np->currAreaIndex = areaIndex; + network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); np->currLevelSyncValid = levelSyncValid; np->currAreaSyncValid = areaSyncValid; } diff --git a/src/pc/network/packets/packet_network_players.c b/src/pc/network/packets/packet_network_players.c index f6d0d761..3478d9b2 100644 --- a/src/pc/network/packets/packet_network_players.c +++ b/src/pc/network/packets/packet_network_players.c @@ -87,10 +87,7 @@ void network_receive_network_players(struct Packet* p) { struct NetworkPlayer* np = &gNetworkPlayers[localIndex]; if (localIndex != 0) { np->currLevelAreaSeqId = levelAreaSeqId; - np->currCourseNum = courseNum; - np->currActNum = actNum; - np->currLevelNum = levelNum; - np->currAreaIndex = areaIndex; + network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); np->currLevelSyncValid = levelSyncValid; np->currAreaSyncValid = areaSyncValid; LOG_INFO("received network player location (%d, %d, %d, %d)", courseNum, actNum, levelNum, areaIndex); diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c index 2a450ba9..10f56c53 100644 --- a/src/pc/network/packets/packet_player.c +++ b/src/pc/network/packets/packet_player.c @@ -341,7 +341,7 @@ void network_receive_player(struct Packet* p) { // display popup u8* rgb = get_player_color(np->paletteIndex, 0); char popupMsg[128] = { 0 }; - snprintf(popupMsg, 128, "\\#%02x%02x%02x\\%s\\#dcdcdc\\ died.", rgb[0], rgb[1], rgb[2], np->name); + snprintf(popupMsg, 128, "\\#%02x%02x%02x\\%s\\#dcdcdc\\ died", rgb[0], rgb[1], rgb[2], np->name); djui_popup_create(popupMsg, 1); } From addd16721fc8a8a48c6db1b3bb7044d2e5844234 Mon Sep 17 00:00:00 2001 From: MysterD Date: Fri, 21 Jan 2022 19:13:41 -0800 Subject: [PATCH 7/8] Added headless server compile mode --- Makefile | 17 +- developer/dummy.sh | 2 + src/game/obj_behaviors.c | 2 +- src/pc/controller/controller_entry_point.c | 9 + src/pc/controller/controller_sdl1.c | 8 +- src/pc/controller/controller_sdl2.c | 8 +- src/pc/djui/djui_panel_playerlist.c | 7 +- src/pc/gfx/gfx_dummy.c | 240 +++++++++++++++++++++ src/pc/gfx/gfx_dummy.h | 10 + src/pc/network/network.c | 6 + src/pc/network/network.h | 1 + src/pc/network/packets/packet_join.c | 2 + src/pc/network/packets/packet_player.c | 6 +- src/pc/pc_main.c | 5 + src/pc/platform.c | 2 + 15 files changed, 305 insertions(+), 20 deletions(-) create mode 100644 developer/dummy.sh create mode 100644 src/pc/gfx/gfx_dummy.c create mode 100644 src/pc/gfx/gfx_dummy.h diff --git a/Makefile b/Makefile index d1552296..74d2d9b3 100644 --- a/Makefile +++ b/Makefile @@ -64,11 +64,11 @@ NO_LDIV ?= 0 # Backend selection -# Renderers: GL, GL_LEGACY, D3D11, D3D12 +# Renderers: GL, GL_LEGACY, D3D11, D3D12, DUMMY RENDER_API ?= GL -# Window managers: SDL1, SDL2, DXGI (forced if D3D11 or D3D12 in RENDER_API) +# Window managers: SDL1, SDL2, DXGI (forced if D3D11 or D3D12 in RENDER_API), DUMMY (forced if RENDER_API is DUMMY) WINDOW_API ?= SDL2 -# Audio backends: SDL1, SDL2 +# Audio backends: SDL1, SDL2, DUMMY AUDIO_API ?= SDL2 # Controller backends (can have multiple, space separated): SDL2, SDL1 CONTROLLER_API ?= SDL2 @@ -242,6 +242,17 @@ else ifeq ($(WINDOW_API),DXGI) $(error DXGI can only be used with DirectX renderers) endif + ifneq ($(WINDOW_API),DUMMY) + ifeq ($(RENDER_API),DUMMY) + $(warning Dummy renderer requires dummy window API, forcing WINDOW_API value) + WINDOW_API := DUMMY + endif + else + ifneq ($(RENDER_API),DUMMY) + $(warning Dummy window API requires dummy renderer, forcing RENDER_API value) + RENDER_API := DUMMY + endif + endif endif ################### Universal Dependencies ################### diff --git a/developer/dummy.sh b/developer/dummy.sh new file mode 100644 index 00000000..93370cd5 --- /dev/null +++ b/developer/dummy.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make RENDER_API=DUMMY AUDIO_API=DUMMY CONTROLLER_API= DEBUG=1 DEVELOPMENT=1 STRICT=1 -j && ./build/us_pc/sm64.us.f3dex2e.exe --server 7777 --savepath ./build/us_pc/ diff --git a/src/game/obj_behaviors.c b/src/game/obj_behaviors.c index 72562289..98b07007 100644 --- a/src/game/obj_behaviors.c +++ b/src/game/obj_behaviors.c @@ -518,9 +518,9 @@ s32 is_point_within_radius_of_mario(f32 x, f32 y, f32 z, s32 dist) { u8 is_player_active(struct MarioState* m) { if (gNetworkType == NT_NONE && m == &gMarioStates[0]) { return TRUE; } - if (m->action == ACT_BUBBLED) { return FALSE; } struct NetworkPlayer* np = &gNetworkPlayers[m->playerIndex]; + if (np == gNetworkPlayerServer && gServerSettings.headlessServer) { return FALSE; } if (np->type != NPT_LOCAL) { if (!np->connected) { return FALSE; } if (gNetworkPlayerLocal == NULL) { return FALSE; } diff --git a/src/pc/controller/controller_entry_point.c b/src/pc/controller/controller_entry_point.c index 34ca9ca0..27e0a4b7 100644 --- a/src/pc/controller/controller_entry_point.c +++ b/src/pc/controller/controller_entry_point.c @@ -11,6 +11,15 @@ // Analog camera movement by Pathétique (github.com/vrmiguel), y0shin and Mors // Contribute or communicate bugs at github.com/vrmiguel/sm64-analog-camera +// moved these from sdl controller implementations + +int mouse_x; +int mouse_y; + +int mouse_window_buttons; +int mouse_window_x; +int mouse_window_y; + static struct ControllerAPI *controller_implementations[] = { &controller_recorded_tas, #if defined(CAPI_SDL2) || defined(CAPI_SDL1) diff --git a/src/pc/controller/controller_sdl1.c b/src/pc/controller/controller_sdl1.c index 33c935e2..a94d0d79 100644 --- a/src/pc/controller/controller_sdl1.c +++ b/src/pc/controller/controller_sdl1.c @@ -18,6 +18,7 @@ #include "controller_api.h" #include "controller_sdl.h" +#include "controller_mouse.h" #include "../configfile.h" #include "../platform.h" #include "../fs/fs.h" @@ -41,13 +42,6 @@ enum { MAX_AXES, }; -int mouse_x; -int mouse_y; - -int mouse_window_buttons; -int mouse_window_x; -int mouse_window_y; - #ifdef BETTERCAMERA extern u8 newcam_mouse; #endif diff --git a/src/pc/controller/controller_sdl2.c b/src/pc/controller/controller_sdl2.c index a06b72e1..aacfc93c 100644 --- a/src/pc/controller/controller_sdl2.c +++ b/src/pc/controller/controller_sdl2.c @@ -18,6 +18,7 @@ #include "controller_api.h" #include "controller_sdl.h" +#include "controller_mouse.h" #include "../configfile.h" #include "../platform.h" #include "../fs/fs.h" @@ -31,13 +32,6 @@ #define MAX_JOYBUTTONS 32 // arbitrary; includes virtual keys for triggers #define AXIS_THRESHOLD (30 * 256) -int mouse_x; -int mouse_y; - -int mouse_window_buttons; -int mouse_window_x; -int mouse_window_y; - #ifdef BETTERCAMERA extern u8 newcam_mouse; #endif diff --git a/src/pc/djui/djui_panel_playerlist.c b/src/pc/djui/djui_panel_playerlist.c index 345cd166..d9c2f2cc 100644 --- a/src/pc/djui/djui_panel_playerlist.c +++ b/src/pc/djui/djui_panel_playerlist.c @@ -20,7 +20,12 @@ static void playerlist_update_row(u8 i, struct NetworkPlayer* np) { if (charIndex >= CT_MAX) { charIndex = 0; } djuiImages[i]->texture = gCharacters[charIndex].hudHeadTexture; - djui_base_set_visible(&djuiRow[i]->base, np->connected); + u8 visible = np->connected; + if (np == gNetworkPlayerServer && gServerSettings.headlessServer) { + visible = false; + } + + djui_base_set_visible(&djuiRow[i]->base, visible); u8* rgb = get_player_color(np->paletteIndex, 0); djui_base_set_color(&djuiTextNames[i]->base, rgb[0], rgb[1], rgb[2], 255); diff --git a/src/pc/gfx/gfx_dummy.c b/src/pc/gfx/gfx_dummy.c new file mode 100644 index 00000000..62895156 --- /dev/null +++ b/src/pc/gfx/gfx_dummy.c @@ -0,0 +1,240 @@ +#if defined(RAPI_DUMMY) || defined(WAPI_DUMMY) + +#ifdef WIN32 +#include +#elif _POSIX_C_SOURCE >= 199309L +#include // for nanosleep +#else +#include // for usleep +#endif + +#include +#include +#include + +#include "macros.h" +#include "gfx_window_manager_api.h" +#include "gfx_rendering_api.h" + +#include "pc/pc_main.h" +#include "pc/utils/misc.h" +#include "pc/debuglog.h" + +// TODO: figure out if this shit even works +#ifdef VERSION_EU +# define FRAMERATE 25 +#else +# define FRAMERATE 30 +#endif +// time between consequtive game frames +static const f64 sFrameTime = 1.0 / ((double)FRAMERATE); +static f64 sFrameTargetTime = 0; + +static void sleep_ms(int milliseconds) { // cross-platform sleep function + // from StackOverflow user Bernardo Ramos: https://stackoverflow.com/a/28827188 +#ifdef WIN32 + Sleep(milliseconds); +#elif _POSIX_C_SOURCE >= 199309L + struct timespec ts; + ts.tv_sec = milliseconds / 1000; + ts.tv_nsec = (milliseconds % 1000) * 1000000; + nanosleep(&ts, NULL); +#else + if (milliseconds >= 1000) + sleep(milliseconds / 1000); + usleep((milliseconds % 1000) * 1000); +#endif +} + +static void gfx_dummy_wm_init(UNUSED const char *game_name) { +} + +static void gfx_dummy_wm_set_keyboard_callbacks(UNUSED kb_callback_t on_key_down, UNUSED kb_callback_t on_key_up, UNUSED void (*on_all_keys_up)(void), UNUSED void (*on_text_input)(char*)) { +} + +static void gfx_dummy_wm_set_fullscreen_changed_callback(UNUSED void (*on_fullscreen_changed)(bool is_now_fullscreen)) { +} + +static void gfx_dummy_wm_set_fullscreen(UNUSED bool enable) { +} + +static void gfx_dummy_wm_main_loop(void (*run_one_game_iter)(void)) { + while (1) { + run_one_game_iter(); + } +} + +static void gfx_dummy_wm_get_dimensions(uint32_t *width, uint32_t *height) { + *width = 320; + *height = 240; +} + +static void gfx_dummy_wm_handle_events(void) { +} + +static bool gfx_dummy_wm_start_frame(void) { + return true; +} + +static inline void sync_framerate_with_timer(void) { + f64 curTime = clock_elapsed_f64(); + if (curTime < sFrameTargetTime) { + u32 delayMs = (sFrameTargetTime - curTime) * 1000.0; + if (delayMs > 0) { + sleep_ms(delayMs); + } + } + f64 frameTime = config60Fps ? (sFrameTime / 2.0) : sFrameTime; + sFrameTargetTime += frameTime; +} + +static void gfx_dummy_wm_swap_buffers_begin(void) { + sync_framerate_with_timer(); +} + +static void gfx_dummy_wm_swap_buffers_end(void) { +} + +static double gfx_dummy_wm_get_time(void) { + return 0.0; +} + +static char* gfx_dummy_wm_get_clipboard_text(void) { + return ""; +} + +static void gfx_dummy_wm_shutdown(void) { +} + +static void gfx_dummy_wm_start_text_input(void) { +} + +static void gfx_dummy_wm_stop_text_input(void) { +} + +static void gfx_dummy_wm_set_clipboard_text(UNUSED char* text) { +} + +static void gfx_dummy_wm_set_cursor_visible(UNUSED bool visible) { +} + +static bool gfx_dummy_renderer_z_is_from_0_to_1(void) { + return false; +} + +static void gfx_dummy_renderer_unload_shader(UNUSED struct ShaderProgram *old_prg) { +} + +static void gfx_dummy_renderer_load_shader(UNUSED struct ShaderProgram *new_prg) { +} + +static struct ShaderProgram *gfx_dummy_renderer_create_and_load_new_shader(UNUSED uint32_t shader_id) { + return NULL; +} + +static struct ShaderProgram *gfx_dummy_renderer_lookup_shader(UNUSED uint32_t shader_id) { + return NULL; +} + +static void gfx_dummy_renderer_shader_get_info(UNUSED struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]) { + *num_inputs = 0; + used_textures[0] = false; + used_textures[1] = false; +} + +static uint32_t gfx_dummy_renderer_new_texture(void) { + return 0; +} + +static void gfx_dummy_renderer_select_texture(UNUSED int tile, UNUSED uint32_t texture_id) { +} + +static void gfx_dummy_renderer_upload_texture(UNUSED const uint8_t *rgba32_buf, UNUSED int width, UNUSED int height) { +} + +static void gfx_dummy_renderer_set_sampler_parameters(UNUSED int tile, UNUSED bool linear_filter, UNUSED uint32_t cms, UNUSED uint32_t cmt) { +} + +static void gfx_dummy_renderer_set_depth_test(UNUSED bool depth_test) { +} + +static void gfx_dummy_renderer_set_depth_mask(UNUSED bool z_upd) { +} + +static void gfx_dummy_renderer_set_zmode_decal(UNUSED bool zmode_decal) { +} + +static void gfx_dummy_renderer_set_viewport(UNUSED int x, UNUSED int y, UNUSED int width, UNUSED int height) { +} + +static void gfx_dummy_renderer_set_scissor(UNUSED int x, UNUSED int y, UNUSED int width, UNUSED int height) { +} + +static void gfx_dummy_renderer_set_use_alpha(UNUSED bool use_alpha) { +} + +static void gfx_dummy_renderer_draw_triangles(UNUSED float buf_vbo[], UNUSED size_t buf_vbo_len, UNUSED size_t buf_vbo_num_tris) { +} + +static void gfx_dummy_renderer_init(void) { +} + +static void gfx_dummy_renderer_on_resize(void) { +} + +static void gfx_dummy_renderer_start_frame(void) { +} + +static void gfx_dummy_renderer_end_frame(void) { +} + +static void gfx_dummy_renderer_finish_render(void) { +} + +static void gfx_dummy_renderer_shutdown(void) { +} + +struct GfxWindowManagerAPI gfx_dummy_wm_api = { + gfx_dummy_wm_init, + gfx_dummy_wm_set_keyboard_callbacks, + gfx_dummy_wm_main_loop, + gfx_dummy_wm_get_dimensions, + gfx_dummy_wm_handle_events, + gfx_dummy_wm_start_frame, + gfx_dummy_wm_swap_buffers_begin, + gfx_dummy_wm_swap_buffers_end, + gfx_dummy_wm_get_time, + gfx_dummy_wm_shutdown, + gfx_dummy_wm_start_text_input, + gfx_dummy_wm_stop_text_input, + gfx_dummy_wm_get_clipboard_text, + gfx_dummy_wm_set_clipboard_text, + gfx_dummy_wm_set_cursor_visible +}; + +struct GfxRenderingAPI gfx_dummy_renderer_api = { + gfx_dummy_renderer_z_is_from_0_to_1, + gfx_dummy_renderer_unload_shader, + gfx_dummy_renderer_load_shader, + gfx_dummy_renderer_create_and_load_new_shader, + gfx_dummy_renderer_lookup_shader, + gfx_dummy_renderer_shader_get_info, + gfx_dummy_renderer_new_texture, + gfx_dummy_renderer_select_texture, + gfx_dummy_renderer_upload_texture, + gfx_dummy_renderer_set_sampler_parameters, + gfx_dummy_renderer_set_depth_test, + gfx_dummy_renderer_set_depth_mask, + gfx_dummy_renderer_set_zmode_decal, + gfx_dummy_renderer_set_viewport, + gfx_dummy_renderer_set_scissor, + gfx_dummy_renderer_set_use_alpha, + gfx_dummy_renderer_draw_triangles, + gfx_dummy_renderer_init, + gfx_dummy_renderer_on_resize, + gfx_dummy_renderer_start_frame, + gfx_dummy_renderer_end_frame, + gfx_dummy_renderer_finish_render, + gfx_dummy_renderer_shutdown +}; +#endif diff --git a/src/pc/gfx/gfx_dummy.h b/src/pc/gfx/gfx_dummy.h new file mode 100644 index 00000000..8ef215a6 --- /dev/null +++ b/src/pc/gfx/gfx_dummy.h @@ -0,0 +1,10 @@ +#ifndef GFX_DUMMY_H +#define GFX_DUMMY_H + +#include "gfx_rendering_api.h" +#include "gfx_window_manager_api.h" + +extern struct GfxRenderingAPI gfx_dummy_renderer_api; +extern struct GfxWindowManagerAPI gfx_dummy_wm_api; + +#endif diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 6c12b99e..b384ceda 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -43,6 +43,7 @@ struct ServerSettings gServerSettings = { .shareLives = 0, .enableCheats = 0, .bubbleDeath = 1, + .headlessServer = 0, }; void network_set_system(enum NetworkSystemType nsType) { @@ -70,6 +71,11 @@ bool network_init(enum NetworkType inNetworkType) { gServerSettings.shareLives = configShareLives; gServerSettings.enableCheats = configEnableCheats; gServerSettings.bubbleDeath = configBubbleDeath; +#if defined(RAPI_DUMMY) || defined(WAPI_DUMMY) + gServerSettings.headlessServer = (inNetworkType == NT_SERVER); +#else + gServerSettings.headlessServer = 0; +#endif Cheats.EnableCheats = gServerSettings.enableCheats; // initialize the network system diff --git a/src/pc/network/network.h b/src/pc/network/network.h index 11ee7c57..d669dce5 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -89,6 +89,7 @@ struct ServerSettings { u8 shareLives; u8 enableCheats; u8 bubbleDeath; + u8 headlessServer; }; // Networking-specific externs diff --git a/src/pc/network/packets/packet_join.c b/src/pc/network/packets/packet_join.c index bbd2e0d1..deb434a4 100644 --- a/src/pc/network/packets/packet_join.c +++ b/src/pc/network/packets/packet_join.c @@ -90,6 +90,7 @@ void network_send_join(struct Packet* joinRequestPacket) { packet_write(&p, &gServerSettings.shareLives, sizeof(u8)); packet_write(&p, &gServerSettings.enableCheats, sizeof(u8)); packet_write(&p, &gServerSettings.bubbleDeath, sizeof(u8)); + packet_write(&p, &gServerSettings.headlessServer, sizeof(u8)); packet_write(&p, eeprom, sizeof(u8) * 512); u8 modCount = string_linked_list_count(&gRegisteredMods); @@ -152,6 +153,7 @@ void network_receive_join(struct Packet* p) { packet_read(p, &gServerSettings.shareLives, sizeof(u8)); packet_read(p, &gServerSettings.enableCheats, sizeof(u8)); packet_read(p, &gServerSettings.bubbleDeath, sizeof(u8)); + packet_read(p, &gServerSettings.headlessServer, sizeof(u8)); packet_read(p, eeprom, sizeof(u8) * 512); packet_read(p, &modCount, sizeof(u8)); diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c index 10f56c53..4659eb61 100644 --- a/src/pc/network/packets/packet_player.c +++ b/src/pc/network/packets/packet_player.c @@ -360,5 +360,9 @@ void network_receive_player(struct Packet* p) { void network_update_player(void) { if (!network_player_any_connected()) { return; } - network_send_player(0); + + u8 localIsHeadless = (&gNetworkPlayers[0] == gNetworkPlayerServer && gServerSettings.headlessServer); + if (!localIsHeadless) { + network_send_player(0); + } } diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index fda30d3d..c7d2a980 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -22,6 +22,7 @@ #include "gfx/gfx_dxgi.h" #include "gfx/gfx_sdl.h" +#include "gfx/gfx_dummy.h" #include "audio/audio_api.h" #include "audio/audio_sdl.h" @@ -231,6 +232,8 @@ void main_func(void) { wm_api = &gfx_sdl; #elif defined(WAPI_DXGI) wm_api = &gfx_dxgi; + #elif defined(WAPI_DUMMY) + wm_api = &gfx_dummy_wm_api; #else #error No window API! #endif @@ -248,6 +251,8 @@ void main_func(void) { # else # define RAPI_NAME "OpenGL" # endif + #elif defined(RAPI_DUMMY) + rendering_api = &gfx_dummy_renderer_api; #else #error No rendering API! #endif diff --git a/src/pc/platform.c b/src/pc/platform.c index 760985ed..0e295ea9 100644 --- a/src/pc/platform.c +++ b/src/pc/platform.c @@ -162,7 +162,9 @@ static void sys_fatal_impl(const char *msg) { #else +#ifndef WAPI_DUMMY #warning "You might want to implement these functions for your platform" +#endif const char *sys_user_path(void) { return "."; From edec02a89b2b0acb3dff28e2bb0245cae380bc4c Mon Sep 17 00:00:00 2001 From: MysterD Date: Fri, 21 Jan 2022 19:15:51 -0800 Subject: [PATCH 8/8] Bump version to unst 13 --- src/pc/network/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pc/network/version.h b/src/pc/network/version.h index 2c8b7949..b07f578f 100644 --- a/src/pc/network/version.h +++ b/src/pc/network/version.h @@ -2,7 +2,7 @@ #define VERSION_H #define UNSTABLE_BRANCH -#define VERSION_NUMBER 12 +#define VERSION_NUMBER 13 #define MAX_VERSION_LENGTH 10 char* get_version(void);