Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * Portions of this file are copyright Rebirth contributors and licensed as
3
 * described in COPYING.txt.
4
 * Portions of this file are copyright Parallax Software and licensed
5
 * according to the Parallax license below.
6
 * See COPYING.txt for license details.
7
 
8
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
9
SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
10
END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
11
ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
12
IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
13
SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
14
FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
15
CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
16
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
17
COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
18
*/
19
 
20
/*
21
 *
22
 * Code for localizable text
23
 *
24
 */
25
 
26
 
27
#include <stdlib.h>
28
#include <string.h>
29
 
30
#include "physfsx.h"
31
#include "pstypes.h"
32
#include "u_mem.h"
33
#include "dxxerror.h"
34
#include "inferno.h"
35
#include "text.h"
36
#include "strutil.h"
37
#include "args.h"
38
#include <memory>
39
 
40
#ifdef GENERATE_BUILTIN_TEXT_TABLE
41
#include <ctype.h>
42
#endif
43
 
44
#if defined(DXX_BUILD_DESCENT_I)
45
#define IDX_TEXT_OVERWRITTEN    330
46
#elif defined(DXX_BUILD_DESCENT_II)
47
#define IDX_TEXT_OVERWRITTEN    350
48
#define SHAREWARE_TEXTSIZE  14677
49
#endif
50
 
51
static std::unique_ptr<char[]> text;
52
static std::unique_ptr<char[]> overwritten_text;
53
 
54
// rotates a byte left one bit, preserving the bit falling off the right
55
static uint8_t encode_rotate_left(const uint8_t v)
56
{
57
        return (v >> 7) | (v << 1);
58
}
59
 
60
constexpr std::integral_constant<uint8_t, 0xd3> BITMAP_TBL_XOR{};
61
 
62
static uint8_t decode_char(const uint8_t c)
63
{
64
        const auto c1 = encode_rotate_left(c);
65
        const auto c2 = c1 ^ BITMAP_TBL_XOR;
66
        return encode_rotate_left(c2);
67
}
68
 
69
//decode an encoded line of text of bitmaps.tbl
70
void decode_text_line(char *p)
71
{
72
        for (; const char c = *p; p++)
73
                *p = decode_char(c);
74
}
75
 
76
// decode buffer of text, preserves newlines
77
void decode_text(char *ptr, unsigned len)
78
{
79
        for (; len--; ptr++)
80
        {
81
                const char c = *ptr;
82
                if (c != '\n')
83
                        *ptr = decode_char(c);
84
        }
85
}
86
 
