mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 13:35:12 +00:00
Merge pull request #175 from sm64pc/nightly
Update master with new stuff from nightly
This commit is contained in:
commit
34e5ff3fc7
13 changed files with 277 additions and 57 deletions
|
@ -1,4 +1,4 @@
|
||||||
#ifndef TEXT_STRINGS_H
|
#ifndef TEXT_STRINGS_H
|
||||||
#define TEXT_STRINGS_H
|
#define TEXT_STRINGS_H
|
||||||
|
|
||||||
#include "text_menu_strings.h"
|
#include "text_menu_strings.h"
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
#define TEXT_OPT_NEAREST _("Nearest")
|
#define TEXT_OPT_NEAREST _("Nearest")
|
||||||
#define TEXT_OPT_LINEAR _("Linear")
|
#define TEXT_OPT_LINEAR _("Linear")
|
||||||
#define TEXT_OPT_MVOLUME _("Master Volume")
|
#define TEXT_OPT_MVOLUME _("Master Volume")
|
||||||
|
#define TEXT_RESET_WINDOW _("Reset Window")
|
||||||
|
|
||||||
#define TEXT_OPT_UNBOUND _("NONE")
|
#define TEXT_OPT_UNBOUND _("NONE")
|
||||||
#define TEXT_OPT_PRESSKEY _("...")
|
#define TEXT_OPT_PRESSKEY _("...")
|
||||||
|
@ -45,6 +46,14 @@
|
||||||
#define TEXT_BIND_LEFT _("Stick Left")
|
#define TEXT_BIND_LEFT _("Stick Left")
|
||||||
#define TEXT_BIND_RIGHT _("Stick Right")
|
#define TEXT_BIND_RIGHT _("Stick Right")
|
||||||
|
|
||||||
|
#define TEXT_OPT_CHEATS _("CHEATS")
|
||||||
|
#define TEXT_OPT_CHEAT1 _("Enable cheats")
|
||||||
|
#define TEXT_OPT_CHEAT2 _("Moonjump (Press L)")
|
||||||
|
#define TEXT_OPT_CHEAT3 _("Invincible Mario")
|
||||||
|
#define TEXT_OPT_CHEAT4 _("Infinite lives")
|
||||||
|
#define TEXT_OPT_CHEAT5 _("Super speed")
|
||||||
|
#define TEXT_OPT_CHEAT6 _("Super responsive controls")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global Symbols
|
* Global Symbols
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -617,7 +617,7 @@ static void newcam_apply_values(struct Camera *c)
|
||||||
gLakituState.yaw = -newcam_yaw+0x4000;
|
gLakituState.yaw = -newcam_yaw+0x4000;
|
||||||
|
|
||||||
//Adds support for wing mario tower
|
//Adds support for wing mario tower
|
||||||
if (gMarioState->floor->type == SURFACE_LOOK_UP_WARP) {
|
if (gMarioState->floor && gMarioState->floor->type == SURFACE_LOOK_UP_WARP) {
|
||||||
if (save_file_get_total_star_count(gCurrSaveFileNum - 1, 0, 0x18) >= 10) {
|
if (save_file_get_total_star_count(gCurrSaveFileNum - 1, 0, 0x18) >= 10) {
|
||||||
if (newcam_tilt < -8000 && gMarioState->forwardVel == 0) {
|
if (newcam_tilt < -8000 && gMarioState->forwardVel == 0) {
|
||||||
level_trigger_warp(gMarioState, 1);
|
level_trigger_warp(gMarioState, 1);
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#include "engine/surface_collision.h"
|
#include "engine/surface_collision.h"
|
||||||
#include "level_table.h"
|
#include "level_table.h"
|
||||||
#include "thread6.h"
|
#include "thread6.h"
|
||||||
|
#include "pc/configfile.h"
|
||||||
|
#include "pc/cheats.h"
|
||||||
#ifdef BETTERCAMERA
|
#ifdef BETTERCAMERA
|
||||||
#include "bettercamera.h"
|
#include "bettercamera.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -1397,6 +1399,13 @@ void update_mario_inputs(struct MarioState *m) {
|
||||||
|
|
||||||
debug_print_speed_action_normal(m);
|
debug_print_speed_action_normal(m);
|
||||||
|
|
||||||
|
/* Moonjump cheat */
|
||||||
|
while (Cheats.MoonJump == true && Cheats.EnableCheats == true && m->controller->buttonDown & L_TRIG ){
|
||||||
|
m->vel[1] = 25;
|
||||||
|
break; // TODO: Unneeded break?
|
||||||
|
}
|
||||||
|
/*End of moonjump cheat */
|
||||||
|
|
||||||
if (gCameraMovementFlags & CAM_MOVE_C_UP_MODE) {
|
if (gCameraMovementFlags & CAM_MOVE_C_UP_MODE) {
|
||||||
if (m->action & ACT_FLAG_ALLOW_FIRST_PERSON) {
|
if (m->action & ACT_FLAG_ALLOW_FIRST_PERSON) {
|
||||||
m->input |= INPUT_FIRST_PERSON;
|
m->input |= INPUT_FIRST_PERSON;
|
||||||
|
@ -1717,7 +1726,24 @@ void func_sh_8025574C(void) {
|
||||||
*/
|
*/
|
||||||
s32 execute_mario_action(UNUSED struct Object *o) {
|
s32 execute_mario_action(UNUSED struct Object *o) {
|
||||||
s32 inLoop = TRUE;
|
s32 inLoop = TRUE;
|
||||||
|
/**
|
||||||
|
* Cheat stuff
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (Cheats.EnableCheats)
|
||||||
|
{
|
||||||
|
if (Cheats.GodMode)
|
||||||
|
gMarioState->health = 0x880;
|
||||||
|
|
||||||
|
if (Cheats.InfiniteLives && gMarioState->numLives < 99)
|
||||||
|
gMarioState->numLives += 1;
|
||||||
|
|
||||||
|
if (Cheats.SuperSpeed && gMarioState->forwardVel > 0)
|
||||||
|
gMarioState->forwardVel += 100;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* End of cheat stuff
|
||||||
|
*/
|
||||||
if (gMarioState->action) {
|
if (gMarioState->action) {
|
||||||
gMarioState->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
gMarioState->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||||
mario_reset_bodystate(gMarioState);
|
mario_reset_bodystate(gMarioState);
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "behavior_data.h"
|
#include "behavior_data.h"
|
||||||
#include "thread6.h"
|
#include "thread6.h"
|
||||||
|
#include "pc/configfile.h"
|
||||||
|
#include "pc/cheats.h"
|
||||||
|
|
||||||
struct LandingAction {
|
struct LandingAction {
|
||||||
s16 numFrames;
|
s16 numFrames;
|
||||||
|
@ -461,8 +463,14 @@ void update_walking_speed(struct MarioState *m) {
|
||||||
m->forwardVel = 48.0f;
|
m->forwardVel = 48.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
m->faceAngle[1] =
|
/* Handles the "Super responsive controls" cheat. The content of the "else" is Mario's original code for turning around.*/
|
||||||
m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800);
|
|
||||||
|
if (Cheats.Responsive == true && Cheats.EnableCheats == true ) {
|
||||||
|
m->faceAngle[1] = m->intendedYaw;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m->faceAngle[1] = m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800);
|
||||||
|
}
|
||||||
apply_slope_accel(m);
|
apply_slope_accel(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "game/options_menu.h"
|
#include "game/options_menu.h"
|
||||||
#include "pc/pc_main.h"
|
#include "pc/pc_main.h"
|
||||||
#include "pc/cliopts.h"
|
#include "pc/cliopts.h"
|
||||||
|
#include "pc/cheats.h"
|
||||||
#include "pc/configfile.h"
|
#include "pc/configfile.h"
|
||||||
#include "pc/controller/controller_api.h"
|
#include "pc/controller/controller_api.h"
|
||||||
|
|
||||||
|
@ -50,6 +51,8 @@ static const u8 menuStr[][32] = {
|
||||||
{ TEXT_OPT_VIDEO },
|
{ TEXT_OPT_VIDEO },
|
||||||
{ TEXT_OPT_AUDIO },
|
{ TEXT_OPT_AUDIO },
|
||||||
{ TEXT_EXIT_GAME },
|
{ TEXT_EXIT_GAME },
|
||||||
|
{ TEXT_OPT_CHEATS },
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u8 optsCameraStr[][32] = {
|
static const u8 optsCameraStr[][32] = {
|
||||||
|
@ -69,12 +72,22 @@ static const u8 optsVideoStr[][32] = {
|
||||||
{ TEXT_OPT_TEXFILTER },
|
{ TEXT_OPT_TEXFILTER },
|
||||||
{ TEXT_OPT_NEAREST },
|
{ TEXT_OPT_NEAREST },
|
||||||
{ TEXT_OPT_LINEAR },
|
{ TEXT_OPT_LINEAR },
|
||||||
|
{ TEXT_RESET_WINDOW }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u8 optsAudioStr[][32] = {
|
static const u8 optsAudioStr[][32] = {
|
||||||
{ TEXT_OPT_MVOLUME },
|
{ TEXT_OPT_MVOLUME },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const u8 optsCheatsStr[][64] = {
|
||||||
|
{ TEXT_OPT_CHEAT1 },
|
||||||
|
{ TEXT_OPT_CHEAT2 },
|
||||||
|
{ TEXT_OPT_CHEAT3 },
|
||||||
|
{ TEXT_OPT_CHEAT4 },
|
||||||
|
{ TEXT_OPT_CHEAT5 },
|
||||||
|
{ TEXT_OPT_CHEAT6 },
|
||||||
|
};
|
||||||
|
|
||||||
static const u8 bindStr[][32] = {
|
static const u8 bindStr[][32] = {
|
||||||
{ TEXT_OPT_UNBOUND },
|
{ TEXT_OPT_UNBOUND },
|
||||||
{ TEXT_OPT_PRESSKEY },
|
{ TEXT_OPT_PRESSKEY },
|
||||||
|
@ -165,6 +178,10 @@ static void optmenu_act_exit(UNUSED struct Option *self, s32 arg) {
|
||||||
if (!arg) game_exit(); // only exit on A press and not directions
|
if (!arg) game_exit(); // only exit on A press and not directions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void optvide_reset_window(UNUSED struct Option *self, s32 arg) {
|
||||||
|
if (!arg) configWindow.reset = true;; // Restrict reset to A press and not directions
|
||||||
|
}
|
||||||
|
|
||||||
/* submenu option lists */
|
/* submenu option lists */
|
||||||
|
|
||||||
#ifdef BETTERCAMERA
|
#ifdef BETTERCAMERA
|
||||||
|
@ -199,14 +216,25 @@ static struct Option optsControls[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct Option optsVideo[] = {
|
static struct Option optsVideo[] = {
|
||||||
DEF_OPT_TOGGLE( optsVideoStr[0], &configFullscreen ),
|
DEF_OPT_TOGGLE( optsVideoStr[0], &configWindow.fullscreen ),
|
||||||
DEF_OPT_CHOICE( optsVideoStr[1], &configFiltering, filterChoices ),
|
DEF_OPT_CHOICE( optsVideoStr[1], &configFiltering, filterChoices ),
|
||||||
|
DEF_OPT_BUTTON( optsVideoStr[4], optvide_reset_window ),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct Option optsAudio[] = {
|
static struct Option optsAudio[] = {
|
||||||
DEF_OPT_SCROLL( optsAudioStr[0], &configMasterVolume, 0, MAX_VOLUME, 1 ),
|
DEF_OPT_SCROLL( optsAudioStr[0], &configMasterVolume, 0, MAX_VOLUME, 1 ),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct Option optsCheats[] = {
|
||||||
|
DEF_OPT_TOGGLE( optsCheatsStr[0], &Cheats.EnableCheats ),
|
||||||
|
DEF_OPT_TOGGLE( optsCheatsStr[1], &Cheats.MoonJump ),
|
||||||
|
DEF_OPT_TOGGLE( optsCheatsStr[2], &Cheats.GodMode ),
|
||||||
|
DEF_OPT_TOGGLE( optsCheatsStr[3], &Cheats.InfiniteLives ),
|
||||||
|
DEF_OPT_TOGGLE( optsCheatsStr[4], &Cheats.SuperSpeed),
|
||||||
|
DEF_OPT_TOGGLE( optsCheatsStr[5], &Cheats.Responsive),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/* submenu definitions */
|
/* submenu definitions */
|
||||||
|
|
||||||
#ifdef BETTERCAMERA
|
#ifdef BETTERCAMERA
|
||||||
|
@ -215,6 +243,7 @@ static struct SubMenu menuCamera = DEF_SUBMENU( menuStr[4], optsCamera );
|
||||||
static struct SubMenu menuControls = DEF_SUBMENU( menuStr[5], optsControls );
|
static struct SubMenu menuControls = DEF_SUBMENU( menuStr[5], optsControls );
|
||||||
static struct SubMenu menuVideo = DEF_SUBMENU( menuStr[6], optsVideo );
|
static struct SubMenu menuVideo = DEF_SUBMENU( menuStr[6], optsVideo );
|
||||||
static struct SubMenu menuAudio = DEF_SUBMENU( menuStr[7], optsAudio );
|
static struct SubMenu menuAudio = DEF_SUBMENU( menuStr[7], optsAudio );
|
||||||
|
static struct SubMenu menuCheats = DEF_SUBMENU( menuStr[9], optsCheats );
|
||||||
|
|
||||||
/* main options menu definition */
|
/* main options menu definition */
|
||||||
|
|
||||||
|
@ -226,6 +255,8 @@ static struct Option optsMain[] = {
|
||||||
DEF_OPT_SUBMENU( menuStr[6], &menuVideo ),
|
DEF_OPT_SUBMENU( menuStr[6], &menuVideo ),
|
||||||
DEF_OPT_SUBMENU( menuStr[7], &menuAudio ),
|
DEF_OPT_SUBMENU( menuStr[7], &menuAudio ),
|
||||||
DEF_OPT_BUTTON ( menuStr[8], optmenu_act_exit ),
|
DEF_OPT_BUTTON ( menuStr[8], optmenu_act_exit ),
|
||||||
|
DEF_OPT_SUBMENU( menuStr[9], &menuCheats ),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct SubMenu menuMain = DEF_SUBMENU( menuStr[3], optsMain );
|
static struct SubMenu menuMain = DEF_SUBMENU( menuStr[3], optsMain );
|
||||||
|
|
2
src/pc/cheats.c
Normal file
2
src/pc/cheats.c
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#include "cheats.h"
|
||||||
|
struct CheatList Cheats;
|
13
src/pc/cheats.h
Normal file
13
src/pc/cheats.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
struct CheatList
|
||||||
|
{
|
||||||
|
bool EnableCheats;
|
||||||
|
bool MoonJump;
|
||||||
|
bool GodMode;
|
||||||
|
bool InfiniteLives;
|
||||||
|
bool SuperSpeed;
|
||||||
|
bool Responsive;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct CheatList Cheats;
|
|
@ -13,6 +13,7 @@ void parse_cli_opts(int argc, char* argv[])
|
||||||
gCLIOpts.FullScreen = 0;
|
gCLIOpts.FullScreen = 0;
|
||||||
gCLIOpts.ConfigFile = malloc(31);
|
gCLIOpts.ConfigFile = malloc(31);
|
||||||
strncpy(gCLIOpts.ConfigFile, "sm64config.txt", strlen("sm64config.txt"));
|
strncpy(gCLIOpts.ConfigFile, "sm64config.txt", strlen("sm64config.txt"));
|
||||||
|
gCLIOpts.ConfigFile[strlen("sm64config.txt")] = '\0';
|
||||||
|
|
||||||
// Scan arguments for options
|
// Scan arguments for options
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
|
@ -48,6 +49,7 @@ void parse_cli_opts(int argc, char* argv[])
|
||||||
} else {
|
} else {
|
||||||
memset(gCLIOpts.ConfigFile, 0, 30);
|
memset(gCLIOpts.ConfigFile, 0, 30);
|
||||||
strncpy(gCLIOpts.ConfigFile, argv[i+1], strlen(argv[i+1]));
|
strncpy(gCLIOpts.ConfigFile, argv[i+1], strlen(argv[i+1]));
|
||||||
|
gCLIOpts.ConfigFile[strlen(argv[i+1])] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,10 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#include "configfile.h"
|
#include "configfile.h"
|
||||||
|
#include "gfx/gfx_screen_config.h"
|
||||||
#include "controller/controller_api.h"
|
#include "controller/controller_api.h"
|
||||||
|
|
||||||
#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0]))
|
#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
|
@ -33,7 +35,16 @@ struct ConfigOption {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Video/audio stuff
|
// Video/audio stuff
|
||||||
bool configFullscreen = false;
|
ConfigWindow configWindow = {
|
||||||
|
.x = SDL_WINDOWPOS_CENTERED,
|
||||||
|
.y = SDL_WINDOWPOS_CENTERED,
|
||||||
|
.w = DESIRED_SCREEN_WIDTH,
|
||||||
|
.h = DESIRED_SCREEN_HEIGHT,
|
||||||
|
.reset = false,
|
||||||
|
.vsync = false,
|
||||||
|
.fullscreen = false,
|
||||||
|
.exiting_fullscreen = false,
|
||||||
|
};
|
||||||
unsigned int configFiltering = 1; // 0=force nearest, 1=linear, (TODO) 2=three-point
|
unsigned int configFiltering = 1; // 0=force nearest, 1=linear, (TODO) 2=three-point
|
||||||
unsigned int configMasterVolume = MAX_VOLUME; // 0 - MAX_VOLUME
|
unsigned int configMasterVolume = MAX_VOLUME; // 0 - MAX_VOLUME
|
||||||
|
|
||||||
|
@ -68,7 +79,11 @@ bool configCameraMouse = false;
|
||||||
unsigned int configSkipIntro = 0;
|
unsigned int configSkipIntro = 0;
|
||||||
|
|
||||||
static const struct ConfigOption options[] = {
|
static const struct ConfigOption options[] = {
|
||||||
{.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configFullscreen},
|
{.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configWindow.fullscreen},
|
||||||
|
{.name = "window_x", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.x},
|
||||||
|
{.name = "window_y", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.y},
|
||||||
|
{.name = "window_w", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.w},
|
||||||
|
{.name = "window_h", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.h},
|
||||||
{.name = "texture_filtering", .type = CONFIG_TYPE_UINT, .uintValue = &configFiltering},
|
{.name = "texture_filtering", .type = CONFIG_TYPE_UINT, .uintValue = &configFiltering},
|
||||||
{.name = "master_volume", .type = CONFIG_TYPE_UINT, .uintValue = &configMasterVolume},
|
{.name = "master_volume", .type = CONFIG_TYPE_UINT, .uintValue = &configMasterVolume},
|
||||||
{.name = "key_a", .type = CONFIG_TYPE_BIND, .uintValue = configKeyA},
|
{.name = "key_a", .type = CONFIG_TYPE_BIND, .uintValue = configKeyA},
|
||||||
|
|
|
@ -7,7 +7,15 @@
|
||||||
#define MAX_VOLUME 127
|
#define MAX_VOLUME 127
|
||||||
#define VOLUME_SHIFT 7
|
#define VOLUME_SHIFT 7
|
||||||
|
|
||||||
extern bool configFullscreen;
|
typedef struct {
|
||||||
|
unsigned int x, y, w, h;
|
||||||
|
bool reset;
|
||||||
|
bool vsync;
|
||||||
|
bool fullscreen;
|
||||||
|
bool exiting_fullscreen;
|
||||||
|
} ConfigWindow;
|
||||||
|
|
||||||
|
extern ConfigWindow configWindow;
|
||||||
extern unsigned int configFiltering;
|
extern unsigned int configFiltering;
|
||||||
extern unsigned int configMasterVolume;
|
extern unsigned int configMasterVolume;
|
||||||
extern unsigned int configKeyA[];
|
extern unsigned int configKeyA[];
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include "controller_sdl.h"
|
#include "controller_sdl.h"
|
||||||
#include "../configfile.h"
|
#include "../configfile.h"
|
||||||
|
|
||||||
|
#include "game/level_update.h"
|
||||||
|
|
||||||
// mouse buttons are also in the controller namespace (why), just offset 0x100
|
// mouse buttons are also in the controller namespace (why), just offset 0x100
|
||||||
#define VK_OFS_SDL_MOUSE 0x0100
|
#define VK_OFS_SDL_MOUSE 0x0100
|
||||||
#define VK_BASE_SDL_MOUSE (VK_BASE_SDL_GAMEPAD + VK_OFS_SDL_MOUSE)
|
#define VK_BASE_SDL_MOUSE (VK_BASE_SDL_GAMEPAD + VK_OFS_SDL_MOUSE)
|
||||||
|
@ -101,7 +103,7 @@ static void controller_sdl_read(OSContPad *pad) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BETTERCAMERA
|
#ifdef BETTERCAMERA
|
||||||
if (newcam_mouse == 1)
|
if (newcam_mouse == 1 && sCurrPlayMode != 2)
|
||||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||||
else
|
else
|
||||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||||
|
|
|
@ -285,6 +285,12 @@ static bool gfx_texture_cache_lookup(int tile, struct TextureHashmapNode **n, co
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void import_texture_rgba32(int tile) {
|
||||||
|
uint32_t width = rdp.texture_tile.line_size_bytes / 2;
|
||||||
|
uint32_t height = (rdp.loaded_texture[tile].size_bytes / 2) / rdp.texture_tile.line_size_bytes;
|
||||||
|
gfx_rapi->upload_texture(rdp.loaded_texture[tile].addr, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
static void import_texture_rgba16(int tile) {
|
static void import_texture_rgba16(int tile) {
|
||||||
uint8_t rgba32_buf[8192];
|
uint8_t rgba32_buf[8192];
|
||||||
|
|
||||||
|
@ -371,6 +377,41 @@ static void import_texture_ia16(int tile) {
|
||||||
gfx_rapi->upload_texture(rgba32_buf, width, height);
|
gfx_rapi->upload_texture(rgba32_buf, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void import_texture_i4(int tile) {
|
||||||
|
uint8_t rgba32_buf[32768];
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes * 2; i++) {
|
||||||
|
uint8_t byte = rdp.loaded_texture[tile].addr[i / 2];
|
||||||
|
uint8_t intensity = (byte >> (4 - (i % 2) * 4)) & 0xf;
|
||||||
|
rgba32_buf[4*i + 0] = SCALE_4_8(intensity);
|
||||||
|
rgba32_buf[4*i + 1] = SCALE_4_8(intensity);
|
||||||
|
rgba32_buf[4*i + 2] = SCALE_4_8(intensity);
|
||||||
|
rgba32_buf[4*i + 3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t width = rdp.texture_tile.line_size_bytes * 2;
|
||||||
|
uint32_t height = rdp.loaded_texture[tile].size_bytes / rdp.texture_tile.line_size_bytes;
|
||||||
|
|
||||||
|
gfx_rapi->upload_texture(rgba32_buf, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void import_texture_i8(int tile) {
|
||||||
|
uint8_t rgba32_buf[16384];
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes; i++) {
|
||||||
|
uint8_t intensity = rdp.loaded_texture[tile].addr[i];
|
||||||
|
rgba32_buf[4*i + 0] = intensity;
|
||||||
|
rgba32_buf[4*i + 1] = intensity;
|
||||||
|
rgba32_buf[4*i + 2] = intensity;
|
||||||
|
rgba32_buf[4*i + 3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t width = rdp.texture_tile.line_size_bytes;
|
||||||
|
uint32_t height = rdp.loaded_texture[tile].size_bytes / rdp.texture_tile.line_size_bytes;
|
||||||
|
|
||||||
|
gfx_rapi->upload_texture(rgba32_buf, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
static void import_texture_ci4(int tile) {
|
static void import_texture_ci4(int tile) {
|
||||||
uint8_t rgba32_buf[32768];
|
uint8_t rgba32_buf[32768];
|
||||||
|
|
||||||
|
@ -426,7 +467,10 @@ static void import_texture(int tile) {
|
||||||
|
|
||||||
int t0 = get_time();
|
int t0 = get_time();
|
||||||
if (fmt == G_IM_FMT_RGBA) {
|
if (fmt == G_IM_FMT_RGBA) {
|
||||||
if (siz == G_IM_SIZ_16b) {
|
if (siz == G_IM_SIZ_32b) {
|
||||||
|
import_texture_rgba32(tile);
|
||||||
|
}
|
||||||
|
else if (siz == G_IM_SIZ_16b) {
|
||||||
import_texture_rgba16(tile);
|
import_texture_rgba16(tile);
|
||||||
} else {
|
} else {
|
||||||
abort();
|
abort();
|
||||||
|
@ -449,6 +493,14 @@ static void import_texture(int tile) {
|
||||||
} else {
|
} else {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
} else if (fmt == G_IM_FMT_I) {
|
||||||
|
if (siz == G_IM_SIZ_4b) {
|
||||||
|
import_texture_i4(tile);
|
||||||
|
} else if (siz == G_IM_SIZ_8b) {
|
||||||
|
import_texture_i8(tile);
|
||||||
|
} else {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
@ -976,7 +1028,6 @@ static void gfx_dp_set_texture_image(uint32_t format, uint32_t size, uint32_t wi
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t tmem, uint8_t tile, uint32_t palette, uint32_t cmt, uint32_t maskt, uint32_t shiftt, uint32_t cms, uint32_t masks, uint32_t shifts) {
|
static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t tmem, uint8_t tile, uint32_t palette, uint32_t cmt, uint32_t maskt, uint32_t shiftt, uint32_t cms, uint32_t masks, uint32_t shifts) {
|
||||||
SUPPORT_CHECK(siz != G_IM_SIZ_32b);
|
|
||||||
|
|
||||||
if (tile == G_TX_RENDERTILE) {
|
if (tile == G_TX_RENDERTILE) {
|
||||||
SUPPORT_CHECK(palette == 0); // palette should set upper 4 bits of color index in 4b mode
|
SUPPORT_CHECK(palette == 0); // palette should set upper 4 bits of color index in 4b mode
|
||||||
|
@ -1035,12 +1086,45 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t
|
||||||
}
|
}
|
||||||
uint32_t size_bytes = (lrs + 1) << word_size_shift;
|
uint32_t size_bytes = (lrs + 1) << word_size_shift;
|
||||||
rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes;
|
rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes;
|
||||||
assert(size_bytes <= 4096 && "bug: too big texture");
|
|
||||||
rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr;
|
rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr;
|
||||||
|
|
||||||
rdp.textures_changed[rdp.texture_to_load.tile_number] = true;
|
rdp.textures_changed[rdp.texture_to_load.tile_number] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, uint32_t lrt) {
|
||||||
|
if (tile == 1) return;
|
||||||
|
SUPPORT_CHECK(tile == G_TX_LOADTILE);
|
||||||
|
SUPPORT_CHECK(uls == 0);
|
||||||
|
SUPPORT_CHECK(ult == 0);
|
||||||
|
|
||||||
|
uint32_t word_size_shift;
|
||||||
|
switch (rdp.texture_to_load.siz) {
|
||||||
|
case G_IM_SIZ_4b:
|
||||||
|
word_size_shift = 0; // Or -1? It's unused in SM64 anyway.
|
||||||
|
break;
|
||||||
|
case G_IM_SIZ_8b:
|
||||||
|
word_size_shift = 0;
|
||||||
|
break;
|
||||||
|
case G_IM_SIZ_16b:
|
||||||
|
word_size_shift = 1;
|
||||||
|
break;
|
||||||
|
case G_IM_SIZ_32b:
|
||||||
|
word_size_shift = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t size_bytes = (((lrs >> G_TEXTURE_IMAGE_FRAC) + 1) * ((lrt >> G_TEXTURE_IMAGE_FRAC) + 1)) << word_size_shift;
|
||||||
|
rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes;
|
||||||
|
|
||||||
|
rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr;
|
||||||
|
rdp.texture_tile.uls = uls;
|
||||||
|
rdp.texture_tile.ult = ult;
|
||||||
|
rdp.texture_tile.lrs = lrs;
|
||||||
|
rdp.texture_tile.lrt = lrt;
|
||||||
|
|
||||||
|
rdp.textures_changed[rdp.texture_to_load.tile_number] = true;
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t color_comb_component(uint32_t v) {
|
static uint8_t color_comb_component(uint32_t v) {
|
||||||
switch (v) {
|
switch (v) {
|
||||||
case G_CCMUX_TEXEL0:
|
case G_CCMUX_TEXEL0:
|
||||||
|
@ -1384,6 +1468,9 @@ static void gfx_run_dl(Gfx* cmd) {
|
||||||
case G_LOADBLOCK:
|
case G_LOADBLOCK:
|
||||||
gfx_dp_load_block(C1(24, 3), C0(12, 12), C0(0, 12), C1(12, 12), C1(0, 12));
|
gfx_dp_load_block(C1(24, 3), C0(12, 12), C0(0, 12), C1(12, 12), C1(0, 12));
|
||||||
break;
|
break;
|
||||||
|
case G_LOADTILE:
|
||||||
|
gfx_dp_load_tile(C1(24, 3), C0(12, 12), C0(0, 12), C1(12, 12), C1(0, 12));
|
||||||
|
break;
|
||||||
case G_SETTILE:
|
case G_SETTILE:
|
||||||
gfx_dp_set_tile(C0(21, 3), C0(19, 2), C0(9, 9), C0(0, 9), C1(24, 3), C1(20, 4), C1(18, 2), C1(14, 4), C1(10, 4), C1(8, 2), C1(4, 4), C1(0, 4));
|
gfx_dp_set_tile(C0(21, 3), C0(19, 2), C0(9, 9), C0(0, 9), C1(24, 3), C1(20, 4), C1(18, 2), C1(14, 4), C1(10, 4), C1(8, 2), C1(4, 4), C1(0, 4));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
#endif // End of OS-Specific GL defines
|
#endif // End of OS-Specific GL defines
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "gfx_window_manager_api.h"
|
#include "gfx_window_manager_api.h"
|
||||||
#include "gfx_screen_config.h"
|
#include "gfx_screen_config.h"
|
||||||
#include "../pc_main.h"
|
#include "../pc_main.h"
|
||||||
|
@ -41,10 +43,6 @@ static SDL_Window *wnd;
|
||||||
static SDL_GLContext ctx = NULL;
|
static SDL_GLContext ctx = NULL;
|
||||||
static int inverted_scancode_table[512];
|
static int inverted_scancode_table[512];
|
||||||
|
|
||||||
static bool window_fullscreen;
|
|
||||||
static bool window_vsync;
|
|
||||||
static int window_width, window_height;
|
|
||||||
|
|
||||||
const SDL_Scancode windows_scancode_table[] =
|
const SDL_Scancode windows_scancode_table[] =
|
||||||
{
|
{
|
||||||
/* 0 1 2 3 4 5 6 7 */
|
/* 0 1 2 3 4 5 6 7 */
|
||||||
|
@ -96,22 +94,40 @@ const SDL_Scancode scancode_rmapping_nonextended[][2] = {
|
||||||
{SDL_SCANCODE_KP_MULTIPLY, SDL_SCANCODE_PRINTSCREEN}
|
{SDL_SCANCODE_KP_MULTIPLY, SDL_SCANCODE_PRINTSCREEN}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void gfx_sdl_set_fullscreen(bool fullscreen) {
|
#define IS_FULLSCREEN (SDL_GetWindowFlags(wnd) & SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||||
if (fullscreen == window_fullscreen) return;
|
|
||||||
|
|
||||||
if (fullscreen) {
|
static void gfx_sdl_set_fullscreen() {
|
||||||
|
if (configWindow.fullscreen == IS_FULLSCREEN)
|
||||||
|
return;
|
||||||
|
if (configWindow.fullscreen) {
|
||||||
SDL_SetWindowFullscreen(wnd, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
SDL_SetWindowFullscreen(wnd, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||||
SDL_ShowCursor(SDL_DISABLE);
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
} else {
|
} else {
|
||||||
SDL_SetWindowFullscreen(wnd, 0);
|
SDL_SetWindowFullscreen(wnd, 0);
|
||||||
SDL_ShowCursor(SDL_ENABLE);
|
SDL_ShowCursor(SDL_ENABLE);
|
||||||
// reset back to small window just in case
|
configWindow.exiting_fullscreen = true;
|
||||||
window_width = DESIRED_SCREEN_WIDTH;
|
|
||||||
window_height = DESIRED_SCREEN_HEIGHT;
|
|
||||||
SDL_SetWindowSize(wnd, window_width, window_height);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
window_fullscreen = fullscreen;
|
static void gfx_sdl_reset_dimension_and_pos() {
|
||||||
|
if (configWindow.exiting_fullscreen)
|
||||||
|
configWindow.exiting_fullscreen = false;
|
||||||
|
else if (configWindow.reset) {
|
||||||
|
configWindow.x = SDL_WINDOWPOS_CENTERED;
|
||||||
|
configWindow.y = SDL_WINDOWPOS_CENTERED;
|
||||||
|
configWindow.w = DESIRED_SCREEN_WIDTH;
|
||||||
|
configWindow.h = DESIRED_SCREEN_HEIGHT;
|
||||||
|
configWindow.reset = false;
|
||||||
|
|
||||||
|
if (IS_FULLSCREEN) {
|
||||||
|
configWindow.fullscreen = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return;
|
||||||
|
|
||||||
|
SDL_SetWindowSize(wnd, configWindow.w, configWindow.h);
|
||||||
|
SDL_SetWindowPosition(wnd, configWindow.x, configWindow.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool test_vsync(void) {
|
static bool test_vsync(void) {
|
||||||
|
@ -147,8 +163,12 @@ static void gfx_sdl_init(void) {
|
||||||
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||||
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
|
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
|
||||||
|
|
||||||
if (gCLIOpts.FullScreen)
|
if (gCLIOpts.FullScreen == 1)
|
||||||
configFullscreen = true;
|
configWindow.fullscreen = true;
|
||||||
|
|
||||||
|
if (gCLIOpts.FullScreen == 2)
|
||||||
|
configWindow.fullscreen = false;
|
||||||
|
|
||||||
|
|
||||||
const char* window_title =
|
const char* window_title =
|
||||||
#ifndef USE_GLES
|
#ifndef USE_GLES
|
||||||
|
@ -157,28 +177,18 @@ static void gfx_sdl_init(void) {
|
||||||
"Super Mario 64 PC port (OpenGL_ES2)";
|
"Super Mario 64 PC port (OpenGL_ES2)";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
|
wnd = SDL_CreateWindow(
|
||||||
|
window_title,
|
||||||
window_fullscreen = configFullscreen;
|
configWindow.x, configWindow.y, configWindow.w, configWindow.h,
|
||||||
|
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
|
||||||
if (configFullscreen) {
|
);
|
||||||
window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
|
||||||
SDL_ShowCursor(SDL_DISABLE);
|
|
||||||
} else {
|
|
||||||
SDL_ShowCursor(SDL_ENABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
wnd = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
|
||||||
DESIRED_SCREEN_WIDTH, DESIRED_SCREEN_HEIGHT, window_flags);
|
|
||||||
|
|
||||||
ctx = SDL_GL_CreateContext(wnd);
|
ctx = SDL_GL_CreateContext(wnd);
|
||||||
SDL_GL_SetSwapInterval(2);
|
SDL_GL_SetSwapInterval(2);
|
||||||
|
|
||||||
// in case FULLSCREEN_DESKTOP set our size to god knows what
|
gfx_sdl_set_fullscreen();
|
||||||
SDL_GetWindowSize(wnd, &window_width, &window_height);
|
|
||||||
|
|
||||||
window_vsync = test_vsync();
|
configWindow.vsync = test_vsync();
|
||||||
if (!window_vsync)
|
if (!configWindow.vsync)
|
||||||
printf("Warning: VSync is not enabled or not working. Falling back to timer for synchronization\n");
|
printf("Warning: VSync is not enabled or not working. Falling back to timer for synchronization\n");
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDL_Scancode); i++) {
|
for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDL_Scancode); i++) {
|
||||||
|
@ -201,8 +211,7 @@ static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) {
|
static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) {
|
||||||
*width = window_width;
|
SDL_GetWindowSize(wnd, width, height);
|
||||||
*height = window_height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int translate_scancode(int scancode) {
|
static int translate_scancode(int scancode) {
|
||||||
|
@ -219,9 +228,9 @@ static void gfx_sdl_onkeydown(int scancode) {
|
||||||
const Uint8 *state = SDL_GetKeyboardState(NULL);
|
const Uint8 *state = SDL_GetKeyboardState(NULL);
|
||||||
|
|
||||||
if (state[SDL_SCANCODE_LALT] && state[SDL_SCANCODE_RETURN])
|
if (state[SDL_SCANCODE_LALT] && state[SDL_SCANCODE_RETURN])
|
||||||
configFullscreen = !configFullscreen;
|
configWindow.fullscreen = !configWindow.fullscreen;
|
||||||
else if (state[SDL_SCANCODE_ESCAPE] && configFullscreen)
|
else if (state[SDL_SCANCODE_ESCAPE] && configWindow.fullscreen)
|
||||||
configFullscreen = false;
|
configWindow.fullscreen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_sdl_onkeyup(int scancode) {
|
static void gfx_sdl_onkeyup(int scancode) {
|
||||||
|
@ -241,10 +250,18 @@ static void gfx_sdl_handle_events(void) {
|
||||||
gfx_sdl_onkeyup(event.key.keysym.scancode);
|
gfx_sdl_onkeyup(event.key.keysym.scancode);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT: // TODO: Check if this makes sense to be included in the Web build
|
||||||
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
if (!(IS_FULLSCREEN || configWindow.exiting_fullscreen)) {
|
||||||
window_width = event.window.data1;
|
switch (event.window.event) {
|
||||||
window_height = event.window.data2;
|
case SDL_WINDOWEVENT_MOVED:
|
||||||
|
configWindow.x = event.window.data1;
|
||||||
|
configWindow.y = event.window.data2;
|
||||||
|
break;
|
||||||
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||||
|
configWindow.w = event.window.data1;
|
||||||
|
configWindow.h = event.window.data2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
|
@ -252,9 +269,9 @@ static void gfx_sdl_handle_events(void) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// just check if the fullscreen value has changed and toggle fullscreen if it has
|
|
||||||
if (configFullscreen != window_fullscreen)
|
gfx_sdl_reset_dimension_and_pos();
|
||||||
gfx_sdl_set_fullscreen(configFullscreen);
|
gfx_sdl_set_fullscreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool gfx_sdl_start_frame(void) {
|
static bool gfx_sdl_start_frame(void) {
|
||||||
|
@ -274,7 +291,7 @@ static void sync_framerate_with_timer(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_sdl_swap_buffers_begin(void) {
|
static void gfx_sdl_swap_buffers_begin(void) {
|
||||||
if (!window_vsync)
|
if (!configWindow.vsync)
|
||||||
sync_framerate_with_timer();
|
sync_framerate_with_timer();
|
||||||
SDL_GL_SwapWindow(wnd);
|
SDL_GL_SwapWindow(wnd);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue