예제 #1
0
//draws a bitmap with the specified 3d width & height 
//returns 1 if off screen, 0 if drew
void g3_draw_bitmap(const vms_vector &pos,fix width,fix height,grs_bitmap &bm)
{
	g3s_point pnt;
	fix w,h;
	if (g3_rotate_point(pnt,pos) & CC_BEHIND)
		return;
	g3_project_point(pnt);
	if (pnt.p3_flags & PF_OVERFLOW)
		return;
#ifndef __powerc
	fix t;
	if (checkmuldiv(&t,width,Canv_w2,pnt.p3_z))
		w = fixmul(t,Matrix_scale.x);
	else
		return;

	if (checkmuldiv(&t,height,Canv_h2,pnt.p3_z))
		h = fixmul(t,Matrix_scale.y);
	else
		return;
#else
	if (pnt.p3_z == 0)
		return;
	double fz = f2fl(pnt.p3_z);
	w = fixmul(fl2f(((f2fl(width)*fCanv_w2) / fz)), Matrix_scale.x);
	h = fixmul(fl2f(((f2fl(height)*fCanv_h2) / fz)), Matrix_scale.y);
#endif
	const fix blob0y = pnt.p3_sy - h, blob1x = pnt.p3_sx + w;
	const array<grs_point, 3> blob_vertices{{
		{pnt.p3_sx - w, blob0y},
		{blob1x, blob0y},
		{blob1x, pnt.p3_sy + h},
	}};
	scale_bitmap(bm, blob_vertices, 0);
}
예제 #2
0
void
died_in_mine_message(void)
{
	// Tell the player he died in the mine, explain why
	int old_fmode, pcx_error;
	grs_bitmap bmp;
	grs_point scale_pts[] = FULLSCREEN_SCALE_PTS;

	if (Game_mode & GM_MULTI)
		return;

	gr_palette_fade_out(gr_palette, 32, 0);

	gr_set_current_canvas(NULL);
	
	bmp.bm_data = NULL;
	pcx_error = pcx_read_bitmap("STARS.PCX",&bmp,BM_LINEAR,NULL);
	Assert(pcx_error == PCX_ERROR_NONE);
	scale_bitmap(&bmp, scale_pts);
	free(bmp.bm_data);

	old_fmode = Function_mode;
	Function_mode = FMODE_MENU;
	nm_messagebox(NULL, 1, TXT_OK, TXT_DIED_IN_MINE);
	Function_mode = old_fmode;
}
예제 #3
0
파일: gtkplotgdk.c 프로젝트: deweerdt/TSP
static void gtk_plot_gdk_draw_pixmap                (GtkPlotPC *pc,
                                                     GdkPixmap *pixmap,
                                                     GdkBitmap *mask,
                                                     gint xsrc, gint ysrc,
                                                     gint xdest, gint ydest,
                                                     gint width,
                                                     gint height,
                                                     gdouble scale_x, 
                                                     gdouble scale_y)
{
  GdkGC *gc;
  GdkPixmap *new_pixmap;
  GdkBitmap *new_mask = NULL;

  if(!GTK_PLOT_GDK(pc)->drawable) return;
  if(!GTK_PLOT_GDK(pc)->window) return;
  if(!GTK_PLOT_GDK(pc)->gc) return;

  gc = GTK_PLOT_GDK(pc)->gc;

  if(!gc) return;

  new_pixmap = scale_pixmap(GTK_PLOT_GDK(pc)->window, pixmap, scale_x, scale_y);
  
  if(mask)
    new_mask = scale_bitmap(GTK_PLOT_GDK(pc)->window, mask, scale_x, scale_y);

  gtk_plot_pc_clip_mask(pc, xdest, ydest, new_mask);
  gdk_draw_pixmap(GTK_PLOT_GDK(pc)->drawable, gc, new_pixmap,
                  xsrc, ysrc, xdest, ydest, width*scale_x, height*scale_y);
  gtk_plot_pc_clip_mask(pc, xdest, ydest, NULL);

  if(new_mask) gdk_bitmap_unref(new_mask);
  gdk_pixmap_unref(new_pixmap);
}
예제 #4
0
void state_callback(int nitems, newmenu_item *items, int *last_key, int citem) {
	fix x = fl2f((grd_curcanv->cv_bitmap.bm_w - THUMBNAIL_W * f2fl(Scale_x)) / 2);
	fix y = fl2f(items[0].y - 5 * f2fl(Scale_factor));
	grs_point scale_pts[] = {
			{x,                              y},
			{x + i2f(THUMBNAIL_W),           y + i2f(THUMBNAIL_H)},
			{x + THUMBNAIL_W * Scale_factor, y + THUMBNAIL_H * Scale_factor}
	};

	if (citem > 0) {
		if (sc_bmp[citem - 1]) {
			scale_bitmap(sc_bmp[citem - 1], scale_pts);
		}
	}
}
예제 #5
0
파일: state.c 프로젝트: btb/d2x
//-------------------------------------------------------------------
void state_callback(int nitems,newmenu_item * items, int * last_key, int citem)
{
//	if ( sc_last_item != citem )	{
//		sc_last_item = citem;
		if ( citem > 0 )	{
			if ( sc_bmp[citem-1] )	{
				if (MenuHires) {
					grs_canvas *save_canv = grd_curcanv;
					grs_canvas *temp_canv = gr_create_canvas(THUMBNAIL_W*2,(THUMBNAIL_H*24/10));
					grs_point vertbuf[3] = {{0,0}, {0,0}, {i2f(THUMBNAIL_W*2),i2f(THUMBNAIL_H*24/10)} };
					gr_set_current_canvas(temp_canv);
					scale_bitmap(sc_bmp[citem-1], vertbuf, 0 );
					gr_set_current_canvas( save_canv );
					gr_bitmap( (grd_curcanv->cv_bitmap.bm_w-THUMBNAIL_W*2)/2,items[0].y-10, &temp_canv->cv_bitmap);
					gr_free_canvas(temp_canv);
				}
				else	{
					gr_bitmap( (grd_curcanv->cv_bitmap.bm_w-THUMBNAIL_W)/2,items[0].y-5, sc_bmp[citem-1] );
				}
			}
		}
//	}	
}
예제 #6
0
파일: rod.c 프로젝트: paud/d2x-xl
//draws a bitmap with the specified 3d width & height 
//returns 1 if off screen, 0 if drew
bool G3DrawBitMap (vmsVector *pos, fix width, fix height, grsBitmap *bm, int orientation)
{
#ifndef __powerc
	g3sPoint pnt;
	fix t, w, h;

	if (G3TransformAndEncodePoint (&pnt, pos) & CC_BEHIND)
		return 1;

	G3ProjectPoint (&pnt);

	if (pnt.p3Flags & PF_OVERFLOW)
		return 1;

	if (CheckMulDiv (&t, width, xCanvW2, pnt.p3_z))
		w = FixMul (t, viewInfo.scale.x);
	else
		return 1;

	if (CheckMulDiv (&t, height, xCanvH2, pnt.p3_z))
		h = FixMul (t, viewInfo.scale.y);
	else
		return 1;

	blob_vertices[0].x = pnt.p3_sx - w;
	blob_vertices[0].y = blob_vertices[1].y = pnt.p3_sy - h;
	blob_vertices[1].x = blob_vertices[2].x = pnt.p3_sx + w;
	blob_vertices[2].y = pnt.p3_sy + h;

	scale_bitmap (bm, blob_vertices, 0);

	return 0;
#else
	g3sPoint pnt;
	fix w, h;
	double fz;

	if (G3TransformAndEncodePoint (&pnt, pos) & CC_BEHIND)
		return 1;

	G3ProjectPoint (&pnt);

	if (pnt.p3Flags & PF_OVERFLOW)
		return 1;

	if (pnt.p3_z == 0)
		return 1;
		
	fz = f2fl (pnt.p3_z);
	w = FixMul (fl2f (( (f2fl (width)*fxCanvW2) / fz)), viewInfo.scale.x);
	h = FixMul (fl2f (( (f2fl (height)*fxCanvH2) / fz)), viewInfo.scale.y);

	blob_vertices[0].x = pnt.p3_sx - w;
	blob_vertices[0].y = blob_vertices[1].y = pnt.p3_sy - h;
	blob_vertices[1].x = blob_vertices[2].x = pnt.p3_sx + w;
	blob_vertices[2].y = pnt.p3_sy + h;

	scale_bitmap (bm, blob_vertices);

	return 0;
#endif
}
예제 #7
0
파일: rod.cpp 프로젝트: Pickle/dxx-rebirth
//draws a bitmap with the specified 3d width & height 
//returns 1 if off screen, 0 if drew
bool g3_draw_bitmap(vms_vector *pos,fix width,fix height,grs_bitmap *bm)
{
#ifndef __powerc
	g3s_point pnt;
	fix t,w,h;

	if (g3_rotate_point(&pnt,pos) & CC_BEHIND)
		return 1;

	g3_project_point(&pnt);

	if (pnt.p3_flags & PF_OVERFLOW)
		return 1;

	if (checkmuldiv(&t,width,Canv_w2,pnt.p3_z))
		w = fixmul(t,Matrix_scale.x);
	else
		return 1;

	if (checkmuldiv(&t,height,Canv_h2,pnt.p3_z))
		h = fixmul(t,Matrix_scale.y);
	else
		return 1;

	blob_vertices[0].x = pnt.p3_sx - w;
	blob_vertices[0].y = blob_vertices[1].y = pnt.p3_sy - h;
	blob_vertices[1].x = blob_vertices[2].x = pnt.p3_sx + w;
	blob_vertices[2].y = pnt.p3_sy + h;

	scale_bitmap(bm,blob_vertices,0);

	return 0;
#else
	g3s_point pnt;
	fix w,h;
	double fz;

	if (g3_rotate_point(&pnt,pos) & CC_BEHIND)
		return 1;

	g3_project_point(&pnt);

	if (pnt.p3_flags & PF_OVERFLOW)
		return 1;

	if (pnt.p3_z == 0)
		return 1;
		
	fz = f2fl(pnt.p3_z);
	w = fixmul(fl2f(((f2fl(width)*fCanv_w2) / fz)), Matrix_scale.x);
	h = fixmul(fl2f(((f2fl(height)*fCanv_h2) / fz)), Matrix_scale.y);

	blob_vertices[0].x = pnt.p3_sx - w;
	blob_vertices[0].y = blob_vertices[1].y = pnt.p3_sy - h;
	blob_vertices[1].x = blob_vertices[2].x = pnt.p3_sx + w;
	blob_vertices[2].y = pnt.p3_sy + h;

	scale_bitmap(bm, blob_vertices, 0);

	return 0;
#endif
}
예제 #8
0
파일: state.c 프로젝트: osgcc/descent-mac
int state_save_all_sub(char *filename, char *desc, int between_levels)
{
	int i,j;
	FILE * fp;
	grs_canvas * cnv;
	FInfo finfo;
	OSErr err;
	Str255 pfilename;

	if ( Game_mode & GM_MULTI )	{
#ifdef MULTI_SAVE
		if ( !FindArg( "-multisave" ) ) 
#endif  
			return 0;
	}

	fp = fopen( filename, "wb" );
	if ( !fp ) {
		start_time();
		return 0;
	}

//Save id
	fwrite( dgss_id, sizeof(char)*4, 1, fp );

//Save version
	i = STATE_VERSION;
	fwrite( &i, sizeof(int), 1, fp );

//Save description
	fwrite( desc, sizeof(char)*DESC_LENGTH, 1, fp );
	
// Save the current screen shot...
	cnv = gr_create_canvas( THUMBNAIL_W, THUMBNAIL_H );
	if ( cnv )	{
		gr_set_current_canvas( cnv );
		if ( between_levels )	{
			char * pcx_file;
			ubyte pcx_palette[768];
			grs_bitmap bmp;

			gr_clear_canvas( BM_XRGB(0,0,0) );
			pcx_file = get_briefing_screen( Next_level_num );
			if ( pcx_file != NULL )	{
				bmp.bm_data = NULL;
				if (pcx_read_bitmap( pcx_file, &bmp, BM_LINEAR, pcx_palette )==PCX_ERROR_NONE)	{
					grs_point vertbuf[3];
					gr_clear_canvas( TRANSPARENCY_COLOR );
					vertbuf[0].x = vertbuf[0].y = -F1_0*6;		// -6 pixel rows for ascpect
					vertbuf[1].x = vertbuf[1].y = 0;
					vertbuf[2].x = i2f(THUMBNAIL_W); vertbuf[2].y = i2f(THUMBNAIL_H+7);	// + 7 pixel rows for ascpect
					scale_bitmap(&bmp, vertbuf );
					gr_remap_bitmap_good( &cnv->cv_bitmap, pcx_palette, -1, -1 );
					myfree( bmp.bm_data );
				}
			}
		} else {
			render_frame(0);
		}
		fwrite( cnv->cv_bitmap.bm_data, THUMBNAIL_W*THUMBNAIL_H, 1, fp );
		gr_free_canvas( cnv );
	} else {
	 	ubyte color = 0;
	 	for ( i=0; i<THUMBNAIL_W*THUMBNAIL_H; i++ )
	 		fwrite( &color, sizeof(ubyte), 1, fp );		
	}

// Save the Between levels flag...
	fwrite( &between_levels, sizeof(int), 1, fp );

// Save the mission info...
#ifdef MAC_SHAREWARE
	fwrite( mission_save, sizeof(char)*9, 1, fp);
#else
	fwrite( &Mission_list[Current_mission_num], sizeof(char)*9, 1, fp );
#endif

//Save level info
	fwrite( &Current_level_num, sizeof(int), 1, fp );
	fwrite( &Next_level_num, sizeof(int), 1, fp );

//Save GameTime
	fwrite( &GameTime, sizeof(fix), 1, fp );

//Save player info
	fwrite( &Players[Player_num], sizeof(player), 1, fp );

// Save the current weapon info
	fwrite( &Primary_weapon, sizeof(byte), 1, fp );
	fwrite( &Secondary_weapon, sizeof(byte), 1, fp );

// Save the difficulty level
	fwrite( &Difficulty_level, sizeof(int), 1, fp );

// Save the Cheats_enabled
	fwrite( &Cheats_enabled, sizeof(int), 1, fp );
	fwrite( &Game_turbo_mode, sizeof(int), 1, fp );


	if ( !between_levels )	{

	//Finish all morph objects
		for (i=0; i<=Highest_object_index; i++ )	{
			if ( (Objects[i].type != OBJ_NONE) && (Objects[i].render_type==RT_MORPH))	{
				morph_data *md;
				md = find_morph_data(&Objects[i]);
				if (md) {					
					md->obj->control_type = md->morph_save_control_type;
					md->obj->movement_type = md->morph_save_movement_type;
					md->obj->render_type = RT_POLYOBJ;
					md->obj->mtype.phys_info = md->morph_save_phys_info;
					md->obj = NULL;
				} else {						//maybe loaded half-morphed from disk
					Objects[i].flags |= OF_SHOULD_BE_DEAD;
					Objects[i].render_type = RT_POLYOBJ;
					Objects[i].control_type = CT_NONE;
					Objects[i].movement_type = MT_NONE;
				}
			}
		}
	
	//Save object info
		i = Highest_object_index+1;
		fwrite( &i, sizeof(int), 1, fp );
		fwrite( Objects, sizeof(object)*i, 1, fp );
		
	//Save wall info
		i = Num_walls;
		fwrite( &i, sizeof(int), 1, fp );
		fwrite( Walls, sizeof(wall)*i, 1, fp );
	
	//Save door info
		i = Num_open_doors;
		fwrite( &i, sizeof(int), 1, fp );
		fwrite( ActiveDoors, sizeof(active_door)*i, 1, fp );
	
	//Save trigger info
		fwrite( &Num_triggers, sizeof(int), 1, fp );
		fwrite( Triggers, sizeof(trigger)*Num_triggers, 1, fp );
	
	//Save tmap info
		for (i=0; i<=Highest_segment_index; i++ )	{
			for (j=0; j<6; j++ )	{
				fwrite( &Segments[i].sides[j].wall_num, sizeof(short), 1, fp );
				fwrite( &Segments[i].sides[j].tmap_num, sizeof(short), 1, fp );
				fwrite( &Segments[i].sides[j].tmap_num2, sizeof(short), 1, fp );
			}
		}
	
	// Save the fuelcen info
		fwrite( &Fuelcen_control_center_destroyed, sizeof(int), 1, fp );
		fwrite( &Fuelcen_seconds_left, sizeof(int), 1, fp );
		fwrite( &Num_robot_centers, sizeof(int), 1, fp );
		fwrite( RobotCenters, sizeof(matcen_info)*Num_robot_centers, 1, fp );
		fwrite( &ControlCenterTriggers, sizeof(control_center_triggers), 1, fp );
		fwrite( &Num_fuelcenters, sizeof(int), 1, fp );
		fwrite( Station, sizeof(FuelCenter)*Num_fuelcenters, 1, fp );
	
	// Save the control cen info
		fwrite( &Control_center_been_hit, sizeof(int), 1, fp );
		fwrite( &Control_center_player_been_seen, sizeof(int), 1, fp );
		fwrite( &Control_center_next_fire_time, sizeof(int), 1, fp );
		fwrite( &Control_center_present, sizeof(int), 1, fp );
		fwrite( &Dead_controlcen_object_num, sizeof(int), 1, fp );
	
	// Save the AI state
		ai_save_state( fp );
	
	// Save the automap visited info
		fwrite( Automap_visited, sizeof(ubyte)*MAX_SEGMENTS, 1, fp );
	}
	fwrite( &state_game_id, sizeof(uint), 1, fp );
	fwrite( &Laser_rapid_fire, sizeof(int), 1, fp );
	fwrite( &Ugly_robot_cheat, sizeof(int), 1, fp );
	fwrite( &Ugly_robot_texture, sizeof(int), 1, fp );
	fwrite( &Physics_cheat_flag, sizeof(int), 1, fp );
	fwrite( &Lunacy, sizeof(int), 1, fp );

	fclose(fp);
	
// set the type and creator of the saved game file

	strcpy(pfilename, filename);
	c2pstr(pfilename);
	err = HGetFInfo(0, 0, pfilename, &finfo);
	finfo.fdType = 'SVGM';
	finfo.fdCreator = 'DCNT';
	err = HSetFInfo(0, 0, pfilename, &finfo);

	start_time();

	return 1;
}
예제 #9
0
파일: state.c 프로젝트: osgcc/descent-mac
int state_save_old_game(int slotnum, char * sg_name, player * sg_player, 
                        int sg_difficulty_level, int sg_primary_weapon, 
                        int sg_secondary_weapon, int sg_next_level_num  	)
{
	int i;
	int temp_int;
	ubyte temp_byte;
	char desc[DESC_LENGTH+1];
	char filename[128];
	grs_canvas * cnv;
	FILE * fp;

	sprintf( filename, "%s.sg%d", sg_player->callsign, slotnum );
	fp = fopen( filename, "wb" );
	if ( !fp ) return 0;

//Save id
	fwrite( dgss_id, sizeof(char)*4, 1, fp );

//Save version
	temp_int = STATE_VERSION;
	fwrite( &temp_int, sizeof(int), 1, fp );

//Save description
	strncpy( desc, sg_name, DESC_LENGTH );
	fwrite( desc, sizeof(char)*DESC_LENGTH, 1, fp );
	
// Save the current screen shot...
	cnv = gr_create_canvas( THUMBNAIL_W, THUMBNAIL_H );
	if ( cnv )	{
		char * pcx_file;
		ubyte pcx_palette[768];
		grs_bitmap bmp;

		gr_set_current_canvas( cnv );

		gr_clear_canvas( BM_XRGB(0,0,0) );
		pcx_file = get_briefing_screen( sg_next_level_num );
		if ( pcx_file != NULL )	{
			bmp.bm_data = NULL;
			if (pcx_read_bitmap( pcx_file, &bmp, BM_LINEAR, pcx_palette )==PCX_ERROR_NONE)	{
				grs_point vertbuf[3];
				gr_clear_canvas( TRANSPARENCY_COLOR );
				vertbuf[0].x = vertbuf[0].y = -F1_0*6;		// -6 pixel rows for ascpect
				vertbuf[1].x = vertbuf[1].y = 0;
				vertbuf[2].x = i2f(THUMBNAIL_W); vertbuf[2].y = i2f(THUMBNAIL_H+7);	// + 7 pixel rows for ascpect
				scale_bitmap(&bmp, vertbuf );
				gr_remap_bitmap_good( &cnv->cv_bitmap, pcx_palette, -1, -1 );
				myfree( bmp.bm_data );
			}
		}
		fwrite( cnv->cv_bitmap.bm_data, THUMBNAIL_W*THUMBNAIL_H, 1, fp );
		gr_free_canvas( cnv );
	} else {
	 	ubyte color = 0;
	 	for ( i=0; i<THUMBNAIL_W*THUMBNAIL_H; i++ )
	 		fwrite( &color, sizeof(ubyte), 1, fp );		
	}

// Save the Between levels flag...
	temp_int = 1;
	fwrite( &temp_int, sizeof(int), 1, fp );

// Save the mission info...
#ifdef MAC_SHAREWARE
	fwrite( mission_save, sizeof(char)*9, 1, fp);
#else
	fwrite( &Mission_list[0], sizeof(char)*9, 1, fp );
#endif

//Save level info
	temp_int = sg_player->level;
	fwrite( &temp_int, sizeof(int), 1, fp );
	temp_int = sg_next_level_num;
	fwrite( &temp_int, sizeof(int), 1, fp );

//Save GameTime
	temp_int = 0;
	fwrite( &temp_int, sizeof(fix), 1, fp );

//Save player info
	fwrite( sg_player, sizeof(player), 1, fp );

// Save the current weapon info
	temp_byte = sg_primary_weapon;
	fwrite( &temp_byte, sizeof(byte), 1, fp );
	temp_byte = sg_secondary_weapon;
	fwrite( &temp_byte, sizeof(byte), 1, fp );

// Save the difficulty level
	temp_int = sg_difficulty_level;
	fwrite( &temp_int, sizeof(int), 1, fp );

// Save the Cheats_enabled
	temp_int = 0;
	fwrite( &temp_int, sizeof(int), 1, fp );
	temp_int = 0;		// turbo mode
	fwrite( &temp_int, sizeof(int), 1, fp );

	fwrite( &state_game_id, sizeof(uint), 1, fp );
	fwrite( &Laser_rapid_fire, sizeof(int), 1, fp );
	fwrite( &Ugly_robot_cheat, sizeof(int), 1, fp );
	fwrite( &Ugly_robot_texture, sizeof(int), 1, fp );
	fwrite( &Physics_cheat_flag, sizeof(int), 1, fp );
	fwrite( &Lunacy, sizeof(int), 1, fp );

	fclose(fp);

	return 1;
}
예제 #10
0
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);
}