//decode an encoded line of text of bitmaps.tbl void decode_text_line(char *p) { for (;*p;p++) { encode_rotate_left(p); *p = *p ^ BITMAP_TBL_XOR; encode_rotate_left(p); } }
// decode buffer of text, preserves newlines void decode_text(char *buf, int len) { char *ptr; int i; for (i = 0, ptr = buf; i < len; i++, ptr++) { if (*ptr != '\n') { encode_rotate_left(ptr); *ptr = *ptr ^ BITMAP_TBL_XOR; encode_rotate_left(ptr); } } }
//load all the text strings for Descent void load_text() { CFILE *tfile; CFILE *ifile; int len,i, have_binary = 0; char *tptr; char *filename="descent.tex"; if ((i=FindArg("-text"))!=0) filename = Args[i+1]; if ((tfile = cfopen(filename,"rb")) == NULL) { filename="descent.txb"; if ((ifile = cfopen(filename, "rb")) == NULL) Error("Cannot open file DESCENT.TEX or DESCENT.TXB"); have_binary = 1; len = cfilelength(ifile); //MALLOC(text,char,len);//Won't compile... working on it..-KRB text=malloc(len*sizeof(char));//my hack -KRB atexit(free_text); cfread(text,1,len,ifile); cfclose(ifile); } else { int c; char * p; len = cfilelength(tfile); //MALLOC(text,char,len);//Won't compile... working on it..-KRB text=malloc(len*sizeof(char));//my hack -KRB atexit(free_text); //fread(text,1,len,tfile); p = text; do { c = cfgetc( tfile ); if ( c != 13 ) *p++ = c; } while ( c!=EOF ); cfclose(tfile); } for (i=0,tptr=text;i<N_TEXT_STRINGS;i++) { char *p; Text_string[i] = tptr; tptr = strchr(tptr,'\n'); if (!tptr) Error("Not enough strings in text file - expecting %d, found %d",N_TEXT_STRINGS,i); if ( tptr ) *tptr++ = 0; if (have_binary) { for (p=Text_string[i]; p < tptr - 1; p++) { encode_rotate_left(p); *p = *p ^ BITMAP_TBL_XOR; encode_rotate_left(p); } } //scan for special chars (like \n) for (p=Text_string[i];p=strchr(p,'\\');) { char newchar; if (p[1] == 'n') newchar = '\n'; else if (p[1] == 't') newchar = '\t'; else if (p[1] == '\\') newchar = '\\'; else Error("Unsupported key sequence <\\%c> on line %d of file <%s>",p[1],i+1,filename); p[0] = newchar; sprintf(p+1, "%s", p+2); p++; } } // Assert(tptr==text+len || tptr==text+len-2); }
//called for each level to load & setup the exit sequence load_endlevel_data(int level_num) { char filename[13]; char line[LINE_LEN],*p; CFILE *ifile; int var,segnum,sidenum; int exit_side, i; int have_binary = 0; endlevel_data_loaded = 0; //not loaded yet try_again: ; if (level_num<0) //secret level strcpy(filename,Secret_level_names[-level_num-1]); else //normal level strcpy(filename,Level_names[level_num-1]); if (!convert_ext(filename,"END")) return; ifile = cfopen(filename,"rb"); if (!ifile) { convert_ext(filename,"TXB"); ifile = cfopen(filename,"rb"); if (!ifile) if (level_num==1) { return; //abort //Error("Cannot load file text of binary version of <%s>",filename); } else { level_num = 1; goto try_again; } have_binary = 1; } //ok...this parser is pretty simple. It ignores comments, but //everything else must be in the right place var = 0; while (cfgets(line,LINE_LEN,ifile)) { if (have_binary) { for (i = 0; i < strlen(line) - 1; i++) { encode_rotate_left(&(line[i])); line[i] = line[i] ^ BITMAP_TBL_XOR; encode_rotate_left(&(line[i])); } p = line; } if ((p=strchr(line,';'))!=NULL) *p = 0; //cut off comment for (p=line+strlen(line)-1;p>line && isspace(*p);*p--=0); for (p=line;isspace(*p);p++); if (!*p) //empty line continue; switch (var) { case 0: { //ground terrain int iff_error; ubyte pal[768]; if (terrain_bm_instance.bm_data) free(terrain_bm_instance.bm_data); iff_error = iff_read_bitmap(p,&terrain_bm_instance,BM_LINEAR,pal); if (iff_error != IFF_NO_ERROR) { mprintf((1, "File %s - IFF error: %s",p,iff_errormsg(iff_error))); Error("File %s - IFF error: %s",p,iff_errormsg(iff_error)); } terrain_bitmap = &terrain_bm_instance; gr_remap_bitmap_good( terrain_bitmap, pal, iff_transparent_color, -1); break; } case 1: //height map load_terrain(p); break; case 2: sscanf(p,"%d,%d",&exit_point_bmx,&exit_point_bmy); break; case 3: //exit heading exit_angles.h = i2f(atoi(p))/360; break; case 4: { //planet bitmap int iff_error; ubyte pal[768]; if (satellite_bm_instance.bm_data) free(satellite_bm_instance.bm_data); iff_error = iff_read_bitmap(p,&satellite_bm_instance,BM_LINEAR,pal); if (iff_error != IFF_NO_ERROR) { mprintf((1, "File %s - IFF error: %s",p,iff_errormsg(iff_error))); Error("File %s - IFF error: %s",p,iff_errormsg(iff_error)); } satellite_bitmap = &satellite_bm_instance; gr_remap_bitmap_good( satellite_bitmap, pal, iff_transparent_color, -1); break; } case 5: //earth pos case 7: { //station pos vms_matrix tm; vms_angvec ta; int pitch,head; sscanf(p,"%d,%d",&head,&pitch); ta.h = i2f(head)/360; ta.p = -i2f(pitch)/360; ta.b = 0; vm_angles_2_matrix(&tm,&ta); if (var==5) satellite_pos = tm.fvec; //vm_vec_copy_scale(&satellite_pos,&tm.fvec,SATELLITE_DIST); else station_pos = tm.fvec; break; } case 6: //planet size satellite_size = i2f(atoi(p)); break; } var++; } Assert(var == NUM_VARS); // OK, now the data is loaded. Initialize everything //find the exit sequence by searching all segments for a side with //children == -2 for (segnum=0,exit_segnum=-1;exit_segnum==-1 && segnum<=Highest_segment_index;segnum++) for (sidenum=0;sidenum<6;sidenum++) if (Segments[segnum].children[sidenum] == -2) { exit_segnum = segnum; exit_side = sidenum; break; } Assert(exit_segnum!=-1); compute_segment_center(&mine_exit_point,&Segments[exit_segnum]); extract_orient_from_segment(&mine_exit_orient,&Segments[exit_segnum]); compute_center_point_on_side(&mine_side_exit_point,&Segments[exit_segnum],exit_side); vm_vec_scale_add(&mine_ground_exit_point,&mine_exit_point,&mine_exit_orient.uvec,-i2f(20)); //compute orientation of surface { vms_vector tv; vms_matrix exit_orient,tm; vm_angles_2_matrix(&exit_orient,&exit_angles); vm_transpose_matrix(&exit_orient); vm_matrix_x_matrix(&surface_orient,&mine_exit_orient,&exit_orient); vm_copy_transpose_matrix(&tm,&surface_orient); vm_vec_rotate(&tv,&station_pos,&tm); vm_vec_scale_add(&station_pos,&mine_exit_point,&tv,STATION_DIST); vm_vec_rotate(&tv,&satellite_pos,&tm); vm_vec_scale_add(&satellite_pos,&mine_exit_point,&tv,SATELLITE_DIST); vm_vector_2_matrix(&tm,&tv,&surface_orient.uvec,NULL); vm_vec_copy_scale(&satellite_upvec,&tm.uvec,SATELLITE_HEIGHT); } cfclose(ifile); endlevel_data_loaded = 1; }
void credits_show() { int i, j, l, done; CFILE * file; char buffer[NUM_LINES][80]; grs_bitmap backdrop; ubyte backdrop_palette[768]; int pcx_error; int buffer_line = 0; fix last_time; fix time_delay = 4180 / f2fl(Scale_y); // ~ F1_0 / 12.9 int first_line_offset,extra_inc=0; int have_bin_file = 0; char * tempp; grs_point scale_pts[] = FULLSCREEN_SCALE_PTS; ubyte *fade_values = malloc(grd_curscreen->sc_h); for (i = 0; i < grd_curscreen->sc_h; ++i) { fade_values[i] = fade_values_200[(int)(((float)i / (float)grd_curscreen->sc_h) * 200)]; } set_screen_mode(SCREEN_MENU); // Clear out all tex buffer lines. for (i=0; i<NUM_LINES; i++ ) buffer[i][0] = 0; have_bin_file = 0; file = cfopen( "credits.tex", "rb" ); if (file == NULL) { file = cfopen("credits.txb", "rb"); if (file == NULL) Error("Missing CREDITS.TEX and CREDITS.TXB file\n"); have_bin_file = 1; } gr_use_palette_table( "credits.256" ); header_font = gr_init_font( "font1-1.fnt" ); title_font = gr_init_font( "font2-3.fnt" ); names_font = gr_init_font( "font2-2.fnt" ); backdrop.bm_data=NULL; pcx_error = pcx_read_bitmap("stars.pcx",&backdrop,BM_LINEAR,backdrop_palette); if (pcx_error != PCX_ERROR_NONE) { cfclose(file); return; } songs_play_song( SONG_CREDITS, 0 ); gr_remap_bitmap_good( &backdrop,backdrop_palette, -1, -1 ); gr_set_current_canvas(NULL); scale_bitmap(&backdrop,scale_pts); gr_palette_fade_in( gr_palette, 32, 0 ); vfx_set_palette_sub( gr_palette ); //gr_clear_canvas(BM_XRGB(0,0,0)); key_flush(); last_time = timer_get_fixed_seconds(); done = 0; first_line_offset = 0; while( 1 ) { int k; do { buffer_line = (buffer_line+1) % NUM_LINES; if (cfgets( buffer[buffer_line], 80, file )) { char *p; if (have_bin_file) { // is this a binary tbl file for (i = 0; i < strlen(buffer[buffer_line]) - 1; i++) { encode_rotate_left(&(buffer[buffer_line][i])); buffer[buffer_line][i] ^= BITMAP_TBL_XOR; encode_rotate_left(&(buffer[buffer_line][i])); } } p = strchr(&buffer[buffer_line][0],'\n'); if (p) *p = '\0'; } else { //fseek( file, 0, SEEK_SET); buffer[buffer_line][0] = 0; done++; } } while (extra_inc--); extra_inc = 0; for (i=0; i<ROW_SPACING; i++ ) { int y; y = first_line_offset - i; #ifndef OGLES gr_set_current_canvas(VR_offscreen_buffer); #endif scale_bitmap(&backdrop, scale_pts); for (j=0; j<NUM_LINES; j++ ) { char *s; l = (buffer_line + j + 1 ) % NUM_LINES; s = buffer[l]; if ( s[0] == '!' ) { s++; } else if ( s[0] == '$' ) { grd_curcanv->cv_font = header_font; s++; } else if ( s[0] == '*' ) { grd_curcanv->cv_font = title_font; s++; } else grd_curcanv->cv_font = names_font; gr_bitblt_fade_table = fade_values; tempp = strchr( s, '\t' ); if ( tempp ) { int w, h, aw; *tempp = 0; gr_get_string_size( s, &w, &h, &aw ); w *= f2fl(Scale_x); h *= f2fl(Scale_y); gr_scale_printf( (160-w)/2, y, Scale_factor, Scale_factor, s ); gr_get_string_size( &tempp[1], &w, &h, &aw ); w *= f2fl(Scale_x); h *= f2fl(Scale_y); gr_scale_printf( 160+((160-w)/2), y, Scale_factor, Scale_factor, &tempp[1] ); *tempp = '\t'; } else { gr_scale_printf( 0x8000, y, Scale_factor, Scale_factor, s ); } gr_bitblt_fade_table = NULL; if (buffer[l][0] == '!') y += ROW_SPACING/2; else y += ROW_SPACING; } #ifdef OGLES showRenderBuffer(); #else gr_bm_ubitblt(grd_curscreen->sc_w, grd_curscreen->sc_h, 0, 0, 0, 0, &(VR_offscreen_buffer->cv_bitmap), &(grd_curscreen->sc_canvas.cv_bitmap) ); #endif while( timer_get_fixed_seconds() < last_time+time_delay ); last_time = timer_get_fixed_seconds(); k = key_inkey(); #ifndef NDEBUG if (k == KEY_BACKSP) { Int3(); k=0; } #endif // { // fix ot = time_delay; // time_delay += (keyd_pressed[KEY_X] - keyd_pressed[KEY_Z])*100; // if (ot!=time_delay) { // mprintf( (0, "[%x] ", time_delay )); // } // } if (k == KEY_PRINT_SCREEN) { save_screen_shot(0); k = 0; } if ((k>0)||(done>NUM_LINES)) { gr_close_font(header_font); gr_close_font(title_font); gr_close_font(names_font); gr_palette_fade_out( gr_palette, 32, 0 ); gr_use_palette_table( "palette.256" ); free(backdrop.bm_data); cfclose(file); songs_play_song( SONG_TITLE, 1 ); return; } } if (buffer[(buffer_line + 1 ) % NUM_LINES][0] == '!') { first_line_offset -= ROW_SPACING-ROW_SPACING/2; if (first_line_offset <= -ROW_SPACING) { first_line_offset += ROW_SPACING; extra_inc++; } } } free(fade_values); }