summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--stadiumgs/Makefile2
-rw-r--r--utils/Makefile15
-rw-r--r--utils/cattbl.c79
-rw-r--r--utils/constants.h1264
-rw-r--r--utils/extractbin.c107
-rw-r--r--utils/extractrostertbltbl.c50
-rw-r--r--utils/json2rostertbl.c184
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");
+}