Merge branch 'unstable' into lua

This commit is contained in:
MysterD 2022-01-21 19:19:21 -08:00
commit 34e903b89a
44 changed files with 815 additions and 14412 deletions

View file

@ -64,11 +64,11 @@ NO_LDIV ?= 0
# Backend selection # Backend selection
# Renderers: GL, GL_LEGACY, D3D11, D3D12 # Renderers: GL, GL_LEGACY, D3D11, D3D12, DUMMY
RENDER_API ?= GL 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 WINDOW_API ?= SDL2
# Audio backends: SDL1, SDL2 # Audio backends: SDL1, SDL2, DUMMY
AUDIO_API ?= SDL2 AUDIO_API ?= SDL2
# Controller backends (can have multiple, space separated): SDL2, SDL1 # Controller backends (can have multiple, space separated): SDL2, SDL1
CONTROLLER_API ?= SDL2 CONTROLLER_API ?= SDL2
@ -242,6 +242,17 @@ else
ifeq ($(WINDOW_API),DXGI) ifeq ($(WINDOW_API),DXGI)
$(error DXGI can only be used with DirectX renderers) $(error DXGI can only be used with DirectX renderers)
endif 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 endif
################### Universal Dependencies ################### ################### Universal Dependencies ###################
@ -749,6 +760,7 @@ endif
# lua # lua
LDFLAGS += -Llib/lua -l:liblua54.a LDFLAGS += -Llib/lua -l:liblua54.a
LUA_LIBS := lib/lua/lua54.dll
ifeq ($(WINDOWS_BUILD),1) ifeq ($(WINDOWS_BUILD),1)
LDFLAGS += -L"ws2_32" -lwsock32 LDFLAGS += -L"ws2_32" -lwsock32
@ -853,6 +865,9 @@ $(BUILD_DIR)/$(RPC_LIBS):
$(BUILD_DIR)/$(DISCORD_SDK_LIBS): $(BUILD_DIR)/$(DISCORD_SDK_LIBS):
@$(CP) -f $(DISCORD_SDK_LIBS) $(BUILD_DIR) @$(CP) -f $(DISCORD_SDK_LIBS) $(BUILD_DIR)
$(BUILD_DIR)/$(LUA_LIBS):
@$(CP) -f $(LUA_LIBS) $(BUILD_DIR)
$(BUILD_DIR)/$(MOD_DIR): $(BUILD_DIR)/$(MOD_DIR):
@$(CP) -f -r $(MOD_DIR) $(BUILD_DIR) @$(CP) -f -r $(MOD_DIR) $(BUILD_DIR)
@ -1106,7 +1121,7 @@ $(BUILD_DIR)/%.o: %.s
$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS) $(BUILD_DIR)/$(DISCORD_SDK_LIBS) $(BUILD_DIR)/$(MOD_DIR) $(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS) $(BUILD_DIR)/$(DISCORD_SDK_LIBS) $(BUILD_DIR)/$(LUA_LIBS) $(BUILD_DIR)/$(MOD_DIR)
$(LD) -L $(BUILD_DIR) -o $@ $(O_FILES) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS) $(LD) -L $(BUILD_DIR) -o $@ $(O_FILES) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS)
.PHONY: all clean distclean default diff test load libultra res .PHONY: all clean distclean default diff test load libultra res

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

2
developer/dummy.sh Normal file
View file

@ -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/

1
developer/sdl1.sh Normal file
View file

@ -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

View file

