bsuite.cpp
1 /* 2 Build Game Customization Suite 3 Copyright (c) 1999, 2004 Jonathon Fowler 4 5 15 September 2004 6 7 This is the source code to BCS. It was written in Borland Turbo C++ for DOS 8 and [was] a 16bit real-mode DOS application. I'm releasing the code because 9 I have no reason to keep it a secret. Some folks might find it interesting. 10 11 BTW, you can use this code for any purpose you want. 12 13 Jonathon Fowler 14 jf@jonof.id.au 15 http://www.jonof.id.au/ 16 */ 17 /* 18 NOTE: This program does not fall under BUILDLIC. 19 */ 20 // DOS 16-bit real mode UI --> portable command line conversion by Hendricks266 21 22 #include "compat.h" 23 24 const char APP_NAME[] = "Build Game Customization Suite v0.2-EDuke32"; 25 const char APP_CPRT[] = "Copyright (c) 1999, 2004 Jonathon Fowler"; 26 27 int bsExtractD3DPalette(int, const char*); 28 int bsUpdateD3DPalette(int, const char*); 29 30 int bsExtractPalette(const char*); 31 int bsUpdatePalette(const char*); 32 33 const char *MainMenuStrings[] = { 34 "Options:", 35 "Extract Duke Nukem 3D-specific Palettes", 36 "Update Duke Nukem 3D-specific Palettes", 37 "Extract Build Game Palette", 38 "Update Build Game Palette" 39 }; 40 41 const char *D3DMenuStrings[] = { 42 "Sub-Option: Duke Nukem 3D-specific Palettes:", 43 "Water Palette", 44 "Night-Vision Palette", 45 "Title Screen Palette", 46 "3D Realms Logo Palette", 47 "Episode 1 Ending Animation Palette" 48 }; 49 50 const char *pal_deffn[] = { 51 "GAME.PAL", 52 "D3DWATER.PAL", 53 "D3DNVIS.PAL", 54 "D3DTITLE.PAL", 55 "D3D3DR.PAL", 56 "D3DEP1.PAL" 57 }; 58 59 int main(const int32_t argc, const char **argv) 60 { 61 int opt = 0, d3dpal = 0, k = 0; 62 int16_t i = 1; 63 char const * filename = NULL; // This is only a pointer. Do not strcpy to it. 64 char const * c = NULL; 65 66 Bprintf("%s\n%s\n\n", APP_NAME, APP_CPRT); 67 68 if (argc > 1) 69 { 70 opt = Bstrtol(argv[i++],NULL,10); 71 if ((opt == 1 || opt == 2) && i < argc) // Duke-specific palettes 72 d3dpal = Bstrtol(argv[i++],NULL,10); 73 74 while (i < argc) 75 { 76 c = (char const *)argv[i]; 77 if ((*c == '-') 78 #ifdef _WIN32 79 || (*c == '/') 80 #endif 81 ) 82 { 83 ++c; 84 if (!Bstrcasecmp(c,"f")) 85 { 86 if (argc > i+1) 87 filename = (char const *)argv[++i]; 88 ++i; 89 continue; 90 } 91 92 } 93 ++i; 94 } 95 } 96 97 if (opt < 1 || opt > 4 || (opt < 3 && (d3dpal < 1 || d3dpal > 5))) 98 { 99 Bprintf("usage: %s <option> <sub-option(s)> [-f filename]\n",argv[0]); 100 Bprintf("If a filename is not specified, internal defaults will be used.\n"); 101 Bprintf("\n"); 102 for (k = 0; k < 5; ++k) 103 { 104 if (k > 0) 105 Bprintf("%d - ",k); 106 Bprintf("%s\n",MainMenuStrings[k]); 107 } 108 Bprintf("\n"); 109 for (k = 0; k < 6; ++k) 110 { 111 if (k > 0) 112 Bprintf("%d - ",k); 113 Bprintf("%s\n",D3DMenuStrings[k]); 114 } 115 Bprintf("\n"); 116 /* 117 Bprintf( "This program is, well, I guess freeware. Questions, suggestions,\n" 118 "comments and bug reports are welcome at jf@jonof.id.au. Visit\n" 119 "my website at http://www.jonof.id.au/ for more information\n" 120 "on this program and others that I may happen to write.\n\n"); 121 */ 122 } 123 else 124 { 125 if (filename == NULL) 126 switch (opt) 127 { 128 case 1: // Duke-specific palettes 129 case 2: 130 filename = (char const *)pal_deffn[d3dpal]; 131 break; 132 133 case 3: // game palette 134 case 4: 135 filename = (char const *)pal_deffn[0]; 136 break; 137 } 138 139 switch (opt) 140 { 141 case 1: // extract Duke-specific palettes 142 bsExtractD3DPalette(d3dpal-1, filename); 143 break; 144 145 case 2: // update Duke-specific palettes 146 bsUpdateD3DPalette(d3dpal-1, filename); 147 break; 148 149 case 3: // extract game palette 150 bsExtractPalette(filename); 151 break; 152 153 case 4: // update game palette 154 bsUpdatePalette(filename); 155 break; 156 } 157 } 158 159 return 0; 160 } 161 162 163 164 165 166 const int pal_offsets[5] = {6426, 7194, 7962, 8730, 9498}; 167 168 169 #define PAL_LEN 768 170 171 ///////////////////////////////////////////////// 172 // 173 // Extract and update functions 174 175 int bsExtractD3DPalette(int palnum, const char *outfn) 176 { 177 BFILE *lookup, *out; 178 char cb[3]; 179 int lp; 180 181 Bprintf("Using: %s\n",outfn); 182 183 lookup = Bfopen("LOOKUP.DAT", "rb"); 184 if (lookup == NULL) 185 { 186 // could not open LOOKUP.DAT 187 Bprintf("Error opening LOOKUP.DAT!\n" 188 "Make sure that the file is in the current\n" 189 "directory, then try again.\n\n"); 190 191 return 1; 192 } 193 194 // create output file 195 out = Bfopen(outfn, "w+t"); 196 if (out == NULL) 197 { 198 Bfclose(lookup); 199 Bprintf("Error creating output file!\n" 200 "The file may be open by another program\n" 201 "or is read-only, or the disk may be read-only.\n\n"); 202 return 1; 203 } 204 205 // write out the palette data in PSP format 206 207 // find palette data 208 Bfseek(lookup, pal_offsets[palnum], SEEK_SET); 209 210 // write out a Paint Shop Pro palette file 211 Bfprintf(out, "JASC-PAL\n0100\n256\n"); 212 for (lp=0; lp < 256; lp++) 213 { 214 cb[0] = Bfgetc(lookup) * 4; 215 cb[1] = Bfgetc(lookup) * 4; 216 cb[2] = Bfgetc(lookup) * 4; 217 218 Bfprintf(out, "%d %d %d\n", cb[0], cb[1], cb[2]); 219 } 220 221 // close files 222 Bfclose(out); 223 Bfclose(lookup); 224 225 Bprintf("Palette dumped successfully!\n\n"); 226 227 return 0; 228 } 229 230 231 int bsUpdateD3DPalette(int palnum, const char *palfn) 232 { 233 BFILE *lookup, *pal; 234 char cb[3], work[64]; 235 int lp; 236 237 Bprintf("Using: %s\n",palfn); 238 239 lookup = Bfopen("LOOKUP.DAT", "r+b"); 240 if (lookup == NULL) 241 { 242 // could not open LOOKUP.DAT 243 Bprintf("Error opening LOOKUP.DAT!\n" 244 "The file may be open by another program\n" 245 "or is read-only, or the disk may be read-only.\n\n"); 246 247 return 1; 248 } 249 250 // open source file 251 pal = Bfopen(palfn, "rt"); 252 if (pal == NULL) 253 { 254 Bfclose(lookup); 255 Bprintf("Error opening palette file!\n" 256 "Make sure that the file exists.\n\n"); 257 return 1; 258 } 259 260 // read the palette data and write it to LOOKUP.DAT 261 262 Bfgets(work, 64, pal); 263 if (strncmp(work, "JASC-PAL", 8)) 264 { 265 Bfclose(pal); Bfclose(lookup); 266 Bprintf("Error validating palette file!\n" 267 "This palette file appears to be in a format\n" 268 "other than Paint Shop Pro format. This program\n" 269 "works only with Paint Shop Pro palette files.\n\n"); 270 return 1; 271 } 272 273 Bfgets(work, 64, pal); 274 if (strncmp(work, "0100", 4)) 275 { 276 Bfclose(pal); Bfclose(lookup); 277 Bprintf("Error validating palette file!\n" 278 "This palette file appears to be in a version\n" 279 "other than 0100. This program works only with\n" 280 "Paint Shop Pro palettes of version 0100.\n\n"); 281 return 1; 282 } 283 284 Bfgets(work, 64, pal); 285 if (strncmp(work, "256", 3)) 286 { 287 Bfclose(pal); Bfclose(lookup); 288 Bprintf("Error validating palette file!\n" 289 "This palette file appears to be for a palette\n" 290 "size other than 256 colours. This program works\n" 291 "only with Paint Shop Pro palettes of 256 colours.\n\n"); 292 return 1; 293 } 294 295 // find palette data 296 Bfseek(lookup, pal_offsets[palnum], SEEK_SET); 297 298 // write out new palette info 299 for (lp=0; lp < 256; lp++) 300 { 301 Bfscanf(pal, "%c %c %c\n", &cb[0], &cb[1], &cb[2]); 302 303 Bfputc(cb[0] / 4, lookup); 304 Bfputc(cb[1] / 4, lookup); 305 Bfputc(cb[2] / 4, lookup); 306 } 307 308 // close files 309 Bfclose(pal); 310 Bfclose(lookup); 311 312 Bprintf("Palette updated successfully!\n\n"); 313 314 return 0; 315 } 316 317 318 319 320 // Format of PALETTE.DAT files 321 // 322 // 256 bytes - palette 323 // 2 bytes - short: number of palette lookups 324 // n*256 bytes - shading lookup tables 325 // 256*256 bytes - translucency lookup array 326 327 328 329 int bsExtractPalette(const char *outfn) 330 { 331 BFILE *palette, *out; 332 char cb[3]; 333 int lp; 334 335 Bprintf("Using: %s\n",outfn); 336 337 palette = Bfopen("PALETTE.DAT", "rb"); 338 if (palette == NULL) 339 { 340 // could not open PALETTE.DAT 341 Bprintf("Error opening PALETTE.DAT!\n" 342 "Make sure that the file is in the current\n" 343 "directory, then try again.\n\n"); 344 345 return 1; 346 } 347 348 // create output file 349 out = Bfopen(outfn, "w+t"); 350 if (out == NULL) 351 { 352 Bfclose(palette); 353 Bprintf("Error creating output file!\n" 354 "The file may be open by another program\n" 355 "or is read-only, or the disk may be read-only.\n\n"); 356 return 1; 357 } 358 359 // write out the palette data in PSP format 360 361 // write out a Paint Shop Pro palette file 362 Bfprintf(out, "JASC-PAL\n0100\n256\n"); 363 for (lp=0; lp < 256; lp++) 364 { 365 cb[0] = Bfgetc(palette) * 4; 366 cb[1] = Bfgetc(palette) * 4; 367 cb[2] = Bfgetc(palette) * 4; 368 369 Bfprintf(out, "%d %d %d\n", cb[0], cb[1], cb[2]); 370 } 371 372 // close files 373 Bfclose(out); 374 Bfclose(palette); 375 376 Bprintf("Palette dumped successfully!\n\n"); 377 378 return 0; 379 } 380 381 382 int bsUpdatePalette(const char *palfn) 383 { 384 BFILE *palette, *pal; 385 char cb[3], work[64]; 386 int lp; 387 388 Bprintf("Using: %s\n",palfn); 389 390 palette = Bfopen("PALETTE.DAT", "w+b"); 391 if (palette == NULL) 392 { 393 // could not open LOOKUP.DAT 394 Bprintf("Error opening PALETTE.DAT!\n" 395 "The file may be open by another program\n" 396 "or is read-only, or the disk may be read-only.\n\n"); 397 398 return 1; 399 } 400 401 // open source file 402 pal = Bfopen(palfn, "rt"); 403 if (pal == NULL) 404 { 405 Bfclose(palette); 406 Bprintf("Error opening palette file!\n" 407 "Make sure that the file exists.\n\n"); 408 return 1; 409 } 410 411 // read the palette data and write it to PALETTE.DAT 412 413 Bfgets(work, 64, pal); 414 if (strncmp(work, "JASC-PAL", 8)) 415 { 416 Bfclose(pal); Bfclose(palette); 417 Bprintf("Error validating palette file!\n" 418 "This palette file appears to be in a format\n" 419 "other than Paint Shop Pro format. This program\n" 420 "works only with Paint Shop Pro palette files.\n\n"); 421 return 1; 422 } 423 424 Bfgets(work, 64, pal); 425 if (strncmp(work, "0100", 4)) 426 { 427 Bfclose(pal); Bfclose(palette); 428 Bprintf("Error validating palette file!\n" 429 "This palette file appears to be in a version\n" 430 "other than 0100. This program works only with\n" 431 "Paint Shop Pro palettes of version 0100.\n\n"); 432 return 1; 433 } 434 435 Bfgets(work, 64, pal); 436 if (strncmp(work, "256", 3)) 437 { 438 Bfclose(pal); Bfclose(palette); 439 Bprintf("Error validating palette file!\n" 440 "This palette file appears to be for a palette\n" 441 "size other than 256 colours. This program works\n" 442 "only with Paint Shop Pro palettes of 256 colours.\n\n"); 443 return 1; 444 } 445 446 // write out new palette info 447 for (lp=0; lp < 256; lp++) 448 { 449 Bfscanf(pal, "%c %c %c\n", &cb[0], &cb[1], &cb[2]); 450 451 // put the bytes into the basergb array as well 452 Bfputc(cb[0] / 4, palette); 453 Bfputc(cb[1] / 4, palette); 454 Bfputc(cb[2] / 4, palette); 455 } 456 457 // close files 458 Bfclose(pal); 459 Bfclose(palette); 460 461 Bprintf("Palette updated successfully!\n" 462 "Now run TRANSPAL.EXE to create the shading\n" 463 "and translucency tables for the palette.\n\n"); 464 465 return 0; 466 }