87
//load all the text strings for Descent
88
namespace dsx {
89
 
90
#ifdef USE_BUILTIN_ENGLISH_TEXT_STRINGS
91
static
92
#endif
93
std::array<const char *, N_TEXT_STRINGS> Text_string;
94
 
95
void load_text()
96
{
97
        int len,i, have_binary = 0;
98
        char *tptr;
99
        const char *filename="descent.tex";
100
#if defined(DXX_BUILD_DESCENT_I)
101
        static const char *const extra_strings[] = {
102
                "done",
103
                "I am a",
104
                "CHEATER!",
105
                "Loading Data",
106
                "ALT-F2\t  Save Game",
107
                "ALT-F3\t  Load Game",
108
                "Only in Registered version!",
109
                "Concussion",
110
                "Homing",
111
                "ProxBomb",
112
                "Smart",
113
                "Mega",
114
                "Mission '%s' not found.\nYou must have this mission\nfile in order to playback\nthis demo.",
115
                "All player callsigns on screen",
116
                "There is already a game\nin progress with that name",
117
                "This mission is designated\nAnarchy-only",
118
                "Force level start",
119
                "Quitting now means ending the\nentire netgame\n\nAre you sure?",
120
                "The mission for that netgame\nis not installed on your\nsystem.  Cannot join.",
121
                "Start Multiplayer Game\n\nSelect mission",
122
                "Error loading mission file",
123
                "Custom (return to set)",
124
                "Base address (in Hex)",
125
                "IRQ Number",
126
                "Reset to Default",
127
                "Valid IRQ values are 2-7",
128
                "No UART was detected\nat those settings",
129
                "You will pay dearly for that!",
130
                "Revenge is mine!!",
131
                "Man I'm good!",
132
                "Its almost too easy!",
133
                "   Mission:",
134
                "+/- Changes viewing distance",
135
                "Alternate exit found!\n\nProceeding to Secret Level!",
136
                "Show all players on automap",
137
                "Killed by a robot",
138
                "Baud",
139
                "A consistency error has been\ndetected in your network connection.\nCheck you hardware and re-join",
140
                "Press any key to continue (Print Screen to save screenshot)",
141
                "An error occured while writing\ndemo.  Demo is likely corrupted.\nEnter demo name now or\npress ESC to delete demo.",
142
                "The main reactor is invulnerable for",
143
                "The level being loaded is not\navailable in Destination Saturn.\nUnable to continue demo playback.\n\nPress any key to continue.",
144
                "Reactor life",
145
                "min",
146
                "Current IPX Socket is default",
147
                "This program requires MS-DOS 5.0 or higher.\nYou are using MS-DOS",
148
                "You can use the -nodoscheck command line\nswitch to override this check, but it\nmay have unpredictable results, namely\nwith DOS file error handling.\n",
149
                "Not enough file handles!",
150
                "of the necessary file handles\nthat Descent requires to execute properly.  You will\nneed to increase the FILES=n line in your config.sys.",
151
                "If you are running with a clean boot, then you will need\nto create a CONFIG.SYS file in your root directory, with\nthe line FILES=15 in it.  If you need help with this,\ncontact Interplay technical support.",
152
                "You may also run with the -nofilecheck command line option\nthat will disable this check, but you might get errors\nwhen loading saved games or playing demos.",
153
                "Available memory",
154
                "more bytes of DOS memory needed!",
155
                "more bytes of virtual memory needed.  Reconfigure VMM.",
156
                "more bytes of extended/expanded memory needed!",
157
                "Or else you you need to use virtual memory (See README.TXT)",
158
                "more bytes of physical memory needed!",
159
                "Check to see that your virtual memory settings allow\nyou to use all of your physical memory (See README.TXT)",
160
                "Initializing DPMI services",
161
                "Initializing critical error handler",
162
                "Enables Virtual I/O Iglasses! stereo display",
163
                "Enables Iglasses! head tracking via COM port",
164
                "Enables Kasan's 3dMax stereo display in low res.",
165
                "3DBios must be installed for 3dMax operation.",
166
                "Enables Kasan's 3dMax stereo display in high res",
167
                "Press any key for more options...",
168
                "Enables dynamic socket changing",
169
                "Disables the file handles check",
170
                "Getting settings from DESCENT.CFG...",
171
                "Initializing timer system...",
172
                "Initializing keyboard handler...",
173
                "Initializing mouse handler...",
174
                "Mouse support disabled...",
175
                "Initializing joystick handler...",
176
                "Slow joystick reading enabled...",
177
                "Polled joystick reading enabled...",
178
                "BIOS joystick reading enabled...",
179
                "Joystick support disabled...",
180
                "Initializing divide by zero handler...",
181
                "Initializing network...",
182
                "Using IPX network support on channel",
183
                "No IPX compatible network found.",
184
                "Error opening socket",
185
                "Not enough low memory for IPX buffers.",
186
                "Error initializing IPX.  Error code:",
187
                "Network support disabled...",
188
                "Initializing graphics system...",
189
                "SOUND: Error opening",
190
                "SOUND: Error locking down instruments",
191
                "SOUND: (HMI)",
192
                "SOUND: Error locking down drums",
193
                "SOUND: Error locking midi track map!",
194
                "SOUND: Error locking midi callback function!",
195
                "Using external control:",
196
                "Invalid serial port parameter for -itrak!",
197
                "Initializing i-glasses! head tracking on serial port %d",
198
                "Make sure the glasses are turned on!",
199
                "Press ESC to abort",
200
                "Failed to open serial port.  Status =",
201
                "Message",
202
                "Macro",
203
                "Error locking serial interrupt routine!",
204
                "Error locking serial port data!",
205
                "Robots are normal",
206
                "Robots move fast, fire seldom",
207
                "Robot painting OFF",
208
                "Robot painting with texture %d"
209
        };
210
#endif
211
 
212
        if (!CGameArg.DbgAltTex.empty())
213
                filename = CGameArg.DbgAltTex.c_str();
214
 
215
        auto tfile = PHYSFSX_openReadBuffered(filename);
216
        if (!tfile)
217
        {
218
                filename="descent.txb";
219
                auto ifile = PHYSFSX_openReadBuffered(filename);
220
                if (!ifile)
221
                {
222
                        Error("Cannot open file DESCENT.TEX or DESCENT.TXB");
223
                        return;
224
                }
225
                have_binary = 1;
226
 
227
                len = PHYSFS_fileLength(ifile);
228
 
229
//edited 05/17/99 Matt Mueller - malloc an extra byte, and null terminate.
230
                text = std::make_unique<char[]>(len + 1);
231
                PHYSFS_read(ifile,text,1,len);
232
                text[len]=0;
233
//end edit -MM
234
        } else {
235
                int c;
236
                char * p;
237
 
238
                len = PHYSFS_fileLength(tfile);
239
 
240
//edited 05/17/99 Matt Mueller - malloc an extra byte, and null terminate.
241
                text = std::make_unique<char[]>(len + 1);
242
                //fread(text,1,len,tfile);
243
                p = text.get();
244
                do {
245
                        c = PHYSFSX_fgetc( tfile );
246
                        if ( c != 13 )
247
                                *p++ = c;
248
                } while ( c!=EOF );
249
                *p=0;
250
//end edit -MM
251
        }
252
 
253
        for (i=0,tptr=text.get();i<N_TEXT_STRINGS;i++) {
254
                char *p;
255
 
256
#if defined(DXX_BUILD_DESCENT_I)
257
                if (!tptr && i >= N_TEXT_STRINGS_MIN)   // account for non-registered 1.4/1.5 text files
258
                {
259
                        Text_string[i-1] = extra_strings[i - N_TEXT_STRINGS_MIN - 1];
260
                        Text_string[i] = extra_strings[i - N_TEXT_STRINGS_MIN];
261
                        continue;
262
                }
263
                else if (!tptr && i < N_TEXT_STRINGS_MIN)
264
                {
265
                        Error("Not enough strings in text file - expecting %d (or at least %d), found %d",N_TEXT_STRINGS,N_TEXT_STRINGS_MIN,i);
266
                }
267
#endif
268
                Text_string[i] = tptr;
269
                char *ts = tptr;
270
 
271
                tptr = strchr(tptr,'\n');
272
 
273
#if defined(DXX_BUILD_DESCENT_II)
274
                if (!tptr)
275
                {
276
                        if (i == 644) break;    /* older datafiles */
277
 
278
                        Error("Not enough strings in text file - expecting %d, found %d\n", N_TEXT_STRINGS, i);
279
                }
280
#endif
281
                if ( tptr ) *tptr++ = 0;
282
 
283
                if (have_binary)
284
                        decode_text_line(ts);
285
 
286
                //scan for special chars (like \n)
287
                if ((p = strchr(ts, '\\')) != NULL) {
288
                        for (char *q = p; assert(*p == '\\'), *p;) {
289
                        char newchar;
290
 
291
                        if (p[1] == 'n') newchar = '\n';
292
                        else if (p[1] == 't') newchar = '\t';
293
                        else if (p[1] == '\\') newchar = '\\';
294
                        else
295
                                Error("Unsupported key sequence <\\%c> on line %d of file <%s>",p[1],i+1,filename);
296
 
297
                                *q++ = newchar;
298
                                p += 2;
299
                                char *r = strchr(p, '\\');
300
                                if (!r)
301
                                {
302
                                        r = tptr;
303
                                        assert(!r[-1]);
304
                                        assert(r == 1 + p + strlen(p));
305
                                        memmove(q, p, r - p);
306
                                        break;
307
                                }
308
                                memmove(q, p, r - p);
309
                                q += (r - p);
310
                                p = r;
311
                        }
312
                }
313
 
314
          switch(i) {
315
#if defined(DXX_BUILD_DESCENT_I)
316
                        case 116:
317
                                if (!d_stricmp(ts, "SPREADFIRE")) // This string is too long to fit in the cockpit-box
318
                                {
319
                                        ts[6] = 0;
320
                                }
321
                                break;
322
#endif
323
 
324
                          case IDX_TEXT_OVERWRITTEN:
325
                                {
326
                                  static const char extra[] = "\n<Ctrl-C> converts format\nIntel <-> PowerPC";
327
                                std::size_t l = strlen(ts);
328
                                overwritten_text = std::make_unique<char[]>(l + sizeof(extra));
329
                                char *o = overwritten_text.get();
330
                                std::copy_n(extra, sizeof(extra), std::copy_n(ts, l, o));
331
                                Text_string[i] = o;
332
                                  break;
333
                                }
334
          }
335
 
336
        }
337
 
338
#if defined(DXX_BUILD_DESCENT_II)
339
        if (i == 644)
340
        {
341
                if (len == SHAREWARE_TEXTSIZE)
342
                {
343
                        Text_string[173] = Text_string[172];
344
                        Text_string[172] = Text_string[171];
345
                        Text_string[171] = Text_string[170];
346
                        Text_string[170] = Text_string[169];
347
                        Text_string[169] = "Windows Joystick";
348
                }
349
 
350
                Text_string[644] = "Z1";
351
                Text_string[645] = "UN";
352
                Text_string[646] = "P1";
353
                Text_string[647] = "R1";
354
                Text_string[648] = "Y1";
355
        }
356
#endif
357
 
358
#ifdef GENERATE_BUILTIN_TEXT_TABLE
359
        for (unsigned u = 0; u < std::size(Text_string); ++u)
360
        {
361
                printf("\t%u\t\"", u);
362
                for (char *px = Text_string[u]; *px; ++px) {
363
                        unsigned x = (unsigned)*px;
364
                        if (isprint(x))
365
                                putchar(x);
366
                        else if (x == '\t')
367
                                printf("\\t");
368
                        else if (x == '\r')
369
                                printf("\\r");
370
                        else if (x == '\n')
371
                                printf("\\n");
372
                        else
373
                                printf("\\x%.2x", x);
374
                }
375
                printf("\"\n");
376
        }      
377
#endif
378
 
379
        //Assert(tptr==text+len || tptr==text+len-2);
380
 
381
}
382
}
383
 
384