diff --git a/BRS-Extract.ps1 b/BRS-Extract.ps1 index f61a3c2..70d476d 100644 --- a/BRS-Extract.ps1 +++ b/BRS-Extract.ps1 @@ -25,9 +25,9 @@ $vgmstream_command = Get-Item -Path $vgmstream_command | % { $_.FullName } $extraction_script = "Scripts\BRS-Extract.bms" $extraction_script = Get-Item -Path $extraction_script | % { $_.FullName } -$archive_types += @("vol", "bin", "zzz", "gz", "efp", "lpk", "efc") +$archive_types += @("vol", "zzz", "gz") -$sleep = 2 +$sleep = 3 Write-Output "Checking If Required Extraction Tools Are Available" @@ -42,12 +42,6 @@ if ((Get-Command $quickbms_command -ErrorAction SilentlyContinue) -eq $null) $download_qbms = 1 } -Write-Output "Checking VgmStream" -if ((Get-Command $vgmstream_command -ErrorAction SilentlyContinue) -eq $null) -{ - $download_vgms = 1 -} - if ($download_qbms -eq '1' -Or $download_vgms -eq '1') { $input = Read-Host 'Can I download the missing tools? (y/N)' @@ -70,129 +64,191 @@ if ($download_qbms -eq '1' -Or $download_vgms -eq '1') { } } else { - Write-Output "Please download QuickBMS and VgmStream and place them inside of the Tools directory; then run this script again" + Write-Output "Please download QuickBMS and place it inside of the Tools directory; then run this script again" exit } } Start-Sleep $sleep -Write-Output "Extracting and decrypting game archives. This process can take awhile" +Function Delete { + Write-Output "Removing extracted files. Please wait" + Start-Sleep $sleep + Remove-Item $extraction_dir -Force -Recurse +} -foreach ($item in (Get-ChildItem -Path $game_dir -Force -Recurse | % { $_.FullName })) { - $ext = (Split-Path -Path $item -Leaf).Split(".")[1] - $dir = $item.replace(($game_dir + "\"), ($extraction_dir + "\")) - foreach ($arc in $archive_types) { - if ($ext -eq $arc) { - if (!($item -like '*ITM*ZZZ') -And !($dir -like '*INSDIR*') -And !$($dir -like '*SYSDIR*') -And !($item -like '*UMD*')) { - & $quickbms_command -Y $extraction_script $item $dir - } +Function Clean { + Write-Output "Cleaning up. Please wait" + Start-Sleep $sleep + Get-ChildItem -Path $extraction_dir -Force -Recurse -Directory | + Sort-Object -Property FullName -Descending | + Where-Object { $($_ | Get-ChildItem -Force | Select-Object -First 1).Count -eq 0 } | + Remove-Item + + foreach ($item in (Get-ChildItem -Path $extraction_dir -Force -Recurse | % { $_.FullName })) { + if ($item -like "*TEMP*") { + Remove-Item $Item -Force } } - # Copy the sound folder over so they get converted - if (($item -like '*SOUND*') -And ($ext -eq 'at3')) { - $sound_dir = $extraction_dir + "\PSP_GAME\USRDIR\GAMEDATA\SOUND" - New-Item -Path $sound_dir -Force -ItemType Directory | Out-null - Copy-Item -Path $item -Destination $sound_dir - } } -Start-Sleep $sleep - -Write-Output "Recursively extracting archives" - -Function Extract-Internals { - (Get-ChildItem -Path . -Force -Recurse -File | % { $_.FullName } ) | ForEach-Object -Parallel { - $file = Split-Path $_ -Leaf - $dir = Split-Path $_ -Parent - $extract = $file + '_extract' - $ext = (Split-Path -Path $file -Leaf).Split(".")[1] +Function Extract_Internals { + Write-Output "Extracting embedded archives. Please wait" + Start-Sleep $sleep + foreach ($item in (Get-ChildItem -Path $extraction_dir -Force -Recurse | % { $_.FullName })) { + $ext = (Split-Path -Path $item -Leaf).Split(".")[1] + $dir = Split-Path -Path $item -Parent foreach ($arc in $archive_types) { - if (($ext -eq $arc)) { - & $quickbms_command -Y $extraction_script $file $extract - cd $extract - Extract-Internals - } else { - break + if (($ext -eq $arc) -And (($dir -like "*SYSTEM*") -Or ($dir -like "*TITLE*") -Or ($dir -like "*IF*"))) { + cd $dir + & $quickbms_command -Y -d $extraction_script $item + cd $cwd } } } } -foreach ($item in (Get-ChildItem -Path $extraction_dir -Force -Recurse -File | % { $_.FullName } )) { - $dir = Split-Path $item -Parent - $file = Split-Path $item -Leaf - $extract = $file + '_extract' - $ext = (Split-Path -Path $file -Leaf).Split(".")[1] - - cd $dir - foreach ($arc in $archive_types) { - if (($ext -eq $arc)) { - & $quickbms_command -Y $extraction_script $file $extract - cd $extract - Extract-Internals - } +Function Extract_Field { + Write-Output "Extracting the Field models" + Start-Sleep $sleep + $field_dir = $game_dir + "\FLD" + foreach ($item in (Get-ChildItem -Path $field_dir -Force -Recurse | % { $_.FullName })) { + $dir = $item.replace(($game_dir + "\"), ($extraction_dir + "\")) + & $quickbms_command -Y -d $extraction_script $item $dir } - cd $cwd } -Start-Sleep $sleep +Function Extract_Battle { + Write-Output "Extracting the Battle models" + Start-Sleep $sleep + $btl_dir = $game_dir + "\BTL" + foreach ($item in (Get-ChildItem -Path $btl_dir -Force -Recurse | % { $_.FullName })) { + $dir = $item.replace(($game_dir + "\"), ($extraction_dir + "\")) + & $quickbms_command -Y -d $extraction_script $item $dir + } +} -Write-Output "Preparing asset extraction" +Function Extract_Gallery { + Write-Output "Extracting the Gallery files" + Start-Sleep $sleep + $gallery_dir = $game_dir + "\GALLERY" + foreach ($item in (Get-ChildItem -Path $gallery_dir -Force -Recurse | % { $_.FullName })) { + $dir = $item.replace(($game_dir + "\"), ($extraction_dir + "\")) + & $quickbms_command -Y -d $extraction_script $item $dir + } +} -if (!(Test-Path -Path $audio_dir -PathType Container)) { - New-Item -Path . -Name $audio_dir -ItemType Directory | Out-Null +Function Extract_Interface { + Write-Output "Extracting the Interface files" + Start-Sleep $sleep + $if_dir = $game_dir + "\IF" + foreach ($item in (Get-ChildItem -Path $if_dir -Force -Recurse | % { $_.FullName })) { + $dir = $item.replace(($game_dir + "\"), ($extraction_dir + "\")) + & $quickbms_command -Y -d $extraction_script $item $dir + } + Extract_Internals } -$audio_dir = Get-Item -Path $audio_dir | % { $_.FullName } +Function Extract_MiniGames { + Write-Output "Extracting the Mini-Games" + Start-Sleep $sleep + $mg_dir = $game_dir + "\Mini_Game" + foreach ($item in (Get-ChildItem -Path $mg_dir -Force -Recurse | % { $_.FullName })) { + $dir = $item.replace(($game_dir + "\"), ($extraction_dir + "\")) + & $quickbms_command -Y -d $extraction_script $item $dir + } +} -if (!(Test-Path -Path $models_dir -PathType Container)) { - New-Item -Path . -Name $models_dir -ItemType Directory | Out-Null +Function Extract_MemoryCard { + Write-Output "Extracting the Memory Card Volume" + Start-Sleep $sleep + $item = $game_dir + "\PSP_GAME\USRDIR\GAMEDATA\MC.VOL" + $item = Get-Item -Path $item | % { $_.FullName } + $dir = $item.replace(($game_dir + "\"), ($extraction_dir + "\")) + $dir = Split-Path $dir -Parent + & $quickbms_command -Y -d $extraction_script $item $dir } -$models_dir = Get-Item -Path $models_dir | % { $_.FullName } +Function Extract_System { + Write-Output "Extracting the System Volume" + Start-Sleep $sleep + $item = $game_dir + "\PSP_GAME\USRDIR\GAMEDATA\SYSTEM.VOL" + $item = Get-Item -Path $item | % { $_.FullName } + $dir = $item.replace(($game_dir + "\"), ($extraction_dir + "\")) + $dir = Split-Path $dir -Parent + & $quickbms_command -Y -d $extraction_script $item $dir + Extract_Internals +} -Start-Sleep $sleep +Function Extract_Title { + Write-Output "Extracting the Title Volume" + Start-Sleep $sleep + $item = $game_dir + "\PSP_GAME\USRDIR\GAMEDATA\TITLE.VOL" + $item = Get-Item -Path $item | % { $_.FullName } + $dir = $item.replace(($game_dir + "\"), ($extraction_dir + "\")) + $dir = Split-Path $dir -Parent + & $quickbms_command -Y -d $extraction_script $item $dir + Extract_Internals +} -Write-Output "Extracting and converting assets" - -foreach ($item in (Get-ChildItem -Path $extraction_dir -Force -Recurse -File | % { $_.FullName } )) { - $dir = Split-Path $item -Parent - $file = Split-Path $item -Leaf - $extract = $file + '_extract' - $ext = (Split-Path -Path $file -Leaf).Split(".")[1] - - # Generate a UID for assets so that all converted files can be placed in Audio directory if they have are named the same on disc - $guid = New-Guid - $audio = (Split-Path -Path $file -Leaf).Split(".")[0] - $audio = $audio + '-' + $guid + '.wav' - - $model = (Split-Path -Path $file -Leaf).Split(".")[0] - $model = $model + '-' + $guid + '.mdl' - - cd $dir - if ($ext -eq "at3") { - & $vgmstream_command $file -o $audio - Move-Item -Path $audio -Destination $audio_dir - } elseif (($ext -eq "mdl") -Or ($ext -eq "md")) { - Copy-Item -Path $file -Destination $model - Move-Item -Path $model -Destination $models_dir - } - cd $cwd +Function Extract_All { + Extract_Field + Extract_Battle + Extract_Gallery + Extract_Interface + Extract_MiniGames + Extract_MemoryCard + Extract_System + Extract_Title } -Start-Sleep $sleep +$Continue = 1 + +Function Get_User_Input { + Write-Output "What would you like to do today?" + Write-Output "1) Extract the Field models" + Write-Output "2) Extract the Battle models" + Write-Output "3) Extract the Gallery files" + Write-Output "4) Extract the Interface files" + Write-Output "5) Extract the Mini-Game files" + Write-Output "6) Extract the Memory Card Volume" + Write-Output "7) Extract the System Volume" + Write-Output "8) Extract the Title Volume" + Write-Output "a) Extract the important things" + Write-Output "q) Quit the program" + Write-Output "d) Remove extracted files" + + $input = Read-Host "Type value and press enter" + + if ($input -eq 'q') { + break + } + if ($input -eq 'a') { + Extract_All + } + if ($input -eq 'd') { + Delete + } -Write-Output "Removing empty folders" + switch ($input) { + 1 { Extract_Field } + 2 { Extract_Battle } + 3 { Extract_Gallery } + 4 { Extract_Interface } + 5 { Extract_MiniGames } + 6 { Extract_MemoryCard } + 7 { Extract_System } + 8 { Extract_Title } + default {} + } +} -Get-ChildItem -Path $extraction_dir -Force -Recurse -Directory | - Sort-Object -Property FullName -Descending | - Where-Object { $($_ | Get-ChildItem -Force | Select-Object -First 1).Count -eq 0 } | - Remove-Item +Do { + Get_User_Input +} While ($Continue -eq '1') -cd $cwd +Clean -Start-Sleep $sleep +Write-Output "Have a wonderful day! Happy modding, digging, and BRSing!!! :D" -Write-Output "Extraction finished." -Write-Output "Models, Audio and other extracted assets can be found in the Assets folder" \ No newline at end of file +#Write-Output "Models, Audio and other extracted assets can be found in the Assets folder" \ No newline at end of file diff --git a/Disc Map/GAMEDATA/FLD/FCHR/FCHR.MD b/Disc Map/GAMEDATA/FLD/FCHR/FCHR.MD index 46975ef..01708ce 100644 --- a/Disc Map/GAMEDATA/FLD/FCHR/FCHR.MD +++ b/Disc Map/GAMEDATA/FLD/FCHR/FCHR.MD @@ -1,6 +1,20 @@ # FCHR.BIN Data Structures -* NOTE: All of the files here are SC (Stacked Container) types related to a variety of different game assets. Until we figure out what exactly FLD and FCHR stand for, I won't be fully documenting this section. All of these were contained within GZip compressed BIN files within `GAMEDATA\FLD\FCHR` on the game disc. +This document is separate from the individual FCHR files because there's a specific structure to the entire section (that I will refer to as Namespaces from here on out). + +## Namespaces + +* FCHR_B - Bosses + +* FCHR_G - Gimmicks/Gizmos/Game Objects - It's a grab bag of multiple types of models that are mostly interacted with by the player but aren't enemies + +* FCHR_M - Mobs - All of the non-boss enemies the player fights + +* FCHR_P - Playable Characters (see SCPM in FileFormats.md doc for notes on a possible second character found) + +* FCHR_S - Skills + +* FCHR_W - Weapons ===================================================================== diff --git a/README.MD b/README.MD index 1b44ef9..b4223b2 100644 --- a/README.MD +++ b/README.MD @@ -3,19 +3,23 @@ This repository will host my findings and various scripts, tools and documentation I've put together from diving into [Black Rock Shooter: The Game](https://web.archive.org/web/20150328084959/http://brs.jrpg.jp/) for the Playstation Portable handheld console. It's a work in progress and contributions are welcomed. All that I ask is that any projects that use anything from this repository will link back here and not claim ownership of anything within. ===================================================================== -## How to Extract the Game Files for Beginners +## How to Quickly Extract Most of the Game Data -* Download and install a modern version of Windows Powershell: https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell?view=powershell-7.4 +* Download and install a modern version of Windows [Powershell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell?view=powershell-7.4) -* Copy the `PSP_GAME` directory from a ripped and extracted release of Black Rock Shooter: the Game into the `Game` folder in this directory +* Copy the `PSP_GAME` directory from a ripped and extracted release of Black Rock Shooter: the Game into the `Game` folder -* Open the folder this Directory is in and right-click->Open in Terminal +* Right click and Click "Open in Terminal" -* Run: `.\BRS-Extract.ps1` +* Type `.\BRS-Extract.ps1` and hit enter to run this script -* If you don't have the `Tools` directory or any of the tools installed, it will ask you if you want to download and install them. Type 'y' for yes. This should be the only time you'll need to input anything. +* If you don't have the `Tools` directory or any of the tools installed, it will ask you if you want to download and install them. Type 'y' to download. -* Wait for the script to finish. It can take 15+ minutes due to just how many files there are. +* When prompted, choose what all you want to extract. + +* Wait for the script to finish extracting the game files. This used to take 15+ minutes but current optimizations have drastically dropped that number. + +* All of the scripts will frequently receive updates for as long as they are needed to improve the process, so expect possible breakage from time to time but updating regularly hopefully won't be required as much. * NOTE: Depending on your security settings, Windows may say it can't run Powershell scripts. If this happens, you'll either need to run the script with elevated privileges or temporarily set your policy to allow it. See [here](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-7.4) for more information @@ -32,19 +36,21 @@ This repository will host my findings and various scripts, tools and documentati * [7-zip](https://www.7-zip.org/) - for extracting the game disc mostly. All of the main archive types can be extracted with BRS-extract.bms without the need of external tools. -* [Vgmstream-cli](https://github.com/vgmstream/vgmstream) - for converting at3 files into a user playable format +* [K-Lite Mega Codec Pack](https://www.codecguide.com/download_k-lite_codec_pack_mega.htm) - Install this with all codec options selected, the audio files for the game won't need to be converted; converting can possibly make modding them an issue when reinjecting them or replacing them in the game (testing needed) ===================================================================== ## Optional Tools * [Offzip](https://aluigi.altervista.org/mytoolz/offzip.zip) - for extracting data from ZZZ archives; extraction script should work with all of these without issues now +* [Vgmstream-cli](https://github.com/vgmstream/vgmstream) - for converting at3 files into a user playable format; probably not needed if an audio editing tools is found that can work with the audio as is + ===================================================================== ## Navigating This Repository The folder structure is meant to be pretty straight forward, but here's what they represent: -* Disc Map - To help find specific files on the disc without having to fully navigate each directory. If a file is an archive or container, the "Contents" of them will be listed once extracted (unless unnecessary). +* Disc Map - To help find specific files on the disc without having to fully navigate each directory. If a file is an archive or container, the "Contents" of them will be listed once extracted (unless unnecessary) * Game - Where the game files go @@ -52,9 +58,7 @@ The folder structure is meant to be pretty straight forward, but here's what the * Specifications - The documentation here is meant to be more for tool makers, modders and developers. It's all technical and deals heavily with memory structures of different formats, encryption, etc. -* Tools - Where the tools are downloaded and installed for extracting the game files; right now, this only supports Windows but shouldn't be super hard to get working on the BSDs, Linux, Mac, etc - -* Assets - When running the automatic extraction script, any sound files, models, and possibly other asset types will be found in their own directories here. This is for convenience but do note that on subsequent extractions, there will be duplicates of everything unless you remove or move this folder somewhere else +* Tools - Where the tools are downloaded and installed for extracting the game files; right now, this only supports Windows but shouldn't be difficult to get working on the BSDs, Linux, Mac, etc ===================================================================== ## Current TODO diff --git a/Scripts/BRS-Extract.bms b/Scripts/BRS-Extract.bms index 36913d0..44fe6cd 100644 --- a/Scripts/BRS-Extract.bms +++ b/Scripts/BRS-Extract.bms @@ -47,6 +47,14 @@ elseif FILE_TYPE == "at3" callfunction extract_riff elseif FILE_TYPE == "efp" | FILE_TYPE == "efc" callfunction extract_efp +else + goto 0x00 + get BYTE byte + if BYTE == 0x53 + set CURRENT_FILE_START 0x00 + set FILE 0 + callfunction extract_sc 1 FILE CURRENT_FILE_START + endif endif startfunction extract_vol @@ -122,6 +130,8 @@ startfunction file_builder getdstring MAGIC_NUMBER 0x04 if MAGIC_NUMBER == "PTMD" | MAGIC_NUMBER == "PTM" set EXTENSION ".ptm" + elseif MAGIC_NUMBER == "SSCR" + set EXTENSION == ".ss" elseif MAGIC_NUMBER == "LPK" set EXTENSION ".lpk" elseif MAGIC_NUMBER == "INSA" @@ -163,15 +173,19 @@ startfunction file_builder set EXTENSION == ".xbn" elseif MAGIC_NUMBER == "EFC" set EXTENSION == ".efc" - elseif MAGIC_NUMBER == "SC" - set EXTENSION == ".sc" else goto CURRENT_FILE_START get MAGIC_NUMBER byte if MAGIC_NUMBER == 0x1f # Sort of hack since only a single GZip version exists in the files set EXTENSION ".gz" - elseif MAGIC_NUMBER == 0x0c - set EXTENSION == ".esb" + # Cover specific SC files that have issues being detected + elseif MAGIC_NUMBER == 0x53 + get SECOND_NUMBER byte + getbits HIERARCHY 0x08 + get FOURTH_NUMBER byte + if SECOND_NUMBER == 0x43 & FOURTH_NUMBER == 0 + set EXTENSION ".sc" + endif else set EXTENSION ".pbd" endif @@ -212,7 +226,7 @@ startfunction extract_gzip # This is a bit of a hack to cover the archive files in multiple locations so they extract with the proper extension string TMP = FILE string TMP % "_" - if TMP == "FCHR" | TMP == "FEVT" | TMP == "MAP" # For FLD + if TMP == "FCHR" | TMP == "FEVT" | TMP == "FEVT2" | TMP == "MAP" | TMP == "BTL" | TMP == "EV" # For FLD string FILE + ".SC" elseif TMP == "GLR" | TMP == "MINI" | TMP == "IF" | TMP == "MENU" # For Gallery string FILE + ".LPK" @@ -315,6 +329,9 @@ startfunction extract_efp else # Check if an esb file is embedded with a crazy hack since they only have a name and a size to distinguish their section but are always found at the very end of the EFC file get NAME FILENAME + if NAME == "TEMPORARY_FILE" + set NAME FILE + endif string NAME - ".efc" string NAME + ".esb" get SIZE asize @@ -375,6 +392,33 @@ startfunction extract_ptmd goto OFFSET endfunction +startfunction extract_sc +endfunction + +startfunction extract_sscr + # Grab the end of the file by recursively setting DATA_END + set DATA_END CURRENT_FILE_START + math DATA_END + 0x18 + goto DATA_END + get DATA_END long + goto DATA_END + savepos OFFSET + callfunction file_builder 1 FILE CURRENT_FILE_START OFFSET +endfunction + +# This builds an array of bit values I can compare to +startfunction power_of_two + set BIT 0 + for i = 0 < 8 + if i = 0 + set BIT = 1 + else + math BIT * 2 + endif + putarray POW2 i BIT + next i +endfunction + startfunction extract_riff print "Use VGMStream or any other audio conversion tool that supports the Atrac3 codec" endfunction diff --git a/Scripts/BRS-Model-Data.bms b/Scripts/BRS-Model-Data.bms index b9c40c4..4890c59 100644 --- a/Scripts/BRS-Model-Data.bms +++ b/Scripts/BRS-Model-Data.bms @@ -1,85 +1,20 @@ -idstring "INSM" +#Copyright 2024 - Brad D +#See LICENSE for copyright information. +#Please include this header and that license for any derivative works. +# +# Just a simple script for finding vertex data inside of various file formats; all are of the float type and typically come in patterns of 4-7 lines with break in a section -# Start getting some known variables -set EMBED_START 0x34 # to get embedded section if it exists -set DATA_START 0x28 -set VERTEX_OFFSET 0x2c -set CHUNK 0x04 get SIZE asize -set ARBITRARY_NUMBER 10000000000 -set VERTEX_STRIDE 0x1c # Distance between Vertex Buffers - -# Recursively replace known locations with their values since those are address locations in the ROM -goto EMBED_START -get EMBED_START long - -goto DATA_START -get DATA_START long - -goto VERTEX_OFFSET -get VERTEX_OFFSET long - -# Do some math to get where the first data section ends so we can access the rest of the Vertex Data in the next section -set VERTEX_START VERTEX_OFFSET -math VERTEX_START + DATA_START - -# Get the total size of the VERTEX_DATA section -set VERTEX_DATA_SIZE EMBED_START -math VERTEX_DATA_SIZE - DATA_START - -set TRIS VERTEX_DATA_SIZE -math TRIS / VERTEX_STRIDE - -# Get the amount of lines to part before moving to next triangle -set LINES VERTEX_STRIDE +set CHUNK 0x04 +set LINES SIZE math LINES / CHUNK - -# Start the parsing here -goto DATA_START +goto 0 savepos CUR_POS - -# Create a Vertex Array to house the data -set SHIFT VERTEX_OFFSET -set START_POS CUR_POS -math SHIFT + START_POS - -for i = TRIS > 0 - if CUR_POS > EMBED_START | CUR_POS == EMBED_START | START_POS > VERTEX_OFFSET | START_POS == VERTEX_OFFSET - break - endif - print "TRI: %i%" +for i = 0 < LINES goto CUR_POS - for k = 0 < 4 - get WHAT long - string T = WHAT - string T b T - if T != "00000010" - #print "CURRENT_OFFSET: %CUR_POS% ==== WHAT: %T%" - print "WHAT: %T%" - else - savepos START_POS # So that we can come back to the chunk right after - goto SHIFT - set CUR_POS SHIFT - # Reset SHIFT so it doesn't stack the offsets - set SHIFT VERTEX_OFFSET - math SHIFT + START_POS - endif - set TMP CUR_POS - math TMP + CHUNK - set CUR_POS TMP - next k - for k = 0 < 4 - get VERTEX float - if VERTEX > -257 & VERTEX < 257 - #print "CURRENT_OFFSET: %CUR_POS% ==== VERTEX: %VERTEX%" - print "VERTEX: %VERTEX%" - else - math k - 1 - math VERTEX_OFFSET - CHUNK - endif - set TMP CUR_POS - math TMP + CHUNK - set CUR_POS TMP - next k - set CUR_POS START_POS -next i - 1 \ No newline at end of file + get VERTEX float + savepos CUR_POS + if VERTEX > -257 & VERTEX < 257 # Vertex data is primarily between -0xff and 0xff despite being stored in 4-byte chunks + print "CUR_POS: %CUR_POS% <=> VERTEX: %VERTEX%" + endif +next i \ No newline at end of file diff --git a/Scripts/BRS-Xor.bms b/Scripts/BRS-Xor.bms deleted file mode 100644 index 059fcf3..0000000 --- a/Scripts/BRS-Xor.bms +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2024 - Brad D -# See LICENSE for copyright information. -# Please include this header and that license for any derivative works. -# NOTE: Only the documentation, tools and anything that's not directly a part of the game's data fall under this copyright. I don't claim any ownership of the game or any of its assets - -# Just decode files with all known decoder keys to see which ones produce the correct results; -# I plan to clean this up later -get SIZE asize - -if SIZE != 0 - getdstring MAGIC_NUMBER 0x08 # some of the magic numbers take up 16 bytes (example: PTMD-XP) - -# Key 0x55 - mostly for directories but can have issues with scripts -set XORKEY "0x55" -set FILE decoded-55 - -filexor XORKEY 0 -append -log FILE 0 SIZE \ No newline at end of file diff --git a/Scripts/README.MD b/Scripts/README.MD index 55be025..092c5ee 100644 --- a/Scripts/README.MD +++ b/Scripts/README.MD @@ -1,8 +1,8 @@ Use these files to extract data from the game's ROM. These are subject to change and some may be usable for other games. -* BRS-Extract - New script for extracting files. BRS-Vol.bms and BRS-Lpk.bms are no longer needed. BRS-Xor.bms will still be needed for decryption of some files. +* BRS-Extract.bms - New script for extracting files. BRS-Vol.bms, BRS-Xor.bms and BRS-Lpk.bms are no longer needed.All main extraction code is in this file -* BRS-Xor.bms - many files inside of archives will be encrypted. Run this on those files to see which XOR encryption was used. This one is going to possibly change quite a bit as more keys are found. +* BRS-Model-Data.bms - Used this quick and dirty script for finding bones and vertices in model data. ===================================================================== diff --git a/Specifications/3D-Pipeline-Notes-and-Observations b/Specifications/3D-Pipeline-Notes-and-Observations new file mode 100644 index 0000000..30f0410 --- /dev/null +++ b/Specifications/3D-Pipeline-Notes-and-Observations @@ -0,0 +1,26 @@ +# 3 D Pipeline, Rigging and Animation Observations + +This documentation is meant to be a simple way to convey concepts based on my observations related to how the game's rendering system works with a heavy focus on the 3D rendering pipeline and design decisions. It's a fluid document and will be changed where needed as new discoveries are found but hopefully will help others understand how the game was built. + +* Everything is built using quads instead of triangles + +* Extracting most of the internal files like lpks, efps, etc is probably not the best way to handle them since they are essentially the entire model package shredded into smaller pieces so that they can be swapped out and reused when needed for battles; much of the data needed for converting to a more friendly format won't be found in just one part of each but instead spread out a bit. + +* Outside of the SSCR sections of SC containers, most of the scripting language used in the `bms` files are exclusive to combat meaning that figuring out how the scripting system works would be less important to rendering and more gameplay related, although, they do tell what modules are used where in each encounter; this could theoretically help stitch together the pieces required to make a functional battle model that modders can work with + +* Most of the modularization is exclusive to the the battle system but figuring out how everything interacts there applies to anything on the field or in the gallery (which uses meshes and materials for their assets) + +* Cameras and the maps themselves are built on the same general rigging system as the models + +* The formats used for storing assets are non-standard but do seem to have a fairly strict structure with some having shared general locations of tables and other important data + +* Some of the interface elements may be 3D but are viewed as 2D, so any discoveries related to character models should apply here + +================================================================== +*Copyright 2024 - Brad D* + +*See LICENSE for copyright information.* + +*Please include this header and that license for any derivative works.* + +*NOTE: Only the documentation, tools and anything that's not directly a part of the game's data fall under this copyright. I don't claim any ownership of the game or any of its assets* \ No newline at end of file diff --git a/Specifications/File Formats.md b/Specifications/File Formats.md index 2ffc0e9..3f729ef 100644 --- a/Specifications/File Formats.md +++ b/Specifications/File Formats.md @@ -40,10 +40,10 @@ This documentation is mostly here to help structure, describe and name the vario ================================================================== * Tentative Name: Plot Thickens, My Dear -* Type: Data +* Type: 3D Pipeline Data * Extension: .ptm * Header: PTMD, PTM, PTMD-XP -* Purpose: General purpose data type related to visual assets +* Purpose: Contains textures, materials and other data related to models and user interface elements * Structure: * 0x08 - This looks like it may be some kind of ID * 0x0c - Offset from Header / Size of file (can be around 0x400 less than what Windows shows the file size to be, possibly due to padding) @@ -66,30 +66,69 @@ This documentation is mostly here to help structure, describe and name the vario * Notes: * Uses some duplicate structures as LPK but is considered a separate File Type due to being unique * Structure: + * Currently Unknown how similar it is to a normal LPK ================================================================== -* Tentative Name: Stacked Container -* Type: Container / Data archive -* Extension: .sc +* Tentative Name: Skeletal Container +* Type: Container / 3D Pipeline Data +* Extension: .sc(hierarchy value) * Header: SC -* Purpose: General purpose container that is often packed together more tightly than other ones +* Purpose: Houses the main models, riggings and animation data * Notes: - * Almost always has other file types inside (such as INSM, INSA, and SSCR) - * Can contain any amount of other types - * Each container wrapped with SC + * SC's have a multilevel hierarchy based on the bit value of the byte after the header * Structure: - * 0x04 - Internal Container list start - * 0x24 - Internal Container list end - * 0x24 - Main Container end - * Each internal container list data takes up 8-bytes with the first 4-bytes being the start point and last 4-bytes being the end - * Every end can become the start point of the next stored data (hence why these begin and end with the SC header) + * 0x00 - (2-bytes) Header + (1-byte) Hierarchy level + 0 = Magic Number + * Hierarchy (by Bit Flag; rest are internals) + * 0x80 (Bit8) - Unknown + * 0x40 (Bit7) - Field Event Armateur Skeleton (Internal to 0x10) + * 0x3D - Field Object/Enemy Armateur Skeleton (Probably destructable or interactive) + * 0x34 - Field Player Character Armateur Skeleton + * 0x20 (Bit6) - Field Map EFC Skeleton + * 0x1D - Field SUM00P Armateur Skeleton + * 0x16 - Field Enemy Armateur Skeleton + * 0x14 - Field Skill (?) Armateur Skeleton + * 0x10 (Bit4) - Field Event/Map Skeleton Top Level (Probably related to Cutscenes) - Can contain multiple 0x40 SC's / SSCR's + * 0x0A - Field SUM00 Armateur Skeleton + * 0x0B - Field SUM Armateur Skeleton (Rest of SUM's use this + RID Gimmicks) + * 0x0C - Field Test Enemy Armateur Skeleton + * 0x09 - Same as 0x03 (Multiple TEST FEVTs) + * 0x08 (Bit 3) - Field Character/Map Skeleton Top Level (Can contain an internal STCM if a Map) + * 0x04 (Bit2) - Unknown + * 0x03 - Test Field Event with BTL Model data (FEVT_TEST_AOIK00) + * 0x02 (Bit1) - Field Event PHD Skeleton + * 0x01 (Bit0) - Field Character Skeleton Without Armateur + * 0x00 - Field Event Unused SC data + types (FEVT_TEST_KAMI00) - There were multiple different data types unique to this section found here + + * 0x04 - Internal Container list start - Can be 0x3c for some models; that's a bug that doesn't seem to affect the game but will break the extraction process + * 0x08 - First internal object ends here but not guaranteed to help with any extra extraction + * The rest of this section is variable based on how big the SC container is, so may have to wing it quite a bit to get anything extracted ================================================================== -* Tentative Name: Super Stacked ContaineR -* Type: Container -* Extension: None known +* Tentative Name: Skeletal Container Missing Player +* Type: Container / 3D Pipeline Data +* Header: SCMP +* Purpose: Possible unused Player Character model +* Notes: + * Seems to be the only SC container that doesn't have an SSCR section but instead contains an extra SCMP section in its place + * Shares the same Namespace as the BRS model meaning it's probably a scrapped Player character + * The header suggests that there may have been a scrapped Multiplayer mode and this was the character for it + * Codenamed ZIG in the files + +================================================================== +* Tentative Name: Scripted Skeletal Character Rigging +* Type: 3D Pipeline Data +* Extension: .ss * Header: SSCR -* Purpose: Not fully known but these seem to be an extension of SC and contain much of the Scripted data. +* Purpose: Controls the animation and armatures for animated 3D Models +* Notes: + * This was first discovered on a random hunch while out for food. A quick script to check for vertex values found BRS's model pretty quickly under the `BTL\FLD\FCHR` directory + * Often found inside of SC containers +* Structure: + * 0x0c - Scripted Data Section Start + * 0x10 - Scripted Data String End Address + * 0x14 - Scripted Data Section End Address + * 0x18 - SSCR Data End Address (Everything below is padding) + * 0x2c - Scripted Data String Start Address ================================================================== * Tentative Name: Playing Donkey Kong @@ -132,18 +171,16 @@ This documentation is mostly here to help structure, describe and name the vario * Type: Container * Extension: .efc * Header: EFC -* Purpose: Exactly the same as EFP's with one difference. +* Purpose: Alternative version of EFP found heavily inside of SCs. * Notes: - * Difference: Includes an embedded ESB file with only a size, a name and some data - * These also exist in very small quantities + * Originally thought a unique type but `BTL\CHR\BCHR_CAT00` contains an EFP with multiple ESB files inside ================================================================== * Tentative Name: Effective Stealthy Binary * Type: Data * Extension: .esb * Header: None -* Notes: - * Consistently found as one of the last embedded objects inside of what would otherwise be an EFP +* Purpose: Unknown * Structure: * 0x00 (2 bytes) - Size of data @@ -152,34 +189,43 @@ This documentation is mostly here to help structure, describe and name the vario * Type: Data * Extension: .cam (if INSA structures are found) * Header: INSM -* Purpose: Stores model data +* Purpose: Stores model data without the texture or material data * Structure: - * 0x34 - Offset of INSA structure from Header + * See the next section for structure; they're both mostly the same =================================================================== * Tentative Name: Internal Node Structure Model * Type: Data * Extension: .mdl (if PTMD or alternative structures are found within) * Header: INSM -* Purpose: Stores model data +* Purpose: Stores model, texture and material data * Notes: - * Vertex Stride: 0x0c (first section); 0x14 (second section) + * Vertex Stride seems to vary a bit depending on where the model will be seen in game; ranges between 4 and 8 lines from what I've observed with some junk here and there that must be skipped on read + * Vertex Data Section ranges from where 0x3c starts to just before the location at 0x34 * Structure: + * 0x10 - Address where padding starts before embedded section + * 0x18 - Address to unknown data structure + * 0x24 - Address where the math calculation tables start + * 0x28 - Start position of Unknown Data section - patterns of floats have been found here and at 0x2c but not sure what they're for yet + * 0x2c - Offset from 0x28 to get to the a Second Unknown Data Section * 0x34 - Offset of PTMD or alternative structures from Header - * 0x28 - Start position of First Data section - * 0x2c - Offset from 0x28 to get to the Second Data Section + * 0x3c - Vertex Data Section Start Address (where model quads are found) =================================================================== * Tentative Name: Internal Node Structure Animation * Type: Data * Extension: .anm * Header: INSA -* Purpose: Stores animation data +* Purpose: Stores animation and armateur data * Notes: * Can be embedded inside of an INSM container * 24-byte name string found at Offset -0x18 from start when embedded * Structure: * 0x1c - Offset from Header / Size of file + * 0x18 - End of data address before padding + * 0x2c - Address to a table of addresses to other tables and locations in memory; may be related to rigging or bones but not completely sure yet + * 0x28 - (2-bytes) Address to Unknown Data Section + * 0x1d8 - Unknown Data starts here ================================================================== * Tentative Name: Extensible Text Container @@ -244,11 +290,14 @@ This documentation is mostly here to help structure, describe and name the vario ================================================================== * Tentative Name: Everything Does eXtensive Duties +* Type: Data * Extension: .edx * Header: EDXD -* Purpose: Unsure what this is for as of now +* Purpose: Archive padding with very little data inside +* Notes: + * All are of 1.5 KB in size and found only inside of `GAMEDATA\BTL\BCHR` directory * Structure: - * Currently Unknown + * 0x5c - Shared value among most if not all edx files - 8FED8D55 ================================================================== * Tentative Name: BRS eXtensible Contancorous Binary