diff --git a/.gitignore b/.gitignore index 06cc002..2f56ceb 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,10 @@ *.ilk *.exp +# Patch and wiggle related residdue +*.rej +*.porig + # Precompiled Headers *.gch *.pch diff --git a/Dockerfile b/Dockerfile index dbc31e2..a4344f2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,11 +5,14 @@ RUN apt-get update && \ binutils-mips-linux-gnu \ bsdmainutils \ build-essential \ + git \ libaudiofile-dev \ + libsdl2-dev \ pkg-config \ python3 \ wget \ - zlib1g-dev + zlib1g-dev && \ + rm -rf /var/lib/apt/lists/* RUN wget \ https://github.com/n64decomp/qemu-irix/releases/download/v2.11-deb/qemu-irix-2.11.0-2169-g32ab296eef_amd64.deb \ @@ -18,9 +21,16 @@ RUN wget \ dpkg -i qemu.deb && \ rm qemu.deb +RUN cd /tmp && \ + git clone https://github.com/emscripten-core/emsdk.git && \ + cd emsdk && \ + ./emsdk install latest && \ + cd .. && \ + rm -rf emsdk + RUN mkdir /sm64 WORKDIR /sm64 -ENV PATH="/sm64/tools:${PATH}" +ENV PATH="/sm64/tools:/emsdk:${PATH}" CMD echo 'usage: docker run --rm --mount type=bind,source="$(pwd)",destination=/sm64 sm64 make VERSION=${VERSION:-us} -j4\n' \ 'see https://github.com/n64decomp/sm64/blob/master/README.md for advanced usage' diff --git a/README.md b/README.md index 32cd8b6..180f12f 100644 --- a/README.md +++ b/README.md @@ -61,11 +61,67 @@ Run `make` to build (defaults to `VERSION=us`) ``` make VERSION=jp -j6 # build (J) version with 6 jobs make VERSION=us WINDOWS_BUILD=1 # builds a (U) Windows executable +make TARGET_RPI=1 # targets an executable for a Raspberry Pi ``` ### On Windows -A full guide is to be written. You can use [mxe](https://mxe.cc/) and MinGW. +#### 1. Set up MSYS2, following [this guide](https://github.com/orlp/dev-on-windows/wiki/Installing-GCC--&-MSYS2). + +#### 2. Install dependencies +``` +pacman -S mingw-w64-i686-glew mingw-w64-x86_64-glew mingw-w64-i686-SDL2 mingw-w64-x86_64-SDL2 python3 +``` +#### 3. Copy baserom(s) for asset extraction + +For each version (jp/us/eu) that you want to build an executable for, put an existing ROM at +`./baserom..z64` for asset extraction. + +#### 4. On MSYS2, navigate to the sm64pc folder and then enter `./tools/audiofile-0.3.6/`. Inside this directory, run +``` +autoreconf -i +``` + +Only leave this directory on step 9. + +#### 5. Run the `configure` script +``` +PATH=/mingw64/bin:/mingw32/bin:$PATH LIBS=-lstdc++ ./configure --disable-docs +``` +#### 6. Run the `make` script +``` +PATH=/mingw64/bin:/mingw32/bin:$PATH make +``` +#### 7. Create a lib directory in `tools/` +``` +mkdir ../lib +``` + +#### 8. Copy the compiled libaudiofile to `tools/lib/` +``` +cp libaudiofile/.libs/libaudiofile.a ../lib/ +cp libaudiofile/.libs/libaudiofile.la ../lib/ +``` + +#### 9. Navigate back to `tools/`, then alter the `Makefile` and add `-lstdc++` on the following line +``` +tabledesign_CFLAGS := -Wno-uninitialized -laudiofile -lstdc++ +``` + +#### 10. Run `make` +``` +PATH=/mingw64/bin:/mingw32/bin:$PATH make +``` + +#### 11. Navigate back to the sm64pc root directory. + +#### 12. Finally, run `make` once more. + +(Note that mingw32 and mingw64 have been swapped. This is so you can build the 32bit application successfully.) + +``` +PATH=/mingw32/bin:/mingw64/bin:$PATH make +``` ### For the web diff --git a/enhancements/L-trigger-mapping/README.md b/enhancements/L-trigger-mapping/README.md new file mode 100644 index 0000000..0538f09 --- /dev/null +++ b/enhancements/L-trigger-mapping/README.md @@ -0,0 +1,12 @@ +# L-trigger mapping + +Some parts of the code might require the pressing of the L-trigger for testing reasons. + +If you need that, alter `controller_sdl.c`. +In the following line: +``` + if (SDL_GameControllerGetButton(sdl_cntrl, SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) pad->button |= Z_TRIG; +``` +Replace `Z_TRIG` with `L_TRIG`, save and rebuild. + +On a DS4, this now means that Z-trigger will be mapped to L2 and the L-trigger to L1. diff --git a/levels/menu/script.c b/levels/menu/script.c index 46cd066..5a9d3e4 100644 --- a/levels/menu/script.c +++ b/levels/menu/script.c @@ -50,7 +50,7 @@ const LevelScript level_main_menu_entry_1[] = { GET_OR_SET(/*op*/ OP_SET, /*var*/ VAR_CURR_SAVE_FILE_NUM), STOP_MUSIC(/*fadeOutTime*/ 0x00BE), TRANSITION(/*transType*/ WARP_TRANSITION_FADE_INTO_COLOR, /*time*/ 16, /*color*/ 0xFF, 0xFF, 0xFF), - SLEEP(/*frames*/ 24), + SLEEP(/*frames*/ 16), CLEAR_LEVEL(), SLEEP_BEFORE_EXIT(/*frames*/ 1), SET_REG(/*value*/ LEVEL_CASTLE_GROUNDS), @@ -89,7 +89,7 @@ const LevelScript level_main_menu_entry_2[] = { /*35*/ GET_OR_SET(/*op*/ OP_SET, /*var*/ VAR_CURR_ACT_NUM), /*36*/ STOP_MUSIC(/*fadeOutTime*/ 0x00BE), /*37*/ TRANSITION(/*transType*/ WARP_TRANSITION_FADE_INTO_COLOR, /*time*/ 16, /*color*/ 0xFF, 0xFF, 0xFF), - /*39*/ SLEEP(/*frames*/ 24), + /*39*/ SLEEP(/*frames*/ 16), /*40*/ CLEAR_LEVEL(), /*41*/ SLEEP_BEFORE_EXIT(/*frames*/ 1), // L1: diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 10ff1e6..a2de665 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -34,6 +34,7 @@ bool configFullscreen = false; unsigned int configKeyA = 0x26; unsigned int configKeyB = 0x33; unsigned int configKeyStart = 0x39; +unsigned int configKeyL = 0x34; unsigned int configKeyR = 0x36; unsigned int configKeyZ = 0x25; unsigned int configKeyCUp = 0x148; @@ -51,6 +52,7 @@ static const struct ConfigOption options[] = { {.name = "key_a", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyA}, {.name = "key_b", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyB}, {.name = "key_start", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyStart}, + {.name = "key_l", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyL}, {.name = "key_r", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyR}, {.name = "key_z", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyZ}, {.name = "key_cup", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyCUp}, diff --git a/src/pc/configfile.h b/src/pc/configfile.h index ae9070b..7128aaa 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -5,6 +5,7 @@ extern bool configFullscreen; extern unsigned int configKeyA; extern unsigned int configKeyB; extern unsigned int configKeyStart; +extern unsigned int configKeyL; extern unsigned int configKeyR; extern unsigned int configKeyZ; extern unsigned int configKeyCUp; diff --git a/src/pc/controller/controller_keyboard.c b/src/pc/controller/controller_keyboard.c index a49b86a..87eaee0 100644 --- a/src/pc/controller/controller_keyboard.c +++ b/src/pc/controller/controller_keyboard.c @@ -11,7 +11,7 @@ static int keyboard_buttons_down; -static int keyboard_mapping[13][2]; +static int keyboard_mapping[14][2]; static int keyboard_map_scancode(int scancode) { int ret = 0; @@ -58,6 +58,7 @@ static void keyboard_init(void) { set_keyboard_mapping(i++, L_CBUTTONS, configKeyCLeft); set_keyboard_mapping(i++, D_CBUTTONS, configKeyCDown); set_keyboard_mapping(i++, R_CBUTTONS, configKeyCRight); + set_keyboard_mapping(i++, L_TRIG, configKeyL); set_keyboard_mapping(i++, R_TRIG, configKeyR); set_keyboard_mapping(i++, START_BUTTON, configKeyStart); diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c index 034d426..fb7f6a0 100644 --- a/src/pc/gfx/gfx_sdl2.c +++ b/src/pc/gfx/gfx_sdl2.c @@ -78,13 +78,29 @@ const SDL_Scancode scancode_rmapping_nonextended[][2] = { {SDL_SCANCODE_KP_MULTIPLY, SDL_SCANCODE_PRINTSCREEN} }; +static void gfx_sdl_set_fullscreen(bool fullscreen) +{ + if (fullscreen) + { + SDL_SetWindowFullscreen(wnd, SDL_WINDOW_FULLSCREEN_DESKTOP); + SDL_ShowCursor(SDL_DISABLE); + } + else + { + SDL_SetWindowFullscreen(wnd, 0); + SDL_ShowCursor(SDL_ENABLE); + } + + configFullscreen = fullscreen; +} + static void gfx_sdl_init(void) { SDL_Init(SDL_INIT_VIDEO); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - #ifdef TARGET_RPI + #ifdef USE_GLES SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); // These attributes allow for hardware acceleration on RPis. SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); @@ -93,22 +109,18 @@ static void gfx_sdl_init(void) { //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); - #ifndef TARGET_RPI - wnd = SDL_CreateWindow("Super Mario 64 PC-Port", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + #ifndef USE_GLES + wnd = SDL_CreateWindow("Super Mario 64 PC port (OpenGL)", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, DESIRED_SCREEN_WIDTH, DESIRED_SCREEN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); #else - wnd = SDL_CreateWindow("Super Mario 64 RPi (GLES2)", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + wnd = SDL_CreateWindow("Super Mario 64 PC port (OpenGL_ES2)", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, DESIRED_SCREEN_WIDTH, DESIRED_SCREEN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); #endif - if (configFullscreen) - { - SDL_SetWindowFullscreen(wnd, SDL_WINDOW_FULLSCREEN_DESKTOP); - SDL_ShowCursor(SDL_DISABLE); - } + gfx_sdl_set_fullscreen(configFullscreen); SDL_GL_CreateContext(wnd); - SDL_GL_SetSwapInterval(2); // TODO 0, 1 or 2 or remove this line + SDL_GL_SetSwapInterval(1); // We have a double buffered GL context, it makes no sense to want tearing. for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDL_Scancode); i++) { inverted_scancode_table[windows_scancode_table[i]] = i; @@ -156,24 +168,11 @@ static void gfx_sdl_onkeydown(int scancode) { if (state[SDL_SCANCODE_LALT] && state[SDL_SCANCODE_RETURN]) { - if (!configFullscreen) - { - SDL_SetWindowFullscreen(wnd, SDL_WINDOW_FULLSCREEN_DESKTOP); - SDL_ShowCursor(SDL_DISABLE); - } - else - { - SDL_SetWindowFullscreen(wnd, 0); - SDL_ShowCursor(SDL_ENABLE); - } - - configFullscreen = !configFullscreen; + gfx_sdl_set_fullscreen(!configFullscreen); } else if (state[SDL_SCANCODE_ESCAPE] && configFullscreen) { - SDL_SetWindowFullscreen(wnd, 0); - SDL_ShowCursor(SDL_ENABLE); - configFullscreen = false; + gfx_sdl_set_fullscreen(false); } }