// QSP dump and fix program /***************************************************************** $Author: peter $ $Date: $ $Header: $ $Name: $ $Revision: $ $Log: $ *****************************************************************/ /*'// Visual Basic 5.0 Code: Type QShipType nm As String * 40 '// Name of the ship plan Hull As Long '// Number from 1 to 500 hull ID cost As Long '// Total cost of EVERYTHING, hull, weapons parts . . . eleD As Long '// Total usage for everything, armor, weapons, engine and hull eleM As Long '// Total usage for everything eleT As Long '// Total usage for everything HullCost As Long '// Cost of just the hull HulleleD As Long '// Duranium used just to build the hull HulleleM As Long HulleleT As Long maxArmor As Long '// The max armor the ship can have hullMass As Long '// mass of just the hull alone EngCount As Long '// Number of engines the ship has Tally As Long '// Unused Ignore // EDrain As Long '// Sum of the charge rates of all weapons OrdDrain As Long '// Sum of the ord usage of all weapons Ord As Long '// Max ord that the ship can carry E As Long '// Total energy output from engine and generators part(1 To 69) As Byte '// A list of all the ship parts the ship has '// 1 to 10 PD '// 11 to 30 Large '// 31 to 60 Small '// 61 to 65 Generator '// 66 Eng '// 67 Hyp '// 68 Shield '// 69 Super techSuper As Byte '// The Highest Super Weapon Tech used on this ship // techGen As Byte '// The Highest Generator Tech used on this ship // techShield As Byte '// The Highest Shield Tech used on this ship // techHull As Byte '// The Hull Tech of this ship // techPD As Byte techSmall As Byte techLarge As Byte techEngine As Byte techHyp As Byte techIsGood As Boolean '// Unused Ignore // IsAlien As Boolean '// Unused Ignore // FileName As String * 12 '// Unused Ignore // End Type */ #include #define NUL '\0' #define QSP_SIZE 202 #define PD_PART 0 #define PD_NUM 10 #define PD_TECH 10 #define LA_PART 10 #define LA_NUM 20 #define LA_TYPE 20 #define LA_TECH 14 #define SM_PART 30 #define SM_NUM 30 #define SM_TECH 10 #define GE_PART 60 #define GE_NUM 5 #define GE_TECH 10 #define SU_TECH 5 #define SH_TECH 10 #define EN_TECH 20 #define HY_TECH 10 typedef unsigned char uchar; typedef struct { char nm[40]; // Name of the ship plan long Hullg; // Number from 1 to 2000 hull ID long cost; // Total cost of EVERYTHING, hull, weapons parts . . . long eleD; // Total usage for everything, armor, weapons, engine and hull long eleM; // Total usage for everything long eleT; // Total usage for everything long HullCost; // Cost of just the hull long HulleleD; // Duranium used just to build the hull long HulleleM; long HulleleT; long maxArmor; // The max armor the ship can have long hullMass; // mass of just the hull alone long EngCount; // Number of engines the ship has long Tally; // Unused Ignore // long EDrain; // Sum of the charge rates of all weapons long OrdDrain; // Sum of the ord usage of all weapons long Ord; // Max ord that the ship can carry long E; // Total energy output from engine and generators uchar part[69]; // A list of all the ship parts the ship has // 1 to 10 PD // 11 to 30 Large // 31 to 60 Small // 61 to 65 Generator // 66 Eng // 67 Hyp // 68 Shield // 69 Super uchar techSuper; // The Highest Super Weapon Tech used on this ship // uchar techGen; // The Highest Generator Tech used on this ship // uchar techShield; // The Highest Shield Tech used on this ship // uchar techHull; // The Hull Tech of this ship // uchar techPD; uchar techSmall; uchar techLarge; uchar techEngine; uchar techHyp; short techIsGood; // Unused Ignore // short IsAlien; // Unused Ignore // char FileName[12];// Unused Ignore // char fence[2]; } QShipType; static const char whoami[] = "qspdump"; static int writeback = 0; static const char *pdWeaps[PD_TECH+1] = { "nosuch", "holo decoy", "35mm", "flake", "concussion", "MSC", "auto blaster", "turbo laser", "quad laser", "micro missile", "intercept" }; static const char *laWeaps[LA_TYPE+1] = { "nosuch", "heavy laser", "merculite", "500mm", "sand caster", "fusion cannon", "force beam", "disrupter cannon", "mass driver", "anti-matter", "blaster cannon", "ion cannon", "energy mine", "PTT", "plasma bolt", "particle cannon", "PPC","ionic array", "turbo array", "large turbo array","gatling phasor", }; static const int laTechs[LA_TYPE+1] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; static const char *smWeaps[SM_TECH+1] = { "nosuch", "laser", "pulse laser", "disrupter", "streak m", "phasor", "positron", "meson gun", "xenon beam", "tachyon gun", "plasma gun" }; static const char *geWeaps[GE_TECH+1] = { "no generator", "GF Prilldyne 100", "GF Prilldyne 120", "GF Prilldyne 140", "Servodyne 600", "Servodyne 700", "Servodyne 800", "Microquad 950", "Firestorm 3000", "Tifuss KH4000", "GF Tokamak 8080" }; static const char *suWeaps[SU_TECH+1] = { "no super", "super laser", "nemesis torpedo", "world crusher missile", "anti-matter maul", "proto matter cannon" }; static const char *shNames[SH_TECH+1] = { "no shield", "Fleece S30", "Crane X40", "Crane X80", "Corber 210", "Corber 350", "Corber 400", "Galefleck DT900", "GS-SX 1000", "GS_LX 1500", "GS-BFS 3000" }; static const char *enNames[EN_TECH+1] = { "no engine", "N20", "N30", "Lasno-1", "Lasno-2", "R50", "I-17", "I-20", "I-25", "Electrogravitic", "Turbo T", "Tylium", "Energy Conversion", "Scalar Wave", "Lazar", "FTL-1", "FTL-2", "FTL-3", "FTL-4", "FTL-5", "Transwarp" }; static const char *hyNames[HY_TECH+1] = { "no hyper", "Yoyodyne 88", "Microfold 200", "Yoyodyne 300", "Keplan 450", "Keplan 505", "Keplan 660", "Yoyodyne 900", "Soleum H1000", "Warhop 2020", "Cydonia 3000" }; static void warn(const char *s1,const char *s2) { fprintf(stderr, "%s:%s %s\n", whoami, s1, s2); } static void trimBasString(char str[], int len) { int i; for (i = len-1 ; (i >= 0) && (str[i] == ' ') ; i--) if (str[i] == ' ') str[i] = NUL; for (i = 0 ; str[i] != NUL ; i++) str[i] &= 0x7f; // remove MSB possibly used for BASIC tagging } static void dumpShip(const char *f) { QShipType ship; size_t nread; int dirty = 0; FILE *fp = fopen(f, "r+b"); if (fp == NULL) { warn("Cannot open file", f); return; } nread = fread((char *)&ship, sizeof(char), QSP_SIZE, fp); if (nread != QSP_SIZE) { warn("Read size error", f); fclose(fp); return; } ship.fence[0] = '\0'; trimBasString(ship.nm, 40); trimBasString(ship.FileName, 12); printf("===================================================================\n"); printf("%s: %s: \"%s\" Hull#: %ld\n", f, ship.FileName, ship.nm, ship.Hullg); if (ship.Hullg > 4000) printf("Illegal hull number\n"); printf("Cost: %5ld Dur: %4ld Tri: %4ld Moly: %4ld\n", ship.cost, ship.eleD, ship.eleT, ship.eleT); printf("Hull: %5ld Dur: %4ld Tri: %4ld Moly: %4ld ", ship.HullCost, ship.HulleleD, ship.HulleleT, ship.HulleleM); if ((ship.HullCost > ship.cost) || (ship.HulleleD > ship.eleD) || (ship.HulleleT > ship.eleT) || (ship.HulleleM > ship.eleM)) printf("Suspicious ship/hull costs\n"); printf("Hull Tech: %d\n", ship.techHull); printf("Max Armour: %ld Hull mass: %ld Engines: %ld Tally: %ld\n", ship.maxArmor, ship.hullMass, ship.EngCount, ship.Tally); printf("E-Drain: %ld Ord-Drain: %ld Ord: %ld Energy: %ld\n", ship.EDrain, ship.OrdDrain, ship.Ord, ship.E); if (ship.EDrain > ship.E) printf("Warning ship short of energy\n"); { int i, tech; tech = 0; printf("PD: "); for (i = 0 ; i < PD_NUM ; i++) { int part = (int)ship.part[i + PD_PART]; if (part > PD_TECH) { printf("illegal tech %d ", part); ship.part[i + PD_PART] = part = 0; dirty = 1; } else if (part > 0) printf("\"%s\" ", pdWeaps[part]); if (tech < part) tech = part; } printf("tech: %d ", ship.techPD); if(tech > ship.techPD) { printf(" ERROR!\n"); ship.techPD = tech; dirty = 1; } else printf("\n"); tech = 0; printf("Large: "); for (i = 0 ; i < LA_NUM ; i++) { int part = (int)ship.part[i + LA_PART]; if (part > LA_TYPE) { printf("illegal type %d ", part); ship.part[i + LA_PART] = part = 0; dirty = 1; } else if (part > 0) printf("\"%s\" ", laWeaps[part]); if (tech < laTechs[part]) tech = laTechs[part]; } printf("tech: %d", ship.techLarge); if(tech > ship.techLarge) { printf(" ERROR!\n"); ship.techLarge = tech; dirty = 1; } else printf("\n"); tech = 0; printf("Small: "); for (i = 0 ; i < SM_NUM ; i++) { int part = (int)ship.part[i + SM_PART]; if (part > SM_TECH) { printf("illegal tech %d ", part); ship.part[i + SM_PART] = part = 0; dirty = 1; } else if (part > 0) printf("\"%s\" ", smWeaps[part]); if (tech < part) tech = part; } printf("tech: %d", ship.techSmall); if(tech > ship.techSmall) { printf(" ERROR!\n"); ship.techSmall = tech; dirty = 1; } else printf("\n"); tech = 0; printf("Gen: "); for (i = 0 ; i < GE_NUM ; i++) { int part = (int)ship.part[i + GE_PART]; if (part > GE_TECH) { printf("illegal tech %d ", part); ship.part[i + GE_PART] = part = 0; dirty = 1; } else if (part > 0) printf("\"%s\" ", geWeaps[part]); if (tech < part) tech = part; } printf("tech: %d", ship.techGen); if(tech > ship.techGen) { printf(" ERROR!\n"); ship.techGen = tech; dirty = 1; } else printf("\n"); } if (ship.part[65] > EN_TECH) { printf("ERROR illegal engine tech! %d\n", ship.part[65]); ship.part[65] = 0; ship.techEngine = 0; dirty = 1; } else if (ship.EngCount == 0) printf("No engines"); else printf("Engine: (%ldx)%s tech %d\n", ship.EngCount, enNames[(int)ship.part[65]], ship.techEngine); if (ship.part[65] > ship.techEngine) { printf("ERROR Engine tech\n"); ship.techGen = ship.part[65]; dirty = 1; } if (ship.part[66] > HY_TECH) { printf("ERROR illegal hyper tech! %d\n", ship.part[66]); ship.part[66] = 0; ship.techHyp = 0; dirty = 1; } else printf("HyperD: %s tech %d\n", hyNames[(int)ship.part[66]], ship.techHyp); if (ship.part[66] > ship.techHyp) { printf("ERROR Hyper tech\n"); ship.techHyp = ship.part[66]; dirty = 1; } if (ship.part[67] > SH_TECH) { printf("ERROR illegal shield tech!%d\n", ship.part[67]); ship.part[67] = 0; ship.techShield = 0; dirty = 1; } else printf("Shield: %s tech: %d\n", shNames[(int)ship.part[67]], ship.techShield); if (ship.part[67] > ship.techShield) { printf("ERROR Shield tech\n"); ship.techShield = ship.part[67]; dirty = 1; } if (ship.part[68] > SU_TECH) { printf("ERROR illegal super weapon tech! %d\n", ship.part[68]); ship.part[68] = 0; ship.techSuper = 0; dirty = 1; } else printf("SuperW: %s tech %d\n", suWeaps[(int)ship.part[68]], ship.techSuper); if (ship.part[68] > ship.techSuper) { printf("ERROR Super tech\n"); ship.techSuper = ship.part[68]; dirty = 1; } printf("Tech Good: %d\n", (ship.techIsGood != 0)); printf("Alien Plans: %d\n", (ship.IsAlien != 0)); if (dirty) { printf("+++ Fix"); if (writeback) { printf(" & Writeback"); rewind(fp); nread = fwrite((char *)&ship, sizeof(char), QSP_SIZE, fp); if (nread != QSP_SIZE) { warn("Writeback size error", f); } } printf(" +++\n"); } fclose(fp); } int main(int argc, char *argv[]) { int argno; for (argno = 1 ; argno < argc ; argno++) // element 0 is exe-name { dumpShip(argv[argno]); } return(0); }