diff options
-rw-r--r-- | stadiumgs/Makefile | 2 | ||||
-rw-r--r-- | utils/Makefile | 15 | ||||
-rw-r--r-- | utils/cattbl.c | 79 | ||||
-rw-r--r-- | utils/constants.h | 1264 | ||||
-rw-r--r-- | utils/extractbin.c | 107 | ||||
-rw-r--r-- | utils/extractrostertbltbl.c | 50 | ||||
-rw-r--r-- | utils/json2rostertbl.c | 184 |
7 files changed, 1656 insertions, 45 deletions
diff --git a/stadiumgs/Makefile b/stadiumgs/Makefile index 882b36a..dc59f97 100644 --- a/stadiumgs/Makefile +++ b/stadiumgs/Makefile @@ -340,7 +340,7 @@ TBLS = \ # md5 of text.tbl: a8c362b564cd2ca2d48f54dd663ca959 text.tbl: ${TBLS} - ../utils/cattbl ${TBLS} > $@ + ../utils/cattbl 0xd0000 ${TBLS} > $@ clean: rm -f text.tbl ${TBLS} diff --git a/utils/Makefile b/utils/Makefile index 950a29e..6e0f221 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -1,4 +1,15 @@ -all: extractstrtbltbl extractrostertbltbl txt2strtbl cattbl +BINARIES = \ + extractstrtbltbl \ + extractrostertbltbl \ + txt2strtbl \ + cattbl \ + json2rostertbl \ + extractbin + +all: ${BINARIES} + +json2rostertbl: json2rostertbl.c constants.h + cc `pkg-config --cflags --libs json-c` -o $@ json2rostertbl.c clean: - rm -f extractstrtbltbl extractrostertbltbl txt2strtbl cattbl + rm -f ${BINARIES} diff --git a/utils/cattbl.c b/utils/cattbl.c index 494b6b9..99a7349 100644 --- a/utils/cattbl.c +++ b/utils/cattbl.c @@ -15,6 +15,8 @@ */ #include <err.h> +#include <errno.h> +#include <limits.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -33,48 +35,91 @@ int main(int argc, char *argv[]) { int i, runsum, numptrs; + long size; uint32_t *ptrs, *runsums; FILE **f; uint8_t buf[8192]; + char *ep; - if (argc < 2) { - errx(1, "Usage: cattbl file ..."); + if (argc < 3) { + errx(1, "Usage: cattbl size file ..."); } - f = reallocarray(NULL, argc - 1, sizeof *f); - ptrs = reallocarray(NULL, argc - 1, sizeof *ptrs); - runsums = reallocarray(NULL, argc - 1, sizeof *runsums); + size = strtol(argv[1], &ep, 0); + if (argv[1][0] == '\0' || *ep != '\0') { + errx(1, "invalid size '%s'", argv[1]); + } + if (errno == ERANGE && (size == LONG_MAX || size == LONG_MIN)) { + errx(1, "invalid size '%s'", argv[1]); + } + + argc -= 2; + argv += 2; + + f = reallocarray(NULL, argc, sizeof *f); + ptrs = reallocarray(NULL, argc, sizeof *ptrs); + runsums = reallocarray(NULL, argc, sizeof *runsums); numptrs = 0; putuint32BE(0, stdout); putuint32BE(0, stdout); - runsum = 16 + 16 * (argc - 1); - for (i = 1; i < argc; ++i) { - f[i - 1] = fopen(argv[i], "rb"); - if (f[i - 1] == NULL) { + runsum = 16 + 16 * (argc); + for (i = 0; i < argc; ++i) { + if (i > 0 && strcmp(argv[i], argv[i - 1]) == 0) { + runsums[i] = runsums[i - 1]; + ptrs[i] = ptrs[i - 1]; + continue; + } + f[i] = fopen(argv[i], "rb"); + if (f[i] == NULL) { err(1, "Could not open file '%s'", argv[i]); } - fseek(f[i - 1], 0, SEEK_END); - runsums[i - 1] = runsum; - runsum += ftell(f[i - 1]); - ptrs[i - 1] = ftell(f[i - 1]); - fseek(f[i - 1], 0, SEEK_SET); + fseek(f[i], 0, SEEK_END); + runsums[i] = runsum; + runsum += ftell(f[i]); + while (runsum % 16) { + ++runsum; + } + ptrs[i] = ftell(f[i]); + fseek(f[i], 0, SEEK_SET); } putuint32BE(runsum, stdout); - putuint32BE(argc - 1, stdout); - for (i = 0; i < argc - 1; ++i) { + putuint32BE(argc, stdout); + for (i = 0; i < argc; ++i) { + while (ptrs[i] % 16) { + ++ptrs[i]; + } putuint32BE(runsums[i], stdout); putuint32BE(ptrs[i], stdout); putuint32BE(0, stdout); putuint32BE(0, stdout); } - for (i = 0; i < argc - 1; ++i) { + for (i = 0; i < argc; ++i) { + if (i > 0 && strcmp(argv[i], argv[i - 1]) == 0) { + continue; + } size_t n; while ((n = fread(buf, sizeof *buf, sizeof buf, f[i])) > 0) if (fwrite(buf, sizeof *buf, n, stdout) != n) ; + while (ftell(stdout) % 16) { + fputc(0xff, stdout); + } + } + + int padspace; + padspace = size - ftell(stdout); + for (i = 0; i < sizeof buf; ++i) { + buf[i] = 0xff; + } + while (padspace > sizeof buf) { + fwrite(buf, sizeof *buf, sizeof buf, stdout); + padspace -= sizeof buf; } + fwrite(buf, sizeof *buf, padspace, stdout); + + return 0; } diff --git a/utils/constants.h b/utils/constants.h new file mode 100644 index 0000000..2755aaf --- /dev/null +++ b/utils/constants.h @@ -0,0 +1,1264 @@ +char pokemon[][11] = { + "", + "Bulbasaur", + "Ivysaur", + "Venusaur", + "Charmander", + "Charmeleon", + "Charizard", + "Squirtle", + "Wartortle", + "Blastoise", + "Caterpie", + "Metapod", + "Butterfree", + "Weedle", + "Kakuna", + "Beedrill", + "Pidgey", + "Pidgeotto", + "Pidgeot", + "Rattata", + "Raticate", + "Spearow", + "Fearow", + "Ekans", + "Arbok", + "Pikachu", + "Raichu", + "Sandshrew", + "Sandslash", + "Nidoran♀", + "Nidorina", + "Nidoqueen", + "Nidoran♂", + "Nidorino", + "Nidoking", + "Clefairy", + "Clefable", + "Vulpix", + "Ninetales", + "Jigglypuff", + "Wigglytuff", + "Zubat", + "Golbat", + "Oddish", + "Gloom", + "Vileplume", + "Paras", + "Parasect", + "Venonat", + "Venomoth", + "Diglett", + "Dugtrio", + "Meowth", + "Persian", + "Psyduck", + "Golduck", + "Mankey", + "Primeape", + "Growlithe", + "Arcanine", + "Poliwag", + "Poliwhirl", + "Poliwrath", + "Abra", + "Kadabra", + "Alakazam", + "Machop", + "Machoke", + "Machamp", + "Bellsprout", + "Weepinbell", + "Victreebel", + "Tentacool", + "Tentacruel", + "Geodude", + "Graveler", + "Golem", + "Ponyta", + "Rapidash", + "Slowpoke", + "Slowbro", + "Magnemite", + "Magneton", + "Farfetch'd", + "Doduo", + "Dodrio", + "Seel", + "Dewgong", + "Grimer", + "Muk", + "Shellder", + "Cloyster", + "Gastly", + "Haunter", + "Gengar", + "Onix", + "Drowzee", + "Hypno", + "Krabby", + "Kingler", + "Voltorb", + "Electrode", + "Exeggcute", + "Exeggutor", + "Cubone", + "Marowak", + "Hitmonlee", + "Hitmonchan", + "Lickitung", + "Koffing", + "Weezing", + "Rhyhorn", + "Rhydon", + "Chansey", + "Tangela", + "Kangaskhan", + "Horsea", + "Seadra", + "Goldeen", + "Seaking", + "Staryu", + "Starmie", + "Mr.Mime", + "Scyther", + "Jynx", + "Electabuzz", + "Magmar", + "Pinsir", + "Tauros", + "Magikarp", + "Gyarados", + "Lapras", + "Ditto", + "Eevee", + "Vaporeon", + "Jolteon", + "Flareon", + "Porygon", + "Omanyte", + "Omastar", + "Kabuto", + "Kabutops", + "Aerodactyl", + "Snorlax", + "Articuno", + "Zapdos", + "Moltres", + "Dratini", + "Dragonair", + "Dragonite", + "Mewtwo", + "Mew", + "Chikorita", + "Bayleef", + "Meganium", + "Cyndaquil", + "Quilava", + "Typhlosion", + "Totodile", + "Croconaw", + "Feraligatr", + "Sentret", + "Furret", + "Hoothoot", + "Noctowl", + "Ledyba", + "Ledian", + "Spinarak", + "Ariados", + "Crobat", + "Chinchou", + "Lanturn", + "Pichu", + "Cleffa", + "Igglybuff", + "Togepi", + "Togetic", + "Natu", + "Xatu", + "Mareep", + "Flaaffy", + "Ampharos", + "Bellossom", + "Marill", + "Azumarill", + "Sudowoodo", + "Politoed", + "Hoppip", + "Skiploom", + "Jumpluff", + "Aipom", + "Sunkern", + "Sunflora", + "Yanma", + "Wooper", + "Quagsire", + "Espeon", + "Umbreon", + "Murkrow", + "Slowking", + "Misdreavus", + "Unown", + "Wobbuffet", + "Girafarig", + "Pineco", + "Forretress", + "Dunsparce", + "Gligar", + "Steelix", + "Snubbull", + "Granbull", + "Qwilfish", + "Scizor", + "Shuckle", + "Heracross", + "Sneasel", + "Teddiursa", + "Ursaring", + "Slugma", + "Magcargo", + "Swinub", + "Piloswine", + "Corsola", + "Remoraid", + "Octillery", + "Delibird", + "Mantine", + "Skarmory", + "Houndour", + "Houndoom", + "Kingdra", + "Phanpy", + "Donphan", + "Porygon2", + "Stantler", + "Smeargle", + "Tyrogue", + "Hitmontop", + "Smoochum", + "Elekid", + "Magby", + "Miltank", + "Blissey", + "Raikou", + "Entei", + "Suicune", + "Larvitar", + "Pupitar", + "Tyranitar", + "Lugia", + "Ho-oh", + "Celebi", + "???", + "Egg" +}; + +char moves[][15] = { + "", + "Pound", + "Karate Chop", + "Doubleslap", + "Comet Punch", + "Mega Punch", + "Pay Day", + "Fire Punch", + "Ice Punch", + "Thunderpunch", + "Scratch", + "Vicegrip", + "Guillotine", + "Razor Wind", + "Swords Dance", + "Cut", + "Gust", + "Wing Attack", + "Whirlwind", + "Fly", + "Bind", + "Slam", + "Vine Whip", + "Stomp", + "Double Kick", + "Mega Kick", + "Jump Kick", + "Rolling Kick", + "Sand-Attack", + "Headbutt", + "Horn Attack", + "Fury Attack", + "Horn Drill", + "Tackle", + "Body Slam", + "Wrap", + "Take Down", + "Thrash", + "Double-Edge", + "Tail Whip", + "Poison Sting", + "Twineedle", + "Pin Missile", + "Leer", + "Bite", + "Growl", + "Roar", + "Sing", + "Supersonic", + "Sonicboom", + "Disable", + "Acid", + "Ember", + "Flamethrower", + "Mist", + "Water Gun", + "Hydro Pump", + "Surf", + "Ice Beam", + "Blizzard", + "Psybeam", + "Bubblebeam", + "Aurora Beam", + "Hyper Beam", + "Peck", + "Drill Peck", + "Submission", + "Low Kick", + "Counter", + "Seismic Toss", + "Strength", + "Absorb", + "Mega Drain", + "Leech Seed", + "Growth", + "Razor Leaf", + "Solarbeam", + "Poisonpowder", + "Stun Spore", + "Sleep Powder", + "Petal Dance", + "String Shot", + "Dragon Rage", + "Fire Spin", + "Thundershock", + "Thunderbolt", + "Thunder Wave", + "Thunder", + "Rock Throw", + "Earthquake", + "Fissure", + "Dig", + "Toxic", + "Confusion", + "Psychic", + "Hypnosis", + "Meditate", + "Agility", + "Quick Attack", + "Rage", + "Teleport", + "Night Shade", + "Mimic", + "Screech", + "Double Team", + "Recover", + "Harden", + "Minimize", + "Smokescreen", + "Confuse Ray", + "Withdraw", + "Defense Curl", + "Barrier", + "Light Screen", + "Haze", + "Reflect", + "Focus Energy", + "Bide", + "Metronome", + "Mirror Move", + "Selfdestruct", + "Egg Bomb", + "Lick", + "Smog", + "Sludge", + "Bone Club", + "Fire Blast", + "Waterfall", + "Clamp", + "Swift", + "Skull Bash", + "Spike Cannon", + "Constrict", + "Amnesia", + "Kinesis", + "Softboiled", + "Hi Jump Kick", + "Glare", + "Dream Eater", + "Poison Gas", + "Barrage", + "Leech Life", + "Lovely Kiss", + "Sky Attack", + "Transform", + "Bubble", + "Dizzy Punch", + "Spore", + "Flash", + "Psywave", + "Splash", + "Acid Armor", + "Crabhammer", + "Explosion", + "Fury Swipes", + "Bonemerang", + "Rest", + "Rock Slide", + "Hyper Fang", + "Sharpen", + "Conversion", + "Tri Attack", + "Super Fang", + "Slash", + "Substitute", + "Struggle", + "Sketch", + "Triple Kick", + "Thief", + "Spider Web", + "Mind Reader", + "Nightmare", + "Flame Wheel", + "Snore", + "Curse", + "Flail", + "Conversion 2", + "Aeroblast", + "Cotton Spore", + "Reversal", + "Spite", + "Powder Snow", + "Protect", + "Mach Punch", + "Scary Face", + "Faint Attack", + "Sweet Kiss", + "Belly Drum", + "Sludge Bomb", + "Mud-Slap", + "Octazooka", + "Spikes", + "Zap Cannon", + "Foresight", + "Destiny Bond", + "Perish Song", + "Icy Wind", + "Detect", + "Bone Rush", + "Lock-On", + "Outrage", + "Sandstorm", + "Giga Drain", + "Endure", + "Charm", + "Rollout", + "False Swipe", + "Swagger", + "Milk Drink", + "Spark", + "Fury Cutter", + "Steel Wing", + "Mean Look", + "Attract", + "Sleep Talk", + "Heal Bell", + "Return", + "Present", + "Frustration", + "Safeguard", + "Pain Split", + "Sacred Fire", + "Magnitude", + "Dynamicpunch", + "Megahorn", + "Dragonbreath", + "Baton Pass", + "Encore", + "Pursuit", + "Rapid Spin", + "Sweet Scent", + "Iron Tail", + "Metal Claw", + "Vital Throw", + "Morning Sun", + "Synthesis", + "Moonlight", + "Hidden Power", + "Cross Chop", + "Twister", + "Rain Dance", + "Sunny Day", + "Crunch", + "Mirror Coat", + "Psych Up", + "Extremespeed", + "Ancientpower", + "Shadow Ball", + "Future Sight", + "Rock Smash", + "Whirlpool", + "Beat Up" +}; + +char groups[][18] = { + "", + "Medium", + "Cooltrainer♂", + "Cooltrainer♀", + "Beauty", + "Officer", + "Pokémaniac", + "Swimmer♂", + "Burglar", + "Blackbelt", + "Guitarist", + "Camper", + "Psychic", + "Gentleman", + "Juggler", + "Schoolboy", + "Skier", + "Teacher", + "Pokéfan♂", + "Pokéfan♀", + "Youngster", + "Fisherman", + "Bird Keeper", + "Scientist", + "Swimmer♀", + "Picnicker", + "Firebreather", + "Twins", + "Sailor", + "Sage", + "Biker", + "Boarder", + "Kimono Girl", + "Lass", + "Bug Catcher", + "Hiker", + "Super Nerd", + "Grunt♂", + "Grunt♀", + "Champion", + "Elite Four", + "Gym Leader", + "Pokémon Trainer", + "Rival", + "Executive♂", + "Executive♀", + "Rival1", + "Rival2", + "Rival3", + "Rival4", + "Rival5", + "Rival6", + "Rival7", + "Rival8", + "Rival9", + "Rival10", + "Rival11", + "Rival12", + "Rival13", + "Rival14", + "Rival15", + "Rival16", + "Rival17" +}; + +char trainers[][15] = { + "", + "Grunt", + "Executive", + "Rival", + "Lance", + "Will", + "Bruno", + "Karen", + "Koga", + "Clair", + "Chuck", + "Jasmine", + "Pryce", + "Morty", + "Bugsy", + "Whitney", + "Falkner", + "Cal", + "Red", + "Blue", + "Blaine", + "Sabrina", + "Janine", + "Erika", + "Lt.Surge", + "Misty", + "Brock", + "Clark", + "Marty", + "Yang", + "Bruce", + "Jensen", + "Craig", + "Roberto", + "Chester", + "Clifford", + "Pedro", + "Baxter", + "Curtis", + "Cliff", + "Dillon", + "Marcus", + "Dwight", + "Curt", + "Gerald", + "Travis", + "Oliver", + "Mason", + "Claude", + "Darcy", + "Bernie", + "Wyatt", + "Adam", + "Daren", + "Nelson", + "Terry", + "Kathy", + "Melissa", + "Emiko", + "Chase", + "Grant", + "Rex", + "Chen", + "Ty", + "Vince", + "Nick", + "Alvin", + "Matt", + "Chaz", + "Peggy", + "Holly", + "Jan&Jane", + "Min&Lyn", + "Floria", + "Tina", + "Janet", + "Cora", + "Stacy", + "Alissa", + "Molly", + "Carmen", + "Gloria", + "Rita", + "Carol", + "Lois", + "1P", + "2P", + "Rental", + "1P", + "Cole", + "Melvin", + "Carson", + "Clayton", + "Jonathan", + "Cyndy", + "Nancy", + "Joseph", + "Naomi", + "Tammy", + "Dustin", + "Nolan", + "Connor", + "Becky", + "Ferris", + "Julian", + "Student", + "Carrie" +}; + +char items[][20] = { + "", + "Master Ball", + "Ultra Ball", + "Bright Powder", + "Great Ball", + "Poké Ball", + "teru-sama", + "Bicycle", + "Moon Stone", + "Antidote", + "Burn Heal", + "Ice Heal", + "Awakening", + "Parlyz Heal", + "Full Restore", + "Max Potion", + "Hyper Potion", + "Super Potion", + "Potion", + "Escape Rope", + "Repel", + "Max Elixer", + "Fire Stone", + "Thunderstone", + "Water Stone", + "teru-sama", + "HP Up", + "Protein", + "Iron", + "Carbos", + "Lucky Punch", + "Calcium", + "Rare Candy", + "X Accuracy", + "Leaf Stone", + "Metal Powder", + "Nugget", + "PokÉ Doll", + "Full Heal", + "Revive", + "Max Revive", + "Guard Spec.", + "Super Repel", + "Max Repel", + "Dire Hit", + "teru-sama", + "Fresh Water", + "Soda Pop", + "Lemonade", + "X Attack", + "teru-sama", + "X Defend", + "X Speed", + "X Special", + "Coin Case", + "Itemfinder", + "teru-sama", + "Exp. Share", + "Old Rod", + "Good Rod", + "Silver Leaf", + "Super Rod", + "PP Up", + "Ether", + "Max Ether", + "Elixer", + "Red Scale", + "Secretpotion", + "S.S. Ticket", + "Mystery Egg", + "Clear Bell", + "Silver Wing", + "Moomoo Milk", + "Quick Claw", + "Psncureberry", + "Gold Leaf", + "Soft Sand", + "Sharp Beak", + "Przcureberry", + "Burnt Berry", + "Ice Berry", + "Poison Barb", + "King's Rock", + "Bitter Berry", + "Mint Berry", + "Red Apricorn", + "Tinymushroom", + "Big Mushroom", + "Silverpowder", + "Blu Apricorn", + "teru-sama", + "Amulet Coin", + "Ylw Apricorn", + "Grn Apricorn", + "Cleanse Tag", + "Mystic Water", + "Twistedspoon", + "Wht Apricorn", + "Black Belt", + "Blk Apricorn", + "teru-sama", + "Pnk Apricorn", + "Blackglasses", + "Slowpoketail", + "Pink Bow", + "Stick", + "Smoke Ball", + "Nevermeltice", + "Magnet", + "Miracleberry", + "Pearl", + "Big Pearl", + "Everstone", + "Spell Tag", + "Ragecandybar", + "Gs Ball", + "Blue Card", + "Miracle Seed", + "Thick Club", + "Focus Band", + "teru-sama", + "Energypowder", + "Energy Root", + "Heal Powder", + "Revival Herb", + "Hard Stone", + "Lucky Egg", + "Card Key", + "Machine Part", + "Egg Ticket", + "Lost Item", + "Stardust", + "Star Piece", + "Basement Key", + "Pass", + "teru-sama", + "teru-sama", + "teru-sama", + "Charcoal", + "Berry Juice", + "Scope Lens", + "teru-sama", + "teru-sama", + "Metal Coat", + "Dragon Fang", + "teru-sama", + "Leftovers", + "teru-sama", + "teru-sama", + "teru-sama", + "Mysteryberry", + "Dragon Scale", + "Berserk Gene", + "teru-sama", + "teru-sama", + "teru-sama", + "Sacred Ash", + "Heavy Ball", + "Flower Mail", + "Level Ball", + "Lure Ball", + "Fast Ball", + "teru-sama", + "Light Ball", + "Friend Ball", + "Moon Ball", + "Love Ball", + "Normal Box", + "Gorgeous Box", + "Sun Stone", + "Polkadot Bow", + "teru-sama", + "Up-Grade", + "Berry", + "Gold Berry", + "Squirtbottle", + "teru-sama", + "Park Ball", + "Rainbow Wing", + "teru-sama", + "Brick Piece", + "Surf Mail", + "Liteblue Mail", + "Portrait Mail", + "Lovely Mail", + "Eon Mail", + "Morph Mail", + "Bluesky Mail", + "Music Mail", + "Mirage Mail", + "teru-sama", + "TM01", + "TM02", + "TM03", + "TM04", + "teru-sama", + "TM05", + "TM06", + "TM07", + "TM08", + "TM09", + "TM10", + "TM11", + "TM12", + "TM13", + "TM14", + "TM15", + "TM16", + "TM17", + "TM18", + "TM19", + "TM20", + "TM21", + "TM22", + "TM23", + "TM24", + "TM25", + "TM26", + "TM27", + "TM28", + "teru-sama", + "TM29", + "TM30", + "TM31", + "TM32", + "TM33", + "TM34", + "TM35", + "TM36", + "TM37", + "TM38", + "TM39", + "TM40", + "TM41", + "TM42", + "TM43", + "TM44", + "TM45", + "TM46", + "TM47", + "TM48", + "TM49", + "TM50", + "HM01", + "HM02", + "HM03", + "HM04", + "HM05", + "HM06", + "HM07" +}; + +char texts[][50] = { + "text/cal.txt", + "text/gymleadercastle/violet/matt1.txt", + "text/gymleadercastle/violet/falkner1.txt", + "text/gymleadercastle/azalea/chaz1.txt", + "text/gymleadercastle/azalea/minlyn1.txt", + "text/gymleadercastle/azalea/bugsy1.txt", + "text/gymleadercastle/goldenrod/lois1.txt", + "text/gymleadercastle/goldenrod/rita1.txt", + "text/gymleadercastle/goldenrod/whitney1.txt", + "text/gymleadercastle/ecruteak/ty1.txt", + "text/gymleadercastle/ecruteak/holly1.txt", + "text/gymleadercastle/ecruteak/morty1.txt", + "text/gymleadercastle/cianwood/nick1.txt", + "text/gymleadercastle/cianwood/chuck1.txt", + "text/gymleadercastle/olivine/jasmine1.txt", + "text/gymleadercastle/rocket/gruntm1.txt", + "text/gymleadercastle/rocket/gruntf1.txt", + "text/gymleadercastle/rocket/executivef1.txt", + "text/gymleadercastle/rocket/executivem1.txt", + "text/gymleadercastle/mahogany/alvin1.txt", + "text/gymleadercastle/mahogany/carol1.txt", + "text/gymleadercastle/mahogany/pryce1.txt", + "text/gymleadercastle/blackthorn/gloria1.txt", + "text/gymleadercastle/blackthorn/vince1.txt", + "text/gymleadercastle/blackthorn/clair1.txt", + "text/gymleadercastle/indigo/will1.txt", + "text/gymleadercastle/indigo/koga1.txt", + "text/gymleadercastle/indigo/bruno1.txt", + "text/gymleadercastle/indigo/karen1.txt", + "text/gymleadercastle/indigo/lance1.txt", + "text/gymleadercastle/kanto/surge1.txt", + "text/gymleadercastle/kanto/sabrina1.txt", + "text/gymleadercastle/kanto/misty1.txt", + "text/gymleadercastle/kanto/erika1.txt", + "text/gymleadercastle/kanto/janine1.txt", + "text/gymleadercastle/kanto/brock1.txt", + "text/gymleadercastle/kanto/blaine1.txt", + "text/gymleadercastle/kanto/blue1.txt", + "text/gymleadercastle/kanto/red1.txt", + "text/rival1.txt", + "text/pokecup/pokeball/nelson1.txt", + "text/pokecup/pokeball/bruce1.txt", + "text/pokecup/pokeball/chester1.txt", + "text/pokecup/pokeball/clifford1.txt", + "text/pokecup/pokeball/alissa1.txt", + "text/pokecup/pokeball/jensen1.txt", + "text/pokecup/pokeball/claude1.txt", + "text/pokecup/pokeball/mason1.txt", + "text/pokecup/greatball/carmen1.txt", + "text/pokecup/greatball/wyatt1.txt", + "text/pokecup/greatball/cliff1.txt", + "text/pokecup/greatball/dillon1.txt", + "text/pokecup/greatball/molly1.txt", + "text/pokecup/greatball/baxter1.txt", + "text/pokecup/greatball/chen1.txt", + "text/pokecup/greatball/pedro1.txt", + "text/pokecup/ultraball/nelson1.txt", + "text/pokecup/ultraball/bruce1.txt", + "text/pokecup/ultraball/chester1.txt", + "text/pokecup/ultraball/clifford1.txt", + "text/pokecup/ultraball/alissa1.txt", + "text/pokecup/ultraball/jensen1.txt", + "text/pokecup/ultraball/claude1.txt", + "text/pokecup/ultraball/mason1.txt", + "text/pokecup/masterball/carmen1.txt", + "text/pokecup/masterball/wyatt1.txt", + "text/pokecup/masterball/cliff1.txt", + "text/pokecup/masterball/dillon1.txt", + "text/pokecup/masterball/molly1.txt", + "text/pokecup/masterball/baxter1.txt", + "text/pokecup/masterball/chen1.txt", + "text/pokecup/masterball/pedro1.txt", + "text/challengecup/pokeball/marcus1.txt", + "text/challengecup/pokeball/peggy1.txt", + "text/challengecup/pokeball/gruntm1.txt", + "text/challengecup/pokeball/melissa1.txt", + "text/challengecup/pokeball/daren1.txt", + "text/challengecup/greatball/curt1.txt", + "text/challengecup/pokeball/gruntf1.txt", + "text/challengecup/pokeball/dwight1.txt", + "text/challengecup/greatball/janjane1.txt", + "text/challengecup/pokeball/curtis1.txt", + "text/challengecup/greatball/oliver1.txt", + "text/challengecup/greatball/darcy1.txt", + "text/challengecup/greatball/gerald1.txt", + "text/challengecup/greatball/emiko1.txt", + "text/challengecup/greatball/roberto1.txt", + "text/challengecup/greatball/travis1.txt", + "text/challengecup/ultraball/marcus1.txt", + "text/challengecup/ultraball/peggy1.txt", + "text/challengecup/ultraball/gruntm1.txt", + "text/challengecup/ultraball/melissa1.txt", + "text/challengecup/ultraball/daren1.txt", + "text/challengecup/masterball/curt1.txt", + "text/challengecup/ultraball/gruntf1.txt", + "text/challengecup/ultraball/dwight1.txt", + "text/challengecup/masterball/janjane1.txt", + "text/challengecup/ultraball/curtis1.txt", + "text/challengecup/masterball/oliver1.txt", + "text/challengecup/masterball/darcy1.txt", + "text/challengecup/masterball/gerald1.txt", + "text/challengecup/masterball/emiko1.txt", + "text/challengecup/masterball/roberto1.txt", + "text/challengecup/masterball/travis1.txt", + "text/littlecup/bernie1.txt", + "text/littlecup/stacy1.txt", + "text/littlecup/grant1.txt", + "text/littlecup/janet1.txt", + "text/littlecup/clark1.txt", + "text/littlecup/cora1.txt", + "text/littlecup/tina1.txt", + "text/littlecup/rex1.txt", + "text/primecup/terry1.txt", + "text/primecup/yang1.txt", + "text/primecup/adam1.txt", + "text/primecup/floria1.txt", + "text/primecup/chase1.txt", + "text/primecup/craig1.txt", + "text/primecup/kathy1.txt", + "text/primecup/marty1.txt", + "text/gymleadercastle/violet/matt2.txt", + "text/gymleadercastle/violet/falkner2.txt", + "text/gymleadercastle/azalea/chaz2.txt", + "text/gymleadercastle/azalea/minlyn2.txt", + "text/gymleadercastle/azalea/bugsy2.txt", + "text/gymleadercastle/goldenrod/lois2.txt", + "text/gymleadercastle/goldenrod/rita2.txt", + "text/gymleadercastle/goldenrod/whitney2.txt", + "text/gymleadercastle/ecruteak/ty2.txt", + "text/gymleadercastle/ecruteak/holly2.txt", + "text/gymleadercastle/ecruteak/morty2.txt", + "text/gymleadercastle/cianwood/nick2.txt", + "text/gymleadercastle/cianwood/chuck2.txt", + "text/gymleadercastle/olivine/jasmine2.txt", + "text/gymleadercastle/rocket/gruntm2.txt", + "text/gymleadercastle/rocket/gruntf2.txt", + "text/gymleadercastle/rocket/executivef2.txt", + "text/gymleadercastle/rocket/executivem2.txt", + "text/gymleadercastle/mahogany/alvin2.txt", + "text/gymleadercastle/mahogany/carol2.txt", + "text/gymleadercastle/mahogany/pryce2.txt", + "text/gymleadercastle/blackthorn/gloria2.txt", + "text/gymleadercastle/blackthorn/vince2.txt", + "text/gymleadercastle/blackthorn/clair2.txt", + "text/gymleadercastle/indigo/will2.txt", + "text/gymleadercastle/indigo/koga2.txt", + "text/gymleadercastle/indigo/bruno2.txt", + "text/gymleadercastle/indigo/karen2.txt", + "text/gymleadercastle/indigo/lance2.txt", + "text/gymleadercastle/kanto/surge2.txt", + "text/gymleadercastle/kanto/sabrina2.txt", + "text/gymleadercastle/kanto/misty2.txt", + "text/gymleadercastle/kanto/erika2.txt", + "text/gymleadercastle/kanto/janine2.txt", + "text/gymleadercastle/kanto/brock2.txt", + "text/gymleadercastle/kanto/blaine2.txt", + "text/gymleadercastle/kanto/blue2.txt", + "text/gymleadercastle/kanto/red2.txt", + "text/pokecup/pokeball/nelson2.txt", + "text/pokecup/pokeball/bruce2.txt", + "text/pokecup/pokeball/chester2.txt", + "text/pokecup/pokeball/clifford2.txt", + "text/pokecup/pokeball/alissa2.txt", + "text/pokecup/pokeball/jensen2.txt", + "text/pokecup/pokeball/claude2.txt", + "text/pokecup/pokeball/mason2.txt", + "text/pokecup/greatball/carmen2.txt", + "text/pokecup/greatball/wyatt2.txt", + "text/pokecup/greatball/cliff2.txt", + "text/pokecup/greatball/dillon2.txt", + "text/pokecup/greatball/molly2.txt", + "text/pokecup/greatball/baxter2.txt", + "text/pokecup/greatball/chen2.txt", + "text/pokecup/greatball/pedro2.txt", + "text/pokecup/ultraball/nelson2.txt", + "text/pokecup/ultraball/bruce2.txt", + "text/pokecup/ultraball/chester2.txt", + "text/pokecup/ultraball/clifford2.txt", + "text/pokecup/ultraball/alissa2.txt", + "text/pokecup/ultraball/jensen2.txt", + "text/pokecup/ultraball/claude2.txt", + "text/pokecup/ultraball/mason2.txt", + "text/pokecup/masterball/carmen2.txt", + "text/pokecup/masterball/wyatt2.txt", + "text/pokecup/masterball/cliff2.txt", + "text/pokecup/masterball/dillon2.txt", + "text/pokecup/masterball/molly2.txt", + "text/pokecup/masterball/baxter2.txt", + "text/pokecup/masterball/chen2.txt", + "text/pokecup/masterball/pedro2.txt", + "text/challengecup/pokeball/marcus2.txt", + "text/challengecup/pokeball/peggy2.txt", + "text/challengecup/pokeball/executivem2.txt", + "text/challengecup/pokeball/melissa2.txt", + "text/challengecup/pokeball/daren2.txt", + "text/challengecup/greatball/curt2.txt", + "text/challengecup/pokeball/executivef2.txt", + "text/challengecup/pokeball/dwight2.txt", + "text/challengecup/greatball/janjane2.txt", + "text/challengecup/pokeball/curtis2.txt", + "text/challengecup/greatball/oliver2.txt", + "text/challengecup/greatball/darcy2.txt", + "text/challengecup/greatball/gerald2.txt", + "text/challengecup/greatball/emiko2.txt", + "text/challengecup/greatball/roberto2.txt", + "text/challengecup/greatball/travis2.txt", + "text/challengecup/ultraball/marcus2.txt", + "text/challengecup/ultraball/peggy2.txt", + "text/challengecup/ultraball/executivem2.txt", + "text/challengecup/ultraball/melissa2.txt", + "text/challengecup/ultraball/daren2.txt", + "text/challengecup/masterball/curt2.txt", + "text/challengecup/ultraball/executivef2.txt", + "text/challengecup/ultraball/dwight2.txt", + "text/challengecup/masterball/janjane2.txt", + "text/challengecup/ultraball/curtis2.txt", + "text/challengecup/masterball/oliver2.txt", + "text/challengecup/masterball/darcy2.txt", + "text/challengecup/masterball/gerald2.txt", + "text/challengecup/masterball/emiko2.txt", + "text/challengecup/masterball/roberto2.txt", + "text/challengecup/masterball/travis2.txt", + "text/littlecup/bernie2.txt", + "text/littlecup/stacy2.txt", + "text/littlecup/grant2.txt", + "text/littlecup/janet2.txt", + "text/littlecup/clark2.txt", + "text/littlecup/cora2.txt", + "text/littlecup/tina2.txt", + "text/littlecup/rex2.txt", + "text/primecup/terry2.txt", + "text/primecup/yang2.txt", + "text/primecup/adam2.txt", + "text/primecup/floria2.txt", + "text/primecup/chase2.txt", + "text/primecup/craig2.txt", + "text/primecup/kathy2.txt", + "text/primecup/marty2.txt", + "text/rival2.txt", + "text/academy/skilltest/trainer/cole.txt", + "text/academy/skilltest/trainer/melvin.txt", + "text/academy/skilltest/trainer/carson.txt", + "text/academy/skilltest/trainer/clayton.txt", + "text/academy/skilltest/trainer/jonathan.txt", + "text/academy/skilltest/trainer/cyndy.txt", + "text/academy/skilltest/trainer/nancy.txt", + "text/academy/skilltest/gymleader/joseph.txt", + "text/academy/skilltest/gymleader/naomi.txt", + "text/academy/skilltest/gymleader/tammy.txt", + "text/academy/skilltest/gymleader/dustin.txt", + "text/academy/skilltest/gymleader/nolan.txt", + "text/academy/skilltest/elitefour/connor.txt", + "text/academy/skilltest/elitefour/becky.txt", + "text/academy/skilltest/elitefour/ferris.txt", + "text/academy/skilltest/elitefour/julian.txt" +}; + +int +strtopokemon(const char *s) +{ + int i; + for (i = 0; i < 254; ++i) { + if (strcasecmp(s, pokemon[i]) == 0) { + return i; + } + } +} + +int +strtoitem(const char *s) +{ + int i; + for (i = 0; i < 250; ++i) { + if (strcasecmp(s, items[i]) == 0) { + return i; + } + } +} + +int +strtomove(const char *s) +{ + int i; + for (i = 0; i < 252; ++i) { + if (strcasecmp(s, moves[i]) == 0) { + return i; + } + } +} + +int +strtogroup(const char *s) +{ + int i; + for (i = 0; i < 63; ++i) { + if (strcasecmp(s, groups[i]) == 0) { + return i; + } + } +} + +int +strtotrainer(const char *s) +{ + int i; + for (i = 0; i < 106; ++i) { + if (strcasecmp(s, trainers[i]) == 0) { + return i; + } + } +} + +int +strtotext(const char *s) +{ + int i; + for (i = 0; i < 255; ++i) { + if (strcasecmp(s, texts[i]) == 0) { + return i; + } + } +} diff --git a/utils/extractbin.c b/utils/extractbin.c new file mode 100644 index 0000000..aed6163 --- /dev/null +++ b/utils/extractbin.c @@ -0,0 +1,107 @@ +/* + * Copyright © 2014 IIMarckus <imarckus@gmail.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Dump a table of files to individual binary files. + */ + +#include <err.h> +#include <errno.h> +#include <limits.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +/* 0x1708000 in Stadium GS */ + +uint32_t +getint32BE(FILE *f) +{ + uint32_t n; + n = fgetc(f) << 24; + n |= fgetc(f) << 16; + n |= fgetc(f) << 8; + n |= fgetc(f); + + return n; +} + +int +main(int argc, char *argv[]) +{ + FILE *rom; + FILE *outfile; + uint32_t ntables, nentries; + uint32_t *tableptrs, *sizes; + int i, x, table, entry; + char outfilename[16]; + char *ep; + unsigned long long dataoff; + + if (argc != 3) { + errx(1, "Usage: extractbin file offset"); + } + + rom = fopen(argv[1], "rb"); + if (rom == NULL) { + err(1, "Error opening file '%s'", argv[1]); + } + + dataoff = strtoull(argv[2], &ep, 0); + if (argv[2][0] == '\0' || *ep != '\0') { + err(1, "invalid offset '%s'", argv[2]); + } + if (errno == ERANGE && dataoff == ULLONG_MAX) { + err(1, "invalid offset '%s'", argv[2]); + } + if (dataoff > 64 * 1024 * 1024) { + err(1, "invalid offset '%s'", argv[2]); + } + + fseek(rom, dataoff + 0xc, SEEK_SET); + ntables = getint32BE(rom); + tableptrs = reallocarray(NULL, ntables, sizeof(uint32_t)); + sizes = reallocarray(NULL, ntables, sizeof(uint32_t)); + if (tableptrs == NULL || sizes == NULL) { + err(1, "Could not allocate memory for table table"); + } + + for (i = 0; i < ntables; ++i) { + tableptrs[i] = getint32BE(rom); + sizes[i] = getint32BE(rom); + getint32BE(rom); + getint32BE(rom); + } + printf("%d tables\n", ntables); + + for (table = 0; table < ntables; ++table) { + for (i = 0; i < 16; ++i) { + fseek(rom, dataoff + tableptrs[table] + sizes[table] - i - 1, SEEK_SET); + if (fgetc(rom) != 0xff) { + sizes[table] -= i; + break; + } + } + fseek(rom, dataoff + tableptrs[table], SEEK_SET); + snprintf(outfilename, sizeof outfilename, "0x%x.bin", ftell(rom)); + outfile = fopen(outfilename, "wb"); + + for (i = 0; i < sizes[table]; ++i) { + fputc(fgetc(rom), outfile); + } + fclose(outfile); + } +} diff --git a/utils/extractrostertbltbl.c b/utils/extractrostertbltbl.c index a1d0cf0..06465c4 100644 --- a/utils/extractrostertbltbl.c +++ b/utils/extractrostertbltbl.c @@ -543,8 +543,8 @@ char moves[][15] = { char groups[][18] = { "", "Medium", - "Cooltrainer", - "Cooltrainer", + "Cooltrainer♂", + "Cooltrainer♀", "Beauty", "Officer", "Pokémaniac", @@ -559,8 +559,8 @@ char groups[][18] = { "Schoolboy", "Skier", "Teacher", - "Pokéfan", - "Pokéfan", + "Pokéfan♂", + "Pokéfan♀", "Youngster", "Fisherman", "Bird Keeper", @@ -578,32 +578,32 @@ char groups[][18] = { "Bug Catcher", "Hiker", "Super Nerd", - "Rocket", - "Rocket", + "Grunt♂", + "Grunt♀", "Champion", "Elite Four", "Gym Leader", "Pokémon Trainer", "Rival", - "Rocket", - "Rocket", - "Rival", - "Rival", - "Rival", - "Rival", - "Rival", - "Rival", - "Rival", - "Rival", - "Rival", - "Rival", - "Rival", - "Rival", - "Rival", - "Rival", - "Rival", - "Rival", - "Rival" + "Executive♂", + "Executive♀", + "Rival1", + "Rival2", + "Rival3", + "Rival4", + "Rival5", + "Rival6", + "Rival7", + "Rival8", + "Rival9", + "Rival10", + "Rival11", + "Rival12", + "Rival13", + "Rival14", + "Rival15", + "Rival16", + "Rival17" }; char trainers[][15] = { diff --git a/utils/json2rostertbl.c b/utils/json2rostertbl.c new file mode 100644 index 0000000..6b31cef --- /dev/null +++ b/utils/json2rostertbl.c @@ -0,0 +1,184 @@ +#include <err.h> +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <json_tokener.h> +#include <json_util.h> + +#include "constants.h" + +void printpokemon(struct json_object *); + +void +required8int(struct json_object *k, struct json_object *l, const char *s) +{ + if (!json_object_object_get_ex(k, s, &l)) { + errx(1, "Needs a '%s'!", s); + } + fputc(json_object_get_int(l), stdout); +} + +void +required8id(struct json_object *k, struct json_object *l, const char *s, + int (*f)(const char *)) +{ + if (!json_object_object_get_ex(k, s, &l)) { + errx(1, "Needs a '%s'!", s); + } + fputc(f(json_object_get_string(l)), stdout); +} + +void +optional8id(struct json_object *k, struct json_object *l, const char *s, + int (*f)(const char *)) +{ + if (!json_object_object_get_ex(k, s, &l)) { + fputc(0, stdout); + } else { + fputc(f(json_object_get_string(l)), stdout); + } +} + +void +optional8strint(struct json_object *k, struct json_object *l, const char *s) +{ + if (!json_object_object_get_ex(k, s, &l)) { + fputc(0, stdout); + } else { + char *ep; + unsigned long x; + x = strtoul(json_object_get_string(l), &ep, 0); + if (json_object_get_string(l)[0] == '\0' || *ep != '\0') { + errx(1, "invalid number for '%s'", s); + } + if (errno == ERANGE && x == ULONG_MAX) { + errx(1, "invalid number for '%s'", s); + } + fputc(x, stdout); + } +} + +void +required16strint(struct json_object *k, struct json_object *l, const char *s) +{ + if (!json_object_object_get_ex(k, s, &l)) { + errx(1, "Needs a '%s'!", s); + } else { + char *ep; + unsigned long x; + x = strtoul(json_object_get_string(l), &ep, 0); + if (json_object_get_string(l)[0] == '\0' || *ep != '\0') { + errx(1, "invalid number for '%s'", s); + } + if (errno == ERANGE && x == ULONG_MAX) { + errx(1, "invalid number for '%s'", s); + } + fputc(x >> 8, stdout); + fputc(x & 0xff, stdout); + } +} + +int +main(int argc, char *argv[]) +{ + struct json_object *j, *k, *l; + int len, i; + + if (argc != 2) { + errx(1, "usage: json2rostertbl file"); + } + + j = json_object_from_file(argv[1]); + + len = json_object_array_length(j); + + if (len > 50) { + /* rentals */ + fputc(len, stdout); + fputc(0, stdout); + fputc(0, stdout); + fputc(0, stdout); + for (i = 0; i < len; ++i) { + printpokemon(json_object_array_get_idx(j, i)); + } + } else { + /* rosters */ + fputc(len, stdout); + fputc(0, stdout); + fputc(0, stdout); + fputc(0, stdout); + for (i = 0; i < len; ++i) { + k = json_object_array_get_idx(j, i); + required8id(k, l, "group", strtogroup); + required8id(k, l, "trainer", strtotrainer); + optional8strint(k, l, "unknown1"); + required8id(k, l, "text", strtotext); + + if (!json_object_object_get_ex(k, "pokemon", &l)) { + errx(1, "Needs a pokemon!"); + } + fputc(json_object_array_length(l), stdout); + + struct json_object *m; + optional8strint(k, m, "unknown3"); + optional8strint(k, m, "unknown4"); + optional8strint(k, m, "unknown5"); + + int z; + struct json_object *o; + for (z = 0; z < json_object_array_length(l); ++z) { + printpokemon(json_object_array_get_idx(l, z)); + } + while (z++ < 6) { + /* + * XXX should create a json string for generic + * pokemon, parse it here, and pass it to + * printpokemon() + */ + fputc(1, stdout); + fputc(1, stdout); + int A; + for (A = 0; A < 7; ++A) { + fputc(0, stdout); + } + fputc(0x7f, stdout); + for (A = 0; A < 10; ++A) { + fputc(0, stdout); + } + fputc(0x67, stdout); + fputc(0x77, stdout); + fputc(0, stdout); + fputc(0, stdout); + } + } + } + + return 0; +} + +void +printpokemon(struct json_object *k) +{ + struct json_object *l; + required8int(k, l, "level"); + required8id(k, l, "species", strtopokemon); + optional8id(k, l, "item", strtoitem); + optional8strint(k, l, "unknown1"); + required8id(k, l, "move1", strtomove); + optional8id(k, l, "move2", strtomove); + optional8id(k, l, "move3", strtomove); + optional8id(k, l, "move4", strtomove); + optional8strint(k, l, "unknown2"); + optional8strint(k, l, "unknown3"); + required16strint(k, l, "hp exp"); + required16strint(k, l, "attack exp"); + required16strint(k, l, "defense exp"); + required16strint(k, l, "speed exp"); + required16strint(k, l, "special exp"); + required16strint(k, l, "dvs"); + optional8strint(k, l, "unknown4"); + optional8strint(k, l, "unknown5"); +} |