]> Shamusworld >> Repos - thunder/blob - test/rthack4.cpp
Added save states; updated application icon.
[thunder] / test / rthack4.cpp
1 // Rolling Thunder hacker #4: more character graphics
2 //
3 // I *think* that the ROMs R17-R20 are character graphics data encoded:
4 //
5 //   BYTE 1: char # (0-255)
6 //   BYTE 2: Top 3 bits = charset index (i.e. idx*256)
7 //
8
9 #include <fstream.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <iomanip.h>
13 #include <stdio.h>
14 #include <conio.h>
15 #include <dos.h>
16 #include <new.h>
17 #include "screen.h"
18
19 // With C++ string constants, you need to use a double backslash in
20 // order to indicate a single backslash.  Confusing?  You bet!
21 // [It's called "escaping the escape character."]
22
23 #define fn1 "c:\\games\\romhac~1\\r5"
24 #define fn2 "c:\\games\\romhac~1\\r6"
25 #define fn3 "c:\\games\\romhac~1\\r18"
26
27 // Global shit (shouldn't be, but I can't think of an alternative)
28
29 ifstream ff, ff2, ff3;           // Creates IFSTREAMs without any file hooks
30 char * r7l, * r7r, * r8;       // Place holders for our charset
31
32 // Get a word from the current input stream
33
34 unsigned int GetWord(ifstream &fstr)
35 {
36   unsigned int word = 0;
37   unsigned char ch;
38
39   fstr.get(ch);  word = int(ch) << 8;
40   fstr.get(ch);  word |= (int)ch;
41   
42   return(word);
43 }
44
45 // Get a double word from the current input stream
46
47 unsigned long int GetDWord(ifstream &fstr)
48 {
49   unsigned long int dword = 0;
50   unsigned char ch;
51
52   for(int i=0; i<4; i++)
53   { 
54     fstr.get(ch);  dword <<= 8;  dword |= (int)ch;
55   }
56   return(dword);
57 }
58
59 void plot(int x, int y, int c)
60 {
61   extern char * screen;
62
63   screen[x + y*320] = c;
64 }
65
66 void decode(int b1, int b2, int b3, int xx, int yy)
67 {
68   int cc = ((b3 & 0x80) >> 5) | ((b1 & 0x80) >> 6) | ((b1 & 0x08) >> 3);
69   plot(xx, yy, cc);
70   cc =  ((b3 & 0x40) >> 4) | ((b1 & 0x40) >> 5) | ((b1 & 0x04) >> 2);
71   plot(xx+1, yy, cc);
72   cc =  ((b3 & 0x20) >> 3) | ((b1 & 0x20) >> 4) | ((b1 & 0x02) >> 1);
73   plot(xx+2, yy, cc);
74   cc =  ((b3 & 0x10) >> 2) | ((b1 & 0x10) >> 3) | (b1 & 0x01);
75   plot(xx+3, yy, cc);
76   cc =  ((b3 & 0x08) >> 1) | ((b2 & 0x80) >> 6) | ((b2 & 0x08) >> 3);
77   plot(xx+4, yy, cc);
78   cc =  (b3 & 0x04)        | ((b2 & 0x40) >> 5) | ((b2 & 0x04) >> 2);
79   plot(xx+5, yy, cc);
80   cc =  ((b3 & 0x02) << 1) | ((b2 & 0x20) >> 4) | ((b2 & 0x02) >> 1);
81   plot(xx+6, yy, cc);
82   cc =  ((b3 & 0x01) << 2) | ((b2 & 0x10) >> 3) | (b2 & 0x01);
83   plot(xx+7, yy, cc);
84 }
85
86 void PlotChar(int sx, int sy, int chr, int idx)
87 {
88   unsigned char ch;
89   long chr_index;
90
91   chr_index = (((idx<<8)+chr)<<3);
92
93   for(int i=0; i<8; i++)
94   {
95     int b1 = (int)r7l[chr_index];
96     int b2 = (int)r7r[chr_index];
97     int b3 = (int)r8[chr_index++];
98     decode(b1, b2, b3, sx*8, (sy*12)+i);
99   }
100 }
101
102 void main(int argc, char *argv[])
103 {
104   char pal[768];
105   unsigned char ch;
106   int i, j, x, y, index;
107   
108   if (argc == 2)  index = atoi(argv[1]);
109   else            index = 0;
110
111   set_new_handler(0);          // Make 'new' return NULL on failure...
112   r7l = new char[32768];  r7r = new char[32768];
113   r8 = new char[32768];        // Initialize charspaces
114
115   ff.open(fn1, ios::binary);   // Open as a binary file
116   ff2.open(fn2, ios::binary);  // ditto
117   ff3.open(fn3, ios::binary);  // ditto
118            
119   if (!ff)   cerr << "Could not open 'ff'";   // Handle any errors...
120   if (!ff2)  cerr << "Could not open 'ff2'";
121   if (!ff3)  cerr << "Could not open 'ff3'";
122   if (!r7l)  cerr << "Could not allocate RAM space #1!";
123   if (!r7r)  cerr << "Could not allocate RAM space #2!";
124   if (!r8)   cerr << "Could not allocate RAM space #3!";
125
126   for(long i=0; i<32768; i++)  { ff.get(ch);  r7l[i] = ch;
127                                  ff.get(ch);  r7r[i] = ch; }
128   for(long i=0; i<32768; i++)  { ff2.get(ch);  r8[i] = ch; }
129
130   ff.close();  ff2.close();      // Close da filez...
131
132   SetMode(0x13);  // Set up VGA screen
133
134   while (!kbhit())
135   {
136     int charact = 0;
137
138     for(j=0; j<16; j++)
139     {
140       for(i=0; i<32; i+=2)
141       {
142         PlotChar(i, j, charact++, index);
143       }
144     }
145     i = getch();
146     if (i==27)  break;  // Break out on ESC
147     if (i=='[')  index--;  // Decrease...
148     if (i==']')  index++;  // Increase...
149   }
150   SetMode(0x03);        // Reset text mode
151 }