mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 05:25:14 +00:00
Merge branch 'master' into osx_build_clean
This commit is contained in:
commit
54f986a528
58 changed files with 343 additions and 837 deletions
11
Makefile
11
Makefile
|
@ -1,3 +1,4 @@
|
|||
|
||||
# Makefile to rebuild SM64 split image
|
||||
|
||||
### Default target ###
|
||||
|
@ -251,8 +252,8 @@ ifeq ($(TARGET_WEB),1)
|
|||
endif
|
||||
|
||||
# Use a default opt flag for gcc, then override if RPi
|
||||
# OPT_FLAGS := -O2 # -O2 opt breaks sound on x86?
|
||||
|
||||
# OPT_FLAGS := -O2 # "Whole-compile optimization flag" Breaks sound on x86.
|
||||
|
||||
ifeq ($(TARGET_RPI),1)
|
||||
machine = $(shell sh -c 'uname -m 2>/dev/null || echo unknown')
|
||||
|
@ -427,7 +428,13 @@ else
|
|||
endif
|
||||
|
||||
ifeq ($(WINDOWS_BUILD),1)
|
||||
LD := $(CXX)
|
||||
ifeq ($(CROSS),i686-w64-mingw32.static-) # fixes compilation in MXE on Linux and WSL
|
||||
LD := $(CC)
|
||||
else ifeq ($(CROSS),x86_64-w64-mingw32.static-)
|
||||
LD := $(CC)
|
||||
else
|
||||
LD := $(CXX)
|
||||
endif
|
||||
else
|
||||
LD := $(CC)
|
||||
endif
|
||||
|
|
|
@ -4,6 +4,9 @@ OpenGL adaptation of [n64decomp/sm64](https://github.com/n64decomp/sm64).
|
|||
Feel free to report bugs and contribute, but remember, there must be **no upload of any copyrighted asset**.
|
||||
Run `./extract_assets.py --clean && make clean` or `make distclean` to remove ROM-originated content. This port has been made possible mostly thanks to [Emill](https://github.com/Emill) and his [n64-fast32-engine](https://github.com/Emill/n64-fast3d-engine/) renderer.
|
||||
|
||||
|
||||
Please contribute **first** to the [nightly branch](https://github.com/sm64pc/sm64pc/tree/nightly/). New functionality will be merged to master once they're considered to be well-tested.
|
||||
|
||||
*Read this in other languages: [Español](README_es_ES.md) [简体中文](README_zh_CN.md).*
|
||||
|
||||
## Features
|
||||
|
|
|
@ -2499,41 +2499,23 @@ static const Lights1 segment2_lights_unused = gdSPDefLights1(
|
|||
|
||||
// 0x02014470 - 0x020144B0
|
||||
static const Mtx matrix_identity = {
|
||||
#ifdef TARGET_N64
|
||||
{{0x00010000, 0x00000000,
|
||||
0x00000001, 0x00000000},
|
||||
{0x00000000, 0x00010000,
|
||||
0x00000000, 0x00000001},
|
||||
{0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000},
|
||||
{0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000}}
|
||||
#else
|
||||
|
||||
{{1.0f, 0.0f, 0.0f, 0.0f},
|
||||
{0.0f, 1.0f, 0.0f, 0.0f},
|
||||
{0.0f, 0.0f, 1.0f, 0.0f},
|
||||
{0.0f, 0.0f, 0.0f, 1.0f}}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
// 0x020144B0 - 0x020144F0
|
||||
static const Mtx matrix_fullscreen = {
|
||||
#if TARGET_N64
|
||||
{{0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000},
|
||||
{0x00000000, 0xffff0000,
|
||||
0xffffffff, 0xffff0001},
|
||||
{((65536 * 2 / SCREEN_WIDTH) << 16) | 0, 0x00000000,
|
||||
(0 << 16) | (65536 * 2 / SCREEN_HEIGHT), 0x00000000},
|
||||
{0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000}}
|
||||
#else
|
||||
|
||||
{{2.0f / SCREEN_WIDTH, 0.0f, 0.0f, 0.0f},
|
||||
{0.0f, 2.0f / SCREEN_HEIGHT, 0.0f, 0.0f},
|
||||
{0.0f, 0.0f, -1.0f, 0.0f},
|
||||
{-1.0f, -1.0f, -1.0f, 1.0f}}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1109,11 +1109,7 @@
|
|||
* Vertex (set up for use with colors)
|
||||
*/
|
||||
typedef struct {
|
||||
#ifdef TARGET_N64
|
||||
short ob[3]; /* x, y, z */
|
||||
#else
|
||||
float ob[3]; /* x, y, z */
|
||||
#endif
|
||||
unsigned short flag;
|
||||
short tc[2]; /* texture coord */
|
||||
unsigned char cn[4]; /* color & alpha */
|
||||
|
@ -1123,11 +1119,7 @@ typedef struct {
|
|||
* Vertex (set up for use with normals)
|
||||
*/
|
||||
typedef struct {
|
||||
#ifdef TARGET_N64
|
||||
short ob[3]; /* x, y, z */
|
||||
#else
|
||||
float ob[3]; /* x, y, z */
|
||||
#endif
|
||||
unsigned short flag;
|
||||
short tc[2]; /* texture coord */
|
||||
signed char n[3]; /* normal */
|
||||
|
@ -1176,23 +1168,9 @@ typedef struct {
|
|||
unsigned char v[3];
|
||||
} Tri;
|
||||
|
||||
#ifdef TARGET_N64
|
||||
/*
|
||||
* 4x4 matrix, fixed point s15.16 format.
|
||||
* First 8 words are integer portion of the 4x4 matrix
|
||||
* Last 8 words are the fraction portion of the 4x4 matrix
|
||||
*/
|
||||
typedef s32 Mtx_t[4][4];
|
||||
|
||||
typedef union {
|
||||
Mtx_t m;
|
||||
long long int force_structure_alignment;
|
||||
} Mtx;
|
||||
#else
|
||||
typedef struct {
|
||||
float m[4][4];
|
||||
} Mtx;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Viewport
|
||||
|
|
|
@ -3,13 +3,28 @@
|
|||
|
||||
#include "ultratypes.h"
|
||||
|
||||
#ifdef OSX_BUILD
|
||||
#include <strings.h> // OSX doesn't like it not being included?
|
||||
// old bstring functions that aren't present on some platforms
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
// macOS libc has them
|
||||
#include <strings.h>
|
||||
|
||||
#elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L)
|
||||
|
||||
// there's no way that shit's defined, use memcpy/memset
|
||||
#include <string.h>
|
||||
#undef bzero
|
||||
#undef bcopy
|
||||
#define bzero(buf, len) memset((buf), 0, (len))
|
||||
#define bcopy(src, dst, len) memcpy((dst), (src), (len))
|
||||
|
||||
#else
|
||||
|
||||
// Old deprecated functions from strings.h, replaced by memcpy/memset.
|
||||
// hope for the best
|
||||
extern void bcopy(const void *, void *, size_t);
|
||||
extern void bzero(void *, size_t);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* !_OS_LIBC_H_ */
|
||||
|
|
|
@ -29,16 +29,9 @@ typedef volatile s64 vs64;
|
|||
typedef float f32;
|
||||
typedef double f64;
|
||||
|
||||
#ifdef TARGET_N64
|
||||
typedef u32 size_t;
|
||||
typedef s32 ssize_t;
|
||||
typedef u32 uintptr_t;
|
||||
typedef s32 intptr_t;
|
||||
typedef s32 ptrdiff_t;
|
||||
#else
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
typedef ptrdiff_t ssize_t;
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#ifndef CONFIG_H
|
||||
|
||||
#define CONFIG_H
|
||||
|
||||
/**
|
||||
|
@ -27,16 +28,7 @@
|
|||
#define SCREEN_WIDTH 320
|
||||
#define SCREEN_HEIGHT 240
|
||||
|
||||
// Border Height Define for NTSC Versions
|
||||
#ifdef TARGET_N64
|
||||
#ifndef VERSION_EU
|
||||
#define BORDER_HEIGHT 8
|
||||
#else
|
||||
#define BORDER_HEIGHT 1
|
||||
#endif
|
||||
#else
|
||||
// What's the point of having a border?
|
||||
#define BORDER_HEIGHT 0
|
||||
#endif
|
||||
// What's the point of having a border if we're not an N64?
|
||||
#define BORDER_HEIGHT 0 // Never use a border as not-N64
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef GFX_DIMENSIONS_H
|
||||
#define GFX_DIMENSIONS_H
|
||||
|
||||
#ifndef TARGET_N64
|
||||
#include <math.h>
|
||||
#include "pc/gfx/gfx_pc.h"
|
||||
#define GFX_DIMENSIONS_FROM_LEFT_EDGE(v) (SCREEN_WIDTH / 2 - SCREEN_HEIGHT / 2 * gfx_current_dimensions.aspect_ratio + (v))
|
||||
|
@ -9,12 +8,5 @@
|
|||
#define GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(v) ((int)floorf(GFX_DIMENSIONS_FROM_LEFT_EDGE(v)))
|
||||
#define GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(v) ((int)ceilf(GFX_DIMENSIONS_FROM_RIGHT_EDGE(v)))
|
||||
#define GFX_DIMENSIONS_ASPECT_RATIO (gfx_current_dimensions.aspect_ratio)
|
||||
#else
|
||||
#define GFX_DIMENSIONS_FROM_LEFT_EDGE(v) (v)
|
||||
#define GFX_DIMENSIONS_FROM_RIGHT_EDGE(v) (SCREEN_WIDTH - (v))
|
||||
#define GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(v) (v)
|
||||
#define GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(v) (SCREEN_WIDTH - (v))
|
||||
#define GFX_DIMENSIONS_ASPECT_RATIO (4.0f / 3.0f)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -46,20 +46,9 @@
|
|||
#define ALIGNED16
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_N64
|
||||
// convert a virtual address to physical.
|
||||
#define VIRTUAL_TO_PHYSICAL(addr) ((uintptr_t)(addr) & 0x1FFFFFFF)
|
||||
|
||||
// convert a physical address to virtual.
|
||||
#define PHYSICAL_TO_VIRTUAL(addr) ((uintptr_t)(addr) | 0x80000000)
|
||||
|
||||
// another way of converting virtual to physical
|
||||
#define VIRTUAL_TO_PHYSICAL2(addr) ((u8 *)(addr) - 0x80000000U)
|
||||
#else
|
||||
// no conversion for pc port other than cast
|
||||
#define VIRTUAL_TO_PHYSICAL(addr) ((uintptr_t)(addr))
|
||||
#define PHYSICAL_TO_VIRTUAL(addr) ((uintptr_t)(addr))
|
||||
#define VIRTUAL_TO_PHYSICAL2(addr) ((void *)(addr))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,11 +1,4 @@
|
|||
#ifndef MAKE_CONST_NONCONST_H
|
||||
#define MAKE_CONST_NONCONST_H
|
||||
|
||||
#ifdef TARGET_N64
|
||||
// IDO sometimes puts const variables in .rodata and sometimes in .data, which breaks ordering.
|
||||
// This makes sure all variables are put into the same section (.data). We need to do this for
|
||||
// both IDO and gcc for TARGET_N64.
|
||||
#define const
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
#ifndef PLATFORM_INFO_H
|
||||
#define PLATFORM_INFO_H
|
||||
|
||||
#ifdef TARGET_N64
|
||||
#define IS_64_BIT 0
|
||||
#define IS_BIG_ENDIAN 1
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#define IS_64_BIT (UINTPTR_MAX == 0xFFFFFFFFFFFFFFFFU)
|
||||
#define IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
#endif
|
||||
|
||||
#define DOUBLE_SIZE_ON_64_BIT(size) ((size) * (sizeof(void *) / 4))
|
||||
|
||||
|
|
|
@ -1,15 +1,9 @@
|
|||
#ifndef SEGMENT_SYMBOLS_H
|
||||
#define SEGMENT_SYMBOLS_H
|
||||
|
||||
#ifdef TARGET_N64
|
||||
#define DECLARE_SEGMENT(name) \
|
||||
extern u8 _##name##SegmentRomStart[]; \
|
||||
extern u8 _##name##SegmentRomEnd[];
|
||||
#else
|
||||
#define DECLARE_SEGMENT(name) \
|
||||
static u8 _##name##SegmentRomStart[1]; \
|
||||
static u8 _##name##SegmentRomEnd[1];
|
||||
#endif
|
||||
|
||||
#define DECLARE_ACTOR_SEGMENT(name) \
|
||||
DECLARE_SEGMENT(name##_mio0) \
|
||||
|
@ -43,11 +37,7 @@ DECLARE_ACTOR_SEGMENT(group17)
|
|||
DECLARE_SEGMENT(behavior)
|
||||
DECLARE_SEGMENT(scripts)
|
||||
DECLARE_SEGMENT(goddard)
|
||||
#ifdef TARGET_N64
|
||||
extern u8 _goddardSegmentStart[];
|
||||
#else
|
||||
static u8 _goddardSegmentStart[1];
|
||||
#endif
|
||||
|
||||
DECLARE_LEVEL_SEGMENT(menu)
|
||||
DECLARE_LEVEL_SEGMENT(intro)
|
||||
|
|
|
@ -72,19 +72,16 @@ const LevelScript level_main_menu_entry_2[] = {
|
|||
|
||||
/*25*/ FREE_LEVEL_POOL(),
|
||||
/*26*/ LOAD_AREA(/*area*/ 2),
|
||||
#ifndef TARGET_N64
|
||||
|
||||
// sVisibleStars is set to 0 during FIXED_LOAD above on N64, but not on PC-port.
|
||||
// lvl_init_act_selector_values_and_stars must be called here otherwise the
|
||||
// previous value is retained and causes incorrect drawing during the 16 transition
|
||||
// frames.
|
||||
CALL(/*arg*/ 0, /*func*/ lvl_init_act_selector_values_and_stars),
|
||||
#endif
|
||||
|
||||
/*27*/ TRANSITION(/*transType*/ WARP_TRANSITION_FADE_FROM_COLOR, /*time*/ 16, /*color*/ 0xFF, 0xFF, 0xFF),
|
||||
/*29*/ SLEEP(/*frames*/ 16),
|
||||
/*30*/ SET_MENU_MUSIC(/*seq*/ 0x000D),
|
||||
#ifdef TARGET_N64
|
||||
/*31*/ CALL(/*arg*/ 0, /*func*/ lvl_init_act_selector_values_and_stars),
|
||||
#endif
|
||||
/*33*/ CALL_LOOP(/*arg*/ 0, /*func*/ lvl_update_obj_and_load_act_button_actions),
|
||||
/*35*/ GET_OR_SET(/*op*/ OP_SET, /*var*/ VAR_CURR_ACT_NUM),
|
||||
/*36*/ STOP_MUSIC(/*fadeOutTime*/ 0x00BE),
|
||||
|
|
|
@ -1,49 +1,9 @@
|
|||
#include "libultra_internal.h"
|
||||
#ifndef TARGET_N64
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_N64
|
||||
void guMtxF2L(float mf[4][4], Mtx *m) {
|
||||
int r, c;
|
||||
s32 tmp1;
|
||||
s32 tmp2;
|
||||
s32 *m1 = &m->m[0][0];
|
||||
s32 *m2 = &m->m[2][0];
|
||||
for (r = 0; r < 4; r++) {
|
||||
for (c = 0; c < 2; c++) {
|
||||
tmp1 = mf[r][2 * c] * 65536.0f;
|
||||
tmp2 = mf[r][2 * c + 1] * 65536.0f;
|
||||
*m1++ = (tmp1 & 0xffff0000) | ((tmp2 >> 0x10) & 0xffff);
|
||||
*m2++ = ((tmp1 << 0x10) & 0xffff0000) | (tmp2 & 0xffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
void guMtxL2F(float mf[4][4], Mtx *m) {
|
||||
int r, c;
|
||||
u32 tmp1;
|
||||
u32 tmp2;
|
||||
u32 *m1;
|
||||
u32 *m2;
|
||||
s32 stmp1, stmp2;
|
||||
m1 = (u32 *) &m->m[0][0];
|
||||
m2 = (u32 *) &m->m[2][0];
|
||||
for (r = 0; r < 4; r++) {
|
||||
for (c = 0; c < 2; c++) {
|
||||
tmp1 = (*m1 & 0xffff0000) | ((*m2 >> 0x10) & 0xffff);
|
||||
tmp2 = ((*m1++ << 0x10) & 0xffff0000) | (*m2++ & 0xffff);
|
||||
stmp1 = *(s32 *) &tmp1;
|
||||
stmp2 = *(s32 *) &tmp2;
|
||||
mf[r][c * 2 + 0] = stmp1 / 65536.0f;
|
||||
mf[r][c * 2 + 1] = stmp2 / 65536.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void guMtxF2L(float mf[4][4], Mtx *m) {
|
||||
memcpy(m, mf, sizeof(Mtx));
|
||||
}
|
||||
#endif
|
||||
|
||||
void guMtxIdentF(float mf[4][4]) {
|
||||
int r, c;
|
||||
|
@ -58,11 +18,8 @@ void guMtxIdentF(float mf[4][4]) {
|
|||
}
|
||||
}
|
||||
void guMtxIdent(Mtx *m) {
|
||||
#ifdef TARGET_N64
|
||||
float mf[4][4];
|
||||
guMtxIdentF(mf);
|
||||
guMtxF2L(mf, m);
|
||||
#else
|
||||
|
||||
guMtxIdentF(m->m);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -738,6 +738,7 @@ void func_8031D838(s32 player, FadeT fadeInTime, u8 targetVolume) {
|
|||
}
|
||||
seqPlayer->fadeVelocity =
|
||||
(((f32)(FLOAT_CAST(targetVolume) / EU_FLOAT(127.0)) - seqPlayer->fadeVolume) / (f32) fadeInTime);
|
||||
|
||||
#ifdef VERSION_EU
|
||||
seqPlayer->state = 0;
|
||||
#else
|
||||
|
@ -764,117 +765,15 @@ void func_eu_802e9bec(s32 player, s32 channel, s32 arg2) {
|
|||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef TARGET_N64
|
||||
struct SPTask *create_next_audio_frame_task(void) {
|
||||
u32 samplesRemainingInAI;
|
||||
s32 writtenCmds;
|
||||
s32 index;
|
||||
OSTask_t *task;
|
||||
s32 oldDmaCount;
|
||||
s32 flags;
|
||||
|
||||
gAudioFrameCount++;
|
||||
if (gAudioLoadLock != AUDIO_LOCK_NOT_LOADING) {
|
||||
stubbed_printf("DAC:Lost 1 Frame.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gAudioTaskIndex ^= 1;
|
||||
gCurrAiBufferIndex++;
|
||||
gCurrAiBufferIndex %= NUMAIBUFFERS;
|
||||
index = (gCurrAiBufferIndex - 2 + NUMAIBUFFERS) % NUMAIBUFFERS;
|
||||
samplesRemainingInAI = osAiGetLength() / 4;
|
||||
|
||||
// Audio is triple buffered; the audio interface reads from two buffers
|
||||
// while the third is being written by the RSP. More precisely, the
|
||||
// lifecycle is:
|
||||
// - this function computes an audio command list
|
||||
// - wait for vblank
|
||||
// - the command list is sent to the RSP (we could have sent it to the
|
||||
// RSP before the vblank, but that gives the RSP less time to finish)
|
||||
// - wait for vblank
|
||||
// - the RSP is now expected to be finished, and we can send its output
|
||||
// on to the AI
|
||||
// Here we thus send to the AI the sound that was generated two frames ago.
|
||||
if (gAiBufferLengths[index] != 0) {
|
||||
osAiSetNextBuffer(gAiBuffers[index], gAiBufferLengths[index] * 4);
|
||||
}
|
||||
|
||||
oldDmaCount = gCurrAudioFrameDmaCount;
|
||||
// There has to be some sort of no-op if here, but it's not exactly clear
|
||||
// how it should look... It's also very unclear why gCurrAudioFrameDmaQueue
|
||||
// isn't read from here, despite gCurrAudioFrameDmaCount being reset.
|
||||
if (oldDmaCount > AUDIO_FRAME_DMA_QUEUE_SIZE) {
|
||||
stubbed_printf("DMA: Request queue over.( %d )\n", oldDmaCount);
|
||||
}
|
||||
gCurrAudioFrameDmaCount = 0;
|
||||
|
||||
gAudioTask = &gAudioTasks[gAudioTaskIndex];
|
||||
gAudioCmd = gAudioCmdBuffers[gAudioTaskIndex];
|
||||
|
||||
index = gCurrAiBufferIndex;
|
||||
gCurrAiBuffer = gAiBuffers[index];
|
||||
gAiBufferLengths[index] = ((gSamplesPerFrameTarget - samplesRemainingInAI +
|
||||
EXTRA_BUFFERED_AI_SAMPLES_TARGET) & ~0xf) + SAMPLES_TO_OVERPRODUCE;
|
||||
if (gAiBufferLengths[index] < gMinAiBufferLength) {
|
||||
gAiBufferLengths[index] = gMinAiBufferLength;
|
||||
}
|
||||
if (gAiBufferLengths[index] > gSamplesPerFrameTarget + SAMPLES_TO_OVERPRODUCE) {
|
||||
gAiBufferLengths[index] = gSamplesPerFrameTarget + SAMPLES_TO_OVERPRODUCE;
|
||||
}
|
||||
|
||||
if (sGameLoopTicked != 0) {
|
||||
update_game_sound();
|
||||
sGameLoopTicked = 0;
|
||||
}
|
||||
|
||||
// For the function to match we have to preserve some arbitrary variable
|
||||
// across this function call.
|
||||
flags = 0;
|
||||
gAudioCmd = synthesis_execute(gAudioCmd, &writtenCmds, gCurrAiBuffer, gAiBufferLengths[index]);
|
||||
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
|
||||
|
||||
index = gAudioTaskIndex;
|
||||
gAudioTask->msgqueue = NULL;
|
||||
gAudioTask->msg = NULL;
|
||||
|
||||
task = &gAudioTask->task.t;
|
||||
task->type = M_AUDTASK;
|
||||
task->flags = flags;
|
||||
task->ucode_boot = rspF3DBootStart;
|
||||
task->ucode_boot_size = (u8 *) rspF3DBootEnd - (u8 *) rspF3DBootStart;
|
||||
task->ucode = rspAspMainStart;
|
||||
task->ucode_size = 0x800; // (this size is ignored)
|
||||
task->ucode_data = rspAspMainDataStart;
|
||||
task->ucode_data_size = (rspAspMainDataEnd - rspAspMainDataStart) * sizeof(u64);
|
||||
task->dram_stack = NULL;
|
||||
task->dram_stack_size = 0;
|
||||
task->output_buff = NULL;
|
||||
task->output_buff_size = NULL;
|
||||
task->data_ptr = gAudioCmdBuffers[index];
|
||||
task->data_size = writtenCmds * sizeof(u64);
|
||||
|
||||
// The audio task never yields, so having a yield buffer is pointless.
|
||||
// This wastefulness was fixed in US.
|
||||
#ifdef VERSION_JP
|
||||
task->yield_data_ptr = (u64 *) gAudioSPTaskYieldBuffer;
|
||||
task->yield_data_size = OS_YIELD_AUDIO_SIZE;
|
||||
#else
|
||||
task->yield_data_ptr = NULL;
|
||||
task->yield_data_size = 0;
|
||||
// Stubbed N64-US/JP audio code
|
||||
// continue;
|
||||
#endif
|
||||
|
||||
decrease_sample_dma_ttls();
|
||||
return gAudioTask;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_N64
|
||||
struct SPTask *create_next_audio_frame_task(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void create_next_audio_buffer(s16 *samples, u32 num_samples) {
|
||||
gAudioFrameCount++;
|
||||
if (sGameLoopTicked != 0) {
|
||||
|
@ -886,7 +785,6 @@ void create_next_audio_buffer(s16 *samples, u32 num_samples) {
|
|||
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
|
||||
decrease_sample_dma_ttls();
|
||||
}
|
||||
#endif
|
||||
|
||||
void play_sound(s32 soundBits, f32 *pos) {
|
||||
sSoundRequests[sSoundRequestCount].soundBits = soundBits;
|
||||
|
|
|
@ -651,12 +651,7 @@ s32 audio_shut_down_and_reset_step(void) {
|
|||
*/
|
||||
void wait_for_audio_frames(s32 frames) {
|
||||
gAudioFrameCount = 0;
|
||||
#ifdef TARGET_N64
|
||||
// Sound thread will update gAudioFrameCount
|
||||
while (gAudioFrameCount < frames) {
|
||||
// spin
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -507,9 +507,6 @@ struct Note
|
|||
/* U/J, EU */
|
||||
/*0xA4, 0x00*/ struct AudioListItem listItem;
|
||||
/* 0x10*/ struct NoteSynthesisState synthesisState;
|
||||
#ifdef TARGET_N64
|
||||
u8 pad0[12];
|
||||
#endif
|
||||
/*0x04, 0x30*/ u8 priority;
|
||||
/* 0x31*/ u8 waveId;
|
||||
/* 0x32*/ u8 sampleCountIndex;
|
||||
|
|
|
@ -34,107 +34,6 @@ void decrease_sample_dma_ttls(void);
|
|||
s32 audio_shut_down_and_reset_step(void);
|
||||
void func_802ad7ec(u32);
|
||||
|
||||
#ifdef TARGET_N64
|
||||
struct SPTask *create_next_audio_frame_task(void) {
|
||||
u32 samplesRemainingInAI;
|
||||
s32 writtenCmds;
|
||||
s32 index;
|
||||
OSTask_t *task;
|
||||
s32 flags;
|
||||
u16 *currAiBuffer;
|
||||
s32 oldDmaCount;
|
||||
OSMesg sp30;
|
||||
OSMesg sp2C;
|
||||
|
||||
gAudioFrameCount++;
|
||||
if (gAudioFrameCount % gAudioBufferParameters.presetUnk4 != 0) {
|
||||
stubbed_printf("DAC:Lost 1 Frame.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osSendMesg(OSMesgQueues[0], (OSMesg) gAudioFrameCount, 0);
|
||||
|
||||
gAudioTaskIndex ^= 1;
|
||||
gCurrAiBufferIndex++;
|
||||
gCurrAiBufferIndex %= NUMAIBUFFERS;
|
||||
index = (gCurrAiBufferIndex - 2 + NUMAIBUFFERS) % NUMAIBUFFERS;
|
||||
samplesRemainingInAI = osAiGetLength() / 4;
|
||||
|
||||
if (gAiBufferLengths[index] != 0) {
|
||||
osAiSetNextBuffer(gAiBuffers[index], gAiBufferLengths[index] * 4);
|
||||
}
|
||||
|
||||
oldDmaCount = gCurrAudioFrameDmaCount;
|
||||
if (oldDmaCount > AUDIO_FRAME_DMA_QUEUE_SIZE) {
|
||||
stubbed_printf("DMA: Request queue over.( %d )\n", oldDmaCount);
|
||||
}
|
||||
gCurrAudioFrameDmaCount = 0;
|
||||
|
||||
decrease_sample_dma_ttls();
|
||||
if (osRecvMesg(OSMesgQueues[2], &sp30, 0) != -1) {
|
||||
gAudioResetPresetIdToLoad = (u8) (s32) sp30;
|
||||
gAudioResetStatus = 5;
|
||||
}
|
||||
|
||||
if (gAudioResetStatus != 0) {
|
||||
if (audio_shut_down_and_reset_step() == 0) {
|
||||
if (gAudioResetStatus == 0) {
|
||||
osSendMesg(OSMesgQueues[3], (OSMesg) (s32) gAudioResetPresetIdToLoad, OS_MESG_NOBLOCK);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gAudioTask = &gAudioTasks[gAudioTaskIndex];
|
||||
gAudioCmd = gAudioCmdBuffers[gAudioTaskIndex];
|
||||
index = gCurrAiBufferIndex;
|
||||
currAiBuffer = gAiBuffers[index];
|
||||
|
||||
gAiBufferLengths[index] = ((gAudioBufferParameters.samplesPerFrameTarget - samplesRemainingInAI +
|
||||
EXTRA_BUFFERED_AI_SAMPLES_TARGET) & ~0xf) + SAMPLES_TO_OVERPRODUCE;
|
||||
if (gAiBufferLengths[index] < gAudioBufferParameters.minAiBufferLength) {
|
||||
gAiBufferLengths[index] = gAudioBufferParameters.minAiBufferLength;
|
||||
}
|
||||
if (gAiBufferLengths[index] > gAudioBufferParameters.maxAiBufferLength) {
|
||||
gAiBufferLengths[index] = gAudioBufferParameters.maxAiBufferLength;
|
||||
}
|
||||
|
||||
if (osRecvMesg(OSMesgQueues[1], &sp2C, OS_MESG_NOBLOCK) != -1) {
|
||||
func_802ad7ec((u32) sp2C);
|
||||
}
|
||||
|
||||
flags = 0;
|
||||
gAudioCmd = synthesis_execute(gAudioCmd, &writtenCmds, currAiBuffer, gAiBufferLengths[index]);
|
||||
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
|
||||
gAudioRandom = gAudioRandom + writtenCmds / 8;
|
||||
|
||||
index = gAudioTaskIndex;
|
||||
gAudioTask->msgqueue = NULL;
|
||||
gAudioTask->msg = NULL;
|
||||
|
||||
task = &gAudioTask->task.t;
|
||||
task->type = M_AUDTASK;
|
||||
task->flags = flags;
|
||||
#if TARGET_N64
|
||||
task->ucode_boot = rspF3DBootStart;
|
||||
task->ucode_boot_size = (u8 *) rspF3DBootEnd - (u8 *) rspF3DBootStart;
|
||||
task->ucode = rspAspMainStart;
|
||||
task->ucode_data = rspAspMainDataStart;
|
||||
task->ucode_size = 0x800; // (this size is ignored)
|
||||
task->ucode_data_size = (rspAspMainDataEnd - rspAspMainDataStart) * sizeof(u64);
|
||||
#endif
|
||||
task->dram_stack = NULL;
|
||||
task->dram_stack_size = 0;
|
||||
task->output_buff = NULL;
|
||||
task->output_buff_size = NULL;
|
||||
task->data_ptr = gAudioCmdBuffers[index];
|
||||
task->data_size = writtenCmds * sizeof(u64);
|
||||
task->yield_data_ptr = NULL;
|
||||
task->yield_data_size = 0;
|
||||
return gAudioTask;
|
||||
}
|
||||
#endif
|
||||
|
||||
void eu_process_audio_cmd(struct EuAudioCmd *cmd) {
|
||||
s32 i;
|
||||
|
||||
|
|
|
@ -8,10 +8,7 @@
|
|||
#include "seqplayer.h"
|
||||
#include "external.h"
|
||||
|
||||
|
||||
#ifndef TARGET_N64
|
||||
#include "../pc/mixer.h"
|
||||
#endif
|
||||
|
||||
#define DMEM_ADDR_TEMP 0x0
|
||||
#define DMEM_ADDR_UNCOMPRESSED_NOTE 0x180
|
||||
|
|
|
@ -27,11 +27,8 @@ extern struct SaveBuffer gSaveBuffer;
|
|||
|
||||
extern u8 gGfxSPTaskStack[];
|
||||
|
||||
#ifdef TARGET_N64
|
||||
#define GFX_NUM_POOLS 2
|
||||
#else
|
||||
#define GFX_NUM_POOLS 1
|
||||
#endif
|
||||
|
||||
extern struct GfxPool gGfxPools[GFX_NUM_POOLS];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include <ultra64.h>
|
||||
#ifndef TARGET_N64
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "sm64.h"
|
||||
#include "audio/external.h"
|
||||
|
@ -605,9 +604,7 @@ static void level_cmd_set_gamma(void) {
|
|||
|
||||
static void level_cmd_set_terrain_data(void) {
|
||||
if (sCurrAreaIndex != -1) {
|
||||
#ifdef TARGET_N64
|
||||
gAreas[sCurrAreaIndex].terrainData = segmented_to_virtual(CMD_GET(void *, 4));
|
||||
#else
|
||||
|
||||
Collision *data;
|
||||
u32 size;
|
||||
|
||||
|
@ -615,7 +612,7 @@ static void level_cmd_set_terrain_data(void) {
|
|||
size = get_area_terrain_size(data) * sizeof(Collision);
|
||||
gAreas[sCurrAreaIndex].terrainData = alloc_only_pool_alloc(sLevelPool, size);
|
||||
memcpy(gAreas[sCurrAreaIndex].terrainData, data, size);
|
||||
#endif
|
||||
|
||||
}
|
||||
sCurrentCmd = CMD_NEXT;
|
||||
}
|
||||
|
@ -629,9 +626,7 @@ static void level_cmd_set_rooms(void) {
|
|||
|
||||
static void level_cmd_set_macro_objects(void) {
|
||||
if (sCurrAreaIndex != -1) {
|
||||
#ifdef TARGET_N64
|
||||
gAreas[sCurrAreaIndex].macroObjects = segmented_to_virtual(CMD_GET(void *, 4));
|
||||
#else
|
||||
|
||||
MacroObject *data = segmented_to_virtual(CMD_GET(void *, 4));
|
||||
s32 len = 0;
|
||||
while (data[len++] != 0x001E) {
|
||||
|
@ -639,7 +634,7 @@ static void level_cmd_set_macro_objects(void) {
|
|||
}
|
||||
gAreas[sCurrAreaIndex].macroObjects = alloc_only_pool_alloc(sLevelPool, len * sizeof(MacroObject));
|
||||
memcpy(gAreas[sCurrAreaIndex].macroObjects, data, len * sizeof(MacroObject));
|
||||
#endif
|
||||
|
||||
}
|
||||
sCurrentCmd = CMD_NEXT;
|
||||
}
|
||||
|
|
|
@ -533,7 +533,6 @@ void alloc_surface_pools(void) {
|
|||
reset_red_coins_collected();
|
||||
}
|
||||
|
||||
#ifndef TARGET_N64
|
||||
/**
|
||||
* Get the size of the terrain data, to get the correct size when copying later.
|
||||
*/
|
||||
|
@ -581,8 +580,6 @@ u32 get_area_terrain_size(s16 *data) {
|
|||
|
||||
return data - startPos;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Process the level file, loading in vertices, surfaces, some objects, and environmental
|
||||
|
|
|
@ -28,9 +28,9 @@ extern struct Surface *sSurfacePool;
|
|||
extern s16 sSurfacePoolSize;
|
||||
|
||||
void alloc_surface_pools(void);
|
||||
#ifndef TARGET_N64
|
||||
|
||||
u32 get_area_terrain_size(s16 *data);
|
||||
#endif
|
||||
|
||||
void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects);
|
||||
void clear_dynamic_surfaces(void);
|
||||
void load_object_collision_model(void);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "sm64.h"
|
||||
#include "audio/external.h"
|
||||
#include "buffers/buffers.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "buffers/gfx_output_buffer.h"
|
||||
#include "buffers/framebuffers.h"
|
||||
#include "buffers/zbuffer.h"
|
||||
|
@ -152,8 +153,9 @@ void clear_frame_buffer(s32 a) {
|
|||
gDPSetCycleType(gDisplayListHead++, G_CYC_FILL);
|
||||
|
||||
gDPSetFillColor(gDisplayListHead++, a);
|
||||
gDPFillRectangle(gDisplayListHead++, 0, BORDER_HEIGHT, SCREEN_WIDTH - 1,
|
||||
SCREEN_HEIGHT - 1 - BORDER_HEIGHT);
|
||||
|
||||
// Ratio-correct borderfill
|
||||
gDPFillRectangle(gDisplayListHead++, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(0), BORDER_HEIGHT, GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(0) - 1, SCREEN_HEIGHT - BORDER_HEIGHT - 1);
|
||||
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
|
||||
|
@ -217,13 +219,7 @@ void create_task_structure(void) {
|
|||
gGfxSPTask->msgqueue = &D_80339CB8;
|
||||
gGfxSPTask->msg = (OSMesg) 2;
|
||||
gGfxSPTask->task.t.type = M_GFXTASK;
|
||||
#if TARGET_N64
|
||||
gGfxSPTask->task.t.ucode_boot = rspF3DBootStart;
|
||||
gGfxSPTask->task.t.ucode_boot_size = ((u8 *) rspF3DBootEnd - (u8 *) rspF3DBootStart);
|
||||
gGfxSPTask->task.t.flags = 0;
|
||||
gGfxSPTask->task.t.ucode = rspF3DStart;
|
||||
gGfxSPTask->task.t.ucode_data = rspF3DDataStart;
|
||||
#endif
|
||||
|
||||
gGfxSPTask->task.t.ucode_size = SP_UCODE_SIZE; // (this size is ignored)
|
||||
gGfxSPTask->task.t.ucode_data_size = SP_UCODE_DATA_SIZE;
|
||||
gGfxSPTask->task.t.dram_stack = (u64 *) gGfxSPTaskStack;
|
||||
|
@ -267,33 +263,9 @@ void end_master_display_list(void) {
|
|||
create_task_structure();
|
||||
}
|
||||
|
||||
void draw_reset_bars(void) {
|
||||
s32 sp24;
|
||||
s32 sp20;
|
||||
s32 fbNum;
|
||||
u64 *sp18;
|
||||
|
||||
if (gResetTimer != 0 && D_8032C648 < 15) {
|
||||
if (sCurrFBNum == 0) {
|
||||
fbNum = 2;
|
||||
} else {
|
||||
fbNum = sCurrFBNum - 1;
|
||||
}
|
||||
|
||||
sp18 = (u64 *) PHYSICAL_TO_VIRTUAL(gPhysicalFrameBuffers[fbNum]);
|
||||
sp18 += D_8032C648++ * (SCREEN_WIDTH / 4);
|
||||
|
||||
for (sp24 = 0; sp24 < ((SCREEN_HEIGHT / 16) + 1); sp24++) {
|
||||
// Must be on one line to match -O2
|
||||
for (sp20 = 0; sp20 < (SCREEN_WIDTH / 4); sp20++) *sp18++ = 0;
|
||||
sp18 += ((SCREEN_WIDTH / 4) * 14);
|
||||
}
|
||||
}
|
||||
|
||||
osWritebackDCacheAll();
|
||||
osRecvMesg(&gGameVblankQueue, &D_80339BEC, OS_MESG_BLOCK);
|
||||
osRecvMesg(&gGameVblankQueue, &D_80339BEC, OS_MESG_BLOCK);
|
||||
}
|
||||
//void draw_reset_bars(void) { // TARGET_64 only
|
||||
// Stubbed. Only N64 target uses this
|
||||
// }
|
||||
|
||||
void rendering_init(void) {
|
||||
gGfxPool = &gGfxPools[0];
|
||||
|
@ -525,7 +497,7 @@ void read_controller_inputs(void) {
|
|||
controller->stickMag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
@ -626,16 +598,12 @@ void setup_game_memory(void) {
|
|||
load_segment_decompress(2, _segment2_mio0SegmentRomStart, _segment2_mio0SegmentRomEnd);
|
||||
}
|
||||
|
||||
#ifndef TARGET_N64
|
||||
|
||||
static struct LevelCommand *levelCommandAddr;
|
||||
#endif
|
||||
|
||||
// main game loop thread. runs forever as long as the game
|
||||
// continues.
|
||||
void thread5_game_loop(UNUSED void *arg) {
|
||||
#ifdef TARGET_N64
|
||||
struct LevelCommand *levelCommandAddr;
|
||||
#endif
|
||||
|
||||
setup_game_memory();
|
||||
#ifdef VERSION_SH
|
||||
|
@ -655,32 +623,21 @@ void thread5_game_loop(UNUSED void *arg) {
|
|||
play_music(SEQ_PLAYER_SFX, SEQUENCE_ARGS(0, SEQ_SOUND_PLAYER), 0);
|
||||
set_sound_mode(save_file_get_sound_mode());
|
||||
|
||||
#ifdef TARGET_N64
|
||||
func_80247ED8();
|
||||
rendering_init();
|
||||
|
||||
while (1) {
|
||||
#else
|
||||
gGlobalTimer++;
|
||||
}
|
||||
|
||||
void game_loop_one_iteration(void) {
|
||||
#endif
|
||||
// if the reset timer is active, run the process to reset the game.
|
||||
if (gResetTimer) {
|
||||
//if (gResetTimer) {
|
||||
// draw_reset_bars(); (N64 target only?)
|
||||
//}
|
||||
|
||||
#ifdef TARGET_N64
|
||||
draw_reset_bars();
|
||||
continue;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
profiler_log_thread5_time(THREAD5_START);
|
||||
|
||||
// if any controllers are plugged in, start read the data for when
|
||||
// read_controller_inputs is called later.
|
||||
if (gControllerBits) {
|
||||
|
||||
#ifdef VERSION_SH
|
||||
block_until_rumble_pak_free();
|
||||
#endif
|
||||
|
@ -699,7 +656,5 @@ void game_loop_one_iteration(void) {
|
|||
// amount of free space remaining.
|
||||
print_text_fmt_int(180, 20, "BUF %d", gGfxPoolEnd - (u8 *) gDisplayListHead);
|
||||
}
|
||||
#ifdef TARGET_N64
|
||||
}
|
||||
#endif
|
||||
// } was here for ifdef targ 64
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ extern void clear_viewport(Vp *, s32);
|
|||
void make_viewport_clip_rect(Vp *viewport);
|
||||
extern void init_render_image(void);
|
||||
extern void end_master_display_list(void);
|
||||
extern void draw_reset_bars(void);
|
||||
//extern void draw_reset_bars(void); Target_64 only. Not used
|
||||
extern void rendering_init(void);
|
||||
extern void config_gfx_pool(void);
|
||||
extern void display_and_vsync(void);
|
||||
|
|
|
@ -46,11 +46,8 @@ s8 gFlyingCarpetState;
|
|||
*
|
||||
* Texture coordinates are s10.5 fixed-point, which means you should left-shift the actual coordinates by 5.
|
||||
*/
|
||||
#ifdef TARGET_N64
|
||||
void make_vertex(Vtx *vtx, s32 n, s16 x, s16 y, s16 z, s16 tx, s16 ty, u8 r, u8 g, u8 b, u8 a) {
|
||||
#else
|
||||
void make_vertex(Vtx *vtx, s32 n, f32 x, f32 y, f32 z, s16 tx, s16 ty, u8 r, u8 g, u8 b, u8 a) {
|
||||
#endif
|
||||
|
||||
vtx[n].v.ob[0] = x;
|
||||
vtx[n].v.ob[1] = y;
|
||||
vtx[n].v.ob[2] = z;
|
||||
|
|
|
@ -12,15 +12,9 @@ enum FlyingCarpetState
|
|||
|
||||
extern s8 gFlyingCarpetState;
|
||||
|
||||
#ifdef TARGET_N64
|
||||
extern void make_vertex(
|
||||
Vtx *vtx, s32 n, s16 x, s16 y, s16 z, s16 tx, s16 ty, u8 r, u8 g, u8 b, u8 a
|
||||
);
|
||||
#else
|
||||
extern void make_vertex(
|
||||
Vtx *vtx, s32 n, f32 x, f32 y, f32 z, s16 tx, s16 ty, u8 r, u8 g, u8 b, u8 a
|
||||
);
|
||||
#endif
|
||||
extern s16 round_float(f32);
|
||||
extern Gfx *geo_exec_inside_castle_light(s32 callContext, struct GraphNode *node, f32 mtx[4][4]);
|
||||
extern Gfx *geo_exec_flying_carpet_timer_update(s32 callContext, struct GraphNode *node,
|
||||
|
|
|
@ -134,14 +134,7 @@ void create_dl_identity_matrix(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef TARGET_N64
|
||||
matrix->m[0][0] = 0x00010000; matrix->m[1][0] = 0x00000000; matrix->m[2][0] = 0x00000000; matrix->m[3][0] = 0x00000000;
|
||||
matrix->m[0][1] = 0x00000000; matrix->m[1][1] = 0x00010000; matrix->m[2][1] = 0x00000000; matrix->m[3][1] = 0x00000000;
|
||||
matrix->m[0][2] = 0x00000001; matrix->m[1][2] = 0x00000000; matrix->m[2][2] = 0x00000000; matrix->m[3][2] = 0x00000000;
|
||||
matrix->m[0][3] = 0x00000000; matrix->m[1][3] = 0x00000001; matrix->m[2][3] = 0x00000000; matrix->m[3][3] = 0x00000000;
|
||||
#else
|
||||
guMtxIdent(matrix);
|
||||
#endif
|
||||
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
|
@ -1805,25 +1798,18 @@ void render_dialog_entries(void) {
|
|||
render_dialog_box_type(dialog, dialog->linesPerBox);
|
||||
|
||||
gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE,
|
||||
#ifdef TARGET_N64
|
||||
ensure_nonnegative(dialog->leftOffset),
|
||||
#else
|
||||
|
||||
0,
|
||||
#endif
|
||||
ensure_nonnegative(DIAG_VAL2 - dialog->width),
|
||||
#ifdef VERSION_EU
|
||||
#ifdef TARGET_N64
|
||||
ensure_nonnegative(dialog->leftOffset + DIAG_VAL3 / gDialogBoxScale),
|
||||
#else
|
||||
|
||||
SCREEN_WIDTH,
|
||||
#endif
|
||||
|
||||
ensure_nonnegative((240 - dialog->width) + ((dialog->linesPerBox * 80) / DIAG_VAL4) / gDialogBoxScale));
|
||||
#else
|
||||
#ifdef TARGET_N64
|
||||
ensure_nonnegative(DIAG_VAL3 + dialog->leftOffset),
|
||||
#else
|
||||
|
||||
SCREEN_WIDTH,
|
||||
#endif
|
||||
|
||||
ensure_nonnegative(240 + ((dialog->linesPerBox * 80) / DIAG_VAL4) - dialog->width));
|
||||
#endif
|
||||
#if defined(VERSION_JP) || defined(VERSION_SH)
|
||||
|
@ -2136,12 +2122,9 @@ void shade_screen(void) {
|
|||
|
||||
// This is a bit weird. It reuses the dialog text box (width 130, height -80),
|
||||
// so scale to at least fit the screen.
|
||||
#ifdef TARGET_N64
|
||||
create_dl_scale_matrix(MENU_MTX_NOPUSH, 2.6f, 3.4f, 1.0f);
|
||||
#else
|
||||
|
||||
create_dl_scale_matrix(MENU_MTX_NOPUSH,
|
||||
GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_HEIGHT / 130.0f, 3.0f, 1.0f);
|
||||
#endif
|
||||
|
||||
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 110);
|
||||
gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box);
|
||||
|
|
|
@ -328,7 +328,7 @@ void spawn_special_objects(s16 areaIndex, s16 **specialObjList) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef TARGET_N64
|
||||
// PC Port, so always use below
|
||||
u32 get_special_objects_size(s16 *data) {
|
||||
s16 *startPos = data;
|
||||
s32 numOfSpecialObjects;
|
||||
|
@ -372,4 +372,3 @@ u32 get_special_objects_size(s16 *data) {
|
|||
|
||||
return data - startPos;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,8 +16,6 @@ extern void spawn_macro_abs_special(u32 model, const BehaviorScript *behavior, s
|
|||
extern void spawn_macro_objects(s16 areaIndex, s16 * macroObjList);
|
||||
extern void spawn_macro_objects_hardcoded(s16 areaIndex, s16 * macroObjList);
|
||||
extern void spawn_special_objects(s16 areaIndex, s16 ** specialObjList);
|
||||
#ifndef TARGET_N64
|
||||
extern u32 get_special_objects_size(s16 *data);
|
||||
#endif
|
||||
|
||||
#endif /* MACRO_SPECIAL_OBJECTS_H */
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include <ultra64.h>
|
||||
#ifndef TARGET_N64
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "sm64.h"
|
||||
|
||||
|
@ -78,27 +76,6 @@ void *get_segment_base_addr(s32 segment) {
|
|||
return (void *) (sSegmentTable[segment] | 0x80000000);
|
||||
}
|
||||
|
||||
#ifdef TARGET_N64
|
||||
void *segmented_to_virtual(const void *addr) {
|
||||
size_t segment = (uintptr_t) addr >> 24;
|
||||
size_t offset = (uintptr_t) addr & 0x00FFFFFF;
|
||||
|
||||
return (void *) ((sSegmentTable[segment] + offset) | 0x80000000);
|
||||
}
|
||||
|
||||
void *virtual_to_segmented(u32 segment, const void *addr) {
|
||||
size_t offset = ((uintptr_t) addr & 0x1FFFFFFF) - sSegmentTable[segment];
|
||||
|
||||
return (void *) ((segment << 24) + offset);
|
||||
}
|
||||
|
||||
void move_segment_table_to_dmem(void) {
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
gSPSegment(gDisplayListHead++, i, sSegmentTable[i]);
|
||||
}
|
||||
#else
|
||||
void *segmented_to_virtual(const void *addr) {
|
||||
return (void *) addr;
|
||||
}
|
||||
|
@ -109,7 +86,7 @@ void *virtual_to_segmented(u32 segment, const void *addr) {
|
|||
|
||||
void move_segment_table_to_dmem(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the main memory pool. This pool is conceptually a pair of stacks
|
||||
|
@ -248,22 +225,8 @@ u32 main_pool_pop_state(void) {
|
|||
*/
|
||||
static void dma_read(u8 *dest, u8 *srcStart, u8 *srcEnd) {
|
||||
u32 size = ALIGN16(srcEnd - srcStart);
|
||||
#ifdef TARGET_N64
|
||||
osInvalDCache(dest, size);
|
||||
while (size != 0) {
|
||||
u32 copySize = (size >= 0x1000) ? 0x1000 : size;
|
||||
|
||||
osPiStartDma(&gDmaIoMesg, OS_MESG_PRI_NORMAL, OS_READ, (uintptr_t) srcStart, dest, copySize,
|
||||
&gDmaMesgQueue);
|
||||
osRecvMesg(&gDmaMesgQueue, &D_80339BEC, OS_MESG_BLOCK);
|
||||
|
||||
dest += copySize;
|
||||
srcStart += copySize;
|
||||
size -= copySize;
|
||||
}
|
||||
#else
|
||||
memcpy(dest, srcStart, srcEnd - srcStart);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -281,103 +244,6 @@ static void *dynamic_dma_read(u8 *srcStart, u8 *srcEnd, u32 side) {
|
|||
return dest;
|
||||
}
|
||||
|
||||
#ifdef TARGET_N64
|
||||
/**
|
||||
* Load data from ROM into a newly allocated block, and set the segment base
|
||||
* address to this block.
|
||||
*/
|
||||
void *load_segment(s32 segment, u8 *srcStart, u8 *srcEnd, u32 side) {
|
||||
void *addr = dynamic_dma_read(srcStart, srcEnd, side);
|
||||
|
||||
if (addr != NULL) {
|
||||
set_segment_base_addr(segment, addr);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a block of memory starting at destAddr and ending at the righthand
|
||||
* end of the memory pool. Then copy srcStart through srcEnd from ROM to this
|
||||
* block.
|
||||
* If this block is not large enough to hold the ROM data, or that portion
|
||||
* of the pool is already allocated, return NULL.
|
||||
*/
|
||||
void *load_to_fixed_pool_addr(u8 *destAddr, u8 *srcStart, u8 *srcEnd) {
|
||||
void *dest = NULL;
|
||||
u32 srcSize = ALIGN16(srcEnd - srcStart);
|
||||
u32 destSize = ALIGN16((u8 *) sPoolListHeadR - destAddr);
|
||||
|
||||
if (srcSize <= destSize) {
|
||||
dest = main_pool_alloc(destSize, MEMORY_POOL_RIGHT);
|
||||
if (dest != NULL) {
|
||||
bzero(dest, destSize);
|
||||
osWritebackDCacheAll();
|
||||
dma_read(dest, srcStart, srcEnd);
|
||||
osInvalICache(dest, destSize);
|
||||
osInvalDCache(dest, destSize);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress the block of ROM data from srcStart to srcEnd and return a
|
||||
* pointer to an allocated buffer holding the decompressed data. Set the
|
||||
* base address of segment to this address.
|
||||
*/
|
||||
void *load_segment_decompress(s32 segment, u8 *srcStart, u8 *srcEnd) {
|
||||
void *dest = NULL;
|
||||
|
||||
u32 compSize = ALIGN16(srcEnd - srcStart);
|
||||
u8 *compressed = main_pool_alloc(compSize, MEMORY_POOL_RIGHT);
|
||||
|
||||
// Decompressed size from mio0 header
|
||||
u32 *size = (u32 *) (compressed + 4);
|
||||
|
||||
if (compressed != NULL) {
|
||||
dma_read(compressed, srcStart, srcEnd);
|
||||
dest = main_pool_alloc(*size, MEMORY_POOL_LEFT);
|
||||
if (dest != NULL) {
|
||||
decompress(compressed, dest);
|
||||
set_segment_base_addr(segment, dest);
|
||||
main_pool_free(compressed);
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *load_segment_decompress_heap(u32 segment, u8 *srcStart, u8 *srcEnd) {
|
||||
UNUSED void *dest = NULL;
|
||||
u32 compSize = ALIGN16(srcEnd - srcStart);
|
||||
u8 *compressed = main_pool_alloc(compSize, MEMORY_POOL_RIGHT);
|
||||
UNUSED u32 *pUncSize = (u32 *) (compressed + 4);
|
||||
|
||||
if (compressed != NULL) {
|
||||
dma_read(compressed, srcStart, srcEnd);
|
||||
decompress(compressed, gDecompressionHeap);
|
||||
set_segment_base_addr(segment, gDecompressionHeap);
|
||||
main_pool_free(compressed);
|
||||
} else {
|
||||
}
|
||||
return gDecompressionHeap;
|
||||
}
|
||||
|
||||
void load_engine_code_segment(void) {
|
||||
void *startAddr = (void *) SEG_ENGINE;
|
||||
u32 totalSize = SEG_FRAMEBUFFERS - SEG_ENGINE;
|
||||
UNUSED u32 alignedSize = ALIGN16(_engineSegmentRomEnd - _engineSegmentRomStart);
|
||||
|
||||
bzero(startAddr, totalSize);
|
||||
osWritebackDCacheAll();
|
||||
dma_read(startAddr, _engineSegmentRomStart, _engineSegmentRomEnd);
|
||||
osInvalICache(startAddr, totalSize);
|
||||
osInvalDCache(startAddr, totalSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Allocate an allocation-only pool from the main pool. This pool doesn't
|
||||
* support freeing allocated memory.
|
||||
|
|
|
@ -37,19 +37,11 @@ u32 main_pool_available(void);
|
|||
u32 main_pool_push_state(void);
|
||||
u32 main_pool_pop_state(void);
|
||||
|
||||
#ifdef TARGET_N64
|
||||
void *load_segment(s32 segment, u8 *srcStart, u8 *srcEnd, u32 side);
|
||||
void *load_to_fixed_pool_addr(u8 *destAddr, u8 *srcStart, u8 *srcEnd);
|
||||
void *load_segment_decompress(s32 segment, u8 *srcStart, u8 *srcEnd);
|
||||
void *load_segment_decompress_heap(u32 segment, u8 *srcStart, u8 *srcEnd);
|
||||
void load_engine_code_segment(void);
|
||||
#else
|
||||
#define load_segment(...)
|
||||
#define load_to_fixed_pool_addr(...)
|
||||
#define load_segment_decompress(...)
|
||||
#define load_segment_decompress_heap(...)
|
||||
#define load_engine_code_segment(...)
|
||||
#endif
|
||||
|
||||
struct AllocOnlyPool *alloc_only_pool_init(u32 size, u32 side);
|
||||
void *alloc_only_pool_alloc(struct AllocOnlyPool *pool, s32 size);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "game/game_init.h"
|
||||
#include "game/ingame_menu.h"
|
||||
#include "game/options_menu.h"
|
||||
#include "pc/cliopts.h"
|
||||
#include "pc/configfile.h"
|
||||
#include "pc/controller/controller_api.h"
|
||||
|
||||
|
@ -424,7 +425,7 @@ void optmenu_toggle(void) {
|
|||
newcam_init_settings(); // load bettercam settings from config vars
|
||||
#endif
|
||||
controller_reconfigure(); // rebind using new config values
|
||||
configfile_save(CONFIG_FILE);
|
||||
configfile_save(gCLIOpts.ConfigFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -366,29 +366,6 @@ void add_glyph_texture(s8 glyphIndex) {
|
|||
gSPDisplayList(gDisplayListHead++, dl_hud_img_load_tex_block);
|
||||
}
|
||||
|
||||
#ifdef TARGET_N64
|
||||
/**
|
||||
* Clips textrect into the boundaries defined.
|
||||
*/
|
||||
void clip_to_bounds(s32 *x, s32 *y) {
|
||||
if (*x < TEXRECT_MIN_X) {
|
||||
*x = TEXRECT_MIN_X;
|
||||
}
|
||||
|
||||
if (*x > TEXRECT_MAX_X) {
|
||||
*x = TEXRECT_MAX_X;
|
||||
}
|
||||
|
||||
if (*y < TEXRECT_MIN_Y) {
|
||||
*y = TEXRECT_MIN_Y;
|
||||
}
|
||||
|
||||
if (*y > TEXRECT_MAX_Y) {
|
||||
*y = TEXRECT_MAX_Y;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Renders the glyph that's set at the given position.
|
||||
*/
|
||||
|
@ -398,9 +375,6 @@ void render_textrect(s32 x, s32 y, s32 pos) {
|
|||
s32 rectX;
|
||||
s32 rectY;
|
||||
|
||||
#ifdef TARGET_N64
|
||||
clip_to_bounds(&rectBaseX, &rectBaseY);
|
||||
#endif
|
||||
rectX = rectBaseX;
|
||||
rectY = rectBaseY;
|
||||
gSPTextureRectangle(gDisplayListHead++, rectX << 2, rectY << 2, (rectX + 15) << 2,
|
||||
|
|
|
@ -506,11 +506,7 @@ static void geo_process_background(struct GraphNodeBackground *node) {
|
|||
if (list != 0) {
|
||||
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(list), node->fnNode.node.flags >> 8);
|
||||
} else if (gCurGraphNodeMasterList != NULL) {
|
||||
#ifdef TARGET_N64
|
||||
Gfx *gfxStart = alloc_display_list(sizeof(Gfx) * 7);
|
||||
#else
|
||||
Gfx *gfxStart = alloc_display_list(sizeof(Gfx) * 8);
|
||||
#endif
|
||||
Gfx *gfx = gfxStart;
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
|
@ -757,9 +753,7 @@ static int obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) {
|
|||
// the amount of units between the center of the screen and the horizontal edge
|
||||
// given the distance from the object to the camera.
|
||||
|
||||
#ifndef TARGET_N64
|
||||
hScreenEdge *= GFX_DIMENSIONS_ASPECT_RATIO;
|
||||
#endif
|
||||
|
||||
if (geo != NULL && geo->type == GRAPH_NODE_TYPE_CULLING_RADIUS) {
|
||||
cullingRadius =
|
||||
|
|
|
@ -15,6 +15,12 @@
|
|||
#define MENU_DATA_MAGIC 0x4849
|
||||
#define SAVE_FILE_MAGIC 0x4441
|
||||
|
||||
#define BSWAP16(x) \
|
||||
( (((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00) )
|
||||
#define BSWAP32(x) \
|
||||
( (((x) >> 24) & 0x000000FF) | (((x) >> 8) & 0x0000FF00) | \
|
||||
(((x) << 8) & 0x00FF0000) | (((x) << 24) & 0xFF000000) )
|
||||
|
||||
STATIC_ASSERT(sizeof(struct SaveBuffer) == EEPROM_SIZE, "eeprom buffer size must match");
|
||||
|
||||
extern struct SaveBuffer gSaveBuffer;
|
||||
|
@ -50,6 +56,38 @@ static void stub_save_file_1(void) {
|
|||
UNUSED s32 pad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Byteswap all multibyte fields in a SaveBlockSignature.
|
||||
*/
|
||||
static inline void bswap_signature(struct SaveBlockSignature *data) {
|
||||
data->magic = BSWAP16(data->magic);
|
||||
data->chksum = BSWAP16(data->chksum); // valid as long as the checksum is a literal sum
|
||||
}
|
||||
|
||||
/**
|
||||
* Byteswap all multibyte fields in a MainMenuSaveData.
|
||||
*/
|
||||
static inline void bswap_menudata(struct MainMenuSaveData *data) {
|
||||
for (int i = 0; i < NUM_SAVE_FILES; ++i)
|
||||
data->coinScoreAges[i] = BSWAP32(data->coinScoreAges[i]);
|
||||
data->soundMode = BSWAP16(data->soundMode);
|
||||
#ifdef VERSION_EU
|
||||
data->language = BSWAP16(data->language);
|
||||
#endif
|
||||
bswap_signature(&data->signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Byteswap all multibyte fields in a SaveFile.
|
||||
*/
|
||||
static inline void bswap_savefile(struct SaveFile *data) {
|
||||
data->capPos[0] = BSWAP16(data->capPos[0]);
|
||||
data->capPos[1] = BSWAP16(data->capPos[1]);
|
||||
data->capPos[2] = BSWAP16(data->capPos[2]);
|
||||
data->flags = BSWAP32(data->flags);
|
||||
bswap_signature(&data->signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from EEPROM to a given address.
|
||||
* The EEPROM address is computed using the offset of the destination address from gSaveBuffer.
|
||||
|
@ -80,16 +118,16 @@ static s32 read_eeprom_data(void *buffer, s32 size) {
|
|||
|
||||
/**
|
||||
* Write data to EEPROM.
|
||||
* The EEPROM address is computed using the offset of the source address from gSaveBuffer.
|
||||
* The EEPROM address was originally computed using the offset of the source address from gSaveBuffer.
|
||||
* Try at most 4 times, and return 0 on success. On failure, return the status returned from
|
||||
* osEepromLongWrite. Unlike read_eeprom_data, return 1 if EEPROM isn't loaded.
|
||||
*/
|
||||
static s32 write_eeprom_data(void *buffer, s32 size) {
|
||||
static s32 write_eeprom_data(void *buffer, s32 size, const uintptr_t baseofs) {
|
||||
s32 status = 1;
|
||||
|
||||
if (gEepromProbe != 0) {
|
||||
s32 triesLeft = 4;
|
||||
u32 offset = (u32)((u8 *) buffer - (u8 *) &gSaveBuffer) >> 3;
|
||||
u32 offset = (u32)baseofs >> 3;
|
||||
|
||||
do {
|
||||
#ifdef VERSION_SH
|
||||
|
@ -106,6 +144,41 @@ static s32 write_eeprom_data(void *buffer, s32 size) {
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrappers that byteswap the data on LE platforms before writing it to 'EEPROM'
|
||||
*/
|
||||
|
||||
static inline s32 write_eeprom_savefile(const u32 file, const u32 slot, const u32 num) {
|
||||
// calculate the EEPROM address using the file number and slot
|
||||
const uintptr_t ofs = (u8*)&gSaveBuffer.files[file][slot] - (u8*)&gSaveBuffer;
|
||||
|
||||
#if IS_BIG_ENDIAN
|
||||
return write_eeprom_data(&gSaveBuffer.files[file][slot], num * sizeof(struct SaveFile), ofs);
|
||||
#else
|
||||
// byteswap the data and then write it
|
||||
struct SaveFile sf[num];
|
||||
bcopy(&gSaveBuffer.files[file][slot], sf, num * sizeof(sf[0]));
|
||||
for (u32 i = 0; i < num; ++i) bswap_savefile(&sf[i]);
|
||||
return write_eeprom_data(&sf, sizeof(sf), ofs);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline s32 write_eeprom_menudata(const u32 slot, const u32 num) {
|
||||
// calculate the EEPROM address using the slot
|
||||
const uintptr_t ofs = (u8*)&gSaveBuffer.menuData[slot] - (u8*)&gSaveBuffer;
|
||||
|
||||
#if IS_BIG_ENDIAN
|
||||
return write_eeprom_data(&gSaveBuffer.menuData[slot], num * sizeof(struct MainMenuSaveData), ofs);
|
||||
#else
|
||||
// byteswap the data and then write it
|
||||
struct MainMenuSaveData md[num];
|
||||
bcopy(&gSaveBuffer.menuData[slot], md, num * sizeof(md[0]));
|
||||
for (u32 i = 0; i < num; ++i) bswap_menudata(&md[i]);
|
||||
return write_eeprom_data(&md, sizeof(md), ofs);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sum the bytes in data to data + size - 2. The last two bytes are ignored
|
||||
* because that is where the checksum is stored.
|
||||
|
@ -157,7 +230,7 @@ static void restore_main_menu_data(s32 srcSlot) {
|
|||
bcopy(&gSaveBuffer.menuData[srcSlot], &gSaveBuffer.menuData[destSlot], sizeof(gSaveBuffer.menuData[destSlot]));
|
||||
|
||||
// Write destination data to EEPROM
|
||||
write_eeprom_data(&gSaveBuffer.menuData[destSlot], sizeof(gSaveBuffer.menuData[destSlot]));
|
||||
write_eeprom_menudata(destSlot, 1);
|
||||
}
|
||||
|
||||
static void save_main_menu_data(void) {
|
||||
|
@ -169,7 +242,7 @@ static void save_main_menu_data(void) {
|
|||
bcopy(&gSaveBuffer.menuData[0], &gSaveBuffer.menuData[1], sizeof(gSaveBuffer.menuData[1]));
|
||||
|
||||
// Write to EEPROM
|
||||
write_eeprom_data(gSaveBuffer.menuData, sizeof(gSaveBuffer.menuData));
|
||||
write_eeprom_menudata(0, 2);
|
||||
|
||||
gMainMenuDataModified = FALSE;
|
||||
}
|
||||
|
@ -245,8 +318,35 @@ static void restore_save_file_data(s32 fileIndex, s32 srcSlot) {
|
|||
sizeof(gSaveBuffer.files[fileIndex][destSlot]));
|
||||
|
||||
// Write destination data to EEPROM
|
||||
write_eeprom_data(&gSaveBuffer.files[fileIndex][destSlot],
|
||||
sizeof(gSaveBuffer.files[fileIndex][destSlot]));
|
||||
write_eeprom_savefile(fileIndex, destSlot, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the 'EEPROM' save has different endianness (e.g. it's from an actual N64).
|
||||
*/
|
||||
static u8 save_file_need_bswap(const struct SaveBuffer *buf) {
|
||||
// check all signatures just in case
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (buf->menuData[i].signature.magic == BSWAP16(MENU_DATA_MAGIC))
|
||||
return TRUE;
|
||||
for (int j = 0; j < NUM_SAVE_FILES; ++j) {
|
||||
if (buf->files[j][i].signature.magic == BSWAP16(SAVE_FILE_MAGIC))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Byteswap all multibyte fields in a SaveBuffer.
|
||||
*/
|
||||
static void save_file_bswap(struct SaveBuffer *buf) {
|
||||
bswap_menudata(buf->menuData + 0);
|
||||
bswap_menudata(buf->menuData + 1);
|
||||
for (int i = 0; i < NUM_SAVE_FILES; ++i) {
|
||||
bswap_savefile(buf->files[i] + 0);
|
||||
bswap_savefile(buf->files[i] + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void save_file_do_save(s32 fileIndex) {
|
||||
|
@ -260,7 +360,7 @@ void save_file_do_save(s32 fileIndex) {
|
|||
sizeof(gSaveBuffer.files[fileIndex][1]));
|
||||
|
||||
// Write to EEPROM
|
||||
write_eeprom_data(gSaveBuffer.files[fileIndex], sizeof(gSaveBuffer.files[fileIndex]));
|
||||
write_eeprom_savefile(fileIndex, 0, 2);
|
||||
|
||||
gSaveFileModified = FALSE;
|
||||
}
|
||||
|
@ -298,6 +398,9 @@ void save_file_load_all(void) {
|
|||
bzero(&gSaveBuffer, sizeof(gSaveBuffer));
|
||||
read_eeprom_data(&gSaveBuffer, sizeof(gSaveBuffer));
|
||||
|
||||
if (save_file_need_bswap(&gSaveBuffer))
|
||||
save_file_bswap(&gSaveBuffer);
|
||||
|
||||
// Verify the main menu data and create a backup copy if only one of the slots is valid.
|
||||
validSlots = verify_save_block_signature(&gSaveBuffer.menuData[0], sizeof(gSaveBuffer.menuData[0]), MENU_DATA_MAGIC);
|
||||
validSlots |= verify_save_block_signature(&gSaveBuffer.menuData[1], sizeof(gSaveBuffer.menuData[1]),MENU_DATA_MAGIC) << 1;
|
||||
|
|
|
@ -241,13 +241,10 @@ int render_screen_transition(s8 fadeTimer, s8 transType, u8 transTime, struct Wa
|
|||
}
|
||||
|
||||
Gfx *render_cannon_circle_base(void) {
|
||||
#ifdef TARGET_N64
|
||||
Vtx *verts = alloc_display_list(4 * sizeof(*verts));
|
||||
Gfx *dlist = alloc_display_list(16 * sizeof(*dlist));
|
||||
#else
|
||||
|
||||
Vtx *verts = alloc_display_list(8 * sizeof(*verts));
|
||||
Gfx *dlist = alloc_display_list(20 * sizeof(*dlist));
|
||||
#endif
|
||||
|
||||
Gfx *g = dlist;
|
||||
|
||||
if (verts != NULL && dlist != NULL) {
|
||||
|
@ -256,12 +253,10 @@ Gfx *render_cannon_circle_base(void) {
|
|||
make_vertex(verts, 2, SCREEN_WIDTH, SCREEN_HEIGHT, -1, 1152, 192, 0, 0, 0, 255);
|
||||
make_vertex(verts, 3, 0, SCREEN_HEIGHT, -1, -1152, 192, 0, 0, 0, 255);
|
||||
|
||||
#ifndef TARGET_N64
|
||||
make_vertex(verts, 4, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), 0, -1, 0, 0, 0, 0, 0, 255);
|
||||
make_vertex(verts, 5, GFX_DIMENSIONS_FROM_RIGHT_EDGE(0), 0, -1, 0, 0, 0, 0, 0, 255);
|
||||
make_vertex(verts, 6, GFX_DIMENSIONS_FROM_RIGHT_EDGE(0), SCREEN_HEIGHT, -1, 0, 0, 0, 0, 0, 255);
|
||||
make_vertex(verts, 7, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), SCREEN_HEIGHT, -1, 0, 0, 0, 0, 0, 255);
|
||||
#endif
|
||||
|
||||
gSPDisplayList(g++, dl_proj_mtx_fullscreen);
|
||||
gDPSetCombineMode(g++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA);
|
||||
|
@ -272,12 +267,12 @@ Gfx *render_cannon_circle_base(void) {
|
|||
gSPVertex(g++, VIRTUAL_TO_PHYSICAL(verts), 4, 0);
|
||||
gSPDisplayList(g++, dl_draw_quad_verts_0123);
|
||||
gSPTexture(g++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF);
|
||||
#ifndef TARGET_N64
|
||||
|
||||
gDPSetCombineMode(g++, G_CC_SHADE, G_CC_SHADE);
|
||||
gSPVertex(g++, VIRTUAL_TO_PHYSICAL(verts + 4), 4, 4);
|
||||
gSP2Triangles(g++, 4, 0, 3, 0, 4, 3, 7, 0);
|
||||
gSP2Triangles(g++, 1, 5, 6, 0, 1, 6, 2, 0);
|
||||
#endif
|
||||
|
||||
gSPDisplayList(g++, dl_screen_transition_end);
|
||||
gSPEndDisplayList(g);
|
||||
} else {
|
||||
|
|
|
@ -242,7 +242,6 @@ void *create_skybox_ortho_matrix(s8 player) {
|
|||
f32 top = sSkyBoxInfo[player].scaledY;
|
||||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
|
||||
#ifndef TARGET_N64
|
||||
f32 half_width = (4.0f / 3.0f) / GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_WIDTH / 2;
|
||||
f32 center = (sSkyBoxInfo[player].scaledX + SCREEN_WIDTH / 2);
|
||||
if (half_width < SCREEN_WIDTH / 2) {
|
||||
|
@ -250,7 +249,6 @@ void *create_skybox_ortho_matrix(s8 player) {
|
|||
left = center - half_width;
|
||||
right = center + half_width;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mtx != NULL) {
|
||||
guOrtho(mtx, left, right, bottom, top, 0.0f, 3.0f, 1.0f);
|
||||
|
|
|
@ -28,15 +28,9 @@
|
|||
#define MAX_GD_DLS 1000
|
||||
#define OS_MESG_SI_COMPLETE 0x33333333
|
||||
|
||||
#ifdef TARGET_N64
|
||||
#define GD_VIRTUAL_TO_PHYSICAL(addr) ((uintptr_t)(addr) &0x0FFFFFFF)
|
||||
#define GD_LOWER_24(addr) ((uintptr_t)(addr) &0x00FFFFFF)
|
||||
#define GD_LOWER_29(addr) (((uintptr_t)(addr)) & 0x1FFFFFFF)
|
||||
#else
|
||||
#define GD_VIRTUAL_TO_PHYSICAL(addr) (addr)
|
||||
#define GD_LOWER_24(addr) ((uintptr_t)(addr))
|
||||
#define GD_LOWER_29(addr) (((uintptr_t)(addr)))
|
||||
#endif
|
||||
|
||||
#define MTX_INTPART_PACK(w1, w2) (((w1) &0xFFFF0000) | (((w2) >> 16) & 0xFFFF))
|
||||
#define MTX_FRACPART_PACK(w1, w2) ((((w1) << 16) & 0xFFFF0000) | ((w2) &0xFFFF))
|
||||
|
@ -1692,27 +1686,9 @@ u32 Unknown8019EC88(Gfx *dl, UNUSED s32 arg1) {
|
|||
|
||||
/* 24D4C4 -> 24D63C; orig name: func_8019ECF4 */
|
||||
void mat4_to_mtx(const Mat4f *src, Mtx *dst) {
|
||||
#ifdef TARGET_N64
|
||||
s32 i; // 14
|
||||
s32 j; // 10
|
||||
s32 w1;
|
||||
s32 w2;
|
||||
s32 *mtxInt = (s32 *) dst->m[0]; // s32 part
|
||||
s32 *mtxFrc = (s32 *) dst->m[2]; // frac part
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
w1 = (s32)((*src)[i][j * 2] * 65536.0f);
|
||||
w2 = (s32)((*src)[i][j * 2 + 1] * 65536.0f);
|
||||
*mtxInt = MTX_INTPART_PACK(w1, w2);
|
||||
mtxInt++;
|
||||
*mtxFrc = MTX_FRACPART_PACK(w1, w2);
|
||||
mtxFrc++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
guMtxF2L(src, dst);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* 24D63C -> 24D6E4; orig name: func_8019EE6C */
|
||||
|
@ -3634,89 +3610,9 @@ void Unknown801A6E30(UNUSED u32 a0) {
|
|||
void Unknown801A6E44(UNUSED u32 a0) {
|
||||
}
|
||||
|
||||
#ifdef TARGET_N64
|
||||
/* 255628 -> 255704; orig name: func_801A6E58 */
|
||||
void gd_block_dma(u32 devAddr, void *vAddr, s32 size) {
|
||||
s32 transfer; // 2c
|
||||
|
||||
do {
|
||||
if ((transfer = size) > 0x1000) {
|
||||
transfer = 0x1000;
|
||||
}
|
||||
|
||||
osPiStartDma(&D_801BE980, OS_MESG_PRI_NORMAL, OS_READ, devAddr, vAddr, transfer, &sGdDMAQueue);
|
||||
osRecvMesg(&sGdDMAQueue, &D_801BE97C, OS_MESG_BLOCK);
|
||||
devAddr += transfer;
|
||||
vAddr = (void *) ((uintptr_t) vAddr + transfer);
|
||||
size -= 0x1000;
|
||||
} while (size > 0);
|
||||
}
|
||||
|
||||
/* 255704 -> 255988 */
|
||||
struct GdObj *load_dynlist(struct DynList *dynlist) {
|
||||
u32 segSize; // 4c
|
||||
u8 *allocSegSpace; // 48
|
||||
void *allocPtr; // 44
|
||||
uintptr_t dynlistSegStart; // 40
|
||||
uintptr_t dynlistSegEnd; // 3c
|
||||
s32 i; // 38
|
||||
s32 sp34; // tlbPage
|
||||
struct GdObj *loadedList; // 30
|
||||
|
||||
i = -1;
|
||||
|
||||
while (sDynLists[++i].list != NULL) {
|
||||
if (sDynLists[i].list == dynlist) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sDynLists[i].list == NULL) {
|
||||
fatal_printf("load_dynlist() ptr not found in any banks");
|
||||
}
|
||||
|
||||
switch (sDynLists[i].flag) {
|
||||
case STD_LIST_BANK:
|
||||
dynlistSegStart = (uintptr_t) _gd_dynlistsSegmentRomStart;
|
||||
dynlistSegEnd = (uintptr_t) _gd_dynlistsSegmentRomEnd;
|
||||
break;
|
||||
default:
|
||||
fatal_printf("load_dynlist() unkown bank");
|
||||
}
|
||||
|
||||
segSize = dynlistSegEnd - dynlistSegStart;
|
||||
allocSegSpace = gd_malloc_temp(segSize + 0x10000);
|
||||
|
||||
if ((allocPtr = (void *) allocSegSpace) == NULL) {
|
||||
fatal_printf("Not enough DRAM for DATA segment \n");
|
||||
}
|
||||
|
||||
allocSegSpace = (u8 *) (((uintptr_t) allocSegSpace + 0x10000) & 0xFFFF0000);
|
||||
gd_block_dma(dynlistSegStart, (void *) allocSegSpace, segSize);
|
||||
osUnmapTLBAll();
|
||||
|
||||
sp34 = (segSize / 0x10000) / 2 + 1; //? has to be written this way
|
||||
if (sp34 >= 31) {
|
||||
fatal_printf("load_dynlist() too many TLBs");
|
||||
}
|
||||
|
||||
for (i = 0; i < sp34; i++) {
|
||||
osMapTLB(i, OS_PM_64K, (void *) (uintptr_t) (0x04000000 + (i * 2 * 0x10000)),
|
||||
GD_LOWER_24(((uintptr_t) allocSegSpace) + (i * 2 * 0x10000)),
|
||||
GD_LOWER_24(((uintptr_t) allocSegSpace) + (i * 2 * 0x10000) + 0x10000), -1);
|
||||
}
|
||||
|
||||
loadedList = proc_dynlist(dynlist);
|
||||
gd_free(allocPtr);
|
||||
osUnmapTLBAll();
|
||||
|
||||
return loadedList;
|
||||
}
|
||||
#else
|
||||
struct GdObj *load_dynlist(struct DynList *dynlist) {
|
||||
return proc_dynlist(dynlist);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 255988 -> 25599C */
|
||||
void stub_801A71B8(UNUSED u32 a0) {
|
||||
|
|
|
@ -303,9 +303,7 @@ void convert_gd_verts_to_Vn(struct ObjGroup *grp) {
|
|||
u8 nx, ny, nz; // 24, 25, 26
|
||||
UNUSED u32 pad20;
|
||||
register struct VtxLink *vtxlink; // a1
|
||||
#ifdef TARGET_N64
|
||||
register s16 *vnPos; // a2
|
||||
#endif
|
||||
|
||||
register s16 x; // a3
|
||||
register s16 y; // t0
|
||||
register s16 z; // t1
|
||||
|
@ -325,18 +323,12 @@ void convert_gd_verts_to_Vn(struct ObjGroup *grp) {
|
|||
nz = (u8)(vtx->normal.z * 255.0f);
|
||||
|
||||
for (vtxlink = vtx->gbiVerts; vtxlink != NULL; vtxlink = vtxlink->prev) {
|
||||
#ifdef TARGET_N64
|
||||
vnPos = vtxlink->data->n.ob;
|
||||
vn = vtxlink->data;
|
||||
*vnPos++ = x;
|
||||
*vnPos++ = y;
|
||||
*vnPos++ = z;
|
||||
#else
|
||||
|
||||
vn = vtxlink->data;
|
||||
vn->n.ob[0] = x;
|
||||
vn->n.ob[1] = y;
|
||||
vn->n.ob[2] = z;
|
||||
#endif
|
||||
|
||||
vn->n.n[0] = nx;
|
||||
vn->n.n[1] = ny;
|
||||
vn->n.n[2] = nz;
|
||||
|
@ -348,9 +340,7 @@ void convert_gd_verts_to_Vn(struct ObjGroup *grp) {
|
|||
void convert_gd_verts_to_Vtx(struct ObjGroup *grp) {
|
||||
UNUSED u32 pad24[6];
|
||||
register struct VtxLink *vtxlink; // a1
|
||||
#ifdef TARGET_N64
|
||||
register s16 *vtxcoords; // a2
|
||||
#endif
|
||||
|
||||
register s16 x; // a3
|
||||
register s16 y; // t0
|
||||
register s16 z; // t1
|
||||
|
@ -366,16 +356,10 @@ void convert_gd_verts_to_Vtx(struct ObjGroup *grp) {
|
|||
z = (s16) vtx->pos.z;
|
||||
|
||||
for (vtxlink = vtx->gbiVerts; vtxlink != NULL; vtxlink = vtxlink->prev) {
|
||||
#ifdef TARGET_N64
|
||||
vtxcoords = vtxlink->data->v.ob;
|
||||
vtxcoords[0] = x;
|
||||
vtxcoords[1] = y;
|
||||
vtxcoords[2] = z;
|
||||
#else
|
||||
|
||||
vtxlink->data->v.ob[0] = x;
|
||||
vtxlink->data->v.ob[1] = y;
|
||||
vtxlink->data->v.ob[2] = z;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ struct AudioAPI {
|
|||
int (*buffered)(void);
|
||||
int (*get_desired_buffered)(void);
|
||||
void (*play)(const uint8_t *buf, size_t len);
|
||||
void (*shutdown)(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,9 +15,13 @@ static int audio_null_get_desired_buffered(void) {
|
|||
static void audio_null_play(const uint8_t *buf, size_t len) {
|
||||
}
|
||||
|
||||
static void audio_null_shutdown(void) {
|
||||
}
|
||||
|
||||
struct AudioAPI audio_null = {
|
||||
audio_null_init,
|
||||
audio_null_buffered,
|
||||
audio_null_get_desired_buffered,
|
||||
audio_null_play
|
||||
};
|
||||
audio_null_play,
|
||||
audio_null_shutdown
|
||||
};
|
|
@ -40,9 +40,21 @@ static void audio_sdl_play(const uint8_t *buf, size_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
static void audio_sdl_shutdown(void)
|
||||
{
|
||||
if (SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
if (dev != 0) {
|
||||
SDL_CloseAudioDevice(dev);
|
||||
dev = 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_play,
|
||||
audio_sdl_shutdown
|
||||
};
|
|
@ -1,5 +1,7 @@
|
|||
#include "cliopts.h"
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct PCCLIOptions gCLIOpts;
|
||||
|
||||
|
@ -8,6 +10,8 @@ void parse_cli_opts(int argc, char* argv[])
|
|||
// Initialize options with false values.
|
||||
gCLIOpts.SkipIntro = 0;
|
||||
gCLIOpts.FullScreen = 0;
|
||||
gCLIOpts.ConfigFile = malloc(31);
|
||||
strncpy(gCLIOpts.ConfigFile, "sm64config.txt", strlen("sm64config.txt"));
|
||||
|
||||
// Scan arguments for options
|
||||
if (argc > 1)
|
||||
|
@ -20,6 +24,19 @@ void parse_cli_opts(int argc, char* argv[])
|
|||
|
||||
if (strcmp(argv[i], "--fullscreen") == 0) // Open game in fullscreen
|
||||
gCLIOpts.FullScreen = 1;
|
||||
|
||||
if (strncmp(argv[i], "--configfile", strlen("--configfile")) == 0)
|
||||
{
|
||||
if (i+1 < argc)
|
||||
{
|
||||
if (strlen(argv[i]) > 30) {
|
||||
fprintf(stderr, "Configuration file supplied has a name too long.\n");
|
||||
} else {
|
||||
memset(gCLIOpts.ConfigFile, 0, 30);
|
||||
strncpy(gCLIOpts.ConfigFile, argv[i+1], strlen(argv[i+1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ struct PCCLIOptions
|
|||
{
|
||||
u8 SkipIntro;
|
||||
u8 FullScreen;
|
||||
char * ConfigFile;
|
||||
};
|
||||
|
||||
extern struct PCCLIOptions gCLIOpts;
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define CONFIG_FILE "sm64config.txt"
|
||||
|
||||
#define MAX_BINDS 3
|
||||
#define MAX_VOLUME 127
|
||||
#define VOLUME_SHIFT 7
|
||||
|
|
|
@ -13,10 +13,14 @@ struct ControllerAPI {
|
|||
void (*read)(OSContPad *pad); // read controller and update N64 pad values
|
||||
u32 (*rawkey)(void); // returns last pressed virtual key or VK_INVALID if none
|
||||
void (*reconfig)(void); // (optional) call when bindings have changed
|
||||
void (*shutdown)(void); // (optional) call in osContReset
|
||||
};
|
||||
|
||||
// used for binding keys
|
||||
u32 controller_get_raw_key(void);
|
||||
void controller_reconfigure(void);
|
||||
|
||||
// calls the shutdown() function of all controller subsystems
|
||||
void controller_shutdown(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -65,6 +65,13 @@ u32 controller_get_raw_key(void) {
|
|||
return VK_INVALID;
|
||||
}
|
||||
|
||||
void controller_shutdown(void) {
|
||||
for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++) {
|
||||
if (controller_implementations[i]->shutdown)
|
||||
controller_implementations[i]->shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
void controller_reconfigure(void) {
|
||||
for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++) {
|
||||
if (controller_implementations[i]->reconfig)
|
||||
|
|
|
@ -107,10 +107,14 @@ static u32 keyboard_rawkey(void) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void keyboard_shutdown(void) {
|
||||
}
|
||||
|
||||
struct ControllerAPI controller_keyboard = {
|
||||
VK_BASE_KEYBOARD,
|
||||
keyboard_init,
|
||||
keyboard_read,
|
||||
keyboard_rawkey,
|
||||
keyboard_bindkeys,
|
||||
keyboard_shutdown
|
||||
};
|
||||
|
|
|
@ -23,6 +23,13 @@ static void tas_read(OSContPad *pad) {
|
|||
}
|
||||
}
|
||||
|
||||
static void tas_shutdown(void) {
|
||||
if (fp != NULL) {
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 tas_rawkey(void) {
|
||||
return VK_INVALID;
|
||||
}
|
||||
|
@ -33,4 +40,5 @@ struct ControllerAPI controller_recorded_tas = {
|
|||
tas_read,
|
||||
tas_rawkey,
|
||||
NULL, // no rebinding
|
||||
tas_shutdown
|
||||
};
|
||||
|
|
|
@ -204,10 +204,22 @@ static u32 controller_sdl_rawkey(void) {
|
|||
return VK_INVALID;
|
||||
}
|
||||
|
||||
static void controller_sdl_shutdown(void) {
|
||||
if (SDL_WasInit(SDL_INIT_GAMECONTROLLER)) {
|
||||
if (sdl_cntrl) {
|
||||
SDL_GameControllerClose(sdl_cntrl);
|
||||
sdl_cntrl = NULL;
|
||||
}
|
||||
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||
}
|
||||
init_ok = false;
|
||||
}
|
||||
|
||||
struct ControllerAPI controller_sdl = {
|
||||
VK_BASE_SDL_GAMEPAD,
|
||||
controller_sdl_init,
|
||||
controller_sdl_read,
|
||||
controller_sdl_rawkey,
|
||||
controller_sdl_bind,
|
||||
controller_sdl_shutdown
|
||||
};
|
||||
|
|
|
@ -501,6 +501,9 @@ static void gfx_opengl_start_frame(void) {
|
|||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
static void gfx_opengl_shutdown(void) {
|
||||
}
|
||||
|
||||
struct GfxRenderingAPI gfx_opengl_api = {
|
||||
gfx_opengl_z_is_from_0_to_1,
|
||||
gfx_opengl_unload_shader,
|
||||
|
@ -520,5 +523,6 @@ struct GfxRenderingAPI gfx_opengl_api = {
|
|||
gfx_opengl_set_use_alpha,
|
||||
gfx_opengl_draw_triangles,
|
||||
gfx_opengl_init,
|
||||
gfx_opengl_start_frame
|
||||
gfx_opengl_start_frame,
|
||||
gfx_opengl_shutdown
|
||||
};
|
||||
|
|
|
@ -571,10 +571,16 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
|
|||
calculate_normal_dir(&lookat_y, rsp.current_lookat_coeffs[1]);
|
||||
rsp.lights_changed = false;
|
||||
}
|
||||
|
||||
int r = rsp.current_lights[rsp.current_num_lights - 1].col[0];
|
||||
int g = rsp.current_lights[rsp.current_num_lights - 1].col[1];
|
||||
int b = rsp.current_lights[rsp.current_num_lights - 1].col[2];
|
||||
|
||||
// Inspired by:
|
||||
// https://github.com/gonetz/GLideN64/commit/c8cbafff71a81bee5112aaafe6e21d6648ff8125#diff-69d8715ec7f9fd627ec4f5516edd003dL484
|
||||
const bool useFirstColor = (dest_index & 1) == 0;
|
||||
const unsigned char* col = useFirstColor
|
||||
? rsp.current_lights[rsp.current_num_lights - 1].col
|
||||
: rsp.current_lights[rsp.current_num_lights - 1].colc;
|
||||
int r = col[0];
|
||||
int g = col[1];
|
||||
int b = col[2];
|
||||
|
||||
for (int i = 0; i < rsp.current_num_lights - 1; i++) {
|
||||
float intensity = 0;
|
||||
|
@ -583,9 +589,14 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
|
|||
intensity += vn->n[2] * rsp.current_lights_coeffs[i][2];
|
||||
intensity /= 127.0f;
|
||||
if (intensity > 0.0f) {
|
||||
r += intensity * rsp.current_lights[i].col[0];
|
||||
g += intensity * rsp.current_lights[i].col[1];
|
||||
b += intensity * rsp.current_lights[i].col[2];
|
||||
// Inspired by:
|
||||
// https://github.com/gonetz/GLideN64/commit/c8cbafff71a81bee5112aaafe6e21d6648ff8125#diff-69d8715ec7f9fd627ec4f5516edd003dL492
|
||||
col = useFirstColor
|
||||
? rsp.current_lights[i].col
|
||||
: rsp.current_lights[i].colc;
|
||||
r += intensity * col[0];
|
||||
g += intensity * col[1];
|
||||
b += intensity * col[2];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1547,3 +1558,14 @@ void gfx_end_frame(void) {
|
|||
gfx_wapi->swap_buffers_end();
|
||||
}
|
||||
}
|
||||
|
||||
void gfx_shutdown(void) {
|
||||
if (gfx_rapi) {
|
||||
if (gfx_rapi->shutdown) gfx_rapi->shutdown();
|
||||
gfx_rapi = NULL;
|
||||
}
|
||||
if (gfx_wapi) {
|
||||
if (gfx_wapi->shutdown) gfx_wapi->shutdown();
|
||||
gfx_wapi = NULL;
|
||||
}
|
||||
}
|
|
@ -15,5 +15,6 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi);
|
|||
void gfx_start_frame(void);
|
||||
void gfx_run(Gfx *commands);
|
||||
void gfx_end_frame(void);
|
||||
void gfx_shutdown(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,6 +27,7 @@ struct GfxRenderingAPI {
|
|||
void (*draw_triangles)(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris);
|
||||
void (*init)(void);
|
||||
void (*start_frame)(void);
|
||||
void (*shutdown)(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "src/pc/controller/controller_keyboard.h"
|
||||
|
||||
static SDL_Window *wnd;
|
||||
static SDL_GLContext ctx = NULL;
|
||||
static int inverted_scancode_table[512];
|
||||
|
||||
static bool cur_fullscreen;
|
||||
|
@ -241,6 +242,15 @@ static double gfx_sdl_get_time(void) {
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
static void gfx_sdl_shutdown(void) {
|
||||
if (SDL_WasInit(0)) {
|
||||
if (ctx) { SDL_GL_DeleteContext(ctx); ctx = NULL; }
|
||||
if (wnd) { SDL_DestroyWindow(wnd); wnd = NULL; }
|
||||
SDL_Quit();
|
||||
}
|
||||
}
|
||||
|
||||
struct GfxWindowManagerAPI gfx_sdl = {
|
||||
gfx_sdl_init,
|
||||
gfx_sdl_main_loop,
|
||||
|
@ -249,5 +259,6 @@ struct GfxWindowManagerAPI gfx_sdl = {
|
|||
gfx_sdl_start_frame,
|
||||
gfx_sdl_swap_buffers_begin,
|
||||
gfx_sdl_swap_buffers_end,
|
||||
gfx_sdl_get_time
|
||||
gfx_sdl_get_time,
|
||||
gfx_sdl_shutdown
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@ struct GfxWindowManagerAPI {
|
|||
void (*swap_buffers_begin)(void);
|
||||
void (*swap_buffers_end)(void);
|
||||
double (*get_time)(void); // For debug
|
||||
void (*shutdown)(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "cliopts.h"
|
||||
#include "configfile.h"
|
||||
#include "controller/controller_api.h"
|
||||
|
||||
OSMesg D_80339BEC;
|
||||
OSMesgQueue gSIEventMesgQueue;
|
||||
|
@ -84,6 +85,20 @@ void produce_one_frame(void) {
|
|||
gfx_end_frame();
|
||||
}
|
||||
|
||||
void audio_shutdown(void) {
|
||||
if (audio_api) {
|
||||
if (audio_api->shutdown) audio_api->shutdown();
|
||||
audio_api = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void game_shutdown(void) {
|
||||
configfile_save(gCLIOpts.ConfigFile);;
|
||||
controller_shutdown();
|
||||
audio_shutdown();
|
||||
gfx_shutdown();
|
||||
}
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
static void em_main_loop(void) {
|
||||
}
|
||||
|
@ -117,17 +132,13 @@ static void on_anim_frame(double time) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static void save_config(void) {
|
||||
configfile_save(CONFIG_FILE);
|
||||
}
|
||||
|
||||
void main_func(void) {
|
||||
static u64 pool[0x165000/8 / 4 * sizeof(void *)];
|
||||
main_pool_init(pool, pool + sizeof(pool) / sizeof(pool[0]));
|
||||
gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT);
|
||||
|
||||
configfile_load(CONFIG_FILE);
|
||||
atexit(save_config);
|
||||
configfile_load(gCLIOpts.ConfigFile);
|
||||
atexit(game_shutdown);
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
emscripten_set_main_loop(em_main_loop, 0, 0);
|
||||
|
|
Loading…
Reference in a new issue