/ source / tools / src / bsuite.cpp
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  }