@ -2493,6 +2493,9 @@ void render_pause_camera_options(s16 x, s16 y, s8 *index, s16 xIndex) {
#endif #endif
void render_pause_course_options(s16 x, s16 y, s8 *index, s16 yIndex) { 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 #ifdef VERSION_EU
u8 textContinue[][10] = { u8 textContinue[][10] = {
{ TEXT_CONTINUE }, { 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 }; u8 textCameraAngleR[] = { TEXT_CAMERA_ANGLE_R };
#endif #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); gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha); gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
print_generic_string(x + 10, y - 2, textContinue); print_generic_string(x + 10, y - 2, textContinue);
print_generic_string(x + 10, y - 17, textExitCourse); print_generic_string(x + 10, y - 17, textExitCourse);
print_generic_string(x + 10, y - 32, TEXT_EXIT_TO_CASTLE);
if (index[0] != 3) { if (index[0] != 4) {
print_generic_string(x + 10, y - 33, textCameraAngleR); print_generic_string(x + 10, y - 47, textCameraAngleR);
gSPDisplayList(gDisplayListHead++, dl_ia_text_end); gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
create_dl_translation_matrix(MENU_MTX_PUSH, x - X_VAL8, (y - ((index[0] - 1) * yIndex)) - Y_VAL8, 0); 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); gSPDisplayList(gDisplayListHead++, dl_draw_triangle);
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
} else { } 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; gDialogBoxState = DIALOG_STATE_OPENING;
gMenuMode = -1; gMenuMode = -1;
if (gDialogLineNum == 2) { if (gDialogLineNum == 2 || gDialogLineNum == 3) {
num = gDialogLineNum; num = gDialogLineNum;
} else { } else {
num = 1; num = 1;

136
src/game/level_info.c Normal file
View file

@ -0,0 +1,136 @@
#include <stdbool.h>
#include <string.h>
#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;
}

8
src/game/level_info.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef LEVEL_INFO_H
#define LEVEL_INFO_H
#include <PR\ultratypes.h>
const char* get_level_name(s16 courseNum, s16 levelNum, s16 areaIndex);
#endif // LEVEL_INFO_H

View file

@ -826,6 +826,15 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) {
play_sound(SOUND_MENU_BOWSER_LAUGH, gDefaultSoundArgs); play_sound(SOUND_MENU_BOWSER_LAUGH, gDefaultSoundArgs);
break; 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: case WARP_OP_WARP_FLOOR:
sSourceWarpNodeId = WARP_NODE_WARP_FLOOR; sSourceWarpNodeId = WARP_NODE_WARP_FLOOR;
if (area_get_warp_node(sSourceWarpNodeId) == NULL) { if (area_get_warp_node(sSourceWarpNodeId) == NULL) {
@ -1127,6 +1136,9 @@ s32 play_mode_paused(void) {
gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN; gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN;
set_play_mode(PLAY_MODE_NORMAL); set_play_mode(PLAY_MODE_NORMAL);
} else if (gPauseScreenMode == 2) { } else if (gPauseScreenMode == 2) {
level_trigger_warp(&gMarioStates[0], WARP_OP_EXIT);
set_play_mode(PLAY_MODE_NORMAL);
} else if (gPauseScreenMode == 3) {
// Exit level // Exit level
if (gDebugLevelSelect) { if (gDebugLevelSelect) {
fade_into_special_warp(-9, 1); fade_into_special_warp(-9, 1);
@ -1136,12 +1148,12 @@ s32 play_mode_paused(void) {
gSavedCourseNum = COURSE_NONE; gSavedCourseNum = COURSE_NONE;
} }
set_play_mode(PLAY_MODE_CHANGE_LEVEL); set_play_mode(PLAY_MODE_CHANGE_LEVEL);
} else if (gPauseScreenMode == 3) { } /* else if (gPauseScreenMode == 4) {
// We should only be getting "int 3" to here // We should only be getting "int 4" to here
initiate_warp(LEVEL_CASTLE, 1, 0x1F, 0); initiate_warp(LEVEL_CASTLE, 1, 0x1F, 0);
fade_into_special_warp(0, 0); fade_into_special_warp(0, 0);
game_exit(); game_exit();
} }*/
gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN; gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN;
return 0; return 0;

View file

@ -27,6 +27,7 @@
#define WARP_OP_CREDITS_NEXT 0x18 #define WARP_OP_CREDITS_NEXT 0x18
#define WARP_OP_DEMO_END 0x19 #define WARP_OP_DEMO_END 0x19
#define WARP_OP_FORCE_SYNC 0x20 #define WARP_OP_FORCE_SYNC 0x20
#define WARP_OP_EXIT 0x21
#define WARP_OP_TRIGGERS_LEVEL_SELECT 0x10 #define WARP_OP_TRIGGERS_LEVEL_SELECT 0x10

View file

@ -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) { u8 is_player_active(struct MarioState* m) {
if (gNetworkType == NT_NONE && m == &gMarioStates[0]) { return TRUE; } if (gNetworkType == NT_NONE && m == &gMarioStates[0]) { return TRUE; }
if (m->action == ACT_BUBBLED) { return FALSE; } if (m->action == ACT_BUBBLED) { return FALSE; }
struct NetworkPlayer* np = &gNetworkPlayers[m->playerIndex]; struct NetworkPlayer* np = &gNetworkPlayers[m->playerIndex];
if (np == gNetworkPlayerServer && gServerSettings.headlessServer) { return FALSE; }
if (np->type != NPT_LOCAL) { if (np->type != NPT_LOCAL) {
if (!np->connected) { return FALSE; } if (!np->connected) { return FALSE; }
if (gNetworkPlayerLocal == NULL) { return FALSE; } if (gNetworkPlayerLocal == NULL) { return FALSE; }

View file

@ -0,0 +1,154 @@
#ifdef HAVE_SDL2
#include <SDL2/SDL.h>
#else
#include <SDL/SDL.h>
#endif
#include "controller_bind_mapping.h"
#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 };
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;
}
#endif

View file

@ -0,0 +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

View file

@ -11,6 +11,15 @@
// Analog camera movement by Pathétique (github.com/vrmiguel), y0shin and Mors // Analog camera movement by Pathétique (github.com/vrmiguel), y0shin and Mors
// Contribute or communicate bugs at github.com/vrmiguel/sm64-analog-camera // 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[] = { static struct ControllerAPI *controller_implementations[] = {
&controller_recorded_tas, &controller_recorded_tas,
#if defined(CAPI_SDL2) || defined(CAPI_SDL1) #if defined(CAPI_SDL2) || defined(CAPI_SDL1)

View file

@ -5,6 +5,10 @@
#define VK_BASE_SDL_GAMEPAD 0x1000 #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; extern struct ControllerAPI controller_sdl;
void controller_sdl_read_mouse_window(void); void controller_sdl_read_mouse_window(void);

View file

@ -18,6 +18,7 @@
#include "controller_api.h" #include "controller_api.h"
#include "controller_sdl.h" #include "controller_sdl.h"
#include "controller_mouse.h"
#include "../configfile.h" #include "../configfile.h"
#include "../platform.h" #include "../platform.h"
#include "../fs/fs.h" #include "../fs/fs.h"
@ -26,9 +27,6 @@
#include "pc/djui/djui.h" #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_JOYBINDS 32
#define MAX_MOUSEBUTTONS 8 // arbitrary #define MAX_MOUSEBUTTONS 8 // arbitrary
#define MAX_JOYBUTTONS 32 // arbitrary; includes virtual keys for triggers #define MAX_JOYBUTTONS 32 // arbitrary; includes virtual keys for triggers
@ -44,13 +42,6 @@ enum {
MAX_AXES, MAX_AXES,
}; };
int mouse_x;
int mouse_y;
int mouse_window_buttons;
int mouse_window_x;
int mouse_window_y;
#ifdef BETTERCAMERA #ifdef BETTERCAMERA
extern u8 newcam_mouse; extern u8 newcam_mouse;
#endif #endif

View file

@ -18,6 +18,7 @@
#include "controller_api.h" #include "controller_api.h"
#include "controller_sdl.h" #include "controller_sdl.h"
#include "controller_mouse.h"
#include "../configfile.h" #include "../configfile.h"
#include "../platform.h" #include "../platform.h"
#include "../fs/fs.h" #include "../fs/fs.h"
@ -26,21 +27,11 @@
#include "pc/djui/djui.h" #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_JOYBINDS 32
#define MAX_MOUSEBUTTONS 8 // arbitrary #define MAX_MOUSEBUTTONS 8 // arbitrary
#define MAX_JOYBUTTONS 32 // arbitrary; includes virtual keys for triggers #define MAX_JOYBUTTONS 32 // arbitrary; includes virtual keys for triggers
#define AXIS_THRESHOLD (30 * 256) #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 #ifdef BETTERCAMERA
extern u8 newcam_mouse; extern u8 newcam_mouse;
#endif #endif

View file

@ -2,6 +2,7 @@
#include <string.h> #include <string.h>
#include "djui.h" #include "djui.h"
#include "src/pc/controller/controller_api.h" #include "src/pc/controller/controller_api.h"
#include "src/pc/controller/controller_bind_mapping.h"
#include "audio_defines.h" #include "audio_defines.h"
#include "audio/external.h" #include "audio/external.h"
@ -32,11 +33,11 @@ static void djui_bind_button_on_bind(struct DjuiBase* caller) {
// set key // set key
bind->configKey[button->base.tag] = key; bind->configKey[button->base.tag] = key;
char keyStr[5] = { 0 }; #if defined(CAPI_SDL1) || defined(CAPI_SDL2)
if (key != VK_INVALID) { djui_text_set_text(button->text, translate_bind_to_name(key));
sprintf(keyStr, "%04x", key); #else
} djui_text_set_text(button->text, "???");
djui_text_set_text(button->text, keyStr); #endif
djui_interactable_set_binding(NULL); djui_interactable_set_binding(NULL);
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs); play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
controller_reconfigure(); controller_reconfigure();
@ -55,7 +56,7 @@ struct DjuiBind* djui_bind_create(struct DjuiBase* parent, const char* message,
djui_base_init(parent, base, NULL, djui_bind_destroy); 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_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); djui_base_set_color(&bind->base, 0, 0, 0, 0);
struct DjuiText* text = djui_text_create(&bind->base, message); struct DjuiText* text = djui_text_create(&bind->base, message);
@ -70,17 +71,17 @@ struct DjuiBind* djui_bind_create(struct DjuiBase* parent, const char* message,
struct DjuiRect* rect = djui_rect_create(&bind->base); struct DjuiRect* rect = djui_rect_create(&bind->base);
djui_base_set_alignment(&rect->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_CENTER); 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_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); djui_base_set_color(&rect->base, 0, 0, 0, 0);
bind->rect = rect; bind->rect = rect;
for (int i = 0; i < MAX_BINDS; i++) { for (int i = 0; i < MAX_BINDS; i++) {
#if defined(CAPI_SDL1) || defined(CAPI_SDL2)
unsigned int key = configKey[i]; unsigned int key = configKey[i];
char keyStr[5] = { 0 }; struct DjuiButton* button = djui_button_create(&rect->base, translate_bind_to_name(key));
if (key != VK_INVALID) { #else
sprintf(keyStr, "%04x", key); struct DjuiButton* button = djui_button_create(&rect->base, "???");
} #endif
struct DjuiButton* button = djui_button_create(&rect->base, keyStr);
djui_base_set_size_type(&button->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE); djui_base_set_size_type(&button->base, DJUI_SVT_RELATIVE, DJUI_SVT_RELATIVE);
djui_base_set_size(&button->base, 0.33f, 1.0f); djui_base_set_size(&button->base, 0.33f, 1.0f);
button->base.tag = i; button->base.tag = i;

View file

@ -8,7 +8,7 @@ void djui_panel_controls_value_change(UNUSED struct DjuiBase* caller) {
} }
void djui_panel_controls_create(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; f32 bodyHeight = bindBodyHeight + 16 * 3 + 32 * 2 + 64;
struct DjuiBase* defaultBase = NULL; 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 Left", configKeyCLeft);
djui_bind_create(&bindBody->base, "C Right", configKeyCRight); djui_bind_create(&bindBody->base, "C Right", configKeyCRight);
djui_bind_create(&bindBody->base, "Chat", configKeyChat); 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; defaultBase = &bind1->buttons[0]->base;
} }

View file

@ -8,22 +8,17 @@ void djui_panel_options_back(struct DjuiBase* caller) {
} }
void djui_panel_options_create(struct DjuiBase* caller) { void djui_panel_options_create(struct DjuiBase* caller) {
f32 bodyHeight = 64 * 5 + 16 * 4; f32 bodyHeight = 64 * 6 + 16 * 5;
if (gNetworkType == NT_NONE) {
bodyHeight += 64 + 16;
}
struct DjuiBase* defaultBase = NULL; 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 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); struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
{ {
if (gNetworkType == NT_NONE) { struct DjuiButton* button1 = djui_button_create(&body->base, "Player");
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_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&button1->base, 1.0f, 64);
djui_base_set_size(&button1->base, 1.0f, 64); djui_interactable_hook_click(&button1->base, djui_panel_player_create);
djui_interactable_hook_click(&button1->base, djui_panel_player_create); defaultBase = &button1->base;
defaultBase = &button1->base;
}
struct DjuiButton* button2 = djui_button_create(&body->base, "Camera"); struct DjuiButton* button2 = djui_button_create(&body->base, "Camera");
djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);

View file

@ -33,6 +33,10 @@ static void djui_panel_player_name_on_focus_end(struct DjuiBase* caller) {
} }
snprintf(configPlayerName, 20, "%s", inputbox1->buffer); snprintf(configPlayerName, 20, "%s", inputbox1->buffer);
djui_inputbox_set_text_color(inputbox1, 0, 0, 0, 255); 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) { 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].modelIndex = configPlayerModel;
gNetworkPlayers[0].paletteIndex = configPlayerPalette; gNetworkPlayers[0].paletteIndex = configPlayerPalette;
network_player_update_model(0); network_player_update_model(0);
if (gNetworkType != NT_NONE) {
network_send_player_settings();
}
} }
void djui_panel_player_create(struct DjuiBase* caller) { void djui_panel_player_create(struct DjuiBase* caller) {

View file

@ -1,5 +1,6 @@
#include <string.h> #include <string.h>
#include "game/level_info.h"
#include "pc/network/network.h" #include "pc/network/network.h"
#include "djui.h" #include "djui.h"
#include "djui_panel_playerlist.h" #include "djui_panel_playerlist.h"
@ -14,148 +15,23 @@ static struct DjuiImage* djuiImages[MAX_PLAYERS] = { 0 };
static struct DjuiText* djuiTextNames[MAX_PLAYERS] = { 0 }; static struct DjuiText* djuiTextNames[MAX_PLAYERS] = { 0 };
static struct DjuiText* djuiTextLocations[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) { static void playerlist_update_row(u8 i, struct NetworkPlayer* np) {
u8 charIndex = np->modelIndex; u8 charIndex = np->modelIndex;
if (charIndex >= CT_MAX) { charIndex = 0; } if (charIndex >= CT_MAX) { charIndex = 0; }
djuiImages[i]->texture = gCharacters[charIndex].hudHeadTexture; djuiImages[i]->texture = gCharacters[charIndex].hudHeadTexture;
set_details(np->currCourseNum, np->currLevelNum, np->currAreaIndex); u8 visible = np->connected;
djui_base_set_visible(&djuiRow[i]->base, 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); u8* rgb = get_player_color(np->paletteIndex, 0);
djui_base_set_color(&djuiTextNames[i]->base, rgb[0], rgb[1], rgb[2], 255); 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(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) { void djui_panel_playerlist_on_render_pre(UNUSED struct DjuiBase* base, UNUSED bool* skipRender) {

View file

@ -22,6 +22,10 @@
#include "gfx_rendering_api.h" #include "gfx_rendering_api.h"
#include "gfx_direct3d_common.h" #include "gfx_direct3d_common.h"
extern "C" {
#include "src/pc/controller/controller_bind_mapping.h"
}
#define DECLARE_GFX_DXGI_FUNCTIONS #define DECLARE_GFX_DXGI_FUNCTIONS
#include "gfx_dxgi.h" #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."); gfx_dxgi_get_h_wnd(), "Failed to create per-draw constant buffer.");
d3d.context->PSSetConstantBuffers(1, 1, d3d.per_draw_cb.GetAddressOf()); d3d.context->PSSetConstantBuffers(1, 1, d3d.per_draw_cb.GetAddressOf());
controller_bind_init();
} }

View file

@ -37,6 +37,10 @@
#include "gfx_rendering_api.h" #include "gfx_rendering_api.h"
#include "gfx_direct3d_common.h" #include "gfx_direct3d_common.h"
extern "C" {
#include "src/pc/controller/controller_bind_mapping.h"
}
#include "gfx_screen_config.h" #include "gfx_screen_config.h"
#define DEBUG_D3D 0 #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 CD3DX12_RANGE read_range(0, 0); // Read not possible from CPU
ThrowIfFailed(d3d.vertex_buffer->Map(0, &read_range, &d3d.mapped_vbuf_address)); ThrowIfFailed(d3d.vertex_buffer->Map(0, &read_range, &d3d.mapped_vbuf_address));
} }
controller_bind_init();
} }
static void gfx_direct3d12_end_frame(void) { static void gfx_direct3d12_end_frame(void) {

240
src/pc/gfx/gfx_dummy.c Normal file
View file

@ -0,0 +1,240 @@
#if defined(RAPI_DUMMY) || defined(WAPI_DUMMY)
#ifdef WIN32
#include <windows.h>
#elif _POSIX_C_SOURCE >= 199309L
#include <time.h> // for nanosleep
#else
#include <unistd.h> // for usleep
#endif
#include <errno.h>
#include <stdbool.h>
#include <PR/ultratypes.h>
#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

10
src/pc/gfx/gfx_dummy.h Normal file
View file

@ -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

View file

@ -19,6 +19,7 @@
#include "../platform.h" #include "../platform.h"
#include "src/pc/controller/controller_keyboard.h" #include "src/pc/controller/controller_keyboard.h"
#include "src/pc/controller/controller_bind_mapping.h"
// TODO: figure out if this shit even works // TODO: figure out if this shit even works
#ifdef VERSION_EU #ifdef VERSION_EU
@ -27,8 +28,6 @@
# define FRAMERATE 30 # define FRAMERATE 30
#endif #endif
static int inverted_scancode_table[512];
static kb_callback_t kb_key_down = NULL; static kb_callback_t kb_key_down = NULL;
static kb_callback_t kb_key_up = NULL; static kb_callback_t kb_key_up = NULL;
static void (*kb_all_keys_up)(void) = 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_w = 0;
static int window_h = 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) { static void gfx_sdl_set_mode(void) {
if (configWindow.exiting_fullscreen) if (configWindow.exiting_fullscreen)
configWindow.exiting_fullscreen = false; configWindow.exiting_fullscreen = false;
@ -160,18 +109,7 @@ static void gfx_sdl_init(const char *window_title) {
SDL_ShowCursor(0); SDL_ShowCursor(0);
} }
for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDLKey); i++) { controller_bind_init();
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;
}
} }
static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) { 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; 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) { static void gfx_sdl_onkeydown(int scancode) {
if (kb_key_down) 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) { static void gfx_sdl_onkeyup(int scancode) {
if (kb_key_up) 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) { static void gfx_sdl_handle_events(void) {

View file

@ -34,7 +34,8 @@
#include "../cliopts.h" #include "../cliopts.h"
#include "src/pc/controller/controller_keyboard.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" #include "pc/utils/misc.h"
// TODO: figure out if this shit even works // TODO: figure out if this shit even works
@ -49,63 +50,12 @@ static f64 sFrameTargetTime = 0;
static SDL_Window *wnd; static SDL_Window *wnd;
static SDL_GLContext ctx = NULL; 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_down = NULL;
static kb_callback_t kb_key_up = NULL; static kb_callback_t kb_key_up = NULL;
static void (*kb_all_keys_up)(void) = NULL; static void (*kb_all_keys_up)(void) = NULL;
static void (*kb_text_input)(char*) = 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) #define IS_FULLSCREEN() ((SDL_GetWindowFlags(wnd) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0)
int test_vsync(void) { int test_vsync(void) {
@ -211,18 +161,7 @@ static void gfx_sdl_init(const char *window_title) {
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
} }
for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDL_Scancode); i++) { controller_bind_init();
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;
}
} }
static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) { 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; 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) { static void gfx_sdl_onkeydown(int scancode) {
if (kb_key_down) if (kb_key_down)
kb_key_down(translate_scancode(scancode)); kb_key_down(translate_sdl_scancode(scancode));
const Uint8 *state = SDL_GetKeyboardState(NULL); const Uint8 *state = SDL_GetKeyboardState(NULL);
@ -258,7 +189,7 @@ static void gfx_sdl_onkeydown(int scancode) {
static void gfx_sdl_onkeyup(int scancode) { static void gfx_sdl_onkeyup(int scancode) {
if (kb_key_up) if (kb_key_up)
kb_key_up(translate_scancode(scancode)); kb_key_up(translate_sdl_scancode(scancode));
} }
static void gfx_sdl_handle_events(void) { static void gfx_sdl_handle_events(void) {

View file

@ -43,6 +43,7 @@ struct ServerSettings gServerSettings = {
.shareLives = 0, .shareLives = 0,
.enableCheats = 0, .enableCheats = 0,
.bubbleDeath = 1, .bubbleDeath = 1,
.headlessServer = 0,
}; };
void network_set_system(enum NetworkSystemType nsType) { void network_set_system(enum NetworkSystemType nsType) {
@ -70,6 +71,11 @@ bool network_init(enum NetworkType inNetworkType) {
gServerSettings.shareLives = configShareLives; gServerSettings.shareLives = configShareLives;
gServerSettings.enableCheats = configEnableCheats; gServerSettings.enableCheats = configEnableCheats;
gServerSettings.bubbleDeath = configBubbleDeath; gServerSettings.bubbleDeath = configBubbleDeath;
#if defined(RAPI_DUMMY) || defined(WAPI_DUMMY)
gServerSettings.headlessServer = (inNetworkType == NT_SERVER);
#else
gServerSettings.headlessServer = 0;
#endif
Cheats.EnableCheats = gServerSettings.enableCheats; Cheats.EnableCheats = gServerSettings.enableCheats;
// initialize the network system // initialize the network system

View file

@ -89,6 +89,7 @@ struct ServerSettings {
u8 shareLives; u8 shareLives;
u8 enableCheats; u8 enableCheats;
u8 bubbleDeath; u8 bubbleDeath;
u8 headlessServer;
}; };
// Networking-specific externs // Networking-specific externs

View file

@ -6,6 +6,7 @@
#include "pc/debuglog.h" #include "pc/debuglog.h"
#include "pc/utils/misc.h" #include "pc/utils/misc.h"
#include "game/area.h" #include "game/area.h"
#include "game/level_info.h"
struct NetworkPlayer gNetworkPlayers[MAX_PLAYERS] = { 0 }; struct NetworkPlayer gNetworkPlayers[MAX_PLAYERS] = { 0 };
struct NetworkPlayer* gNetworkPlayerLocal = NULL; struct NetworkPlayer* gNetworkPlayerLocal = NULL;
@ -25,22 +26,6 @@ void network_player_update_model(u8 localIndex) {
m->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[m->character->modelId]; 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) { bool network_player_any_connected(void) {
for (int i = 1; i < MAX_PLAYERS; i++) { for (int i = 1; i < MAX_PLAYERS; i++) {
if (gNetworkPlayers[i].connected) { return true; } if (gNetworkPlayers[i].connected) { return true; }
@ -111,43 +96,9 @@ struct NetworkPlayer* get_network_player_smallest_global(void) {
return smallest; 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) { void network_player_update(void) {
if (!network_player_any_connected()) { return; } if (!network_player_any_connected()) { return; }
network_player_update_level_popup();
#ifndef DEVELOPMENT #ifndef DEVELOPMENT
if (gNetworkType == NT_SERVER) { if (gNetworkType == NT_SERVER) {
for (int i = 1; i < MAX_PLAYERS; i++) { for (int i = 1; i < MAX_PLAYERS; i++) {
@ -203,10 +154,7 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 mode
np->currLevelAreaSeqId = 0; np->currLevelAreaSeqId = 0;
extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex; extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex;
np->currCourseNum = gCurrCourseNum; network_player_update_course_level(np, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex);
np->currActNum = gCurrActStarNum;
np->currLevelNum = gCurrLevelNum;
np->currAreaIndex = gCurrAreaIndex;
np->currLevelSyncValid = false; np->currLevelSyncValid = false;
np->currAreaSyncValid = false; np->currAreaSyncValid = false;
np->modelIndex = modelIndex; np->modelIndex = modelIndex;
@ -252,10 +200,7 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 mode
np->connected = true; np->connected = true;
np->currLevelAreaSeqId = 0; np->currLevelAreaSeqId = 0;
if (gNetworkType == NT_SERVER && !np->currAreaSyncValid) { if (gNetworkType == NT_SERVER && !np->currAreaSyncValid) {
np->currCourseNum = 0; network_player_update_course_level(np, 0, 0, 16, 1);
np->currActNum = 0;
np->currLevelNum = 16;
np->currAreaIndex = 1;
np->currLevelSyncValid = false; np->currLevelSyncValid = false;
np->currAreaSyncValid = false; np->currAreaSyncValid = false;
} }
@ -280,7 +225,7 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 mode
// display popup // display popup
u8* rgb = get_player_color(np->paletteIndex, 0); u8* rgb = get_player_color(np->paletteIndex, 0);
char popupMsg[128] = { 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); djui_popup_create(popupMsg, 1);
} }
LOG_INFO("player connected, local %d, global %d", i, np->globalIndex); LOG_INFO("player connected, local %d, global %d", i, np->globalIndex);
@ -327,7 +272,7 @@ u8 network_player_disconnected(u8 globalIndex) {
// display popup // display popup
u8* rgb = get_player_color(np->paletteIndex, 0); u8* rgb = get_player_color(np->paletteIndex, 0);
char popupMsg[128] = { 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); djui_popup_create(popupMsg, 1);
packet_ordered_clear(globalIndex); packet_ordered_clear(globalIndex);
@ -337,6 +282,27 @@ u8 network_player_disconnected(u8 globalIndex) {
return UNKNOWN_GLOBAL_INDEX; 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) { void network_player_shutdown(void) {
gNetworkPlayerLocal = NULL; gNetworkPlayerLocal = NULL;
gNetworkPlayerServer = NULL; gNetworkPlayerServer = NULL;
@ -346,6 +312,6 @@ void network_player_shutdown(void) {
gNetworkSystem->clear_id(i); 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"); LOG_INFO("cleared all network players");
} }

View file

@ -37,7 +37,7 @@ struct NetworkPlayer {
u8 modelIndex; u8 modelIndex;
u8 paletteIndex; u8 paletteIndex;
bool localLevelMatch; bool localLevelMatch;
char name[MAX_PLAYER_STRING]; char name[MAX_PLAYER_STRING+1];
u16 rxSeqIds[MAX_RX_SEQ_IDS]; u16 rxSeqIds[MAX_RX_SEQ_IDS];
u32 rxPacketHash[MAX_RX_SEQ_IDS]; u32 rxPacketHash[MAX_RX_SEQ_IDS];
}; };
@ -48,7 +48,6 @@ extern struct NetworkPlayer* gNetworkPlayerServer;
void network_player_init(void); void network_player_init(void);
void network_player_update_model(u8 localIndex); void network_player_update_model(u8 localIndex);
u8 network_player_unique_palette(u8 palette);
bool network_player_any_connected(void); bool network_player_any_connected(void);
u8 network_player_connected_count(void); u8 network_player_connected_count(void);
struct NetworkPlayer* network_player_from_global_index(u8 globalIndex); struct NetworkPlayer* network_player_from_global_index(u8 globalIndex);
@ -58,6 +57,7 @@ struct NetworkPlayer* get_network_player_smallest_global(void);
void network_player_update(void); void network_player_update(void);
u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 modelIndex, u8 paletteIndex, char* name); u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 modelIndex, u8 paletteIndex, char* name);
u8 network_player_disconnected(u8 globalIndex); 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); void network_player_shutdown(void);
#endif #endif

View file

@ -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_AREA_INFORM: network_receive_level_area_inform(p); break;
case PACKET_LEVEL_RESPAWN_INFO: network_receive_level_respawn_info(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 // custom
case PACKET_CUSTOM: network_receive_custom(p); break; case PACKET_CUSTOM: network_receive_custom(p); break;
default: LOG_ERROR("received unknown packet: %d", p->buffer[0]); default: LOG_ERROR("received unknown packet: %d", p->buffer[0]);

View file

@ -52,6 +52,8 @@ enum PacketType {
PACKET_LEVEL_AREA_INFORM, PACKET_LEVEL_AREA_INFORM,
PACKET_LEVEL_RESPAWN_INFO, PACKET_LEVEL_RESPAWN_INFO,
PACKET_PLAYER_SETTINGS,
/// ///
PACKET_CUSTOM = 255, PACKET_CUSTOM = 255,
}; };
@ -275,4 +277,8 @@ void network_receive_reservation_release(struct Packet* p);
void network_send_debug_sync(void); void network_send_debug_sync(void);
void network_receive_debug_sync(struct Packet* p); 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 #endif

View file

@ -7,10 +7,7 @@
static void player_changed_area(struct NetworkPlayer* np, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { static void player_changed_area(struct NetworkPlayer* np, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) {
// set NetworkPlayer variables // set NetworkPlayer variables
np->currCourseNum = courseNum; network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex);
np->currActNum = actNum;
np->currLevelNum = levelNum;
np->currAreaIndex = areaIndex;
np->currAreaSyncValid = false; np->currAreaSyncValid = false;
reservation_area_change(np); reservation_area_change(np);
@ -56,10 +53,7 @@ void network_send_change_area(void) {
network_send_to(gNetworkPlayerServer->localIndex, &p); network_send_to(gNetworkPlayerServer->localIndex, &p);
struct NetworkPlayer* np = gNetworkPlayerLocal; struct NetworkPlayer* np = gNetworkPlayerLocal;
np->currCourseNum = gCurrCourseNum; network_player_update_course_level(np, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex);
np->currActNum = gCurrActStarNum;
np->currLevelNum = gCurrLevelNum;
np->currAreaIndex = gCurrAreaIndex;
np->currAreaSyncValid = false; np->currAreaSyncValid = false;
LOG_INFO("tx change area"); LOG_INFO("tx change area");

View file

@ -7,10 +7,7 @@
static void player_changed_level(struct NetworkPlayer* np, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { static void player_changed_level(struct NetworkPlayer* np, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) {
// set NetworkPlayer variables // set NetworkPlayer variables
np->currCourseNum = courseNum; network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex);
np->currActNum = actNum;
np->currLevelNum = levelNum;
np->currAreaIndex = areaIndex;
np->currLevelSyncValid = false; np->currLevelSyncValid = false;
np->currAreaSyncValid = false; np->currAreaSyncValid = false;
reservation_area_change(np); reservation_area_change(np);
@ -62,10 +59,7 @@ void network_send_change_level(void) {
network_send_to(gNetworkPlayerServer->localIndex, &p); network_send_to(gNetworkPlayerServer->localIndex, &p);
struct NetworkPlayer* np = gNetworkPlayerLocal; struct NetworkPlayer* np = gNetworkPlayerLocal;
np->currCourseNum = gCurrCourseNum; network_player_update_course_level(np, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex);
np->currActNum = gCurrActStarNum;
np->currLevelNum = gCurrLevelNum;
np->currAreaIndex = gCurrAreaIndex;
np->currAreaSyncValid = false; np->currAreaSyncValid = false;
np->currLevelSyncValid = false; np->currLevelSyncValid = false;

View file

@ -61,9 +61,6 @@ void network_receive_join_request(struct Packet* p) {
void network_send_join(struct Packet* joinRequestPacket) { void network_send_join(struct Packet* joinRequestPacket) {
SOFT_ASSERT(gNetworkType == NT_SERVER); SOFT_ASSERT(gNetworkType == NT_SERVER);
// make palette unique
sJoinRequestPlayerPalette = network_player_unique_palette(sJoinRequestPlayerPalette);
// do connection event // do connection event
joinRequestPacket->localIndex = network_player_connected(NPT_CLIENT, joinRequestPacket->localIndex, sJoinRequestPlayerModel, sJoinRequestPlayerPalette, sJoinRequestPlayerName); joinRequestPacket->localIndex = network_player_connected(NPT_CLIENT, joinRequestPacket->localIndex, sJoinRequestPlayerModel, sJoinRequestPlayerPalette, sJoinRequestPlayerName);
if (joinRequestPacket->localIndex == UNKNOWN_LOCAL_INDEX) { if (joinRequestPacket->localIndex == UNKNOWN_LOCAL_INDEX) {
@ -93,6 +90,7 @@ void network_send_join(struct Packet* joinRequestPacket) {
packet_write(&p, &gServerSettings.shareLives, sizeof(u8)); packet_write(&p, &gServerSettings.shareLives, sizeof(u8));
packet_write(&p, &gServerSettings.enableCheats, sizeof(u8)); packet_write(&p, &gServerSettings.enableCheats, sizeof(u8));
packet_write(&p, &gServerSettings.bubbleDeath, sizeof(u8)); packet_write(&p, &gServerSettings.bubbleDeath, sizeof(u8));
packet_write(&p, &gServerSettings.headlessServer, sizeof(u8));
packet_write(&p, eeprom, sizeof(u8) * 512); packet_write(&p, eeprom, sizeof(u8) * 512);
u8 modCount = string_linked_list_count(&gRegisteredMods); u8 modCount = string_linked_list_count(&gRegisteredMods);
@ -155,6 +153,7 @@ void network_receive_join(struct Packet* p) {
packet_read(p, &gServerSettings.shareLives, sizeof(u8)); packet_read(p, &gServerSettings.shareLives, sizeof(u8));
packet_read(p, &gServerSettings.enableCheats, sizeof(u8)); packet_read(p, &gServerSettings.enableCheats, sizeof(u8));
packet_read(p, &gServerSettings.bubbleDeath, 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, eeprom, sizeof(u8) * 512);
packet_read(p, &modCount, sizeof(u8)); packet_read(p, &modCount, sizeof(u8));

View file

@ -4,6 +4,10 @@
//#define DISABLE_MODULE_LOG 1 //#define DISABLE_MODULE_LOG 1
#include "pc/debuglog.h" #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 }; static u16 sLevelAreaInformSeq[MAX_PLAYERS][MAX_PLAYERS] = { 0 };
void network_send_level_area_inform(struct NetworkPlayer* np) { 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; sLevelAreaInformSeq[0][globalIndex] = seq;
np->currCourseNum = courseNum; network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex);
np->currActNum = actNum;
np->currLevelNum = levelNum;
np->currAreaIndex = areaIndex;
np->currLevelSyncValid = levelSyncValid; np->currLevelSyncValid = levelSyncValid;
np->currAreaSyncValid = areaSyncValid; np->currAreaSyncValid = areaSyncValid;
} }

View file

@ -87,10 +87,7 @@ void network_receive_network_players(struct Packet* p) {
struct NetworkPlayer* np = &gNetworkPlayers[localIndex]; struct NetworkPlayer* np = &gNetworkPlayers[localIndex];
if (localIndex != 0) { if (localIndex != 0) {
np->currLevelAreaSeqId = levelAreaSeqId; np->currLevelAreaSeqId = levelAreaSeqId;
np->currCourseNum = courseNum; network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex);
np->currActNum = actNum;
np->currLevelNum = levelNum;
np->currAreaIndex = areaIndex;
np->currLevelSyncValid = levelSyncValid; np->currLevelSyncValid = levelSyncValid;
np->currAreaSyncValid = areaSyncValid; np->currAreaSyncValid = areaSyncValid;
LOG_INFO("received network player location (%d, %d, %d, %d)", courseNum, actNum, levelNum, areaIndex); LOG_INFO("received network player location (%d, %d, %d, %d)", courseNum, actNum, levelNum, areaIndex);

View file

@ -341,7 +341,7 @@ void network_receive_player(struct Packet* p) {
// display popup // display popup
u8* rgb = get_player_color(np->paletteIndex, 0); u8* rgb = get_player_color(np->paletteIndex, 0);
char popupMsg[128] = { 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); djui_popup_create(popupMsg, 1);
} }
@ -360,5 +360,9 @@ void network_receive_player(struct Packet* p) {
void network_update_player(void) { void network_update_player(void) {
if (!network_player_any_connected()) { return; } if (!network_player_any_connected()) { return; }
network_send_player(0);
u8 localIsHeadless = (&gNetworkPlayers[0] == gNetworkPlayerServer && gServerSettings.headlessServer);
if (!localIsHeadless) {
network_send_player(0);
}
} }

View file

@ -0,0 +1,45 @@
#include <stdio.h>
#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);
}

View file

@ -2,7 +2,7 @@
#define VERSION_H #define VERSION_H
#define UNSTABLE_BRANCH #define UNSTABLE_BRANCH
#define VERSION_NUMBER 12 #define VERSION_NUMBER 13
#define MAX_VERSION_LENGTH 10 #define MAX_VERSION_LENGTH 10
char* get_version(void); char* get_version(void);

View file

@ -25,6 +25,7 @@
#include "gfx/gfx_dxgi.h" #include "gfx/gfx_dxgi.h"
#include "gfx/gfx_sdl.h" #include "gfx/gfx_sdl.h"
#include "gfx/gfx_dummy.h"
#include "audio/audio_api.h" #include "audio/audio_api.h"
#include "audio/audio_sdl.h" #include "audio/audio_sdl.h"
@ -236,6 +237,8 @@ void main_func(void) {
wm_api = &gfx_sdl; wm_api = &gfx_sdl;
#elif defined(WAPI_DXGI) #elif defined(WAPI_DXGI)
wm_api = &gfx_dxgi; wm_api = &gfx_dxgi;
#elif defined(WAPI_DUMMY)
wm_api = &gfx_dummy_wm_api;
#else #else
#error No window API! #error No window API!
#endif #endif
@ -253,6 +256,8 @@ void main_func(void) {
# else # else
# define RAPI_NAME "OpenGL" # define RAPI_NAME "OpenGL"
# endif # endif
#elif defined(RAPI_DUMMY)
rendering_api = &gfx_dummy_renderer_api;
#else #else
#error No rendering API! #error No rendering API!
#endif #endif

View file

@ -162,7 +162,9 @@ static void sys_fatal_impl(const char *msg) {
#else #else
#ifndef WAPI_DUMMY
#warning "You might want to implement these functions for your platform" #warning "You might want to implement these functions for your platform"
#endif
const char *sys_user_path(void) { const char *sys_user_path(void) {
return "."; return ".";