mirror of
https://github.com/cave-story-randomizer/cave-story-randomizer
synced 2024-11-21 22:32:53 +00:00
Initial commit.
This commit is contained in:
parent
c41cf626fe
commit
0094c34e51
|
@ -1,2 +1,3 @@
|
|||
# cave-story-randomizer
|
||||
Cave Story Randomizer
|
||||
=====================
|
||||
|
||||
|
|
666
docs/csresearch.txt
Normal file
666
docs/csresearch.txt
Normal file
|
@ -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]
|
557
docs/tsc notes.txt
Normal file
557
docs/tsc notes.txt
Normal file
|
@ -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)
|
||||
============
|
||||
<AE+ Arms Energy + Refill ammo
|
||||
<AM+x:y ArMs + Get weapon X, add Y to max ammo (just adds ammo if you have the weapon)
|
||||
<AM-x ArMs - Lose weapon X
|
||||
<AMJx:y ArMs Jump Jump to event Y if you have weapon X
|
||||
<ANPx:y:z Animate NPc Animate npc X with method Y in direction Z [npc type determines Y values?]
|
||||
<BOAx BOss Animate Animate boss
|
||||
<BSLx Boss [Script Load?] Start a boss fight with npc X (npc flag 0200 must be set) (should work with anything that has HP)
|
||||
<CAT [?] @ [same as SAT?]
|
||||
<CIL Clear ILlustration Clear illustration during credits (used after SIL)
|
||||
<CLO CLOse Close the text box (used after MSG/MS2/MS3)
|
||||
<CLR CLeaR Clear the text box (used after MSG/MS2/MS3)
|
||||
<CMPx:y:z Change Map [P?] Change map coords X:Y to tile Z
|
||||
<CMUx Change MUsic Change music to song X
|
||||
<CNPx:y:z Change NPc Change npc X to npc type Y with direction Z
|
||||
<CPS Clear Prop. Sound Stop propeller sound (used after SPS) (from helicopter cutscene after final battles)
|
||||
<CRE CREdits Roll credits
|
||||
<CSS Clear Stream Sound Stop stream sound (used after SSS) (from River area)
|
||||
<DNAx [?] [something to do with bosses]
|
||||
<DNPx Delete NPc Npc X is removed completely
|
||||
<ECJx:y [EC?] Jump @ Jump to event Y if any npc with ID X is present
|
||||
<END END End scripted event
|
||||
<EQ+x EQuip + Add X to equip flag bytes
|
||||
<EQ-x EQuip - Subtract X from equip flag bytes
|
||||
<ESC ESCape Quit to title screen
|
||||
<EVEx EVEnt Jump to event X (non-conditional)
|
||||
<FACx FACe Show face X in text box
|
||||
<FAIx FAde In Fade in with direction X
|
||||
<FAOx FAde Out Fade out with direction X
|
||||
<FL+x FLag + Set flag X
|
||||
<FL-x FLag - Clear flag X
|
||||
<FLA FLAsh Flash the screen
|
||||
<FLJx:y FLag Jump Jump to event Y if flag X is set
|
||||
<FMU Fade MUsic Fade the music to a low volume (good to use before CMU)
|
||||
<FOBx:y Focus On Boss [Focus view on boss X? why not use FON?], view movement takes Y ticks
|
||||
<FOMx Focus On Me Focus view on you (normal view), view movement takes X ticks (WARNING: speed 0000 crashes)
|
||||
<FONx:y Focus On Npc Focus view on npc X, view movement takes Y ticks
|
||||
<FRE FREe Frees menu cursor [also used after ZAM for some reason?]
|
||||
<GITx Graphic ITem Show weapon/item X icon above text box - add 1000 to X for items - GIT0000 to hide
|
||||
<HMC Hide My Character Removes main character npc (use SMC after)
|
||||
<INI INItialize Resets memory and starts game from the beginning
|
||||
<INPx:y:z [I?] NPc @ Change npc X to npc type Y with direction Z with setting Flag 0x0100 [It seems that it setting the "No Player Damage" Flag and not the Costum 0x0100 Flag]
|
||||
<IT+x ITem + Get item X
|
||||
<IT-x ITem - Lose item X
|
||||
<ITJx:y ITem Jump Jump to event Y if you have item X
|
||||
<KEY KEYlock Hides status bars and locks out input to your character until END (used with MSG/MS2/MS3 and PRI)
|
||||
<LDP LoaD Profile Loads profile.dat into memory and starts game from save
|
||||
<LI+x LIfe + Restore X amount of health
|
||||
<ML+x Max Life + Max health increased X amount
|
||||
<MLP Map [LP?] Display map
|
||||
<MM0 My Motion 0 Instantly halts your horizontal motion
|
||||
<MNA [Map NAme?] Displays name of current map
|
||||
<MNPx:y:z:w Move NPc Move npc X to coords Y:Z facing direction W
|
||||
<MOVx:y MOVe Move you to coords X:Y
|
||||
<MP+x [MaP ??] @ [map-related]
|
||||
<MPJx [MaP Jump?] [Jump to event X if map exists for current area? the single instance of this seems to be dummied out]
|
||||
<MS2 MeSsage 2 Open invisible text box at top of screen (text follows)
|
||||
<MS3 MeSsage 3 Open normal text box at top of screen (text follows)
|
||||
<MSG MeSsaGe 1 Open normal text box (text follows)
|
||||
<MYBx MY Bump Knocks you back from direction X (0000 knocked right, 0002 knocked left, any other just hops in place)
|
||||
<MYDx MY Direction Make you face direction X
|
||||
<NCJx:y [NpC?] Jump Jump to event Y if any npc of type X is present
|
||||
<NOD [Nod? Text box wait for button press (used after MSG/MS2/MS3)
|
||||
<NUM0000 [Number?] Used to output Y from AM+ as text
|
||||
<PRI [?] Hides status bars and freezes game action until KEY or END (used with MSG/MS2/MS3)
|
||||
<PS+x:y [P? Slot?] Set teleporter slot X to location Y
|
||||
<QUAx QUAke Shake the screen for X ticks
|
||||
<RMU Restore MUsic Restore music playback [plays previous song? or only works with some songs?]
|
||||
<SAT Speed-up All Text Instant text display on all messages until END (glitches scrolling text)
|
||||
<SILx Show ILlustration Show illustration during credits (use CIL after)
|
||||
<SK+x SKipflag + Set skipflag X (remains set until program exits, to avoid repeating cutscenes/dialogue after retrying)
|
||||
<SK-x SKipflag -? @ Clear skipflag
|
||||
<SKJx:y SKipflag Jump Jump to event Y if skipflag X is set
|
||||
<SLP [Show? Location? P?] Teleporter location menu
|
||||
<SMC Show My Character Restores main character npc (used after HMC)
|
||||
<SMPx:y [?] [do something with npc X? - only used before and after the Omega fight]
|
||||
<SNPx:y:z:w [Start?] NPc @ Create npc type X at coords Y:Z with direction W
|
||||
<SOUx SOUnd Play sound effect X
|
||||
<SPS Start Prop. Sound Start propeller sound (use CPS after) (from helicopter cutscene after final battles)
|
||||
<SSSx Start Stream Sound Start stream sound at pitch X (use CSS after) (from River area - normal pitch is 0400)
|
||||
<STC Save Time Counted Saves the current time to 290.rec
|
||||
<SVP SaVe Profile Save game
|
||||
<TAMx:y:z Trade ArMs Trade weapon X for weapon Y, set max ammo to Z (max ammo 0000 = no change) (GLITCH: first weapon 0000)
|
||||
<TRAx:y:z:w TRAnsport Load map X, run event Y, transport you to coords Z:W
|
||||
<TUR [?] Instant text display [until what? CLR?] (used after MSG/MS2/MS3)
|
||||
<UNIx [?] [0000 normal / 0001 zero-g movement, facing direction is locked (disables focus commands) (from Stream boss) / 0002 movement is locked, can still fire]
|
||||
<UNJx [?] Jump? [?]
|
||||
<WAIx WAIt Pause script for X ticks
|
||||
<WAS WAit until Standing Pause script until your character touches the ground
|
||||
<XX1x [?] [shows distant view of island?]
|
||||
<YNJx Yes/No Jump Ask yes or no, jump to event X if No
|
||||
<ZAM Zero ArMs All weapons drop to level 1
|
||||
|
||||
Notes:
|
||||
Invalid commands show an error message displaying the command before the game exits
|
||||
The "jump if equipped" function is done with FLJ - an arbitrary flag is chosen, and every instance of EQ+/EQ- must also have the FL+/FL- command
|
||||
The colon between parameters can be any character (it's ignored)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
CREDITS FORMAT (credit.tsc)
|
||||
==============
|
||||
[T]X Text T with casts.pbm image X [on left?]
|
||||
+X [?]
|
||||
!X [?]
|
||||
-X [line has height X?]
|
||||
fX:Y Jump to location Y if flag X is set
|
||||
jX Jump to location X
|
||||
lX Location X
|
||||
~ [switch to the left half of the screen?]
|
||||
/ [end?]
|
||||
<<< [comment?]
|
||||
|
||||
|
||||
|
||||
|
||||
NPC FLAGS
|
||||
==============
|
||||
0x0001 - Solid
|
||||
0x0002 - No effect about Tile 44
|
||||
0x0004 - Invulnerable (Blink Sound)
|
||||
0x0008 - Ignore solid
|
||||
0x0010 - Bouncing at top
|
||||
0x0020 - Shootable
|
||||
0x0040 - Special Solid
|
||||
0x0080 - Rear and top attack power 0
|
||||
0x0100 - Costum
|
||||
0x0200 - Boss Flag
|
||||
0x0400 - ???
|
||||
0x0800 - Is visible if FlagID is set
|
||||
0x1000 - Costum
|
||||
0x2000 - Call on Event
|
||||
0x4000 - Is invisible if FlagID is set
|
||||
0x8000 - Show Damage Numbers
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
COMMAND VALUES
|
||||
==============
|
||||
Maps (TRA) Profile.dat byte 0x008 - for position, 0x011-012: distance from left,
|
||||
0x015-016: distance from top, 20h (32) per map tile (low byte first)
|
||||
0000 0 Credits
|
||||
0001 Pens1 Arthur's House - normal
|
||||
0002 Eggs Egg Corridor
|
||||
0003 EggX Egg No. 00 - normal
|
||||
0004 Egg6 Egg No. 06
|
||||
0005 EggR Egg Observation Room
|
||||
0006 Weed Grasstown
|
||||
0007 Santa Santa's House
|
||||
0008 Chako Chaco's House
|
||||
0009 MazeI Labyrinth I (vertical starting room)
|
||||
0010 Sand Sand Zone - normal
|
||||
0011 Mimi Mimiga Village
|
||||
0012 Cave First Cave
|
||||
0013 Start Start Point
|
||||
0014 Barr Shack (Mimiga Village)
|
||||
0015 Pool Reservoir
|
||||
0016 Cemet Graveyard
|
||||
0017 Plant Yamashita Farm
|
||||
0018 Shelt Shelter (Grasstown)
|
||||
0019 Comu Assembly Hall (Mimiga Village)
|
||||
0020 MiBox Save Point (Mimiga Village)
|
||||
0021 EgEnd1 Side Room (Egg Corridor)
|
||||
0022 Cthu Cthulhu's Abode (Egg Corridor)
|
||||
0023 Egg1 Egg No. 01
|
||||
0024 Pens2 Arthur's House - Sue on computer
|
||||
0025 Malco Power Room (Grasstown)
|
||||
0026 WeedS Save Point (Grasstown)
|
||||
0027 WeedD Execution Chamber (Grasstown)
|
||||
0028 Frog Gum (Grasstown)
|
||||
0029 Curly Sand Zone Residence
|
||||
0030 WeedB Grasstown Hut
|
||||
0031 Stream Main Artery (Waterway)
|
||||
0032 CurlyS Small Room (Sand Zone)
|
||||
0033 Jenka1 Jenka's House - normal
|
||||
0034 Dark Deserted House (Sand Zone)
|
||||
0035 Gard Sand Zone Storehouse
|
||||
0036 Jenka2 Jenka's House - after Balrog attacks
|
||||
0037 SandE Sand Zone - after boss fight
|
||||
0038 MazeH Labyrinth H (sliding block room)
|
||||
0039 MazeW Labyrinth W (main area w/shop, camp)
|
||||
0040 MazeO Camp (Labyrinth)
|
||||
0041 MazeD Clinic Ruins (Labyrinth)
|
||||
0042 MazeA Labyrinth Shop
|
||||
0043 MazeB Labyrinth B (booster)
|
||||
0044 MazeS Boulder Chamber (Labyrinth)
|
||||
0045 MazeM Labyrinth M (gaudi eggs)
|
||||
0046 Drain Dark Place (Labyrinth)
|
||||
0047 Almond Core (Labyrinth)
|
||||
0048 River Waterway
|
||||
0049 Eggs2 Egg Corridor?
|
||||
0050 Cthu2 Cthulhu's Abode? (Egg Corridor?)
|
||||
0051 EggR2 Egg Observation Room?
|
||||
0052 EggX2 Egg No. 00 - hatched
|
||||
0053 Oside Outer Wall
|
||||
0054 EgEnd2 Side Room (Egg Corridor?)
|
||||
0055 Itoh Storehouse (Outer Wall)
|
||||
0056 Cent Plantation
|
||||
0057 Jail1 Jail No. 1 (Plantation)
|
||||
0058 Momo Hideout (Plantation)
|
||||
0059 Lounge Rest Area (Plantation)
|
||||
0060 CentW Teleporter (Plantation)
|
||||
0061 Jail2 Jail No. 2 (Plantation)
|
||||
0062 Blcny1 Balcony - normal
|
||||
0063 Priso1 Last Cave
|
||||
0064 Ring1 Throne Room (Balcony)
|
||||
0065 Ring2 The King's Table (Balcony)
|
||||
0066 Prefa1 Prefab House (Balcony) - normal
|
||||
0067 Priso2 Last Cave Hidden
|
||||
0068 Ring3 Black Space (Balcony)
|
||||
0069 Little Little House (Outer Wall)
|
||||
0070 Blcny2 Balcony - after boss fights
|
||||
0071 Fall Ending
|
||||
0072 Kings Intro
|
||||
0073 Pixel Waterway Cabin
|
||||
0074 e_Maze Credits - Labyrinth
|
||||
0075 e_Jenk Credits - Jenka's House
|
||||
0076 e_Malc Credits - Power Room
|
||||
0077 e_Ceme Credits - Graveyard
|
||||
0078 e_Sky Credits - Sky
|
||||
0079 Prefa2 Prefab House (Balcony) - entrance to hell
|
||||
0080 Hell1 Sacred Ground B1
|
||||
0081 Hell2 Sacred Ground B2
|
||||
0082 Hell3 Sacred Ground B3
|
||||
0083 Mapi Storage (Graveyard)
|
||||
0084 Hell4 Passage? - normal
|
||||
0085 Hell42 Passage? - from Sacred Ground B3
|
||||
0086 Statue Statue Chamber (Plantation/Sacred Grounds)
|
||||
0087 Ballo1 Seal Chamber (Sacred Grounds) - normal
|
||||
0088 Ostep Corridor (Sacred Grounds)
|
||||
0089 e_Labo Credits - Laboratory
|
||||
0090 Pole Hermit Gunsmith
|
||||
0091 Island [map is totally blank - TSC is called right before good/best endings]
|
||||
0092 Ballo2 Seal Chamber (Sacred Grounds) - after boss fight
|
||||
0093 e_Blcn Credits - Balcony
|
||||
0094 Clock Clock Room (Outer Wall)
|
||||
|
||||
|
||||
|
||||
Directions (FAI/FAO/MYD/MYB) Profile.dat bytes 0x018 (your direction)
|
||||
0000 Left
|
||||
0001 Up [FAI/FAO only?]
|
||||
0002 Right
|
||||
0003 Down
|
||||
0004 Center [FAI/FAO only?]
|
||||
NOTE: MYB is 0000 Right, 0002 Left (reversed)
|
||||
|
||||
|
||||
|
||||
Focus speed (FOB/FOM/FON)
|
||||
0000 (CRASH - probably divide by zero error)
|
||||
0001 Instant
|
||||
0016 Fast
|
||||
0032 Medium
|
||||
0064 Slow
|
||||
NOTE: Any value besides zero should work, these four are the only ones used normally
|
||||
|
||||
|
||||
|
||||
Weapons (AM+/AM-/AMJ/GIT/TAM) Profile.dat bytes 0x038-098 (every 4 bytes: weapon, level (1-3),
|
||||
energy, max ammo (0 = infinite), current ammo) (every 20 bytes)
|
||||
0000 [nothing?]
|
||||
0001 Snake
|
||||
0002 Polar Star
|
||||
0003 Fireball
|
||||
0004 Machine Gun
|
||||
0005 Missile Launcher
|
||||
0006 Missiles (GIT only)
|
||||
0007 Bubbler
|
||||
0008 [nothing?]
|
||||
0009 Blade
|
||||
0010 Super Missile Launcher
|
||||
0011 Super Missiles (GIT only)
|
||||
0012 Nemesis
|
||||
0013 Spur
|
||||
|
||||
|
||||
|
||||
Items (GIT/IT+/IT-/ITJ) Profile.dat bytes 0x0D8-14C (every 4 bytes)
|
||||
0000 [nothing?]
|
||||
0001 Arthur's Key
|
||||
0002 Map System
|
||||
0003 Santa's Key
|
||||
0004 Silver Locket
|
||||
0005 Beast Fang
|
||||
0006 Life Capsule (GIT only)
|
||||
0007 ID Card
|
||||
0008 Jellyfish Juice
|
||||
0009 Rusty Key
|
||||
0010 Gum Key
|
||||
0011 Gum Base
|
||||
0012 Charcoal
|
||||
0013 Explosive
|
||||
0014 Puppy
|
||||
0015 Life Pot
|
||||
0016 Cure-All
|
||||
0017 Clinic Key
|
||||
0018 Booster 0.8
|
||||
0019 Arms Barrier
|
||||
0020 Turbocharge
|
||||
0021 Curly's Air Tank
|
||||
0022 Nikumaru Counter
|
||||
0023 Booster v2.0
|
||||
0024 Mimiga Mask
|
||||
0025 Teleporter Room Key
|
||||
0026 Sue's Letter
|
||||
0027 Controller
|
||||
0028 Broken Sprinkler
|
||||
0029 Sprinkler
|
||||
0030 Tow Rope
|
||||
0031 Clay Figure Medal
|
||||
0032 Little Man
|
||||
0033 Mushroom Badge
|
||||
0034 Ma Pignon
|
||||
0035 Curly's Underwear
|
||||
0036 Alien Medal
|
||||
0037 Chaco's Lipstick
|
||||
0038 Whimsical Star
|
||||
0039 Iron Bond
|
||||
|
||||
|
||||
|
||||
Equip (EQ+/EQ-) Profile.dat bytes 0x02C-02D (low byte first)
|
||||
0001 Booster v0.8 (ignored if v2.0 on)
|
||||
0002 Map System
|
||||
0004 Arms Barrier
|
||||
0008 Turbocharge
|
||||
0016 Curly's Air Tank
|
||||
0032 Booster v2.0
|
||||
0064 Mimiga Mask
|
||||
0128 Whimsical Star
|
||||
0256 Nikumaru Counter
|
||||
NOTE: these are bitwise flags, the final value is the sum of the equipped items
|
||||
|
||||
|
||||
|
||||
Faces (FAC)
|
||||
0000 [blank - does this set the text to normal width?]
|
||||
0001 Sue (smile)
|
||||
0002 Sue (frown)
|
||||
0003 Sue (angry)
|
||||
0004 Sue (hurt)
|
||||
0005 Balrog (normal)
|
||||
0006 Toroko (normal)
|
||||
0007 King
|
||||
0008 Toroko (angry)
|
||||
0009 Jack
|
||||
0010 Kazuma
|
||||
0011 Toroko (rage)
|
||||
0012 Igor
|
||||
0013 Jenka
|
||||
0014 Balrog (smile)
|
||||
0015 Misery (normal)
|
||||
0016 Misery (smile)
|
||||
0017 Booster (hurt)
|
||||
0018 Booster (normal)
|
||||
0019 Curly (smile)
|
||||
0020 Curly (frown)
|
||||
0021 Doctor
|
||||
0022 Momorin
|
||||
0023 Balrog (hurt)
|
||||
0024 Broken robot
|
||||
0025 Curly (?)
|
||||
0026 Misery (angry)
|
||||
0027 Human Sue
|
||||
0028 Itoh
|
||||
0029 Ballos
|
||||
|
||||
|
||||
|
||||
Illustrations (SIL)
|
||||
0001 riding Sky Dragon
|
||||
0002 fighting Core
|
||||
0003 fighting Misery
|
||||
0004 Momorin's rocket
|
||||
0005 Outer Wall
|
||||
0006 fighting Ironhead
|
||||
0007 fighting Balrog (with missiles)
|
||||
0008 Clinic
|
||||
0009 King fighting the Doctor
|
||||
0010 Jenka with puppies
|
||||
0011 Curly with Mimiga children
|
||||
0012 riding Balrog
|
||||
0014 Hell
|
||||
0015 floating island (blue sky)
|
||||
0016 floating island (orange sky)
|
||||
0017 King, Jack, Sue
|
||||
0018 Ballos
|
||||
NOTE: any other values (including 0013) show 0001
|
||||
|
||||
|
||||
|
||||
Songs (CMU) Profile.dat byte 0x00C
|
||||
0000 (none - silence)
|
||||
0001 Mischievous Robot Egg Chamber
|
||||
0002 Safety various homes
|
||||
0003 (no title) game over
|
||||
0004 Gravity boss battle
|
||||
0005 On To Grasstown Grasstown
|
||||
0006 Meltdown 2 Sand Zone
|
||||
0007 Eyes of Flame major boss battle
|
||||
0008 Gestation First Cave, various small rooms
|
||||
0009 Mimiga Town Mimiga Village
|
||||
0010 (no title) get item
|
||||
0011 Balrog's Theme Balrog cutscenes
|
||||
0012 Cemetary Graveyard
|
||||
0013 Plant Yamashita Farm
|
||||
0014 Pulse Egg No. 00, Waterway Cabin, Arthur's House after Waterway
|
||||
0015 (no title) boss defeated
|
||||
0016 (no title) get life capsule
|
||||
0017 Tyrant Doctor cutscenes
|
||||
0018 Run! Balcony areas after boss fights
|
||||
0019 Jenka 1 Jenka's House, Labyrinth I & H (first two areas)
|
||||
0020 Labyrinth Fight Labyrinth M (gaudi eggs)
|
||||
0021 Access Shelter (Kazuma on computer)
|
||||
0022 Oppression Core battle
|
||||
0023 Geothermal Dark Place, Core, [Main Artery?]
|
||||
0024 Cave Story title screen, Plantation
|
||||
0025 Moonsong Outer Wall
|
||||
0026 Hero's End bad ending
|
||||
0027 Scorching Back Egg Corridor?
|
||||
0028 Quiet Mimiga Village and homes after Waterway
|
||||
0029 Final Cave Last Cave
|
||||
0030 Balcony Balcony
|
||||
0031 Charge Muscle Doctor battle
|
||||
0032 Last Battle final battles
|
||||
0033 The Way Back Home Credits
|
||||
0034 Zombie before Undead Core battle, after Ballos battle
|
||||
0035 Break Down Ending
|
||||
0036 Running Hell Sacred Grounds
|
||||
0037 Jenka 2 Labyrinth W (main area w/shop, camp)
|
||||
0038 Living Waterway Waterway
|
||||
0039 Seal Chamber before Ballos battle
|
||||
0040 Toroko's Theme Title Screen - Toroko
|
||||
0041 ["White"?] Title Screen - King
|
||||
|
||||
|
||||
|
||||
Sound Effects (SOU)
|
||||
0000 <nothing>
|
||||
0001 [blip]
|
||||
0002 Message typing
|
||||
0003 Bonk
|
||||
0004 Weapon switch
|
||||
0005 [?]
|
||||
0006 [critter hop?]
|
||||
0007 [nothing?]
|
||||
0008 [nothing?]
|
||||
0009 [nothing?]
|
||||
0010 [nothing?]
|
||||
0011 Door
|
||||
0012 [*plsh* - map tile change?]
|
||||
0013 [nothing?]
|
||||
0014 Get weapon energy
|
||||
0015 [click]
|
||||
0016 Take damage
|
||||
0017 Die
|
||||
0018 [menu?]
|
||||
0019 [nothing?]
|
||||
0020 Health/ammo refill
|
||||
0021 [bubble]
|
||||
0022 Click (chest, life capsule, unlock door)
|
||||
0023 [thud]
|
||||
0024 [tap - walking?]
|
||||
0025 [enemy killed?]
|
||||
0026 [loud thud - balrog?]
|
||||
0027 Level Up
|
||||
0028 [thump]
|
||||
0029 Teleport
|
||||
0030 [jump]
|
||||
0031 Invulnerable "ting"
|
||||
0032 [shot - polar star?]
|
||||
0033 [shot - fireball]
|
||||
0034 [shot - fireball bounce?]
|
||||
0035 [explosion (missiles?]
|
||||
0036 [nothing?]
|
||||
0037 [click]
|
||||
0038 [get item?]
|
||||
0039 [*bvng*]
|
||||
0040 [water?]
|
||||
0041 [water?]
|
||||
0042 [beep]
|
||||
0043 Computer beep (activate terminals, etc.)
|
||||
0044 Blast (blow up door to Shelt)
|
||||
0045 Weapon energy bounce
|
||||
0046 [*ftt*]
|
||||
0047 [?]
|
||||
0048 [shot - bubble pop?]
|
||||
0049 [shot - spur lv 1]
|
||||
0050 [enemy squeak]
|
||||
0051 [enemy take damage]
|
||||
0052 [large enemy take damage (roar)]
|
||||
0053 [enemy squeak-bblblbl]
|
||||
0054 [object shot (thud)]
|
||||
0055 [enemy squeak]
|
||||
0056 [splash]
|
||||
0057 [little damage sound]
|
||||
0058 [*chlk*]
|
||||
0059 [nothing?]
|
||||
0060 [spur charge - lower]
|
||||
0061 [spur charge - higher]
|
||||
0062 Shot - Spur lv 2
|
||||
0063 Shot - Spur lv 3
|
||||
0064 Shot - Spur max
|
||||
0065 Spur fully charged
|
||||
0066 [nothing?]
|
||||
0067 [nothing?]
|
||||
0068 [nothing?]
|
||||
0069 [nothing?]
|
||||
0070 [Sue hitting you while you're unconscious in Jail1]
|
||||
0071 [explosion]
|
||||
0072 [explosion]
|
||||
0073 [nothing?]
|
||||
0074 [nothing?]
|
||||
0075 [nothing?]
|
||||
0076 [nothing?]
|
||||
0077 [nothing?]
|
||||
0078 [nothing?]
|
||||
0079 [nothing?]
|
||||
0080 [nothing?]
|
||||
0081 [nothing?]
|
||||
0082 [nothing?]
|
||||
0083 [nothing?]
|
||||
0084 [nothing?]
|
||||
0085 [nothing?]
|
||||
0086 [nothing?]
|
||||
0087 [nothing?]
|
||||
0088 [nothing?]
|
||||
0089 [nothing?]
|
||||
0090 [nothing?]
|
||||
0091 [nothing?]
|
||||
0092 [nothing?]
|
||||
0093 [nothing?]
|
||||
0094 [nothing?]
|
||||
0095 [nothing?]
|
||||
0096 [nothing?]
|
||||
0097 [nothing?]
|
||||
0098 [nothing?]
|
||||
0099 [nothing?]
|
||||
|
||||
http://spgardebiter.sp.funpic.de/CaveStory/FAQ/TSC.txt
|
2250
src/lib/moses.lua
Normal file
2250
src/lib/moses.lua
Normal file
File diff suppressed because it is too large
Load diff
124
src/lib/serpent.lua
Normal file
124
src/lib/serpent.lua
Normal file
|
@ -0,0 +1,124 @@
|
|||
local n, v = "serpent", 0.28 -- (C) 2012-15 Paul Kulchenko; MIT License
|
||||
local c, d = "Paul Kulchenko", "Lua serializer and pretty printer"
|
||||
local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'}
|
||||
local badtype = {thread = true, userdata = true, cdata = true}
|
||||
local keyword, globals, G = {}, {}, (_G or _ENV)
|
||||
for _,k in ipairs({'and', 'break', 'do', 'else', 'elseif', 'end', 'false',
|
||||
'for', 'function', 'goto', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat',
|
||||
'return', 'then', 'true', 'until', 'while'}) do keyword[k] = true end
|
||||
for k,v in pairs(G) do globals[v] = k end -- build func to name mapping
|
||||
for _,g in ipairs({'coroutine', 'debug', 'io', 'math', 'string', 'table', 'os'}) do
|
||||
for k,v in pairs(G[g] or {}) do globals[v] = g..'.'..k end end
|
||||
|
||||
local function s(t, opts)
|
||||
local name, indent, fatal, maxnum = opts.name, opts.indent, opts.fatal, opts.maxnum
|
||||
local sparse, custom, huge = opts.sparse, opts.custom, not opts.nohuge
|
||||
local space, maxl = (opts.compact and '' or ' '), (opts.maxlevel or math.huge)
|
||||
local iname, comm = '_'..(name or ''), opts.comment and (tonumber(opts.comment) or math.huge)
|
||||
local seen, sref, syms, symn = {}, {'local '..iname..'={}'}, {}, 0
|
||||
local function gensym(val) return '_'..(tostring(tostring(val)):gsub("[^%w]",""):gsub("(%d%w+)",
|
||||
-- tostring(val) is needed because __tostring may return a non-string value
|
||||
function(s) if not syms[s] then symn = symn+1; syms[s] = symn end return tostring(syms[s]) end)) end
|
||||
local function safestr(s) return type(s) == "number" and tostring(huge and snum[tostring(s)] or s)
|
||||
or type(s) ~= "string" and tostring(s) -- escape NEWLINE/010 and EOF/026
|
||||
or ("%q"):format(s):gsub("\010","n"):gsub("\026","\\026") end
|
||||
local function comment(s,l) return comm and (l or 0) < comm and ' --[['..tostring(s)..']]' or '' end
|
||||
local function globerr(s,l) return globals[s] and globals[s]..comment(s,l) or not fatal
|
||||
and safestr(select(2, pcall(tostring, s))) or error("Can't serialize "..tostring(s)) end
|
||||
local function safename(path, name) -- generates foo.bar, foo[3], or foo['b a r']
|
||||
local n = name == nil and '' or name
|
||||
local plain = type(n) == "string" and n:match("^[%l%u_][%w_]*$") and not keyword[n]
|
||||
local safe = plain and n or '['..safestr(n)..']'
|
||||
return (path or '')..(plain and path and '.' or '')..safe, safe end
|
||||
local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(k, o, n) -- k=keys, o=originaltable, n=padding
|
||||
local maxn, to = tonumber(n) or 12, {number = 'a', string = 'b'}
|
||||
local function padnum(d) return ("%0"..tostring(maxn).."d"):format(tonumber(d)) end
|
||||
table.sort(k, function(a,b)
|
||||
-- sort numeric keys first: k[key] is not nil for numerical keys
|
||||
return (k[a] ~= nil and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum))
|
||||
< (k[b] ~= nil and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end
|
||||
local function val2str(t, name, indent, insref, path, plainindex, level)
|
||||
local ttype, level, mt = type(t), (level or 0), getmetatable(t)
|
||||
local spath, sname = safename(path, name)
|
||||
local tag = plainindex and
|
||||
((type(name) == "number") and '' or name..space..'='..space) or
|
||||
(name ~= nil and sname..space..'='..space or '')
|
||||
if seen[t] then -- already seen this element
|
||||
sref[#sref+1] = spath..space..'='..space..seen[t]
|
||||
return tag..'nil'..comment('ref', level) end
|
||||
if type(mt) == 'table' and (mt.__serialize or mt.__tostring) then -- knows how to serialize itself
|
||||
seen[t] = insref or spath
|
||||
if mt.__serialize then t = mt.__serialize(t) else t = tostring(t) end
|
||||
ttype = type(t) end -- new value falls through to be serialized
|
||||
if ttype == "table" then
|
||||
if level >= maxl then return tag..'{}'..comment('max', level) end
|
||||
seen[t] = insref or spath
|
||||
if next(t) == nil then return tag..'{}'..comment(t, level) end -- table empty
|
||||
local maxn, o, out = math.min(#t, maxnum or #t), {}, {}
|
||||
for key = 1, maxn do o[key] = key end
|
||||
if not maxnum or #o < maxnum then
|
||||
local n = #o -- n = n + 1; o[n] is much faster than o[#o+1] on large tables
|
||||
for key in pairs(t) do if o[key] ~= key then n = n + 1; o[n] = key end end end
|
||||
if maxnum and #o > maxnum then o[maxnum+1] = nil end
|
||||
if opts.sortkeys and #o > maxn then alphanumsort(o, t, opts.sortkeys) end
|
||||
local sparse = sparse and #o > maxn -- disable sparsness if only numeric keys (shorter output)
|
||||
for n, key in ipairs(o) do
|
||||
local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse
|
||||
if opts.valignore and opts.valignore[value] -- skip ignored values; do nothing
|
||||
or opts.keyallow and not opts.keyallow[key]
|
||||
or opts.valtypeignore and opts.valtypeignore[type(value)] -- skipping ignored value types
|
||||
or sparse and value == nil then -- skipping nils; do nothing
|
||||
elseif ktype == 'table' or ktype == 'function' or badtype[ktype] then
|
||||
if not seen[key] and not globals[key] then
|
||||
sref[#sref+1] = 'placeholder'
|
||||
local sname = safename(iname, gensym(key)) -- iname is table for local variables
|
||||
sref[#sref] = val2str(key,sname,indent,sname,iname,true) end
|
||||
sref[#sref+1] = 'placeholder'
|
||||
local path = seen[t]..'['..tostring(seen[key] or globals[key] or gensym(key))..']'
|
||||
sref[#sref] = path..space..'='..space..tostring(seen[value] or val2str(value,nil,indent,path))
|
||||
else
|
||||
out[#out+1] = val2str(value,key,indent,insref,seen[t],plainindex,level+1)
|
||||
end
|
||||
end
|
||||
local prefix = string.rep(indent or '', level)
|
||||
local head = indent and '{\n'..prefix..indent or '{'
|
||||
local body = table.concat(out, ','..(indent and '\n'..prefix..indent or space))
|
||||
local tail = indent and "\n"..prefix..'}' or '}'
|
||||
return (custom and custom(tag,head,body,tail) or tag..head..body..tail)..comment(t, level)
|
||||
elseif badtype[ttype] then
|
||||
seen[t] = insref or spath
|
||||
return tag..globerr(t, level)
|
||||
elseif ttype == 'function' then
|
||||
seen[t] = insref or spath
|
||||
local ok, res = pcall(string.dump, t)
|
||||
local func = ok and ((opts.nocode and "function() --[[..skipped..]] end" or
|
||||
"((loadstring or load)("..safestr(res)..",'@serialized'))")..comment(t, level))
|
||||
return tag..(func or globerr(t, level))
|
||||
else return tag..safestr(t) end -- handle all other types
|
||||
end
|
||||
local sepr = indent and "\n" or ";"..space
|
||||
local body = val2str(t, name, indent) -- this call also populates sref
|
||||
local tail = #sref>1 and table.concat(sref, sepr)..sepr or ''
|
||||
local warn = opts.comment and #sref>1 and space.."--[[incomplete output with shared/self-references skipped]]" or ''
|
||||
return not name and body..warn or "do local "..body..sepr..tail.."return "..name..sepr.."end"
|
||||
end
|
||||
|
||||
local function deserialize(data, opts)
|
||||
local env = (opts and opts.safe == false) and G
|
||||
or setmetatable({}, {
|
||||
__index = function(t,k) return t end,
|
||||
__call = function(t,...) error("cannot call functions") end
|
||||
})
|
||||
local f, res = (loadstring or load)('return '..data, nil, nil, env)
|
||||
if not f then f, res = (loadstring or load)(data, nil, nil, env) end
|
||||
if not f then return f, res end
|
||||
if setfenv then setfenv(f, env) end
|
||||
return pcall(f)
|
||||
end
|
||||
|
||||
local function merge(a, b) if b then for k,v in pairs(b) do a[k] = v end end; return a; end
|
||||
return { _NAME = n, _COPYRIGHT = c, _DESCRIPTION = d, _VERSION = v, serialize = s,
|
||||
load = deserialize,
|
||||
dump = function(a, opts) return s(a, merge({name = '_', compact = true, sparse = true}, opts)) end,
|
||||
line = function(a, opts) return s(a, merge({sortkeys = true, comment = true}, opts)) end,
|
||||
block = function(a, opts) return s(a, merge({indent = ' ', sortkeys = true, comment = true}, opts)) end }
|
39
src/lib/strict.lua
Normal file
39
src/lib/strict.lua
Normal file
|
@ -0,0 +1,39 @@
|
|||
-- strict.lua
|
||||
-- checks uses of undeclared global variables
|
||||
-- All global variables must be 'declared' through a regular assignment
|
||||
-- (even assigning nil will do) in a main chunk before being used
|
||||
-- anywhere or assigned to inside a function.
|
||||
-- distributed under the Lua license: http://www.lua.org/license.html
|
||||
|
||||
local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget
|
||||
|
||||
local mt = getmetatable(_G)
|
||||
if mt == nil then
|
||||
mt = {}
|
||||
setmetatable(_G, mt)
|
||||
end
|
||||
|
||||
mt.__declared = {}
|
||||
|
||||
local function what ()
|
||||
local d = getinfo(3, "S")
|
||||
return d and d.what or "C"
|
||||
end
|
||||
|
||||
mt.__newindex = function (t, n, v)
|
||||
if not mt.__declared[n] then
|
||||
local w = what()
|
||||
if w ~= "main" and w ~= "C" then
|
||||
error("assign to undeclared variable '"..n.."'", 2)
|
||||
end
|
||||
mt.__declared[n] = true
|
||||
end
|
||||
rawset(t, n, v)
|
||||
end
|
||||
|
||||
mt.__index = function (t, n)
|
||||
if not mt.__declared[n] and what() ~= "C" then
|
||||
error("variable '"..n.."' is not declared", 2)
|
||||
end
|
||||
return rawget(t, n)
|
||||
end
|
214
src/main.lua
Normal file
214
src/main.lua
Normal file
|
@ -0,0 +1,214 @@
|
|||
io.stdout:setvbuf("no")
|
||||
|
||||
require 'lib.strict'
|
||||
|
||||
local _ = require 'lib.moses'
|
||||
local Serpent = require 'lib.serpent'
|
||||
|
||||
local lf = love.filesystem
|
||||
|
||||
local MODE_READ_BINARY = 'rb'
|
||||
local MODE_WRITE_BINARY = 'wb'
|
||||
|
||||
function readLittleEndian(file, bytes)
|
||||
local string = file:read(2)
|
||||
local bytes = string:byte()
|
||||
-- print(string, type(bytes), bytes)
|
||||
return bytes
|
||||
end
|
||||
|
||||
-- https://gist.github.com/fdeitylink/3fded36e9187fe838eb18a412c712800
|
||||
-- -=~ PXM File Data ~=-
|
||||
-- maps must be minimum of 21x16
|
||||
function readPXM(filename)
|
||||
print('reading PXM: ' .. filename)
|
||||
local file = assert(io.open(filename, MODE_READ_BINARY))
|
||||
-- First three bytes are PXM, then 0x10.
|
||||
assert(file:read(3) == "PXM")
|
||||
assert(file:read(1):byte() == 0x10)
|
||||
|
||||
-- Then 0x_map_length - 2 bytes
|
||||
-- Then 0x_map_height - 2 bytes
|
||||
local length = readLittleEndian(file, 2)
|
||||
local height = readLittleEndian(file, 2)
|
||||
print('length:', length)
|
||||
print('height:', height)
|
||||
|
||||
-- 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
|
||||
local tiles = {}
|
||||
for x = 1, length do
|
||||
tiles[x] = {}
|
||||
end
|
||||
for y = 1, height do
|
||||
for x = 1, length do
|
||||
tiles[x][y] = file:read(1):byte()
|
||||
end
|
||||
end
|
||||
-- Print result
|
||||
local XXX = 3
|
||||
for y = 1, height do
|
||||
local line = ""
|
||||
for x = 1, length do
|
||||
local tile = tiles[x][y]
|
||||
local len = string.len(tile)
|
||||
line = line .. string.rep(' ', XXX - len) .. tile
|
||||
end
|
||||
print(line)
|
||||
end
|
||||
end
|
||||
|
||||
local ITEM_DATA = {
|
||||
-- Weapons
|
||||
wPolar = {
|
||||
name = "Polar Star",
|
||||
map = "Pole",
|
||||
getText = "Got the =Polar Star=!",
|
||||
command = "<AM+0002:0000",
|
||||
displayCmd = "<GIT0002",
|
||||
},
|
||||
-- Items
|
||||
iPanties = {
|
||||
name = "Curly's Panties",
|
||||
map = "CurlyS",
|
||||
-- getText = "Found =Curly's Underwear=.",
|
||||
getText = "Found =Curly's Panties=.",
|
||||
command = "<IT+0035",
|
||||
displayCmd = "<GIT1035",
|
||||
},
|
||||
}
|
||||
|
||||
function stringReplace(text, needle, replacement)
|
||||
local i = text:find(needle, 1, true)
|
||||
if i == nil then
|
||||
return text
|
||||
end
|
||||
local len = needle:len()
|
||||
local j = i + len - 1
|
||||
assert((i % 1 == 0) and (i > 0) and (i <= j), tostring(i))
|
||||
assert((j % 1 == 0), tostring(j))
|
||||
local a = text:sub(1, i - 1)
|
||||
local b = text:sub(j + 1)
|
||||
return a .. replacement .. b
|
||||
end
|
||||
|
||||
function readTSC(filename, decodedFilename)
|
||||
print('reading TSC: ' .. filename)
|
||||
local file = assert(io.open(filename, MODE_READ_BINARY))
|
||||
local filesize = file:seek("end")
|
||||
local encodingCharPosition = math.floor(filesize / 2)
|
||||
file:seek("set", encodingCharPosition)
|
||||
local encodingChar = file:read(1):byte()
|
||||
print(" filesize", filesize)
|
||||
print(" encoding char:", encodingChar)
|
||||
print(" encoding char position:", encodingCharPosition)
|
||||
|
||||
-- Decode
|
||||
local chars, len = {}, 0
|
||||
file:seek("set")
|
||||
for pos = 0, filesize - 1 do
|
||||
local byte = file:read(1):byte()
|
||||
if pos ~= encodingCharPosition then
|
||||
-- print(pos, encodingCharPosition)
|
||||
byte = (byte - encodingChar) % 256
|
||||
-- byte = byte - encodingChar
|
||||
end
|
||||
len = len + 1
|
||||
chars[len] = string.char(byte)
|
||||
end
|
||||
local decoded = table.concat(chars)
|
||||
|
||||
local t = {}
|
||||
decoded:gsub(".",function(c) table.insert(t,c) end)
|
||||
-- for i, c in ipairs(t) do
|
||||
local near = 10
|
||||
for i = 1270 - near, 1270 + near do
|
||||
local c = t[i]
|
||||
print (i, c, chars[i])
|
||||
-- print(string.byte(chars[i]) == string.byte(c), string.byte(chars[i]), string.byte(c))
|
||||
end
|
||||
|
||||
-- -- Replace
|
||||
-- decoded = stringReplace(decoded, ITEM_DATA.wPolar.command, ITEM_DATA.iPanties.command)
|
||||
-- decoded = stringReplace(decoded, ITEM_DATA.wPolar.getText, ITEM_DATA.iPanties.getText)
|
||||
-- decoded = stringReplace(decoded, ITEM_DATA.wPolar.displayCmd, ITEM_DATA.iPanties.displayCmd)
|
||||
|
||||
-- Write
|
||||
-- return decoded
|
||||
local tmpFile, err = io.open(decodedFilename, MODE_WRITE_BINARY)
|
||||
assert(err == nil, err)
|
||||
tmpFile:write(decoded)
|
||||
tmpFile:flush()
|
||||
tmpFile:close()
|
||||
end
|
||||
|
||||
function writeTSC(filename)
|
||||
print('writing TSC: ' .. filename)
|
||||
local file = assert(io.open(filename, MODE_READ_BINARY))
|
||||
local filesize = file:seek("end")
|
||||
local encodingCharPosition = math.floor(filesize / 2)
|
||||
file:seek("set", encodingCharPosition)
|
||||
local encodingChar = file:read(1):byte()
|
||||
file:seek("set", encodingCharPosition)
|
||||
print(file:read(1))
|
||||
-- local encodingChar = 32
|
||||
print(" filesize", filesize)
|
||||
print(" encoding char:", encodingChar)
|
||||
print(" encoding char position:", encodingCharPosition)
|
||||
|
||||
-- Encode
|
||||
local chars, len = {}, 0
|
||||
file:seek("set")
|
||||
for pos = 0, filesize - 1 do
|
||||
local byte = file:read(1):byte()
|
||||
if pos ~= encodingCharPosition then
|
||||
byte = (byte + encodingChar) % 255
|
||||
end
|
||||
len = len + 1
|
||||
chars[len] = string.char(byte)
|
||||
end
|
||||
local decoded = table.concat(chars)
|
||||
|
||||
-- Write
|
||||
local tmpFile, err = io.open('TestingEncoded.tsc', MODE_WRITE_BINARY)
|
||||
assert(err == nil, err)
|
||||
tmpFile:write(decoded)
|
||||
tmpFile:flush()
|
||||
tmpFile:close()
|
||||
end
|
||||
|
||||
function love.load()
|
||||
-- readPXM('Pole.pxm')
|
||||
-- readTSC('Pole.tsc', 'Testing.tsc')
|
||||
-- writeTSC('Testing.tsc')
|
||||
-- readTSC('TestingEncoded.tsc', 'TestingDecoded.tsc')
|
||||
end
|
||||
|
||||
function love.directorydropped(path)
|
||||
local success = lf.mount(path, 'data')
|
||||
assert(success)
|
||||
|
||||
local items = lf.getDirectoryItems('/data')
|
||||
local containsStage = _.contains(items, 'Stage')
|
||||
assert(containsStage)
|
||||
local dirStage = '/data/Stage'
|
||||
|
||||
-- local items = lf.getDirectoryItems(dirStage)
|
||||
-- print(Serpent.block(items))
|
||||
end
|
||||
|
||||
function love.keypressed(key)
|
||||
if key == 'escape' then
|
||||
love.event.push('quit')
|
||||
end
|
||||
end
|
||||
|
||||
-- #0200
|
||||
-- <KEY<FLJ1640:0201<FL+1640<SOU0022<CNP0200:0021:0000
|
||||
-- <MSGOpened the chest.<NOD<GIT0002<AM+0002:0000<CLR
|
||||
-- <CMU0010Got the =Polar Star=!<WAI0160<NOD<GIT0000<CLO<RMU
|
||||
-- <MSG
|
||||
-- From somewhere, a transmission...<FAO0004<NOD<TRA0018:0501:0002:0000
|
||||
|
||||
-- #0420
|
||||
-- <KEY<DNP0420<MSG<GIT1035<IT+0035
|
||||
-- Found Curly's Panties.<NOD<END
|
Loading…
Reference in a new issue