# khdays-port [![Discord](https://img.shields.io/badge/Discord-Join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/rVeTPhPbsx) A native PC port of **Kingdom Hearts 358/2 Days**, built on [`khdays-decomp`](https://github.com/Yokimitsuro/khdays-decomp). The game is the decompilation's C, compiled for the PC; the port supplies what the Nintendo DS hardware did underneath it -- graphics, sound, input, the card, interrupts and the system calls of its SDK -- and, around it, what a PC version wants: modern controls, rendering, resolutions, a single-screen mode and replaceable content. This is how other decompilation-based ports work: the game code is the original's, readable and moddable; the platform layer is new. > [!IMPORTANT] > This repository contains no ROM, game assets, audio, video, text, SDK files or > game binaries. You need your own legally obtained copy of the game. > [!WARNING] > The port is a work in progress and may have bugs. Reports are very welcome, > in the [issues](https://github.com/Yokimitsuro/khdays-port/issues) or on > [Discord](https://discord.gg/rVeTPhPbsx): what happened and what you were > doing when it did. AI-assisted coding tools were used to help make this possible. ## Status The whole game runs natively from the decompilation: the title and its menus, Story Mode (opening movie, days, cutscenes, the field), Mission Mode (character select, camp, missions, results), combat and magic, the shop, and a player's save loaded, played and saved again. Crashes found while playing are fixed as classes in the build's source preparation, and what they show about the C goes back to the decompilation ([`docs/DECOMP_FINDINGS.md`](docs/DECOMP_FINDINGS.md)). Today it builds for **Windows x64 (64-bit)**. It plays with the keyboard, the mouse or a gamepad, with remappable controls and optional enhancements (an analog camera among them). The picture is the port's own: the 2D composed by the port on the graphics card from what the game asks for, and the 3D's geometry answered by the port and drawn there too -- at up to eight times the DS's resolution, in widescreen, and with HD textures, models and 2D graphics from mods; the DS's own engines remain only as the reference the port is checked against. The sound is the port's own: the ARM7's sound driver in C, mixed at the PC's rate, with its own volumes and every sound replaceable from mods. So are the movies: decoded by the port, shown at full colour, their sound at its own volume, each replaceable by a video from a mod. No machine code of the DS runs: the port has no ARM interpreter, and what the decompilation keeps as assembly and the game calls is C the port wrote from it. The game's files reach it from the port as well: each read copied at once from a mod's file or the extracted data, with no card in between (the emulated card stays as the reference). The game's time is the port's too: its frames, its tick and alarms on the PC's clock, its interrupts taken where the game waits or unmasks them, nothing simulating the DS's timers or its display; and the 3D is drawn at the monitor's refresh rate, between the game's frames, which still come 30 a second as on the DS. The game's memory is the port's: a range Windows places, with each DS region at its DS address from its start, the game's pointers kept as references into it -- the DS's own addresses hold nothing. The HUD, the menus and the game's text are drawn anew by the port, each element placeable. Underneath, the game still sees a DS -- two screens one above the other, and the ARM7's services, which the port answers on the PC: the clock from the PC's, the save from its files. On top of the game, a new edition from content the user provides: HD textures, models and 2D graphics, new rooms, sounds and videos, a single-screen mode, and Mission Mode's multiplayer. Planned: the port on other systems -- Linux first, then, from one ARM64 build, macOS, Windows on ARM and the Nintendo Switch. ## Installing On Windows, the installer from the releases page is all you need besides your own copy of the game: it asks for your ROM (the European release of KINGDOM HEARTS 358/2 Days; it finds it by itself where KH Melon Mix keeps one in your KINGDOM HEARTS HD 1.5+2.5 ReMIX folder), prepares the game's data from it, and can also make the HD pack from your HD collections, add the port to Steam (PC and Steam Deck), and install the mod studio. Nothing of the game comes with it. The port tells you when a newer release is out. More: [`installer/README.md`](installer/README.md). ## Getting started To build the port from source instead: 1. Check and extract your copy of the game (Python 3.11+): ```powershell py .\tools\verify_rom.py "E:\path\game.nds" py .\tools\extract_data.py "E:\path\game.nds" ``` The data goes to `data/extracted//`, which is never committed. 2. Build (Windows, Visual Studio 2026 with the C++ workload, CMake, Ninja, and for the preparation Python's `pycparser`): ```powershell py -m pip install pycparser py .\port\build.py --config Release ``` `port/tools/prepare.py` generates the build's sources from the decompilation -- the game's C rewritten with every pointer a reference (`build/port/gen-x64`); the executable is `build/port/obj-release-x64/khdays-native.exe` (`--config Debug`: `build/port/obj-x64/`). 3. Run it from the repository root, so it finds `data/` and keeps the save in `saves/khdays.sav`: ```powershell .\build\port\obj-release-x64\khdays-native.exe 2> khdays.log ``` The runtime reports to stderr; `2>` keeps it for a bug report. Started without the data (or with it incomplete), it says so in a message box in the system's language, with the folder it looked in. The save is the DS's backup memory as a file, in the same format as a DS save (a 64 KB raw backup), so a save from the DS loads. It is written whole each time the game saves -- a new file beside it, then put in its place -- so a crash of the game or the PC while saving leaves the save as it was before, or as it is after, never half of one. 4. When something seems wrong -- music late, the game stopping for a moment -- the session log says what the game was doing: the Debug build writes one for every session in `saves/logs/` (Release: turn on **Session log** in the settings, or `KHDAYS_LOG=1`): its scenes, the files it read and how long they took, when each music was asked for and when it was heard, and every stretch over 50 ms without a frame. Press **F12** when you see it happen: the log gets a mark there, and what the DS's two screens show then is saved in `saves/marks/` (`mark__frame_.bmp`, with the upper screen's layer registers and the pause's pieces in the log). Send the log and the pictures with the bug report. ## Controls By default the game is played as on the DS. - **Keyboard:** arrows = D-pad, Z = A, X = B, S = X, A = Y, Q = L, E = R, Enter = START, right Shift = SELECT. - **Mouse:** its buttons (left, middle, right, the side buttons X1 and X2) and its wheel can be bound to any action in Settings -> Controls, in the keyboard's column; a notch of the wheel is a short press. Its pointer shows only over the settings menu (the touch screen is not used). - **Gamepad** (Xbox, PlayStation, Switch Pro, Steam Deck, or any controller your system recognises as a gamepad): connect it whenever you like, even in the middle of a battle. The buttons follow the DS's layout by *position*, whatever is printed on them: the right-hand face button is A, the bottom one B, the left one Y and the top one X; the shoulders are L and R; Start or Options is START; Select, Share or View is SELECT. The left stick moves like the D-pad (the DS's eight directions). With several gamepads connected, the first one plays. **Settings.** Press **Esc**, the gamepad's **Guide / Home** button or **L3** (click the left stick in; Steam and the Steam Deck keep Guide for themselves), or click the title's settings key where the title is the theater's. The menu covers the window, the game dimmed and paused behind it (in a multiplayer session the game goes on). Every section is on one screen -- Controls, Enhancements, Sticks and camera, Video, Sound, Multiplayer, Language, General -- and works with the mouse alone, the keyboard alone or a gamepad alone (its shoulders move between the sections). A change takes effect when you make it: the picture behind the menu follows the video settings, each volume plays a sample of its kind (the game is heard at it when it resumes), and a new binding works from the first press after the menu closes. The Controls section shows every action with its two keys and two gamepad buttons side by side: choose a cell and press the new input; the Kingdom Hearts II layout and the defaults of each section are there too. A setting that waits for something says so beside it (the movies' choice from the next movie; the nickname, online play and the server from the next multiplayer session while one is open). **Language.** The game and the settings menu follow your system's language when the game has it (English, French, German, Italian or Spanish; English otherwise). Settings → Language chooses one of the five instead: the menu changes at once, the game's own text when the screen you are on ends (a mission, a menu of the game, the title) -- a screen of the game loads its text when it is built, so every one is built whole in one language. `KHDAYS_LANGUAGE=es` (or `en`, `fr`, `de`, `it`) wins over both. Where the screen names one of the game's Config options, it uses the game's own words in that language. Your choices are kept in `saves/settings.ini`, a text file you may also edit by hand (`KHDAYS_SETTINGS=` uses another file). If the port cannot read it, it starts with the defaults and keeps the old file as `settings.ini.bad`. **Enhancements** (Settings → Enhancements; all off by default, so the game plays as on the DS until you switch one on). Each does only what the game's own controls can do, through the same parts of the game: - **Analog camera:** the right stick turns the field camera and tilts it, as far as the tilt of the stick, at up to the game's own turning speed (adjustable, and invertible, under Sticks and camera). On the DS the camera is turned by dragging on the touch screen, by Select's look view, or with L/R when the game's Config sets them to the camera. - **Mouse camera:** moving the mouse turns and tilts the field camera, through the same part of the game as the analog camera, at a speed of its own (Sticks and camera -> Mouse camera speed) and with the camera's inversions. While you play the window holds the mouse; Esc frees it with the settings menu. - **Command menu on the D-pad:** in a field, the gamepad's D-pad moves through the command deck instead of moving Roxas, by making the presses the DS itself uses (X, or X held with a direction); menus, dialogs and open panels keep the D-pad. Which directions work depends on the game's own Config option for the command deck: with X alone moving it (the new-game default), only Down can. - **Analog movement:** Roxas moves in the exact direction of the left stick; pushed less than the run threshold (75 % by default) he walks, at half his speed by default, his steps slowed to match. Fully pushed he runs at the game's own speed, never faster. - **Separate lock-on:** lock on (and off) and switch to the next target on buttons of their own, by making the presses the game uses: its lock-on is R pressed twice quickly, a single R moves to the next target once locked (with Controls: Type B, L tapped goes to the previous one). The game takes two R presses within 9 of its frames (0.3 s) as the double press that lets go, so switching quickly on the DS drops the lock: here the next target waits for that window instead, and a quick series of switches keeps the lock. On the DS a single R press also resets the camera and a long one switches the chase cam; the DS's R stays available for those. Out of the field -- menus, tutorials, the pause -- there is no lock-on, and these buttons are the DS's R (lock on, next target) and L (previous target), so they turn pages as R and L do there. The **Kingdom Hearts II layout** (Settings → Gamepad preset; Kingdom Hearts III uses the same buttons for these actions) puts attack on the bottom face button, jump on the right, guard on the left, DS X on the top, the shortcuts on L1, lock-on on R1, the next target on R2, the camera's reset on R3 (the DS's R), the command menu on the D-pad, the camera on the right stick and SELECT on View / the touch pad, and switches on the enhancements it uses. The keyboard is not changed. ## Picture By default the picture is the DS's: each screen 256x192, drawn exactly as the DS draws it, its pixels scaled up sharp to fill the window at 4:3. The port draws it through the graphics card (Direct3D 12 or Vulkan, whichever the system offers), and needs one: without, it says why in a message box and its log, and does not start. **Settings → Video** changes it; the picture behind the screen follows at once: - **Display mode**: a window (the default) you can move and resize, a borderless window over the whole screen, or full screen (the screen for the game alone, at your desktop's resolution). **Alt+Enter** switches between the window and the full screen you chose last (the borderless window if none) while the settings menu is closed, and keeps it. - **Internal resolution** (1x, 2x, 3x, 4x, 6x, 8x, or the window's own size): the 3D -- the field, the characters, the effects -- drawn at that many times the DS's pixels. "The window's" draws at the next whole multiple up and shrinks it on the graphics card to the window's own pixels (with sharp scaling, the largest that fits, its pixels square); a picture drawn larger than the window is always shrunk so, each pixel the average of what is under it, never stretched. The 2D -- the HUD, the menus, the text, the lower screen -- stays the DS's pixels, as the game drew them, unless a mod replaces it (below). It is the same picture, only sharper: the 3D follows the same rules as at 1x, and wherever the 2D covers or blends with it, it does so as on the DS. - **Antialiasing** (off, 2x, 3x, 4x): the picture made that many times larger, then shrunk to the size shown, each pixel the average of what is under it -- the 3D's edges come out smooth instead of in steps. 2x is four times the graphics card's work, 4x sixteen; off by default. (A mod's textures, and the HD replacements, are read at the size they are drawn whatever this says: smaller copies of each are kept, so a model far away does not break into steps that flicker.) - **Aspect ratio** (4:3, 16:9, 16:10, or the window's): the 3D view of the upper screen widens to it, and the field's HUD keeps to the corners of the wider picture as it does on the DS -- the command deck bottom left, the portrait and gauge bottom right, the hearts counter top left. What the game centres (dialogs, menus) and what follows the 3D (markers over targets) stays where it was, and the lower screen stays 4:3 in the middle. The game sees nothing different: it still computes its 4:3 view. - **Screen scaling**: sharp (the DS's pixels as squares) or smooth. - **3D texture smoothing**: off as on the DS, or blended between texels. - **HD graphics**: the replacements in your mods (below), on by default. - **Dump graphics**: each texture and 2D tile sheet written out the first time it is drawn, into `saves/dump/graphics`. - **Movies**: HD, the default -- the HD collection's own videos where you have copied them (below), the other movies at full colour -- at full colour (the decoded frames as they are), or as on the DS (15-bit colour with its checkerboard dither). - **Picture pace**: smooth, the default -- the 3D drawn at your monitor's refresh rate (60, 120, 144, 165 Hz...), placed between the game's last two frames (the game itself runs at 30 frames a second, as on the DS), the picture up to one game frame behind -- or as on the DS, a new picture each game frame. Camera cuts and scene changes are not smoothed across. The 2D (HUD, menus, text) and the movies change when the game changes them. - **Show FPS**: a counter in the window's corner -- the pictures drawn a second and the game's own frames a second. - **Graphics API**: what draws the picture -- automatic (Direct3D 12 on Windows, Vulkan on a Steam Deck or under Proton), Direct3D 12 or Vulkan, changed at once. If the graphics card stops answering on Direct3D 12, try Vulkan. Should the card stop answering anyway (Windows resets its driver), the game carries on: the picture is made again, and an internal resolution lost twice drops to 1x for the session. The choices are kept in the `[video]` section of `saves/settings.ini`: ```ini [video] internal_resolution = window # the window's size (the default), or a multiple: 2 to 16 in the settings antialiasing = off # off, 2x, 3x or 4x: made that many times larger and shrunk aspect = 16:9 # 4:3 (the DS's), 16:9, 16:10, or window scaling = sharp # sharp (the DS's) or smooth texture_smoothing = off # off (the DS's) or on hd_graphics = on # the mods' replacements dump_graphics = off # write what is drawn to saves/dump/graphics movies = hd # hd (your HD videos, the rest pc), pc (full colour) or ds (the DS's) picture_pace = smooth # smooth (the monitor's rate) or ds show_fps = off # the live counter backend = auto # auto, direct3d12 or vulkan ``` **The field on one screen.** With one screen (`[video] screens = one`, the default) the field's HUD is laid out for a PC screen, made of the game's own pieces: the mission's objective and gauge at the top left, its badges and chests counted at the right of the objective, the hearts counter under it; in the top right corner the map, drawn over the field as in Kingdom Hearts II, with the enemy's health over it; the command deck at the bottom left and the party at the bottom right. The panels' dark ground is half see-through, their text and edges are not. The INFORMATION banner shows at the top left, over everything, for five seconds each time its message changes, instead of staying on screen; at a mission's start the mission's panel and map show at once, before the game brings in the rest of its HUD. **Badges on the mission panel.** In a story mission the lower screen's mission panel shows, left of the chest icon, the mission's badges with the camp's mission list's own icons -- the ordeal badge and the blazon, then the unity badge -- grey until found, lit once your save holds them or you pick one up; on one screen it shows how many are found of how many. The DS shows them only in the list. Mission Mode puts out no badges, so it shows none. **The players' names in multiplayer.** In a Mission Mode session the field's party shows each player's name left of their J label, in white in the game's own font -- yours by your bar, the others' by theirs. The DS shows only the labels. **The title as the HD collection's theater menu.** If you have KINGDOM HEARTS HD 1.5+2.5 ReMIX, `tools/hd/theater_title.py` makes a mod from your copy (nothing of the collection is in the port) that shows the title's menu, on one screen, as the collection's 358/2 Days theater draws its main menu -- its logo, key art, bars and settings key, animated as there -- with the game's own options in its font, in the five languages. It reads the theater's files as OpenKh's extractor writes them (`Image/Mare.hed_out/original`): ```bash python tools/hd/theater_title.py "/Image/Mare.hed_out/original" ``` The pictures go to `mods/Theater title/layouts/title/`; the screens after the menu (the save list, the theater's list; the difficulty, unless the new game's dialogs below are made) are the game's. Its settings key opens the settings menu when clicked and, while you play with a gamepad, shows your gamepad's button for the settings in the collection's own icons (the left stick's click by default: the collection has no icon for the Guide button). The boot logos are the theater's too: its Disney, SQUARE ENIX and copyright screens in the DS's three turns. **The new game's dialogs as in Dream Drop Distance HD.** If you also have KINGDOM HEARTS HD 2.8 Final Chapter Prologue, `tools/hd/newgame_dialog.py` adds to the same mod the new game's steps as Dream Drop Distance HD draws its own -- the game's difficulty, then the port's question whether the movies show their subtitles, then the review of both ("Continue with these settings?") -- in Days's colours (greys, the selected button red; `--colours ddd` keeps DDD's blue), with DDD's words in its font, in the five languages, over the theater's menu. It reads DDD's files as OpenKh's extractor writes them (`Image/dt/kh3d_first.hed_out`), the theater's as above, and the pointing glove of KINGDOM HEARTS II's title sheet (DDD's own is not among those files; OpenKh's KH2 data: `remastered/menu/fm/title.2ld/UK_title_2ld0.png`): ```bash python tools/hd/newgame_dialog.py "<2.8>/Image/dt/kh3d_first.hed_out" "/Image/Mare.hed_out/original" "/remastered/menu/fm/title.2ld/UK_title_2ld0.png" ``` **The settings menu as the HD collection's.** `tools/hd/theater_settings.py` makes, from the same copy, the collection's own settings menu's pieces in the new game's dialogs' tones -- its screen and heading's tab, a faded picture for each section, the sections' tabs, the rows' capsules, a switch's check, a number's slider, a choice's arrows, the question's window, the hints' bar -- and its font; the port's settings menu draws itself with them (its rows, keys and mouse unchanged), the selected pieces red with a silver rim: ```bash python tools/hd/theater_settings.py "/Image/SettingMenu.hed_out/original" ``` They go to `mods/Theater title/layouts/settings//`; without them the menu keeps its own look. **The save list as Dream Drop Distance HD's, with 99 files.** `tools/hd/save_screen.py` makes, from DDD's files (as above) and the port's extracted game data, the pieces of DDD's own save screen in Days's tones -- its screen, the list's rows (the selected one red), the scrollbar, the crown, the questions' buttons -- with DDD's font and input icons, Days's three faces and the theater's hand (the 1.5+2.5 collection's, as below): ```bash python tools/hd/save_screen.py "<2.8>/Image/dt/kh3d_first.hed_out" "/Image/Mare.hed_out/original" ``` They go to `mods/Theater title/layouts/save//`. With them, the lists of files are the port's -- CONTINUE's and Mission Mode's on the title, and Save in the story's and Mission Mode's camp menus: 99 files, each row with Days's face and its day, level, munny, difficulty and time, the game's own questions and words, and the keys shown as the icons of what you have for them (an Xbox pad's, a PlayStation's, a Switch's for other pads, the keyboard's keys). Files 1-3 are the DS's three, in `saves/khdays.sav` as always; files 4-99 go to `saves/slots/slotNN.sav`. The save after the story's ending still shows the DS's three. Without those pieces the game's own lists reach the 99 files as well, in pages of three: past the first or last row the list moves on, each row numbered, file 99 tagged AUTO (the autosave's), the game's questions naming the file. In `saves/settings.ini`, `[save] files = 3` keeps the DS's three. **Autosave.** After each cleared mission -- in the story, in Mission Mode alone or with friends -- the game saves itself the first time it is back at a camp's menu (Mission Mode's after the results, the story's that opens after a mission), with the camp's own Save, into file 99 by default; a corner line in the game's font says it was saved, or that it could not be. In the settings menu's General page, "Autosave" chooses file 99, the file being played (a game never saved: the first empty file) or off (`[save] autosave = file99 | played | off`), and "Files in the game's lists" the 99 or the DS's three. A mission given up or lost writes nothing, and Mission Mode's guest game, which has no file, is never saved. **THEATER MODE as the HD collection's theater.** `tools/hd/theater_cine.py` makes, from the same copy of the collection and the port's extracted game data, the theater's chapter list -- its heading, its rows (the selected one red, the glove), its DAY and digits, its scrollbar and help bar, its font and button and key icons -- and the artwork of each scene's chapter: ```bash python tools/hd/theater_cine.py "/Image/Mare.hed_out/original" ``` They go to `mods/Theater title/layouts/cine/` (`/` and `art/`). With them THEATER MODE's list is drawn as the theater draws its chapters. With the Movies setting on HD and the theater's videos made (*HD scenes* above) the list is the theater's own: its 53 chapters with videos, each with its name, its length and its day when it is a day's first, the artwork of the selected one behind; UP and DOWN move a row, LEFT and RIGHT a page, A plays the chapter's videos in a row with their subtitles (START stops them), B leaves as the game's list does. Otherwise the list is the game's 28 movies, ten to a page, its own list running underneath (its keys, pages and movies). **Mission Mode's rooms and character select on one screen.** `tools/hd/theater_mission.py` makes, from the same copy, the faces of the game's nineteen characters as the theater has them (in colour and in grey) and its hooded figure, the rows, scroll bar and help bar of its chapter list, its veil, one of its artworks, its font and its icons: ```bash python tools/hd/theater_mission.py "/Image/Mare.hed_out/original" ``` They go to `mods/Theater title/layouts/select/` and `layouts/rooms/`. With them the list of rooms and a room (below, Multiplayer) are drawn as the theater's chapters, and the character select, alone or in a group, is one screen: the character you are on large, with its name, weapon and gauges; the characters you can choose (the ones not bought are not there, as in the game) in rows; each player's place along the bottom, in its colour and label (J1-J4), ringed once it has chosen. The directions move on that grid; A, B and START are the game's. **The camp menus on one screen.** `tools/hd/ddd_camp.py` makes, from your copy of KINGDOM HEARTS HD 2.8 Final Chapter Prologue (Dream Drop Distance's camp menu) and the theater of the 1.5+2.5 collection, Mission Mode's and the story's camp menus as one screen in DDD's pieces in Days's greys: ```bash python tools/hd/ddd_camp.py "<2.8>/Image/dt/kh3d_first.hed_out" "/Image/Mare.hed_out/original" "/Image/SettingMenu.hed_out/original" ``` They go to `mods/Theater title/layouts/camp//`. With them the camp's menu shows its options in DDD's command bars (the selected one lit), the character's own 3D model large in a grey box where DDD's portrait frame goes (cut at its edge, as the DS's frame cuts it), its face, name and numbers on the right, the trials with the DS's sigil and DDD's crown, the munny and heart points in DDD's digits, the option's description and the settings key, the hand at the option selected, the game mode (the story's difficulty, or Mission Mode) on the panel, Title Screen's question with its two answers, and the Preferences page in the menu -- all the game's settings in sections, in the settings menu's tabs and rows, L and R between the sections; in the story's, its day on the box; in a group, a plate for each player with its face and where it is (an option, the menu, or ready -- ringed in its colour -- once it accepted the mission). The game's menu runs underneath (its cursor, sounds and pages); its other pages (the holo-missions, the panels, the shop, ...) are still the game's screens. **Retry.** In a Mission Mode mission or a story challenge played alone, the pause has a third line between Continue and Give Up: Retry, drawn like the game's lines in its own font. After the game's "Are you sure?", the mission starts again from its beginning, without the results screen (`KHDAYS_UI=pause=off` gives the game's two lines back). **The pause in HD.** A mod can draw every pause (Mission Mode's, a scene's with Skip, "Are you sure?", and Retry) in its own pictures. From your own pictures of the KH games' pause (its title's bars, a line's capsule plain and lit, the hand) and the free fonts of Televo's *Kingdom Hearts Re:Collection* (KHGummi for the title, KHMenu for the lines), in the game's words in each language: ```bash python tools/hd/hd_pause.py "/Fonts" --mod "mods/HD HUD" ``` They go to `mods/HD HUD/layouts/pause/` (see the tool for the pictures' names). **Subtitles.** `[video] subtitles = on|off` (Video in the settings menu, and the new game's question where those dialogs show): off, the game's movies show without the subtitles the DS draws over them. With `movies = hd`, the HD videos show the theater's own subtitles when it is on -- in its event font, in your language -- if you made them from your copy; `tools/hd/theater_movies.py` also copies the theater's videos, which carry no subtitles in the picture (a video with them drawn in: leave subtitles off). A video you already have is kept unless `--force`: ```bash python tools/hd/theater_movies.py "/Image/Mare.hed_out/original" ``` The videos go to `data/cutscenes/cinematics/hd.mp4` (the opening's from the theater's `DOP.mp4`; the ending's, 843, is not among them), the subtitles to `data/cutscenes/cinematics/subtitles//hd.png` and `.txt`; a mod's `movies/subtitles//hd.txt` comes first. **HD graphics from mods.** A mod replaces any of the game's graphics, at any resolution, with a file named after it: ```text mods//graphics/[#]/ ├── tex/[@].png # a 3D texture, any size (with any palette: .png) ├── chr/.png # a 2D tile sheet, a whole multiple of its size └── mdl/.gltf # a model -- or .glb, or .fbx (.bones.txt beside it pairs its joints) ``` `` is the game file the graphic is loaded from and `#` its entry in a pack. A texture is drawn with the original's mapping at the PNG's resolution. A 2D tile sheet's PNG holds the sheet's tiles in its rows: indexed, its pixels are the game's palette indices and it is drawn with the palettes the game draws the tiles with, so its fades and palette effects stay; in true colour, with its own colours. Only tiles the game has not drawn over itself are replaced, so the game's text stays its own. A model keeps its own skeleton, weights, polygons and textures and is moved by the game's animations: its joints named like the original's nodes follow them, `.bones.txt` pairs the others (a line ` `; `scale ` sizes the model), the rest move with their parents, and a rest pose far from the game's (a T-pose) is turned to match. A model may be glTF (`.gltf`, or `.glb` with its textures inside) or FBX (`.fbx`, binary or ASCII), taken in that order when more than one is there; an FBX in centimetres or with Z up is converted to glTF's metres and Y up, so the same model measures the same in either. Its textures are PNG, JPEG, TGA or BMP, embedded or beside it -- one the file stores under another machine's path is found by its name beside the model -- and one that is missing is drawn white and named once in the log. The model's own animations are not used: the game's move it. While a mod's graphics are drawn, the 3D and the 2D's blending and brightness work in 8 bits a channel instead of the DS's 6 and 5. A file that cannot be used is named once in the log, and the original is drawn. **The originals** to make them from: `khdays-native --dump-graphics [DIR]` writes, without starting the game, every texture (with each palette it is drawn with), every model as glTF with its skeleton, and every 2D tile sheet as an indexed PNG, under those names (default `saves/dump/graphics`). A dumped 2D tile sheet put back unchanged is drawn as the original. ## Sound The port plays the game's sound itself: the DS's sound driver, which the game's ARM7 binary carries, written in C and run on a thread of its own, so loading and busy frames no longer cut it; the music streams read by the port as the game's stream player would; and the channels mixed at the PC's output rate in floating point, without the DS's 10 bits. **Settings → Sound** sets the overall volume and those of the music, the effects, the voices (what each sound is comes from the name of the player the game's sound archive gives it) and the movies, kept in `saves/settings.ini`: ```ini [sound] volume = 100 # 0 to 100, each music = 100 effects = 100 voices = 100 movies = 100 ds_exact = off # on: the DS's own output (32,728 Hz, 10 bits) ``` **Replacing sounds.** A mod replaces any sound with a WAV, FLAC or Ogg Vorbis file at any rate, mono or stereo, named after the sound in the game's sound archive: ```text mods//sounds/ ├── seq/. # a whole sequence (music) ├── seqarc//. # one effect or voice of a sequence archive ├── wave//. # one wave an instrument plays └── strm/. # a stream (music, voices) ``` The loop is a WAV's `smpl` loop, else the Vorbis comments `LOOPSTART` and `LOOPLENGTH`, else the original's. The original keeps running unheard, so the game waits for it and reads it as before; a file that cannot be read is named once and the original plays. **The originals** to make them from: `khdays-native --dump-sounds [DIR]` writes every wave, stream, sequence and sequence-archive entry as WAV under those same names, loops included (default `saves/dump/sounds`, about 2.3 GB). It runs without starting the game; the sequences are played by the port's driver and mixer at 48,000 Hz. A dumped file put back unchanged plays as the original. **HD movies.** If you own KINGDOM HEARTS HD 1.5+2.5 ReMIX, the HD videos of this game's movies its 358/2 Days theater holds can play in their place: make them from your copy with `tools/hd/theater_movies.py --videos` (see *Subtitles* below), which writes them to the port's `data/cutscenes/cinematics/` (`hd802.mp4` to `hd848.mp4`). They are yours: nothing of them is in this repository, and `data/` is never committed. With the Movies setting on HD, a movie that has one shows it over the whole window with its own sound, in both screen layouts; the game plays its own movie behind it, unseen, and waits at its end until the video ends. START stops the video where the DS lets you skip the movie. Windows decodes the videos (Media Foundation); a file it cannot play, or a movie without an HD video, plays the game's movie, and the log says why. A mod's movie for the same movie comes first. Subtitles are not shown over the HD videos. **HD scenes.** The theater also holds the game's event scenes the DS draws in real time, made again in HD, and Roxas's monologues as a voice. The same tool makes the ones the port plays: the scene map, `port/movies/hd_scenes.txt` (86 scenes and 7 monologues, each paired by its lines or its pictures, every pair checked side by side; `tools/hd/scene_report.py` says where each video of your collection plays). With the Movies setting on HD, when the game reaches a scene of the map its videos play over the whole window with their sound and subtitles while the game waits; then the game takes its own skip, so it goes on exactly as after the DS's Skip. A day's monologue keeps the game's page, and the theater's voice reads it. Without the video, or with Movies on PC or DS, the DS's scene plays. START pauses the video and opens the game's own pause over it, as on the DS: Continue goes on with the video, Skip ends the scene (on two screens the pause shows over the game's screens). A mod's `cutscenes/scenes.txt` adds or replaces entries (`