//draws the given model in the current canvas. The distance is set to //more-or-less fill the canvas. Note that this routine actually renders //into an off-screen canvas that it creates, then copies to the current //canvas. void draw_model_picture(int mn,vms_angvec *orient_angles) { vms_vector temp_pos=ZERO_VECTOR; vms_matrix temp_orient = IDENTITY_MATRIX; grs_canvas *save_canv = grd_curcanv,*temp_canv; Assert(mn>=0 && mn<N_polygon_models); temp_canv = gr_create_canvas(save_canv->cv_bitmap.bm_w,save_canv->cv_bitmap.bm_h); gr_set_current_canvas(temp_canv); gr_clear_canvas( BM_XRGB(0,0,0) ); g3_start_frame(); g3_set_view_matrix(&temp_pos,&temp_orient,0x9000); if (Polygon_models[mn].rad != 0) temp_pos.z = fixmuldiv(DEFAULT_VIEW_DIST,Polygon_models[mn].rad,BASE_MODEL_SIZE); else temp_pos.z = DEFAULT_VIEW_DIST; vm_angles_2_matrix(&temp_orient, orient_angles); PA_DFX(save_light = Lighting_on); PA_DFX(Lighting_on = 0); draw_polygon_model(&temp_pos,&temp_orient,NULL,mn,0,f1_0,NULL,NULL); PA_DFX (Lighting_on = save_light); gr_set_current_canvas(save_canv); gr_bitmap(0,0,&temp_canv->cv_bitmap); gr_free_canvas(temp_canv); }
//print to canvas & double height grs_canvas *print_to_canvas(char *s,grs_font *font, int fc, int bc) { int y; ubyte *data; int rs; grs_canvas *temp_canv,*save_canv; save_canv = grd_curcanv; temp_canv = gr_create_canvas(font->ft_w*strlen(s),font->ft_h*2); gr_set_current_canvas(temp_canv); gr_set_curfont(font); gr_clear_canvas(255); //trans color gr_set_fontcolor(fc,bc); gr_printf(0,0,s); //now double it, since we're drawing to 400-line modex screen data = temp_canv->cv_bitmap.bm_data; rs = temp_canv->cv_bitmap.bm_rowsize; for (y=temp_canv->cv_bitmap.bm_h/2;y--;) { memcpy(data+(rs*y*2),data+(rs*y),temp_canv->cv_bitmap.bm_w); memcpy(data+(rs*(y*2+1)),data+(rs*y),temp_canv->cv_bitmap.bm_w); } gr_set_current_canvas(save_canv); return temp_canv; }
void init_editor() { minit(); ui_init(); init_med_functions(); // Must be called before medlisp_init ui_pad_read( 0, "segmove.pad" ); ui_pad_read( 1, "segsize.pad" ); ui_pad_read( 2, "curve.pad" ); ui_pad_read( 3, "texture.pad" ); ui_pad_read( 4, "object.pad" ); ui_pad_read( 5, "objmov.pad" ); ui_pad_read( 6, "group.pad" ); ui_pad_read( 7, "lighting.pad" ); ui_pad_read( 8, "test.pad" ); medkey_init(); editor_font = gr_init_font( "pc8x16.fnt" ); menubar_init( "MED.MNU" ); canv_offscreen = gr_create_canvas(LVIEW_W,LVIEW_H); Draw_all_segments = 1; // Say draw all segments, not just connected ones init_autosave(); // atexit(close_editor); Clear_window = 1; // do full window clear. }
void title_save_game() { grs_canvas * save_canv; grs_canvas * save_canv_data; grs_font * save_font; ubyte palette[768]; if ( Next_level_num == 0 ) return; save_canv = grd_curcanv; save_font = grd_curcanv->cv_font; save_canv_data = gr_create_canvas( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h ); gr_set_current_canvas(save_canv_data); gr_ubitmap(0,0,&save_canv->cv_bitmap); gr_set_current_canvas(save_canv); gr_clear_canvas(gr_find_closest_color_current( 0, 0, 0)); gr_palette_read( palette ); gr_palette_load( gr_palette ); #ifndef SHAREWARE state_save_all(1); #endif gr_palette_clear(); gr_set_current_canvas(save_canv); gr_ubitmap(0,0,&save_canv_data->cv_bitmap); gr_palette_load( palette ); gr_set_curfont(save_font); }
//------------------------------------------------------------------- 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] ); } } } // } }
void modex_print_message(int x, int y, char *str) { #ifndef AUTOMAP_DIRECT_RENDER #ifndef AUTOMAP_NO_PAGING int i; for (i=0; i<2; i++ ) { gr_set_current_canvas(&Pages[i]); #else { gr_set_current_canvas(OffscreenPage); #endif #endif modex_printf(x, y, str, GFONT_MEDIUM_1); #ifndef AUTOMAP_DIRECT_RENDER } gr_set_current_canvas(&DrawingPages[current_page]); #endif } extern void GameLoop(int, int ); extern int set_segment_depths(int start_seg, ubyte *segbuf); u_int32_t automap_mode = SM(640,480); int automap_width = 640; int automap_height = 480; int automap_use_game_res=0; int nice_automap=0; void do_automap( int key_code ) { int done=0; vms_matrix tempm; vms_angvec tangles; int leave_mode=0; int first_time=1; // int pcx_error; int c; // char filename[] = "MAP.PCX"; fix entry_time; int pause_game=1; // Set to 1 if everything is paused during automap...No pause during net. fix t1, t2; control_info saved_control_info; grs_bitmap Automap_background; int Max_segments_away = 0; int SegmentLimit = 1; //added on 10/28/98 by adb to fix compile versions #if !defined (NDEBUG) || (!defined(AUTOMAP_NO_PAGING) && !defined(AUTOMAP_DIRECT_RENDER)) int i; #endif key_code = key_code; // disable warning... if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence)) pause_game = 0; if (pause_game) stop_time(); create_name_canv(); Max_edges = min(MAX_EDGES_FROM_VERTS(Num_vertices),MAX_EDGES); //make maybe smaller than max //Edges = malloc( sizeof(Edge_info)*Max_edges); //if ( Edges == NULL ) { // mprintf((0, "Couldn't get %dK for automap!", sizeof(Edge_info)*Max_edges/1024)); // return; //} //DrawingListBright = malloc( sizeof(short)*Max_edges); //if ( DrawingListBright == NULL ) { // mprintf((0, "Couldn't get %dK for automap!", sizeof(short)*Max_edges/1024)); // return; //} mprintf( (0, "Num_vertices=%d, Max_edges=%d, (MAX:%d)\n", Num_vertices, Max_edges, MAX_EDGES )); mprintf( (0, "Allocated %d K for automap edge list\n", (sizeof(Edge_info)+sizeof(short))*Max_edges/1024 )); //edit 4/23/99 Matt Mueller - don't switch res unless we need to if (grd_curscreen->sc_mode != AUTOMAP_MODE) gr_set_mode( AUTOMAP_MODE ); else gr_set_current_canvas(NULL); //end edit -MM automap_width=grd_curscreen->sc_canvas.cv_bitmap.bm_w; automap_height=grd_curscreen->sc_canvas.cv_bitmap.bm_h; gr_palette_clear(); #ifndef AUTOMAP_DIRECT_RENDER gr_init_sub_canvas(&Pages[0],grd_curcanv,0,0,automap_width,automap_height); #ifndef AUTOMAP_NO_PAGING // NOTICE: should be 0,401! FIXME! gr_init_sub_canvas(&Pages[1],grd_curcanv,0,0,automap_width,automap_height); gr_init_sub_canvas(&DrawingPages[0],&Pages[0],0,0,automap_width,automap_height); gr_init_sub_canvas(&DrawingPages[1],&Pages[1],0,0,automap_width,automap_height); #else OffscreenPage = gr_create_canvas( automap_width,automap_height ); if (!OffscreenPage) { nm_messagebox("No memory for automap", 1, "Ok"); return; } gr_init_sub_canvas(&DrawingPages[0],OffscreenPage,0,0,automap_width,automap_height); #endif #endif gr_init_bitmap_data (&Automap_background); // pcx_error = pcx_read_bitmap(filename,&Automap_background,BM_LINEAR,NULL); // if ( pcx_error != PCX_ERROR_NONE ) { // printf("File %s - PCX error: %s",filename,pcx_errormsg(pcx_error)); // Error("File %s - PCX error: %s",filename,pcx_errormsg(pcx_error)); // return; // } #ifndef AUTOMAP_DIRECT_RENDER #ifndef AUTOMAP_NO_PAGING for (i=0; i<2; i++ ) { gr_set_current_canvas(&Pages[i]); #else { gr_set_current_canvas(OffscreenPage); #endif // gr_bitmap( 0, 0, &Automap_background ); // modex_printf( 40, 22,TXT_AUTOMAP,GFONT_BIG_1); // modex_printf( 70,353,TXT_TURN_SHIP,GFONT_SMALL); // modex_printf( 70,369,TXT_SLIDE_UPDOWN,GFONT_SMALL); // modex_printf( 70,385,TXT_VIEWING_DISTANCE,GFONT_SMALL); } #ifdef AUTOMAP_NO_PAGING //killed 05/17/99 Matt Mueller - this seems to merely copy undefined bytes around.. not needed //--killed-- gr_bm_ubitblt(automap_width,automap_height, 0, 0, 0, 0, &OffscreenPage->cv_bitmap,&Pages[0].cv_bitmap); //end kill -MM #endif gr_free_bitmap_data (&Automap_background); gr_set_current_canvas(&DrawingPages[current_page]); #endif automap_build_edge_list(); if ( ViewDist==0 ) ViewDist = ZOOM_DEFAULT; ViewMatrix = Objects[Players[Player_num].objnum].orient; tangles.p = PITCH_DEFAULT; tangles.h = 0; tangles.b = 0; done = 0; view_target = Objects[Players[Player_num].objnum].pos; t1 = entry_time = timer_get_fixed_seconds(); t2 = t1; //Fill in Automap_visited from Objects[Players[Player_num].objnum].segnum Max_segments_away = set_segment_depths(Objects[Players[Player_num].objnum].segnum, Automap_visited); SegmentLimit = Max_segments_away; adjust_segment_limit(SegmentLimit); while(!done) { if ( leave_mode==0 && Controls.automap_state && (timer_get_fixed_seconds()-entry_time)>LEAVE_TIME) leave_mode = 1; if ( !Controls.automap_state && (leave_mode==1) ) done=1; if (!pause_game) { ushort old_wiggle; saved_control_info = Controls; // Save controls so we can zero them memset(&Controls,0,sizeof(control_info)); // Clear everything... old_wiggle = ConsoleObject->mtype.phys_info.flags & PF_WIGGLE; // Save old wiggle ConsoleObject->mtype.phys_info.flags &= ~PF_WIGGLE; // Turn off wiggle #ifdef NETWORK if (multi_menu_poll()) done = 1; #endif // GameLoop( 0, 0 ); // Do game loop with no rendering and no reading controls. ConsoleObject->mtype.phys_info.flags |= old_wiggle; // Restore wiggle Controls = saved_control_info; } controls_read_all(); if ( Controls.automap_down_count ) { if (leave_mode==0) done = 1; c = 0; } while( (c=key_inkey()) ) { switch( c ) { #ifndef NDEBUG case KEY_BACKSP: Int3(); break; #endif case KEY_PRINT_SCREEN: save_screen_shot(1); break; case KEY_ESC: if (leave_mode==0) done = 1; break; case KEY_ALTED+KEY_F: // Alt+F shows full map, if cheats enabled if (Cheats_enabled) { uint t; t = Players[Player_num].flags; Players[Player_num].flags |= PLAYER_FLAGS_MAP_ALL_CHEAT; automap_build_edge_list(); Players[Player_num].flags=t; } break; #ifndef NDEBUG case KEY_DEBUGGED+KEY_F: { for (i=0; i<=Highest_segment_index; i++ ) Automap_visited[i] = 1; automap_build_edge_list(); Max_segments_away = set_segment_depths(Objects[Players[Player_num].objnum].segnum, Automap_visited); SegmentLimit = Max_segments_away; adjust_segment_limit(SegmentLimit); } break; #endif case KEY_MINUS: if (SegmentLimit > 1) { SegmentLimit--; adjust_segment_limit(SegmentLimit); } break; case KEY_EQUAL: if (SegmentLimit < Max_segments_away) { SegmentLimit++; adjust_segment_limit(SegmentLimit); } break; } } if ( Controls.fire_primary_down_count ) { // Reset orientation ViewDist = ZOOM_DEFAULT; tangles.p = PITCH_DEFAULT; tangles.h = 0; tangles.b = 0; view_target = Objects[Players[Player_num].objnum].pos; } ViewDist -= Controls.forward_thrust_time*ZOOM_SPEED_FACTOR; tangles.p += fixdiv( Controls.pitch_time, ROT_SPEED_DIVISOR ); tangles.h += fixdiv( Controls.heading_time, ROT_SPEED_DIVISOR ); tangles.b += fixdiv( Controls.bank_time, ROT_SPEED_DIVISOR*2 ); if ( Controls.vertical_thrust_time || Controls.sideways_thrust_time ) { vms_angvec tangles1; vms_vector old_vt; old_vt = view_target; tangles1 = tangles; vm_angles_2_matrix(&tempm,&tangles1); vm_matrix_x_matrix(&ViewMatrix,&Objects[Players[Player_num].objnum].orient,&tempm); vm_vec_scale_add2( &view_target, &ViewMatrix.uvec, Controls.vertical_thrust_time*SLIDE_SPEED ); vm_vec_scale_add2( &view_target, &ViewMatrix.rvec, Controls.sideways_thrust_time*SLIDE_SPEED ); if ( vm_vec_dist_quick( &view_target, &Objects[Players[Player_num].objnum].pos) > i2f(1000) ) { view_target = old_vt; } } vm_angles_2_matrix(&tempm,&tangles); vm_matrix_x_matrix(&ViewMatrix,&Objects[Players[Player_num].objnum].orient,&tempm); if ( ViewDist < ZOOM_MIN_VALUE ) ViewDist = ZOOM_MIN_VALUE; if ( ViewDist > ZOOM_MAX_VALUE ) ViewDist = ZOOM_MAX_VALUE; draw_automap(); if ( first_time ) { first_time = 0; gr_palette_load( gr_palette ); } t2 = timer_get_fixed_seconds(); while (t2-t1<F1_0/100){//ogl is fast enough that the automap can read the input too fast and you start to turn really slow. So delay a bit (and free up some cpu :) if (nice_automap) d_delay(1); t2 = timer_get_fixed_seconds(); } if (pause_game) FrameTime=t2-t1; t1 = t2; } //free(Edges); //free(DrawingListBright); gr_free_canvas(name_canv); name_canv=NULL; #ifdef AUTOMAP_NO_PAGING gr_free_canvas(OffscreenPage); OffscreenPage = NULL; #endif mprintf( (0, "Automap memory freed\n" )); game_flush_inputs(); if (pause_game) start_time(); } void adjust_segment_limit(int SegmentLimit) { int i,e1; Edge_info * e; mprintf(( 0, "Seglimit: %d\n", SegmentLimit )); for (i=0; i<=Highest_edge_index; i++ ) { e = &Edges[i]; e->flags |= EF_TOO_FAR; for (e1=0; e1<e->num_faces; e1++ ) { if ( Automap_visited[e->segnum[e1]] <= SegmentLimit ) { e->flags &= (~EF_TOO_FAR); break; } } } }
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; }
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; }
int state_save_all_sub(char *filename, char *desc, int between_levels) { int i,j; PHYSFS_file *fp; grs_canvas * cnv; ubyte *pal; Assert(between_levels == 0); //between levels save ripped out /* if ( Game_mode & GM_MULTI ) { { start_time(); return 0; } }*/ #if defined(MACINTOSH) && !defined(NDEBUG) if ( strncmp(filename, PLAYER_DIR, 9) ) Int3(); #endif fp = PHYSFSX_openWriteBuffered(filename); if ( !fp ) { if ( !(Game_mode & GM_MULTI) ) nm_messagebox(NULL, 1, TXT_OK, "Error writing savegame.\nPossibly out of disk\nspace."); start_time(); return 0; } //Save id PHYSFS_write(fp, dgss_id, sizeof(char) * 4, 1); //Save version i = STATE_VERSION; PHYSFS_write(fp, &i, sizeof(int), 1); //Save description PHYSFS_write(fp, desc, sizeof(char) * DESC_LENGTH, 1); // Save the current screen shot... cnv = gr_create_canvas( THUMBNAIL_W, THUMBNAIL_H ); if ( cnv ) { #ifdef OGL ubyte *buf; int k; GLint gl_draw_buffer; #endif grs_canvas * cnv_save; cnv_save = grd_curcanv; gr_set_current_canvas( cnv ); render_frame(0, 0); #if defined(OGL) buf = d_malloc(THUMBNAIL_W * THUMBNAIL_H * 3); glGetIntegerv(GL_DRAW_BUFFER, &gl_draw_buffer); glReadBuffer(gl_draw_buffer); glReadPixels(0, SHEIGHT - THUMBNAIL_H, THUMBNAIL_W, THUMBNAIL_H, GL_RGB, GL_UNSIGNED_BYTE, buf); k = THUMBNAIL_H; for (i = 0; i < THUMBNAIL_W * THUMBNAIL_H; i++) { if (!(j = i % THUMBNAIL_W)) k--; cnv->cv_bitmap.bm_data[THUMBNAIL_W * k + j] = gr_find_closest_color(buf[3*i]/4, buf[3*i+1]/4, buf[3*i+2]/4); } d_free(buf); #endif pal = gr_palette; PHYSFS_write(fp, cnv->cv_bitmap.bm_data, THUMBNAIL_W * THUMBNAIL_H, 1); gr_set_current_canvas(cnv_save); gr_free_canvas( cnv ); PHYSFS_write(fp, pal, 3, 256); } else { ubyte color = 0; for ( i=0; i<THUMBNAIL_W*THUMBNAIL_H; i++ ) PHYSFS_write(fp, &color, sizeof(ubyte), 1); } // Save the Between levels flag... PHYSFS_write(fp, &between_levels, sizeof(int), 1); // Save the mission info... mprintf ((0, "HEY! Mission name is %s\n", Current_mission_filename)); PHYSFS_write(fp, Current_mission_filename, 9 * sizeof(char), 1); //Save level info PHYSFS_write(fp, &Current_level_num, sizeof(int), 1); PHYSFS_write(fp, &Next_level_num, sizeof(int), 1); //Save GameTime PHYSFS_write(fp, &GameTime, sizeof(fix), 1); // If coop save, save all #ifdef NETWORK if (Game_mode & GM_MULTI_COOP) { PHYSFS_write(fp, &state_game_id,sizeof(int), 1); PHYSFS_write(fp, &Netgame,sizeof(netgame_info), 1); PHYSFS_write(fp, &NetPlayers,sizeof(AllNetPlayers_info), 1); PHYSFS_write(fp, &N_players,sizeof(int), 1); PHYSFS_write(fp, &Player_num,sizeof(int), 1); for (i=0;i<N_players;i++) PHYSFS_write(fp, &Players[i], sizeof(player), 1); #ifdef RISKY_PROPOSITION PHYSFS_write(fp, &robot_controlled[0], 4 * MAX_ROBOTS_CONTROLLED, 1); PHYSFS_write(fp, &robot_agitation[0], 4 * MAX_ROBOTS_CONTROLLED, 1); PHYSFS_write(fp, &robot_controlled_time[0], 4 * MAX_ROBOTS_CONTROLLED, 1); PHYSFS_write(fp, &robot_last_send_time[0], 4 * MAX_ROBOTS_CONTROLLED, 1); PHYSFS_write(fp, &robot_last_message_time[0], 4 * MAX_ROBOTS_CONTROLLED, 1); PHYSFS_write(fp, &robot_send_pending[0], 4 * MAX_ROBOTS_CONTROLLED, 1); PHYSFS_write(fp, &robot_fired[0], 4 * MAX_ROBOTS_CONTROLLED, 1); for (i=0;i<MAX_ROBOTS_CONTROLLED;i++) PHYSFS_write(fp, robot_fire_buf[i][0], 18 + 3, 1); #endif } #endif //Save player info PHYSFS_write(fp, &Players[Player_num], sizeof(player), 1); // Save the current weapon info PHYSFS_write(fp, &Primary_weapon, sizeof(sbyte), 1); PHYSFS_write(fp, &Secondary_weapon, sizeof(sbyte), 1); // Save the difficulty level PHYSFS_write(fp, &Difficulty_level, sizeof(int), 1); // Save cheats enabled PHYSFS_write(fp, &Cheats_enabled.intval, sizeof(int), 1); 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; PHYSFS_write(fp, &i, sizeof(int), 1); PHYSFS_write(fp, Objects, sizeof(object), i); //Save wall info i = Num_walls; PHYSFS_write(fp, &i, sizeof(int), 1); PHYSFS_write(fp, Walls, sizeof(wall), i); //Save exploding wall info i = MAX_EXPLODING_WALLS; PHYSFS_write(fp, &i, sizeof(int), 1); PHYSFS_write(fp, expl_wall_list, sizeof(*expl_wall_list), i); //Save door info i = Num_open_doors; PHYSFS_write(fp, &i, sizeof(int), 1); PHYSFS_write(fp, ActiveDoors, sizeof(active_door), i); //Save cloaking wall info i = Num_cloaking_walls; PHYSFS_write(fp, &i, sizeof(int), 1); PHYSFS_write(fp, CloakingWalls, sizeof(cloaking_wall), i); //Save trigger info PHYSFS_write(fp, &Num_triggers, sizeof(int), 1); PHYSFS_write(fp, Triggers, sizeof(trigger), Num_triggers); //Save tmap info for (i = 0; i <= Highest_segment_index; i++) { for (j = 0; j < 6; j++) { PHYSFS_write(fp, &Segments[i].sides[j].wall_num, sizeof(short), 1); PHYSFS_write(fp, &Segments[i].sides[j].tmap_num, sizeof(short), 1); PHYSFS_write(fp, &Segments[i].sides[j].tmap_num2, sizeof(short), 1); } } // Save the fuelcen info PHYSFS_write(fp, &Control_center_destroyed, sizeof(int), 1); PHYSFS_write(fp, &Countdown_timer, sizeof(int), 1); PHYSFS_write(fp, &Num_robot_centers, sizeof(int), 1); PHYSFS_write(fp, RobotCenters, sizeof(matcen_info), Num_robot_centers); PHYSFS_write(fp, &ControlCenterTriggers, sizeof(control_center_triggers), 1); PHYSFS_write(fp, &Num_fuelcenters, sizeof(int), 1); PHYSFS_write(fp, Station, sizeof(FuelCenter), Num_fuelcenters); // Save the control cen info PHYSFS_write(fp, &Control_center_been_hit, sizeof(int), 1); PHYSFS_write(fp, &Control_center_player_been_seen, sizeof(int), 1); PHYSFS_write(fp, &Control_center_next_fire_time, sizeof(int), 1); PHYSFS_write(fp, &Control_center_present, sizeof(int), 1); PHYSFS_write(fp, &Dead_controlcen_object_num, sizeof(int), 1); // Save the AI state ai_save_state( fp ); // Save the automap visited info PHYSFS_write(fp, Automap_visited, sizeof(ubyte), MAX_SEGMENTS); } PHYSFS_write(fp, &state_game_id, sizeof(uint), 1); PHYSFS_write(fp, &Laser_rapid_fire, sizeof(int), 1); PHYSFS_write(fp, &Lunacy, sizeof(int), 1); // Yes, writing this twice. Removed the Ugly robot system, but didn't want to change savegame format. PHYSFS_write(fp, &Lunacy, sizeof(int), 1); // Save automap marker info PHYSFS_write(fp, MarkerObject, sizeof(MarkerObject) ,1); PHYSFS_write(fp, MarkerOwner, sizeof(MarkerOwner), 1); PHYSFS_write(fp, MarkerMessage, sizeof(MarkerMessage), 1); PHYSFS_write(fp, &Afterburner_charge, sizeof(fix), 1); //save last was super information PHYSFS_write(fp, &Primary_last_was_super, sizeof(Primary_last_was_super), 1); PHYSFS_write(fp, &Secondary_last_was_super, sizeof(Secondary_last_was_super), 1); // Save flash effect stuff PHYSFS_write(fp, &Flash_effect, sizeof(int), 1); PHYSFS_write(fp, &Time_flash_last_played, sizeof(int), 1); PHYSFS_write(fp, &PaletteRedAdd, sizeof(int), 1); PHYSFS_write(fp, &PaletteGreenAdd, sizeof(int), 1); PHYSFS_write(fp, &PaletteBlueAdd, sizeof(int), 1); PHYSFS_write(fp, Light_subtracted, sizeof(Light_subtracted[0]), MAX_SEGMENTS); PHYSFS_write(fp, &First_secret_visit, sizeof(First_secret_visit), 1); if (PHYSFS_write(fp, &Omega_charge, sizeof(Omega_charge), 1) < 1) { if ( !(Game_mode & GM_MULTI) ) { nm_messagebox(NULL, 1, TXT_OK, "Error writing savegame.\nPossibly out of disk\nspace."); PHYSFS_close(fp); PHYSFS_delete(filename); } } else { PHYSFS_close(fp); #ifdef MACINTOSH // set the type and creator of the saved game file { FInfo finfo; OSErr err; Str255 pfilename; strcpy(pfilename, filename); c2pstr(pfilename); err = HGetFInfo(0, 0, pfilename, &finfo); finfo.fdType = 'SVGM'; finfo.fdCreator = 'DCT2'; err = HSetFInfo(0, 0, pfilename, &finfo); } #endif } start_time(); return 1; }
//make a series of photographs do_photos() { FILE *vfile,*upvfile; int photo_num=0; char savename[13]; grs_canvas *photo_canvas; vms_vector viewer_pos; vms_matrix viewer_orient; vfile=fopen("vectors.lst","rt"); upvfile=fopen("upvecs.c","wt"); Assert(vfile!=NULL && upvfile!=NULL); fprintf(upvfile,"\n\n#include \"vecmat.h\"\n\nvms_vector up_vecs[] = {\n"); photo_canvas = gr_create_canvas(64,64); gr_set_current_canvas(photo_canvas); while (!feof(vfile)) { vms_vector v; vms_matrix m; float x,y,z; int nf; nf = fscanf(vfile,"%f %f %f",&x,&y,&z); if (nf!=3) break; vm_vec_make(&v,fl2f(x),fl2f(y),fl2f(z)); vm_vector_2_matrix(&m,&v,NULL,NULL); fprintf(upvfile,"\t\t\t{%#x,%#x,%#x},\n",m.uvec.x,m.uvec.y,m.uvec.z); vm_vec_scale(&v,PHOTO_DIST); vm_vec_add(&viewer_pos,&cube_position,&v); viewer_orient = m; vm_vec_negate(&viewer_orient.fvec); vm_vec_negate(&viewer_orient.rvec); gr_clear_canvas(129); g3_start_frame(); g3_set_view_matrix(&viewer_pos,&viewer_orient,0x9000); draw_cube(); g3_end_frame(); gr_set_current_canvas(Canv_game); gr_ubitmap(0,0,&photo_canvas->cv_bitmap); gr_set_current_canvas(photo_canvas); sprintf(savename,"cube_%02d.bbm",photo_num); iff_write_bitmap(savename,&photo_canvas->cv_bitmap,gr_palette); photo_num++; } gr_free_canvas(photo_canvas); fprintf(upvfile,"\t\t};\n"); fclose(vfile); fclose(upvfile); }