2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
14 char copyright[] = "DESCENT II COPYRIGHT (C) 1994-1996 PARALLAX SOFTWARE CORPORATION";
24 #include "pa_enabl.h" //$$POLY_ACC
36 #include "segment.h" //for Side_to_verts
76 // # include "3dfx_des.h"
80 extern int Current_display_mode; //$$ there's got to be a better way than hacking this.
84 #include "editor\editor.h"
85 #include "editor\kdefs.h"
93 void arch_init_start(void);
95 //Current version number
97 ubyte Version_major = 1; //FULL VERSION
98 ubyte Version_minor = 2;
100 static const char desc_id_checksum_str[] = DESC_ID_CHKSUM_TAG "0000"; //4-byte checksum
101 char desc_id_exit_num = 0;
103 int Function_mode=FMODE_MENU; //game or editor?
104 int Screen_mode=-1; //game screen or editor screen?
106 //--unused-- grs_bitmap Inferno_bitmap_title;
108 int WVIDEO_running=0; //debugger can set to 1 if running
111 int Inferno_is_800x600_available = 0;
114 //--unused-- int Cyberman_installed=0; // SWIFT device present
115 ubyte CybermouseActive=0;
117 int __far descent_critical_error_handler( unsigned deverr, unsigned errcode, unsigned __far * devhdr );
119 void check_joystick_calibration(void);
122 //--------------------------------------------------------------------------
124 extern int piggy_low_memory;
127 int descent_critical_error = 0;
128 unsigned descent_critical_deverror = 0;
129 unsigned descent_critical_errcode = 0;
131 extern int Network_allow_socket_changes;
133 extern void vfx_set_palette_sub(ubyte *);
135 extern int VR_low_res;
137 extern int Config_vr_type;
138 extern int Config_vr_resolution;
139 extern int Config_vr_tracking;
140 int grd_fades_disabled=1;
144 void do_joystick_init()
148 if (!args_find( "-nojoystick" )) {
149 con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_6);
151 if ( args_find( "-joyslow" )) {
152 con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_7);
153 joy_set_slow_reading(JOY_SLOW_READINGS);
155 if ( args_find( "-joypolled" )) {
156 con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_8);
157 joy_set_slow_reading(JOY_POLLED_READINGS);
159 if ( args_find( "-joybios" )) {
160 con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_9);
161 joy_set_slow_reading(JOY_BIOS_READINGS);
164 // Added from Descent v1.5 by John. Adapted by Samir.
166 con_printf(CON_VERBOSE, "\n%s", TXT_VERBOSE_10);
170 //set this to force game to run in low res
171 int disable_high_res=0;
173 void do_register_player(ubyte *title_pal)
175 Players[Player_num].callsign[0] = '\0';
181 //now, before we bring up the register player menu, we need to
182 //do some stuff to make sure the palette is ok. First, we need to
183 //get our current palette into the 2d's array, so the remapping will
184 //work. Second, we need to remap the fonts. Third, we need to fill
185 //in part of the fade tables so the darkening of the menu edges works
187 memcpy(gr_palette,title_pal,sizeof(gr_palette));
188 remap_fonts_and_menus(1);
189 RegisterPlayer(); //get player's name
195 void do_network_init()
197 if (!args_find( "-nonetwork" )) {
198 int socket=0, showaddress=0, t;
201 con_printf(CON_VERBOSE, "\n%s ", TXT_INITIALIZING_NETWORK);
202 if ((t=args_find("-socket")))
203 socket = atoi( Args[t+1] );
204 //@@if ( args_find("-showaddress") ) showaddress=1;
205 if ((ipx_error=ipx_init(IPX_DEFAULT_SOCKET+socket,showaddress))==0) {
206 con_printf(CON_VERBOSE, "%s %d.\n", TXT_IPX_CHANNEL, socket );
209 switch( ipx_error ) {
210 case 3: con_printf(CON_VERBOSE, "%s\n", TXT_NO_NETWORK); break;
211 case -2: con_printf(CON_VERBOSE, "%s 0x%x.\n", TXT_SOCKET_ERROR, IPX_DEFAULT_SOCKET+socket); break;
212 case -4: con_printf(CON_VERBOSE, "%s\n", TXT_MEMORY_IPX ); break;
214 con_printf(CON_VERBOSE, "%s %d", TXT_ERROR_IPX, ipx_error );
216 con_printf(CON_VERBOSE, "%s\n",TXT_NETWORK_DISABLED);
217 Network_active = 0; // Assume no network
219 ipx_read_user_file( "descent.usr" );
220 ipx_read_network_file( "descent.net" );
221 //@@if ( args_find( "-dynamicsockets" ))
222 //@@ Network_allow_socket_changes = 1;
224 //@@ Network_allow_socket_changes = 0;
226 con_printf(CON_VERBOSE, "%s\n", TXT_NETWORK_DISABLED);
227 Network_active = 0; // Assume no network
233 #define PROGNAME "d2demo"
235 #define PROGNAME "d2"
238 extern char Language[];
240 //can we do highres menus?
241 extern int MenuHiresAvailable;
244 int intro_played = 0;
247 int open_movie_file(char *filename,int must_have);
249 #if defined(POLY_ACC)
250 #define MENU_HIRES_MODE SM_640x480x15xPA
252 #define MENU_HIRES_MODE SM(640,480)
255 // DESCENT II by Parallax Software
258 //extern ubyte gr_current_pal[];
262 char Auto_file[128] = "";
265 int main(int argc,char **argv)
268 ubyte title_pal[768];
271 con_init(); // Initialise the console
274 error_init(NULL, NULL);
276 args_init( argc,argv );
278 if ( args_find( "-debug") )
280 con_threshold.value = (float)2;
283 if ( args_find( "-verbose" ) )
285 con_threshold.value = (float)1;
292 //tell cfile about our counter
293 cfile_set_critical_error_counter_ptr(&descent_critical_error);
296 cfile_init("d2demo.hog"); //specify name of hogfile
298 #define HOGNAME "descent2.hog"
299 if (! cfile_init(HOGNAME)) { //didn't find HOG. Check on CD
301 Error("Could not find required file <%s>",HOGNAME);
308 //print out the banner title
309 con_printf(CON_NORMAL, "\nDESCENT 2 %s v%d.%d",VERSION_TYPE,Version_major,Version_minor);
310 con_printf(CON_NORMAL, " %s %s\n", __DATE__,__TIME__);
311 con_printf(CON_NORMAL, "%s\n%s\n",TXT_COPYRIGHT,TXT_TRADEMARK);
312 con_printf(CON_NORMAL, "This is a MODIFIED version of Descent 2. Copyright (c) 1999 Peter Hawkins\n");
315 if (args_find( "-?" ) || args_find( "-help" ) || args_find( "?" ) ) {
316 //print_commandline_help();
317 set_exit_message("");
321 con_printf(CON_NORMAL, "\n");
322 con_printf(CON_NORMAL, TXT_HELP, PROGNAME); //help message has %s for program name
323 con_printf(CON_NORMAL, "\n");
325 con_printf(CON_VERBOSE, "\n%s...", "Checking for Descent 2 CD-ROM");
327 if ( args_find( "-autodemo" ))
330 if ( args_find( "-noscreens" ) )
331 Skip_briefing_screens = 1;
335 // if (init_graphics()) return 1;
338 if (!Inferno_is_800x600_available) {
339 con_printf(CON_NORMAL "The editor will not be available, press any key to start game...\n" );
340 Function_mode = FMODE_MENU;
345 con_printf(CON_DEBUG,"WVIDEO_running = %d\n",WVIDEO_running);
347 con_printf (CON_VERBOSE, "%s", TXT_VERBOSE_1);
354 #if defined(POLY_ACC)
355 Current_display_mode = -1;
356 game_init_render_buffers(SM_640x480x15xPA, 640, 480, VR_NONE, VRF_COMPATIBLE_MENUS+VRF_ALLOW_COCKPIT );
359 if (!VR_offscreen_buffer) //if hasn't been initialied (by headset init)
360 set_display_mode(0); //..then set default display mode
363 i = args_find( "-xcontrol" );
365 kconfig_init_external_controls( strtol(Args[i+1], NULL, 0), strtol(Args[i+2], NULL, 0) );
368 con_printf(CON_VERBOSE, "\n%s\n\n", TXT_INITIALIZING_GRAPHICS);
369 if (args_find("-nofade"))
370 grd_fades_disabled=1;
372 if ((t=gr_init())!=0) //doesn't do much
373 Error(TXT_CANT_INIT_GFX,t);
379 // Load the palette stuff. Returns non-zero if error.
380 con_printf(CON_DEBUG, "\nInitializing palette system..." );
381 gr_use_palette_table(DEFAULT_PALETTE );
383 con_printf(CON_DEBUG, "\nInitializing font system..." );
384 gamefont_init(); // must load after palette data loaded.
386 //determine whether we're using high-res menus & movies
387 #if !defined(POLY_ACC)
388 if (args_find("-nohires") || args_find("-nohighres") || (gr_check_mode(MENU_HIRES_MODE) != 0) || disable_high_res)
389 MovieHires = MenuHires = MenuHiresAvailable = 0;
392 //NOTE LINK TO ABOVE!
393 MenuHires = MenuHiresAvailable = 1;
395 con_printf( CON_DEBUG, "\nInitializing movie libraries..." );
396 init_movies(); //init movie libraries
398 con_printf(CON_VERBOSE, "\nGoing into graphics mode...\n");
399 #if defined(POLY_ACC)
400 gr_set_mode(SM_640x480x15xPA);
402 gr_set_mode(MovieHires?SM(640,480):SM(320,200));
406 if ( args_find( "-notitles" ) )
407 songs_play_song( SONG_TITLE, 1);
410 { //NOTE LINK TO ABOVE!
411 int played=MOVIE_NOT_PLAYED; //default is not played
412 int song_playing = 0;
415 #define MOVIE_REQUIRED 0
417 #define MOVIE_REQUIRED 1
420 #ifdef D2_OEM //$$POLY_ACC, jay.
421 { //show bundler screens
423 char filename[FILENAME_LEN];
425 played=MOVIE_NOT_PLAYED; //default is not played
427 played = PlayMovie("pre_i.mve",0);
430 strcpy(filename,MenuHires?"pre_i1b.pcx":"pre_i1.pcx");
432 while ((tfile=fopen(filename,"rb")) != NULL) {
434 show_title_screen( filename, 1, 0 );
442 init_subtitles("intro.tex");
443 played = PlayMovie("intro.mve",MOVIE_REQUIRED);
448 if (played != MOVIE_NOT_PLAYED)
450 else { //didn't get intro movie, try titles
452 played = PlayMovie("titles.mve",MOVIE_REQUIRED);
454 if (played == MOVIE_NOT_PLAYED) {
455 #if defined(POLY_ACC)
456 gr_set_mode(SM_640x480x15xPA);
458 gr_set_mode(MenuHires?SM_640x480V:SM_320x200C);
460 con_printf( CON_DEBUG, "\nPlaying title song..." );
461 songs_play_song( SONG_TITLE, 1);
463 con_printf( CON_DEBUG, "\nShowing logo screens..." );
464 show_title_screen( MenuHires?"iplogo1b.pcx":"iplogo1.pcx", 1, 1 );
465 show_title_screen( MenuHires?"logob.pcx":"logo.pcx", 1, 1 );
469 { //show bundler movie or screens
472 char filename[FILENAME_LEN];
475 played=MOVIE_NOT_PLAYED; //default is not played
477 //check if OEM movie exists, so we don't stop the music if it doesn't
478 movie_handle = open_movie_file("oem.mve",0);
479 if (movie_handle != -1) {
481 played = PlayMovie("oem.mve",0);
482 song_playing = 0; //movie will kill sound
486 strcpy(filename,MenuHires?"oem1b.pcx":"oem1.pcx");
488 while ((tfile=fopen(filename,"rb")) != NULL) {
490 show_title_screen( filename, 1, 0 );
498 songs_play_song( SONG_TITLE, 1);
502 PA_DFX (pa_splash());
504 con_printf( CON_DEBUG, "\nShowing loading screen..." );
506 //grs_bitmap title_bm;
511 strcpy(filename, "descentd.pcx");
514 strcpy(filename, MenuHires?"descntob.pcx":"descento.pcx");
516 strcpy(filename, MenuHires?"descentb.pcx":"descent.pcx");
520 #if defined(POLY_ACC)
521 gr_set_mode(SM_640x480x15xPA);
523 gr_set_mode(MenuHires?SM(640,480):SM(320,200));
526 FontHires = MenuHires;
528 if ((pcx_error=pcx_read_bitmap( filename, &grd_curcanv->cv_bitmap, grd_curcanv->cv_bitmap.bm_type, title_pal ))==PCX_ERROR_NONE) {
529 //vfx_set_palette_sub( title_pal );
531 gr_palette_fade_in( title_pal, 32, 0 );
533 Error( "Couldn't load pcx file '%s', PCX load error: %s\n",filename, pcx_errormsg(pcx_error));
536 con_printf( CON_DEBUG , "\nDoing bm_init..." );
544 if (args_find("-hoarddata") != 0) {
545 #define MAX_BITMAPS_PER_BRUSH 30
546 grs_bitmap * bm[MAX_BITMAPS_PER_BRUSH];
550 ubyte palette[256*3];
553 char *sounds[] = {"selforb.raw","selforb.r22", //SOUND_YOU_GOT_ORB
554 "teamorb.raw","teamorb.r22", //SOUND_FRIEND_GOT_ORB
555 "enemyorb.raw","enemyorb.r22", //SOUND_OPPONENT_GOT_ORB
556 "OPSCORE1.raw","OPSCORE1.r22"}; //SOUND_OPPONENT_HAS_SCORED
558 ofile = fopen("hoard.ham","wb");
560 iff_error = iff_read_animbrush("orb.abm",bm,MAX_BITMAPS_PER_BRUSH,&nframes,palette);
561 Assert(iff_error == IFF_NO_ERROR);
562 nframes_short = nframes;
563 fwrite(&nframes_short,sizeof(nframes_short),1,ofile);
564 fwrite(&bm[0]->bm_w,sizeof(short),1,ofile);
565 fwrite(&bm[0]->bm_h,sizeof(short),1,ofile);
566 fwrite(palette,3,256,ofile);
567 for (i=0;i<nframes;i++)
568 fwrite(bm[i]->bm_data,1,bm[i]->bm_w*bm[i]->bm_h,ofile);
570 iff_error = iff_read_animbrush("orbgoal.abm",bm,MAX_BITMAPS_PER_BRUSH,&nframes,palette);
571 Assert(iff_error == IFF_NO_ERROR);
572 Assert(bm[0]->bm_w == 64 && bm[0]->bm_h == 64);
573 nframes_short = nframes;
574 fwrite(&nframes_short,sizeof(nframes_short),1,ofile);
575 fwrite(palette,3,256,ofile);
576 for (i=0;i<nframes;i++)
577 fwrite(bm[i]->bm_data,1,bm[i]->bm_w*bm[i]->bm_h,ofile);
580 iff_error = iff_read_bitmap(i?"orbb.bbm":"orb.bbm",&icon,BM_LINEAR,palette);
581 Assert(iff_error == IFF_NO_ERROR);
582 fwrite(&icon.bm_w,sizeof(short),1,ofile);
583 fwrite(&icon.bm_h,sizeof(short),1,ofile);
584 fwrite(palette,3,256,ofile);
585 fwrite(icon.bm_data,1,icon.bm_w*icon.bm_h,ofile);
588 for (i=0;i<sizeof(sounds)/sizeof(*sounds);i++) {
592 ifile = fopen(sounds[i],"rb");
593 Assert(ifile != NULL);
594 size = filelength(ifile->_handle);
595 buf = d_malloc(size);
596 fread(buf,1,size,ifile);
597 fwrite(&size,sizeof(size),1,ofile);
598 fwrite(buf,1,size,ofile);
609 //the bitmap loading code changes gr_palette, so restore it
610 memcpy(gr_palette,title_pal,sizeof(gr_palette));
612 if ( args_find( "-norun" ) )
615 con_printf( CON_DEBUG, "\nInitializing 3d system..." );
618 con_printf( CON_DEBUG, "\nInitializing texture caching system..." );
619 texmerge_init( 10 ); // 10 cache bitmaps
621 con_printf( CON_DEBUG, "\nRunning game...\n" );
622 set_screen_mode(SCREEN_MENU);
626 // If built with editor, option to auto-load a level and quit game
627 // to write certain data.
630 if ( t = args_find( "-autoload" ) ) {
632 strcpy(Auto_file, Args[t+1]);
638 strcpy(Players[0].callsign, "dummy");
641 do_register_player(title_pal);
643 gr_palette_fade_out( title_pal, 32, 0 );
645 Game_mode = GM_GAME_OVER;
648 newdemo_start_playback("descent.dem");
649 if (Newdemo_state == ND_STATE_PLAYBACK )
650 Function_mode = FMODE_GAME;
653 //do this here because the demo code can do a longjmp when trying to
654 //autostart a demo from the main menu, never having gone into the game
657 while (Function_mode != FMODE_EXIT)
659 switch( Function_mode ) {
661 set_screen_mode(SCREEN_MENU);
663 newdemo_start_playback(NULL); // Randomly pick a file
664 if (Newdemo_state != ND_STATE_PLAYBACK)
665 Error("No demo files were found for autodemo mode!");
669 strcpy(&Level_names[0], Auto_file);
671 Function_mode = FMODE_EXIT;
676 check_joystick_calibration();
677 gr_palette_clear(); //I'm not sure why we need this, but we do
680 if ( Function_mode == FMODE_EDITOR ) {
682 SetPlayerFromCurseg();
683 load_palette(NULL,1,0);
690 keyd_editor_mode = 0;
693 if ( Function_mode == FMODE_MENU )
694 songs_play_song( SONG_TITLE, 1 );
698 keyd_editor_mode = 1;
700 _harderr( (void*)descent_critical_error_handler ); // Reinstall game error handler
701 if ( Function_mode == FMODE_GAME ) {
702 Game_mode = GM_EDITOR;
703 editor_reset_stuff_on_level();
709 Error("Invalid function mode %d",Function_mode);
716 if (!args_find( "-notitles" ))
720 if ( args_find( "-showmeminfo" ) )
721 show_mem_info = 1; // Make memory statistics show
724 return(0); //presumably successful exit
728 void check_joystick_calibration() {
729 int x1, y1, x2, y2, c;
732 if ( (Config_control_type!=CONTROL_JOYSTICK) &&
733 (Config_control_type!=CONTROL_FLIGHTSTICK_PRO) &&
734 (Config_control_type!=CONTROL_THRUSTMASTER_FCS) &&
735 (Config_control_type!=CONTROL_GRAVIS_GAMEPAD)
738 joy_get_pos( &x1, &y1 );
740 t1 = timer_get_fixed_seconds();
741 while( timer_get_fixed_seconds() < t1 + F1_0/100 )
744 joy_get_pos( &x2, &y2 );
746 // If joystick hasn't moved...
747 if ( (abs(x2-x1)<30) && (abs(y2-y1)<30) ) {
748 if ( (abs(x1)>30) || (abs(x2)>30) || (abs(y1)>30) || (abs(y2)>30) ) {
749 c = nm_messagebox( NULL, 2, TXT_CALIBRATE, TXT_SKIP, TXT_JOYSTICK_NOT_CEN );