Merge remote-tracking branch 'sm64ex/nightly' into ex/nightly

This commit is contained in:
VDavid003
2021-07-01 22:28:19 +02:00
28 changed files with 1328 additions and 428 deletions
+36 -16
View File
@@ -30,6 +30,9 @@ TARGET_WEB ?= 0
# Makeflag to enable OSX fixes
OSX_BUILD ?= 0
# Enable -no-pie linker option
NO_PIE ?= 1
# Specify the target you are building for, TARGET_BITS=0 means native
TARGET_ARCH ?= native
TARGET_BITS ?= 0
@@ -59,11 +62,11 @@ NO_LDIV ?= 0
# Renderers: GL, GL_LEGACY, D3D11, D3D12
RENDER_API ?= GL
# Window managers: SDL2, DXGI (forced if D3D11 or D3D12 in RENDER_API)
# Window managers: SDL1, SDL2, DXGI (forced if D3D11 or D3D12 in RENDER_API)
WINDOW_API ?= SDL2
# Audio backends: SDL2
# Audio backends: SDL1, SDL2
AUDIO_API ?= SDL2
# Controller backends (can have multiple, space separated): SDL2
# Controller backends (can have multiple, space separated): SDL2, SDL1
CONTROLLER_API ?= SDL2
# Misc settings for EXTERNAL_DATA
@@ -501,7 +504,9 @@ SDLCONFIG := $(CROSS)sdl2-config
BACKEND_CFLAGS := -DRAPI_$(RENDER_API)=1 -DWAPI_$(WINDOW_API)=1 -DAAPI_$(AUDIO_API)=1
# can have multiple controller APIs
BACKEND_CFLAGS += $(foreach capi,$(CONTROLLER_API),-DCAPI_$(capi)=1)
BACKEND_LDFLAGS :=
BACKEND_LDFLAG0S :=
SDL1_USED := 0
SDL2_USED := 0
# for now, it's either SDL+GL or DXGI+DirectX, so choose based on WAPI
@@ -512,7 +517,7 @@ ifeq ($(WINDOW_API),DXGI)
endif
BACKEND_LDFLAGS += -ld3dcompiler -ldxgi -ldxguid
BACKEND_LDFLAGS += -lsetupapi -ldinput8 -luser32 -lgdi32 -limm32 -lole32 -loleaut32 -lshell32 -lwinmm -lversion -luuid -static
else ifeq ($(WINDOW_API),SDL2)
else ifeq ($(findstring SDL,$(WINDOW_API)),SDL)
ifeq ($(WINDOWS_BUILD),1)
BACKEND_LDFLAGS += -lglew32 -lglu32 -lopengl32
else ifeq ($(TARGET_ANDROID),1)
@@ -524,24 +529,35 @@ else ifeq ($(WINDOW_API),SDL2)
else
BACKEND_LDFLAGS += -lGL
endif
SDL_USED := 2
endif
ifeq ($(AUDIO_API),SDL2)
SDL_USED := 2
ifneq (,$(findstring SDL2,$(AUDIO_API)$(WINDOW_API)$(CONTROLLER_API)))
SDL2_USED := 1
endif
ifneq (,$(findstring SDL,$(CONTROLLER_API)))
SDL_USED := 2
ifneq (,$(findstring SDL1,$(AUDIO_API)$(WINDOW_API)$(CONTROLLER_API)))
SDL1_USED := 1
endif
ifeq ($(SDL1_USED)$(SDL2_USED),11)
$(error Cannot link both SDL1 and SDL2 at the same time)
endif
# SDL can be used by different systems, so we consolidate all of that shit into this
ifeq ($(SDL_USED),2)
ifeq ($(SDL2_USED),1)
SDLCONFIG := $(CROSS)sdl2-config
BACKEND_CFLAGS += -DHAVE_SDL2=1
else ifeq ($(SDL1_USED),1)
SDLCONFIG := $(CROSS)sdl-config
BACKEND_CFLAGS += -DHAVE_SDL1=1
endif
ifneq ($(SDL1_USED)$(SDL2_USED),00)
ifeq ($(TARGET_ANDROID),1)
BACKEND_CFLAGS += -DHAVE_SDL2=1
BACKEND_LDFLAGS += -lhidapi -lSDL2
else
BACKEND_CFLAGS += -DHAVE_SDL2=1 `$(SDLCONFIG) --cflags`
BACKEND_CFLAGS += `$(SDLCONFIG) --cflags`
ifeq ($(WINDOWS_BUILD),1)
BACKEND_LDFLAGS += `$(SDLCONFIG) --static-libs` -lsetupapi -luser32 -limm32 -lole32 -loleaut32 -lshell32 -lwinmm -lversion
else
@@ -637,7 +653,7 @@ endif
ASFLAGS := -I include -I $(BUILD_DIR) $(VERSION_ASFLAGS)
ifeq ($(TARGET_WEB),1)
LDFLAGS := -lm -lGL -lSDL2 -no-pie -s TOTAL_MEMORY=20MB -g4 --source-map-base http://localhost:8080/ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']"
LDFLAGS := -lm -lGL -lSDL2 -no-pie -s TOTAL_MEMORY=64MB -g4 --source-map-base http://localhost:8080/ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']"
else ifeq ($(WINDOWS_BUILD),1)
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -Llib -lpthread $(BACKEND_LDFLAGS) -static
@@ -668,9 +684,13 @@ else ifeq ($(OSX_BUILD),1)
LDFLAGS := -lm $(BACKEND_LDFLAGS) -no-pie -lpthread
else
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm $(BACKEND_LDFLAGS) -no-pie -lpthread
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm $(BACKEND_LDFLAGS) -lpthread -ldl
ifeq ($(NO_PIE), 1)
LDFLAGS += -no-pie
endif
ifeq ($(DISCORDRPC),1)
LDFLAGS += -ldl -Wl,-rpath .
LDFLAGS += -Wl,-rpath .
endif
endif # End of LDFLAGS
+15 -15
View File
@@ -112,7 +112,7 @@ index 802d97a..1b0d677 100644
/** A node that allows an object to specify a different culling radius than the
diff --git a/src/engine/surface_collision.c b/src/engine/surface_collision.c
index 5b6775f..2c11e25 100644
index 1da535b..49a5c03 100644
--- a/src/engine/surface_collision.c
+++ b/src/engine/surface_collision.c
@@ -8,6 +8,7 @@
@@ -1890,19 +1890,10 @@ index 0467495..fa4eb33 100644
using namespace Microsoft::WRL; // For ComPtr
diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c
index 5f4c690..de96bbd 100644
index 42b8541..388e137 100644
--- a/src/pc/gfx/gfx_sdl2.c
+++ b/src/pc/gfx/gfx_sdl2.c
@@ -61,7 +61,7 @@ static void (*touch_up_callback)(void* event);
// whether to use timer for frame control
static bool use_timer = true;
// time between consequtive game frames
-static const int frame_time = 1000 / FRAMERATE;
+static const int frame_time = 1000 / (2 * FRAMERATE);
const SDL_Scancode windows_scancode_table[] = {
/* 0 1 2 3 4 5 6 7 */
@@ -153,11 +153,11 @@ int test_vsync(void) {
@@ -161,11 +161,11 @@ static int test_vsync(void) {
* On SGI models, turning vsync off will help with framerate, but the best is 60fps patch.
* The actual solution would be to render or copy the buffer to a texture
* and then render that to the screen.*/
@@ -1916,11 +1907,11 @@ index 5f4c690..de96bbd 100644
#endif
}
@@ -165,7 +165,11 @@ static inline void gfx_sdl_set_vsync(const bool enabled) {
@@ -173,7 +173,11 @@ static inline void gfx_sdl_set_vsync(const bool enabled) {
if (enabled) {
// try to detect refresh rate
SDL_GL_SetSwapInterval(1);
- const int vblanks = test_vsync();
- const int vblanks = gCLIOpts.SyncFrames ? (int)gCLIOpts.SyncFrames : test_vsync();
+ int vblanks = test_vsync();
+ if (vblanks & 1)
+ vblanks = 0; // not divisible by 60, fuck that
@@ -1929,8 +1920,17 @@ index 5f4c690..de96bbd 100644
if (vblanks) {
printf("determined swap interval: %d\n", vblanks);
SDL_GL_SetSwapInterval(vblanks);
@@ -258,7 +262,7 @@ static void gfx_sdl_init(const char *window_title) {
gfx_sdl_set_fullscreen();
perf_freq = SDL_GetPerformanceFrequency();
- frame_time = perf_freq / FRAMERATE;
+ frame_time = perf_freq / (2 * FRAMERATE);
for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDL_Scancode); i++) {
inverted_scancode_table[windows_scancode_table[i]] = i;
diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c
index a3c9817..8c61830 100644
index 5fda297..35d50db 100644
--- a/src/pc/pc_main.c
+++ b/src/pc/pc_main.c
@@ -84,6 +84,25 @@ void send_display_list(struct SPTask *spTask) {
+2 -1
View File
@@ -14,7 +14,8 @@
// Markers
#define TEXT_OPT_HIGHLIGHT _("O")
#define TEXT_OPT_L_HIGHLIGHT _(">")
#define TEXT_OPT_R_HIGHLIGHT _("<")
#define TEXT_OPT_UNBOUND _("NONE")
// Language specific strings
+12 -5
View File
@@ -851,7 +851,11 @@ void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f
// Reject surface if out of vertical bounds
if (list->surface->lowerY > top || list->surface->upperY < bottom)
continue;
// Reject no-cam collision surfaces
if (gCheckingSurfaceCollisionsForCamera && (list->surface->flags & SURFACE_FLAG_NO_CAM_COLLISION))
continue;
// Check intersection between the ray and this surface
if ((hit = ray_surface_intersect(orig, dir, dir_length, list->surface, chk_hit_pos, &length)) != 0)
{
@@ -919,13 +923,16 @@ void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Ve
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length);
return;
}
// increase collision checking precision (normally 1)
f32 precision = gCheckingSurfaceCollisionsForCamera ? 3 : 1;
// Get cells we cross using DDA
if (absx(dir[0]) >= absx(dir[2]))
step = absx(dir[0]) / CELL_SIZE;
step = precision * absx(dir[0]) / CELL_SIZE;
else
step = absx(dir[2]) / CELL_SIZE;
step = precision * absx(dir[2]) / CELL_SIZE;
dx = dir[0] / step / CELL_SIZE;
dz = dir[2] / step / CELL_SIZE;
@@ -4,6 +4,14 @@ struct Struct8032F754 D_8032F754[] = { { 145, { 0.7f, 1.5f, 0.7f }, 7.0f },
{ 235, { 1.2f, 2.0f, 1.2f }, 11.6f } };
void bhv_checkerboard_elevator_group_init(void) {
// Added to prevent a crash in the vanish cap stage
cur_obj_hide();
// Here's the theory: Since it is only valid for a few frames, I believe
// the model gets deallocated after removal. Since changing the camera
// precision makes the camera end up in a slightly different spot, it
// could be trying to render the object when `precision` is set to 3 but
// not to 1.
s32 sp3C;
s32 sp38;
s32 sp34;
+2 -3
View File
@@ -181,10 +181,9 @@ void bhv_snufit_balls_loop(void) {
// If far from Mario or in a different room, despawn.
if ((o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)
#ifndef NODRAWINGDISTANCE
|| (o->oTimer != 0 && o->oDistanceToMario > 1500.0f)) {
#else
|| (o->oTimer != 0)) {
|| (o->oTimer != 0 && o->oDistanceToMario > 1500.0f)
#endif
){
obj_mark_for_deletion(o);
}
+71 -15
View File
@@ -10,12 +10,16 @@
#include "engine/surface_collision.h"
#include "pc/configfile.h"
#include "pc/controller/controller_mouse.h"
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
//quick and dirty fix for some older MinGW.org mingwrt
#else
#include <stdio.h>
#endif
#define NEW_CAM_BOUNDING_BOX_RAYS 4
#define NEW_CAM_BOUNDING_BOX_HRADIUS 250
#define NEW_CAM_BOUNDING_BOX_VRADIUS 100
/**
Quick explanation of the camera modes
@@ -269,18 +273,18 @@ static void newcam_rotate_button(void) {
play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs);
#endif
if (newcam_modeflags & NC_FLAG_8D)
newcam_yaw_target = newcam_yaw_target+(ivrt(newcam_invertX)*0x2000);
newcam_yaw_target = newcam_yaw_target+(ivrt(0)*0x2000);
else
newcam_yaw_target = newcam_yaw_target+(ivrt(newcam_invertX)*0x4000);
newcam_yaw_target = newcam_yaw_target+(ivrt(0)*0x4000);
newcam_centering = 1;
} else if ((gPlayer1Controller->buttonPressed & R_CBUTTONS) && newcam_analogue == 0) {
#ifndef nosound
play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs);
#endif
if (newcam_modeflags & NC_FLAG_8D)
newcam_yaw_target = newcam_yaw_target-(ivrt(newcam_invertX)*0x2000);
newcam_yaw_target = newcam_yaw_target-(ivrt(0)*0x2000);
else
newcam_yaw_target = newcam_yaw_target-(ivrt(newcam_invertX)*0x4000);
newcam_yaw_target = newcam_yaw_target-(ivrt(0)*0x4000);
newcam_centering = 1;
}
} else if (newcam_modeflags & NC_FLAG_XTURN) {
@@ -314,7 +318,7 @@ static void newcam_rotate_button(void) {
newcam_framessincec[1] ++;
if ((gPlayer1Controller->buttonPressed & L_CBUTTONS) && newcam_modeflags & NC_FLAG_XTURN && !(newcam_modeflags & NC_FLAG_8D) && newcam_analogue == 0) {
if (newcam_framessincec[0] < 6) {
newcam_yaw_target = newcam_yaw+(ivrt(newcam_invertX)*0x3000);
newcam_yaw_target = newcam_yaw+(ivrt(0)*0x3000);
newcam_centering = 1;
#ifndef nosound
play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs);
@@ -324,7 +328,7 @@ static void newcam_rotate_button(void) {
}
if ((gPlayer1Controller->buttonPressed & R_CBUTTONS) && newcam_modeflags & NC_FLAG_XTURN && !(newcam_modeflags & NC_FLAG_8D) && newcam_analogue == 0) {
if (newcam_framessincec[1] < 6) {
newcam_yaw_target = newcam_yaw-(ivrt(newcam_invertX)*0x3000);
newcam_yaw_target = newcam_yaw-(ivrt(0)*0x3000);
newcam_centering = 1;
#ifndef nosound
play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs);
@@ -350,14 +354,14 @@ static void newcam_rotate_button(void) {
#endif
if (newcam_stick2[0] > 20) {
if (newcam_modeflags & NC_FLAG_8D)
newcam_yaw_target = newcam_yaw_target+(ivrt(newcam_invertX)*0x2000);
newcam_yaw_target = newcam_yaw_target+(ivrt(0)*0x2000);
else
newcam_yaw_target = newcam_yaw_target+(ivrt(newcam_invertX)*0x4000);
newcam_yaw_target = newcam_yaw_target+(ivrt(0)*0x4000);
} else {
if (newcam_modeflags & NC_FLAG_8D)
newcam_yaw_target = newcam_yaw_target-(ivrt(newcam_invertX)*0x2000);
newcam_yaw_target = newcam_yaw_target-(ivrt(0)*0x2000);
else
newcam_yaw_target = newcam_yaw_target-(ivrt(newcam_invertX)*0x4000);
newcam_yaw_target = newcam_yaw_target-(ivrt(0)*0x4000);
}
}
} else {
@@ -425,9 +429,9 @@ static void newcam_update_values(void) {
u8 waterflag = 0;
if (newcam_modeflags & NC_FLAG_XTURN)
newcam_yaw -= ((newcam_yaw_acc*(newcam_sensitivityX/10))*ivrt(newcam_invertX));
newcam_yaw -= ((newcam_yaw_acc*(newcam_sensitivityX/10))*ivrt(0));
if (((newcam_tilt <= 12000) && (newcam_tilt >= -12000)) && newcam_modeflags & NC_FLAG_YTURN)
newcam_tilt += ((newcam_tilt_acc*ivrt(newcam_invertY))*(newcam_sensitivityY/10));
newcam_tilt += ((newcam_tilt_acc*ivrt(1))*(newcam_sensitivityY/10));
if (newcam_tilt > 12000)
newcam_tilt = 12000;
@@ -473,6 +477,47 @@ static void newcam_update_values(void) {
}
}
static void newcam_bounding_box(void) {
Vec3f camdirs[NEW_CAM_BOUNDING_BOX_RAYS] = { 0 };
Vec3f raypos[NEW_CAM_BOUNDING_BOX_RAYS] = { 0 };
s16 antiYaw = newcam_yaw - 0x4000;
// sideways ray 1
camdirs[0][0] = coss(antiYaw) * NEW_CAM_BOUNDING_BOX_HRADIUS;
camdirs[0][2] = sins(antiYaw) * NEW_CAM_BOUNDING_BOX_HRADIUS;
// sideways ray 2
camdirs[1][0] = -coss(antiYaw) * NEW_CAM_BOUNDING_BOX_HRADIUS;
camdirs[1][2] = -sins(antiYaw) * NEW_CAM_BOUNDING_BOX_HRADIUS;
// vertical rays
camdirs[2][1] = -NEW_CAM_BOUNDING_BOX_VRADIUS;
camdirs[3][1] = NEW_CAM_BOUNDING_BOX_VRADIUS;
for (int i = 0; i < NEW_CAM_BOUNDING_BOX_RAYS; i++) {
struct Surface* surf;
Vec3f offset = { 0 };
Vec3f startpos = { 0 };
vec3f_copy(startpos, newcam_pos);
vec3f_add(startpos, offset);
find_surface_on_ray(startpos, camdirs[i], &surf, raypos[i]);
if (!surf) {
vec3f_copy(raypos[i], startpos);
vec3f_add(raypos[i], camdirs[i]);
}
}
Vec3f avg = { 0 };
for (int i = 0; i < NEW_CAM_BOUNDING_BOX_RAYS; i++) {
vec3f_add(avg, raypos[i]);
}
vec3f_mul(avg, 1.0f / ((f32)NEW_CAM_BOUNDING_BOX_RAYS));
vec3f_copy(newcam_pos, avg);
}
static void newcam_collision(void) {
struct Surface *surf;
Vec3f camdir;
@@ -483,11 +528,20 @@ static void newcam_collision(void) {
camdir[2] = newcam_pos[2]-newcam_lookat[2];
find_surface_on_ray(newcam_pos_target, camdir, &surf, hitpos);
newcam_coldist = sqrtf((newcam_pos_target[0] - hitpos[0]) * (newcam_pos_target[0] - hitpos[0]) + (newcam_pos_target[1] - hitpos[1]) * (newcam_pos_target[1] - hitpos[1]) + (newcam_pos_target[2] - hitpos[2]) * (newcam_pos_target[2] - hitpos[2]));
if (surf) {
// offset the hit pos by the hit normal
Vec3f offset = { 0 };
offset[0] = surf->normal.x;
offset[1] = surf->normal.y;
offset[2] = surf->normal.z;
vec3f_mul(offset, 5.0f);
vec3f_add(hitpos, offset);
newcam_pos[0] = hitpos[0];
newcam_pos[1] = approach_f32(hitpos[1],newcam_pos[1],25,-25);
newcam_pos[1] = hitpos[1];
newcam_pos[2] = hitpos[2];
newcam_pan_x = 0;
newcam_pan_z = 0;
@@ -541,8 +595,10 @@ static void newcam_position_cam(void) {
if (newcam_modeflags & NC_FLAG_FOCUSZ)
newcam_lookat[2] = newcam_pos_target[2]-newcam_pan_z;
if (newcam_modeflags & NC_FLAG_COLLISION)
newcam_collision();
if (newcam_modeflags & NC_FLAG_COLLISION) {
newcam_collision();
newcam_bounding_box();
}
}
+1 -1
View File
@@ -1754,7 +1754,7 @@ s32 act_flying(struct MarioState *m) {
set_camera_mode(m->area->camera, CAMERA_MODE_BEHIND_MARIO, 1);
#else
if (newcam_active == 0)
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
set_camera_mode(m->area->camera, CAMERA_MODE_BEHIND_MARIO, 1);
else
{
m->area->camera->mode = CAMERA_MODE_NEWCAM;
+1
View File
@@ -9,6 +9,7 @@
#define MEMORY_POOL_RIGHT 1
#define GFX_POOL_SIZE (512 * 1024)
#define DEFAULT_POOL_SIZE (0x165000 * 8)
struct AllocOnlyPool
{
+26 -25
View File
@@ -1,7 +1,7 @@
#ifdef EXT_OPTIONS_MENU
#include "sm64.h"
#include "include/text_strings.h"
#include "text_strings.h"
#include "engine/math_util.h"
#include "audio/external.h"
#include "game/camera.h"
@@ -45,10 +45,14 @@ static const u8 toggleStr[][16] = {
{ TEXT_OPT_ENABLED },
};
static const u8 menuStr[][32] = {
{ TEXT_OPT_HIGHLIGHT },
static const u8 optSmallStr[][32] = {
{ TEXT_OPT_BUTTON1 },
{ TEXT_OPT_BUTTON2 },
{ TEXT_OPT_L_HIGHLIGHT },
{ TEXT_OPT_R_HIGHLIGHT },
};
static const u8 menuStr[][32] = {
{ TEXT_OPT_OPTIONS },
{ TEXT_OPT_CAMERA },
{ TEXT_OPT_CONTROLS },
@@ -56,7 +60,6 @@ static const u8 menuStr[][32] = {
{ TEXT_OPT_AUDIO },
{ TEXT_EXIT_GAME },
{ TEXT_OPT_CHEATS },
};
static const u8 optsCameraStr[][32] = {
@@ -122,7 +125,7 @@ static const u8 bindStr[][32] = {
{ TEXT_BIND_LEFT },
{ TEXT_BIND_RIGHT },
{ TEXT_OPT_DEADZONE },
{ TEXT_OPT_RUMBLE }
{ TEXT_OPT_RUMBLE },
};
static const u8 *filterChoices[] = {
@@ -285,28 +288,28 @@ static struct Option optsCheats[] = {
/* submenu definitions */
#ifdef BETTERCAMERA
static struct SubMenu menuCamera = DEF_SUBMENU( menuStr[4], optsCamera );
static struct SubMenu menuCamera = DEF_SUBMENU( menuStr[1], optsCamera );
#endif
static struct SubMenu menuControls = DEF_SUBMENU( menuStr[5], optsControls );
static struct SubMenu menuVideo = DEF_SUBMENU( menuStr[6], optsVideo );
static struct SubMenu menuAudio = DEF_SUBMENU( menuStr[7], optsAudio );
static struct SubMenu menuCheats = DEF_SUBMENU( menuStr[9], optsCheats );
static struct SubMenu menuControls = DEF_SUBMENU( menuStr[2], optsControls );
static struct SubMenu menuVideo = DEF_SUBMENU( menuStr[3], optsVideo );
static struct SubMenu menuAudio = DEF_SUBMENU( menuStr[4], optsAudio );
static struct SubMenu menuCheats = DEF_SUBMENU( menuStr[6], optsCheats );
/* main options menu definition */
static struct Option optsMain[] = {
#ifdef BETTERCAMERA
DEF_OPT_SUBMENU( menuStr[4], &menuCamera ),
DEF_OPT_SUBMENU( menuStr[1], &menuCamera ),
#endif
DEF_OPT_SUBMENU( menuStr[5], &menuControls ),
DEF_OPT_SUBMENU( menuStr[6], &menuVideo ),
DEF_OPT_SUBMENU( menuStr[7], &menuAudio ),
DEF_OPT_BUTTON ( menuStr[8], optmenu_act_exit ),
DEF_OPT_SUBMENU( menuStr[2], &menuControls ),
DEF_OPT_SUBMENU( menuStr[3], &menuVideo ),
DEF_OPT_SUBMENU( menuStr[4], &menuAudio ),
DEF_OPT_BUTTON ( menuStr[5], optmenu_act_exit ),
// NOTE: always keep cheats the last option here because of the half-assed way I toggle them
DEF_OPT_SUBMENU( menuStr[9], &menuCheats )
DEF_OPT_SUBMENU( menuStr[6], &menuCheats )
};
static struct SubMenu menuMain = DEF_SUBMENU( menuStr[3], optsMain );
static struct SubMenu menuMain = DEF_SUBMENU( menuStr[0], optsMain );
/* implementation */
@@ -465,6 +468,7 @@ void optmenu_draw(void) {
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, 80, SCREEN_WIDTH, SCREEN_HEIGHT);
for (u8 i = 0; i < currentMenu->numOpts; i++) {
scroll = 140 - 32 * i + currentMenu->scroll * 32;
// FIXME: just start from the first visible option bruh
@@ -473,18 +477,16 @@ void optmenu_draw(void) {
}
gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255);
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_begin);
print_hud_lut_string(HUD_LUT_GLOBAL, 80, 90 + (32 * (currentMenu->select - currentMenu->scroll)), menuStr[0]);
print_hud_lut_string(HUD_LUT_GLOBAL, 224, 90 + (32 * (currentMenu->select - currentMenu->scroll)), menuStr[0]);
gSPDisplayList(gDisplayListHead++, dl_rgba16_text_end);
print_generic_string(72, 132 - (32 * (currentMenu->select - currentMenu->scroll)), optSmallStr[2]);
print_generic_string(232, 132 - (32 * (currentMenu->select - currentMenu->scroll)), optSmallStr[3]);
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
}
//This has been separated for interesting reasons. Don't question it.
void optmenu_draw_prompt(void) {
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
optmenu_draw_text(264, 212, menuStr[1 + optmenu_open], 0);
optmenu_draw_text(264, 212, optSmallStr[optmenu_open], 0);
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
}
@@ -506,7 +508,6 @@ void optmenu_toggle(void) {
currentMenu = &menuMain;
optmenu_open = 1;
/* Resets l_counter to 0 every time the options menu is open */
l_counter = 0;
} else {
@@ -538,7 +539,7 @@ void optmenu_check_buttons(void) {
if (gPlayer1Controller->buttonPressed & R_TRIG)
optmenu_toggle();
/* Enables cheats if the user press the L trigger 3 times while in the options menu. Also plays a sound. */
if ((gPlayer1Controller->buttonPressed & L_TRIG) && !Cheats.EnableCheats) {
+6
View File
@@ -615,6 +615,12 @@ u32 save_file_get_star_flags(s32 fileIndex, s32 courseIndex) {
return starFlags;
}
u32 save_file_get_cannon_flags(s32 fileIndex, s32 courseIndex) {
if (gSaveBuffer.files[fileIndex][0].courseStars[courseIndex+1] & 0x80){return 1;}
return 0;
}
/**
* Add to the bitset of obtained stars in the specified course.
+1
View File
@@ -135,6 +135,7 @@ void save_file_set_flags(u32 flags);
void save_file_clear_flags(u32 flags);
u32 save_file_get_flags(void);
u32 save_file_get_star_flags(s32 fileIndex, s32 courseIndex);
u32 save_file_get_cannon_flags(s32 fileIndex, s32 courseIndex);
void save_file_set_star_flags(s32 fileIndex, s32 courseIndex, u32 starFlags);
s32 save_file_get_course_coin_score(s32 fileIndex, s32 courseIndex);
s32 save_file_is_cannon_unlocked(void);
+7 -5
View File
@@ -81,7 +81,7 @@ static s32 write_text_save(s32 fileIndex) {
struct MainMenuSaveData *menudata;
char filename[SYS_MAX_PATH] = { 0 };
char value[64];
u32 i, bit, flags, coins, stars, starFlags;
u32 i, bit, flags, coins, stars, starFlags, cannonFlag;
if (snprintf(filename, sizeof(filename), FILENAME_FORMAT, fs_writepath, fileIndex) < 0)
return -1;
@@ -133,9 +133,10 @@ static s32 write_text_save(s32 fileIndex) {
for (i = 0; i < NUM_COURSES; i++) {
stars = save_file_get_star_flags(fileIndex, i);
coins = save_file_get_course_coin_score(fileIndex, i);
cannonFlag = save_file_get_cannon_flags(fileIndex, i);
starFlags = int_to_bin(stars); // 63 -> 111111
fprintf(file, "%s = \"%d, %07d\"\n", sav_courses[i], coins, starFlags);
fprintf(file, "%s = \"%d, %07d, %d\"\n", sav_courses[i], coins, starFlags,cannonFlag);
}
fprintf(file, "\n[bonus]\n");
@@ -208,7 +209,7 @@ static s32 read_text_save(s32 fileIndex) {
const char *value;
ini_t *savedata;
u32 i, flag, coins, stars, starFlags;
u32 i, flag, coins, stars, starFlags, cannonFlag;
u32 capArea;
if (snprintf(filename, sizeof(filename), FILENAME_FORMAT, fs_writepath, fileIndex) < 0)
@@ -255,9 +256,10 @@ static s32 read_text_save(s32 fileIndex) {
for (i = 0; i < NUM_COURSES; i++) {
value = ini_get(savedata, "courses", sav_courses[i]);
if (value) {
sscanf(value, "%d, %d", &coins, &stars);
sscanf(value, "%d, %d, %d", &coins, &stars, &cannonFlag);
starFlags = bin_to_int(stars); // 111111 -> 63
cannonFlag <<= 7; //Shifts the bit to the most significant bit.
save_file_set_star_flags(fileIndex, i+1, cannonFlag); //
save_file_set_star_flags(fileIndex, i, starFlags);
gSaveBuffer.files[fileIndex][0].courseCoinScores[i] = coins;
}
+190
View File
@@ -0,0 +1,190 @@
#ifdef AAPI_SDL1
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <SDL/SDL.h>
#include "audio_api.h"
#define SNDPACKETLEN (8 * 1024)
// this is basically SDL_dataqueue but slightly less generic
typedef struct sndpacket {
size_t datalen; /* bytes currently in use in this packet. */
size_t startpos; /* bytes currently consumed in this packet. */
struct sndpacket *next; /* next item in linked list. */
Uint8 data[]; /* packet data */
} sndpacket_t;
static sndpacket_t *qhead;
static sndpacket_t *qtail;
static sndpacket_t *qpool;
static size_t queued;
static SDL_AudioSpec aspec;
static int was_init = 0;
static void sndqueue_init(const size_t bufsize) {
const size_t wantpackets = (bufsize + (SNDPACKETLEN - 1)) / SNDPACKETLEN;
for (size_t i = 0; i < wantpackets; ++i) {
sndpacket_t *packet = malloc(sizeof(sndpacket_t) + SNDPACKETLEN);
if (packet) {
packet->datalen = 0;
packet->startpos = 0;
packet->next = qpool;
qpool = packet;
}
}
}
static size_t sndqueue_read(void *buf, size_t len) {
sndpacket_t *packet;
Uint8 *ptr = buf;
while ((len > 0) && ((packet = qhead) != NULL)) {
const size_t avail = packet->datalen - packet->startpos;
const size_t tx = (len < avail) ? len : avail;
memcpy(ptr, packet->data + packet->startpos, tx);
packet->startpos += tx;
ptr += tx;
queued -= tx;
len -= tx;
if (packet->startpos == packet->datalen) {
qhead = packet->next;
packet->next = qpool;
qpool = packet;
}
}
if (qhead == NULL)
qtail = NULL;
return (size_t)(ptr - (Uint8*)buf);
}
static inline sndpacket_t *alloc_sndpacket(void) {
sndpacket_t *packet = qpool;
if (packet) {
qpool = packet->next;
} else {
packet = malloc(sizeof(sndpacket_t) + SNDPACKETLEN);
if (!packet) return NULL;
}
packet->datalen = 0;
packet->startpos = 0;
packet->next = NULL;
if (qtail == NULL)
qhead = packet;
else
qtail->next = packet;
qtail = packet;
return packet;
}
static int sndqueue_push(const void *data, size_t len) {
sndpacket_t *orighead = qhead;
sndpacket_t *origtail = qtail;
size_t origlen = origtail ? origtail->datalen : 0;
Uint8 *ptr = data;
while (len > 0) {
sndpacket_t *packet = qtail;
if (!packet || (packet->datalen >= SNDPACKETLEN)) {
packet = alloc_sndpacket();
if (!packet) {
// out of memory, fuck everything
return -1;
}
}
const size_t room = SNDPACKETLEN - packet->datalen;
const size_t datalen = (len < room) ? len : room;
memcpy(packet->data + packet->datalen, ptr, datalen);
ptr += datalen;
len -= datalen;
packet->datalen += datalen;
queued += datalen;
}
return 0;
}
static void audio_drain(void *user, Uint8 *buf, int len) {
const size_t tx = sndqueue_read(buf, len);
buf += tx;
len -= (int)tx;
if (len > 0) memset(buf, aspec.silence, len);
}
static bool audio_sdl_init(void) {
if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) {
fprintf(stderr, "SDL init error: %s\n", SDL_GetError());
return false;
}
SDL_AudioSpec want, have;
memset(&want, 0, sizeof(want));
want.freq = 32000;
want.format = AUDIO_S16SYS;
want.channels = 2;
want.samples = 512;
want.callback = audio_drain;
if (SDL_OpenAudio(&want, &have) == -1) {
fprintf(stderr, "SDL_OpenAudio error: %s\n", SDL_GetError());
return false;
}
aspec = have;
was_init = 1;
SDL_PauseAudio(0);
return true;
}
static int audio_sdl_buffered(void) {
SDL_LockAudio();
int len = queued / 4;
SDL_UnlockAudio();
return len;
}
static int audio_sdl_get_desired_buffered(void) {
return 1100;
}
static void audio_sdl_play(const uint8_t *buf, size_t len) {
SDL_LockAudio();
// Don't fill the audio buffer too much in case this happens
if (queued / 4 < 6000)
sndqueue_push(buf, len);
SDL_UnlockAudio();
}
static void audio_sdl_shutdown(void) {
if (SDL_WasInit(SDL_INIT_AUDIO)) {
if (was_init) {
SDL_CloseAudio();
was_init = 0;
}
SDL_QuitSubSystem(SDL_INIT_AUDIO);
}
}
struct AudioAPI audio_sdl = {
audio_sdl_init,
audio_sdl_buffered,
audio_sdl_get_desired_buffered,
audio_sdl_play,
audio_sdl_shutdown
};
#endif
@@ -11,10 +11,11 @@ static bool audio_sdl_init(void) {
fprintf(stderr, "SDL init error: %s\n", SDL_GetError());
return false;
}
SDL_AudioSpec want, have;
SDL_zero(want);
want.freq = 32000;
want.format = AUDIO_S16;
want.format = AUDIO_S16SYS;
want.channels = 2;
want.samples = 512;
want.callback = NULL;
+13
View File
@@ -3,6 +3,7 @@
#include "cheats.h"
#include "pc_main.h"
#include "platform.h"
#include "macros.h"
#include <strings.h>
#include <stdlib.h>
@@ -34,6 +35,12 @@ static inline int arg_string(const char *name, const char *value, char *target)
return 1;
}
static inline int arg_uint(UNUSED const char *name, const char *value, unsigned int *target) {
const unsigned long int v = strtoul(value, NULL, 0);
*target = v;
return 1;
}
void parse_cli_opts(int argc, char* argv[]) {
// Initialize options with false values.
memset(&gCLIOpts, 0, sizeof(gCLIOpts));
@@ -51,6 +58,12 @@ void parse_cli_opts(int argc, char* argv[]) {
else if (strcmp(argv[i], "--cheats") == 0) // Enable cheats menu
Cheats.EnableCheats = true;
else if (strcmp(argv[i], "--poolsize") == 0) // Main pool size
arg_uint("--poolsize", argv[++i], &gCLIOpts.PoolSize);
else if (strcmp(argv[i], "--syncframes") == 0) // VBlanks to wait
arg_uint("--syncframes", argv[++i], &gCLIOpts.SyncFrames);
else if (strcmp(argv[i], "--configfile") == 0 && (i + 1) < argc)
arg_string("--configfile", argv[++i], gCLIOpts.ConfigFile);
+2
View File
@@ -6,6 +6,8 @@
struct PCCLIOptions {
unsigned int SkipIntro;
unsigned int FullScreen;
unsigned int PoolSize;
unsigned int SyncFrames;
char ConfigFile[SYS_MAX_PATH];
char SavePath[SYS_MAX_PATH];
char GameDir[SYS_MAX_PATH];
+7 -4
View File
@@ -14,7 +14,9 @@
static struct ControllerAPI *controller_implementations[] = {
&controller_recorded_tas,
#if defined(CAPI_SDL2) || defined(CAPI_SDL1)
&controller_sdl,
#endif
&controller_keyboard,
#ifdef TOUCH_CONTROLS
&controller_touchscreen,
@@ -22,9 +24,8 @@ static struct ControllerAPI *controller_implementations[] = {
};
s32 osContInit(UNUSED OSMesgQueue *mq, u8 *controllerBits, UNUSED OSContStatus *status) {
for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++) {
for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++)
controller_implementations[i]->init();
}
*controllerBits = 1;
return 0;
}
@@ -32,12 +33,14 @@ s32 osContInit(UNUSED OSMesgQueue *mq, u8 *controllerBits, UNUSED OSContStatus *
s32 osMotorStart(UNUSED void *pfs) {
// Since rumble stops by osMotorStop, its duration is not nessecary.
// Set it to 5 seconds and hope osMotorStop() is called in time.
controller_rumble_play(configRumbleStrength / 100.0f, 5.0f);
if (configRumbleStrength)
controller_rumble_play(configRumbleStrength / 100.0f, 5.0f);
return 0;
}
s32 osMotorStop(UNUSED void *pfs) {
controller_rumble_stop();
if (configRumbleStrength)
controller_rumble_stop();
return 0;
}
+285
View File
@@ -0,0 +1,285 @@
#ifdef CAPI_SDL1
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <math.h>
#include <SDL/SDL.h>
// Analog camera movement by Pathétique (github.com/vrmiguel), y0shin and Mors
// Contribute or communicate bugs at github.com/vrmiguel/sm64-analog-camera
#include <ultra64.h>
#include "controller_api.h"
#include "controller_sdl.h"
#include "../configfile.h"
#include "../platform.h"
#include "../fs/fs.h"
#include "game/level_update.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
#define AXIS_THRESHOLD (30 * 256)
enum {
JOY_AXIS_LEFTX,
JOY_AXIS_LEFTY,
JOY_AXIS_RIGHTX,
JOY_AXIS_RIGHTY,
JOY_AXIS_LTRIG,
JOY_AXIS_RTRIG,
MAX_AXES,
};
int mouse_x;
int mouse_y;
#ifdef BETTERCAMERA
extern u8 newcam_mouse;
#endif
static bool init_ok;
static SDL_Joystick *sdl_joy;
static u32 num_joy_binds = 0;
static u32 num_mouse_binds = 0;
static u32 joy_binds[MAX_JOYBINDS][2];
static u32 mouse_binds[MAX_JOYBINDS][2];
static int joy_axis_binds[MAX_AXES] = { 0, 1, 2, 3, 4, 5 };
static bool joy_buttons[MAX_JOYBUTTONS] = { false };
static u32 mouse_buttons = 0;
static u32 last_mouse = VK_INVALID;
static u32 last_joybutton = VK_INVALID;
static int num_joy_axes = 0;
static int num_joy_buttons = 0;
static int num_joy_hats = 0;
static inline void controller_add_binds(const u32 mask, const u32 *btns) {
for (u32 i = 0; i < MAX_BINDS; ++i) {
if (btns[i] >= VK_BASE_SDL_GAMEPAD && btns[i] <= VK_BASE_SDL_GAMEPAD + VK_SIZE) {
if (btns[i] >= VK_BASE_SDL_MOUSE && num_joy_binds < MAX_JOYBINDS) {
mouse_binds[num_mouse_binds][0] = btns[i] - VK_BASE_SDL_MOUSE;
mouse_binds[num_mouse_binds][1] = mask;
++num_mouse_binds;
} else if (num_mouse_binds < MAX_JOYBINDS) {
joy_binds[num_joy_binds][0] = btns[i] - VK_BASE_SDL_GAMEPAD;
joy_binds[num_joy_binds][1] = mask;
++num_joy_binds;
}
}
}
}
static void controller_sdl_bind(void) {
bzero(joy_binds, sizeof(joy_binds));
bzero(mouse_binds, sizeof(mouse_binds));
num_joy_binds = 0;
num_mouse_binds = 0;
controller_add_binds(A_BUTTON, configKeyA);
controller_add_binds(B_BUTTON, configKeyB);
controller_add_binds(Z_TRIG, configKeyZ);
controller_add_binds(STICK_UP, configKeyStickUp);
controller_add_binds(STICK_LEFT, configKeyStickLeft);
controller_add_binds(STICK_DOWN, configKeyStickDown);
controller_add_binds(STICK_RIGHT, configKeyStickRight);
controller_add_binds(U_CBUTTONS, configKeyCUp);
controller_add_binds(L_CBUTTONS, configKeyCLeft);
controller_add_binds(D_CBUTTONS, configKeyCDown);
controller_add_binds(R_CBUTTONS, configKeyCRight);
controller_add_binds(L_TRIG, configKeyL);
controller_add_binds(R_TRIG, configKeyR);
controller_add_binds(START_BUTTON, configKeyStart);
}
static void controller_sdl_init(void) {
if (SDL_Init(SDL_INIT_JOYSTICK) != 0) {
fprintf(stderr, "SDL init error: %s\n", SDL_GetError());
return;
}
if (SDL_NumJoysticks() > 0)
sdl_joy = SDL_JoystickOpen(0);
if (sdl_joy) {
num_joy_axes = SDL_JoystickNumAxes(sdl_joy);
num_joy_buttons = SDL_JoystickNumButtons(sdl_joy);
num_joy_hats = SDL_JoystickNumHats(sdl_joy);
for (int i = 0; i < MAX_AXES; ++i)
if (i >= num_joy_axes)
joy_axis_binds[i] = -1;
}
#ifdef BETTERCAMERA
if (newcam_mouse == 1)
SDL_WM_GrabInput(SDL_GRAB_ON);
SDL_GetRelativeMouseState(&mouse_x, &mouse_y);
#endif
controller_sdl_bind();
init_ok = true;
}
static inline void update_button(const int i, const bool new) {
const bool pressed = !joy_buttons[i] && new;
joy_buttons[i] = new;
if (pressed) last_joybutton = i;
}
static inline int16_t get_axis(const int i) {
if (joy_axis_binds[i] >= 0)
return SDL_JoystickGetAxis(sdl_joy, i);
else
return 0;
}
static void controller_sdl_read(OSContPad *pad) {
if (!init_ok) return;
#ifdef BETTERCAMERA
if (newcam_mouse == 1 && sCurrPlayMode != 2)
SDL_WM_GrabInput(SDL_GRAB_ON);
else
SDL_WM_GrabInput(SDL_GRAB_OFF);
u32 mouse = SDL_GetRelativeMouseState(&mouse_x, &mouse_y);
for (u32 i = 0; i < num_mouse_binds; ++i)
if (mouse & SDL_BUTTON(mouse_binds[i][0]))
pad->button |= mouse_binds[i][1];
// remember buttons that changed from 0 to 1
last_mouse = (mouse_buttons ^ mouse) & mouse;
mouse_buttons = mouse;
#endif
if (!sdl_joy) return;
SDL_JoystickUpdate();
int16_t leftx = get_axis(JOY_AXIS_LEFTX);
int16_t lefty = get_axis(JOY_AXIS_LEFTY);
int16_t rightx = get_axis(JOY_AXIS_RIGHTX);
int16_t righty = get_axis(JOY_AXIS_RIGHTY);
int16_t ltrig = get_axis(JOY_AXIS_LTRIG);
int16_t rtrig = get_axis(JOY_AXIS_RTRIG);
#ifdef TARGET_WEB
// Firefox has a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1606562
// It sets down y to 32768.0f / 32767.0f, which is greater than the allowed 1.0f,
// which SDL then converts to a int16_t by multiplying by 32767.0f, which overflows into -32768.
// Maximum up will hence never become -32768 with the current version of SDL2,
// so this workaround should be safe in compliant browsers.
if (lefty == -32768) {
lefty = 32767;
}
if (righty == -32768) {
righty = 32767;
}
#endif
for (int i = 0; i < num_joy_buttons; ++i) {
const bool new = SDL_JoystickGetButton(sdl_joy, i);
update_button(i, new);
}
update_button(VK_LTRIGGER - VK_BASE_SDL_GAMEPAD, ltrig > AXIS_THRESHOLD);
update_button(VK_RTRIGGER - VK_BASE_SDL_GAMEPAD, rtrig > AXIS_THRESHOLD);
u32 buttons_down = 0;
for (u32 i = 0; i < num_joy_binds; ++i)
if (joy_buttons[joy_binds[i][0]])
buttons_down |= joy_binds[i][1];
pad->button |= buttons_down;
const u32 xstick = buttons_down & STICK_XMASK;
const u32 ystick = buttons_down & STICK_YMASK;
if (xstick == STICK_LEFT)
pad->stick_x = -128;
else if (xstick == STICK_RIGHT)
pad->stick_x = 127;
if (ystick == STICK_DOWN)
pad->stick_y = -128;
else if (ystick == STICK_UP)
pad->stick_y = 127;
if (rightx < -0x4000) pad->button |= L_CBUTTONS;
if (rightx > 0x4000) pad->button |= R_CBUTTONS;
if (righty < -0x4000) pad->button |= U_CBUTTONS;
if (righty > 0x4000) pad->button |= D_CBUTTONS;
uint32_t magnitude_sq = (uint32_t)(leftx * leftx) + (uint32_t)(lefty * lefty);
uint32_t stickDeadzoneActual = configStickDeadzone * DEADZONE_STEP;
if (magnitude_sq > (uint32_t)(stickDeadzoneActual * stickDeadzoneActual)) {
pad->stick_x = leftx / 0x100;
int stick_y = -lefty / 0x100;
pad->stick_y = stick_y == 128 ? 127 : stick_y;
}
magnitude_sq = (uint32_t)(rightx * rightx) + (uint32_t)(righty * righty);
stickDeadzoneActual = configStickDeadzone * DEADZONE_STEP;
if (magnitude_sq > (uint32_t)(stickDeadzoneActual * stickDeadzoneActual)) {
pad->ext_stick_x = rightx / 0x100;
int stick_y = -righty / 0x100;
pad->ext_stick_y = stick_y == 128 ? 127 : stick_y;
}
}
static void controller_sdl_rumble_play(f32 strength, f32 length) { }
static void controller_sdl_rumble_stop(void) { }
static u32 controller_sdl_rawkey(void) {
if (last_joybutton != VK_INVALID) {
const u32 ret = last_joybutton;
last_joybutton = VK_INVALID;
return ret;
}
for (int i = 0; i < MAX_MOUSEBUTTONS; ++i) {
if (last_mouse & SDL_BUTTON(i)) {
const u32 ret = VK_OFS_SDL_MOUSE + i;
last_mouse = 0;
return ret;
}
}
return VK_INVALID;
}
static void controller_sdl_shutdown(void) {
if (SDL_WasInit(SDL_INIT_JOYSTICK)) {
if (sdl_joy) {
SDL_JoystickClose(sdl_joy);
sdl_joy = NULL;
}
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
}
init_ok = false;
}
struct ControllerAPI controller_sdl = {
VK_BASE_SDL_GAMEPAD,
controller_sdl_init,
controller_sdl_read,
controller_sdl_rawkey,
controller_sdl_rumble_play,
controller_sdl_rumble_stop,
controller_sdl_bind,
controller_sdl_shutdown
};
#endif // CAPI_SDL1
@@ -89,13 +89,6 @@ static void controller_sdl_bind(void) {
}
static void controller_sdl_init(void) {
if (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS) != 0) {
fprintf(stderr, "SDL init error: %s\n", SDL_GetError());
return;
}
haptics_enabled = (SDL_InitSubSystem(SDL_INIT_HAPTIC) == 0);
// try loading an external gamecontroller mapping file
uint64_t gcsize = 0;
void *gcdata = fs_load_file("gamecontrollerdb.txt", &gcsize);
@@ -109,6 +102,13 @@ static void controller_sdl_init(void) {
free(gcdata);
}
if (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS) != 0) {
fprintf(stderr, "SDL init error: %s\n", SDL_GetError());
return;
}
haptics_enabled = (SDL_InitSubSystem(SDL_INIT_HAPTIC) == 0);
#ifdef BETTERCAMERA
if (newcam_mouse == 1)
SDL_SetRelativeMouseMode(SDL_TRUE);

Some files were not shown because too many files have changed in this diff Show More