├── .gitattributes ├── .gitignore ├── CONTRIBUTING.md ├── Inspector.bt ├── autoload.bt ├── checksums ├── compressed │ ├── Legend of Zelda, The - Majora's Mask (E) (M4) (Debug Version).z64.csv │ ├── MMDBG(zeroed).z64.csv │ ├── MMDBG.z64.csv │ └── The Legend of Zelda Majora's Mask Debug.n64.csv └── decompressed │ ├── Legend of Zelda, The - Majora's Mask (E) (M4) (Debug Version)(ndec clean).z64.csv │ ├── Legend of Zelda, The - Majora's Mask (E) (M4) (Debug Version)(ndec).z64.csv │ ├── Legend of Zelda, The - Majora's Mask (E) (M4) (Debug Version).z64.csv │ ├── Legend of Zelda, The - Ocarina of Time - Master Quest (E) (GC) (Debug Version).z64.csv │ ├── MMDBG(ndec clean).csv │ └── MMDBG(ndec).csv ├── docs ├── 010editor_features_i_would_like.md ├── 010tips.md ├── cliff_notes.md ├── misc_notes.md └── quickstart_guide.md ├── filetypes ├── Animation │ └── Link │ │ ├── LinkAnimationFrame.bt │ │ └── LinkAnimationHeader.bt ├── Audio │ ├── ChannelHead.bt │ ├── Instrument.bt │ ├── InstrumentSet.bt │ ├── Sample.bt │ ├── Sequence.bt │ └── SequenceHead.bt ├── Banks.bt ├── Compressed │ └── Yaz.bt ├── DamageCharts.bt ├── DisplayList │ ├── Commands │ │ ├── DA.bt │ │ ├── DF.bt │ │ └── Dummy.bt │ ├── DisplayList.bt │ └── DisplayListScanner.bt ├── Entrances.bt ├── FileSystem.bt ├── MIPS │ ├── Commands │ │ ├── ADDI.bt │ │ └── ADDIU.bt │ ├── MIPS_Code.bt │ └── MIPS_CodeScanner.bt ├── Memory.bt ├── Messages.bt ├── N64ROMHead.bt ├── NIFF │ ├── Cam.bt │ ├── Common.bt │ ├── Env.bt │ ├── Light.bt │ ├── NIFF.bt │ ├── NIFFFlags.bt │ ├── NIFFTags.bt │ ├── Scene.bt │ └── Tex.bt ├── Overlay │ ├── Actor.bt │ ├── Dummy.bt │ ├── Files │ │ ├── En_GirlA.bt │ │ └── map_marker_data.bt │ ├── Object.bt │ └── OverlayHeader.bt ├── Save │ ├── SaveFile.bt │ └── SaveParts.bt ├── Scene │ ├── HC │ │ ├── ZHC_Actor.bt │ │ ├── ZHC_AltCamera.bt │ │ ├── ZHC_AltHeader.bt │ │ ├── ZHC_Camera.bt │ │ ├── ZHC_Collision.bt │ │ ├── ZHC_Cutscene.bt │ │ ├── ZHC_Entrance.bt │ │ ├── ZHC_Environment.bt │ │ ├── ZHC_Exit.bt │ │ ├── ZHC_Map.bt │ │ ├── ZHC_Mesh.bt │ │ ├── ZHC_Object.bt │ │ ├── ZHC_Path.bt │ │ ├── ZHC_RoomBehavior.bt │ │ ├── ZHC_StartPos.bt │ │ ├── ZHC_TransitionActor.bt │ │ ├── ZHC_UnusedEnvironment.bt │ │ ├── _ZHC_End.bt │ │ ├── _ZHC_Skybox.bt │ │ ├── _ZHC_SkyboxMod.bt │ │ ├── _ZHC_Sound.bt │ │ ├── _ZHC_SpecialObjects.bt │ │ ├── _ZHC_Time.bt │ │ ├── _ZHC_Unknown1A.bt │ │ ├── _ZHC_Unknown1B.bt │ │ ├── _ZHC_Unknown1C.bt │ │ ├── _ZHC_Unknown1D.bt │ │ ├── _ZHC_Unknown1E.bt │ │ ├── _ZHC_Unused09.bt │ │ └── _ZHC_Wind.bt │ ├── HeaderCommand.bt │ └── Scene.bt ├── Simple.bt └── Texture │ ├── JFIF.bt │ ├── ci4.bt │ ├── ci8.bt │ ├── i4.bt │ ├── i8.bt │ ├── ia16.bt │ ├── ia4.bt │ ├── ia8.bt │ ├── rgb5a1.bt │ └── rgba32.bt ├── readme.md ├── scaffolds ├── Anomaly.bt ├── Assert.bt ├── Bits.bt ├── Block.bt ├── Bucket.bt ├── Colors.bt ├── Jumps.bt ├── Padding.bt ├── Significant.bt └── Unknown.bt ├── scripts ├── CurPosInDec.1sc ├── CurPosInHex.1sc ├── DumpAllYaz.1sc ├── FixSaveMM.1sc └── FixSaveOoT.1sc ├── skeleton.bt ├── templates ├── dMM_E_debug-save.bt ├── dMM_E_debug.bt ├── dOoTMQ_E_debug-save.bt └── dOoTMQ_E_debug.bt └── todo.md /.gitattributes: -------------------------------------------------------------------------------- 1 | *.bt linguist-language=C 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dont_tell_dad.md 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | These aren't absolute musts, but they really help out. The current codebase might not obide 100% by all these, but you could help make it. 3 | 4 | ## [Ensure You're Set Up](docs/quickstart_guide.md). 5 | Checking the [Quickstart Guide](docs/quickstart_guide.md) might answer questions you had before you knew you had them. 6 | 7 | ## Code Style 8 | * You should always import [autoload.bt](/autoload.bt). It has important scaffolds and takes virtually no processing time, plus it sets your template's endian and bitfields up right. If you are bothered by the default colors, use the macro `SIOFF;` to disable coloring and `SION;` to turn it back on. 9 | * FSeek as little as possible, and when you do, use the macro `SAVE;` before doing so and `REST;` after allocating all the bytes necessary. This will push the current position to a stack and then pop after returning to the stored location. 10 | * If you are certain you have an individual variable, put `SIT;` on the line before it to change the color automatically. 11 | * If you have bytes in a struct that are unknown, put `UNK;` on the line before them. This makes it easier to find and report them later. 12 | * Traditionally, an unknown is declared as `ubyte unknown[numBytes];` where the name gets a number in the event of more unknowns, e.g. `ubyte unknown2[numBytes];`. 13 | * The naming conventions for unknowns apply to bytes anticipated to be null, expressed as `ubyte zeroes[numBytes];`. After declaring a ubyte array of zeroes, the line after it should contain `AssertUBytesZero( zeroes, thisName+"->zeroes");` to hault execution in the event padding is misaligned. 14 | * Macros like `UNK;` and `SIT;` are decorators, put them on the same line with a space between them in that order when convenient. 15 | 16 | ### Numbers 17 | * It's easier to define constants as hex if they can possibly get bigger than sixteen. 18 | 19 | * If an enum has unknown values or holes in it, explicitly define each value and leave the comment `// ...` where holes are. This way we can raise warnings when an enum has an unknown value. 20 | * Whenever possible, try to use `startof()` instead of storing a location in memory. The same goes for using `sizeof(this)` for finding the end of a structure. 21 | * Try to use `parentof()`, but only when a structure has a simple lineage or whatever behavior utilizing it is operating on abstract / common values. 22 | * Structures should begin with `local string thisName = "ThisStructName";` so the info can be obtained pragmatically. 23 | * After a structure's thisName, use the macro `SIBE;` to signify the beginning of a structure. `SIEND;` should be the last variable in your structure. 24 | * If you're reading bits into a temporary variable, you should use the `Read*Bits()` functions provided by [Bits.bt](/scaffolds/Bits.bt) to reduce the number of bit shifts in the source. 25 | * By default, running a template shouldn't print any text unless a function is included somewhere to print. Printing text should be done through scaffold-based methods. 26 | 27 | ## Git Flow 28 | 1. Check for [existing issues](https://github.com/EntranceJew/zelda-binary-templates/issues) in the repo. 29 | 2. If the issue requires a bigger change you may want to submit the issues without the necessary changes first, so we can confirm the issue and know that you're working on fixing it. You should also create a WIP (work in process) pull request prefixed with ``[WIP]`` early so we can already start reviewing them. 30 | 3. Fork the project, clone it and make your changes in an extra branch with a proper branch name `bugfix/`, `patch/`, `feature/`. Make sure you're up to date with master before making a new branch. 31 | 4. Make sure your changes don't raise any extra assertions. 32 | 5. Submit the pull request with a short summary what you've changed. 33 | 6. If you make additional changes, push new commits to your branch. **Do not squash your changes**, that makes it extremely hard to see what you've changed compared to the previous version of your pull request. -------------------------------------------------------------------------------- /Inspector.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | //----------------------------------- 3 | //--- 010 Editor v4.0 Binary Template 4 | // 5 | // File: Inspector.bt 6 | // Author: SweetScape Software 7 | // Revision: 1.1 8 | // Purpose: This template may be used 9 | // to customize the auto tab of the 10 | // Inspector with your own variables. 11 | // See the Inspector section of the 12 | // Options dialog for more information. 13 | // Changes: 14 | // 1.1 (SweetScape): 15 | // - Added hfloat data type. 16 | //----------------------------------- 17 | RequiresVersion( 4.0 ); 18 | 19 | // Calculate the position for each variable, 20 | // either at the beginning of the selection 21 | // or at the current cursor position. 22 | local int64 pos; 23 | if( GetSelSize() > 0 ) 24 | pos = GetSelStart(); 25 | else 26 | pos = GetCursorPos(); 27 | 28 | // Define variables for the inspector 29 | FSeek( pos ); byte _si8 ; 30 | FSeek( pos ); ubyte _ui8 ; 31 | FSeek( pos ); short _si16 ; 32 | FSeek( pos ); ushort _ui16 ; 33 | FSeek( pos ); int _si32 ; 34 | FSeek( pos ); uint _ui32 ; 35 | FSeek( pos ); int64 _si64 ; 36 | FSeek( pos ); uint64 _ui64 ; 37 | FSeek( pos ); float _f ; 38 | FSeek( pos ); double _d ; 39 | FSeek( pos ); hfloat _hf ; 40 | FSeek( pos ); char _s [ReadStringLength(pos,256)] ; // limit to 256 characters 41 | FSeek( pos ); wchar_t _ws[ReadWStringLength(pos,256)] ; // limit to 256 characters 42 | FSeek( pos ); DOSDATE _dd ; 43 | FSeek( pos ); DOSTIME _dt ; 44 | FSeek( pos ); FILETIME _ft ; 45 | FSeek( pos ); OLETIME _ot ; 46 | FSeek( pos ); time_t _tt ; 47 | 48 | #include "scaffolds/Bits.bt" 49 | #include "filetypes/Banks.bt" 50 | #include "filetypes/Memory.bt" 51 | 52 | BitfieldDisablePadding(); 53 | FSeek( pos ); ZBank _zb ; 54 | FSeek( pos ); ZBankPointer _zbp ; 55 | FSeek( pos ); BitEight _be ; 56 | FSeek( pos ); Ram _ram ; -------------------------------------------------------------------------------- /autoload.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // change the state of 010 3 | BigEndian(); 4 | BitfieldDisablePadding(); 5 | 6 | // helpers for not making a mess 7 | // == scaffolds/*.bt 8 | #include "scaffolds/Anomaly.bt" 9 | #include "scaffolds/Assert.bt" 10 | #include "scaffolds/Bits.bt" 11 | #include "scaffolds/Block.bt" 12 | #include "scaffolds/Bucket.bt" 13 | #include "scaffolds/Colors.bt" 14 | #include "scaffolds/Jumps.bt" 15 | #include "scaffolds/Padding.bt" 16 | #include "scaffolds/Significant.bt" 17 | #include "scaffolds/Unknown.bt" 18 | 19 | // post-helper macros 20 | // turn on painting significant variables 21 | SION; 22 | 23 | // simple things 24 | // == filetypes/*.bt 25 | #include "filetypes/Banks.bt" 26 | #include "filetypes/DamageCharts.bt" 27 | #include "filetypes/Entrances.bt" 28 | #include "filetypes/FileSystem.bt" 29 | #include "filetypes/Memory.bt" 30 | #include "filetypes/Messages.bt" 31 | #include "filetypes/N64ROMHead.bt" 32 | #include "filetypes/Simple.bt" 33 | 34 | // bigger data formats 35 | // == filetypes/Animation/*.bt 36 | // == filetypes/Animation/Link/*.bt 37 | #include "filetypes/Animation/Link/LinkAnimationFrame.bt" 38 | #include "filetypes/Animation/Link/LinkAnimationHeader.bt" 39 | 40 | // == filetypes/Audio/*.bt 41 | #include "filetypes/Audio/Sample.bt" 42 | #include "filetypes/Audio/Instrument.bt" 43 | #include "filetypes/Audio/InstrumentSet.bt" 44 | #include "filetypes/Audio/Sequence.bt" 45 | #include "filetypes/Audio/SequenceHead.bt" 46 | #include "filetypes/Audio/ChannelHead.bt" 47 | // == filetypes/Compressed/*.bt 48 | #include "filetypes/Compressed/Yaz.bt" 49 | // == filetypes/DisplayList/*.bt 50 | #include "filetypes/DisplayList/DisplayList.bt" 51 | #include "filetypes/DisplayList/Commands/DA.bt" 52 | //... 53 | #include "filetypes/DisplayList/Commands/DF.bt" 54 | //... 55 | #include "filetypes/DisplayList/Commands/Dummy.bt" 56 | #include "filetypes/DisplayList/DisplayListScanner.bt" 57 | // == filetypes/MIPS/*.bt 58 | #include "filetypes/MIPS/MIPS_Code.bt" 59 | //... 60 | #include "filetypes/MIPS/Commands/ADDI.bt" 61 | #include "filetypes/MIPS/Commands/ADDIU.bt" 62 | //... 63 | #include "filetypes/MIPS/MIPS_CodeScanner.bt" 64 | // == filetypes/Overlay/*.bt 65 | #include "filetypes/Overlay/OverlayHeader.bt" 66 | #include "filetypes/Overlay/Dummy.bt" 67 | #include "filetypes/Overlay/Actor.bt" 68 | #include "filetypes/Overlay/Object.bt" 69 | // == filetypes/Overlay/Files/*.bt 70 | #include "filetypes/Overlay/Files/En_GirlA.bt" 71 | #include "filetypes/Overlay/Files/map_marker_data.bt" 72 | // == filetypes/Save/*.bt 73 | #include "filetypes/Save/SaveParts.bt" 74 | #include "filetypes/Save/SaveFile.bt" 75 | // == filetypes/Texture/*.bt 76 | #include "filetypes/Texture/ci4.bt" 77 | #include "filetypes/Texture/ci8.bt" 78 | #include "filetypes/Texture/i4.bt" 79 | #include "filetypes/Texture/i8.bt" 80 | #include "filetypes/Texture/ia4.bt" 81 | #include "filetypes/Texture/ia8.bt" 82 | #include "filetypes/Texture/ia16.bt" 83 | #include "filetypes/Texture/JFIF.bt" 84 | #include "filetypes/Texture/rgb5a1.bt" 85 | #include "filetypes/Texture/rgba32.bt" 86 | // == filetypes/Scene/HC/*.bt 87 | // order not indicative of header command order 88 | #include "filetypes/Scene/HC/ZHC_Actor.bt" 89 | #include "filetypes/Scene/HC/ZHC_StartPos.bt" 90 | #include "filetypes/Scene/HC/ZHC_AltCamera.bt" 91 | #include "filetypes/Scene/HC/ZHC_Collision.bt" 92 | #include "filetypes/Scene/HC/ZHC_Map.bt" 93 | #include "filetypes/Scene/HC/_ZHC_Wind.bt" 94 | #include "filetypes/Scene/HC/ZHC_Entrance.bt" 95 | #include "filetypes/Scene/HC/_ZHC_SpecialObjects.bt" 96 | #include "filetypes/Scene/HC/ZHC_RoomBehavior.bt" 97 | #include "filetypes/Scene/HC/_ZHC_Unused09.bt" 98 | #include "filetypes/Scene/HC/ZHC_Mesh.bt" 99 | #include "filetypes/Scene/HC/ZHC_Object.bt" 100 | #include "filetypes/Scene/HC/ZHC_UnusedEnvironment.bt" 101 | #include "filetypes/Scene/HC/ZHC_Path.bt" 102 | #include "filetypes/Scene/HC/ZHC_TransitionActor.bt" 103 | #include "filetypes/Scene/HC/ZHC_Environment.bt" 104 | #include "filetypes/Scene/HC/_ZHC_Time.bt" 105 | #include "filetypes/Scene/HC/_ZHC_Skybox.bt" 106 | #include "filetypes/Scene/HC/_ZHC_SkyboxMod.bt" 107 | #include "filetypes/Scene/HC/ZHC_Exit.bt" 108 | #include "filetypes/Scene/HC/_ZHC_End.bt" 109 | #include "filetypes/Scene/HC/_ZHC_Sound.bt" 110 | #include "filetypes/Scene/HC/ZHC_Cutscene.bt" 111 | #include "filetypes/Scene/HC/ZHC_AltHeader.bt" 112 | #include "filetypes/Scene/HC/ZHC_Camera.bt" 113 | #include "filetypes/Scene/HC/_ZHC_Unknown1A.bt" 114 | #include "filetypes/Scene/HC/_ZHC_Unknown1B.bt" 115 | #include "filetypes/Scene/HC/_ZHC_Unknown1C.bt" 116 | #include "filetypes/Scene/HC/_ZHC_Unknown1D.bt" 117 | #include "filetypes/Scene/HC/_ZHC_Unknown1E.bt" 118 | // == filetypes/Scene/*.bt 119 | #include "filetypes/Scene/HeaderCommand.bt" 120 | 121 | #include "filetypes/Scene/Scene.bt" -------------------------------------------------------------------------------- /checksums/compressed/Legend of Zelda, The - Majora's Mask (E) (M4) (Debug Version).z64.csv: -------------------------------------------------------------------------------- 1 | Algorithm,Checksum/Digest 2 | Checksum - UByte (8 bit),00000001 08D955B3 3 | Checksum - UShort (16 bit) - Little Endian,00000087 D3FE7A17 4 | Checksum - UShort (16 bit) - Big Endian,00000082 0E308E9C 5 | Checksum - UInt (32 bit) - Little Endian,0043E330 53DF174A 6 | Checksum - UInt (32 bit) - Big Endian,0045D352 07C7C1EF 7 | Checksum - UInt64 (64 bit) - Little Endian,06258A51 4DDAD31C 8 | Checksum - UInt64 (64 bit) - Big Endian,432298C0 C4C76316 9 | CRC-16,E10E 10 | CRC-16/CCITT,7E54 11 | CRC-32,7F702FBE 12 | Adler32,59A4DB4C 13 | MD2,6DA563150F374A410FC5E2E1489965CA 14 | MD4,1632A20777DE2D0DAB595F430B89B452 15 | MD5,1AD391B9DF43CE3665D4F5D8771A42E9 16 | RIPEMD160,4E7FA1F55BD7C219C1F9E046B59617987E3B8794 17 | SHA-1,14D10A0EEFB75A720FFBF68540D6C582C4119E9E 18 | SHA-256,6312F1CBC3D5BB90E44CB80E230FEF4F6780271C9E79FD769973C588DB6BB662 19 | SHA-512,CB3FC0184ACB487D9491508EA995318E0CC2F7209AD63409F9D4D05CA6EE750611C5EEE745D564DD215B4086E4196A777A07383146701A8587C846FE26A78EA0 20 | TIGER,5BEBFDF2A33DDD90D146DBDD2DCCE229CD4139599B7DC96A 21 | -------------------------------------------------------------------------------- /checksums/compressed/MMDBG(zeroed).z64.csv: -------------------------------------------------------------------------------- 1 | Algorithm,Checksum/Digest 2 | Checksum - UByte (8 bit),00000001 1E808206 3 | Checksum - UShort (16 bit) - Little Endian,00000091 220DDE88 4 | Checksum - UShort (16 bit) - Big Endian,0000008E 7CF4A97E 5 | Checksum - UInt (32 bit) - Little Endian,00490CF5 2D25C6C3 6 | Checksum - UInt (32 bit) - Big Endian,0048D6DB 3B5D1480 7 | Checksum - UInt64 (64 bit) - Little Endian,5EEE1B9F CE5B743C 8 | Checksum - UInt64 (64 bit) - Big Endian,B95A3EC6 8226D332 9 | CRC-16,6F8D 10 | CRC-16/CCITT,F275 11 | CRC-32,DEBAFB7A 12 | Adler32,E4284C86 13 | MD2,35209BA6B8AC7D4DC574DE6514FBE9EE 14 | MD4,00BE68F05F8707C2AC9A6CAE293B56A6 15 | MD5,F4B6003FD6294F6C8C15A9BB787F670D 16 | RIPEMD160,88899131C756033AC76BE38EA54CB91586D2A0E6 17 | SHA-1,3C38CA869029AA7B0B866EDC059B3BD8E1365A10 18 | SHA-256,CB6F897379FA94AD528BF6272AAA7BCF48BA30157AAC7ECBBB99FC35F88097DC 19 | SHA-512,D47D641130D88B257C2ABDD346766C859F54715D1B39C4F1F560BCD324F02545860366348A34C6AABF3AE588DF73C7150A2531EE23D281C8B75C6A5DC8D88D60 20 | TIGER,8776C331DA8A237D560DB987BA805A91B6EA18507CE79139 21 | -------------------------------------------------------------------------------- /checksums/compressed/MMDBG.z64.csv: -------------------------------------------------------------------------------- 1 | Algorithm,Checksum/Digest 2 | Checksum - UByte (8 bit),00000001 D382570B 3 | Checksum - UShort (16 bit) - Little Endian,000000EC 5640F243 4 | Checksum - UShort (16 bit) - Big Endian,000000E8 FF986FC8 5 | Checksum - UInt (32 bit) - Little Endian,0076B2AE C3ADD29D 6 | Checksum - UInt (32 bit) - Big Endian,007681A6 1731D6FB 7 | Checksum - UInt64 (64 bit) - Little Endian,1F8F314C A458FEF6 8 | Checksum - UInt64 (64 bit) - Big Endian,C480A722 52EC0EFD 9 | CRC-16,AD5B 10 | CRC-16/CCITT,4255 11 | CRC-32,687D8395 12 | Adler32,DE25BD3F 13 | MD2,CC4FBADD7C63B26749CD9D53E1D6C146 14 | MD4,D26023FEBF8F972F41C803080F21742B 15 | MD5,71FBAE5D2B27926EA54E92CE2FC91622 16 | RIPEMD160,7154D5826877E22D4394846F999C3B5BA00F8994 17 | SHA-1,B38B71D2961DFFB523020A67F4807A4B704E347A 18 | SHA-256,9127FD52A05666D0A9A0E278429A758323D507ADD3089AC0EC315616E3ED1FF8 19 | SHA-512,3EE7F7C3AC6F129B3FEEADA71CDA533EFE751EF39DD3B2BCD9113389457FD604C86E1A2EF30A912EDBC392F6D92E58A15C62FD560E3308FDC0221CDFC6AB840B 20 | TIGER,CD6A864F140B947A336DC56DF51DBE6463FFB2CAF67C8CE8 21 | -------------------------------------------------------------------------------- /checksums/compressed/The Legend of Zelda Majora's Mask Debug.n64.csv: -------------------------------------------------------------------------------- 1 | Algorithm,Checksum/Digest 2 | Checksum - UByte (8 bit),00000001 D382570B 3 | Checksum - UShort (16 bit) - Little Endian,000000EC 5640F243 4 | Checksum - UShort (16 bit) - Big Endian,000000E8 FF986FC8 5 | Checksum - UInt (32 bit) - Little Endian,0076B2AE C3ADD29D 6 | Checksum - UInt (32 bit) - Big Endian,007681A6 1731D6FB 7 | Checksum - UInt64 (64 bit) - Little Endian,1F8F314C A458FEF6 8 | Checksum - UInt64 (64 bit) - Big Endian,C480A722 52EC0EFD 9 | CRC-16,AD5B 10 | CRC-16/CCITT,4255 11 | CRC-32,687D8395 12 | Adler32,DE25BD3F 13 | MD2,CC4FBADD7C63B26749CD9D53E1D6C146 14 | MD4,D26023FEBF8F972F41C803080F21742B 15 | MD5,71FBAE5D2B27926EA54E92CE2FC91622 16 | RIPEMD160,7154D5826877E22D4394846F999C3B5BA00F8994 17 | SHA-1,B38B71D2961DFFB523020A67F4807A4B704E347A 18 | SHA-256,9127FD52A05666D0A9A0E278429A758323D507ADD3089AC0EC315616E3ED1FF8 19 | SHA-512,3EE7F7C3AC6F129B3FEEADA71CDA533EFE751EF39DD3B2BCD9113389457FD604C86E1A2EF30A912EDBC392F6D92E58A15C62FD560E3308FDC0221CDFC6AB840B 20 | TIGER,CD6A864F140B947A336DC56DF51DBE6463FFB2CAF67C8CE8 21 | -------------------------------------------------------------------------------- /checksums/decompressed/Legend of Zelda, The - Majora's Mask (E) (M4) (Debug Version)(ndec clean).z64.csv: -------------------------------------------------------------------------------- 1 | Algorithm,Checksum/Digest 2 | Checksum - UByte (8 bit),00000001 08D955B3 3 | Checksum - UShort (16 bit) - Little Endian,00000087 D3FE7A17 4 | Checksum - UShort (16 bit) - Big Endian,00000082 0E308E9C 5 | Checksum - UInt (32 bit) - Little Endian,0043E330 53DF174A 6 | Checksum - UInt (32 bit) - Big Endian,0045D352 07C7C1EF 7 | Checksum - UInt64 (64 bit) - Little Endian,06258A51 4DDAD31C 8 | Checksum - UInt64 (64 bit) - Big Endian,432298C0 C4C76316 9 | CRC-16,E10E 10 | CRC-16/CCITT,7E54 11 | CRC-32,7F702FBE 12 | Adler32,59A4DB4C 13 | MD2,6DA563150F374A410FC5E2E1489965CA 14 | MD4,1632A20777DE2D0DAB595F430B89B452 15 | MD5,1AD391B9DF43CE3665D4F5D8771A42E9 16 | RIPEMD160,4E7FA1F55BD7C219C1F9E046B59617987E3B8794 17 | SHA-1,14D10A0EEFB75A720FFBF68540D6C582C4119E9E 18 | SHA-256,6312F1CBC3D5BB90E44CB80E230FEF4F6780271C9E79FD769973C588DB6BB662 19 | SHA-512,CB3FC0184ACB487D9491508EA995318E0CC2F7209AD63409F9D4D05CA6EE750611C5EEE745D564DD215B4086E4196A777A07383146701A8587C846FE26A78EA0 20 | TIGER,5BEBFDF2A33DDD90D146DBDD2DCCE229CD4139599B7DC96A 21 | -------------------------------------------------------------------------------- /checksums/decompressed/Legend of Zelda, The - Majora's Mask (E) (M4) (Debug Version)(ndec).z64.csv: -------------------------------------------------------------------------------- 1 | Algorithm,Checksum/Digest 2 | Checksum - UByte (8 bit),00000001 08D955B3 3 | Checksum - UShort (16 bit) - Little Endian,00000087 D3FE7A17 4 | Checksum - UShort (16 bit) - Big Endian,00000082 0E308E9C 5 | Checksum - UInt (32 bit) - Little Endian,0043E330 53DF174A 6 | Checksum - UInt (32 bit) - Big Endian,0045D352 07C7C1EF 7 | Checksum - UInt64 (64 bit) - Little Endian,06258A51 4DDAD31C 8 | Checksum - UInt64 (64 bit) - Big Endian,432298C0 C4C76316 9 | CRC-16,E10E 10 | CRC-16/CCITT,7E54 11 | CRC-32,7F702FBE 12 | Adler32,59A4DB4C 13 | MD2,6DA563150F374A410FC5E2E1489965CA 14 | MD4,1632A20777DE2D0DAB595F430B89B452 15 | MD5,1AD391B9DF43CE3665D4F5D8771A42E9 16 | RIPEMD160,4E7FA1F55BD7C219C1F9E046B59617987E3B8794 17 | SHA-1,14D10A0EEFB75A720FFBF68540D6C582C4119E9E 18 | SHA-256,6312F1CBC3D5BB90E44CB80E230FEF4F6780271C9E79FD769973C588DB6BB662 19 | SHA-512,CB3FC0184ACB487D9491508EA995318E0CC2F7209AD63409F9D4D05CA6EE750611C5EEE745D564DD215B4086E4196A777A07383146701A8587C846FE26A78EA0 20 | TIGER,5BEBFDF2A33DDD90D146DBDD2DCCE229CD4139599B7DC96A 21 | -------------------------------------------------------------------------------- /checksums/decompressed/Legend of Zelda, The - Majora's Mask (E) (M4) (Debug Version).z64.csv: -------------------------------------------------------------------------------- 1 | Algorithm,Checksum/Digest 2 | Checksum - UByte (8 bit),00000001 08D955B3 3 | Checksum - UShort (16 bit) - Little Endian,00000087 D3FE7A17 4 | Checksum - UShort (16 bit) - Big Endian,00000082 0E308E9C 5 | Checksum - UInt (32 bit) - Little Endian,0043E330 53DF174A 6 | Checksum - UInt (32 bit) - Big Endian,0045D352 07C7C1EF 7 | Checksum - UInt64 (64 bit) - Little Endian,06258A51 4DDAD31C 8 | Checksum - UInt64 (64 bit) - Big Endian,432298C0 C4C76316 9 | CRC-16,E10E 10 | CRC-16/CCITT,7E54 11 | CRC-32,7F702FBE 12 | Adler32,59A4DB4C 13 | MD2,6DA563150F374A410FC5E2E1489965CA 14 | MD4,1632A20777DE2D0DAB595F430B89B452 15 | MD5,1AD391B9DF43CE3665D4F5D8771A42E9 16 | RIPEMD160,4E7FA1F55BD7C219C1F9E046B59617987E3B8794 17 | SHA-1,14D10A0EEFB75A720FFBF68540D6C582C4119E9E 18 | SHA-256,6312F1CBC3D5BB90E44CB80E230FEF4F6780271C9E79FD769973C588DB6BB662 19 | SHA-512,CB3FC0184ACB487D9491508EA995318E0CC2F7209AD63409F9D4D05CA6EE750611C5EEE745D564DD215B4086E4196A777A07383146701A8587C846FE26A78EA0 20 | TIGER,5BEBFDF2A33DDD90D146DBDD2DCCE229CD4139599B7DC96A 21 | -------------------------------------------------------------------------------- /checksums/decompressed/Legend of Zelda, The - Ocarina of Time - Master Quest (E) (GC) (Debug Version).z64.csv: -------------------------------------------------------------------------------- 1 | Algorithm,Checksum/Digest 2 | Checksum - UByte (8 bit),00000000 EF2C42A6 3 | Checksum - UShort (16 bit) - Little Endian,0000007B 36DFADC5 4 | Checksum - UShort (16 bit) - Big Endian,00000074 E48F3AE1 5 | Checksum - UInt (32 bit) - Little Endian,003E899B 185742EF 6 | Checksum - UInt (32 bit) - Big Endian,003EBB46 1B21493F 7 | Checksum - UInt64 (64 bit) - Little Endian,213A65FE F73ACC07 8 | Checksum - UInt64 (64 bit) - Big Endian,EFA02E11 2B9FCC51 9 | CRC-16,2898 10 | CRC-16/CCITT,2A39 11 | CRC-32,A5635F49 12 | Adler32,5CB2470D 13 | MD2,54B1992D713F5F6102B22CD50FD1DA7C 14 | MD4,6EDECD9F441279561F19B470FAD51E99 15 | MD5,583368D43ED0C44A8DAD79F09F0F3A45 16 | RIPEMD160,82486CAB96C4C9B521A5E984FA5920FAA8E933D1 17 | SHA-1,9FA21F8FC04BC06DCE0725526680B66C26CB44E0 18 | SHA-256,3224108FFF721883D3698B85D3D3741A0FA34D6A1169E4EE5DF5DA67F99C9934 19 | SHA-512,BDEB412C69D2A155965A5349C797F9161C49F4045222C18CFAC2B06A0EB63D4179E7D44600B6BD093A1839FC97E3DB12B9CA985F60F90269C362110FC9BBA01D 20 | TIGER,50EB348381DDABDC47C5218BF5231AE02932232A7F06DC38 21 | -------------------------------------------------------------------------------- /checksums/decompressed/MMDBG(ndec clean).csv: -------------------------------------------------------------------------------- 1 | Algorithm,Checksum/Digest 2 | Checksum - UByte (8 bit),00000001 08D955B3 3 | Checksum - UShort (16 bit) - Little Endian,00000087 D3FE7A17 4 | Checksum - UShort (16 bit) - Big Endian,00000082 0E308E9C 5 | Checksum - UInt (32 bit) - Little Endian,0043E330 53DF174A 6 | Checksum - UInt (32 bit) - Big Endian,0045D352 07C7C1EF 7 | Checksum - UInt64 (64 bit) - Little Endian,06258A51 4DDAD31C 8 | Checksum - UInt64 (64 bit) - Big Endian,432298C0 C4C76316 9 | CRC-16,E10E 10 | CRC-16/CCITT,7E54 11 | CRC-32,7F702FBE 12 | Adler32,59A4DB4C 13 | MD2,6DA563150F374A410FC5E2E1489965CA 14 | MD4,1632A20777DE2D0DAB595F430B89B452 15 | MD5,1AD391B9DF43CE3665D4F5D8771A42E9 16 | RIPEMD160,4E7FA1F55BD7C219C1F9E046B59617987E3B8794 17 | SHA-1,14D10A0EEFB75A720FFBF68540D6C582C4119E9E 18 | SHA-256,6312F1CBC3D5BB90E44CB80E230FEF4F6780271C9E79FD769973C588DB6BB662 19 | SHA-512,CB3FC0184ACB487D9491508EA995318E0CC2F7209AD63409F9D4D05CA6EE750611C5EEE745D564DD215B4086E4196A777A07383146701A8587C846FE26A78EA0 20 | TIGER,5BEBFDF2A33DDD90D146DBDD2DCCE229CD4139599B7DC96A 21 | -------------------------------------------------------------------------------- /checksums/decompressed/MMDBG(ndec).csv: -------------------------------------------------------------------------------- 1 | Algorithm,Checksum/Digest 2 | Checksum - UByte (8 bit),00000001 CCF0FE74 3 | Checksum - UShort (16 bit) - Little Endian,000000EA B034B8A9 4 | Checksum - UShort (16 bit) - Big Endian,000000E4 0DBAB9CB 5 | Checksum - UInt (32 bit) - Little Endian,00756506 F06E13DE 6 | Checksum - UInt (32 bit) - Big Endian,0077544A 5BE817C0 7 | Checksum - UInt64 (64 bit) - Little Endian,16A201B5 DA05D14A 8 | Checksum - UInt64 (64 bit) - Big Endian,623DF88A F9E5210A 9 | CRC-16,B32E 10 | CRC-16/CCITT,C1A6 11 | CRC-32,5FBF1C0B 12 | Adler32,65C80229 13 | MD2,AD673EDEF2E02D5C3A42FEB2DFBC2759 14 | MD4,36046756CEE0A0FD2AF3FCC8E1944B6E 15 | MD5,406A97C49A6BF9F991BAE07E2C6678A0 16 | RIPEMD160,59BCE1D4E8E8E48664E4B8F601485CE7BD5D2727 17 | SHA-1,C8369FFF81D160FBBFAE31207AF2E9DDF87BDFE6 18 | SHA-256,234398066A45734A117F0F874B36467E1652D1644756D7D123B679BAA41B81A8 19 | SHA-512,2AFF076A681EAA9F898258916AE59EE0FA32E8A414EA2EEC74C5D0D99638EBC2593563298EF970E5DDBFD68B80AD91161C1E98043B298D2CFE079ECA0F35AD86 20 | TIGER,518E7EBE7643B41284D8E9C4A86B27AB53437589D45CD931 21 | -------------------------------------------------------------------------------- /docs/010tips.md: -------------------------------------------------------------------------------- 1 | # Generic Functions 2 | You can define simply "struct" to perform operations on generic types in functions. 3 | The following is valid: 4 | ``` 5 | typedef struct { 6 | ubyte weight; 7 | string name; 8 | ubyte age; 9 | } Egrid; 10 | 11 | typedef struct { 12 | string nickname; 13 | uint size; 14 | ubyte age; 15 | } Elephant; 16 | 17 | string GetStructName(struct anything){ 18 | if( exists(anything.name) ){ 19 | return anything.name; 20 | } else if( exists(anything.nickname) ){ 21 | return anything.nickname; 22 | } 23 | } 24 | 25 | int DoesHaveStupidName(string name){ 26 | case "hotdog salesman" 27 | case "mister wigglesworth the third": 28 | return 1; 29 | break; 30 | case "derrike": 31 | return 0; 32 | break; 33 | default: 34 | return -1; 35 | break; 36 | } 37 | 38 | // running it 39 | Egrid myBird; 40 | Egrid someoneElsesBird; 41 | Elephant myDog; 42 | Elephant rabidDog; 43 | 44 | local int i; 45 | local string name; 46 | for( i = 0; i < 3; i++ ){ 47 | switch(i){ 48 | case 0: 49 | name = GetStructName(myBird); 50 | break; 51 | case 1: 52 | name = GetStructName(someoneElsesBird); 53 | break; 54 | case 2: 55 | name = GetStructName(myDog); 56 | break; 57 | case 3: 58 | name = GetStructName(rabidDog); 59 | break; 60 | default: 61 | name = "unloved thing"; 62 | break; 63 | } 64 | 65 | if( DoesHaveStupidName(name) ){ 66 | Printf("stupid name detected: %s\n", name); 67 | } 68 | } 69 | ``` 70 | ## Benefits 71 | - If your data has some stuff in common or some stuff in almost-common, you can write 72 | a set of generic handlers to access members or perform certain operations. 73 | This is handy when unions won't cut it. 74 | - This also works on typedef'd structs. 75 | 76 | ## Limits 77 | - This doesn't enable access to locals defined in the variable's scope, so it can't 78 | utilize offhand access to data outside the scope of a local. 79 | - Yes 80 | 81 | # Size 82 | Despite [what the docs may say](http://www.sweetscape.com/010editor/manual/Sizeof.htm), 83 | the sizeof() function works fine on complex structs IF they have a size function. 84 | 85 | # Reading Locals 86 | The function attribute "read" has access to locals, accessed through structure attributes. 87 | 88 | # Structure Bloat 89 | Does generating an array of your custom structs create a line for each entry? 90 | Don't have time to make it on-demand? 91 | Stick that baby in a disposable struct and get some (not at all) free heirarchy: 92 | ```C 93 | struct { 94 | Items items[192]; 95 | } AllOfTheseItems; 96 | ``` 97 | 98 | # Identifying Data At A Glance (Zelda Specific) 99 | ## Alignment & Colors 100 | u data-ing good 101 | http://i.imgur.com/zHacyVR.png 102 | u probably fucked something up 103 | http://i.imgur.com/ZPpHoLp.png 104 | almost there, hard edges 105 | http://i.imgur.com/Z1iVEVs.png 106 | 107 | to fuck the data up like this: 108 | jump to `TERRAIN_TRIGGER_RESET` and `TERRAIN_HURT_FIRE` inside `ZHC_Collision` 109 | and remove only one of their bitfield paddings for light fuckuppery 110 | remove them both to take them off the fuckin' rails 111 | 112 | ### Keep In Mind 113 | * Not all data is guaranteed to align, there are cases of structures with 114 | 3 integers and no padding. 115 | 116 | # Identifying Data At A Glance (Zelda Specific) 117 | Sometimes there are some patterns you can keep a look out for. 118 | 119 | ## RAM Pointers 120 | Often, data in the code block will contain hex data that looks like `80 15 91 D8`. 121 | Any four-byte sequence that starts with `80` is likely a RAM pointer, as `80` is where 122 | the addresses start for RAM in the N64 memory map. 123 | 124 | ## File Offsets 125 | Sometimes, you'll see data like `01 E1 93 D1`. 126 | The debug ROMs, when decompressed, have their final byte at `03 FF FF FF`. 127 | Any data lower than that has the potential of being a pointer to other data directly. 128 | (This is usually looked up against the VFS to find the physical address in non-compressed ROMs.) -------------------------------------------------------------------------------- /docs/cliff_notes.md: -------------------------------------------------------------------------------- 1 | # Everything I Found I Was Too Lazy To Write Down 2 | Chances are if text ends up here, I already talked about it in IRC elsewhere. 3 | If text gets promoted to this location it means that the templates are more accurate than wikis in some cases. 4 | 5 | # Scenes and Rooms 6 | * Most if not all [unknown header commands](filetypes/Scene/HeaderCommand.bt) accept a number, two bytes of null, and then a scene-local [ZBank](filetypes/Banks.bt). 7 | * Collision data for rooms use densely packed bits for flags, the wiki clumps things by the byte and overlooks certain flags. 8 | 9 | # Audiobank 10 | * Most of these structures don't have strong documentation and DeathBasket's site is missing some data. 11 | * In MM, the 4th sample bank is not referenced directly. It sounds like it only contains one voice clip and garbage data, as it's not big enough for many other samples after that. -------------------------------------------------------------------------------- /docs/misc_notes.md: -------------------------------------------------------------------------------- 1 | # notes for 2 | 3 | # wareya on original dumps 4 | ## ZELOOTMA.z64 5 | * ROM HASH: 8CA71E87DE4CE5E9F6EC916202A623E9 (OOT) 6 | * The OOT Debug ROM is a perfect dump. 7 | * It might have been watermarked, and if it was, the watermark has been removed. 8 | * It's a european-language copy of the game, but it's compiled with NTSC rates, due to being targeted at GC N64 emulation (Master Quest). 9 | 10 | ## MMDBG.z64 11 | * ROM HASH: 71FBAE5D2B27926EA54E92CE2FC91622 (MM) 12 | * The MM Debug ROM is a perfect dump. 13 | * However, it's a full PAL N64 ROM. 14 | * That said, it doesn't have region protection enabled. 15 | * Also, some "useless buffer data", which was full of FFFF bytes, was overwritten with release notes. 16 | * This is not part of the ROM data, so it's fine. 17 | 18 | # About Cutscenes 19 | (5:43:02 PM) mzxrules: the value of the scene setup number is determined by a bunch of things 20 | (5:43:39 PM) mzxrules: the general rule of thumb is that values 0-3 are for child day/night, adult day/night, then 4+ are used for cutscenes 0-C 21 | 22 | # Yaz0 Blocks Still In The Decompressed One 23 | 24 | ## About The Yaz0s 25 | (3:58:13 PM) DerrikeG: CloudMax: at 0x00A4C00C in the decompressed MM debug ROM there's the string "Yaz0", does that mean that it's a block that's still compressed? 26 | (3:58:35 PM) DerrikeG: this is inside the file beginning at 00A09E70 27 | (3:58:42 PM) CloudMax: If I recall correctly, even the decompressed ROM still have yaz0 blocks in it that are decompressed on runtime 28 | (3:59:24 PM) DerrikeG: so if I want whatever is in there, I need to decompress it on the side 29 | 30 | ## Counts 31 | * As many as 928 instances. 32 | * Starts as early as 0x009C30EC (file 009C2000) 33 | * Last instance as late as 0x00A65794 (file 00A65A10) -------------------------------------------------------------------------------- /docs/quickstart_guide.md: -------------------------------------------------------------------------------- 1 | 2 | # Quickstart Guide 3 | 1. Download and install [010 editor](http://www.sweetscape.com/010editor/). 4 | 2. Clone this repository. 5 | 3. Set your 010 includes path. 6 | 1. Open `Tools > Options`. 7 | 2. Select `Compiling`. 8 | 3. Change `Includes:` to be [the path you cloned your repository to](http://i.imgur.com/DW1bSqa.png). 9 | 4. Set your 010 inspector template. 10 | 1. Open `Tools > Options`. 11 | 2. Select `Inspector`. 12 | 3. Change `Auto Inspector` to `Use Custom Template`. 13 | 4. Change the path to be [the Inspector.bt at the root of the path you cloned your repository to](http://i.imgur.com/iXeIRG5.png). 14 | 5. Import custom 010 scripts. 15 | 1. Open `Tools > Options`. 16 | 2. Select `Compiling > Scripts`. 17 | 3. Click `New` and add an entry for each [file in the scripts folder at the root of the path you cloned your repository to](http://i.imgur.com/eqvEA5Q.png). 18 | 6. Use `File > Open File...` to open the ROM of your choice. 19 | 7. Validate the checksums of your ROM. 20 | 1. With the ROM open in 010, Open `Tools > Check Sum ...` 21 | 2. In the [options panel](http://i.imgur.com/DgafBn7.png) ensure that `Entire File` is selected and all the hash methods are checked. 22 | 3. Click `Ok`. When this is done, the `Checksum` panel of the `Output` pane [will have checksums](http://i.imgur.com/LOuKcr6.png). 23 | 4. Ensure that the checksums you just generated match with the relevant ROM in the [checksums/](/checksums/) folder. 24 | * If the checksums don't match, you'll have to find a ROM that does otherwise you can't expect 100% reliable results if data got misaligned or modified unexpectedly. 25 | 8. Open the relevant bootstrap file for your ROM from [templates/](/templates/). 26 | * If you're using the decompressed Majora's Mask debug ROM for example, you'd use `dMM_E_debug.bt`. 27 | 9. Once you have the template open, click `Run Template` [near the file tab](http://i.imgur.com/stHPn56.png). 28 | * You must have both the template and the ROM open in 010 at the same time to do this. 29 | * Once you do this once, it you can just hit F5 on either the template or the ROM to re-run them. You can also click the white triangle. 30 | 10. After you've run the template, you should see the `Template Results` panel. 31 | * You can use this to [explore and modify parts of the ROM that have been templated](http://i.imgur.com/i27WJvD.png). 32 | * This will help you understand where data exists relative to other data. 33 | * It will also make it easier to spot data that hasn't been identified yet. -------------------------------------------------------------------------------- /filetypes/Animation/Link/LinkAnimationFrame.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct(uint limbs){ 3 | // limbs = 21, always 4 | local string thisName = "LinkAnimationFrame"; 5 | SIBE; 6 | 7 | SIT; 8 | ZVector translation; 9 | 10 | SIT; 11 | ZVector rotations[limbs]; 12 | 13 | SIT; 14 | ushort expression; 15 | 16 | SIEND; 17 | } LinkAnimationFrame; -------------------------------------------------------------------------------- /filetypes/Animation/Link/LinkAnimationHeader.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "LinkAnimationHeader"; 4 | SIBE; 5 | 6 | SIT; 7 | ushort frameCount; 8 | 9 | SIT; 10 | ubyte zeroes[2]; 11 | AssertUBytesNull( zeroes, thisName+"->zeroes" ); 12 | 13 | SIT; 14 | ZBankPointer off; 15 | if( off.zb.bankNo == 0x07 ){ 16 | SAVE; 17 | 18 | FSeek(LINKANIMFILE + off.offset); 19 | LinkAnimationFrame frames(21)[frameCount]; 20 | 21 | REST; 22 | } else { 23 | Warning("Unexpected Non-Link Bank"); 24 | } 25 | 26 | SIEND; 27 | } LinkAnimationHeader; -------------------------------------------------------------------------------- /filetypes/Audio/ChannelHead.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct{ 3 | local ubyte op; 4 | local int breakout = 0; 5 | local string warn; 6 | while ( breakout == 0 ){ 7 | op = ReadUByte(FTell()); 8 | switch( op ){ 9 | case 0xC1: 10 | SHCommand C1(1); 11 | // C1 xx 12 | // Sets the instrument number, xx, to be used for the current channel. 13 | break; 14 | case 0xC2: 15 | SHCommand C2(1); 16 | // C2 xx 17 | // Transposition, signed. xx is the number of semitones to transpose by. 18 | break; 19 | case 0xC4: 20 | SHCommand C4(0); 21 | // Initialises the channel for music playback. 22 | break; 23 | case 0xD3: 24 | SHCommand D3(2); 25 | // D3 xx (yy) 26 | // Pitch bend amount, signed, value of xx. yy is a timestamp used between control changes. 27 | break; 28 | case 0xD4: 29 | SHCommand D4(1); 30 | // D4 xx 31 | // Effects level (echo). xx is the effect amount. 32 | break; 33 | case 0xD8: 34 | SHCommand D8(2); 35 | // D8 xx (yy) 36 | // Vibrato amount, value of xx. Higher values can produce odd sounds. yy is a timestamp used between control changes. 37 | break; 38 | case 0xDD: 39 | SHCommand DD(2); 40 | // DD xx 41 | // Channel pan. xx is the pan amount, 00 = hard left, 3F = centre, 7F = hard right. 42 | break; 43 | case 0xDF: 44 | SHCommand DF(2); 45 | // xx (yy) 46 | // Channel volume. xx is the volume value, yy is a timestamp used between control changes (when the volume is changing constantly). 47 | break; 48 | case 0xE9: 49 | SHCommand E9(1); 50 | // E9 xx 51 | // Priority. Unknown how it is used, takes the value of xx. 52 | case 0x80: // unused? 53 | case 0x81: // unused? 54 | case 0x82: // unused? 55 | case 0x83: // unused? 56 | case 0x84: // unused? 57 | case 0x85: // unused? 58 | case 0x86: // unused? 59 | case 0x87: // unused? 60 | case 0x88: 61 | case 0x89: 62 | case 0x8A: 63 | case 0x8B: 64 | case 0x8C: // unused? 65 | case 0x8D: // unused? 66 | case 0x8E: // unused? 67 | case 0x8F: // unused? 68 | SHCommand EIGHTX(2); 69 | // 8x yyyy 70 | // Points to music data to be played on the current channel. x is the 'note layer' to be used (8 - B), up to a maximum of four note layers can be loaded per channel. yyyy is the offset of the music data to be played, relative to the start of the sequence file. 71 | break; 72 | case 0xFB: 73 | SHCommand FB(2); 74 | // xxxx 75 | // Offset to loop from, xxxx is the offset relative to the start of the sequence file. 76 | break; 77 | case 0xFD: 78 | // *** slave copy from SeqHead *** 79 | if( ReadUByte(FTell()+1) > 0x7F ){ 80 | SHCommand FD(2); 81 | } else { 82 | SHCommand FD(1); 83 | } 84 | // FD xx / FD yyyy 85 | // Timestamp (number of 'ticks' to wait before the next command is read, relative to tempo), variable length. If xx goes above 7F, add 8000 to it to get yyyy. 86 | break; 87 | case 0xFF: 88 | // FF 89 | // Marks the end of the channel header. 90 | SHCommand FF(0); 91 | //breakout = 1; 92 | break; 93 | default: 94 | SHCommand IDK(1); 95 | SPrintf(warn, "\nWARNING: Unknown ChanHead opcode (0x%02L)!", op); 96 | EXWarning(warn); 97 | break; 98 | } 99 | } 100 | } ChanHead; -------------------------------------------------------------------------------- /filetypes/Audio/Instrument.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | /* 3 | COVERAGE (ITEMS DONE): 4 | 5 | ITEMS NOT DONE: 6 | TableSample 7 | Unknown2 8 | SampleBlock 9 | SampleHead 10 | InstrumentSample 11 | ElusiveRecord2 12 | ElusiveRecord1 13 | InstProperties 14 | PercussionInstrumentIndex; 15 | PercussionInstrument; 16 | OtherInstrument 17 | */ 18 | 19 | typedef struct(ubyte sampleBank){ 20 | SIBE; 21 | SIT; 22 | ubyte unknown1 : 8; 23 | if( unknown1 != 0 ){ 24 | Printf("WARNING: The first byte of a TableSample wasn't 0 (was %d) @ 0x%Lx\n", unknown1, FTell()-8); 25 | } 26 | SIT; 27 | uint sampleSize : 24; 28 | SIT; 29 | uint offset; // from the Audiotable 30 | SAVE; 31 | FSeek( AUDIOTABLE + sampleTable.mySampRecords[sampleBank].offset + offset ); 32 | SIT; 33 | ubyte audioSample; 34 | //ubyte audioSample[sampleSize]; 35 | REST; 36 | SIEND; 37 | } TableSample; 38 | 39 | // deathbasket structure 1 40 | typedef struct(uint seekPos){ 41 | SIBE; 42 | SIT; 43 | uint unknown1; 44 | SIT; 45 | uint unknown2; 46 | if( unknown1 == 0 ){ 47 | SIT; 48 | uint zeroes[2]; 49 | } else { 50 | SIT; 51 | uint FFs; 52 | SIT; 53 | uint zeroes; 54 | SIT; 55 | uint unknown3[8]; 56 | } 57 | SIEND; 58 | } Unknown2; 59 | 60 | // deathbasket structure 2 61 | typedef struct(uint seekPos){ 62 | SIBE; 63 | SIT; 64 | uint type; 65 | SIT; 66 | uint blockSize; 67 | SIT; 68 | ubyte dataBlock[32 * blockSize]; 69 | SIEND; 70 | } SampleBlock; 71 | 72 | typedef struct(uint seekPos, ubyte sampleBank){ 73 | SIBE; 74 | TableSample sampleFromTable(sampleBank); 75 | SIT; 76 | uint unknownPointer; //chunkFooter?! 77 | SIT; 78 | uint chunkPointer; 79 | SAVE; 80 | FSeek( seekPos + chunkPointer); 81 | SampleBlock sampleData(seekPos); 82 | REST; 83 | 84 | SAVE; 85 | FSeek( seekPos + unknownPointer ); 86 | Unknown2 unknown2(seekPos); 87 | REST; 88 | SIEND; 89 | } SampleHead; 90 | 91 | typedef struct(uint seekPos, ubyte sampleBank){ 92 | SIBE; 93 | SIT; 94 | uint sampleHead; 95 | SIT; 96 | float pitch; 97 | SIT; 98 | if( sampleHead > 0 ){ 99 | SAVE; 100 | FSeek( seekPos + sampleHead ); 101 | SampleHead headSample(seekPos, sampleBank); 102 | REST; 103 | } 104 | SIEND; 105 | } InstrumentSample; 106 | 107 | // elusive record 2 108 | typedef struct(uint seekPos, ubyte sampleBank){ 109 | SIBE; 110 | SIT; 111 | ubyte unknown1 : 8; 112 | SIT; 113 | uint unknown2 : 24; 114 | InstrumentSample sample(seekPos, sampleBank); 115 | SIT; 116 | uint unknown5; // if it's a set-local pointer, 117 | // it's an instrumentProperties pointer 118 | SIEND; 119 | } ElusiveRecord2; 120 | 121 | // elusive record 1 122 | typedef struct(uint seekPos, ubyte sampleBank){ 123 | SIBE; 124 | local uint64 sizeToRead = (parentof(this).seek2 - parentof(this).seek1) / 4; 125 | SIT; 126 | uint er2Pointers[sizeToRead]; 127 | //SIT; // flip it so we don't odd-man-out the next var 128 | local uint64 i; 129 | for( i = 0; i < sizeToRead; i++ ){ 130 | if( er2Pointers[i] > 0){ 131 | SAVE; 132 | FSeek( seekPos + er2Pointers[i] ); 133 | ElusiveRecord2 er2(seekPos, sampleBank); 134 | REST; 135 | } 136 | } 137 | SIEND; 138 | } ElusiveRecord1; 139 | 140 | typedef struct{ 141 | SIBE; 142 | SIT; 143 | ushort props[8]; 144 | SIEND; 145 | } InstProperties; 146 | 147 | // everything below this definitely belongs in this file 148 | 149 | typedef struct(uint seekPos, ubyte sampleBank){ 150 | SIBE; 151 | SIT; 152 | ubyte unknown1[4]; 153 | InstrumentSample sample(seekPos, sampleBank); 154 | SIT; 155 | uint instPropertiesPointer; 156 | /* 157 | xxxxxxxx zzzzzzzz pppppppp yyyyyyyy 158 | 159 | x = Unknown. 160 | zzzzzzzz = Pointer to unknown data structure. 161 | pppppppp = Default sample pitch. 162 | yyyyyyyy = Pointer to instrument properties. 163 | */ 164 | /* 165 | if( pointerToUnknown > 0 ){ 166 | SAVE; 167 | FSeek( seekPos + pointerToUnknown ); 168 | SampleHead headSample(seekPos); 169 | REST; 170 | } 171 | */ 172 | SAVE; 173 | FSeek( seekPos + instPropertiesPointer ); 174 | InstProperties properties; 175 | REST; 176 | SIEND; 177 | } PercussionInstrumentIndex; 178 | 179 | typedef struct(uint seekPos, ubyte sampleBank){ 180 | SIBE; 181 | SIT; 182 | local uint64 numRecords = 64; 183 | local uint64 j; 184 | uint instrumentRecords[numRecords]; 185 | for( j = 0; j < numRecords; j++ ){ 186 | SAVE; 187 | FSeek( seekPos + instrumentRecords[j] ); 188 | PercussionInstrumentIndex myInstruments(seekPos, sampleBank); 189 | REST; 190 | } 191 | SIEND; 192 | } PercussionInstrument; 193 | 194 | typedef struct(uint seekPos, ubyte sampleBank){ 195 | SIBE; 196 | SIT; 197 | ubyte startNoteNumbers[3]; 198 | SIT; 199 | ubyte maybeDecay; 200 | SIT; 201 | uint instPropertiesPointer; 202 | SAVE; 203 | FSeek( seekPos + instPropertiesPointer ); 204 | InstProperties properties; 205 | REST; 206 | InstrumentSample samples(seekPos, sampleBank)[3]; 207 | SIEND; 208 | } OtherInstrument; -------------------------------------------------------------------------------- /filetypes/Audio/InstrumentSet.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | /* 3 | COVERAGE (ITEMS DONE): 4 | InstrumentSetTable 5 | InstrumentSet 6 | 7 | ITEMS NOT DONE: 8 | InstrumentSetData 9 | */ 10 | 11 | typedef struct { 12 | SIBE; 13 | local uint64 i; 14 | /* 15 | the value of Seek1 is valid relative to itself, 16 | wherein it points to a list of relative pointers 17 | */ 18 | SIT; 19 | uint seek1; 20 | 21 | SIT; 22 | uint seek2; 23 | 24 | if(parentof(this).unknown1.bit2 || parentof(this).unknown1.bit4 || parentof(this).unknown1.bit6 || parentof(this).unknown1.bit8){ 25 | AssertUIntGTZero(seek1, "InstrumentSetData->seek1"); 26 | 27 | SAVE; 28 | FSeek( startof(this) + seek1 ); 29 | if(!parentof(this).unknown1.bit2){ 30 | ElusiveRecord1 er1(startof(this), parentof(this).sampleBank); 31 | } else { 32 | PercussionInstrument myInstruments(startof(this), parentof(this).sampleBank); 33 | } 34 | REST; 35 | } 36 | 37 | 38 | if(parentof(this).unknown1.bit4 || parentof(this).unknown1.bit6 || parentof(this).unknown1.bit8){ 39 | AssertUIntGTZero(seek2, "InstrumentSetData->seek2 [non-drums do not blank]"); 40 | SAVE; 41 | FSeek( startof(this) + seek2 ); 42 | for( i = 0; i < numExtraInstrumentSamples; i++ ){ 43 | InstrumentSample extraInstrumentSamples(startof(this), parentof(this).sampleBank); 44 | } 45 | REST; 46 | } else if(parentof(this).unknown1.bit2){ 47 | AssertNumberEquals(seek2, 0, "InstrumentSetData->seek2 [drums should be blank]"); 48 | } 49 | 50 | SIT; 51 | uint myInstrumentLocations[ parentof(this).numInstruments ]; 52 | 53 | // iterate through all the instruments 54 | for( i = 0; i < parentof(this).numInstruments; i++ ){ 55 | if( myInstrumentLocations[ i ] != 0 ){ 56 | SAVE; 57 | FSeek( startof(this) + myInstrumentLocations[ i ] ); 58 | //FSeek( AUDIOBANK + aBankOffset + myInstrumentLocations[ i ] ); 59 | OtherInstrument myInstruments(startof(this), parentof(this).sampleBank); 60 | REST; 61 | } else { 62 | //AssertUIntGTZero( myInstrumentLocations[ i ], "InstrumentSetData->myInstrumentLocations[]" ); 63 | } 64 | } 65 | SIEND; 66 | } InstrumentSetData; 67 | 68 | typedef struct { 69 | SIBE; 70 | SIT; 71 | uint offset; // relative to AUDIOBANK 72 | SIT; 73 | uint size; 74 | SIT; 75 | ubyte majorVersion; 76 | //AssertNumberEquals(majorVersion, 2, "InstrumentSet->majorVersion"); 77 | SIT; 78 | ubyte minorVersion; 79 | AssertNumberInBetween(minorVersion, 0, 2, "InstrumentSet->minorVersion"); 80 | SIT; 81 | ubyte sampleBankmySampRecords[#]">; 82 | AssertNumberInBetween(sampleBank, 0, sampleTable.numSamps, "InstrumentSet->sampleBank"); 83 | SIT; 84 | ubyte unknown2; 85 | AssertNumberEquals(unknown2, 0xFF, "InstrumentSet->unknown2 (NOT PADDING!!!)"); 86 | /* 87 | The third byte is an index for a list at 88 | SAMPLES which gives the base address to load 89 | samples from. What is the purpose of this? Well 90 | apparently just to be a pain in the arse, 91 | because taking these numbers and adding them to sample 92 | pointers will load that sample perfectly if the index 93 | is changed to 1, which has a base address of zero and 94 | is what most instrument sets use. Only four sets seem 95 | to actually do this though, namely the: 96 | Deku Tree, Jabu-Jabu's belly, Goron City and the Spirit Temple. 97 | Super Mario 64 does something similar but it affects every single instrument set in the game. 98 | */ 99 | //Number of instruments to be read (can be less than total but 100 | // not greater, does not include percussion). 101 | SIT; 102 | ubyte numInstruments; 103 | AssertUIntGTZero(numInstruments, "InstrumentSet->numInstruments"); 104 | SIT; 105 | BitEight unknown1; // aa 106 | AssertNumberEquals(unknown1.bit1, 0, "InstrumentSet->unknown1->bit1"); 107 | // AssertNumberEquals(unknown1.bit2, 0, "InstrumentSet->unknown1->bit2"); 108 | AssertNumberEquals(unknown1.bit3, 0, "InstrumentSet->unknown1->bit3"); 109 | //AssertNumberEquals(unknown1.bit4, 0, "InstrumentSet->unknown1->bit4"); 110 | AssertNumberEquals(unknown1.bit5, 0, "InstrumentSet->unknown1->bit5"); 111 | //AssertNumberEquals(unknown1.bit6, 0, "InstrumentSet->unknown1->bit6"); 112 | AssertNumberEquals(unknown1.bit7, 0, "InstrumentSet->unknown1->bit7"); 113 | //AssertNumberEquals(unknown1.bit8, 0, "InstrumentSet->unknown1->bit8"); 114 | /* 115 | aa = a bitrange 116 | only bits 6 8 and 2 are used at any given time 117 | bit 2 handles percussion 118 | * dOoTMQ_E_debug 119 | * dMM_E_debug 120 | bit 4 is only ever set on the first record 121 | * dMM_E_debug 122 | bit 6 is only ever set on the first record 123 | * dOoTMQ_E_debug 124 | bit 8 is only ever set on the second record 125 | * dOoTMQ_E_debug 126 | * dMM_E_debug 127 | */ 128 | 129 | SIT; 130 | ushort numExtraInstrumentSamples; 131 | 132 | /* 133 | foreach on the number of instruments 134 | */ 135 | SAVE; 136 | FSeek( AUDIOBANK + offset ); 137 | InstrumentSetData myData; 138 | REST; 139 | SIEND; 140 | } InstrumentSet; 141 | 142 | typedef struct { 143 | SIBE; 144 | SIT; 145 | ushort numInstrumentSets; 146 | SIT; 147 | ubyte instrumentSetPadding[14]; 148 | AssertUBytesNull( instrumentSetPadding, "instrumentSetPadding" ); 149 | 150 | EXWarning("OPTIMIZE FIX: InstrumentSetTable->myInstrumentSets (InstrumentSet)"); 151 | InstrumentSet myInstrumentSets[numInstrumentSets]; 152 | SIEND; 153 | } InstrumentSetTable; -------------------------------------------------------------------------------- /filetypes/Audio/Sample.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | SIBE; 4 | SIT; 5 | uint offset; // relative to AUDIOTABLE 6 | SIT; 7 | uint size; 8 | SIT; 9 | ubyte unk1; 10 | AssertNumberEquals( unk1, 2, "SampRecord->unk1" ); 11 | SIT; 12 | ubyte unk2; 13 | AssertNumberEquals( unk2, 4, "SampRecord->unk2" ); 14 | SIT; 15 | ubyte zeroes[6]; 16 | AssertUBytesNull( zeroes, "SampRecord->zeroes" ); 17 | SIEND; 18 | } SampRecord; 19 | 20 | typedef struct { 21 | SIBE; 22 | SIT; 23 | ushort numSamps; 24 | SIT; 25 | ubyte numSampsPadding[14]; 26 | AssertUBytesNull( numSampsPadding, "numSampsPadding" ); 27 | 28 | SIT; 29 | 30 | EXWarning("OPTIMIZE FIX: SampleTable->mySampRecords (SampRecord)"); 31 | SampRecord mySampRecords[numSamps]; 32 | SIEND; 33 | } SampleTable; -------------------------------------------------------------------------------- /filetypes/Audio/Sequence.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | struct SeqHead; 3 | 4 | local uint doWalkThrough = 0; 5 | local ushort seqNo = 0; 6 | typedef struct { 7 | SIT; 8 | /* offset relative to start of audioseq file */ 9 | uint relative_offset; 10 | SIT; 11 | /* length in bytes */ 12 | uint length; 13 | SIT; 14 | /* 0x02000000, 0x02010000, 0x02020000 */ 15 | uint seq_type; 16 | SIT; 17 | ubyte padding[4]; 18 | AssertUBytesNull( padding, "SequenceRecord->padding" ); 19 | 20 | SAVE; 21 | SetBackColor( cPurple ); 22 | FSeek(AUDIOSEQ + relative_offset); 23 | SeqHead microcode; 24 | REST; 25 | } SequenceRecord; 26 | 27 | typedef struct { 28 | SIT; 29 | ushort numSeqs; 30 | SIT; 31 | ubyte numSeqsPadding[14]; 32 | AssertUBytesNull( numSeqsPadding, "numSeqsPadding" ); 33 | 34 | EXWarning("OPTIMIZE FIX: SequenceTable->mySequenceRecords (SequenceRecord)"); 35 | SequenceRecord mySequenceRecords[numSeqs]; 36 | } SequenceTable; -------------------------------------------------------------------------------- /filetypes/Audio/SequenceHead.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct (uint noArgs){ 3 | SIT; 4 | ubyte command; 5 | local uint64 i; 6 | for( i = 0; i < noArgs; i++ ){ 7 | SIT; 8 | ubyte arg; 9 | } 10 | } SHCommand; 11 | 12 | typedef struct { 13 | /* 14 | Sequence Header Commands[edit] 15 | 16 | Note: some sequences have the following data after the first four bytes of their sequence header: 17 | D7FFFF 8776CCFF7786F3 vv F2 ww C801F3 xx [C801FA yyyy] FB zzzz 18 | v, w and x are unknowns, y and z seem to be pointers to 9x commands for different parts of the sequence within the sequence header. The part in square brackets is repeated in some sequences. Its purpose is currently unknown but it may be to do with continuing playback mid-sequence after returning to the area from a house/shop. 19 | 20 | https://github.com/sauraen/seq64/blob/master/romdesc/mm_info.xml 21 | https://sites.google.com/site/messiaen64/toads-music-incomplete 22 | https://sites.google.com/site/messiaen64/differences-between-sseq-nds-and-mario64-seq-format 23 | https://sites.google.com/site/messiaen64/mario-64-sequenced-music-specification 24 | */ 25 | local ubyte op; 26 | local ubyte breakout = 0; 27 | local string warn; 28 | while ( breakout == 0 ){ 29 | op = ReadUByte(FTell()); 30 | switch( op ){ 31 | case 0xCC: 32 | SHCommand CC(2); 33 | // yyxx 34 | // Unknown. yy starts at zero and increases each time the command appears, xx is (always?) 73. 35 | break; 36 | case 0xD3: 37 | SHCommand D3(1); 38 | // xx 39 | //Seems to be something to do with the sequence type or format; for Super Mario 64, xx is usually 80, for Zelda 64, xx is usually 20. 40 | break; 41 | case 0xD5: 42 | SHCommand D5(1); 43 | // xx 44 | // Unknown. xx usually takes the value of 32. For sequences that don't play any music xx is 46. 45 | break; 46 | case 0xD6: 47 | SHCommand D6(2); 48 | // xxxx 49 | // Disables channels given by xxxx. 50 | break; 51 | case 0xD7: 52 | SHCommand D7(2); 53 | // xxxx 54 | // Enables channels given by xxxx (boolean, each channel is one bit). 55 | break; 56 | case 0xDB: 57 | SHCommand DB(1); 58 | // xx 59 | // Master volume control, xx is the volume. 60 | break; 61 | case 0xDD: 62 | SHCommand DD(1); 63 | // xx 64 | // Tempo control, xx is the tempo value in beats per minute. 65 | break; 66 | case 0x90: 67 | case 0x91: 68 | case 0x92: 69 | case 0x93: 70 | case 0x94: 71 | case 0x95: 72 | case 0x96: 73 | case 0x97: 74 | case 0x98: 75 | case 0x99: 76 | case 0x9A: 77 | case 0x9B: 78 | case 0x9C: 79 | case 0x9D: 80 | case 0x9E: 81 | case 0x9F: 82 | SHCommand NINEX(2); 83 | // yyyy 84 | // Points to a channel header offset. 9X is the channel number (0 - F) and yyyy is the offset of that channel's header relative to the start of the sequence file. 85 | break; 86 | case 0xFB: 87 | SHCommand FB(2); 88 | // xxxx 89 | // Offset to loop from, xxxx is the offset relative to the start of the sequence file. 90 | break; 91 | case 0xFD: 92 | if( ReadUByte(FTell()+1) > 0x7F ){ 93 | SHCommand FD(2); 94 | } else { 95 | SHCommand FD(1); 96 | } 97 | // FD xx / FD yyyy 98 | // Timestamp (number of 'ticks' to wait before the next command is read, relative to tempo), variable length. If xx goes above 7F, add 8000 to it to get yyyy. 99 | break; 100 | case 0xFF: 101 | SHCommand FF(0); 102 | breakout = 1; 103 | break; 104 | default: 105 | SHCommand IDK(1); 106 | SPrintf(warn, "WARNING: Unknown SeqHead opcode (0x%02LX)!", op); 107 | EXWarning(warn); 108 | break; 109 | } 110 | } 111 | } SeqHead; -------------------------------------------------------------------------------- /filetypes/Banks.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | /* 3 | We don't actually know what the main bank does / us. 4 | Here are some types relating to it, though. 5 | TODO: Find the main bank definition(s). 6 | */ 7 | 8 | typedef struct { 9 | #ifdef SIBE 10 | SIBE; 11 | #endif 12 | #ifdef SIT 13 | SIT; 14 | #endif 15 | ubyte bankNo : 8; 16 | #ifdef SIEND 17 | SIEND; 18 | #endif 19 | } ZBank ; 20 | 21 | //, write=ZBankWrite 22 | 23 | string ZBankRead(ZBank &zb){ 24 | switch(zb.bankNo){ 25 | case 0x01: 26 | return "Title Static?!"; 27 | case 0x02: 28 | return "Scene"; 29 | case 0x03: 30 | return "Room"; 31 | case 0x04: 32 | return "gameplay_keep"; 33 | case 0x05: 34 | return "gameplay_field/dangeon_keep"; 35 | case 0x06: 36 | return "Current Object"; 37 | case 0x07: 38 | return "link_animetion/07?"; 39 | default: 40 | local string s; 41 | SPrintf( s, "0x%LX?", zb.bankNo); 42 | return s; 43 | } 44 | }; 45 | 46 | typedef struct { 47 | #ifdef SIBE 48 | SIBE; 49 | #endif 50 | ZBank zb; 51 | #ifdef SIT 52 | SIT; 53 | #endif 54 | uint offset : 24; 55 | #ifdef SIEND 56 | SIEND; 57 | #endif 58 | } ZBankPointer ; 59 | 60 | typedef struct { 61 | //WARNING: this doesn't care if the exit bank is not at the same bank level 62 | ZBankPointer start; 63 | ZBankPointer end; 64 | } ZBankRange; 65 | 66 | string ZBankPointerRead(ZBankPointer &zbp){ 67 | local string s; 68 | SPrintf( s, "%s @ 0x%LX", ZBankRead(zbp.zb), zbp.offset); 69 | return s; 70 | }; 71 | 72 | int IsZBankLocal( ZBank &zb, int &thisBank ){ 73 | if( zb.bankNo == thisBank ){ 74 | return 1; 75 | } else { 76 | return 0; 77 | } 78 | } 79 | 80 | int IsZBankPointerLocal( ZBankPointer &zbp, int &thisBank ){ 81 | return IsZBankLocal( zbp.zb, thisBank ); 82 | } 83 | 84 | /* 85 | // Custom write function that allows changing 86 | // the name of the file - note that the file 87 | // name size cannot be increased 88 | 89 | void WriteZIPFILERECORD( ZIPFILERECORD &file, string s ) 90 | { 91 | local int len = Strlen( s ); 92 | if( exists( file.frFileName ) ) 93 | { 94 | Strncpy( file.frFileName, s, file.frFileNameLength ); 95 | if( len < file.frFileNameLength ) 96 | file.frFileName[len] = 0; //null terminate 97 | } 98 | } 99 | */ -------------------------------------------------------------------------------- /filetypes/Compressed/Yaz.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | 3 | typedef enum { 4 | YAZ_TYPE_ROM = 48, 5 | YAZ_TYPE_DD = 49, 6 | } YAZ_TYPE; 7 | 8 | typedef struct { 9 | uchar magic[3]; 10 | YAZ_TYPE dest; 11 | uint uncompressedSize; 12 | ubyte zeroes[8]; 13 | local uint64 src = FTell(); 14 | // provide a buffer 15 | local ubyte dst[uncompressedSize]; 16 | 17 | //current read/write positions 18 | local int srcPlace = 0, dstPlace = 0; 19 | //number of valid bits left in "code" byte 20 | local uint validBitCount = 0; 21 | local ubyte currCodeByte; 22 | local ubyte byte1, byte2; 23 | local uint dist, copySource, numBytes; 24 | local int i; 25 | while(dstPlace < uncompressedSize){ 26 | //read new "code" byte if the current one is used up 27 | if(validBitCount == 0){ 28 | currCodeByte = ReadUByte(src + srcPlace); 29 | ++srcPlace; 30 | validBitCount = 8; 31 | } 32 | 33 | if((currCodeByte & 0x80) != 0){ 34 | //straight copy 35 | dst[dstPlace] = ReadUByte(src + srcPlace); 36 | dstPlace++; 37 | srcPlace++; 38 | } else { 39 | //RLE part 40 | byte1 = ReadUByte(src + srcPlace); 41 | byte2 = ReadUByte(src + srcPlace + 1); 42 | srcPlace += 2; 43 | 44 | dist = ((byte1 & 0xF) << 8) | byte2; 45 | copySource = dstPlace - (dist + 1); 46 | 47 | numBytes = byte1 >> 4; 48 | if(numBytes == 0){ 49 | numBytes = ReadUByte(src + srcPlace) + 0x12; 50 | srcPlace++; 51 | } else { 52 | numBytes += 2; 53 | } 54 | 55 | //copy run 56 | for( i = 0; i < numBytes; ++i ){ 57 | dst[dstPlace] = dst[copySource]; 58 | copySource++; 59 | dstPlace++; 60 | } 61 | } 62 | 63 | //use next bit from "code" byte 64 | currCodeByte <<= 1; 65 | validBitCount-=1; 66 | } 67 | ubyte rawData[srcPlace]; 68 | } Yaz; 69 | 70 | typedef struct{ 71 | uint headerSize; 72 | local uint numRecords = (headerSize/4)-1; 73 | uint fileStarts[numRecords]; 74 | local uint64 jumpPos = FTell(); 75 | local uint i; 76 | for( i = 0; i < numRecords; i++ ){ 77 | Yaz file; 78 | //Assert(sizeof(file) == fileStarts[i], "weird sized yaz"); 79 | FSeek(jumpPos + fileStarts[i]); 80 | } 81 | } YazArc; -------------------------------------------------------------------------------- /filetypes/DamageCharts.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | 3 | /* 4 | This lives here until we find a way to dynamically locate them. 5 | */ 6 | 7 | typedef enum { 8 | DAMAGE_EFFECT_NORMAL = 0x0, 9 | DAMAGE_EFFECT_STUN = 0x1, 10 | DAMAGE_EFFECT_FIREARROW = 0x2, 11 | DAMAGE_EFFECT_ICEARROW = 0x3, 12 | DAMAGE_EFFECT_LIGHTARROW = 0x4, 13 | DAMAGE_EFFECT_ZORAMAGIC = 0x5, 14 | } DAMAGE_EFFECT; 15 | 16 | typedef struct { 17 | local string thisName = "ZDamageChart"; 18 | SIBE; 19 | 20 | // effect isn't constant so this can't be enumed. 21 | // 0 is usually normal 22 | // 1 is usually stun 23 | // 2 is sometimes fire 24 | // 3 is sometimes ice (usually follows fire) 25 | ubyte effect : 4; 26 | ubyte damage : 4; 27 | 28 | SIEND; 29 | } ZDamageChartEntry; 30 | 31 | typedef struct { 32 | local string thisName = "ZDamageChart"; 33 | SIBE; 34 | 35 | if( GAME == "MM" ){ 36 | ZDamageChartEntry dekuNuts; 37 | ZDamageChartEntry dekuStick; // unknown: or pot? 38 | ZDamageChartEntry epona; 39 | ZDamageChartEntry explosions; 40 | ZDamageChartEntry zoraBoomerang; 41 | ZDamageChartEntry arrow; 42 | ZDamageChartEntry maybeMirror; 43 | ZDamageChartEntry hookShot; 44 | ZDamageChartEntry goronPunch; 45 | ZDamageChartEntry kokiriSword; 46 | ZDamageChartEntry goronPound; 47 | ZDamageChartEntry fireArrow; 48 | ZDamageChartEntry iceArrow; 49 | ZDamageChartEntry lightArrow; 50 | ZDamageChartEntry goronSpikes; 51 | ZDamageChartEntry dekuSpin; 52 | ZDamageChartEntry dekuShot; 53 | ZDamageChartEntry dekuDive; 54 | ZDamageChartEntry dekuBomb; 55 | ZDamageChartEntry zoraBarrier; 56 | ZDamageChartEntry unknown1; 57 | ZDamageChartEntry unknown2; 58 | ZDamageChartEntry bush; 59 | ZDamageChartEntry zoraKarate; 60 | ZDamageChartEntry kokoriMSpin; 61 | ZDamageChartEntry fierceBeam; 62 | ZDamageChartEntry linkRoll; 63 | ZDamageChartEntry unknown3; 64 | ZDamageChartEntry unknown4; 65 | ZDamageChartEntry unknown5; 66 | ZDamageChartEntry unknown6; 67 | ZDamageChartEntry powderKeg; 68 | } else { 69 | ZDamageChartEntry dekuNuts; 70 | ZDamageChartEntry dekuStickOrPot; // slash / throw 71 | ZDamageChartEntry slingShot; 72 | ZDamageChartEntry explosions; 73 | ZDamageChartEntry boomerang; 74 | ZDamageChartEntry arrow; 75 | ZDamageChartEntry hammerSwing; 76 | ZDamageChartEntry hookShotOrLongShot; 77 | ZDamageChartEntry kokiriSword; // slash 78 | ZDamageChartEntry masterSword; // slash 79 | ZDamageChartEntry biggoronsSword; // slash 80 | ZDamageChartEntry fireArrows; 81 | ZDamageChartEntry iceArrows; 82 | ZDamageChartEntry lightArrows; 83 | ZDamageChartEntry windArrows; 84 | ZDamageChartEntry spiritArrows; 85 | ZDamageChartEntry shadowArrows; 86 | ZDamageChartEntry fireMagic; 87 | ZDamageChartEntry iceMagic; 88 | ZDamageChartEntry lightMagic; 89 | ZDamageChartEntry unknown1; 90 | ZDamageChartEntry unknown2; 91 | ZDamageChartEntry kokiriSwordSpin; // spin attack 92 | ZDamageChartEntry giantsKnifeSpin; // spin attack 93 | ZDamageChartEntry masterSwordSpin; // spin attack 94 | ZDamageChartEntry kokiriSwordOrBrokenGiantsKnifeJump; // jump / strong spin 95 | ZDamageChartEntry giantsKnifeJump; // jump / strong spin 96 | ZDamageChartEntry masterSwordJump; // jump / strong spin 97 | ZDamageChartEntry unknown3; 98 | ZDamageChartEntry unknown4; 99 | ZDamageChartEntry hammer; // jump 100 | ZDamageChartEntry unknown5; 101 | } 102 | SIEND; 103 | } ZDamageChart; -------------------------------------------------------------------------------- /filetypes/DisplayList/Commands/DA.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // Adds a new matrix from mtxaddr to the appropriate matrix stack. 3 | typedef struct { 4 | local string thisName = "DisplayListCommand_DF"; 5 | SIBE; 6 | 7 | SIT; 8 | DISPLAY_LIST_COMMAND commandType; 9 | AssertNumberEquals(commandType, 0xDA, thisName); 10 | 11 | SIT; UNK; 12 | ubyte threeEight; 13 | AssertNumberEquals(threeEight, 0x38, thisName); 14 | 15 | SIT; UNK; 16 | ubyte zero; 17 | AssertNumberEquals(zero, 0x00, thisName); 18 | 19 | SIT; 20 | ubyte unusedBits : 5; 21 | AssertNumberEquals(unusedBits, 0x00, thisName); 22 | 23 | SIT; 24 | /* 25 | MODELVIEW selects the modelview matrix stack 26 | (meaning the new matrix is a modelview matrix), 27 | while PROJECTION refers to the projection matrix "stack". 28 | Since the projection matrix "stack" is not actually a stack, 29 | rather a single matrix, the PUSH option is always ignored 30 | for new projection matrices. 31 | */ 32 | enum G_MTX_VIEWTYPE { 33 | G_MTX_MODELVIEW = 0x00, 34 | G_MTX_PROJECTION = 0x01, 35 | } viewType : 1; 36 | 37 | SIT; 38 | /* 39 | If MUL is specified, the new matrix is multiplied by the 40 | top of the stack before being placed according to PUSH/NOPUSH. 41 | Specifically the matrix product of new matrix * top of the stack 42 | (XXX verify this is the right order, 43 | since matrix multiplication ain't commutative). 44 | LOAD means no multiplication is done against the new matrix. 45 | */ 46 | enum G_MTX_LOADTYPE { 47 | G_MTX_MUL = 0x00, 48 | G_MTX_LOAD = 0x01, 49 | } loadType : 1; 50 | 51 | SIT; 52 | /* 53 | If PUSH is specified, then the matrix will be added to 54 | the top of the stack as a new stack element. If there is no room 55 | on the stack, this option is ignored and NOPUSH behavior occurs 56 | instead. NOPUSH means the top matrix of the stack will be overwritten 57 | with the new matrix. 58 | */ 59 | // the following is inverted from the documentation because how 60 | // the data is stored with this flag reversed 61 | enum G_MTX_PUSHTYPE { 62 | G_MTX_PUSH = 0x00, 63 | G_MTX_NOPUSH = 0x01, 64 | } pushType : 1; 65 | 66 | SIT; 67 | uint ramAddr; 68 | 69 | local string read = ReadDisplayListCommand_DA( this ); 70 | SIEND; 71 | } DisplayListCommand_DA; 72 | 73 | string ReadDisplayListCommand_DA( DisplayListCommand_DA &command ){ 74 | local string out = ""; 75 | SPrintf(out, " %s | %s | %s, 0x%08LX ", 76 | EnumToString(command.viewType), 77 | EnumToString(command.loadType), 78 | EnumToString(command.pushType), 79 | command.ramAddr 80 | ); 81 | return EnumToString(command.commandType) + "(" + out + ");"; 82 | } -------------------------------------------------------------------------------- /filetypes/DisplayList/Commands/DF.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "DisplayListCommand_DF"; 4 | SIBE; 5 | 6 | SIT; 7 | DISPLAY_LIST_COMMAND commandType; 8 | AssertNumberEquals(commandType, 0xDF, thisName); 9 | 10 | SIT; 11 | ubyte zeroes[7]; 12 | AssertUBytesNull(zeroes, thisName+"->zeroes"); 13 | 14 | local string read = ReadDisplayListCommand_DF( this ); 15 | SIEND; 16 | } DisplayListCommand_DF; 17 | 18 | string ReadDisplayListCommand_DF( DisplayListCommand_DF &command ){ 19 | local string out = ""; 20 | SPrintf(out, "%s", command.zeroes); 21 | return EnumToString(command.commandType) + "(" + out + ");"; 22 | } -------------------------------------------------------------------------------- /filetypes/DisplayList/Commands/Dummy.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "DisplayListCommand_Dummy"; 4 | SIBE; 5 | 6 | SIT; 7 | DISPLAY_LIST_COMMAND commandType; 8 | 9 | SIT; 10 | ubyte unknown[7]; 11 | 12 | local string read = ReadDisplayListCommand_Dummy( this ); 13 | SIEND; 14 | } DisplayListCommand_Dummy; 15 | 16 | string ReadDisplayListCommand_Dummy( DisplayListCommand_Dummy &command ){ 17 | local string out = ""; 18 | SPrintf(out, " 0x%02LX, 0x%02LX%02LX%02LX%02LX%02LX%02LX%02LX ", 19 | command.commandType, 20 | command.unknown[0], 21 | command.unknown[1], 22 | command.unknown[2], 23 | command.unknown[3], 24 | command.unknown[4], 25 | command.unknown[5], 26 | command.unknown[6] 27 | ); 28 | return "unknownCommand(" + out + ");"; 29 | } -------------------------------------------------------------------------------- /filetypes/DisplayList/DisplayList.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | 3 | enum DISPLAY_LIST_COMMAND { 4 | //gsDPNoOpTag = 0x00, 5 | //gsSPVertex = 0x01, 6 | //gsSPModifyVertex = 0x02, 7 | gsSPMatrix = 0xDA, 8 | // ... 9 | gsSPEndDisplayList = 0xDF, 10 | }; -------------------------------------------------------------------------------- /filetypes/DisplayList/DisplayListScanner.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local ubyte breakout = 0; 4 | while( !breakout ){ 5 | switch( ReadUByte() ){ 6 | case gsSPMatrix: 7 | DisplayListCommand_DA dlcom; 8 | break; 9 | // ... 10 | case gsSPEndDisplayList: // 0xDF 11 | DisplayListCommand_DF dlcom; 12 | breakout = 1; 13 | break; 14 | default: 15 | DisplayListCommand_Dummy dlcom; 16 | break; 17 | } 18 | } 19 | } DisplayListScanner; -------------------------------------------------------------------------------- /filetypes/Entrances.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | /* 3 | // this struct is for the OoT scene table 4 | typedef struct { 5 | uint vStart; 6 | uint vEnd; 7 | uint vTitleStart; 8 | uint vTitleEnd; 9 | 10 | // UNK; 11 | // Unknown (is either 0x01 or 0x02 for some dungeons, otherwise 0x00) 12 | ubyte maybeBankDef; 13 | 14 | // UNK; 15 | // Scene configuration", responsible for initializing and filling RAM segments; used ex. for camera effects, dynamic textures 16 | // 17 | // 0x15 = screen pulses a la Jabu-Jabu's Belly 18 | // 0x33 = screen shakes a la Ganon's Castle (collapsing) 19 | // 0x34 = same as 0x33 20 | // 0x35 - 0x37 = crashes 21 | // 0x3D+ = crashes 22 | 23 | // UNK; 24 | // Unknown (is unique value between 0x02 and 0x0A for some dungeons) 25 | ubyte maybeDungeonNumber; 26 | 27 | // UNK; 28 | // Nothing? (always 0x00) 29 | ubyte unknown; 30 | } ZSceneTableEntry; 31 | */ 32 | 33 | // this struct is for the MM scene table 34 | typedef struct { 35 | uint vStart; 36 | uint vEnd; 37 | ubyte unknown[4]; 38 | ubyte zeroes[4]; 39 | } SceneTableEntry; 40 | 41 | typedef struct { 42 | local string thisName = "ZEntranceTable"; 43 | ubyte sceneNumber; 44 | ubyte entranceInScene; 45 | // Additionally, this value affects dynamic exits 46 | // Is used to determine which Fairy Fountain you've entered (see below). 47 | ubyte transitionControl; 48 | ubyte transitionAnimation; 49 | } ZEntrance; 50 | 51 | /* 52 | sseevvtt 53 | s is the Scene number to load 54 | e sets what "entrance" within the scene to spawn at. 55 | v is a variable used to control certain behaviors (ex. whether to cut the music short) when transitioning to a new entrance 56 | t sets the transition animation that plays when transitioning to a new entrance. It's important to note that dust transition effect requires a specific object file in both the start scene and the destination scene in order to work without throwing one or more graphic exceptions. 57 | */ 58 | 59 | // 0x00DECD40 where it starts 60 | // 0x00BDE540 what we're gonna bounce it against 61 | // 0x00227300 what to bounce (scene name string pointer) 62 | // 0x00E05840 where we end up (scene name string) 63 | #define EXITBOUNCEHACK 0x00BDE540 64 | typedef struct { 65 | local string thisName = "ZExitTable"; 66 | SIBE; 67 | 68 | SIT; 69 | ubyte numSpawnPoints; 70 | 71 | SIT; 72 | ubyte zeroes[3]; 73 | AssertUBytesNull(zeroes, thisName); 74 | 75 | SIT; 76 | ZBankPointer ramPointerScene; 77 | 78 | local uint64 walk = 0; 79 | if( ramPointerScene.offset > 0 ){ 80 | SAVE; 81 | FSeek(ramPointerScene.offset + EXITBOUNCEHACK); 82 | ZBankPointer theScenePointer[numSpawnPoints]; 83 | for( walk = 0; walk < numSpawnPoints; walk++ ){ 84 | SAVE; 85 | FSeek(theScenePointer[walk].offset + EXITBOUNCEHACK); 86 | ZEntrance entrances; 87 | REST; 88 | } 89 | REST; 90 | } else { 91 | //Assert(false, "bad scene"); 92 | } 93 | 94 | SIT; 95 | ZBankPointer ramPointerSceneName; 96 | 97 | if( ramPointerSceneName.offset > 0 ){ 98 | SAVE; 99 | FSeek(ramPointerSceneName.offset + EXITBOUNCEHACK); 100 | string theSceneName; 101 | REST; 102 | } else { 103 | //Assert(false, "bad scene name"); 104 | } 105 | 106 | SIEND; 107 | } ZExitTable; 108 | 109 | 110 | typedef struct { 111 | SIBE; 112 | 113 | SIT; 114 | ubyte sceneNumber; 115 | 116 | SIT; 117 | ubyte presetPlayerSpawnPoint; 118 | 119 | SIT; 120 | ubyte fadeInEffect; 121 | 122 | SIT; 123 | ubyte fadeOutEffect; 124 | 125 | SIEND; 126 | } ZSpawnEntries; 127 | 128 | /* 129 | exit table stuff: 130 | (10:46:53 AM) Twili: the exit table is at 0xDECD38 131 | (10:47:19 AM) Twili: 0xBDE540 is a value added to the lower 24 bits of some ram pointers to get the rom equivalent 132 | (10:47:38 AM) Twili: 0xDEB2B0 is the scene table 133 | 134 | (10:48:32 AM) Twili: the exit table has this structure 135 | (10:48:48 AM) Twili: XX 00 00 00 YY YY YY YY ZZ ZZ ZZ ZZ 136 | (10:48:59 AM) Twili: XX = number of spawn points 137 | (10:49:08 AM) Twili: YY YY YY YY = ram pointer to scene name 138 | (10:49:26 AM) Twili: ZZ ZZ ZZ ZZ = ram pointer to spawn pointer table 139 | 140 | (10:49:42 AM) Twili: there are as many spawn pointers as XX 141 | (10:49:57 AM) Twili: and they point to the spawn entries 142 | (10:50:03 AM) Twili: AA BB CC DD 143 | (10:50:10 AM) Twili: AA = scene number 144 | (11:03:52 AM) wareya: 10:50 <@Twili> BB = preset link spawn point in the scene file 145 | (11:03:52 AM) wareya: 10:50 <@Twili> CC = fade in effect 146 | (10:51:39 AM) Twili: DD = fade out effect 147 | (10:50:13 AM) Twili: some are negative, though 148 | (10:50:36 AM) Twili: so you have to multiply by -1 149 | (10:50:43 AM) Twili: if they're negative 150 | */ -------------------------------------------------------------------------------- /filetypes/FileSystem.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | uint start; 4 | uint end; 5 | } ZFileSystemRange; 6 | 7 | local uint numVFSFiles = 1; 8 | local uint existingVFSStarts[FileSize()]; 9 | typedef struct { 10 | // the "v" means virtual, relative to the ROM 11 | uint vStart; 12 | existingVFSStarts[vStart] = numVFSFiles; 13 | uint vEnd; 14 | 15 | // the "p" means physical, relative to the N64 memory map 16 | uint pStart; 17 | uint pEnd; 18 | numVFSFiles++; 19 | } ZFileSystemEntry; 20 | 21 | typedef struct { 22 | local uint64 seekPos = FTell(); 23 | while( ReadUInt(seekPos) != startof(this) ){ 24 | seekPos += sizeof(ZFileSystemEntry); 25 | } 26 | local uint64 numVFSEntries = (ReadUInt(seekPos+4) - startof(this)) / sizeof(ZFileSystemEntry); 27 | ZFileSystemEntry vfs[numVFSEntries]; 28 | } ZFileSystemTable; 29 | 30 | uint IsValidFile(uint vstart){ 31 | return existingVFSStarts[vstart]; 32 | } -------------------------------------------------------------------------------- /filetypes/MIPS/Commands/ADDI.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // Adds a new matrix from mtxaddr to the appropriate matrix stack. 3 | typedef struct { 4 | local string asmName = "addi"; 5 | local string thisName = "MIPS_Code_ADDI"; 6 | SIBE; 7 | 8 | SIT; 9 | MIPS_CODE opType : 6; 10 | AssertNumberEquals(opType, MIPS_CODE_ADDI, thisName); 11 | 12 | SIT; 13 | ubyte rs : 5; 14 | 15 | SIT; 16 | ubyte rt : 5; 17 | 18 | SIT; 19 | short imm; 20 | 21 | local string asm_code = ReadASM_MIPS_Code_ADDI( this ); 22 | local string c_code = ReadC_MIPS_Code_ADDI( this ); 23 | SIEND; 24 | } MIPS_Code_ADDI; 25 | 26 | string ReadASM_MIPS_Code_ADDI( MIPS_Code_ADDI &op ){ 27 | local string out = ""; 28 | SPrintf(out, "%s\t%s, %s, 0x%04LX", 29 | op.asmName, 30 | GetRegisterName(op.rt), 31 | GetRegisterName(op.rs), 32 | op.imm 33 | ); 34 | return out; 35 | } 36 | 37 | string ReadC_MIPS_Code_ADDI( MIPS_Code_ADDI &op ){ 38 | local string out = ""; 39 | SPrintf(out, "%s = %s + 0x%04LX;\nadvance_pc(4);\n", 40 | GetRegisterName(op.rt), 41 | GetRegisterName(op.rs), 42 | op.imm 43 | ); 44 | return out; 45 | } -------------------------------------------------------------------------------- /filetypes/MIPS/Commands/ADDIU.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // Adds a new matrix from mtxaddr to the appropriate matrix stack. 3 | typedef struct { 4 | local string asmName = "addiu"; 5 | local string thisName = "MIPS_Code_ADDIU"; 6 | SIBE; 7 | 8 | SIT; 9 | MIPS_CODE opType : 6; 10 | AssertNumberEquals(opType, MIPS_CODE_ADDIU, thisName); 11 | 12 | SIT; 13 | ubyte rs : 5; 14 | 15 | SIT; 16 | ubyte rt : 5; 17 | 18 | SIT; 19 | ushort imm; 20 | 21 | local string asm_code = ReadASM_MIPS_Code_ADDIU( this ); 22 | local string c_code = ReadC_MIPS_Code_ADDIU( this ); 23 | SIEND; 24 | } MIPS_Code_ADDIU; 25 | 26 | string ReadASM_MIPS_Code_ADDIU( MIPS_Code_ADDIU &op ){ 27 | local string out = ""; 28 | SPrintf(out, "%s\t%s, %s, 0x%04LX", 29 | op.asmName, 30 | GetRegisterName(op.rt), 31 | GetRegisterName(op.rs), 32 | op.imm 33 | ); 34 | return out; 35 | } 36 | 37 | string ReadC_MIPS_Code_ADDIU( MIPS_Code_ADDIU &op ){ 38 | local string out = ""; 39 | SPrintf(out, "%s = %s + 0x%04LX;\nadvance_pc(4);\n", 40 | GetRegisterName(op.rt), 41 | GetRegisterName(op.rs), 42 | op.imm 43 | ); 44 | return out; 45 | } -------------------------------------------------------------------------------- /filetypes/MIPS/MIPS_Code.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | 3 | local string MIPS_Context_Code = ""; 4 | MIPS_Context_Code += "void advance_pc( int offset ){\n"; 5 | MIPS_Context_Code += "\t PC = nPC;\n"; 6 | MIPS_Context_Code += "\tnPC += offset;\n"; 7 | MIPS_Context_Code += "}\n"; 8 | 9 | // https://github.com/mikeryan/n64dev/blob/master/docs/n64ops/n64ops%23b.txt 10 | // http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html 11 | // http://groups.csail.mit.edu/cag/raw/documents/R4400_Uman_book_Ed2.pdf 12 | 13 | /* 14 | (12:29:13 PM) notwa: they forgot to remove LDC2/SDC2 from #c.txt 15 | (12:29:20 PM) notwa: they don't exist 16 | (12:30:02 PM) notwa: or technically they're unimplemented on the R4300i 17 | (12:30:07 PM) notwa: but details schmetails 18 | (12:30:12 PM) Zoinkity: RCP is implemented as COP2 iirc 19 | (12:30:26 PM) notwa: hmm 20 | (12:30:12 PM) Zoinkity: RCP is implemented as COP2 iirc 21 | (12:30:26 PM) notwa: hmm 22 | (12:31:19 PM) notwa: i don't think so 23 | (12:31:55 PM) notwa: only COP0 and COP1 24 | */ 25 | 26 | enum MIPS_BRANCH { 27 | MIPS_BRANCH_BLTZ = 0x00, 28 | MIPS_BRANCH_BGEZ = 0x01, 29 | // ... ? 30 | MIPS_BRANCH_BLTZAL = 0x10, 31 | MIPS_BRANCH_BGEZAL = 0x11, 32 | // ... ??? 33 | }; 34 | 35 | enum MIPS_CODE { 36 | MIPS_CODE_LOGICAL = 0x00, // uses last bits 37 | MIPS_CODE_BRANCH = 0x01, // uses bits 10-15 38 | MIPS_CODE_J = 0x02, 39 | MIPS_CODE_JAL = 0x03, 40 | MIPS_CODE_BEQ = 0x04, 41 | MIPS_CODE_BNE = 0x05, 42 | MIPS_CODE_BLEZ = 0x06, 43 | MIPS_CODE_BGTZ = 0x07, 44 | MIPS_CODE_ADDI = 0x08, 45 | MIPS_CODE_ADDIU = 0x09, 46 | MIPS_CODE_SLTI = 0x0A, 47 | MIPS_CODE_SLTIU = 0x0B, 48 | MIPS_CODE_ANDI = 0x0C, 49 | MIPS_CODE_ORI = 0x0D, 50 | MIPS_CODE_XORI = 0x0E, 51 | MIPS_CODE_LUI = 0x0F, 52 | // ... 53 | MIPS_CODE_LB = 0x20, 54 | // ... 55 | MIPS_CODE_LW = 0x23, 56 | MIPS_CODE_LBU = 0x24, 57 | // ... 58 | MIPS_CODE_SB = 0x28, 59 | // ... 60 | MIPS_CODE_SW = 0x2B, 61 | // ... 62 | MIPS_CODE_LD = 0x37, 63 | }; 64 | 65 | enum MIPS_LOGIC { 66 | MIPS_LOGIC_SLL = 0x00, 67 | // ... 68 | MIPS_LOGIC_SRL = 0x02, 69 | MIPS_LOGIC_SRA = 0x03, 70 | MIPS_LOGIC_SLLV = 0x04, 71 | // ... 72 | MIPS_LOGIC_SRLV = 0x06, // 0 0, 0 1 1 0 73 | // ... 74 | MIPS_LOGIC_JR = 0x08, // 0 0, 1 0 0 0 75 | // ... 76 | MIPS_LOGIC_SYSCALL = 0x0B, // 0 0, 1 1 0 0 77 | // ... 78 | MIPS_LOGIC_MFHI = 0x10, // 0 1, 0 0 0 0 79 | // ... 80 | MIPS_LOGIC_MFLO = 0x12, // 0 1, 0 0 1 0 81 | // ... 82 | MIPS_LOGIC_MULT = 0x18, // 0 1, 1 0 0 0 83 | MIPS_LOGIC_MULTU = 0x19, // 0 1, 1 0 0 1 84 | // ... 85 | MIPS_LOGIC_DIV = 0x1A, // 0 1, 1 0 1 0 86 | MIPS_LOGIC_DIVU = 0x1B, // 0 1, 1 0 1 1 87 | // ... 88 | MIPS_LOGIC_ADD = 0x20, // 1 0, 0 0 0 0 89 | MIPS_LOGIC_ADDU = 0x21, // 1 0, 0 0 0 1 90 | MIPS_LOGIC_SUB = 0x22, // 1 0, 0 0 1 0 91 | MIPS_LOGIC_SUBU = 0x23, // 1 0, 0 0 1 1 92 | MIPS_LOGIC_AND = 0x24, // 1 0, 0 1 0 0 93 | // ... 94 | MIPS_LOGIC_OR = 0x25, // 1 0, 0 1 0 1 95 | MIPS_LOGIC_XOR = 0x26, // 1 0, 0 1 1 0 96 | // ... 97 | MIPS_LOGIC_SLT = 0x2A, // 1 0, 1 0 1 0 98 | MIPS_LOGIC_SLTU = 0x2B, // 1 0, 1 0 1 1 99 | // ... 100 | }; 101 | 102 | // NOOP == SLL $0, $0, 0 103 | 104 | string GetRegisterName( uint i ){ 105 | local string ret = "$"; 106 | if( i == 0 ){ 107 | ret += "r" + 0; 108 | } else if( i == 1 ){ 109 | ret += "at"; 110 | } else if( i >= 2 && i <= 3 ){ 111 | ret += "v" + (i-2); 112 | } else if( i >= 4 && i <= 7 ){ 113 | ret += "a" + (i-4); 114 | } else if( i >= 8 && i <= 15 ){ 115 | ret += "t" + (i-8); 116 | } else if( i >= 16 && i <= 23 ){ 117 | ret += "s" + (i-16); 118 | } else if( i >= 24 && i <= 25 ){ 119 | ret += "t" + (i-16); 120 | } else if( i >= 26 && i <= 27 ){ 121 | ret += "v" + (i-26); 122 | } else if( i == 28 ){ 123 | ret += "gp"; 124 | } else if( i == 29 ){ 125 | ret += "sp"; 126 | } else if( i == 30 ){ 127 | ret += "fp"; 128 | } else if( i == 31 ){ 129 | ret += "ra"; 130 | } else if( i == 32 ){ 131 | ret += "Hi/Lo"; 132 | } else { 133 | ret += "unknownRegister"; 134 | } 135 | return ret; 136 | } -------------------------------------------------------------------------------- /filetypes/MIPS/MIPS_CodeScanner.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | 3 | // this doesn't have any stop words (that I know of) 4 | // don't bother with this until all the commands are implemented 5 | 6 | typedef struct { 7 | local ubyte breakout = 0; 8 | while( !breakout ){ 9 | switch( ReadUByteBits(FTell(), 0, 6) ){ 10 | // ... 11 | case MIPS_CODE_ADDIU: // 0x9 12 | MIPS_Code_ADDIU mipsop; 13 | break; 14 | // ... 15 | default: 16 | //MIPS_Code_Dummy mipsop; 17 | breakout = 1; 18 | break; 19 | } 20 | breakout = 1; 21 | } 22 | } MIPS_CodeScanner; -------------------------------------------------------------------------------- /filetypes/Memory.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | #define PRAM_START 0x80000000 3 | #define PRAM_LOW 0x803FFFFF 4 | #define PRAM_HIGH 0x807FFFFF 5 | 6 | #define VRAM_START 0x80800000 7 | #define VRAM_END 0x80FFFFFF 8 | 9 | typedef struct { 10 | uint memoryAddress; 11 | } Ram; 12 | 13 | string ReadRam( Ram &f ){ 14 | local string s; 15 | local string wasBigSize; 16 | if( 17 | f.memoryAddress >= PRAM_START && 18 | f.memoryAddress < VRAM_START 19 | ){ 20 | if( f.memoryAddress <= PRAM_LOW ){ 21 | wasBigSize = "Physical, Low"; 22 | } else if( 23 | f.memoryAddress > PRAM_LOW && 24 | f.memoryAddress <= PRAM_HIGH 25 | ){ 26 | wasBigSize = "Physical, High"; 27 | } 28 | } else if( 29 | f.memoryAddress >= VRAM_START && 30 | f.memoryAddress < VRAM_END 31 | ){ 32 | wasBigSize = "Virtual"; 33 | } else { 34 | return "Invalid"; 35 | } 36 | SPrintf(s, "0x%08LX (%s)", f.memoryAddress, wasBigSize); 37 | return s; 38 | } -------------------------------------------------------------------------------- /filetypes/Messages.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | /* 3 | Read a MM message table and relate it to the text table. 4 | Does not work for the credits yet, as that hinges on 5 | interpreting OoT ANSI text mode. 6 | 7 | Does not yet provide easy-to-manipulate text. 8 | This will fail if an inline text command uses an argument 9 | that contains the stopcommand, only way around that is 10 | to parse the text. 11 | 12 | The suggested implementation is a "text" struct, 13 | and a "command" struct. Maybe multiple command structs. 14 | */ 15 | 16 | typedef struct{ 17 | ubyte textBoxType; 18 | ubyte textBoxYPos; 19 | ubyte textBoxIcon; 20 | ushort nextMessageNumber; 21 | ushort rupeeCost; 22 | ubyte FF[4]; 23 | local ubyte breakout = 0; 24 | local ubyte read = 0; 25 | local uint64 scanPos = 0; 26 | while( !breakout ){ 27 | read = ReadUByte(FTell()+scanPos); 28 | switch(read){ 29 | // 0xBF is the stopword in MM only 30 | case 0xBF: 31 | breakout = 1; 32 | break; 33 | } 34 | scanPos++; 35 | } 36 | uchar text[scanPos]; 37 | } ZMessage; 38 | 39 | typedef struct(uint64 messageBank){ 40 | ushort messageNumber; 41 | ubyte zeroes[2]; 42 | ubyte fontIndex; 43 | uint offset : 24; 44 | 45 | SAVE; 46 | FSeek( messageBank + offset ); 47 | ZMessage message; 48 | REST; 49 | } ZMessageTableEntry; 50 | 51 | typedef struct(uint64 messageBank){ 52 | local ushort numMessages = 0; 53 | while( ReadUShort(FTell() + 8*numMessages) != 0xFFFF ){ 54 | numMessages++; 55 | } 56 | ZMessageTableEntry messages(messageBank)[numMessages]; 57 | } ZMessageTable; -------------------------------------------------------------------------------- /filetypes/N64ROMHead.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // TODO: Finish this (rom head) 3 | // Incomplete. 4 | typedef struct { 5 | ubyte endianess; 6 | 7 | ubyte d1releaseReg : 4; 8 | ubyte d1pagesReg : 4; 9 | ubyte d1pulseWidthReg; 10 | ubyte d1latencyReg; 11 | uint clockrate; //0xFFFFFFF0 for override 12 | uint programCounter; 13 | uint release; 14 | uint CRC1; 15 | uint CRC2; 16 | char unknown[8]; 17 | 18 | char gameTitle[20]; 19 | char nullZone[5]; 20 | char spareNulls[2]; 21 | char gameCode[3]; 22 | char destinationCode; 23 | 24 | /* 25 | 65 0x41 'A' "Asian (NTSC)" 26 | 66 0x42 'B' "Brazilian" 27 | 67 0x43 'C' "Chinese" 28 | 68 0x44 'D' "German" 29 | 69 0x45 'E' "North America" 30 | 70 0x46 'F' "French" 31 | 71 0x47 'G': Gateway 64 (NTSC) 32 | 72 0x48 'H' "Dutch" 33 | 73 0x49 'I' "Italian" 34 | 74 0x4A 'J' "Japanese" 35 | 75 0x4B 'K' "Korean" 36 | 76 0x4C 'L': Gateway 64 (PAL) 37 | 78 0x4E 'N' "Canadian" 38 | 80 0x50 'P' "European (basic spec.)" 39 | 83 0x53 'S' "Spanish" 40 | 85 0x55 'U' "Australian" 41 | 87 0x57 'W' "Scandinavian" 42 | 88 0x58 'X' "European" 43 | 89 0x59 'Y' "European" 44 | 90 0x5A 'Z' "Others" 45 | */ 46 | ubyte maskROMVersion; 47 | char bootCode[4032]; 48 | } N64ROMHead; 49 | -------------------------------------------------------------------------------- /filetypes/NIFF/Cam.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | enum CAM_TYPE { 3 | PERSP = CAM_TYPE_PERSP, 4 | ORTHO = CAM_TYPE_ORTHO 5 | }; 6 | 7 | typedef struct( uint64 size ){ 8 | // @TODO: Validate against ExternalNameList 9 | uint external_lookat_obj_file_name_index; 10 | uint external_lookat_obj_name_index; 11 | uint external_eye_obj_file_name_index; 12 | uint external_eye_obj_name_index; 13 | uint external_up_obj_file_name_index; 14 | uint external_up_obj_name_index; 15 | // since we can be variable size, 16 | // block out all unknown data 17 | local uint64 size_of_the_unknown = size - (FTell() - startof(this)); 18 | if( size_of_the_unknown > 0 ){ 19 | ubyte unknown[size_of_the_unknown]; 20 | } 21 | } NIFF_NEB_Cam; 22 | 23 | 24 | typedef struct { 25 | uint cam_tag; 26 | Assert( cam_tag == TAG_CAM, "Invalid NIFF_Cam: Wrong Tag" ); 27 | uint this_cam_index; 28 | uint cam_size; 29 | // @TODO: Validate against NameList 30 | uint cam_name_index; 31 | CAM_TYPE cam_type; 32 | float cam_near_clip; 33 | float cam_far_clip; 34 | float cam_right_clip; 35 | float cam_left_clip; 36 | float cam_top_clip; 37 | float cam_bottom_clip; 38 | float cam_fovy; 39 | float cam_aspect; 40 | float cam_scale; 41 | // @TODO: Validate against ObjList 42 | uint cam_lookat_obj; 43 | // @TODO: Validate against ObjList 44 | uint cam_eye_obj; 45 | // @TODO: Validate against ObjList 46 | uint cam_up_obj; 47 | uint nintendo_extension_block_size; 48 | uint user_extension_block_size; 49 | if( nintendo_extension_block_size != NINTENDO_EXT_BLOCK_NONE ){ 50 | NIFF_NEB_Cam nintendoExtensionBlock(nintendo_extension_block_size); 51 | } 52 | if( user_extension_block_size != USER_EXT_BLOCK_NONE ){ 53 | NIFF_XEB_Generic userExtensionBlock(user_extension_block_size); 54 | } 55 | } NIFF_Cam; 56 | 57 | typedef struct { 58 | uint cam_list_tag; 59 | Assert( cam_list_tag == TAG_CAM_LIST, "Invalid NIFF_CamListHeader: Wrong Tag" ); 60 | uint cam_list_header_size; 61 | uint cam_list_size; 62 | uint cam_num; 63 | uint nintendo_extension_block_size; 64 | uint user_extension_block_size; 65 | uint cam_num_byte[cam_num]; 66 | } NIFF_CamListHeader; 67 | 68 | typedef struct { 69 | NIFF_CamListHeader header; 70 | Assert( header.cam_list_header_size == sizeof(header), "Invalid NIFF_CamListHeader: Size Mismatch" ); 71 | NIFF_Cam cams[header.cam_num]; 72 | local uint64 i; 73 | local string warn; 74 | local string thisName; 75 | for( i = 0; i < header.cam_num; i++ ){ 76 | SPrintf( thisName, "Invalid NIFF_Cam[%d]: ", i ); 77 | 78 | SPrintf( warn, "%sSize Mismatch: Actual != Header", thisName ); 79 | Assert( header.cam_num_byte[i] == sizeof(cams[i]), warn ); 80 | SPrintf( warn, "%sSize Mismatch: Actual != Internal", thisName ); 81 | Assert( cams[i].cam_size == sizeof(cams[i]), warn ); 82 | SPrintf( warn, "%sSize Mismatch: Header != Internal", thisName ); 83 | Assert( header.cam_num_byte[i] == cams[i].cam_size, warn ); 84 | SPrintf( warn, "%sIndex Mismatch: Header != Internal", thisName ); 85 | Assert( i == cams[i].this_cam_index, warn ); 86 | } 87 | if( header.nintendo_extension_block_size != NINTENDO_EXT_BLOCK_NONE ){ 88 | NIFF_XEB_Generic nintendoExtensionBlock(header.nintendo_extension_block_size); 89 | } 90 | if( header.user_extension_block_size != USER_EXT_BLOCK_NONE ){ 91 | NIFF_XEB_Generic userExtensionBlock(header.user_extension_block_size); 92 | } 93 | } NIFF_CamList; -------------------------------------------------------------------------------- /filetypes/NIFF/Common.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | #define GENERIC_NONE 0xFFFFFFFF 3 | 4 | typedef struct { 5 | ubyte R; 6 | ubyte G; 7 | ubyte B; 8 | ubyte A; 9 | } NIFF_Color; 10 | 11 | typedef struct { 12 | ubyte E; 13 | Assert( E == 0, "Invalid NIFF_FillColor: First Byte Null" ); 14 | ubyte R; 15 | ubyte G; 16 | ubyte B; 17 | } NIFF_FillColor; 18 | 19 | // not everything uses the NEB/UEB, so scaffold it 20 | typedef struct( uint64 size ){ 21 | // since we can be variable size, 22 | // block out all unknown data 23 | local uint64 size_of_the_unknown = size - (FTell() - startof(this)); 24 | if( size_of_the_unknown > 0 ){ 25 | ubyte unknown[size_of_the_unknown]; 26 | } 27 | } NIFF_XEB_Generic; -------------------------------------------------------------------------------- /filetypes/NIFF/Env.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | enum ENV_FOG { 3 | USE = ENV_FOG_USE, 4 | NONE = ENV_FOG_NONE 5 | }; 6 | 7 | typedef struct { 8 | uint env_tag; 9 | Assert( env_tag == TAG_ENV, "Invalid NIFF_Env: Wrong Tag" ); 10 | uint this_env_index; 11 | uint env_size; 12 | // @TODO: Validate against NameList 13 | uint env_name_index; 14 | // @TODO: Validate that item has name 15 | ENV_FOG fog; 16 | NIFF_Color fog_color; 17 | uint fog_near; 18 | uint fog_far; 19 | if( ReadUInt() != FILL_COLOR_NONE ){ 20 | NIFF_FillColor fill_color; 21 | } else { 22 | uint fill_color; 23 | } 24 | if( ReadUInt() != FILL_DEPTH_NONE ){ 25 | NIFF_FillColor fill_depth; 26 | } else { 27 | uint fill_depth; 28 | } 29 | // @TODO: Validate against TexList 30 | if( ReadUInt() != BG_COLOR_IMG_NONE ){ 31 | uint bg_sprite_img; 32 | } else { 33 | uint bg_sprite_img; 34 | } 35 | // @TODO: Validate against TexList 36 | if( ReadUInt() != BG_DEPTH_IMG_NONE ){ 37 | uint bg_depth_img; 38 | } else { 39 | uint bg_depth_img; 40 | } 41 | uint nintendo_extension_block_size; 42 | uint user_extension_block_size; 43 | if( nintendo_extension_block_size != NINTENDO_EXT_BLOCK_NONE ){ 44 | NIFF_XEB_Generic nintendoExtensionBlock(nintendo_extension_block_size); 45 | } 46 | if( user_extension_block_size != USER_EXT_BLOCK_NONE ){ 47 | NIFF_XEB_Generic userExtensionBlock(user_extension_block_size); 48 | } 49 | } NIFF_Env; 50 | 51 | typedef struct { 52 | uint env_list_tag; 53 | Assert( env_list_tag == TAG_ENV_LIST, "Invalid NIFF_EnvListHeader: Wrong Tag" ); 54 | uint env_list_header_size; 55 | uint env_list_size; 56 | uint env_num; 57 | uint nintendo_extension_block_size; 58 | uint user_extension_block_size; 59 | uint env_num_byte[env_num]; 60 | } NIFF_EnvListHeader; 61 | 62 | typedef struct { 63 | NIFF_EnvListHeader header; 64 | Assert( header.env_list_header_size == sizeof(header), "Invalid NIFF_EnvListHeader: Size Mismatch" ); 65 | NIFF_Env envs[header.env_num]; 66 | local uint64 i; 67 | local string warn; 68 | local string thisName; 69 | for( i = 0; i < header.env_num; i++ ){ 70 | SPrintf( thisName, "Invalid NIFF_Env[%d]: ", i ); 71 | 72 | SPrintf( warn, "%sSize Mismatch: Actual != Header", thisName ); 73 | Assert( header.env_num_byte[i] == sizeof(envs[i]), warn ); 74 | SPrintf( warn, "%sSize Mismatch: Actual != Internal", thisName ); 75 | Assert( envs[i].env_size == sizeof(envs[i]), warn ); 76 | SPrintf( warn, "%sSize Mismatch: Header != Internal", thisName ); 77 | Assert( header.env_num_byte[i] == envs[i].env_size, warn ); 78 | SPrintf( warn, "%sIndex Mismatch: Header != Internal", thisName ); 79 | Assert( i == envs[i].this_env_index, warn ); 80 | } 81 | if( header.nintendo_extension_block_size != NINTENDO_EXT_BLOCK_NONE ){ 82 | NIFF_XEB_Generic nintendoExtensionBlock(header.nintendo_extension_block_size); 83 | } 84 | if( header.user_extension_block_size != USER_EXT_BLOCK_NONE ){ 85 | NIFF_XEB_Generic userExtensionBlock(header.user_extension_block_size); 86 | } 87 | } NIFF_EnvList; -------------------------------------------------------------------------------- /filetypes/NIFF/Light.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // @todo: I got distracted while writing these so there's a high chance that 3 | // this needs to be fixed up in some capacity 4 | 5 | enum LIGHT_TYPE { 6 | DIRECTION = LIGHT_TYPE_DIRECTION, 7 | POSITION = LIGHT_TYPE_POSITION 8 | }; 9 | 10 | typedef struct { 11 | uint dir_light_tag; 12 | uint this_dir_light_index; 13 | uint dir_light_size; 14 | float dir_color_r; 15 | float dir_color_g; 16 | float dir_color_b; 17 | float dir_x; 18 | float dir_y; 19 | float dir_z; 20 | } NIFF_DirLight1; 21 | 22 | typedef struct { 23 | uint dir_light_tag; 24 | uint this_dir_light_index; 25 | uint dir_light_size; 26 | float dir_color_r; 27 | float dir_color_g; 28 | float dir_color_b; 29 | float pos_x; 30 | float pos_y; 31 | float pos_z; 32 | //float dir_a1; 33 | //float dir_a2; 34 | } NIFF_DirLightDirection; 35 | 36 | typedef struct { 37 | uint dir_light_tag; 38 | uint this_dir_light_index; 39 | uint dir_light_size; 40 | float dir_color_r; 41 | float dir_color_g; 42 | float dir_color_b; 43 | float dir_x; 44 | float dir_y; 45 | float dir_z; 46 | float pos_x; 47 | float pos_y; 48 | float pos_z; 49 | float dir_a1; 50 | float dir_a2; 51 | } NIFF_DirLightPosition; 52 | 53 | typedef struct { 54 | uint light_tag; 55 | Assert( light_tag == TAG_LIGHT, "Invalid NIFF_Light: Wrong Tag" ); 56 | uint this_light_index; 57 | uint light_header_size; 58 | uint light_size; 59 | // @TODO: Validate against NameList 60 | uint light_name_index; 61 | // @TODO: Validate that item has name 62 | LIGHT_TYPE light_type; 63 | float ambient_r; 64 | float ambient_g; 65 | float ambient_b; 66 | uint dir_light_num; 67 | uint nintendo_extension_block_size; 68 | uint user_extension_block_size; 69 | } NIFF_LightHeader; 70 | 71 | typedef struct { 72 | NIFF_LightHeader header; 73 | Assert( header.light_header_size == sizeof(header), "Invalid NIFF_LightHeader: Size Mismatch" ); 74 | if( header.light_type == LIGHT_TYPE_DIRECTION ){ 75 | NIFF_DirLightDirection dir_lights[header.dir_light_num]; 76 | } else if( header.light_type == LIGHT_TYPE_POSITION ){ 77 | NIFF_DirLightPosition dir_lights[header.dir_light_num]; 78 | } else { 79 | Assert( false, "Invalid NIFF_Light: Unrecognized light_type" ); 80 | } 81 | 82 | local uint64 i; 83 | local string warn; 84 | local string thisName; 85 | for( i = 0; i < header.dir_light_num; i++ ){ 86 | SPrintf( thisName, "Invalid NIFF_DirLight[%d]: ", i ); 87 | 88 | SPrintf( warn, "%sSize Mismatch: Actual != Internal", thisName ); 89 | Assert( dir_lights[i].dir_light_size == sizeof(dir_lights[i]), warn ); 90 | SPrintf( warn, "%sIndex Mismatch: Header != Internal", thisName ); 91 | //Assert( i == lights[i].this_light_index, warn ); 92 | } 93 | } NIFF_Light; 94 | 95 | // everything under here has been vetted ;) 96 | typedef struct { 97 | uint light_list_tag; 98 | Assert( light_list_tag == TAG_LIGHT_LIST, "Invalid NIFF_LightListHeader: Wrong Tag" ); 99 | uint light_list_header_size; 100 | uint light_list_size; 101 | uint light_num; 102 | uint nintendo_extension_block_size; 103 | uint user_extension_block_size; 104 | uint light_num_byte[light_num]; 105 | } NIFF_LightListHeader; 106 | 107 | typedef struct { 108 | NIFF_LightListHeader header; 109 | Assert( header.light_list_header_size == sizeof(header), "Invalid NIFF_LightListHeader: Size Mismatch" ); 110 | 111 | NIFF_Light lights[header.light_num]; 112 | local uint64 i; 113 | local string warn; 114 | local string thisName; 115 | for( i = 0; i < header.light_num; i++ ){ 116 | SPrintf( thisName, "Invalid NIFF_Light[%d]: ", i ); 117 | 118 | SPrintf( warn, "%sSize Mismatch: Actual != Header", thisName ); 119 | Assert( header.light_num_byte[i] == sizeof(lights[i]), warn ); 120 | SPrintf( warn, "%sSize Mismatch: Actual != Internal", thisName ); 121 | //Assert( lights[i].light_size == sizeof(lights[i]), warn ); 122 | SPrintf( warn, "%sSize Mismatch: Header != Internal", thisName ); 123 | //Assert( header.light_num_byte[i] == lights[i].light_size, warn ); 124 | SPrintf( warn, "%sIndex Mismatch: Header != Internal", thisName ); 125 | //Assert( i == lights[i].this_light_index, warn ); 126 | } 127 | if( header.nintendo_extension_block_size != NINTENDO_EXT_BLOCK_NONE ){ 128 | NIFF_XEB_Generic nintendoExtensionBlock(header.nintendo_extension_block_size); 129 | } 130 | if( header.user_extension_block_size != USER_EXT_BLOCK_NONE ){ 131 | NIFF_XEB_Generic userExtensionBlock(header.user_extension_block_size); 132 | } 133 | } NIFF_LightList; -------------------------------------------------------------------------------- /filetypes/NIFF/NIFF.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | #include "filetypes/NIFF/NIFFFlags.bt" 3 | #include "filetypes/NIFF/NIFFTags.bt" 4 | 5 | #include "filetypes/NIFF/Common.bt" 6 | 7 | #include "filetypes/NIFF/Scene.bt" 8 | #include "filetypes/NIFF/Env.bt" 9 | #include "filetypes/NIFF/Cam.bt" 10 | #include "filetypes/NIFF/Light.bt" 11 | //... 12 | #include "filetypes/NIFF/Tex.bt" 13 | 14 | BigEndian(); 15 | BitfieldDisablePadding(); 16 | 17 | local int NIFF2 = 0; 18 | typedef struct { 19 | ubyte majorVersion; 20 | if( majorVersion >= 2 ){ 21 | NIFF2 = 1; 22 | } 23 | ubyte minorVersion; 24 | } NIFF_Version ; 25 | 26 | string ReadNIFF_Version( NIFF_Version &v ){ 27 | local string s; 28 | SPrintf( s, "%u.%X", v.majorVersion, v.minorVersion); 29 | return s; 30 | } 31 | 32 | typedef struct { 33 | ubyte creatorCode; 34 | ubyte toolCode; 35 | NIFF_Version version; 36 | } NIFF_ToolVersion; 37 | 38 | typedef struct( uint64 size ){ 39 | if( NIFF2 ){ 40 | uint ci_img_list_num_byte; 41 | uint color_palette_list_num_byte; 42 | uint envelope_list_num_byte; 43 | uint cluster_list_num_byte; 44 | uint weight_list_num_byte; 45 | uint chain_root_list_num_byte; 46 | uint joint_list_num_byte; 47 | uint effector_list_num_byte; 48 | uint external_name_list_num_byte; 49 | } 50 | // since we can be variable size, 51 | // block out all unknown data 52 | local uint64 size_of_the_unknown = size - (FTell() - startof(this)); 53 | if( size_of_the_unknown > 0 ){ 54 | ubyte unknown[size_of_the_unknown]; 55 | } 56 | } NIFF_NEB_FileHeader; 57 | 58 | typedef struct( uint64 size ){ 59 | // since we can be variable size, 60 | // block out all unknown data 61 | local uint64 size_of_the_unknown = size - (FTell() - startof(this)); 62 | if( size_of_the_unknown > 0 ){ 63 | ubyte unknown[size_of_the_unknown]; 64 | } 65 | } NIFF_UEB_FileHeader; 66 | 67 | typedef struct { 68 | NIFF_ToolVersion version; 69 | uint file_size; 70 | uint header_tag; 71 | Assert( header_tag == TAG_HEADER, "Invalid NIFF_FileHeader: Wrong Tag" ); 72 | // despite the names, all of the following are sizes 73 | uint file_header_num_byte; 74 | uint scene_list_num_byte; 75 | uint env_list_num_byte; 76 | uint cam_list_num_byte; 77 | uint light_list_num_byte; 78 | uint obj_list_num_byte; 79 | uint shape_list_num_byte; 80 | uint vtx_list_num_byte; 81 | uint color_list_num_byte; 82 | uint vector_list_num_byte; 83 | uint st_list_num_byte; 84 | uint tri_list_num_byte; 85 | uint part_list_num_byte; 86 | uint mat_list_num_byte; 87 | uint tex_list_num_byte; 88 | uint tex_img_list_num_byte; 89 | uint anim_list_num_byte; 90 | uint coll_list_num_byte; 91 | uint switch_list_num_byte; 92 | uint name_list_num_byte; 93 | uint nintendo_extension_block_size; 94 | uint user_extension_block_size; 95 | if( nintendo_extension_block_size != NINTENDO_EXT_BLOCK_NONE ){ 96 | NIFF_NEB_FileHeader nintendoExtensionBlock(nintendo_extension_block_size); 97 | Assert( nintendo_extension_block_size == sizeof(nintendoExtensionBlock), "Invalid NIFF_NEB_FileHeader: Size Mismatch" ); 98 | } 99 | if( user_extension_block_size != USER_EXT_BLOCK_NONE ){ 100 | NIFF_UEB_FileHeader userExtensionBlock(user_extension_block_size); 101 | Assert( user_extension_block_size == sizeof(userExtensionBlock), "Invalid NIFF_UEB_FileHeader: Size Mismatch" ); 102 | } 103 | } NIFF_FileHeader; 104 | 105 | typedef struct { 106 | NIFF_FileHeader header; 107 | Assert( header.file_header_num_byte == sizeof(header), "Invalid NIFF_FileHeader: Size Mismatch" ); 108 | 109 | // TODO: Go back and give this the same checks that EnvList has. 110 | // TODO: Inline relevant ENUMs 111 | NIFF_SceneList scenes; 112 | Assert( scenes.header.scene_size == sizeof(scenes), "Invalid NIFF_SceneList: Size Mismatch" ); 113 | 114 | NIFF_EnvList env_list; 115 | Assert( env_list.header.env_list_size == sizeof(env_list), "Invalid NIFF_EnvList: Size Mismatch" ); 116 | 117 | NIFF_CamList cam_list; 118 | Assert( cam_list.header.cam_list_size == sizeof(cam_list), "Invalid NIFF_CamList: Size Mismatch" ); 119 | 120 | NIFF_LightList light_list; 121 | Assert( light_list.header.light_list_size == sizeof(light_list), "Invalid NIFF_LightList: Size Mismatch" ); 122 | 123 | NIFF_XEB_Generic obj_list(header.obj_list_num_byte); 124 | 125 | NIFF_XEB_Generic shape_list(header.shape_list_num_byte); 126 | 127 | NIFF_XEB_Generic vtx_list(header.vtx_list_num_byte); 128 | 129 | //NIFF_XEB_Generic st_list(header.st_list_num_byte); 130 | 131 | NIFF_XEB_Generic tri_list(header.tri_list_num_byte); 132 | 133 | NIFF_XEB_Generic color_list(header.color_list_num_byte); 134 | 135 | // 136 | 137 | NIFF_XEB_Generic vector_list(header.vector_list_num_byte); 138 | 139 | NIFF_XEB_Generic st_list(header.st_list_num_byte); 140 | 141 | NIFF_XEB_Generic part_list(header.part_list_num_byte); 142 | 143 | NIFF_XEB_Generic mat_list(header.mat_list_num_byte); 144 | 145 | NIFF_TexList tex_list; 146 | Assert( tex_list.header.tex_list_size == sizeof(tex_list), "Invalid NIFF_TexList: Size Mismatch" ); 147 | 148 | //NIFF_XEB_Generic st_list(header.st_list_num_byte); 149 | 150 | 151 | } NIFF; 152 | 153 | SetBackColor( cGray ); 154 | NIFF niff; -------------------------------------------------------------------------------- /filetypes/NIFF/NIFFFlags.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // NIFF v1.0 structure flags 3 | 4 | // Scene 5 | #define SCENE_CFG_VIDEO_NTSC 0x00000000 6 | #define SCENE_CFG_VIDEO_PAL 0x00000001 7 | #define SCENE_CFG_VIDEO_MPAL 0x00000002 8 | #define SCENE_CFG_GAMMA 0x00000004 9 | #define SCENE_CFG_DITHER 0x00000008 10 | #define SCENE_CFG_DIVOT 0x00000010 11 | 12 | // Cam 13 | #define CAM_TYPE_PERSP 0x00000000 14 | #define CAM_TYPE_ORTHO 0x00000001 15 | 16 | // Light 17 | #define LIGHT_TYPE_DIRECTION 0x00000000 18 | #define LIGHT_TYPE_POSITION 0x00000001 19 | 20 | // Env 21 | #define ENV_FOG_USE 0x00000001 22 | #define ENV_FOG_NONE 0x00000000 23 | #define FILL_COLOR_NONE 0xffffffff 24 | #define FILL_DEPTH_NONE 0xffffffff 25 | #define BG_COLOR_IMG_NONE 0xffffffff 26 | #define BG_DEPTH_IMG_NONE 0xffffffff -------------------------------------------------------------------------------- /filetypes/NIFF/NIFFTags.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // NIFF v1.0 structure tags 3 | 4 | #define TAG_HEADER 0x00000000 5 | 6 | #define TAG_SCENE_HEADER 0x00010000 7 | 8 | #define TAG_CAM_LIST 0x000e0000 9 | #define TAG_CAM 0x000e0100 10 | 11 | #define TAG_LIGHT_LIST 0x000f0000 12 | #define TAG_LIGHT 0x000f0100 13 | #define TAG_DIR_LIGHT_DIRECTION 0x000f0101 14 | #define TAG_DIR_LIGHT_POSITION 0x000f0102 15 | 16 | #define TAG_ENV_LIST 0x00100000 17 | #define TAG_ENV 0x00100100 18 | 19 | #define TAG_TEX_LIST 0x000b0000 20 | #define TAG_TEX 0x000b0100 21 | 22 | #define TAG_TEX_IMG_LIST 0x00120000 23 | #define TAG_TEX_IMG 0x00120100 24 | 25 | #define NINTENDO_EXT_BLOCK_NONE 0x00000000 26 | #define USER_EXT_BLOCK_NONE 0x00000000 -------------------------------------------------------------------------------- /filetypes/NIFF/Scene.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct( uint64 size ) { 3 | if( NIFF2 ){ 4 | uint scene_chain_root_link_num; 5 | uint external_obj_num; 6 | uint external_env_num; 7 | uint external_cam_num; 8 | uint external_light_num; 9 | if( scene_chain_root_link_num ){ 10 | uint scene_chain_root_link_index[scene_chain_root_link_num]; 11 | } 12 | if( external_obj_num ){ 13 | uint external_obj_file_name_index[external_obj_num]; 14 | uint external_obj_name_index[external_obj_num]; 15 | } 16 | if( external_env_num ){ 17 | uint external_env_file_name_index[external_env_num]; 18 | uint external_env_name_index[external_env_num]; 19 | } 20 | if( external_cam_num ){ 21 | uint external_cam_file_name_index[external_cam_num]; 22 | uint external_cam_name_index[external_cam_num]; 23 | } 24 | if( external_light_num ){ 25 | uint external_light_file_name_index[external_light_num]; 26 | uint external_light_name_index[external_light_num]; 27 | } 28 | } 29 | // since we can be variable size, 30 | // block out all unknown data 31 | local uint64 size_of_the_unknown = size - (FTell() - startof(this)); 32 | if( size_of_the_unknown > 0 ){ 33 | ubyte unknown[size_of_the_unknown]; 34 | } 35 | } NIFF_NEB_SceneHeader; 36 | 37 | typedef struct( uint64 size ){ 38 | // since we can be variable size, 39 | // block out all unknown data 40 | local uint64 size_of_the_unknown = size - (FTell() - startof(this)); 41 | if( size_of_the_unknown > 0 ){ 42 | ubyte unknown[size_of_the_unknown]; 43 | } 44 | } NIFF_UEB_SceneHeader; 45 | 46 | typedef struct { 47 | uint scene_header_tag; 48 | Assert( scene_header_tag == TAG_SCENE_HEADER, "Invalid NIFF_SceneHeader: Wrong Tag"); 49 | uint scene_header_size; 50 | uint scene_size; 51 | // @TODO: enum scene_cfg 52 | uint scene_cfg; 53 | uint scene_name_index; 54 | uint scene_obj_link_num; 55 | uint scene_env_link_num; 56 | uint scene_cam_link_num; 57 | uint scene_light_link_num; 58 | uint nintendo_extension_block_size; 59 | uint user_extension_block_size; 60 | } NIFF_SceneHeader; 61 | 62 | typedef struct { 63 | NIFF_SceneHeader header; 64 | Assert( header.scene_header_size == sizeof(header), "Invalid NIFF SceneHeader: Size Mismatch" ); 65 | uint scene_obj_link_index[header.scene_obj_link_num]; 66 | uint scene_env_link_index[header.scene_env_link_num]; 67 | uint scene_cam_link_index[header.scene_cam_link_num]; 68 | uint scene_light_link_index[header.scene_light_link_num]; 69 | if( header.nintendo_extension_block_size != NINTENDO_EXT_BLOCK_NONE ){ 70 | NIFF_NEB_SceneHeader nintendoExtensionBlock(header.nintendo_extension_block_size); 71 | } 72 | if( header.user_extension_block_size != USER_EXT_BLOCK_NONE ){ 73 | NIFF_UEB_SceneHeader userExtensionBlock(header.user_extension_block_size); 74 | } 75 | } NIFF_SceneList; -------------------------------------------------------------------------------- /filetypes/NIFF/Tex.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | uint tex_img_width; 4 | uint tex_img_height; 5 | uint tex_tile_width; 6 | uint tex_tile_height; 7 | uint tex_offset_x; 8 | uint tex_offset_y; 9 | uint tex_img_index; 10 | } NIFF_TexData; 11 | 12 | typedef struct { 13 | uint tex_tag; 14 | Assert( tex_tag == TAG_TEX, "Invalid NIFF_Tex: Wrong Tag" ); 15 | uint this_tex_index; 16 | uint tex_header_size; 17 | uint tex_size; 18 | // @TODO: Validate against NameList 19 | uint tex_name_index; 20 | // @TODO: enum 21 | uint tex_type; 22 | // @TODO: enum 23 | uint tex_wrap_s; 24 | // @TODO: enum 25 | uint tex_wrap_t; 26 | // @TODO: enum 27 | uint tex_anim; 28 | uint tex_data_area_size; 29 | uint tex_anim_frame_late; 30 | uint nintendo_extension_block_size; 31 | uint user_extension_block_size; 32 | NIFF_XEB_Generic texData(tex_data_area_size); 33 | if( nintendo_extension_block_size != NINTENDO_EXT_BLOCK_NONE ){ 34 | NIFF_XEB_Generic nintendoExtensionBlock(nintendo_extension_block_size); 35 | } 36 | if( user_extension_block_size != USER_EXT_BLOCK_NONE ){ 37 | NIFF_XEB_Generic userExtensionBlock(user_extension_block_size); 38 | } 39 | } NIFF_Tex; 40 | 41 | typedef struct { 42 | uint tex_list_tag; 43 | Assert( tex_list_tag == TAG_TEX_LIST, "Invalid NIFF_TexListHeader: Wrong Tag" ); 44 | uint tex_list_header_size; 45 | uint tex_list_size; 46 | uint tex_num; 47 | uint nintendo_extension_block_size; 48 | uint user_extension_block_size; 49 | uint tex_num_byte[tex_num]; 50 | } NIFF_TexListHeader; 51 | 52 | typedef struct { 53 | NIFF_TexListHeader header; 54 | Assert( header.tex_list_header_size == sizeof(header), "Invalid NIFF_TexListHeader: Size Mismatch" ); 55 | NIFF_Tex texs[header.tex_num]; 56 | local uint64 i; 57 | local string warn; 58 | local string thisName; 59 | for( i = 0; i < header.tex_num; i++ ){ 60 | SPrintf( thisName, "Invalid NIFF_Tex[%d]: ", i ); 61 | 62 | SPrintf( warn, "%sSize Mismatch: Actual != Header", thisName ); 63 | Assert( header.tex_num_byte[i] == sizeof(texs[i]), warn ); 64 | SPrintf( warn, "%sSize Mismatch: Actual != Internal", thisName ); 65 | Assert( texs[i].tex_size == sizeof(texs[i]), warn ); 66 | SPrintf( warn, "%sSize Mismatch: Header != Internal", thisName ); 67 | Assert( header.tex_num_byte[i] == texs[i].tex_size, warn ); 68 | SPrintf( warn, "%sIndex Mismatch: Header != Internal", thisName ); 69 | Assert( i == texs[i].this_tex_index, warn ); 70 | } 71 | if( header.nintendo_extension_block_size != NINTENDO_EXT_BLOCK_NONE ){ 72 | NIFF_XEB_Generic nintendoExtensionBlock(header.nintendo_extension_block_size); 73 | } 74 | if( header.user_extension_block_size != USER_EXT_BLOCK_NONE ){ 75 | NIFF_XEB_Generic userExtensionBlock(header.user_extension_block_size); 76 | } 77 | } NIFF_TexList; -------------------------------------------------------------------------------- /filetypes/Overlay/Actor.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | ushort actorNum; 4 | ubyte actorType; 5 | // if FF then does not despawn on room switch 6 | ubyte roomNumber; 7 | ubyte unknown[4]; 8 | ushort objectNumber; 9 | ubyte zeroes[2]; 10 | uint instanceSize; 11 | } ZActorInitVars; 12 | 13 | typedef struct { 14 | uint vromStart; 15 | uint vromEnd; 16 | uint vramStart; 17 | uint vramEnd; 18 | 19 | uint ramAddrOfActor; 20 | uint vramAddrOfActorInstanceStart; 21 | uint vromActorFileName; 22 | ubyte unknown[2]; 23 | ubyte numActorInstancesOfTypeInRAM; 24 | ubyte unknown2[1]; 25 | 26 | if( vromStart && vromEnd ){ 27 | SAVE; 28 | FSeek(vromStart); 29 | DummyOverlay myOverlay(vromEnd-vromStart); 30 | REST; 31 | 32 | SAVE; 33 | FSeek(vromStart+(vramAddrOfActorInstanceStart-vramStart)); 34 | ZActorInitVars init; 35 | REST; 36 | } 37 | } ZActorTableEntry; 38 | 39 | void DumpZActorTableEntry( ZActorTableEntry &d ){ 40 | local uint64 pair = 0; 41 | local uint64 pos = 0; 42 | local uint64 value = 0; 43 | local uint64 loc = 0; 44 | local uint64 tgt = 0; 45 | local uint64 thingread = 0; 46 | local uint64 rel = d.vramStart; 47 | Printf("num\tsection(S)\ttype(T)\t\top. value\t\taddress\t\tphys addr\t\tread at addr.\tchanged value\tVrel read\t\tVrel read+value\tphys read\t\tphys read+value\n"); 48 | while( exists( d.myOverlay.header.relocationPointers[pos] ) ){ 49 | switch( d.myOverlay.header.relocationPointers[pos].section ){ 50 | case RELO_SECTION_TEXT: 51 | loc = startof(d.myOverlay.textBlockData); 52 | break; 53 | case RELO_SECTION_DATA: 54 | loc = startof(d.myOverlay.dataBlockData); 55 | break; 56 | case RELO_SECTION_RODATA: 57 | loc = startof(d.myOverlay.rodataBlockData); 58 | break; 59 | case RELO_SECTION_BSS: 60 | loc = startof(d.myOverlay.bssBlockData); 61 | break; 62 | } 63 | loc -= startof(d.myOverlay); 64 | tgt = loc; 65 | 66 | switch( d.myOverlay.header.relocationPointers[pos].type ){ 67 | case RELO_TYPE_POINTER: 68 | value = d.myOverlay.header.relocationPointers[pos].offset; 69 | tgt += value; 70 | break; 71 | case RELO_TYPE_JUMP: 72 | value = d.myOverlay.header.relocationPointers[pos].offset / 4; 73 | tgt += value; 74 | break; 75 | case RELO_TYPE_MIPS_LUI: 76 | pair = 1; 77 | value = d.myOverlay.header.relocationPointers[pos].offset << 16; 78 | break; 79 | case RELO_TYPE_MIPS_ORI: 80 | value += d.myOverlay.header.relocationPointers[pos].offset; 81 | pair = 0; 82 | break; 83 | } 84 | 85 | if( !pair ){ 86 | if( startof(d.myOverlay)+tgt < FileSize() ){ 87 | thingread = ReadUInt(startof(d.myOverlay)+tgt); 88 | } 89 | 90 | Printf("%d\t%s\t%s\t0x%08LX\t0x%08LX\t0x%08LX\t0x%08LX\t0x%08LX\t0x%08LX\t0x%08LX\t0x%08LX\t0x%08LX\n", 91 | pos, 92 | EnumToString( d.myOverlay.header.relocationPointers[pos].section ), 93 | EnumToString( d.myOverlay.header.relocationPointers[pos].type ), 94 | value, 95 | tgt, 96 | startof(d.myOverlay)+tgt, 97 | thingread, 98 | thingread+value, 99 | thingread-rel, // if we read an address, peep it 100 | thingread+value-rel, // new value, potentially an addr 101 | startof(d.myOverlay)+(thingread-rel), 102 | startof(d.myOverlay)+(thingread+value-rel) 103 | ); 104 | value = 0; 105 | tgt = 0; 106 | } 107 | 108 | thingread = 0; 109 | loc = 0; 110 | pos++; 111 | } 112 | } -------------------------------------------------------------------------------- /filetypes/Overlay/Dummy.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct(uint64 size){ 3 | SIBE; 4 | 5 | SIT; 6 | OVERLAYHEAD; 7 | 8 | SIT; 9 | ubyte textBlockData[header.textBlock]; 10 | 11 | SIT; 12 | ubyte dataBlockData[header.dataBlock]; 13 | 14 | SIT; 15 | ubyte rodataBlockData[header.rodataBlock]; 16 | 17 | SIEND; 18 | } DummyOverlay; -------------------------------------------------------------------------------- /filetypes/Overlay/Files/En_GirlA.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // to find this data in MM, see: 3 | // http://wiki.cloudmodding.com/mm/Notes:Shop_Item_Modifying 4 | 5 | typedef struct { 6 | SIBE; 7 | 8 | SIT; 9 | ushort objectNumber; 10 | 11 | SIT; 12 | ushort shaderNumber; 13 | /* 14 | (2:00:47 PM) mzxrules: the "shader" variable should be the same as the "get item model identifier" shown here: 15 | http://wiki.cloudmodding.com/oot/Get_Items_(ovl_player_actor)#Format 16 | (2:13:05 PM) mzxrules: the thing here is that there is no "shader" 17 | (2:13:50 PM) mzxrules: what's going on is that there's a special table that stores a list of offsets that point into different obj files for the get item object files 18 | (2:14:15 PM) mzxrules: the shader or get item model id is an index into that table 19 | (2:15:25 PM) mzxrules: lemmy try and find a frame in which this will make sense 20 | (2:16:14 PM) mzxrules: the link instance allocates a special block of memory that is used to store "title cards" 21 | (2:17:16 PM) mzxrules: and get item object files (call 'm gi objects because of how they're named) 22 | (2:18:30 PM) mzxrules: when link is to hold an item over his head, the game uses the get item table to fetch the overlay, and set the get item model id 23 | (2:18:36 PM) mzxrules: object, not overlay bleh 24 | (2:19:48 PM) mzxrules: the model id exists because 1) different objects are allocated into the same space, so it helps differentiate, 2) one object file can contain multiple models, like the rupee for example 25 | (2:20:55 PM) mzxrules: so if you're loading the rupee obj, the model id determines what rupee it will look like 26 | (2:21:07 PM) mzxrules: understand? 27 | */ 28 | SIT; 29 | Ram ramPointer; 30 | // does not equal the price of buying something 31 | 32 | SIT; 33 | ushort itemPrice; 34 | SIT; 35 | ushort quantity; 36 | SIT; 37 | ushort descriptionMessageID; 38 | SIT; 39 | ushort purchasedMessageID; 40 | SIT; 41 | ubyte zeroes[2]; 42 | SIT; 43 | ushort getItemIndex; 44 | SIT; 45 | Ram ramPointers2[3]; 46 | SIEND; 47 | } ZShopData; 48 | 49 | typedef struct(uint64 size){ 50 | SIBE; 51 | 52 | SIT; 53 | OVERLAYHEAD; 54 | 55 | SIT; 56 | ubyte textBlockData[header.textBlock]; 57 | 58 | SIT; 59 | //ubyte dataBlockData[header.dataBlock]; 60 | //FSeek(startof(textBlockData)+sizeof(textBlockData)); 61 | 62 | SIT; 63 | uint unknown[4]; 64 | 65 | SIT; 66 | local uint numRams = 54; 67 | local uint numShopEntries = 50; 68 | if( GAME == "MM" ){ 69 | numRams = 47; 70 | numShopEntries = 43; 71 | } 72 | Ram ramMaybe[numRams]; 73 | 74 | if( GAME != "MM" ){ 75 | SIT; 76 | ushort whats[8]; 77 | 78 | SIT; 79 | ushort moreWhat[5]; 80 | 81 | SIT; 82 | ubyte zeroes[2]; 83 | } 84 | 85 | SIT; 86 | ZShopData shopEntries[numShopEntries]; 87 | //ZShopData shopEntries[header.dataBlock/sizeof(ZShopData)]; 88 | 89 | if( GAME != "MM" ){ 90 | SIT; 91 | ushort evenMoreWhat[8]; 92 | 93 | SIT; 94 | ubyte zeroes2[12]; 95 | } else { 96 | SIT; 97 | ubyte zeroes2[4]; 98 | } 99 | 100 | SIT; 101 | ubyte rodataBlockData[header.rodataBlock]; 102 | 103 | SIEND; 104 | } En_GirlA; -------------------------------------------------------------------------------- /filetypes/Overlay/Files/map_marker_data.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | #define SIZE_MAPDATA 114 3 | #define MAX_ICONS 12 4 | typedef struct{ 5 | //if the flag is not set, then we draw 6 | ubyte chestFlag; 7 | // cordinates for minimap, top-left 8 | ubyte x; 9 | ubyte y; 10 | /* 11 | The minimap textures in map_i_static are 96x85 in size. 12 | The set coordinate will position the icon from the top-left corner, 13 | rather than the center. 14 | 15 | Since the chest icon is 7x7 in size, 16 | to center a chest icon at point 48,50, 17 | subtract 4 from both x and y positions (44,46). 18 | */ 19 | }MapMarkIcon; 20 | 21 | enum MAP_ICON { 22 | MAP_ICON_TREASURE = 0x00, 23 | MAP_ICON_BOSS = 0x01, 24 | MAP_ICON_NOTHING = 0xFF 25 | }; 26 | 27 | 28 | typedef struct{ 29 | MAP_ICON mapIcon; 30 | if( mapIcon == MAP_ICON_NOTHING ){ 31 | ubyte zeroes[SIZE_MAPDATA - 1]; 32 | AssertUBytesNull(zeroes, "map icon set to none, but entire room wasn't empty"); 33 | } else { 34 | ubyte numIcons; 35 | Assert( numIcons <= MAX_ICONS, "more icons than we can handle" ); 36 | MapMarkIcon icons[numIcons]; 37 | local uint numZeroes = sizeof(MapMarkIcon) * (MAX_ICONS - numIcons); 38 | ubyte zeroes[numZeroes]; 39 | AssertUBytesNull(zeroes, "max icon number is wrong"); 40 | } 41 | }MapMarkData; 42 | 43 | typedef struct{ 44 | while( 1 ){ 45 | if( ReadUByte() == MAP_ICON_NOTHING ){ 46 | break; 47 | } 48 | MapMarkData mapMark; 49 | } 50 | ubyte FF; 51 | ubyte zeroes[SIZE_MAPDATA - (FTell()-startof(this))]; 52 | AssertUBytesNull(zeroes, "room too full, probably [no cases like this]"); 53 | }MapMarkScanner; 54 | 55 | typedef struct(uint64 size){ 56 | OVERLAYHEAD; 57 | 58 | SAVE; 59 | FSeek(startof(this)+header.textBlock+header.dataBlock-(4*header.relocationBlock)); 60 | uint dungeonMiniMapStarts[header.relocationBlock]; 61 | REST; 62 | 63 | 64 | local uint64 ustart; 65 | local uint parts, count, part_size; 66 | while( exists(dungeonMiniMapStarts[parts]) ){ 67 | if( exists(dungeonMiniMapStarts[parts+1]) ){ 68 | part_size = (dungeonMiniMapStarts[parts+1]-dungeonMiniMapStarts[parts]); 69 | ustart = startof(this)+(dungeonMiniMapStarts[parts]-dungeonMiniMapStarts[0]); 70 | } else { 71 | // we don't know how big this is gonna be 72 | // but we can find out 73 | ustart = ustart + sizeof(dungeonMiniMaps[parts-1]) + (part_size%SIZE_MAPDATA); 74 | part_size = startof(header) - ustart; 75 | } 76 | count = (part_size-(part_size%SIZE_MAPDATA))/SIZE_MAPDATA; 77 | 78 | FSeek(ustart); 79 | SAVE; 80 | struct(uint zcount) { 81 | MapMarkScanner miniMaps[zcount]; 82 | } dungeonMiniMaps(count); 83 | REST; 84 | 85 | parts++; 86 | } 87 | } OvlMapMarkData; -------------------------------------------------------------------------------- /filetypes/Overlay/Object.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | uint vromStart; 4 | uint vromEnd; 5 | 6 | if( vromStart && vromEnd ){ 7 | SAVE; 8 | FSeek(vromStart); 9 | SIT; 10 | ubyte data[vromEnd-vromStart]; 11 | REST; 12 | } 13 | } ZObjectTableEntry; 14 | 15 | typedef struct { 16 | SIBE; 17 | 18 | SIT; 19 | short childLinkObjectNumber; 20 | 21 | SIT; 22 | short adultLinkObjectNumber; 23 | 24 | SIT; 25 | uint numberOfObjects; 26 | 27 | SIT; 28 | ZObjectTableEntry objects[numberOfObjects]; 29 | 30 | SIEND; 31 | } ZObjectTable; 32 | -------------------------------------------------------------------------------- /filetypes/Overlay/OverlayHeader.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Mips/load32.html 3 | // http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html 4 | // http://vhouten.home.xs4all.nl/mipsel/r3000-isa.html 5 | // https://www.cs.umd.edu/class/fall2003/cmsc311/Lectures/lecture15/C_code.pdf 6 | 7 | #define OVERLAYHEAD SAVE; \ 8 | FSeek(startof(this)+size-ReadUInt(startof(this)+size-4)); \ 9 | OverlayHeader header(startof(this)+size-4); \ 10 | REST; 11 | 12 | typedef struct{ 13 | enum RELO_SECTION { 14 | RELO_SECTION_TEXT = 0x1, 15 | RELO_SECTION_DATA = 0x2, 16 | RELO_SECTION_RODATA = 0x3, 17 | RELO_SECTION_BSS = 0x4, 18 | } section : 2; 19 | ubyte unknown : 2; 20 | enum RELO_TYPE { 21 | RELO_TYPE_POINTER = 0x2, 22 | RELO_TYPE_JUMP = 0x4, //or a jump target? 23 | RELO_TYPE_MIPS_LUI = 0x5, 24 | RELO_TYPE_MIPS_ORI = 0x6, 25 | } type : 4; 26 | uint offset : 24; 27 | } ZRelocationPointer; 28 | 29 | typedef struct(uint64 startPos){ 30 | local string thisName = "OverlayHeader"; 31 | SIBE; 32 | 33 | // the following are sizes 34 | 35 | SIT; 36 | // mips r4000 machine code 37 | uint textBlock; 38 | 39 | SIT; 40 | // Read/Write data (variables) 41 | // This can also include inline model data, 42 | // as seen in element arrows and Ganon to name a few. 43 | uint dataBlock; 44 | 45 | SIT; 46 | // Read-Only Data 47 | // Usually contains text used with the n64 debugging print function 48 | // (0x80002130) and thus contains empty format strings. 49 | uint rodataBlock; 50 | 51 | 52 | SIT; 53 | // Zero-Initialized Data 54 | // BSS data is rarely used in actor overlays. 55 | // Space is allocated immediately after the overlay file. 56 | uint bssBlock; 57 | 58 | SIT; 59 | // Count of one-word long entries of relocation data. 60 | // Relocation block immediately follows this table. 61 | uint relocationBlock; 62 | 63 | SIT; 64 | // Remaps virtual ram to ram 65 | ZRelocationPointer relocationPointers[relocationBlock]; 66 | 67 | SIT; 68 | FSeek(startPos); 69 | uint overlayHeaderPointer; 70 | SIEND; 71 | } OverlayHeader; -------------------------------------------------------------------------------- /filetypes/Save/SaveFile.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZSaveDataInternal"; 4 | KNOWN; 5 | uint entrance_index ; // Stores the Entrance Link starts/respawns at 6 | ZSaveWearingMask wearing_mask; 7 | ubyte opening_flag; // Has completed intro 8 | ubyte text_skip_timer; // Prevents skipping text for a period 9 | 10 | UNKNOWN; 11 | ubyte unknown0; // Something to do with picking up items? 12 | 13 | KNOWN; 14 | ZSaveCutsceneOffset cutscene_offset; 15 | uint16 time_of_day ; 16 | ZSaveOwlID owl_id; 17 | ZSaveDayNight day_night; 18 | ZSaveTimeSpeed time_speed; 19 | uint day; 20 | uint days_elapsed; 21 | ZSaveTransformation transformation; 22 | 23 | UNKNOWN; 24 | ubyte unknown1; // spring_flag? 25 | 26 | KNOWN; 27 | ubyte have_tatl; // boolean 28 | ubyte owl_save; // boolean 29 | char file_validation[6]; 30 | uint16 song_of_time_count; 31 | char file_name[8]; 32 | uint16 heart_containers ; // 0x10 per heart 33 | uint16 health ; // 0x10 per heart 34 | ZSaveMagicMeterSize magic_meter_size; 35 | ubyte magic ; // 0x30 for normal, 0x60 for double 36 | uint16 rupees; 37 | uint navi_timer; 38 | ubyte has_normal_magic; // boolean 39 | ubyte has_double_magic; // boolean 40 | uint16 double_defense; // boolean? actually seems unused in MM 41 | 42 | UNKNOWN; 43 | uint16 unknown2; 44 | 45 | KNOWN; 46 | ZSaveOwlsHit owls_hit; 47 | 48 | UNKNOWN; 49 | uint unknown3 ; 50 | 51 | KNOWN; 52 | ZSaveItemsEquipped items_human; // also used for fierce deity 53 | ZSaveItemsEquipped items_goron; 54 | ZSaveItemsEquipped items_zora; 55 | ZSaveItemsEquipped items_deku; 56 | UNUSED; 57 | ubyte unused; // this is where the b button slot would be 58 | KNOWN; 59 | ZSaveInventorySlot c_left_button_slot; 60 | ZSaveInventorySlot c_down_button_slot; 61 | ZSaveInventorySlot c_right_button_slot; 62 | 63 | UNKNOWN; 64 | uint unknown4; 65 | uint unknown5; 66 | uint unknown6; 67 | 68 | KNOWN; 69 | ZSaveBoots boots : 4; 70 | ZSaveTunic tunic : 4; 71 | ZSaveShield shield : 4; 72 | ZSaveSword sword : 4; 73 | 74 | UNKNOWN; 75 | uint16 unknown7; 76 | 77 | KNOWN; 78 | ZSaveInventorySlotItemIDs inventory_slot_item_ids; 79 | ZSaveInventorySlotItemAmount inventory_slot_item_amount; 80 | 81 | ZSaveUpgrades upgrade_data; 82 | 83 | ZSaveQuestStatus quest_status_data; 84 | 85 | ZSaveDungeonItems dungeon_items[10]; // only 4 are used, but 86 | // debug save has boss/compass/map in all 10 87 | 88 | // all used but the last, i think 89 | byte small_key_amount[9] ; 90 | 91 | // normally 0 or 20 but anything inbetween works fine 92 | ubyte doubled_hearts; 93 | 94 | // maybe unused fairies too 95 | ubyte fairies[10]; 96 | 97 | // says "LINK[eol]LINK[eol]LINK[eol]" in the game's encoding 98 | // on my completed file it actually matches my filename! weird. 99 | char unknown_name0[8]; 100 | char unknown_name1[8]; 101 | char unknown_name2[8]; 102 | 103 | UNKNOWN; 104 | ubyte unknown9[0x37A]; 105 | 106 | KNOWN; 107 | ZSaveSceneFlags scene_flags[0x78]; 108 | 109 | UNKNOWN; 110 | ubyte unknown10[0xAA]; 111 | 112 | KNOWN; // temporary names 113 | ubyte pictograph_special; 114 | ubyte pictograph_quality; 115 | ubyte pictograph_unknown; 116 | 117 | UNKNOWN; 118 | ubyte unknown11[0x27]; 119 | 120 | KNOWN; 121 | // only the first 4 words wind up being used 122 | // but the code supports up to 7 words 123 | BitEight minimaps[7*4] ; 124 | 125 | uint16 skulltulas_woodfall; 126 | uint16 skulltulas_great_bay; 127 | 128 | UNKNOWN; 129 | ubyte unknown12[0x1A]; 130 | 131 | KNOWN; 132 | uint16 banked_rupees; 133 | 134 | UNKNOWN; 135 | ubyte unknown13[0x18]; 136 | 137 | KNOWN; 138 | BitEight week_event_reg[100]; 139 | 140 | BitEight area_arrival[4] ; 141 | BitEight cloud_clear[4] ; 142 | 143 | uint16 scarecrows_song_acquired; 144 | ZSongNote scarecrows_song[0x10]; 145 | 146 | KNOWN; 147 | ubyte bombers_caught; 148 | ubyte bombers_order[5]; // unrelated to bombers code 149 | ZSaveLotteryCodes lottery_codes[3]; 150 | ZSaveSpiderHouseMaskOrder spider_house_mask_order[6]; 151 | ubyte bombers_code[5]; 152 | 153 | uint16 epona_scene; 154 | int16 epona_x; 155 | int16 epona_y; 156 | int16 epona_z; 157 | int16 epona_angle; 158 | uint16 checksum ; 159 | 160 | } ZSaveDataInternal; 161 | 162 | typedef struct { 163 | local string thisName = "ZSaveData"; 164 | KNOWN; 165 | ZSaveDataInternal save; 166 | // nothing past this point is loaded by the game 167 | UNUSED; 168 | uint unused_end[0x3FD]; 169 | } ZSaveData; 170 | 171 | typedef struct { 172 | local string thisName = "ZSaveDataOwl"; 173 | KNOWN; 174 | ZSaveDataInternal save; 175 | 176 | KNOWN; 177 | BitEight event_inf[8]; 178 | 179 | KNOWN; 180 | ubyte rock_sirloin; // boolean 181 | ubyte b_button_enabled; // boolean 182 | uint16 bubble_timer; 183 | uint16 rupee_accumulator; 184 | 185 | ubyte hot_spring_water_statuses[6]; 186 | ubyte hot_spring_water_timers[6*32]; // TODO: reverse engineer 187 | 188 | ubyte pictograph_picture[100*112]; // 5 bits per pixel 0x000090E0 189 | 190 | UNUSED; 191 | uint unused_end[0xD8]; 192 | } ZSaveDataOwl; 193 | 194 | typedef struct { 195 | local string thisName = "ZSave"; 196 | 197 | KNOWN; 198 | ZSaveData save; 199 | ZSaveData backup; 200 | } ZSave; 201 | 202 | typedef struct { 203 | local string thisName = "ZSaveOwl"; 204 | local int isOwl = 1; 205 | 206 | KNOWN; 207 | ZSaveDataOwl save; 208 | ZSaveDataOwl backup; 209 | } ZSaveOwl; -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_Actor.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | SIBE; 4 | SIT; 5 | ushort actorNo; 6 | ZVector pos; 7 | // a value of 1 in the rotation is 2 degrees 8 | SIT; 9 | ubyte rotX; 10 | SIT; 11 | ubyte spawnTime1; 12 | SIT; 13 | ubyte rotY; 14 | SIT; 15 | ubyte unknown; // Unknown, related to the 0x1B command? 16 | //AssertNumberEquals(unknown, 0, "ZHC_Actor->unknown"); 17 | SIT; 18 | ubyte rotZ; 19 | SIT; 20 | ubyte spawnTime2; 21 | //spawnTime1, spawnTime2 = Spawn time flags. 22 | /* 23 | Sets the times that an should spawn, but does not guarantee an actor will spawn. 24 | 25 | The entire set of spawn time flags is stored in an unsigned short variable (probably). 26 | 27 | spawnTime1 & 0x0007 is stored into the "spawn time" var, then left shifted by 7. Bit mask is & 0380 28 | spawnTime2 & 0x007F, then added to the "spawn time" var, giving us a complete mask of & 03FF possible values. 29 | 30 | & 03FF is broken down into 5 groups (for days 0-4) of 2 bits (for day/night). 31 | 32 | To combine everything, if e = 0x07, and f = 0x5A... 33 | 0x07 << 7 = 0x0380 34 | 0x5A & 0x7F = 0x5A 35 | 0x380 + 0x5A = 0x03DA 36 | 37 | 03DA -> 11 1101 1010 38 | 39 | Thus this actor will always spawn on days 0 and 1, the night of day 2, the morning of day 3, and the morning of day 4. 40 | */ 41 | SIT; 42 | ushort initVar; 43 | SIEND; 44 | } ZHC_Actor; 45 | 46 | typedef struct { 47 | local string thisName = "ZHC_ActorList"; 48 | SIBE; 49 | 50 | SIT; 51 | ubyte command; 52 | AssertNumberEquals(command, 0x01, thisName); 53 | 54 | SIT; 55 | ubyte numElms; 56 | AssertUIntGTZero(numElms, thisName); 57 | 58 | SIT; 59 | ubyte zeroes[2]; 60 | AssertUBytesNull(zeroes, thisName); 61 | 62 | SIT; 63 | ZBankPointer listOffset; 64 | 65 | if( listOffset.zb.bankNo == bankType ){ 66 | SAVE; 67 | FSeek(headerStart + listOffset.offset); 68 | ZHC_Actor actors[numElms]; 69 | REST; 70 | } else { 71 | Assert( 0, "External Bank" ); 72 | } 73 | SIEND; 74 | } ZHC_ActorList; -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_AltCamera.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | //(11:20:18 PM) Playtendo: 0x02 command uses this format http://wiki.cloudmodding.com/oot/Collision_Format#Camera_Data 3 | //(11:20:22 PM) Playtendo: first unknown is the camera type 4 | typedef struct { 5 | local string thisName = "ZHC_AltCameraData"; 6 | //https://docs.google.com/spreadsheets/d/1DEFqUYJNpGYVgSAdQ3LVoKZSn6nr-n4-9kUP8vCmXl4/edit#gid=505542003 7 | //https://docs.google.com/spreadsheets/d/1REOAcw6ettmqhBP-kfIJGyVyDTUkYSUwfb0UX8HbR9k/edit#gid=0 8 | SIBE; 9 | SIT; 10 | short unk1[5]; 11 | /* 12 | ubyte unk1[2]; 13 | 14 | SIT; 15 | ubyte camera_type; 16 | //00 = persp 17 | //01 = orth 18 | 19 | SIT; 20 | ubyte unk2[9]; 21 | */ 22 | 23 | SIT; 24 | short wat; 25 | AssertNumberEquals(wat, 0, "Diseases"); 26 | 27 | SIT; 28 | short unkX; 29 | SIT; 30 | short unkY; 31 | SIT; 32 | short unkZ; 33 | SIEND; 34 | } ZHC_AltCameraData; 35 | 36 | typedef struct { 37 | ZVector position; 38 | ZVector rotation; 39 | short w; 40 | ubyte Fs[4]; 41 | } ZHC_SkyboxCamera; 42 | 43 | typedef struct { 44 | local string thisName = "ZHC_AltCamera"; 45 | SIBE; 46 | SIT; 47 | ushort unknown1; 48 | SIT; 49 | ushort unknown2; 50 | SIT; 51 | ZBankPointer point; 52 | if( point.zb.bankNo == bankType && point.offset != 0 ){ 53 | SAVE; 54 | FSeek(headerStart + point.offset); 55 | ZHC_AltCameraData altCameraData; 56 | REST; 57 | } else if( point.zb.bankNo == 0 && point.offset == 0 ){ 58 | // nothing 59 | } else { 60 | Assert( 0, "External Bank" ); 61 | } 62 | SIEND; 63 | } ZHC_AltCamera; 64 | 65 | 66 | //(11:20:18 PM) Playtendo: 0x02 command uses this format http://wiki.cloudmodding.com/oot/Collision_Format#Camera_Data 67 | //(11:20:22 PM) Playtendo: first unknown is the camera type 68 | typedef struct { 69 | local string thisName = "ZHC_AltCameraList"; 70 | SIBE; 71 | SIT; 72 | ubyte command; 73 | AssertNumberEquals(command, 0x02, thisName); 74 | 75 | SIT; 76 | ubyte numElms; 77 | AssertUIntGTZero(numElms, thisName); 78 | SIT; 79 | ubyte zeroes[2]; 80 | AssertUBytesNull(zeroes, thisName); 81 | 82 | ZBankPointer listOffset; 83 | if( listOffset.zb.bankNo == bankType ){ 84 | SAVE; 85 | FSeek(headerStart + listOffset.offset); 86 | //ZHC_AltCamera altCameras[numElms]; 87 | REST; 88 | } else { 89 | Assert( 0, "External Bank" ); 90 | } 91 | SIEND; 92 | } ZHC_AltCameraList; -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_AltHeader.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | struct ZSceneHeader; 3 | 4 | typedef struct { 5 | local string thisName = "ZHC_AltHeader"; 6 | SIBE; 7 | SIT; 8 | local uint64 numAltHeaders = 3; 9 | local uint64 i = 0; 10 | ZBankPointer altHeaderOffsets[numAltHeaders]; 11 | for( i = 0; i < numAltHeaders; i++){ 12 | if( altHeaderOffsets[i].zb.bankNo == bankType ){ 13 | FSeek(headerStart + altHeaderOffsets[i].offset); 14 | ZSceneHeader myster( bankType ); 15 | } else { 16 | Warning("External Bank"); 17 | } 18 | }; 19 | SIEND; 20 | } ZHC_AltHeader; 21 | 22 | typedef struct { 23 | local string thisName = "ZHC_AltHeaderList"; 24 | SIBE; 25 | SIT; 26 | ubyte command; 27 | AssertNumberEquals(command, 0x18, thisName); 28 | 29 | SIT; 30 | ubyte zeroes[3]; 31 | AssertUBytesNull(zeroes, thisName); 32 | 33 | //SIT; 34 | //ubyte numElms; 35 | //AssertUIntGTZero(numElms, thisName); 36 | 37 | ZBankPointer listOffset; 38 | if( listOffset.zb.bankNo == bankType ){ 39 | SAVE; 40 | FSeek(startof(parentof(this)) + listOffset.offset); 41 | ZHC_AltHeader altHeaders[1];; 42 | REST; 43 | } else { 44 | Assert( 0, "External Bank" ); 45 | } 46 | SIEND; 47 | } ZHC_AltHeaderList; -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_Camera.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_Camera"; 4 | SIBE; 5 | SIT; 6 | ubyte command; 7 | //AssertNumberEquals(command, 0x19, thisName); 8 | SIT; 9 | ubyte cameraMovement; //TODO: Document values. 10 | SIT; 11 | ubyte zeroes[5]; 12 | AssertUBytesNull(zeroes, thisName); 13 | SIT; 14 | ubyte worldMapHighlightRegion; //TODO: Write resolver. http://wiki.cloudmodding.com/mm/Scenes_and_Rooms#Camera_Settings 15 | SIEND; 16 | } ZHC_Camera; -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_Collision.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_CollisionWaterBox"; 4 | SIBE; 5 | SIT; 6 | short minX; 7 | SIT; 8 | short topY; 9 | SIT; 10 | short minZ; 11 | SIT; 12 | short sizeX; 13 | SIT; 14 | short sizeZ; 15 | SIT; 16 | ubyte zeroes[4]; 17 | AssertUBytesNull(zeroes, thisName); 18 | SIT; 19 | enum WATER_PROPS { 20 | WATER_PROP_NORMAL = 0x0100, 21 | WATER_PROP_ABNORMAL = 0x0102, 22 | WATER_PROP_CAMERAFUCKER = 0x0105, 23 | } maybeWaterPropertiesOrCameraEffects; 24 | /* 25 | AnomEnum( 26 | EnumToString( maybeWaterPropertiesOrCameraEffects ), 27 | maybeWaterPropertiesOrCameraEffects, 28 | thisName+"->maybeWaterPropertiesOrCameraEffects" 29 | ); 30 | */ 31 | } ZHC_CollisionWaterBox; 32 | 33 | typedef struct { 34 | SIBE; 35 | SIT; 36 | ushort type; 37 | SIT; 38 | ZVector verts; 39 | SIT; 40 | ZNormal normal; 41 | SIT; 42 | short displacement; 43 | SIEND; 44 | } ZHC_CollisionPolyList; 45 | 46 | /* 47 | differences (quicksand-major): 48 | terrain_trigger_reset_enable 49 | terrain_hurt_fire_enable 50 | terrain_hookshot_enable 51 | unknown3 = 1 (else: 0) 52 | unknown4 = 15 53 | */ 54 | /* 55 | other notes (for both): 56 | specialEffects == 1 57 | TERRAIN_CAMERA_PROXIMITY_NOTSO_CLOSEUP 58 | 1 \ 0 \15 \ TERRAIN_SLOPE_BURGOR \ TERRAIN_SOUND_DIRT 59 | */ 60 | 61 | typedef struct { 62 | // This data closely resembles the NIFF_Mat data type (Material) 63 | // Specifically: ambient/primary/fog lighting and user values per-poly 64 | // Outside the typical "UserExpansionBlock" 65 | local string thisName = "ZHC_CollisionPolyTypeList"; 66 | SIBE; 67 | 68 | SIT; UNK; 69 | ubyte unknown1 : 2; 70 | 71 | SIT; 72 | // if these two bits aren't set at the same time, instant transitions 73 | // do not happen 74 | enum TERRAIN_TRIGGER_TRANSITION { 75 | TERRAIN_TRIGGER_TRANSITION_DESERTLOST = 0x3 76 | } do_trigger_transit : 2; 77 | 78 | SIT; 79 | ubyte obj_set_or_exit_number : 4; 80 | 81 | // == milestone: 8 bits 82 | 83 | SIT; 84 | enum TERRAIN_HANDS { 85 | TERRAIN_HANDS_DO_NOTHING = 0x0, // 0 0 0 0 86 | // 0 0 0 1 0x1 ? 87 | // 0 0 1 0 0x2 ? 88 | // 0 0 1 1 0x3 ? 89 | // 0 1 0 0 0x4 ? 90 | // 0 1 0 1 0x5 ? 91 | TERRAIN_HANDS_CLIMB_DOWN = 0x6, // 0 1 1 0 92 | TERRAIN_HANDS_CLIMB_DOWN2 = 0x7, // 0 1 1 1 93 | TERRAIN_HANDS_ALLOW_CLIMB = 0x8, // 1 0 0 0 94 | // 1 0 0 1 0x9 ? 95 | TERRAIN_HANDS_ALLOW_CRAWL = 0xA, // 1 0 1 0 96 | // 1 0 1 1 0xB ? 97 | // 1 1 0 0 0xC ? 98 | // 1 1 0 1 0xD ? 99 | TERRAIN_HANDS_GRAB_SURFACE = 0xE, // 1 1 1 0 100 | // 1 1 1 1 0xF ? 101 | } climbability : 4; 102 | 103 | SIT; UNK; 104 | ubyte unknown2 : 2; 105 | 106 | SIT; 107 | // the first bit impedes the second bit 108 | enum TERRAIN_ANGER_JABBU { 109 | TERRAIN_ANGER_JABBU_DISABLE = 0x0, 110 | TERRAIN_ANGER_JABBU_ENABLE = 0x1, 111 | } do_anger_jabbu : 2; 112 | 113 | // == milestone: 16 bits 114 | 115 | SIT; 116 | enum TERRAIN_TRIGGER_RESET { 117 | TERRAIN_TRIGGER_RESET_DISABLE = 0x0, 118 | TERRAIN_TRIGGER_RESET_ENABLE = 0x1, 119 | } do_out_of_bounds_reset : 1; 120 | 121 | SIT; 122 | // the second half of this is only used for quicksand? 123 | enum TERRAIN_HURT_FIRE { 124 | TERRAIN_HURT_FIRE_DISABLE = 0x0, 125 | TERRAIN_HURT_FIRE_ENABLE = 0x1, 126 | TERRAIN_HURT_FIRE_DISABLE2= 0x2, 127 | TERRAIN_HURT_FIRE_ENABLE2 = 0x3, 128 | } do_trigger_hurt_fire : 2; 129 | 130 | SIT; 131 | // if exitTrigger isn't a valid exit then enabling this will crash 132 | enum TERRAIN_WARP { 133 | TERRAIN_WARP_DISABLE = 0x0, 134 | TERRAIN_WARP_ENABLE = 0x1, 135 | } do_warp : 1; 136 | 137 | SIT; 138 | // 0 == disabled, exit to jump to if this poly triggers one 139 | ubyte exitTrigger : 4; 140 | 141 | // == milestone: 24 bits 142 | 143 | SIT; 144 | // anything above 6 is just a higher angle of 5 145 | enum TERRAIN_CAMERA_PROXIMITY { 146 | TERRAIN_CAMERA_PROXIMITY_NORMAL = 0x00, 147 | TERRAIN_CAMERA_PROXIMITY_HIGHBIRDSEYE = 0x01, 148 | TERRAIN_CAMERA_PROXIMITY_HIGHBIRDSEYE2 = 0x02, 149 | TERRAIN_CAMERA_PROXIMITY_CLOSEUP = 0x03, 150 | TERRAIN_CAMERA_PROXIMITY_NOTSO_CLOSEUP = 0x04, 151 | TERRAIN_CAMERA_PROXIMITY_NORMAL2 = 0x05, // same as 0x5 152 | TERRAIN_CAMERA_PROXIMITY_HIGHER = 0x06, 153 | TERRAIN_CAMERA_PROXIMITY_PROBABLYUNUSED = 0xFF, 154 | } camera_modifier; 155 | 156 | // == milestone: 32 bits 157 | 158 | /* 159 | AnomEnum( 160 | EnumToString( camera_modifier ), 161 | camera_modifier, 162 | thisName+"->camera_modifier" 163 | ); 164 | */ 165 | SIT; UNK; 166 | ubyte unknown3 : 4; 167 | 168 | SIT; 169 | enum WALLS_HURT { 170 | WALLS_HURT_DISABLE = 0, 171 | WALLS_HURT_ENABLE = 1, 172 | } do_walls_hurt : 1; 173 | 174 | SIT; UNK; 175 | ubyte unknown4 : 3; 176 | 177 | // == milestone: 40 bits 178 | 179 | SIT; UNK; 180 | ubyte unknown5 : 4; 181 | 182 | SIT; UNK; 183 | ubyte unknown6 : 2; 184 | 185 | SIT; 186 | enum TERRAIN_HOOKSHOT { 187 | TERRAIN_HOOKSHOT_DISABLE = 0x0, 188 | TERRAIN_HOOKSHOT_ENABLE = 0x1, 189 | } hookshot : 1; 190 | 191 | SIT; UNK; 192 | ubyte unknown7 : 1; 193 | 194 | // == milestone: 48 bits 195 | 196 | SIT; 197 | // Presumably, this is for trick walls that are 198 | // bombable or metal surfaces. 199 | // WILL *OVERRIDE* SCENE ECHO SETTING 200 | ubyte impact_sound_echo : 4; 201 | 202 | SIT; UNK; 203 | // this and the next unknown composed ambient settings 204 | ubyte unknown8 : 4; 205 | 206 | // milestone: 56 bits 207 | 208 | SIT; UNK; 209 | ubyte unknown9 : 2; 210 | 211 | SIT; 212 | // this spans 2 bits because of how it wraps, 213 | // only TERRAIN_SLOPE_ENABLE triggers sloping(?) 214 | enum TERRAIN_SLOPE { 215 | TERRAIN_SLOPE_DISABLE = 0x0, 216 | TERRAIN_SLOPE_ENABLE = 0x1, 217 | TERRAIN_SLOPE_HOTDOG = 0x2, 218 | TERRAIN_SLOPE_BURGOR = 0x3, 219 | } slope : 2; 220 | 221 | SIT; 222 | // this is footstep sounds, but also the sound it makes 223 | // if struck with a sword 224 | enum TERRAIN_SOUND { 225 | TERRAIN_SOUND_DIRT = 0x0, 226 | TERRAIN_SOUND_SAND = 0x1, 227 | TERRAIN_SOUND_STONE_DRY = 0x2, 228 | TERRAIN_SOUND_STONE_WET = 0x3, 229 | TERRAIN_SOUND_WATER_SHALLOW = 0x4, 230 | TERRAIN_SOUND_WATER_DEEP = 0x5, 231 | TERRAIN_SOUND_GRASS = 0x6, 232 | TERRAIN_SOUND_LAVA_OR_GOO = 0x7, 233 | TERRAIN_SOUND_DIRT2 = 0x8, 234 | TERRAIN_SOUND_WOOD_PLANK = 0x9, 235 | TERRAIN_SOUND_DIRT_PACKED_OR_WOOD = 0xA, 236 | TERRAIN_SOUND_DIRT3 = 0xB, 237 | TERRAIN_SOUND_CERAMIC = 0xC, 238 | TERRAIN_SOUND_DIRT_LOOSE = 0xD, 239 | TERRAIN_SOUND_DIRT4 = 0xE, 240 | TERRAIN_SOUND_DIRT5 = 0xF, 241 | } terrainSound : 4; 242 | 243 | // milestone: 64 bits 244 | } ZHC_CollisionPolyTypeList; 245 | 246 | typedef struct { 247 | local string thisName = "ZHC_CollisionHeader"; 248 | SIBE; 249 | SIT; 250 | ZVector min; 251 | SIT; 252 | ZVector max; 253 | SIT; 254 | ushort numVerts; 255 | SIT; 256 | ubyte zeroes1[2]; 257 | AssertUBytesNull(zeroes1, thisName); 258 | SIT; 259 | ZBankPointer vertArrayOffset; 260 | if( vertArrayOffset.zb.bankNo == bankType ){ 261 | SAVE; 262 | FSeek(headerStart + vertArrayOffset.offset); 263 | ZVector verts[numVerts]; 264 | REST; 265 | } else { 266 | Assert( 0, "External Bank" ); 267 | } 268 | SIT; 269 | ushort numPolys; 270 | SIT; 271 | ubyte zeroes2[2]; 272 | AssertUBytesNull(zeroes2, thisName); 273 | SIT; 274 | ZBankPointer polyArrayOffset; 275 | if( polyArrayOffset.zb.bankNo == bankType ){ 276 | SAVE; 277 | FSeek(headerStart + polyArrayOffset.offset); 278 | struct { 279 | ZHC_CollisionPolyList polys[numPolys]; 280 | } AllThesePolyLists; 281 | REST; 282 | } else { 283 | Assert( 0, "External Bank" ); 284 | } 285 | SIT; 286 | ZBankPointer polyTypeArrayOffset; 287 | if( polyTypeArrayOffset.zb.bankNo == bankType ){ 288 | SAVE; 289 | FSeek(headerStart + polyTypeArrayOffset.offset); 290 | struct { 291 | ZHC_CollisionPolyTypeList polyTypes[numPolys]; 292 | } AllThesePolyTypeLists; 293 | REST; 294 | } else { 295 | Assert( 0, "External Bank" ); 296 | } 297 | SIT; 298 | ZBankPointer cameraDataOffset; //if not zeroes 299 | if( cameraDataOffset.zb.bankNo == bankType ){ 300 | SAVE; 301 | FSeek(headerStart + cameraDataOffset.offset); 302 | ZHC_AltCamera cameraData; 303 | REST; 304 | } else { 305 | Assert( 0, "External Bank" ); 306 | } 307 | SIT; 308 | ushort numWaterBoxes; //if not zeroes 309 | SIT; 310 | ubyte zeroes3[2]; 311 | AssertUBytesNull(zeroes3, thisName); 312 | 313 | SIT; 314 | ZBankPointer waterBoxArrayOffset; 315 | if( numWaterBoxes ){ 316 | if( waterBoxArrayOffset.zb.bankNo == bankType ){ 317 | SAVE; 318 | FSeek(headerStart + waterBoxArrayOffset.offset); 319 | struct { 320 | ZHC_CollisionWaterBox waterBoxes[numWaterBoxes]; 321 | } AllTheseWaterBoxes; 322 | REST; 323 | } else { 324 | Assert( 0, "External Bank" ); 325 | } 326 | } 327 | SIEND; 328 | } ZHC_CollisionHeader; 329 | 330 | typedef struct { 331 | local string thisName = "ZHC_CollisionHeader"; 332 | SIBE; 333 | SIT; 334 | ubyte command; 335 | AssertNumberEquals(command, 0x03, thisName); 336 | 337 | SIT; 338 | ubyte zeroes[3]; 339 | AssertUBytesNull(zeroes, thisName); 340 | 341 | ZBankPointer listOffset; 342 | if( listOffset.zb.bankNo == bankType ){ 343 | SAVE; 344 | FSeek(headerStart + listOffset.offset); 345 | ZHC_CollisionHeader collisionHeaders; 346 | REST; 347 | } else { 348 | Assert( 0, "External Bank" ); 349 | } 350 | SIEND; 351 | } ZHC_CollisionList; -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_Cutscene.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_CutsceneData"; 4 | SIBE; 5 | 6 | SIT; 7 | ZBankPointer sceneOffset; 8 | if( sceneOffset.zb.bankNo == bankType ){ 9 | SAVE; 10 | FSeek(headerStart + sceneOffset.offset); 11 | // @TODO: Parse cutscene data. 12 | ubyte u_r_here; 13 | REST; 14 | } else { 15 | Assert( 0, "External Bank" ); 16 | } 17 | 18 | SIT; UNK; 19 | ubyte unknown[4]; 20 | 21 | SIEND; 22 | } ZHC_CutsceneData; 23 | 24 | typedef struct { 25 | local string thisName = "ZHC_Cutscene"; 26 | SIBE; 27 | SIT; 28 | ubyte command; 29 | AssertNumberEquals(command, 0x17, thisName); 30 | 31 | SIT; 32 | ubyte numElms; 33 | AssertUIntGTZero(numElms, thisName); 34 | SIT; 35 | ubyte zeroes[2]; 36 | AssertUBytesNull(zeroes, thisName); 37 | 38 | ZBankPointer listOffset; 39 | if( listOffset.zb.bankNo == bankType ){ 40 | SAVE; 41 | FSeek(headerStart + listOffset.offset); 42 | ZHC_CutsceneData cutsceneData[numElms]; 43 | REST; 44 | } else { 45 | Assert( 0, "External Bank" ); 46 | } 47 | SIEND; 48 | } ZHC_Cutscene; -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_Entrance.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_EntranceData"; 4 | SIBE; 5 | SIT; 6 | ubyte unknown[1]; 7 | SIEND; 8 | } ZHC_EntranceData; 9 | 10 | typedef struct { 11 | local string thisName = "ZHC_Entrance"; 12 | SIBE; 13 | SIT; 14 | ubyte command; 15 | AssertNumberEquals(command, 0x06, thisName); 16 | 17 | SIT; 18 | ubyte numElms; 19 | AssertUIntGTZero(numElms, thisName); 20 | SIT; 21 | ubyte zeroes[2]; 22 | AssertUBytesNull(zeroes, thisName); 23 | 24 | ZBankPointer listOffset; 25 | if( listOffset.zb.bankNo == bankType ){ 26 | SAVE; 27 | FSeek(headerStart + listOffset.offset); 28 | ZHC_EntranceData unknown[numElms]; 29 | REST; 30 | } else { 31 | Assert( 0, "External Bank" ); 32 | } 33 | SIEND; 34 | } ZHC_Entrance; -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_Environment.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_Environment"; 4 | SIBE; 5 | SIT; 6 | // Usually 0x462D39 7 | ZColor ambient; 8 | SIT; 9 | ZColor diffuse1Color; 10 | SIT; 11 | ZByteVector diffuse1Dir; 12 | SIT; 13 | ZColor diffuse2Color; 14 | SIT; 15 | ZByteVector diffuse2Dir; 16 | SIT; 17 | ZColor fogColor; 18 | SIT; 19 | ushort fogStart; // & 0x3FF ? 20 | SIT; 21 | ushort drawDistance; 22 | SIEND; 23 | } ZHC_Environment; 24 | 25 | typedef struct { 26 | local string thisName = "ZHC_EnvironmentList"; 27 | SIBE; 28 | SIT; 29 | ubyte command; 30 | AssertNumberEquals(command, 0x0F, thisName); 31 | 32 | SIT; 33 | ubyte numElms; 34 | AssertUIntGTZero(numElms, thisName); 35 | SIT; 36 | ubyte zeroes[2]; 37 | AssertUBytesNull(zeroes, thisName); 38 | 39 | ZBankPointer listOffset; 40 | if( listOffset.zb.bankNo == bankType ){ 41 | SAVE; 42 | FSeek(startof(parentof(this)) + listOffset.offset); 43 | ZHC_Environment environments[numElms];; 44 | REST; 45 | } else { 46 | Assert( 0, "External Bank" ); 47 | } 48 | SIEND; 49 | } ZHC_EnvironmentList; -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_Exit.bt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EntranceJew/zelda-binary-templates/254ec56a455dc493c1d7eb78746b8156b0c0bc27/filetypes/Scene/HC/ZHC_Exit.bt -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_Map.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | struct ZRoom; 3 | 4 | typedef struct { 5 | local string thisName = "ZHC_Map"; 6 | SIBE; 7 | SIT; 8 | ZFileSystemRange roomPos; 9 | //@TODO: Validate against the VFS 10 | 11 | SAVE; 12 | FSeek(roomPos.start); 13 | ZRoom room; 14 | REST; 15 | 16 | SIEND; 17 | } ZHC_Map; 18 | 19 | typedef struct { 20 | local string thisName = "ZHC_MapList"; 21 | SIBE; 22 | SIT; 23 | ubyte command; 24 | AssertNumberEquals(command, 0x04, thisName); 25 | 26 | SIT; 27 | ubyte numElms; 28 | AssertUIntGTZero(numElms, thisName); 29 | SIT; 30 | ubyte zeroes[2]; 31 | AssertUBytesNull(zeroes, thisName); 32 | 33 | ZBankPointer listOffset; 34 | if( listOffset.zb.bankNo == bankType ){ 35 | SAVE; 36 | FSeek(headerStart + listOffset.offset); 37 | ZHC_Map maps[numElms]; 38 | REST; 39 | } else { 40 | Assert( 0, "External Bank" ); 41 | } 42 | SIEND; 43 | } ZHC_MapList; -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_Mesh.bt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EntranceJew/zelda-binary-templates/254ec56a455dc493c1d7eb78746b8156b0c0bc27/filetypes/Scene/HC/ZHC_Mesh.bt -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_Object.bt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EntranceJew/zelda-binary-templates/254ec56a455dc493c1d7eb78746b8156b0c0bc27/filetypes/Scene/HC/ZHC_Object.bt -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_Path.bt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EntranceJew/zelda-binary-templates/254ec56a455dc493c1d7eb78746b8156b0c0bc27/filetypes/Scene/HC/ZHC_Path.bt -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_RoomBehavior.bt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EntranceJew/zelda-binary-templates/254ec56a455dc493c1d7eb78746b8156b0c0bc27/filetypes/Scene/HC/ZHC_RoomBehavior.bt -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_StartPos.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_StartPosList"; 4 | SIBE; 5 | SIT; 6 | ubyte command; 7 | AssertNumberEquals(command, 0x00, thisName); 8 | 9 | SIT; 10 | ubyte numElms; 11 | AssertUIntGTZero(numElms, thisName); 12 | SIT; 13 | ubyte zeroes[2]; 14 | AssertUBytesNull(zeroes, thisName); 15 | 16 | ZBankPointer listOffset; 17 | if( listOffset.zb.bankNo == bankType ){ 18 | SAVE; 19 | FSeek(headerStart + listOffset.offset); 20 | ZHC_Actor starts[numElms]; 21 | REST; 22 | } else { 23 | Assert( 0, "External Bank" ); 24 | } 25 | SIEND; 26 | } ZHC_StartPosList; -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_TransitionActor.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_TransitionActor"; 4 | SIBE; 5 | SIT; 6 | ubyte frontTriggerRoomSwitch; 7 | SIT; 8 | ubyte frontCameraTransitType; 9 | //00, 0F, FF 10 | SIT; 11 | ubyte backTriggerRoomSwitch; 12 | SIT; 13 | ubyte backCameraTransitType; 14 | //?? 15 | 16 | SIT; 17 | ushort actorNumber; 18 | SIT; 19 | ZVector pos; 20 | SIT; 21 | ushort rotY; 22 | SIT; 23 | ushort actorVar; 24 | SIEND; 25 | } ZHC_TransitionActor; 26 | 27 | 28 | typedef struct { 29 | local string thisName = "ZHC_TransitionActorList"; 30 | SIBE; 31 | SIT; 32 | ubyte command; 33 | AssertNumberEquals(command, 0x0E, thisName); 34 | 35 | SIT; 36 | ubyte numElms; 37 | AssertUIntGTZero(numElms, thisName); 38 | SIT; 39 | ubyte zeroes[2]; 40 | AssertUBytesNull(zeroes, thisName); 41 | 42 | ZBankPointer listOffset; 43 | if( listOffset.zb.bankNo == bankType ){ 44 | SAVE; 45 | FSeek(startof(parentof(this)) + listOffset.offset); 46 | ZHC_TransitionActor transitionActors[numElms]; 47 | REST; 48 | } else { 49 | Assert( 0, "External Bank" ); 50 | } 51 | SIEND; 52 | } ZHC_TransitionActorList; -------------------------------------------------------------------------------- /filetypes/Scene/HC/ZHC_UnusedEnvironment.bt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EntranceJew/zelda-binary-templates/254ec56a455dc493c1d7eb78746b8156b0c0bc27/filetypes/Scene/HC/ZHC_UnusedEnvironment.bt -------------------------------------------------------------------------------- /filetypes/Scene/HC/_ZHC_End.bt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EntranceJew/zelda-binary-templates/254ec56a455dc493c1d7eb78746b8156b0c0bc27/filetypes/Scene/HC/_ZHC_End.bt -------------------------------------------------------------------------------- /filetypes/Scene/HC/_ZHC_Skybox.bt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EntranceJew/zelda-binary-templates/254ec56a455dc493c1d7eb78746b8156b0c0bc27/filetypes/Scene/HC/_ZHC_Skybox.bt -------------------------------------------------------------------------------- /filetypes/Scene/HC/_ZHC_SkyboxMod.bt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EntranceJew/zelda-binary-templates/254ec56a455dc493c1d7eb78746b8156b0c0bc27/filetypes/Scene/HC/_ZHC_SkyboxMod.bt -------------------------------------------------------------------------------- /filetypes/Scene/HC/_ZHC_Sound.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_Sound"; 4 | SIBE; 5 | SIT; 6 | ubyte command; 7 | AssertNumberEquals(command, 0x15, thisName); 8 | 9 | SIT; 10 | ubyte reverb; //TODO: Histogram of usage. 11 | SIT; 12 | ubyte zeroes[4]; 13 | AssertUBytesNull(zeroes, thisName); 14 | SIT; 15 | ubyte nightSFX; 16 | //TODO: Write resolver. http://wiki.cloudmodding.com/mm/Music_Values#Nighttime_SFX 17 | SIT; 18 | ubyte track; 19 | SIEND; 20 | } ZHC_Sound; -------------------------------------------------------------------------------- /filetypes/Scene/HC/_ZHC_SpecialObjects.bt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EntranceJew/zelda-binary-templates/254ec56a455dc493c1d7eb78746b8156b0c0bc27/filetypes/Scene/HC/_ZHC_SpecialObjects.bt -------------------------------------------------------------------------------- /filetypes/Scene/HC/_ZHC_Time.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_Time"; 4 | SIBE; 5 | 6 | SIT; 7 | ubyte command; 8 | AssertNumberEquals(command, 0x10, thisName); 9 | 10 | SIT; 11 | ubyte zeroes1[3]; 12 | AssertUBytesNull(zeroes1, thisName); 13 | 14 | SIT; 15 | ushort startTime; 16 | //0xFFFF == current time 17 | 18 | SIT; 19 | byte timeSpeed; 20 | 21 | SIT; 22 | ubyte zeroes2[1]; 23 | AssertUBytesNull(zeroes2, thisName); 24 | 25 | SIEND; 26 | } ZHC_Time; -------------------------------------------------------------------------------- /filetypes/Scene/HC/_ZHC_Unknown1A.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_Unknown1AData"; 4 | SIBE; 5 | SIT; 6 | ubyte unknown[16]; 7 | SIEND; 8 | } ZHC_Unknown1AData; 9 | 10 | typedef struct { 11 | local string thisName = "ZHC_Unknown1A"; 12 | SIBE; 13 | SIT; 14 | ubyte command; 15 | AssertNumberEquals(command, 0x1A, thisName); 16 | 17 | SIT; 18 | ubyte numElms; 19 | //AssertUIntGTZero(numElms, thisName); 20 | SIT; 21 | ubyte zeroes[2]; 22 | AssertUBytesNull(zeroes, thisName); 23 | 24 | ZBankPointer listOffset; 25 | if( listOffset.zb.bankNo == bankType ){ 26 | SAVE; 27 | FSeek(startof(parentof(this)) + listOffset.offset); 28 | ZHC_Unknown1AData unknown[numElms+1]; 29 | REST; 30 | } else { 31 | Assert( 0, "External Bank" ); 32 | } 33 | SIEND; 34 | } ZHC_Unknown1A; -------------------------------------------------------------------------------- /filetypes/Scene/HC/_ZHC_Unknown1B.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_Unknown1BData"; 4 | SIBE; 5 | SIT; 6 | ubyte uknknown1[2]; 7 | SIT; 8 | ushort length; 9 | // 0xFFFF = constant play 10 | SIT; 11 | ushort cameraToUse; 12 | SIT; 13 | ushort nextEntry; 14 | SIT; 15 | ubyte postPuzzleSFX; 16 | SIT; 17 | ubyte unknown2[3]; 18 | SIT; 19 | ubyte postCameraPos; 20 | SIT; 21 | ubyte blackBarSize; 22 | SIEND; 23 | } ZHC_Unknown1BData; 24 | 25 | /* 26 | 0x1B - Used by actors to decide what camera to use/cutscene to play. 27 | 28 | uuuutttt bbbbcccc nnnnssuu uuuuddee 29 | 30 | tt = length (FFFF = constantly playing) 31 | bb = camera to use 32 | FFF0 = Entering warp after defeating boss 33 | FFF5 = Mask Transformation 34 | FFF6 = opening a large chest 35 | FFF7 = ??? 36 | FFF8 = ??? 37 | FFF9 = ??? 38 | FFFA = Song of Soaring 39 | FFFB = using event item 40 | FFFC = drinking bottle 41 | FFFD = playing ocarina 42 | FFFE = opening a small chest 43 | FFFF = null 44 | 0000+= additional cameras (see 0x02 command) 45 | cc = cutscene to play 46 | FFFF = null 47 | nn = next entry? 48 | ss = puzzle sound effect to play after 49 | dd = camera position after 50 | 00 = keep current position 51 | 01 = place behind link 52 | 02 = rotate until behind link 53 | ee = size of black bars 54 | 80 = max 55 | uu = unknown 56 | */ 57 | 58 | typedef struct { 59 | local string thisName = "ZHC_Unknown1B"; 60 | SIBE; 61 | SIT; 62 | ubyte command; 63 | AssertNumberEquals(command, 0x1B, thisName); 64 | 65 | SIT; 66 | ubyte numElms; 67 | AssertUIntGTZero(numElms, thisName); 68 | SIT; 69 | ubyte zeroes[2]; 70 | AssertUBytesNull(zeroes, thisName); 71 | 72 | ZBankPointer listOffset; 73 | if( listOffset.zb.bankNo == bankType ){ 74 | SAVE; 75 | FSeek(startof(parentof(this)) + listOffset.offset); 76 | ZHC_Unknown1BData unknown[numElms]; 77 | REST; 78 | } else { 79 | Assert( 0, "External Bank" ); 80 | } 81 | SIEND; 82 | } ZHC_Unknown1B; -------------------------------------------------------------------------------- /filetypes/Scene/HC/_ZHC_Unknown1C.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_Unknown1CData"; 4 | SIBE; 5 | SIT; 6 | ubyte unknown[12]; 7 | SIEND; 8 | } ZHC_Unknown1CDataData; 9 | 10 | typedef struct { 11 | local string thisName = "ZHC_Unknown1CData"; 12 | SIBE; 13 | SIT; 14 | ZBankPointer listOffset; 15 | if( listOffset.zb.bankNo == bankType ){ 16 | SAVE; 17 | FSeek(headerStart + listOffset.offset); 18 | ZHC_Unknown1CDataData unknown; 19 | REST; 20 | } else { 21 | Assert( 0, "External Bank" ); 22 | } 23 | SIEND; 24 | } ZHC_Unknown1CData; 25 | 26 | typedef struct { 27 | local string thisName = "ZHC_Unknown1C"; 28 | SIBE; 29 | SIT; 30 | ubyte command; 31 | AssertNumberEquals(command, 0x1C, thisName); 32 | 33 | SIT; 34 | ubyte numElms; 35 | //AssertUIntGTZero(numElms, thisName); 36 | SIT; 37 | ubyte zeroes[2]; 38 | AssertUBytesNull(zeroes, thisName); 39 | 40 | ZBankPointer listOffset; 41 | if( listOffset.zb.bankNo == bankType ){ 42 | SAVE; 43 | FSeek(headerStart + listOffset.offset); 44 | ZHC_Unknown1CData unknown[numElms+1]; 45 | REST; 46 | } else { 47 | Assert( 0, "External Bank" ); 48 | } 49 | SIEND; 50 | } ZHC_Unknown1C; -------------------------------------------------------------------------------- /filetypes/Scene/HC/_ZHC_Unknown1D.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_Unknown1DData"; 4 | SIBE; 5 | SIT; 6 | ubyte unknown[1]; 7 | SIEND; 8 | } ZHC_Unknown1DData; 9 | 10 | typedef struct { 11 | local string thisName = "ZHC_Unknown1D"; 12 | SIBE; 13 | SIT; 14 | ubyte command; 15 | AssertNumberEquals(command, 0x1D, thisName); 16 | 17 | //SIT; 18 | //ubyte numElms; 19 | //AssertUIntGTZero(numElms, thisName); 20 | SIT; 21 | ubyte zeroes[2]; 22 | AssertUBytesNull(zeroes, thisName); 23 | 24 | ZBankPointer listOffset; 25 | if( listOffset.zb.bankNo == bankType ){ 26 | SAVE; 27 | FSeek(headerStart + listOffset.offset); 28 | ZHC_Unknown1DData unknown;//[numElms]; 29 | REST; 30 | } else { 31 | Assert( 0, "External Bank" ); 32 | } 33 | SIEND; 34 | } ZHC_Unknown1D; -------------------------------------------------------------------------------- /filetypes/Scene/HC/_ZHC_Unknown1E.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_Unknown1EData"; 4 | SIBE; 5 | SIT; 6 | ubyte unknown[1]; 7 | SIEND; 8 | } ZHC_Unknown1EData; 9 | 10 | typedef struct { 11 | local string thisName = "ZHC_Unknown1E"; 12 | SIBE; 13 | SIT; 14 | ubyte command; 15 | AssertNumberEquals(command, 0x1E, thisName); 16 | 17 | SIT; 18 | ubyte numElms; 19 | AssertUIntGTZero(numElms, thisName); 20 | SIT; 21 | ubyte zeroes[2]; 22 | AssertUBytesNull(zeroes, thisName); 23 | 24 | ZBankPointer listOffset; 25 | if( listOffset.zb.bankNo == bankType ){ 26 | SAVE; 27 | FSeek(headerStart + listOffset.offset); 28 | ZHC_Unknown1EData unknown[numElms]; 29 | REST; 30 | } else { 31 | Assert( 0, "External Bank" ); 32 | } 33 | SIEND; 34 | } ZHC_Unknown1E; -------------------------------------------------------------------------------- /filetypes/Scene/HC/_ZHC_Unused09.bt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EntranceJew/zelda-binary-templates/254ec56a455dc493c1d7eb78746b8156b0c0bc27/filetypes/Scene/HC/_ZHC_Unused09.bt -------------------------------------------------------------------------------- /filetypes/Scene/HC/_ZHC_Wind.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | local string thisName = "ZHC_Wind"; 4 | SIBE; 5 | 6 | SIT; 7 | ubyte command; 8 | AssertNumberEquals(command, 0x05, thisName); 9 | 10 | SIT; 11 | ubyte zeroes1[3]; 12 | AssertUBytesNull(zeroes1, thisName); 13 | 14 | SIT; 15 | // TODO: figure out what this thing is all about 16 | // in their documented order, with emphasis on the latter item: 17 | // east/west, 18 | // down/up, 19 | // north/south 20 | ZUByteVector windDirection; 21 | 22 | SIT; 23 | ubyte windMagnitude; 24 | 25 | SIEND; 26 | } ZHC_Wind; -------------------------------------------------------------------------------- /filetypes/Scene/Scene.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | struct ZSceneHeader; 3 | struct ZSceneHeaderCommand; 4 | 5 | typedef struct { 6 | SIBE; 7 | local uint64 headerStart = FTell(); 8 | local ubyte bankType = 0x02; 9 | //ZSceneHeaderCommand commands[25]; 10 | ZSceneHeader header( bankType ); 11 | //FSeek(4C40h); 12 | //ZSceneHeader mysteryHeader; 13 | SIEND; 14 | } ZScene; 15 | 16 | typedef struct { 17 | SIBE; 18 | local uint64 headerStart = FTell(); 19 | local ubyte bankType = 0x03; 20 | //ZSceneHeaderCommand commands[25]; 21 | ZSceneHeader header( bankType ); 22 | //FSeek(4C40h); 23 | //ZSceneHeader mysteryHeader; 24 | SIEND; 25 | } ZRoom; -------------------------------------------------------------------------------- /filetypes/Simple.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct { 3 | ubyte red; 4 | ubyte green; 5 | ubyte blue; 6 | } ZColor; 7 | 8 | typedef struct { 9 | // These are signed. 0x7FFF = 1.0 10 | hfloat x; 11 | hfloat y; 12 | hfloat z; 13 | } ZNormal; 14 | 15 | typedef struct { 16 | // These are signed. 17 | short x; 18 | short y; 19 | short z; 20 | } ZVector; 21 | 22 | typedef struct { 23 | ubyte x; 24 | ubyte y; 25 | ubyte z; 26 | } ZByteVector; 27 | 28 | typedef struct { 29 | byte x; 30 | byte y; 31 | byte z; 32 | } ZUByteVector; 33 | -------------------------------------------------------------------------------- /filetypes/Texture/JFIF.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | enum JFIFPixelDensity { 3 | NotSpecified = 0x00, 4 | PixelsPerInch = 0x01, 5 | PixelsPerCentimeter = 0x02 6 | }; 7 | 8 | void NowYCbCr2RGB(){ 9 | local ubyte Y = ReadUByte(FTell()); 10 | local ubyte Cb = ReadUByte(FTell()+1); 11 | local ubyte Cr = ReadUByte(FTell()+2); 12 | local string out; 13 | local int color; 14 | SPrintf(out,"0x%02X%02X%02X", 15 | Y + 1.772 * ( Cb - 128), 16 | Y - 0.34414 * ( Cb - 128 ) - 0.71414 * (Cr - 128 ), 17 | Y + 1.402 * ( Cr - 128) 18 | ); 19 | SScanf(out, "0x%06X", color); 20 | SetBackColor( color ); 21 | } 22 | 23 | typedef struct { 24 | NowYCbCr2RGB(); 25 | ubyte Y; 26 | ubyte Cb; 27 | ubyte Cr; 28 | } YCbCr; 29 | 30 | int YCbCr2RGB( YCbCr &ycbcr ){ 31 | local string out; 32 | local int color; 33 | SPrintf(out,"0x%02X%02X%02X", 34 | ycbcr.Y + 1.402 * ( ycbcr.Cr - 128), 35 | ycbcr.Y - 0.34414 * ( ycbcr.Cb - 128 ) - 0.71414 * (ycbcr.Cr - 128 ), 36 | ycbcr.Y + 1.772 * ( ycbcr.Cb - 128) 37 | ); 38 | SScanf(out, "0x%06X", color); 39 | return color; 40 | } 41 | 42 | typedef struct { 43 | char start[2]; //0xFFD8 or riot 44 | char APP0[2]; //0xFFE0 or riot 45 | ushort headLen; //usually 16 46 | string magic; // "JFIF" followed by a null 47 | ubyte verMajor; //OoT uses v1.01 48 | ubyte verMinor; 49 | JFIFPixelDensity pixelDensity; 50 | ushort densityX; 51 | ushort densityY; 52 | ubyte thumbWidth; // 0 or riot 53 | ubyte thumbHeight; // 0 or riot 54 | ubyte thumbData[thumbWidth * thumbHeight * 3]; // empty or riot 55 | char headEnd[2]; //0xFFDB or riot 56 | local ushort readByte = 0x0000; 57 | local uint64 startPos = FTell(); 58 | while( ReadUShort() != 0xFFD9 ){ 59 | FSkip(1); 60 | // should only advance a single byte, 61 | // not guaranteed to fall on boundaries 62 | } 63 | local uint64 sizeOfData = FTell()-startPos; 64 | FSeek(startPos); 65 | YCbCr pixels[sizeOfData / 3]; 66 | char end[2]; //0xFFD9 or riot 67 | } JFIF; -------------------------------------------------------------------------------- /filetypes/Texture/ci4.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | local uint64 _ci4toggle_hack = 0; 3 | typedef struct{ 4 | local ubyte hX = ReadUByteBits(FTell(), _ci4toggle_hack, 4) * (255.0 / 15.0); 5 | SetBackColorTup( hX, hX, hX ); 6 | ubyte x : 4; 7 | 8 | if( _ci4toggle_hack ){ 9 | _ci4toggle_hack = 0; 10 | } else { 11 | _ci4toggle_hack = 4; 12 | } 13 | } ci4; -------------------------------------------------------------------------------- /filetypes/Texture/ci8.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct{ 3 | local ubyte hX = ReadUByte(FTell()); 4 | SetBackColorTup( hX, hX, hX ); 5 | ubyte x : 8; 6 | } ci8; -------------------------------------------------------------------------------- /filetypes/Texture/i4.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // a hack to allow our in-memory read to stay aligned with 3 | // the actual bitfield, only works if an image dimension evens-out 4 | local uint64 _i4toggle_hack = 0; 5 | typedef struct{ 6 | local ubyte hA = ReadUByteBits(FTell(), _i4toggle_hack, 4) * (255.0 / 15.0); 7 | SetBackColorTup( hA, hA, hA ); 8 | ubyte a : 4; 9 | 10 | if( _i4toggle_hack ){ 11 | _i4toggle_hack = 0; 12 | } else { 13 | _i4toggle_hack = 4; 14 | } 15 | } i4; -------------------------------------------------------------------------------- /filetypes/Texture/i8.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct{ 3 | local ubyte hA = ReadUByte(FTell()); 4 | SetBackColorTup( hA, hA, hA ); 5 | ubyte a : 8; 6 | } i8; -------------------------------------------------------------------------------- /filetypes/Texture/ia16.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct{ 3 | // visualize it 4 | local ubyte hC = ReadUByte(FTell()); 5 | local ubyte hA = ReadUByte(FTell()); 6 | if( hA > 0 ){ 7 | SetBackColorTup( hC, hC, hC ); 8 | } 9 | 10 | ubyte c : 8; 11 | ubyte a : 8; 12 | } ia16; -------------------------------------------------------------------------------- /filetypes/Texture/ia4.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // a hack to allow our in-memory read to stay aligned with 3 | // the actual bitfield, only works if an image dimension evens-out 4 | local uint64 _ia4toggle_hack = 0; 5 | typedef struct{ 6 | local ubyte hC = ReadUByteBits(FTell(), _ia4toggle_hack, 3) * (255.0 / 7.0); 7 | local ubyte hA = ReadUByteBits(FTell(), _ia4toggle_hack+3, 1); 8 | //if(hA > 0){ 9 | SetBackColorTup( hC, hC, hC ); 10 | //} 11 | ubyte c : 3; 12 | ubyte a : 1; 13 | 14 | if( _ia4toggle_hack ){ 15 | _ia4toggle_hack = 0; 16 | } else { 17 | _ia4toggle_hack = 4; 18 | } 19 | } ia4; -------------------------------------------------------------------------------- /filetypes/Texture/ia8.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct{ 3 | // visualize it 4 | local ubyte hC = ReadUByteBits(FTell(), 0, 4) * (255.0 / 15.0); 5 | local ubyte hA = ReadUByteBits(FTell(), 4, 4) * (255.0 / 15.0); 6 | if( hA > 0 ){ 7 | SetBackColorTup( hC, hC, hC ); 8 | } 9 | 10 | ubyte c : 4; 11 | ubyte a : 4; 12 | } ia8; -------------------------------------------------------------------------------- /filetypes/Texture/rgb5a1.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct{ 3 | // visualize it 4 | local uint64 hR = ReadUShortBits(FTell(), 0, 5) * (255.0/31.0); 5 | local uint64 hG = ReadUShortBits(FTell(), 5, 5) * (255.0/31.0); 6 | local uint64 hB = ReadUShortBits(FTell(), 10, 5) * (255.0/31.0); 7 | local uint64 hA = ReadUShortBits(FTell(), 15, 1) * 255.0; 8 | if(hA > 0){ 9 | SetBackColorTup( hR, hG, hB ); 10 | } 11 | 12 | ubyte r : 5; 13 | ubyte g : 5; 14 | ubyte b : 5; 15 | ubyte a : 1; 16 | } rgb5a1; -------------------------------------------------------------------------------- /filetypes/Texture/rgba32.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // 8 bits per channel, allowing values 0 through 255 3 | // for each individual channel. 4 | // TODO: Implement pseudo-alpha drawing. 5 | typedef struct{ 6 | // visualize it 7 | if(ReadUByte(FTell()+3) > 0){ 8 | SetBackColorTup( ReadUByte(FTell()), ReadUByte(FTell()+1), ReadUByte(FTell()+2) ); 9 | } 10 | 11 | ubyte r : 8; 12 | ubyte g : 8; 13 | ubyte b : 8; 14 | ubyte a : 8; 15 | } rgba32; -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Zelda Binary Templates 2 | Did you know? N64 Zelda games (and maybe other zelda games!) are composed of many smaller file types? 3 | If you crack open the ROM you can slurp up that data like some sort of oyster and or egg. 4 | 5 | ![look at that template go](http://i.imgur.com/i27WJvD.png) 6 | 7 | These binary templates aim to cover the gaps in our knowledge by allowing us to explore the data. 8 | When we can see a byte here or there is being skipped or ignored, we can easily tell what is or isn't being used. 9 | 10 | ![previewing image data](https://i.imgur.com/l7U0BuH.png) 11 | _Using the power of templates, we're able to view certain image data exactly as it appears in the ROM without any external tools. [Click here to see a gif of viewing even more image data!](https://i.imgur.com/JuCNQIi.gif)_ 12 | 13 | ## Binary Templates? 010 Editor? 14 | If you don't know what [010 editor](http://www.sweetscape.com/010editor/) is and you've been using a hex editor pretty frequently, 15 | I suggest you try it out. (Plus this repo is mostly useless without it.) If you have it or you can read C structures, 16 | then dive in to the [binary templates](http://www.sweetscape.com/010editor/templates.html) and check out the Important Files section below to get a lay of the land. 17 | If you don't know what any of this is, then I suggest you try out 010 with this repo using the guide linked below. 18 | 19 | ## [Quickstart Guide](docs/quickstart_guide.md) 20 | If you're new to 010 editor or want to get a better picture of how to use this repo, head over to the [Quickstart Guide](docs/quickstart_guide.md). 21 | 22 | # [To Do](todo.md) 23 | Help in any way you think you can. Check out the [todo.md](todo.md) to see if there's anything that you might be able to take a swing at. Just give me a heads up if you do, that way I can plan around that. I suggest experimenting around a little, but when you're ready -- check out [CONTRIBUTING.md](CONTRIBUTING.md). 24 | 25 | # Assumptions 26 | * This repo usually focuses around MM first and OoT second, which is contrary to most existing documentation. 27 | * If unspecified, all of the offsets presented will be for the debug version of the related ROM. 28 | * If unspecified, all or most of the offsets presented will be for the decompressed version of the related ROM. 29 | 30 | ## ROM Names 31 | I tend to reference ROMs by a shorthand name, the full stats of any ROM I work with are listed in [the checksums directory](checksums/). 32 | 33 | ### Majora's Mask 34 | * `dMM_E_debug.z64` is shorthand for a ROM that matches [these checksums](checksums/decompressed/Legend%20of%20Zelda%2C%20The%20-%20Majora's%20Mask%20(E)%20(M4)%20(Debug%20Version).z64.csv) 35 | 36 | ### Ocarina of Time 37 | * `dOoT_MQ_E_debug.z64` is shorthand for a ROM that matches [these checksums](checksums/decompressed/Legend%20of%20Zelda%2C%20The%20-%20Ocarina%20of%20Time%20-%20Master%20Quest%20(E)%20(GC)%20(Debug%20Version).z64.csv) 38 | 39 | # Important Files 40 | * [autoload.bt](autoload.bt) because of nested `#include` restrictions, all includes have go here. Primarily organized alphabetically, and then by dependence. Begins with common scaffolds, then other filetypes. 41 | * [skeleton.bt](skeleton.bt) is a generalized structure that can be included after autoload, it makes use of hardcoded addresses and structure sizes to jump around and read things like the filesystem, scenes, and actor lists. This should always included before any other template variables are defined. 42 | * [Inspector.bt](Inspector.bt) because there are so many small structures, I recommend replacing the default Inspector with this so you can recognize would-be data types at a glance. Makes use of some files in the root of the filetypes folder. 43 | 44 | * [checksums/](checksums/) contains CSVs named after the full ROM name that contain the checksums for said ROM. Use this to verify against shorthand ROM names and that one of us has the right ROM. 45 | * [templates/](templates/) contains files named after the shorthand ROM name for each game and version. Use these as your entry point on ROMs. 46 | * [docs/](docs/) a ton of files for getting up to speed, some scratch notes but others are more valuable. 47 | * [filetypes/](filetypes/) anything that is a small identifiable structure belongs in here. If it's a bigger file type made of many smaller structures (like Scenes) then it gets its own folder. 48 | * [scaffolds/](scaffolds/) a collection of small utility templates that are referenced nearly everywhere. This ranges from automatic color assignment to bit structs or 49 | * [Anomaly.bt](scaffolds/Anomaly.bt) contains useful assertions such as ensuring bytes are null, within numeric ranges, and that enums have definitions. Merely prints warnings with a trace, does not stop execution. 50 | * [Assert.bt](scaffolds/Assert.bt) provides assertion wrappers, functions like Anomaly but all failed asserts will hault execution. 51 | * [Bits.bt](scaffolds/Bits.bt) provides handy wrappers for bit functions like reading N bits from a byte without assignment or bit shifting and a byte-sized struct consisting of eight single-bit variables named `BitEight`. 52 | * [Block.bt](scaffolds/Block.bt) jumps to a location and allocates a predefined amount of space. 53 | * [Bucket.bt](scaffolds/Bucket.bt) provides a method to store values and provide a histogram of their usages. Use `Bucket(var)` to scoop for values, `ClearBucket()` to empty it, and `ReportBucket()` to print information. 54 | * [Colors.bt](scaffolds/Colors.bt) defines extra color constants and allows manipulating tuples of colors as ints and the other way around. 55 | * [Jumps.bt](scaffolds/Jumps.bt) enables saving and restoring the FTell() location with a stack. 56 | * [Padding.bt](scaffolds/Padding.bt) provides a struct to align to the nearest column index for variable sized widths. Also provides a NullEater to consume null bytes. Should not be used in place of `zeroes[]`. 57 | * [Significant.bt](scaffolds/Significant.bt) provides colorization on a per-variable basis to make them stand out from one another. Changes color grades when entering / exiting structures. 58 | * [Unknown.bt](scaffolds/Unknown.bt) handles alerts and traces for unknown variables. Processing this is temporarily disabled, replace `#define UNK NOP()` with `#define UNK AlertUnknownData()` to re-enable. 59 | * [scripts/](scripts/) this is for code that operates on variables provided by the templates. Stuff like extracting Yaz archives, exploding and reassembling the ROM, or correcting save checksums go here. It is also for scripts that extend 010's functionality in some way. 60 | * [CurPosInDec.1sc](scaffolds/CurPosInDec.1sc) puts the cursor position in the file in your clipboard in decimal form. 61 | * [CurPosInHex.1sc](scaffolds/CurPosInHex.1sc) puts the cursor position in the file in your clipboard in padded hex, I suggest putting this on a keyboard shortcut. 62 | * [DumpAllYaz.1sc](scaffolds/DumpAllYaz.1sc) extracts all yaz archives in a file with the variable name "arc" to a user specified folder. 63 | * [FixSaveMM.1sc](scaffolds/FixSaveMM.1sc) recalculates the checksum for a MM save. 64 | * [FixSaveOoT.1sc](scaffolds/FixSaveOoT.1sc) recalculates the checksum for a OoT save. 65 | -------------------------------------------------------------------------------- /scaffolds/Anomaly.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | string EXSAnom(string reason){ 3 | local string out; 4 | SPrintf(out, "%s: @ %08LXh", reason, FTell()); 5 | return out; 6 | }; 7 | 8 | void Anom(uint64 cond, string msg){ 9 | if( !cond ){ 10 | Printf("*ANOMALY %s\n", msg); 11 | } 12 | }; 13 | 14 | // == NULL 15 | void AnomUBytesNull( ubyte b[], string msg ){ 16 | local uint64 i; 17 | local string omsg; 18 | for( i = 0; i < sizeof(b); i++ ){ 19 | if( b[i] != 0x00 ){ 20 | SPrintf(omsg, "%d of %d was not null in %s", i, sizeof(b), msg); 21 | Anom( b[i] != 0x00, EXSAnom(omsg)); 22 | } 23 | } 24 | }; 25 | 26 | // == ZERO 27 | void AnomNotZero( uint a, string msg ){ 28 | local string omsg; 29 | SPrintf(omsg, "%s %d != %d", msg, a, 0); 30 | Anom( !a, EXSAnom(omsg)); 31 | }; 32 | 33 | 34 | void AnomUIntGTZero( uint a, string msg ){ 35 | local string omsg; 36 | SPrintf(omsg, "%s %d was less not greater than zero", msg, a); 37 | Anom( a > 0, EXSAnom(omsg)); 38 | }; 39 | 40 | void AnomUIntGTEZero( uint subject, string msg ){ 41 | local string omsg; 42 | SPrintf(omsg, "%s %d was less not greater than or equal to zero", msg, subject); 43 | Anom( subject >= 0, EXSAnom(omsg)); 44 | }; 45 | 46 | // == EQUALITY 47 | void AnomNumberEquals( uint subject, uint expectation, string msg ){ 48 | local string omsg; 49 | SPrintf(omsg, "%s was %d which isn't %d", msg, subject, expectation); 50 | Anom( subject == expectation, EXSAnom(omsg)); 51 | }; 52 | 53 | void AnomEnum( string e, uint64 d, string msg ){ 54 | local string omsg; 55 | SPrintf(omsg, "%s had an unknown value 0x%04LX", msg, d); 56 | Anom( e != "", EXSAnom(omsg)); 57 | }; 58 | 59 | void AnomNumberInBetween( uint subject, uint min, uint max, string msg ){ 60 | local string omsg; 61 | SPrintf(omsg, "%s was %d which isn't between %d and %d", msg, subject, min, max); 62 | Anom( subject >= min && subject <= max, EXSAnom(omsg)); 63 | }; -------------------------------------------------------------------------------- /scaffolds/Assert.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | string EXSWarning(string reason){ 3 | local string out; 4 | SPrintf(out, "%s: @ 0x%Lx\n", reason, FTell()); 5 | return out; 6 | } 7 | 8 | void EXWarning(string reason){ 9 | Printf("%s: @ 0x%Lx\n", reason, FTell()); 10 | } 11 | 12 | void NLAssert(uint64 cond, string msg){ 13 | if( !cond ){ 14 | Printf("\n"); 15 | } 16 | Assert(cond, msg); 17 | }; 18 | 19 | // == NULL 20 | void AssertUBytesNull( ubyte b[], string msg ){ 21 | local uint64 i; 22 | local string omsg; 23 | for( i = 0; i < sizeof(b); i++ ){ 24 | if( b[i] != 0x00 ){ 25 | SPrintf(omsg, "%d of %d was not null in %s", i, sizeof(b), msg); 26 | NLAssert( b[i] != 0x00, EXSWarning(omsg)); 27 | } 28 | } 29 | }; 30 | 31 | // == ZERO 32 | void AssertUIntGTZero( uint a, string msg ){ 33 | local string omsg; 34 | SPrintf(omsg, "%s %d was less not greater than zero", msg, a); 35 | NLAssert( a > 0, EXSWarning(omsg)); 36 | }; 37 | 38 | void AssertUIntGTEZero( uint subject, string msg ){ 39 | local string omsg; 40 | SPrintf(omsg, "%s %d was less not greater than or equal to zero", msg, subject); 41 | NLAssert( subject >= 0, EXSWarning(omsg)); 42 | }; 43 | 44 | // == EQUALITY 45 | void AssertNumberEquals( uint subject, uint expectation, string msg ){ 46 | local string omsg; 47 | SPrintf(omsg, "%s was %d which isn't %d", msg, subject, expectation); 48 | NLAssert( subject == expectation, EXSWarning(omsg)); 49 | } 50 | 51 | void AssertKnownEnum( string e, uint64 d, string msg ){ 52 | local string omsg; 53 | SPrintf(omsg, "%s had an unknown value 0x%04LX", msg, d); 54 | NLAssert( e != "", EXSWarning(omsg)); 55 | }; 56 | 57 | void AssertNumberInBetween( uint subject, uint min, uint max, string msg ){ 58 | local string omsg; 59 | SPrintf(omsg, "%s was %d which isn't between %d and %d", msg, subject, min, max); 60 | NLAssert( subject >= min && subject <= max, EXSWarning(omsg)); 61 | }; -------------------------------------------------------------------------------- /scaffolds/Bits.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | /* 3 | We don't actually know what the main bank does / us. 4 | Here are some types relating to it, though. 5 | TODO: Find the main bank definition(s). 6 | */ 7 | 8 | /* 9 | list of would-be-nice-to-have-functions 10 | * FindFirstBitO[n|ff](From[Lef|Righ]t) 11 | * BiggestNumberForType 12 | * GetMaskForBits(ubyte d[]{0,1,1,0}) 13 | * FindLowestCommonMask(ubyte d[]) 14 | * BitWeld(uint64 a, uint64 b, int start=-1) //append bits from a in front of b (at first available bit) 15 | */ 16 | 17 | // from stackexchange or some crap 18 | int FlipIntBits(int theNumber, int numBits) { 19 | local int mask = 1; 20 | local int i; 21 | for(i = 1; i < numBits; ++i) 22 | mask |= mask << 1; 23 | 24 | return ~theNumber & mask; 25 | } 26 | 27 | // want your own byte array? check it out: 28 | // http://www.mathcs.emory.edu/~cheung/Courses/255/Syllabus/1-C-intro/bit-array.html 29 | 30 | typedef struct { 31 | byte bit1 : 1; 32 | byte bit2 : 1; 33 | byte bit3 : 1; 34 | byte bit4 : 1; 35 | 36 | byte bit5 : 1; 37 | byte bit6 : 1; 38 | byte bit7 : 1; 39 | byte bit8 : 1; 40 | } BitEight ; 41 | 42 | string BitEightRead(BitEight &be){ 43 | local string s; 44 | SPrintf(s, "%d %d %d %d, %d %d %d %d", be.bit1, be.bit2, be.bit3, be.bit4, be.bit5, be.bit6, be.bit7, be.bit8); 45 | return s; 46 | }; 47 | 48 | uint64 ReadUShortBits(uint64 pos, uint64 bitStart, uint64 readSize){ 49 | local ushort data = ReadUShort(pos); 50 | // we can't adjust the size or type of what we read, so we can hardcode the mask base 51 | // this sure beats writing a geometric function to read bits 52 | local ushort mask = 0xFFFF >> (sizeof(data)*8 - readSize); 53 | local ushort outvalue = (( data >> (sizeof(data)*8 - (readSize + bitStart)) ) & mask); 54 | return outvalue; 55 | } 56 | 57 | uint64 ReadUByteBits(uint64 pos, uint64 bitStart, uint64 readSize){ 58 | local ubyte data = ReadUByte(pos); 59 | // we can't adjust the size or type of what we read, so we can hardcode the mask base 60 | // this sure beats writing a geometric function to read bits 61 | local ubyte mask = 0xFF >> (sizeof(data)*8 - readSize); 62 | local ubyte outvalue = (( data >> (sizeof(data)*8 - (readSize + bitStart)) ) & mask); 63 | return outvalue; 64 | } -------------------------------------------------------------------------------- /scaffolds/Block.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | typedef struct Block( uint64 startPoint, uint64 blockRange){ 3 | local string thisName = "Block"; 4 | SIBE; 5 | 6 | SAVE; 7 | FSeek(startPoint); 8 | 9 | SIT; 10 | char block[ blockRange ]; 11 | REST; 12 | 13 | SIEND; 14 | }; -------------------------------------------------------------------------------- /scaffolds/Bucket.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | 3 | #define BUCKET_TYPE uint64 4 | #define BUCKET_SIZE 0xFFFF 5 | local BUCKET_TYPE __bucket[BUCKET_SIZE] = {0}; 6 | void ClearBucket(){ 7 | local uint64 i; 8 | for( i = 0; i < BUCKET_SIZE; i++ ){ 9 | __bucket[i] = 0; 10 | } 11 | } 12 | 13 | void Bucket(BUCKET_TYPE value){ 14 | __bucket[value] += 1; 15 | } 16 | 17 | // are you analyzing whether or not something is a bitfield? 18 | // use this: http://bitwisecmd.com/ 19 | // type in all the found numbers and visualize the bits 20 | // the following will automatically give you a url with 21 | // all unique values 22 | 23 | // a cheap way to increase the effectiveness of this sort 24 | // of analysis would be to comment out surrounding vars 25 | // and throw in some dummy ones bitfielded to the correct width 26 | // to narrow the scope of the variable you supply to Bucket() 27 | // e.g. 28 | 29 | /* 30 | ushort alignment1 : 3; 31 | ushort toBucket : 4; 32 | ushort alignment2 : 9; 33 | */ 34 | 35 | 36 | void ReportBucket(){ 37 | local uint64 i; 38 | local BUCKET_TYPE max_index = 0; 39 | local BUCKET_TYPE min_index = BUCKET_SIZE; 40 | local string bitwise = "http://bitwisecmd.com/#"; 41 | local string nbitwise = bitwise; 42 | for( i = 0; i < BUCKET_SIZE; i++){ 43 | if( __bucket[i] > 0 ){ 44 | //Printf("INDEX #%d: %d > 0\n", i, __bucket[]); 45 | if( i > max_index ){ 46 | max_index = i; 47 | } 48 | if( i < min_index ){ 49 | min_index = i; 50 | } 51 | } 52 | } 53 | // below is an experimental sort, it ruins everything because 54 | // I don't know how to retain key indexes 55 | /* 56 | local uint64 j; 57 | local BUCKET_TYPE a; 58 | local uint64 order[BUCKET_SIZE] = {0}; 59 | Printf("FUCK: %d\n", __bucket[0]); 60 | Printf("BUCKET: MIN/MAX = %d/%d\n", min_index, max_index); 61 | for (i = min_index; i <= max_index; i++){ 62 | for (j = i + 1; j <= max_index; j++){ 63 | if (__bucket[i] > __bucket[j]){ 64 | a = __bucket[i]; 65 | __bucket[i] = __bucket[j]; 66 | __bucket[j] = a; 67 | 68 | } else { 69 | order[i] = i; 70 | } 71 | } 72 | } 73 | for( i = 0; i <= BUCKET_SIZE; i++ ){ 74 | if( __bucket[order[i]] > 0 ){ 75 | Printf("BUCKET: VALUE 0x%04LX HAPPENED %d TIME(S)!\n", i, __bucket[order[i]]); 76 | } 77 | } 78 | */ 79 | for( i = min_index; i <= max_index; i++ ){ 80 | if( __bucket[i] > 0 ){ 81 | Printf("BUCKET: VALUE 0x%04LX HAPPENED %d TIME(S)!\n", i, __bucket[i]); 82 | SPrintf( nbitwise, "%s0x%04LX,", nbitwise, i); 83 | } 84 | } 85 | if( bitwise != nbitwise ){ 86 | Printf("%s\n", nbitwise); 87 | CopyStringToClipboard(bitwise); 88 | } 89 | } -------------------------------------------------------------------------------- /scaffolds/Colors.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // extra colors 3 | #define cOrange 0x00A5FF 4 | 5 | // color managers 6 | uint64 ColorTupToUInt(uint64 red, uint64 green, uint64 blue){ 7 | local uint64 color; 8 | local string dat; 9 | SPrintf(dat, "0x%02LX%02LX%02LX", blue, green, red); 10 | SScanf(dat, "0x%LX", color); 11 | return color; 12 | } 13 | 14 | // take a tup of colors and set the background 15 | void SetBackColorTup(uint64 red, uint64 green, uint64 blue){ 16 | SetBackColor( ColorTupToUInt(red, green, blue) ); 17 | } 18 | 19 | // set the background color and then 20 | // set the foreground to something readable 21 | void SetBackColorAuto(int color){ 22 | SetBackColor( color ); 23 | SetForeColor( ~color ); 24 | } 25 | 26 | // provide a float between 0 and 1 and get a color 27 | uint64 FloatToRainbowColor(float i){ 28 | local float r, g, b; 29 | if( i < 1.0/6.0 ){ 30 | r = 1.0; 31 | g = i*6.0; 32 | b = 0.0; 33 | } else if( i >= 1.0/6.0 && i < 2.0/6.0 ){ 34 | r = (1.0/6.0-(i-1.0/6.0))*6.0; 35 | g = 1.0; 36 | b = 0.0; 37 | } else if( i >= 2.0/6.0 && i < 3.0/6.0 ){ 38 | r = 0.0; 39 | g = 1.0; 40 | b = (i-2.0/6.0)*6.0; 41 | } else if( i >= 3.0/6.0 && i < 4.0/6.0 ){ 42 | r = 0.0; 43 | g = (1.0/6.0-(i-3.0/6.0))*6.0; 44 | b = 1.0; 45 | } else if( i >= 4.0/6.0 && i < 5.0/6.0 ){ 46 | r = (i-4.0/6.0)*6.0; 47 | g = 0.0; 48 | b = 1.0; 49 | } else { 50 | r = 1.0; 51 | g = 0.0; 52 | b = (1.0/6.0-(i-5.0/6.0))*6.0; 53 | } 54 | return ColorTupToUInt(r*255.0, g*255.0, b*255.0); 55 | } -------------------------------------------------------------------------------- /scaffolds/Jumps.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | /* 3 | Add some macros for getting back to where you were 4 | without caring where you were! 5 | */ 6 | 7 | local uint64 restoreDepth; 8 | local uint64 restorePoints[64]; 9 | #define SAVE { \ 10 | restoreDepth += 1; \ 11 | restorePoints[restoreDepth] = FTell(); 12 | 13 | #define REST FSeek( restorePoints[restoreDepth] ); \ 14 | restorePoints[restoreDepth] = 0; \ 15 | restoreDepth -= 1; \ 16 | } -------------------------------------------------------------------------------- /scaffolds/Padding.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // no macro functions 3 | #define CALIGN16 ColumnAlign(16) 4 | #define CALIGN12 ColumnAlign(12) 5 | #define CALIGN8 ColumnAlign(8) 6 | #define CALIGN4 ColumnAlign(4) 7 | 8 | typedef struct (uint64 place) { 9 | local string thisName = "ColumnAlign"; 10 | SIBE; 11 | 12 | local int64 size = place-(FTell() % 16); 13 | if( size < 0 ){ 14 | size = 16 + size; 15 | } 16 | 17 | SIT; 18 | ubyte zeroes[size]; 19 | AssertUBytesZero( 20 | zeroes, 21 | parentof(this).thisName + "->ColumnAlign" 22 | ); 23 | SIEND; 24 | } ColumnAlign; 25 | 26 | typedef struct { 27 | local string thisName = "NullEater"; 28 | SIBE; 29 | 30 | local uint64 size = 0; 31 | while( ReadUByte(FTell()+size) != 0 ){ 32 | size++; 33 | } 34 | 35 | SIT; 36 | ubyte zeroes[size]; 37 | // If this test ever fails, 38 | // call the cops. 39 | AssertUBytesZero( zeroes, "NullEater" ); 40 | 41 | SIEND; 42 | } NullEater; -------------------------------------------------------------------------------- /scaffolds/Significant.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | /* 3 | Add some macros for toggling background color banding 4 | to increase visibility. 5 | */ 6 | 7 | /* 8 | define a variable for the significant step-grade 9 | this impacts how frequently we see a new color 10 | and when the old one 11 | steps:1 steps:2 12 | 0/6 0/12+ 13 | 1/12 14 | 1/6 2/12-+ 15 | 3/12 16 | 2/6 4/12-+ 17 | 5/12 18 | 3/6 6/12-+ 19 | 7/12 20 | 4/6 8/12-+ 21 | 9/12 22 | 5/6 10/12-+ 23 | 11/12 24 | 6/6 12/12- 25 | */ 26 | local uint64 colorGrades = 4; // how many major denominations of color we got 27 | local uint64 colorSteps = 4; // how many color steps we have between said things 28 | 29 | local int64 gradePos = 0; // stays between 1 and colorGrades 30 | local int64 stepPos = 0; // stays between 1 and colorSteps 31 | 32 | local uint64 isSignificant = 0; 33 | 34 | void BeginSignificantStruct(){ 35 | gradePos += 1; 36 | gradePos = gradePos % colorGrades; 37 | stepPos = 0; 38 | // resetting stepPos makes similarly structured data the same color 39 | } 40 | 41 | void EndSignificantStruct(){ 42 | gradePos -= 1; 43 | gradePos = gradePos % colorGrades; 44 | stepPos = 0; 45 | } 46 | 47 | void ToggleSignificant(){ 48 | stepPos += 1; 49 | stepPos = stepPos % colorSteps; 50 | local float i = ((float)stepPos + (float)gradePos) / ((float)colorGrades*(float)colorSteps); 51 | //Printf("S: %d G: %d | I: %f \t", stepPos, gradePos, i); 52 | local uint64 newcolor = FloatToRainbowColor(i); 53 | //Printf("HAIL SATAN: 0x%06LX\n", newcolor); 54 | SetBackColor( newcolor ); 55 | } 56 | 57 | void TurnOnSignificant(){ 58 | isSignificant = 1; 59 | } 60 | 61 | void TurnOffSignificant(){ 62 | isSignificant = 0; 63 | } 64 | 65 | /* classic significant 66 | local int colorBeforeSignificant = cNone; 67 | local int isSignificant = 0; 68 | void TurnOnSignificant(){ 69 | isSignificant = 1; 70 | colorBeforeSignificant = GetBackColor(); 71 | SetBackColor( cLtGray ); 72 | ToggleSignificant(); 73 | } 74 | 75 | void TurnOffSignificant(){ 76 | isSignificant = 0; 77 | SetBackColor( colorBeforeSignificant ); 78 | } 79 | 80 | void ToggleSignificant(){ 81 | local int color; 82 | local int new; 83 | color = GetBackColor(); 84 | switch(color){ 85 | case cSilver: 86 | new = cLtGray; 87 | break; 88 | case cLtGray: 89 | new = cSilver; 90 | break; 91 | default: 92 | new = color; 93 | break; 94 | } 95 | SetBackColor( new ); 96 | } 97 | */ 98 | 99 | #define SION TurnOnSignificant() 100 | #define SIOFF TurnOffSignificant() 101 | #define SIT ToggleSignificant() 102 | #define SIBE BeginSignificantStruct() 103 | #define SIEND EndSignificantStruct() -------------------------------------------------------------------------------- /scaffolds/Unknown.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | /* 3 | Make note of an unknown variable in style. 4 | */ 5 | void Unknown(string context){ 6 | local string msg; 7 | SPrintf(msg, "UNKNOWN: @%LXh %s\n", FTell(), context); 8 | Printf(msg); 9 | } 10 | 11 | void AlertUnknownData(){ 12 | // @todo: Set the background color here and have SIT undo it. 13 | Printf("UNKNOWN: @%LXh\n", FTell()); 14 | } 15 | void NOP(){}; 16 | #define UNK NOP() -------------------------------------------------------------------------------- /scripts/CurPosInDec.1sc: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | //--- 010 Editor v6.0.3 Script File 3 | // 4 | // File: 5 | // Author: 6 | // Revision: 7 | // Purpose: 8 | //-------------------------------------- 9 | local string s; 10 | SPrintf(s, "%d", GetCursorPos()); 11 | CopyStringToClipboard(s); -------------------------------------------------------------------------------- /scripts/CurPosInHex.1sc: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | //--- 010 Editor v6.0.3 Script File 3 | // 4 | // File: 5 | // Author: 6 | // Revision: 7 | // Purpose: 8 | //-------------------------------------- 9 | local string s; 10 | SPrintf(s, "0x%08LX", GetCursorPos()); 11 | CopyStringToClipboard(s); -------------------------------------------------------------------------------- /scripts/DumpAllYaz.1sc: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | //--- 010 Editor v6.0.3 Script File 3 | // 4 | // File: DumpAllYaz 5 | // Author: EntranceJew 6 | // Revision: 1.0 7 | // Purpose: Dump all Yaz archives from a ROM where they are all named "arc". 8 | //-------------------------------------- 9 | 10 | local string wheredump = InputDirectory( "Where to dump these files?" ); 11 | local uint64 startFile = GetFileNum(); 12 | local string dirToMake; 13 | local string fileToWrite; 14 | local uint64 ui = 0; 15 | local uint64 fi = 0; 16 | local uint64 thisFile = 0; 17 | local uint64 writePos = 0; 18 | local uint64 sizeToWrite = 0; 19 | local int didMakeDir; 20 | local ubyte dst[0xFFFF]; // hail satan 21 | local int writeStatus = 0; 22 | while( exists(arc[ui]) ){ 23 | SPrintf(dirToMake, "%d_0x%08LX", ui, startof(arc[ui])); 24 | Assert( 25 | MakeDir(wheredump + "/" + dirToMake), 26 | "Could not make dir." 27 | ); 28 | 29 | fi = 0; 30 | while( exists(arc[ui].file[fi]) ){ 31 | SPrintf(fileToWrite, "%d_0x%08LX.bin", fi, startof(arc[ui].file[fi])); 32 | 33 | sizeToWrite = arc[ui].file[fi].uncompressedSize; 34 | 35 | Assert( sizeToWrite <= 0xFFFF, "write is bigger than our buffer"); 36 | 37 | writePos = 0; 38 | while( exists(arc[ui].file[fi].dst[writePos]) ){ 39 | dst[writePos] = arc[ui].file[fi].dst[writePos]; 40 | writePos++; 41 | } 42 | thisFile = FileNew("Hex", true); 43 | WriteBytes(dst, 0, sizeToWrite); 44 | writeStatus = FileSave(wheredump + "/" + dirToMake + "/" + fileToWrite); 45 | 46 | Assert( 47 | writeStatus >= 0, 48 | "Could not write file." 49 | ); 50 | FileClose(); 51 | FileSelect(startFile); 52 | 53 | fi++; 54 | } 55 | ui++; 56 | } 57 | FileSelect(startFile); -------------------------------------------------------------------------------- /scripts/FixSaveMM.1sc: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | BigEndian(); 3 | 4 | local uint checksum_offset = 0x100A; 5 | void update_checksum( uint start, int owl ) 6 | { 7 | local uint16 checksum = 0; 8 | local uint pos; 9 | for( pos = start; pos < start + checksum_offset; pos++ ) { 10 | checksum += (ubyte) ReadByte( pos ); 11 | } 12 | if( owl ) { 13 | checksum += 0x24; 14 | } 15 | WriteShort( pos, checksum ); 16 | } 17 | 18 | void copy_save( uint from, uint to, int owl ) 19 | { 20 | local uint size = owl ? 0x4000 : 0x2000; 21 | local ubyte buffer[size]; 22 | ReadBytes( buffer, from, size ); 23 | WriteBytes( buffer, to, size ); 24 | } 25 | 26 | update_checksum( 0x00000, 0 ); 27 | update_checksum( 0x04000, 0 ); 28 | update_checksum( 0x08000, 1 ); 29 | update_checksum( 0x10000, 1 ); 30 | 31 | copy_save( 0x00000, 0x02000, 0 ); 32 | copy_save( 0x04000, 0x06000, 0 ); 33 | copy_save( 0x08000, 0x0C000, 1 ); 34 | copy_save( 0x10000, 0x14000, 1 ); 35 | -------------------------------------------------------------------------------- /scripts/FixSaveOoT.1sc: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | BigEndian(); 3 | 4 | local uint checksum_offset = 0x1352; 5 | void update_checksum( uint start ) 6 | { 7 | local uint16 checksum = 0; 8 | local uint pos; 9 | for( pos = start; pos < start + checksum_offset; pos += 2 ) { 10 | checksum += (uint16) ReadShort( pos ); 11 | } 12 | WriteShort( pos, checksum ); 13 | } 14 | 15 | void copy_save( uint from, uint to ) 16 | { 17 | local uint size = 0x1450; 18 | local ubyte buffer[size]; 19 | ReadBytes( buffer, from, size ); 20 | WriteBytes( buffer, to, size ); 21 | } 22 | 23 | update_checksum( 0x0020 ); 24 | update_checksum( 0x1470 ); 25 | update_checksum( 0x28C0 ); 26 | 27 | copy_save( 0x0020, 0x3D10 ); 28 | copy_save( 0x1470, 0x5160 ); 29 | copy_save( 0x28C0, 0x65B0 ); 30 | -------------------------------------------------------------------------------- /skeleton.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | FSeek( 0 ); 3 | N64ROMHead romHeader; 4 | 5 | #ifdef VFS 6 | FSeek( VFS ); 7 | ZFileSystemTable vfsTable; 8 | #endif 9 | 10 | #ifdef ACTORSTABLE 11 | #ifdef NUMACTORS 12 | FSeek( ACTORSTABLE ); 13 | struct { 14 | ZActorTableEntry actorsTable[NUMACTORS]; 15 | } AllTheseActors; 16 | #endif 17 | #endif 18 | 19 | #ifdef OBJECTSTABLE 20 | FSeek( OBJECTSTABLE ); 21 | ZObjectTable objectTable; 22 | #endif 23 | 24 | #ifdef SCENETABLE 25 | #ifdef NUMSCENES 26 | FSeek( SCENETABLE ); 27 | struct { 28 | SceneTableEntry sceneTable[113]; 29 | SceneTableEntry sceneTable[NUMSCENES]; 30 | } AllTheseScenes; 31 | #endif 32 | #endif 33 | 34 | #ifdef EXITTABLE 35 | #ifdef NUMEXITS 36 | FSeek( EXITTABLE ); 37 | struct { 38 | ZExitTable exitTable[NUMEXITS]; 39 | } AllTheseExits; 40 | #endif 41 | #endif 42 | 43 | #ifdef SAMPLES 44 | FSeek( SAMPLES ); 45 | SampleTable sampleTable; 46 | #endif 47 | 48 | #ifdef INSTRUMENT 49 | FSeek( INSTRUMENT ); 50 | InstrumentSetTable instrumentSetTable; 51 | #endif 52 | 53 | #ifdef SEQTABLE 54 | FSeek( SEQTABLE ); 55 | SequenceTable sequenceTable; 56 | #endif 57 | 58 | #ifdef LINKANIMTABLE 59 | #ifdef LINKANIMFILE 60 | #ifdef NUMLINKANIMATIONS 61 | FSeek( LINKANIMTABLE ); 62 | struct { 63 | LinkAnimationHeader link_animetion[ NUMLINKANIMATIONS ]; 64 | } AllLinkAnimations; 65 | #endif 66 | #endif 67 | #endif -------------------------------------------------------------------------------- /templates/dMM_E_debug-save.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // main identifiers 3 | #define GAME "MM" 4 | #define REGION "E" 5 | #define VIDEO "PAL" 6 | #define DEFLATE 1 7 | #define DEBUG 1 8 | 9 | #define KNOWN SetBackColor(0x62A132) // Green 10 | #define UNKNOWN SetBackColor(0x7DE3FF) // Yellow 11 | #define UNUSED SetBackColor(0xA265B8) // Purple 12 | 13 | #include "autoload.bt" 14 | 15 | struct { 16 | ZSave saveData[2]; 17 | ZSaveOwl saveData[2]; 18 | ZSaveDataFooter saveDataFooter; 19 | } Save; -------------------------------------------------------------------------------- /templates/dMM_E_debug.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // main identifiers 3 | #define GAME "MM" 4 | #define REGION "E" 5 | #define VIDEO "PAL" 6 | #define DEFLATE 1 7 | #define DEBUG 1 8 | 9 | // very significant identifiers that cannot 10 | // be determined dynamically from the rom data yet 11 | #define VFS 0x00024F60 12 | #define AUDIOBANK 0x0002B2D0 13 | #define AUDIOSEQ 0x000516C0 14 | #define AUDIOTABLE 0x000A2B40 15 | #define ATBL_END 0x005EB2B0 16 | #define LINKANIMFILE 0x005EB2B0 17 | #define MSG_1_START 0x00AB0000 18 | #define MSG_1 0x00C71000 19 | #define MSG_2 0x00C7A000 20 | #define MSG_3 0x00C83000 21 | #define MSG_4 0x00C8C000 22 | 23 | #define CODEFILE 0x00C95000 24 | // unk 25 | #define ACTORSTABLE 0x00DD5A50 26 | // unk 27 | #define ACTIONSTRINGS 0x00DDB22C 28 | // unk 29 | #define OBJECTSTABLE 0x00DE9D48 30 | // unk 31 | #define SCENETABLE 0x00DEB2B0 32 | #define SCENELOOKUP 0x00DEB9C0 33 | // unk 34 | #define EXITTABLE 0x00DECD38 35 | // unk 36 | #define CREDITSTABLE 0x00DEEE28 37 | // unk 38 | #define OBJNAMES 0x00DFE500 39 | // unk 40 | #define SCENENAMES 0x00E05840 41 | // unk 42 | 43 | #define INSTRUMENT 0x00E0F7E0 44 | 45 | #define SEQTABLE 0x00E0FC90 46 | 47 | #define SAMPLES 0x00E104A0 48 | 49 | #define CODEFILEEND 0x00E12600 50 | 51 | #define LINKANIMTABLE 0x0128EF40 52 | 53 | // quantities of things 54 | #define NUMVFSITEMS 1591 55 | #define NUMACTORS 691 56 | #define NUMSCENES 113 57 | #define NUMEXITS 110 58 | #define NUMLINKANIMATIONS 695 59 | 60 | // helpers & known types 61 | #include "autoload.bt" 62 | 63 | // import the ROM structure 64 | #include "skeleton.bt" 65 | 66 | //FSeek(0x00DD5A50); 67 | 68 | FSeek(0x00E80DF0); 69 | En_GirlA en_girla(0x22D0); 70 | // 71 | //ZShopData boners; 72 | 73 | FSeek(MSG_1); 74 | ZMessageTable nes_message_static(MSG_1_START); 75 | 76 | FSeek(0x00E82540); 77 | Ram honk; 78 | 79 | 80 | /* 81 | // the following code walks the number of scenes 82 | // maps some things 83 | // but it skips a lot of details 84 | typedef struct { 85 | string sceneName; 86 | } SceneName; 87 | 88 | local uint64 x = 0; 89 | local uint64 y = 0; 90 | local byte scene = 0; 91 | for( y = 0; y < 110; y++ ){ 92 | FSeek(EXITTABLE+5+12*y); 93 | int pointerD : 24; 94 | FSeek(FTell()+1); 95 | int namePointerD : 24; 96 | if( pointerD > 0 ){ 97 | FSeek(namePointerD+EXITBOUNCEHACK); 98 | SceneName sceneName; 99 | //Printf("%s @ 0x%08LX\n", sceneName.sceneName, namePointerD+EXITBOUNCEHACK); 100 | FSeek(pointerD+1+EXITBOUNCEHACK); 101 | int pointerD2 : 24; 102 | FSeek(pointerD2+EXITBOUNCEHACK); 103 | ubyte _scene; 104 | if(_scene>127){ 105 | //Printf("sceen should be negative\n"); 106 | scene = 256-_scene; 107 | } else { 108 | scene = _scene; 109 | } 110 | FSeek(SCENETABLE+16*scene); 111 | uint pointerD3; 112 | uint namePointerD3; 113 | if(IsValidFile(pointerD3)){ 114 | Printf("%08LX %08LX %-20s %02LX\n",pointerD3,namePointerD3,sceneName.sceneName,scene); 115 | } 116 | } 117 | } 118 | */ 119 | 120 | FSeek(03066000h); 121 | ZScene clocktower; 122 | 123 | FSeek(0213B000h); 124 | ZScene Z2_20SICHITAI2; 125 | 126 | FSeek(0219E000h); 127 | ZScene Z2_LAST_BS; 128 | 129 | FSeek(021AF000h); 130 | ZScene Z2_HAKASHITA; 131 | // colorize everything we want to peep 132 | SetBackColor(cOrange); 133 | FSeek(0x01F1F000); 134 | ubyte paint[0x01F2A510-0x01F1F000]; 135 | 136 | // the mayor 137 | FSeek(0x01F1F000); 138 | //FSeek(0x01F1F000 + ); 139 | 140 | ubyte imTheMayor; 141 | 142 | FSeek(0x01F25928); // last display list before a texture 143 | 144 | 145 | DisplayListScanner displayScan; 146 | 147 | 148 | FSeek(0x01F2A510); 149 | ubyte notTheMayor; 150 | ReportBucket(); 151 | //ClearBucket(); -------------------------------------------------------------------------------- /templates/dOoTMQ_E_debug.bt: -------------------------------------------------------------------------------- 1 | // -*- mode: c;-*- 2 | // main identifiers 3 | #define GAME "OoTMQ" 4 | #define REGION "E" 5 | #define VIDEO "PAL" 6 | #define DEFLATE 1 7 | #define DEBUG 1 8 | 9 | // very significant identifiers that cannot 10 | // be determined dynamically from the rom data yet 11 | #define VFS 0x00012F70 12 | #define AUDIOBANK 0x00019030 13 | #define AUDIOSEQ 0x00044DF0 14 | #define AUDIOTABLE 0x00094870 15 | #define ATBL_END 0x004E5C00 16 | #define LINKANIMFILE 0x004E5C00 17 | #define CODEFILE 0x00A94000 18 | #define ACTORSTABLE 0x00B8D440 19 | #define ENTRANCETABLE 0x00B9F360 20 | #define SCENETABLE 0x00BA0BB0 21 | #define INSTRUMENT 0x00BCC270 22 | #define SEQTABLE 0x00BCC6A0 23 | #define SAMPLES 0x00BCCD90 24 | #define CODEFILEEND 0x00BCEF30 25 | #define LINKANIMTABLE 0x00F60310 26 | 27 | // quantities of things 28 | #define NUMACTORS 471 29 | #define NUMSCENES 331 30 | #define NUMLINKANIMATIONS 573 31 | 32 | // helpers & known types 33 | #include "autoload.bt" 34 | 35 | // import the ROM structure 36 | #include "skeleton.bt" 37 | 38 | /* 39 | FSeek(0x032DD000); 40 | ZScene child_temple_thing; 41 | 42 | FSeek(0x02D07000); 43 | ZScene back_alley_day; 44 | */ 45 | 46 | FSeek(0x00D98298); 47 | ZDamageChart guay_or_crow; 48 | 49 | FSeek(0x00ED1494); 50 | ZDamageChart tektite; 51 | 52 | FSeek(0x00EA0960); 53 | ZDamageChart likelike; 54 | 55 | FSeek(0x00B8FBC0); 56 | ZActorTableEntry hotdog; 57 | DumpZActorTableEntry(hotdog); 58 | 59 | FSeek(0x01727000); 60 | ubyte object_ane[0x0172DFB0-0x01727000]; 61 | local uint64 object_start = 0x01727000; 62 | 63 | FSeek(object_start); 64 | // dissecting object here 65 | 66 | typedef struct { 67 | SIBE; 68 | 69 | SIT; 70 | ZBankPointer p; 71 | 72 | SIT; 73 | SAVE; 74 | FSeek( object_start + p.offset ); 75 | ubyte wedge; 76 | REST; 77 | 78 | SIEND; 79 | } PBounce; 80 | 81 | SIT; 82 | ubyte ane_start; 83 | 84 | FSkip(7); 85 | PBounce selfpoint; 86 | 87 | FSeek(startof(object_ane) + sizeof(object_ane)); 88 | SIT; 89 | ubyte ane_done; 90 | 91 | FSeek(0x00E6FCB0); 92 | MIPS_CodeScanner hank; 93 | 94 | 95 | // vram start: 0x80AB9C40 96 | // vram end: 0x80ABBA50 97 | // vram instance start: 0x80ABB380 98 | // vrom filename: 0x80137E1C 99 | 100 | //FSeek(0x00DF1330); 101 | //En_GirlA en_girla(0x00DF42C0-0x00DF1330); 102 | 103 | 104 | // Overlay files need to know their end so they can 105 | // find where their footer starts. 106 | //FSeek(0x00C27940); 107 | //OvlMapMarkData ovl_map_mark_data(0x00C2E420 - FTell()); 108 | // import the ROM structure 109 | 110 | 111 | // test hex this is the first quicksand tile in spot13 112 | // 0x29fa394 113 | 114 | // test hex this is the first quad that triggers a fadeaway 115 | // transition in spot13 116 | // 0x29fa314 117 | 118 | // test hex this is the largest quad to the left on 119 | // the platform to the hippie 120 | // 0x29fa294 121 | 122 | //FSeek(29FA000h); 123 | //ZScene spot13; 124 | 125 | //FSeek(44040192); 126 | //ZRoom spot13_room1; 127 | 128 | //FSeek(44044288); 129 | //ZRoom spot13_room2; 130 | 131 | // sample of polyType from inside jabu jabu's belly: 132 | // 00 01 00 00 00 00 30 03 133 | 134 | // sample of polyType from desert sandpit with jabu flag? 135 | // 30 01 80 04 00 00 0F C1 136 | 137 | // sample of other, nearby sand that doesn't do that 138 | // 00 00 E0 04 05 4C 0F C1 139 | 140 | // sample of water temple that is steep and slopey 141 | // 24 00 00 03 00 00 B8 12 142 | 143 | //FSeek(0x230B000); 144 | //ZScene the_entire_water_temple; -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | # To Do 2 | A handy file that lists everything that must be done, ever. 3 | 4 | # Things To Not Do 5 | * Write general goals that are guidelines that don't list everything that needs to be addressed. 6 | 7 | # Best Ideas 8 | * Import datasources from the spreadsheet into a data folder that can be processed into 9 | template parts, lookups for names and comments, and externally useful data (wiki modules). 10 | 11 | # Scaffolds 12 | * [Trace.bt](/scaffolds/Trace.bt) 13 | * Consume `thisName` and generate a stack using arrays-of-strings. 14 | * Track depth, variable number, starts ends and sizes. 15 | * These need to be made use of by [Anomaly.bt](/scaffolds/Anomaly.bt) and [Assert.bt](/scaffolds/Assert.bt). 16 | * [Unknown.bt](/scaffolds/Unknown.bt) 17 | * Make use of the thisName convention for traces, same as asserts/warns. 18 | * Work with the SIBE/SIEND/SIT for UNK to auto-provide unknown variable names. 19 | * Use the distance between a SIT and an UNK to estimate coverage automatically. 20 | 21 | # Templates 22 | * [all bootstraps](/templates/) 23 | * Make it so that there's RAM/ROM definition pairs for bootstrap headers. 24 | * [SaveParts.bt](/filetypes/Save/SaveParts.bt) 25 | * Some parts are usable in both RAM/ROM. 26 | * Find where to put these logically. 27 | * Change their names to something more general. 28 | * Wrap these with `#ifdef`s. 29 | * 30 | * [dOoT_E_debug-save.bt](/templates/dOoT_E_debug-save.bt) 31 | * Split the structs in here with defchecks for game type. 32 | * 33 | * [Yaz.bt](/filetypes/Compressed/Yaz.bt) 34 | * Could use some fixing up, using bit reads instead of its current logic. 35 | * [N64ROMHead.bt](/filetypes/N64ROMHead.bt) 36 | * Finish this, mark it up, use the endianess flag in the template. 37 | * Write a script to correct the CRCs. 38 | * [Actor.bt](/filetypes/Overlay/Actor.bt) 39 | * Finish resolving the logic for relocation pointers. (1/4) 40 | * [Overlay/Files](/filetypes/Overlay/Files/) 41 | * Locate more pure-data structures and write templates for them. 42 | * [Texture](/filetypes/Texture/) 43 | * Bring up to speed with standards for struct metadata. 44 | * Add a flag somewhere to enable/disable variable colorization. 45 | * Correct JFIF image coloration code (either very wrong or too big to decipher). 46 | * Scanners Patterns 47 | * Examples: 48 | * [Scene](/filetypes/Scene/) (3/32) 49 | * Vet good data, nuke bad data. 50 | * [DisplayList](/filetypes/DisplayList/) (2/256) 51 | * [MIPS](/filetypes/MIPS/) (2/512) 52 | * [NIFF](/filetypes/NIFF/) (6/20) 53 | * Write objects for the many remaining commands. 54 | * Correct the scanner / enums accordingly. 55 | 56 | # Scripts 57 | * Write a handy macro for comparing two like structures using [science](http://www.sweetscape.com/010editor/manual/FuncTools.htm#Compare). 58 | * Make a flag/#define for setting bookmarks in the file. 59 | * Write a macro to report which VFS file the cursor is currently inside. 60 | * Make it so that SIBE / SIEND add "thisName" to a debug stack. 61 | * Make assert functions utilize this behavior / standard. 62 | * [DumpAllYaz.1sc](/scripts/DumpAllYaz.1sc) 63 | * Make a general Export method for Yaz files and not just archives of them. 64 | * Write helpers for SAVE/RESTing the current file and potentially preserving template vars. 65 | * Use Memcpy instead of iteration. 66 | 67 | # Find Data 68 | * Scrounge around for source code from other tools, particularly files of type .cs, .h, or .py -- I don't want to reverse a source-less tool unless I'm absolutely stumped. 69 | * Cross-reference checkums and junk with places like No-Intro, GoodN64, MAME's N64 softwarelist. --------------------------------------------------------------------------------