diff --git a/README.md b/README.md index aee71d4f..8373870c 100644 --- a/README.md +++ b/README.md @@ -1,193 +1,5 @@ -# Super Mario 64 +# Movement Mastery -- This repo contains a full decompilation of Super Mario 64 (J), (U), (E), and (SH). -- Naming and documentation of the source code and data structures are in progress. +Movement Mastery is a SM64 ROM hack oriented towards speedrunners and other people loving the fast movement and precise control of mario. -It builds the following ROMs: - -* sm64.jp.z64 `sha1: 8a20a5c83d6ceb0f0506cfc9fa20d8f438cafe51` -* sm64.us.z64 `sha1: 9bef1128717f958171a4afac3ed78ee2bb4e86ce` -* sm64.eu.z64 `sha1: 4ac5721683d0e0b6bbb561b58a71740845dceea9` -* sm64.sh.z64 `sha1: 3f319ae697533a255a1003d09202379d78d5a2e0` - -This repo does not include all assets necessary for compiling the ROMs. -A prior copy of the game is required to extract the assets. - -## Quick Start (for Ubuntu) - -1. Install prerequisites: `sudo apt install -y build-essential git binutils-mips-linux-gnu python3` -2. Clone the repo from within Linux: `git clone https://github.com/n64decomp/sm64.git` -3. Place a Super Mario 64 ROM called `baserom..z64` into the project folder for asset extraction, where `VERSION` can be `us`, `jp`, `eu`, or `sh`. -4. Run `make` to build. Qualify the version through `make VERSION=`. Add `-j4` to improve build speed (hardware dependent). - -Ensure the repo path length does not exceed 255 characters. Long path names result in build errors. - -## Installation - -### Windows - -Install WSL and a distro of your choice following -[Windows Subsystem for Linux Installation Guide for Windows 10.](https://docs.microsoft.com/en-us/windows/wsl/install-win10) -We recommend either Debian or Ubuntu 18.04 Linux distributions under WSL. -Note: WSL1 does not currently support Ubuntu 20.04. - -Next, clone the SM64 repo from within the Linux shell: -`git clone https://github.com/n64decomp/sm64.git` - -Then continue following the directions in the [Linux](#linux) installation section below. - -### Linux - -There are 3 steps to set up a working build. - -#### Step 1: Install dependencies - -The build system has the following package requirements: - * binutils-mips - * capstone - * pkgconf - * python3 >= 3.6 - -Dependency installation instructions for common Linux distros are provided below: - -##### Debian / Ubuntu -To install build dependencies: -``` -sudo apt install -y binutils-mips-linux-gnu build-essential git libcapstone-dev pkgconf python3 -``` - -##### Arch Linux -To install build dependencies: -``` -sudo pacman -S base-devel capstone python -``` -Install the following AUR packages: -* [mips64-elf-binutils](https://aur.archlinux.org/packages/mips64-elf-binutils) (AUR) - - -##### Other Linux distributions - -Most modern Linux distributions should have equivalent packages to the other two listed above. -You may have to use a different version of GNU binutils. Listed below are fully compatible binutils -distributions with support in the makefile, and examples of distros that offer them: - -* `mips64-elf-` (Arch AUR) -* `mips-linux-gnu-` (Ubuntu and other Debian-based distros) -* `mips64-linux-gnu-` (RHEL/CentOS/Fedora) - -You may also use [Docker](#docker-installation) to handle installing an image with minimal dependencies. - -#### Step 2: Copy baserom(s) for asset extraction - -For each version (jp/us/eu/sh) for which you want to build a ROM, put an existing ROM at -`./baserom..z64` for asset extraction. - -##### Step 3: Build the ROM - -Run `make` to build the ROM (defaults to `VERSION=us`). -Other examples: -``` -make VERSION=jp -j4 # build (J) version instead with 4 jobs -make VERSION=eu COMPARE=0 # build (EU) version but do not compare ROM hashes -``` - -Resulting artifacts can be found in the `build` directory. - -The full list of configurable variables are listed below, with the default being the first listed: - -* ``VERSION``: ``us``, ``jp``, ``eu``, ``sh`` -* ``GRUCODE``: ``f3d_old``, ``f3d_new``, ``f3dex``, ``f3dex2``, ``f3dzex`` -* ``COMPARE``: ``1`` (compare ROM hash), ``0`` (do not compare ROM hash) -* ``NON_MATCHING``: Use functionally equivalent C implementations for non-matchings (Currently there aren't any non-matchings, but this will apply to iQue). Also will avoid instances of undefined behavior. -* ``CROSS``: Cross-compiler tool prefix (Example: ``mips64-elf-``). - -### macOS - -With macOS, you may either use Homebrew or [Docker](#docker-installation). - -#### Homebrew - -#### Step 1: Install dependencies -Install [Homebrew](https://brew.sh) and the following dependencies: -``` -brew update -brew install capstone coreutils make pkg-config tehzz/n64-dev/mips64-elf-binutils -``` - -#### Step 2: Copy baserom(s) for asset extraction - -For each version (jp/us/eu/sh) for which you want to build a ROM, put an existing ROM at -`./baserom..z64` for asset extraction. - -##### Step 3: Build the ROM - -Use Homebrew's GNU make because the version included with macOS is too old. - -``` -gmake VERSION=jp -j4 # build (J) version instead with 4 jobs -``` - -### Docker Installation - -#### Create Docker image - -After installing and starting Docker, create the docker image. This only needs to be done once. -``` -docker build -t sm64 . -``` - -#### Build - -To build, mount the local filesystem into the Docker container and build the ROM with `docker run sm64 make`. - -##### macOS example for (U): -``` -docker run --rm --mount type=bind,source="$(pwd)",destination=/sm64 sm64 make VERSION=us -j4 -``` - -##### Linux example for (U): -For a Linux host, Docker needs to be instructed which user should own the output files: -``` -docker run --rm --mount type=bind,source="$(pwd)",destination=/sm64 --user $UID:$GID sm64 make VERSION=us -j4 -``` - -Resulting artifacts can be found in the `build` directory. - -## Project Structure - - sm64 - ├── actors: object behaviors, geo layout, and display lists - ├── asm: handwritten assembly code, rom header - │ └── non_matchings: asm for non-matching sections - ├── assets: animation and demo data - │ ├── anims: animation data - │ └── demos: demo data - ├── bin: C files for ordering display lists and textures - ├── build: output directory - ├── data: behavior scripts, misc. data - ├── doxygen: documentation infrastructure - ├── enhancements: example source modifications - ├── include: header files - ├── levels: level scripts, geo layout, and display lists - ├── lib: SDK library code - ├── rsp: audio and Fast3D RSP assembly code - ├── sound: sequences, sound samples, and sound banks - ├── src: C source code for game - │ ├── audio: audio code - │ ├── buffers: stacks, heaps, and task buffers - │ ├── engine: script processing engines and utils - │ ├── game: behaviors and rest of game source - │ ├── goddard: Mario intro screen - │ └── menu: title screen and file, act, and debug level selection menus - ├── text: dialog, level names, act names - ├── textures: skybox and generic texture data - └── tools: build tools - -## Contributing - -Pull requests are welcome. For major changes, please open an issue first to -discuss what you would like to change. - -Run `clang-format` on your code to ensure it meets the project's coding standards. - -Official Discord: [discord.gg/DuYH3Fh](https://discord.gg/DuYH3Fh) +This repository is based on https://github.com/n64decomp/sm64 and is not meant to be shared in any way, shape or form. \ No newline at end of file diff --git a/asm/rom_header.s b/asm/rom_header.s index af8b9afd..9d04d32d 100644 --- a/asm/rom_header.s +++ b/asm/rom_header.s @@ -21,13 +21,13 @@ .word 0x00000000 /* Unknown */ .word 0x00000000 /* Unknown */ #ifdef VERSION_SH -.ascii "SUPERMARIO64 " /* Internal ROM name */ +.ascii "MOVEMENTMASTERY " /* Internal ROM name */ #else -.ascii "SUPER MARIO 64 " /* Internal ROM name */ +.ascii "MOVEMENT MASTERY " /* Internal ROM name */ #endif .word 0x00000000 /* Unknown */ .word 0x0000004E /* Cartridge */ -.ascii "SM" /* Cartridge ID */ +.ascii "MM" /* Cartridge ID */ /* Region */ #ifdef VERSION_EU diff --git a/include/PR/ultratypes.h b/include/PR/ultratypes.h index 8a00490a..43e98e92 100644 --- a/include/PR/ultratypes.h +++ b/include/PR/ultratypes.h @@ -8,6 +8,8 @@ #define TRUE 1 #define FALSE 0 +typedef signed char bool; + typedef signed char s8; typedef unsigned char u8; typedef signed short int s16; diff --git a/levels/entry.c b/levels/entry.c index 17c773ed..eea1adef 100644 --- a/levels/entry.c +++ b/levels/entry.c @@ -12,6 +12,7 @@ const LevelScript level_script_entry[] = { SLEEP(/*frames*/ 2), BLACKOUT(/*active*/ FALSE), SET_REG(/*value*/ 0), - EXECUTE(/*seg*/ 0x14, /*script*/ _introSegmentRomStart, /*scriptEnd*/ _introSegmentRomEnd, /*entry*/ level_intro_splash_screen), + EXECUTE(/*seg*/ 0x14, /*script*/ _introSegmentRomStart, /*scriptEnd*/ _introSegmentRomEnd, + /*entry*/ script_intro_L1), JUMP(/*target*/ level_script_entry), }; diff --git a/src/engine/level_script.c b/src/engine/level_script.c index b0463393..d0447ed7 100644 --- a/src/engine/level_script.c +++ b/src/engine/level_script.c @@ -654,12 +654,14 @@ static void level_cmd_unload_area(void) { static void level_cmd_set_mario_start_pos(void) { gMarioSpawnInfo->areaIndex = CMD_GET(u8, 2); + // TODO: values are hardcoded into code rn, maybe look into loading them from a specific memory + // location (as before) or (better) from easily configurable sources #if IS_64_BIT - vec3s_set(gMarioSpawnInfo->startPos, CMD_GET(s16, 6), CMD_GET(s16, 8), CMD_GET(s16, 10)); + vec3s_set(gMarioSpawnInfo->startPos, 0, 1200, 1800); #else - vec3s_copy(gMarioSpawnInfo->startPos, CMD_GET(Vec3s, 6)); + vec3s_set(gMarioSpawnInfo->startPos, 0, 1200, 1800); #endif - vec3s_set(gMarioSpawnInfo->startAngle, 0, CMD_GET(s16, 4) * 0x8000 / 180, 0); + vec3s_set(gMarioSpawnInfo->startAngle, 0, 180 * 0x8000 / 180, 0); sCurrentCmd = CMD_NEXT; } diff --git a/src/game/behaviors/camera_lakitu.inc.c b/src/game/behaviors/camera_lakitu.inc.c index b3371198..1c6107da 100644 --- a/src/game/behaviors/camera_lakitu.inc.c +++ b/src/game/behaviors/camera_lakitu.inc.c @@ -12,10 +12,7 @@ */ void bhv_camera_lakitu_init(void) { if (o->oBehParams2ndByte != CAMERA_LAKITU_BP_FOLLOW_CAMERA) { - // Despawn unless this is the very beginning of the game - if (gNeverEnteredCastle != TRUE) { - obj_mark_for_deletion(o); - } + obj_mark_for_deletion(o); } else { spawn_object_relative_with_scale(CLOUD_BP_LAKITU_CLOUD, 0, 0, 0, 2.0f, o, MODEL_MIST, bhvCloud); } diff --git a/src/game/hud.c b/src/game/hud.c index 5a0f6806..fd66f596 100644 --- a/src/game/hud.c +++ b/src/game/hud.c @@ -458,5 +458,44 @@ void render_hud(void) { if (hudDisplayFlags & HUD_DISPLAY_FLAG_TIMER) { render_hud_timer(); } + +#ifdef DEBUG + print_fps(8, 8); +#endif } } + +// ------------- FPS COUNTER --------------- +// To use it, call print_fps(x,y); every frame. +#define FRAMETIME_COUNT 30 + +OSTime frameTimes[FRAMETIME_COUNT]; +u8 curFrameTimeIndex = 0; + +#include "PR/os.h" + +// Call once per frame +f32 calculate_and_update_fps() { + OSTime newTime = osGetTime(); + OSTime oldTime = frameTimes[curFrameTimeIndex]; + frameTimes[curFrameTimeIndex] = newTime; + + curFrameTimeIndex++; + if (curFrameTimeIndex >= FRAMETIME_COUNT) { + curFrameTimeIndex = 0; + } + return ((f32) FRAMETIME_COUNT * 1000000.0f) / (s32) OS_CYCLES_TO_USEC(newTime - oldTime); +} + +void print_fps(s32 x, s32 y) { + f32 fps = calculate_and_update_fps(); + char text[14]; + + sprintf(text, "FPS %2.2f", fps); +#ifdef PUPPYPRINT + print_small_text(x, y, text, PRINT_TEXT_ALIGN_LEFT, PRINT_ALL, FONT_OUTLINE); +#else + print_text(x, y, text); +#endif +} +// ------------ END OF FPS COUNER ----------------- diff --git a/src/game/hud.h b/src/game/hud.h index bfa44fa5..cd1b01b4 100644 --- a/src/game/hud.h +++ b/src/game/hud.h @@ -24,4 +24,6 @@ enum CameraHUDLut { void set_hud_camera_status(s16 status); void render_hud(void); +void print_fps(s32 x, s32 y); + #endif // HUD_H diff --git a/src/game/level_update.c b/src/game/level_update.c index 03d44077..71707666 100644 --- a/src/game/level_update.c +++ b/src/game/level_update.c @@ -1192,14 +1192,9 @@ s32 init_level(void) { if (gCurrDemoInput != NULL) { set_mario_action(gMarioState, ACT_IDLE, 0); - } else if (!gDebugLevelSelect) { + } else if (gDebugLevelSelect == 0) { if (gMarioState->action != ACT_UNINITIALIZED) { - if (save_file_exists(gCurrSaveFileNum - 1)) { - set_mario_action(gMarioState, ACT_IDLE, 0); - } else { - set_mario_action(gMarioState, ACT_INTRO_CUTSCENE, 0); - val4 = TRUE; - } + set_mario_action(gMarioState, ACT_IDLE, 0); } } } diff --git a/src/game/mario.c b/src/game/mario.c index cc5e8646..2d355298 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1883,7 +1883,7 @@ void init_mario_from_save_file(void) { save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1); gMarioState->numKeys = 0; - gMarioState->numLives = 4; + gMarioState->numLives = 99; gMarioState->health = 0x880; gMarioState->prevNumStarsForDialog = gMarioState->numStars; diff --git a/text/us/courses.h b/text/us/courses.h index 34dc2543..4813e61f 100644 --- a/text/us/courses.h +++ b/text/us/courses.h @@ -1,62 +1,32 @@ -COURSE_ACTS(COURSE_BOB, _(" 1 BOB-OMB BATTLEFIELD"), - _("BIG BOB-OMB ON THE SUMMIT") , _("FOOTRACE WITH KOOPA THE QUICK") , _("SHOOT TO THE ISLAND IN THE SKY"), - _("FIND THE 8 RED COINS") , _("MARIO WINGS TO THE SKY") , _("BEHIND CHAIN CHOMP'S GATE")) +COURSE_ACTS(COURSE_BOB, _(" 1 Stage1"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_WF, _(" 2 WHOMP'S FORTRESS"), - _("CHIP OFF WHOMP'S BLOCK") , _("TO THE TOP OF THE FORTRESS") , _("SHOOT INTO THE WILD BLUE"), - _("RED COINS ON THE FLOATING ISLE"), _("FALL ONTO THE CAGED ISLAND") , _("BLAST AWAY THE WALL")) +COURSE_ACTS(COURSE_WF, _(" 2 Stage2"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_JRB, _(" 3 JOLLY ROGER BAY"), - _("PLUNDER IN THE SUNKEN SHIP") , _("CAN THE EEL COME OUT TO PLAY?") , _("TREASURE OF THE OCEAN CAVE"), - _("RED COINS ON THE SHIP AFLOAT") , _("BLAST TO THE STONE PILLAR") , _("THROUGH THE JET STREAM")) +COURSE_ACTS(COURSE_JRB, _(" 3 Stage3"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_CCM, _(" 4 COOL, COOL MOUNTAIN"), - _("SLIP SLIDIN' AWAY") , _("LI'L PENGUIN LOST") , _("BIG PENGUIN RACE"), - _("FROSTY SLIDE FOR 8 RED COINS") , _("SNOWMAN'S LOST HIS HEAD") , _("WALL KICKS WILL WORK")) +COURSE_ACTS(COURSE_CCM, _(" 4 Stage4"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_BBH, _(" 5 BIG BOO'S HAUNT"), - _("GO ON A GHOST HUNT") , _("RIDE BIG BOO'S MERRY-GO-ROUND") , _("SECRET OF THE HAUNTED BOOKS"), - _("SEEK THE 8 RED COINS") , _("BIG BOO'S BALCONY") , _("EYE TO EYE IN THE SECRET ROOM")) +COURSE_ACTS(COURSE_BBH, _(" 5 Stage5"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_HMC, _(" 6 HAZY MAZE CAVE"), - _("SWIMMING BEAST IN THE CAVERN") , _("ELEVATE FOR 8 RED COINS") , _("METAL-HEAD MARIO CAN MOVE!"), - _("NAVIGATING THE TOXIC MAZE") , _("A-MAZE-ING EMERGENCY EXIT") , _("WATCH FOR ROLLING ROCKS")) +COURSE_ACTS(COURSE_HMC, _(" 6 Stage6"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_LLL, _(" 7 LETHAL LAVA LAND"), - _("BOIL THE BIG BULLY") , _("BULLY THE BULLIES") , _("8-COIN PUZZLE WITH 15 PIECES"), - _("RED-HOT LOG ROLLING") , _("HOT-FOOT-IT INTO THE VOLCANO") , _("ELEVATOR TOUR IN THE VOLCANO")) +COURSE_ACTS(COURSE_LLL, _(" 7 Stage7"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_SSL, _(" 8 SHIFTING SAND LAND"), - _("IN THE TALONS OF THE BIG BIRD") , _("SHINING ATOP THE PYRAMID") , _("INSIDE THE ANCIENT PYRAMID"), - _("STAND TALL ON THE FOUR PILLARS"), _("FREE FLYING FOR 8 RED COINS") , _("PYRAMID PUZZLE")) +COURSE_ACTS(COURSE_SSL, _(" 8 Stage8"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_DDD, _(" 9 DIRE, DIRE DOCKS"), - _("BOARD BOWSER'S SUB") , _("CHESTS IN THE CURRENT") , _("POLE-JUMPING FOR RED COINS"), - _("THROUGH THE JET STREAM") , _("THE MANTA RAY'S REWARD") , _("COLLECT THE CAPS...")) +COURSE_ACTS(COURSE_DDD, _(" 9 Stage9"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_SL, _("10 SNOWMAN'S LAND"), - _("SNOWMAN'S BIG HEAD") , _("CHILL WITH THE BULLY") , _("IN THE DEEP FREEZE"), - _("WHIRL FROM THE FREEZING POND") , _("SHELL SHREDDIN' FOR RED COINS") , _("INTO THE IGLOO")) +COURSE_ACTS(COURSE_SL, _("10 Stage10"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_WDW, _("11 WET-DRY WORLD"), - _("SHOCKING ARROW LIFTS!") , _("TOP O' THE TOWN") , _("SECRETS IN THE SHALLOWS & SKY"), - _("EXPRESS ELEVATOR--HURRY UP!") , _("GO TO TOWN FOR RED COINS") , _("QUICK RACE THROUGH DOWNTOWN!")) +COURSE_ACTS(COURSE_WDW, _("11 Stage11"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_TTM, _("12 TALL, TALL MOUNTAIN"), - _("SCALE THE MOUNTAIN") , _("MYSTERY OF THE MONKEY CAGE") , _("SCARY 'SHROOMS, RED COINS"), - _("MYSTERIOUS MOUNTAINSIDE") , _("BREATHTAKING VIEW FROM BRIDGE") , _("BLAST TO THE LONELY MUSHROOM")) +COURSE_ACTS(COURSE_TTM, _("12 Stage12"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_THI, _("13 TINY-HUGE ISLAND"), - _("PLUCK THE PIRANHA FLOWER") , _("THE TIP TOP OF THE HUGE ISLAND"), _("REMATCH WITH KOOPA THE QUICK"), - _("FIVE ITTY BITTY SECRETS") , _("WIGGLER'S RED COINS") , _("MAKE WIGGLER SQUIRM")) +COURSE_ACTS(COURSE_THI, _("13 Stage13"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_TTC, _("14 TICK TOCK CLOCK"), - _("ROLL INTO THE CAGE") , _("THE PIT AND THE PENDULUMS") , _("GET A HAND"), - _("STOMP ON THE THWOMP") , _("TIMED JUMPS ON MOVING BARS") , _("STOP TIME FOR RED COINS")) +COURSE_ACTS(COURSE_TTC, _("14 Stage14"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) -COURSE_ACTS(COURSE_RR, _("15 RAINBOW RIDE"), - _("CRUISER CROSSING THE RAINBOW") , _("THE BIG HOUSE IN THE SKY") , _("COINS AMASSED IN A MAZE"), - _("SWINGIN' IN THE BREEZE") , _("TRICKY TRIANGLES!") , _("SOMEWHERE OVER THE RAINBOW")) +COURSE_ACTS(COURSE_RR, _("15 Stage15"), _("1"), _("2"), _("3"), _("4"), _("5"), _("6")) SECRET_STAR(COURSE_BITDW, _(" BOWSER IN THE DARK WORLD")) SECRET_STAR(COURSE_BITFS, _(" BOWSER IN THE FIRE SEA")) diff --git a/text/us/dialogs.h b/text/us/dialogs.h index 34a18b20..e77f126a 100644 --- a/text/us/dialogs.h +++ b/text/us/dialogs.h @@ -16,64 +16,26 @@ #define GIVE_UP "give" #endif -DEFINE_DIALOG(DIALOG_000, 1, 6, 30, 200, _("\ -Wow! You're smack in the\n\ -middle of the battlefield.\n\ -You'll find the Power\n\ -Stars that Bowser stole\n\ -inside the painting\n\ -worlds.\n\ -First, talk to the\n\ -Bob-omb Buddy. (Press [B]\n\ -to talk.) He'll certainly\n\ -help you out, and so will\n\ -his " COMRADES " in other\n\ -areas.\n\ -To read signs, stop, face\n\ -them and press [B]. Press [A]\n\ -or [B] to scroll ahead. You\n\ -can talk to some other\n\ -characters by facing them\n\ -and pressing [B].")) +DEFINE_DIALOG(DIALOG_000, 1, 5, 30, 200, _("\ +This movement-based ROM\n\ +hack challenges your\n\ +control of mario in\n\ +various ways.\n\ +Press L to reset the\n\ +current level.\n\ +Have fun!")) -DEFINE_DIALOG(DIALOG_001, 1, 4, 95, 200, _("\ -Watch out! If you wander\n\ -around here, you're liable\n\ -to be " PLASTERED " by a\n\ -water bomb!\n\ -Those enemy Bob-ombs love\n\ -to fight, and they're\n\ -always finding ways to\n\ -attack.\n\ -This meadow has become\n\ -a battlefield ever since\n\ -the Big Bob-omb got his\n\ -paws on the Power Star.\n\ -Can you recover the Star\n\ -for us? Cross the bridge\n\ -and go left up the path\n\ -to find the Big Bob-omb.\n\ -Please come back to see\n\ -me after you've retrieved\n\ -the Power Star!")) +DEFINE_DIALOG(DIALOG_001, 1, 5, 30, 200, _("\ +This movement-based ROM\n\ +hack challenges your\n\ +control of mario in\n\ +various ways.\n\ +Press L to reset the\n\ +current level.\n\ +Have fun!")) DEFINE_DIALOG(DIALOG_002, 1, 4, 95, 200, _("\ -Hey, you! It's dangerous\n\ -ahead, so listen up! Take\n\ -my advice.\n\ -\n\ -Cross the two\n\ -bridges ahead, then\n\ -watch for falling\n\ -water bombs.\n\ -The Big Bob-omb at the\n\ -top of the mountain is\n\ -very powerful--don't let\n\ -him grab you!\n\ -We're Bob-omb Buddies,\n\ -and we're on your side.\n\ -You can talk to us\n\ -whenever you'd like to!")) +Text Placeholder")) DEFINE_DIALOG(DIALOG_003, 1, 5, 95, 200, _("\ Thank you, Mario! The Big\n\