1 module unde.main; 2 3 import unde.draw; 4 import unde.global_state; 5 import unde.tick; 6 import unde.slash; 7 8 import derelict.sdl2.sdl; 9 10 import std.stdio; 11 import std.file; 12 import core.stdc.stdlib; 13 14 import core.sys.posix.signal; 15 16 extern(C) void mybye(int value){ 17 exit(1); 18 } 19 20 int main(string[] args) 21 { 22 bool force_recover; 23 if (args.length > 1) 24 force_recover = (args[1] == "--force_recover"); 25 GlobalState gs = new GlobalState(force_recover); 26 gs.args = args; 27 gs.start_cwd = getcwd(); 28 version(Posix) 29 { 30 sigset(SIGINT, &mybye); 31 } 32 gs.main_path = gs.path = SL; 33 34 /* How many frames was skipped */ 35 uint skipframe; 36 /* How long rendering was last frame */ 37 uint last_draw_time; 38 39 /* Sum of time which was taken by rendering */ 40 uint drawtime; 41 /* Minumum time between 2 frames */ 42 uint min_frame_time = 2; 43 /* Maximum skip frames running */ 44 uint max_skip_frames = 10; 45 46 /* Start time used in below scope(exit) to calculate avarage 47 rendering time*/ 48 uint starttime=SDL_GetTicks(); 49 scope(exit) 50 { 51 uint endtime = SDL_GetTicks(); 52 writefln("FPS= %f, average draw time: %f ms\n", 53 (cast(float)gs.frame)*1000/(endtime-starttime), 54 (cast(float)drawtime)/gs.frame); 55 /* EN: Necessary because otherwise it will destroy 56 gs.dbenv, gs.db_map before and it lead to Seg.Fault 57 RU: Необходим, т.к. иначе до gs будут уничтожены 58 gs.dbenv, gs.db_map, что ведёт к ошибке сегментирования */ 59 destroy(gs); 60 } 61 62 /* The main Idea of rendering process: 63 Splitting the actions which must be done on frame on 2: 64 1. Process events and make tick 65 2. Draw Frame 66 "Draw frame" maybe skipped to catch up real time, 67 But "Make tick" can't be skipped 68 */ 69 while(!gs.finish) 70 { 71 uint time_before_frame=SDL_GetTicks(); 72 73 /* Process incoming events. */ 74 75 process_events(gs); 76 77 make_tick(gs); 78 stdout.flush(); 79 80 uint now=SDL_GetTicks(); 81 /* Draw the screen. */ 82 /* Don't skip frame when: 83 1. Too much frame skipped 84 2. The virtual time (gs.time) too big (more than real time) 85 3. Estimation time of the next frame less than minumum frame time */ 86 if ( skipframe>=max_skip_frames || (gs.time+250.0)>now || 87 (now+last_draw_time)<(time_before_frame+min_frame_time) ) 88 { 89 gs.txn = null;//dbenv.txn_begin(null, DB_TXN_SNAPSHOT); 90 uint time_before_draw=SDL_GetTicks(); 91 92 draw_screen(gs, gs.txn); 93 94 last_draw_time=SDL_GetTicks()-time_before_draw; 95 drawtime+=last_draw_time; 96 97 //gs.txn.commit(); 98 99 gs.frame++; 100 skipframe=0; 101 } 102 else skipframe++; 103 104 now=SDL_GetTicks(); 105 /* Virtual time more real time? */ 106 if (gs.time>now) 107 SDL_Delay(gs.time-now); 108 else /* If time of frame too small */ 109 if ( (now - time_before_frame)<min_frame_time ) 110 SDL_Delay( min_frame_time - (now - time_before_frame) ); 111 112 /* Add 10 ms to time, because we want render with speed 100 FPS 113 1 frame / 100 FPS = 1/100s = 10ms */ 114 gs.time += 10; 115 116 } 117 return 0; 118 }