diff --git a/README.md b/README.md index 2c6e305..31a2607 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# cave-story-randomizer +Cave Story Randomizer +===================== diff --git a/docs/csresearch.txt b/docs/csresearch.txt new file mode 100644 index 0000000..7d0f603 --- /dev/null +++ b/docs/csresearch.txt @@ -0,0 +1,666 @@ +-=~ Cave Story Research Compendium ~=- + +-=~ A guide to Cave Story's file formats and important hacks for those who are interested ~=- +by F_Deity_Link, using research by others as well +Made it for myself to learn as well as because the file formats and important hacks weren't all 'published' + (actually they're in miza.chm, included with the Miza editor, but I hadn't realized this when I started), + and I figured a centralized document with all of it would be helpful + +Last updated 2017-02-06 + +Note that some info might be incorrect - SP's guides are a bit old - feel free to tell me of anything that could be updated + +-=~ Credits ~=- +Big thanks to all the people I got much of this research from! + - Carrotlord for TSC file format + - q3hardcore for (C)Pixel requirement removal + - S.P. Gardebiter for PXA values + EXE mapdata format + npc.tbl format + - dooey100 for flag setting, unsetting, and checking + - Noxid for Booster's Lab, which helped for seeing how edits affected the files, as well as getting newest info + - especially tilesets and sounds in npc.tbl + +-=~ TSC File Format ~=- + Encoding char is the middle character in file: char at floor (file size / 2) + ex: size of 313 bytes, encode char is at 156th byte + + Newlines are Windows-style newlines ("\r\n"): 0x0D + encode char val, then 0x0A + encode char val + - Because they're Windows-style newlines, open your files in binary mode, not text, otherwise the following transformations are done, which will end up corrupting the file + - "\r\n" --> '\n' for input + - '\n' --> "\r\n" for output + + All characters in the file except for the encoding char itself (so other copies of the character are still encoded) have the value of the encoding char added to them when saved + ex: encoding char = [space]: only that instance of the [space] character will not be encoded, but the others will + + When reading a TSC file, subtract the encoding character from each character (except the encoding char itself, as noted above) to properly decode the file + When writing a TSC file, add the encoding character to each character (except the encoding char itself, as noted above) to properly encode the file + +-=~ Removing (C)Pixel Requirement ~=- + 0x1136C: 0x74 --> 0xEB + 0x8C4D8: 0x28 --> 0x00 + + Then in every .pbm, find the (C)Pixel at the end and change the '(' to the null character (0x00) + +-=~ Allowing bitmaps ~=- + 0x8C286 through 8 and 0x0008C30A through C: 0x70, 0x62, and 0x6D --> 0x62, 0x6D, and 0x70 + 0x8C32E and F: 0x70 and 0x62 --> 0x62 and 0x6D + 0x8C330: 0x6D --> 0x70 + +-=~ npc.tbl Format ~=- + Cave Story has 361 entities (0x169) from 0 - 360 + npc.tbl has 11 sets of data, the starting addresses of which are all multiples of 0x169: + 0x0000: Flags - 2 Bytes + 0x02D2: Health - 2 Bytes + 0x05A4: Tileset Number - 1 Byte + 0x070D: Death Sound - 1 Byte + 0x0876: Hurt Sound - 1 Byte + 0x09DF: Death Smoke - 1 Byte + 0x0B48: Experience - 4 Bytes + 0x10EC: Damage - 4 Bytes + 0x1690: Collsion Bounding Box - 4 Bytes + 0x1C34: Display Bounding Box - 4 Bytes + + -=~ Flags ~=- + -=~ Byte 1 ~=- + 0x01: Solid + 0x02: No effect about Tile 44 + 0x04: Invulnerable (Blink Sound) + 0x08: Ignore solid + 0x10: Bouncing at top + 0x20: Shootable + 0x40: Special Solid + 0x80: Rear and top no damage + + -=~ Byte 2 ~=- + 0x01: Call Event on Contact + 0x02: Call Event on Death + 0x04: Drop Hearts and EXP [Unused] + 0x08: Visible if FlagID is set + 0x10: Spawn with Alternate Direction + 0x20: Call Event on Interaction + 0x40: Invisible if FlagID is set + 0x80: Show Damage Numbers ?"Interactable" in Booster's Lab + + Setting Flags: Flag to set OR current flags + Unsetting Flags: (Flag to unset XOR 1111 1111) AND current flags + Checking Flags: Flag to check AND current flags - returns flag being checked if it is set, 0 if not set + + -=~ Tilesets ~=- + 0x00: title.pbm + 0x01: '2004.12 Studio Pixel' + 0x02: Current map tileset + 0x03: [Unused] + 0x04: [Unused] + 0x05: [Unused] + 0x06: Fade.pbm + 0x07: [Unused] + 0x08: ItemImage.pbm + 0x09: Map System Buffer + 0x0A: Screen Buffer + 0x0B: Arms.pbm + 0x0C: ArmsImage.pbm + 0x0D: MNA Text Buffer + 0x0E: StageImage.pbm + 0x0F: Loading.pbm + 0x10: MyChar.pbm + 0x11: Bullet.pbm + 0x12: [Unused] + 0x13: Caret.pbm + 0x14: Npc/NpcSym.pbm + 0x15: Map NPC Set 1 + 0x16: Map NPC Set 2 + 0x17: Npc/NpcRegu.pbm + 0x18: [Unused] + 0x19: [Unused] + 0x1A: TextBox.pbm + 0x1B: Face.pbm + 0x1C: Current Map BG + 0x1D: Damage # Buffer + 0x1E: Textbox Buffer 1 + 0x1F: Textbox Buffer 2 + 0x20: Textbox Buffer 3 + 0x21: [???] + 0x22: [Unused] + 0x23: Credits Buffer 1 + 0x24: Credits Buffer 2 + 0x25: Credits Buffer 3 + 0x26: [Unused] + 0x27: [Unused] + + -=~ Hurt / Death Sounds ~=- + 0x00: [Nothing] + 0x01: Blip + 0x02: Message Typing + 0x03: Bonk + 0x04: Weapon Switching + 0x05: Menu Prompt? + 0x06: Critter hop + 0x07: Silent? + 0x08: Low charge sound + 0x09: [Nothing?] + 0x0A: [Nothing?] + 0x0B: Door + 0x0C: Block Destroy + 0x0D: [Nothing?] + 0x0E: Get EXP + 0x0F: Quote Jump + 0x10: Taking Damage + 0x11: Death + 0x12: [Menu?] + 0x13: [Nothing?] + 0x14: Health/Ammo Refill + 0x15: Bubble + 0x16: Chest open + 0x17: Thud + 0x18: Walking + 0x19: Enemy killed? + 0x1A: Quake + 0x1B: Level up + 0x1C: Shot hit + 0x1D: Teleport + 0x1E: Critter jump + 0x1F: Ting + 0x20: Polar Star lvl + 0x21: Fireball + 0x22: Fireball bounce + 0x23: Explosion + 0x24: [Nothing?] + 0x25: No Ammo + 0x26: Get item? + 0x27: [*bvng*] Em fire? - taken from BL, what is em? + 0x28: Water + 0x29: Water + 0x2A: Get Missile [Beep] + 0x2B: Computer [Beep] + 0x2C: Missile Hit + 0x2D: EXP Bounce + 0x2E: Ironhead Shot + 0x2F: Explosion 2? + 0x30: Bubble pop + 0x31: Spur lvl 1 + 0x32: Sqeek! + 0x33: Squeal! + 0x34: Roar + 0x35: Eyoww + 0x36: Thud + 0x37: Squeek + 0x38: Splash + 0x39: Little damage sound + 0x3A: [*chik*] + 0x3B: Spur Charge (lowest) + 0x3C: Spur Charge (lower) + 0x3D: Spur Charge (higher) + 0x3E: Spur lvl 2 + 0x3F: Spur lvl 3 + 0x40: Spur MAX + 0x41: Spur full? + 0x42: [Nothing?] + 0x43: [Nothing?] + 0x44: [Nothing?] + 0x45: [Nothing?] + 0x46: Tiny Explosion + 0x47: Medium Explosion + 0x48: Large Explosion + 0x49: [Nothing?] + 0x4A: [Nothing?] + 0x4B: [Nothing?] + 0x4C: [Nothing?] + 0x4D: [Nothing?] + 0x4E: [Nothing?] + 0x4F: [Nothing?] + 0x50: [Nothing?] + 0x51: [Nothing?] + 0x52: [Nothing?] + 0x53: [Nothing?] + 0x54: [Nothing?] + 0x55: [Nothing?] + 0x56: [Nothing?] + 0x57: [Nothing?] + 0x58: [Nothing?] + 0x59: [Nothing?] + 0x5A: [Nothing?] + 0x5B: [Nothing?] + 0x5C: [Nothing?] + 0x5D: [Nothing?] + 0x5E: [Nothing?] + 0x5F: [Nothing?] + 0x60: [Nothing?] + 0x61: [Nothing?] + 0x62: [Nothing?] + 0x63: [Nothing?] + 0x64: Bubbler lvl 3 + 0x65: Lightning + 0x66: Sandcroc Bite + 0x67: Curly Charge + 0x68: Hit Invisible Block + 0x69: Puppy Bark + 0x6A: Blade whoosh + 0x6B: Block Move + 0x6C: Power Critter Jump + 0x6D: Critter Fly + 0x6E: Power Critter Fly + 0x6F: Thud + 0x70: Bigger thud + 0x71: [*pshew*] Helicopter? + 0x72: Core hurt + 0x73: Core thrust + 0x74: Core super charge + 0x75: Nemesis? + 0x76: [Nothing?] + 0x77: [Nothing?] + 0x78: [Nothing?] + 0x79: [Nothing?] + 0x7A: [Nothing?] + 0x7B: [Nothing?] + 0x7C: [Nothing?] + 0x7D: [Nothing?] + 0x7E: [Nothing?] + 0x7F: [Nothing?] + 0x80: [Nothing?] + 0x81: [Nothing?] + 0x82: [Nothing?] + 0x83: [Nothing?] + 0x84: [Nothing?] + 0x85: [Nothing?] + 0x86: [Nothing?] + 0x87: [Nothing?] + 0x88: [Nothing?] + 0x89: [Nothing?] + 0x90: [Nothing?] + 0x91: [Nothing?] + 0x92: [Nothing?] + 0x93: [Nothing?] + 0x94: [Nothing?] + 0x95: [Nothing?] + 0x96: BASS01 + 0x97: SNARE01 + 0x98: HICLOSE + 0x99: HIOPEN + 0x9A: TOM01 + 0x9B: PER01 + + -=~ Smoke ~=- + 0x01: None + 0x02: Small amount + 0x03: Medium amount + 0x04: Large amount + + -=~ Bounding Box Addresses ~=- + (from beginning of each portion) + 0x00: Left + 0x01: Top + 0x02: Right + 0x03: Bottom + +-=~ Map Formats ~=- + + -=~ Mapdata Addresses ~=- + (for freeware and stage.tbl(CS+)) + (from the beginning of each map section) + 0x00: Tileset name + 0x20: Filename + 0x40: Background Scrolling Type + 0x44: Background Name + 0x64: NPC Spritesheet 1 + 0x84: NPC Spritesheet 2 + 0xA4: Major Boss + 0xA5: Mapname + + -=~ Background Scrolling Types ~=- + 0x00: No Scrolling + 0x01: Slow Scrolling + 0x02: Equal Scrolling + 0x03: Water-Style + 0x04: Null + 0x05: Auto Scrolling + 0x06: Cloud-Style [Gravity: Left] + 0x07: Cloud-Style [Gravity: Normal] + + -=~ Major Bosses are as follows ~=- + 0x00: No Major Boss + 0x01: Omega + 0x02: Balfrog + 0x03: Monster X + 0x04: The Core + 0x05: Iron Head + 0x06: Dragon Sisters + 0x07: Undead Core + 0x08: Heavy Press + 0x09: Ballos + + + WINDOWS IS LITTLE-ENDIAN AND ALL DATA (with the exception of PXM map tile and PXE entity count) TAKES UP TWO BYTES + ex: x coord of 256 (dec) is 0x0100, seen as 00 01 in hex editor + + -=~ PXM File Data ~=- + maps must be minimum of 21x16 + + First three bytes are PXM, then 0x10 + + Then 0x_map_length - 2 bytes + Then 0x_map_height - 2 bytes + + Then 0x_map_tile_from_tileset for the rest of the file (numbered from 0, and going left to right, top to bottom) - 1 byte + + -=~ PXE File Data ~=- + First three bytes are PXE, then 0x00 + + Then 0x_entity_count - 4 bytes + + Then each entity takes up 12 bytes, and they are in order based on their draw order (higher drawn on top) - lowest in file first: + 0x_x_coord - 2 bytes + 0x_y_coord - 2 bytes + + 0x_flag_num - 2 bytes + 0x_event_num - 2 bytes + + 0x_entity_type - 2 bytes + 0x_entity_flags - 2 bytes + + -=~ Flags ~=- + Setting: Flag to set OR current flags + Unsetting: (Flag to unset XOR 1111 1111) AND current flags + Checking: Flag to check AND current flags - returns flag being checked if it is set, 0 if not set + + -=~ PXA File Data ~=- + Format is tile type, corresponds to tileset directly - file has no header + Tilesets can be 16x16 tiles max, so PXA has 256 bytes, value of 0 for tiles not in tileset image + + -=~ Tile Types ~=- + + Flags: + 0x01: Special + 0x02: Special + 0x04: Special + 0x08: Special + 0x10: Slope + 0x20: Water + 0x40: Foreground + 0x80: Wind + + 0x00 (Null): + 0x00: Null + 0x01: Background Tile + 0x02: Background Water + 0x03: Background NPC-Blocker Tile [Unused] + 0x04: Background NPC-Blocker Tile [Unused] + 0x05: Background Shoot-Passer Tile [Unused] + 0x06: Background Tile [Unused] + 0x07: Background Tile [Unused] + 0x08: Background Tile [Unused] + 0x09: Background Tile [Unused] + 0x0A: Background Tile [Unused] + 0x0B: Background Tile [Unused] + 0x0C: Background Tile [Unused] + 0x0D: Background Tile [Unused] + 0x0E: Background Tile [Unused] + 0x0F: Background Tile [Unused] + + 0x10 (Slope): + 0x10: Background Tile [Unused] + 0x11: Background Tile [Unused] + 0x12: Background Tile [Unused] + 0x13: Background Tile [Unused] + 0x14: Background Tile [Unused] + 0x15: Background Tile [Unused] + 0x16: Background Tile [Unused] + 0x17: Background Tile [Unused] + 0x18: Background Tile [Unused] + 0x19: Background Tile [Unused] + 0x1A: Background Tile [Unused] + 0x1B: Background Tile [Unused] + 0x1C: Background Tile [Unused] + 0x1D: Background Tile [Unused] + 0x1E: Background Tile [Unused] + 0x1F: Background Tile [Unused] + + 0x20 (Water): + 0x20: Null [Unused] + 0x21: Null [Unused] + 0x22: Null [Unused] + 0x23: Null [Unused] + 0x24: Null [Unused] + 0x25: Null [Unused] + 0x26: Null [Unused] + 0x27: Null [Unused] + 0x28: Null [Unused] + 0x29: Null [Unused] + 0x2A: Null [Unused] + 0x2B: Null [Unused] + 0x2C: Null [Unused] + 0x2D: Null [Unused] + 0x2E: Null [Unused] + 0x2F: Null [Unused] + + 0x30 (Slope + Water): + 0x30: Null [Unused] + 0x31: Null [Unused] + 0x32: Null [Unused] + 0x33: Null [Unused] + 0x34: Null [Unused] + 0x35: Null [Unused] + 0x36: Null [Unused] + 0x37: Null [Unused] + 0x38: Null [Unused] + 0x39: Null [Unused] + 0x3A: Null [Unused] + 0x3B: Null [Unused] + 0x3C: Null [Unused] + 0x3D: Null [Unused] + 0x3E: Null [Unused] + 0x3F: Null [Unused] + + 0x40 (Foreground): + 0x40: Foreground Tile + 0x41: Solid Tile + 0x42: 10 Damage Foreground Tile + 0x43: Special Block Tile + 0x44: Foreground NPC-Blocker Tile + 0x45: Foreground Tile [Unused] + 0x46: Character-Blocker Tile [Unused] + 0x47: Foreground Tile [Unused] + 0x48: Foreground Tile [Unused] + 0x49: Foreground Tile [Unused] + 0x4A: Foreground Tile [Unused] + 0x4B: Foreground Tile [Unused] + 0x4C: Foreground Tile [Unused] + 0x4D: Foreground Tile [Unused] + 0x4E: Foreground Tile [Unused] + 0x4F: Foreground Tile [Unused] + + 0x50 (Foreground + Slope): + 0x50: Slope Tile + 0x51: Slope Tile + 0x52: Slope Tile + 0x53: Slope Tile + 0x54: Slope Tile + 0x55: Slope Tile + 0x56: Slope Tile + 0x57: Slope Tile + 0x58: Foreground Tile [Unused] + 0x59: Foreground Tile [Unused] + 0x5A: Foreground Tile [Unused] + 0x5B: Foreground Tile [Unused] + 0x5C: Foreground Tile [Unused] + 0x5D: Foreground Tile [Unused] + 0x5E: Foreground Tile [Unused] + 0x5F: Foreground Tile [Unused] + + 0x60 (Foreground + Water): + 0x60: Foreground Water + 0x61: Solid Tile [Unused] + 0x62: 10 Damage Foreground Water Tile [Red] + 0x63: Foreground Tile [Unused] + 0x64: Foreground NPC-Blocker Tile [Unused] + 0x65: Foreground Tile [Unused] + 0x66: Foreground Tile [Unused] + 0x67: Foreground Tile [Unused] + 0x68: Foreground Tile [Unused] + 0x69: Foreground Tile [Unused] + 0x6A: Foreground Tile [Unused] + 0x6B: Foreground Tile [Unused] + 0x6C: Foreground Tile [Unused] + 0x6D: Foreground Tile [Unused] + 0x6E: Foreground Tile [Unused] + 0x6F: Foreground Tile [Unused] + + 0x70 (Foreground + Slope + Water): + 0x70: Slope Tile [Water] + 0x71: Slope Tile [Water] + 0x72: Slope Tile [Water] + 0x73: Slope Tile [Water] + 0x74: Slope Tile [Water] + 0x75: Slope Tile [Water] + 0x76: Slope Tile [Water] + 0x77: Slope Tile [Water] + 0x78: Foreground Tile [Unused] + 0x79: Foreground Tile [Unused] + 0x7A: Foreground Tile [Unused] + 0x7B: Foreground Tile [Unused] + 0x7C: Foreground Tile [Unused] + 0x7D: Foreground Tile [Unused] + 0x7E: Foreground Tile [Unused] + 0x7F: Foreground Tile [Unused] + + 0x80 (Wind): + 0x80: Wind [Left] + 0x81: Wind [Up] + 0x82: Wind [Right] + 0x83: Wind [Down] + 0x84: Null [Unused] + 0x85: Null [Unused] + 0x86: Null [Unused] + 0x87: Null [Unused] + 0x88: Null [Unused] + 0x89: Null [Unused] + 0x8A: Null [Unused] + 0x8B: Null [Unused] + 0x8C: Null [Unused] + 0x8D: Null [Unused] + 0x8E: Null [Unused] + 0x8F: Null [Unused] + + 0x90 (Wind + Slope): + 0x90: Null [Unused] + 0x91: Null [Unused] + 0x92: Null [Unused] + 0x93: Null [Unused] + 0x94: Null [Unused] + 0x95: Null [Unused] + 0x96: Null [Unused] + 0x97: Null [Unused] + 0x98: Null [Unused] + 0x99: Null [Unused] + 0x9A: Null [Unused] + 0x9B: Null [Unused] + 0x9C: Null [Unused] + 0x9D: Null [Unused] + 0x9E: Null [Unused] + 0x9F: Null [Unused] + + 0xA0 (Wind + Water): + 0xA0: Water Wind [Left] + 0xA1: Water Wind [Up] + 0xA2: Water Wind [Right] + 0xA3: Water Wind [Down] + 0xA4: Null [Unused] + 0xA5: Null [Unused] + 0xA6: Null [Unused] + 0xA7: Null [Unused] + 0xA8 :Null [Unused] + 0xA9: Null [Unused] + 0xAA: Null [Unused] + 0xAB: Null [Unused] + 0xAC: Null [Unused] + 0xAD: Null [Unused] + 0xAE: Null [Unused] + 0xAF: Null [Unused] + + 0xB0 (Wind + Slope + Water): + 0xB0: Null [Unused] + 0xB1: Null [Unused] + 0xB2: Null [Unused] + 0xB3: Null [Unused] + 0xB4: Null [Unused] + 0xB5: Null [Unused] + 0xB6: Null [Unused] + 0xB7: Null [Unused] + 0xB8: Null [Unused] + 0xB9: Null [Unused] + 0xBA: Null [Unused] + 0xBB: Null [Unused] + 0xBC: Null [Unused] + 0xBD: Null [Unused] + 0xBE: Null [Unused] + 0xBF: Null [Unused] + + 0xC0 (Wind + Foreground): + 0xC0: Null [Unused] + 0xC1: Null [Unused] + 0xC2: Null [Unused] + 0xC3: Null [Unused] + 0xC4: Null [Unused] + 0xC5: Null [Unused] + 0xC6: Null [Unused] + 0xC7: Null [Unused] + 0xC8: Null [Unused] + 0xC9: Null [Unused] + 0xCA: Null [Unused] + 0xCB: Null [Unused] + 0xCC: Null [Unused] + 0xCD: Null [Unused] + 0xCE: Null [Unused] + 0xCF: Null [Unused] + + 0xD0 (Wind + Foreground + Slope): + 0xD0: Null [Unused] + 0xD1: Null [Unused] + 0xD2: Null [Unused] + 0xD3: Null [Unused] + 0xD4: Null [Unused] + 0xD5: Null [Unused] + 0xD6: Null [Unused] + 0xD7: Null [Unused] + 0xD8: Null [Unused] + 0xD9: Null [Unused] + 0xDA: Null [Unused] + 0xDB: Null [Unused] + 0xDC: Null [Unused] + 0xDD: Null [Unused] + 0xDE: Null [Unused] + 0xDF: Null [Unused] + + 0xE0 (Wind + Foreground + Water): + 0xE0: Null [Unused] + 0xE1: Null [Unused] + 0xE2: Null [Unused] + 0xE3: Null [Unused] + 0xE4: Null [Unused] + 0xE5: Null [Unused] + 0xE6: Null [Unused] + 0xE7: Null [Unused] + 0xE8: Null [Unused] + 0xE9: Null [Unused] + 0xEA: Null [Unused] + 0xEB: Null [Unused] + 0xEC: Null [Unused] + 0xED: Null [Unused] + 0xEE: Null [Unused] + 0xEF: Null [Unused] + + 0xF0 (Wind + Foreground + Slope + Water): + 0xF0: Null [Unused] + 0xF1: Null [Unused] + 0xF2: Null [Unused] + 0xF3: Null [Unused] + 0xF4: Null [Unused] + 0xF5: Null [Unused] + 0xF6: Null [Unused] + 0xF7: Null [Unused] + 0xF8: Null [Unused] + 0xF9: Null [Unused] + 0xFA: Null [Unused] + 0xFB: Null [Unused] + 0xFC: Null [Unused] + 0xFD: Null [Unused] + 0xFE: Null [Unused] + 0xFF: Null [Unused] diff --git a/docs/tsc notes.txt b/docs/tsc notes.txt new file mode 100644 index 0000000..1d34dd5 --- /dev/null +++ b/docs/tsc notes.txt @@ -0,0 +1,557 @@ +Doukutsu Monogatari - TSC notes (aka Cave Story) + by Kapow - 2006 April 24 + additions by ShInInG PhAnToM - 2007 June 05 + original: http://lotlot.net/misc/doukutsu/tsc.txt + updated: http://filespace.org/ShInInG_PhAnToM/TSC.TXT + +THANKS: + caveoholic and upthorn from gameflaws forums + robert vandiver, for unused TSC commands + supergodantman + +TSC COMMANDS (@ = available but unused commands found through disassembly - currently untested) +============ +