1 // main.cpp: initialisation & main loop
2 
3 #include "cube.h"
4 
cleanup(char * msg)5 void cleanup(char *msg)         // single program exit point;
6 {
7 	stop();
8     disconnect(true);
9     writecfg();
10     cleangl();
11     cleansound();
12     cleanupserver();
13     SDL_ShowCursor(1);
14     if(msg)
15     {
16         #ifdef WIN32
17         MessageBox(NULL, msg, "cube fatal error", MB_OK|MB_SYSTEMMODAL);
18         #else
19         printf(msg);
20         #endif
21     };
22     SDL_Quit();
23     exit(1);
24 };
25 
quit()26 void quit()                     // normal exit
27 {
28     writeservercfg();
29     cleanup(NULL);
30 };
31 
fatal(char * s,char * o)32 void fatal(char *s, char *o)    // failure exit
33 {
34     sprintf_sd(msg)("%s%s (%s)\n", s, o, SDL_GetError());
35     cleanup(msg);
36 };
37 
alloc(int s)38 void *alloc(int s)              // for some big chunks... most other allocs use the memory pool
39 {
40     void *b = calloc(1,s);
41     if(!b) fatal("out of memory!");
42     return b;
43 };
44 
45 int scr_w = 640;
46 int scr_h = 480;
47 
screenshot()48 void screenshot()
49 {
50     SDL_Surface *image;
51     SDL_Surface *temp;
52     int idx;
53     if(image = SDL_CreateRGBSurface(SDL_SWSURFACE, scr_w, scr_h, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0))
54     {
55         if(temp  = SDL_CreateRGBSurface(SDL_SWSURFACE, scr_w, scr_h, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0))
56         {
57             glReadPixels(0, 0, scr_w, scr_h, GL_RGB, GL_UNSIGNED_BYTE, image->pixels);
58             for (idx = 0; idx<scr_h; idx++)
59             {
60                 char *dest = (char *)temp->pixels+3*scr_w*idx;
61                 memcpy(dest, (char *)image->pixels+3*scr_w*(scr_h-1-idx), 3*scr_w);
62                 endianswap(dest, 3, scr_w);
63             };
64             sprintf_sd(buf)("screenshots/screenshot_%d.bmp", lastmillis);
65             SDL_SaveBMP(temp, path(buf));
66             SDL_FreeSurface(temp);
67         };
68         SDL_FreeSurface(image);
69     };
70 };
71 
72 COMMAND(screenshot, ARG_NONE);
73 COMMAND(quit, ARG_NONE);
74 
keyrepeat(bool on)75 void keyrepeat(bool on)
76 {
77     SDL_EnableKeyRepeat(on ? SDL_DEFAULT_REPEAT_DELAY : 0,
78                              SDL_DEFAULT_REPEAT_INTERVAL);
79 };
80 
81 VARF(gamespeed, 10, 100, 1000, if(multiplayer()) gamespeed = 100);
82 VARP(minmillis, 0, 5, 1000);
83 
84 int islittleendian = 1;
85 int framesinmap = 0;
86 
main(int argc,char ** argv)87 int main(int argc, char **argv)
88 {
89     bool dedicated = false;
90     int fs = SDL_FULLSCREEN, par = 0, uprate = 0, maxcl = 4;
91     char *sdesc = "", *ip = "", *master = NULL, *passwd = "";
92     islittleendian = *((char *)&islittleendian);
93 
94     #define log(s) conoutf("init: %s", s)
95     log("sdl");
96 
97     for(int i = 1; i<argc; i++)
98     {
99         char *a = &argv[i][2];
100         if(argv[i][0]=='-') switch(argv[i][1])
101         {
102             case 'd': dedicated = true; break;
103             case 't': fs     = 0; break;
104             case 'w': scr_w  = atoi(a); break;
105             case 'h': scr_h  = atoi(a); break;
106             case 'u': uprate = atoi(a); break;
107             case 'n': sdesc  = a; break;
108             case 'i': ip     = a; break;
109             case 'm': master = a; break;
110             case 'p': passwd = a; break;
111             case 'c': maxcl  = atoi(a); break;
112             default:  conoutf("unknown commandline option");
113         }
114         else conoutf("unknown commandline argument");
115     };
116 
117     #ifdef _DEBUG
118     par = SDL_INIT_NOPARACHUTE;
119     fs = 0;
120     #endif
121 
122     if(SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO|par)<0) fatal("Unable to initialize SDL");
123 
124     log("net");
125     if(enet_initialize()<0) fatal("Unable to initialise network module");
126 
127     initclient();
128     initserver(dedicated, uprate, sdesc, ip, master, passwd, maxcl);  // never returns if dedicated
129 
130     log("world");
131     empty_world(7, true);
132 
133     log("video: sdl");
134     if(SDL_InitSubSystem(SDL_INIT_VIDEO)<0) fatal("Unable to initialize SDL Video");
135 
136     log("video: mode");
137     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
138     if(SDL_SetVideoMode(scr_w, scr_h, 0, SDL_OPENGL|fs)==NULL) fatal("Unable to create OpenGL screen");
139 
140     log("video: misc");
141     SDL_WM_SetCaption("cube engine", NULL);
142     SDL_WM_GrabInput(SDL_GRAB_ON);
143     keyrepeat(false);
144     SDL_ShowCursor(0);
145 
146     log("gl");
147     gl_init(scr_w, scr_h);
148 
149     log("basetex");
150     int xs, ys;
151     if(!installtex(2,  path(newstring("data/newchars.png")), xs, ys) ||
152        !installtex(3,  path(newstring("data/martin/base.png")), xs, ys) ||
153        !installtex(6,  path(newstring("data/martin/ball1.png")), xs, ys) ||
154        !installtex(7,  path(newstring("data/martin/smoke.png")), xs, ys) ||
155        !installtex(8,  path(newstring("data/martin/ball2.png")), xs, ys) ||
156        !installtex(9,  path(newstring("data/martin/ball3.png")), xs, ys) ||
157        !installtex(4,  path(newstring("data/explosion.jpg")), xs, ys) ||
158        !installtex(5,  path(newstring("data/items.png")), xs, ys) ||
159        !installtex(1,  path(newstring("data/crosshair.png")), xs, ys)) fatal("could not find core textures (hint: run cube from the parent of the bin directory)");
160 
161     log("sound");
162     initsound();
163 
164     log("cfg");
165     newmenu("frags\tpj\tping\tteam\tname");
166     newmenu("ping\tplr\tserver");
167     exec("data/keymap.cfg");
168     exec("data/menus.cfg");
169     exec("data/prefabs.cfg");
170     exec("data/sounds.cfg");
171     exec("servers.cfg");
172     if(!execfile("config.cfg")) execfile("data/defaults.cfg");
173     exec("autoexec.cfg");
174 
175     log("localconnect");
176     localconnect();
177     changemap("metl3");		// if this map is changed, also change depthcorrect()
178 
179     log("mainloop");
180     int ignore = 5;
181     for(;;)
182     {
183         int millis = SDL_GetTicks()*gamespeed/100;
184         if(millis-lastmillis>200) lastmillis = millis-200;
185         else if(millis-lastmillis<1) lastmillis = millis-1;
186         if(millis-lastmillis<minmillis) SDL_Delay(minmillis-(millis-lastmillis));
187         cleardlights();
188         updateworld(millis);
189         if(!demoplayback) serverslice((int)time(NULL), 0);
190         static float fps = 30.0f;
191         fps = (1000.0f/curtime+fps*50)/51;
192         computeraytable(player1->o.x, player1->o.y);
193         readdepth(scr_w, scr_h);
194         SDL_GL_SwapBuffers();
195         extern void updatevol(); updatevol();
196         if(framesinmap++<5)	// cheap hack to get rid of initial sparklies, even when triple buffering etc.
197         {
198 			player1->yaw += 5;
199 			gl_drawframe(scr_w, scr_h, fps);
200 			player1->yaw -= 5;
201         };
202         gl_drawframe(scr_w, scr_h, fps);
203         SDL_Event event;
204         int lasttype = 0, lastbut = 0;
205         while(SDL_PollEvent(&event))
206         {
207             switch(event.type)
208             {
209                 case SDL_QUIT:
210                     quit();
211                     break;
212 
213                 case SDL_KEYDOWN:
214                 case SDL_KEYUP:
215                     keypress(event.key.keysym.sym, event.key.state==SDL_PRESSED, event.key.keysym.unicode);
216                     break;
217 
218                 case SDL_MOUSEMOTION:
219                     if(ignore) { ignore--; break; };
220                     mousemove(event.motion.xrel, event.motion.yrel);
221                     break;
222 
223                 case SDL_MOUSEBUTTONDOWN:
224                 case SDL_MOUSEBUTTONUP:
225                     if(lasttype==event.type && lastbut==event.button.button) break; // why?? get event twice without it
226                     keypress(-event.button.button, event.button.state!=0, 0);
227                     lasttype = event.type;
228                     lastbut = event.button.button;
229                     break;
230             };
231         };
232     };
233     quit();
234     return 1;
235 };
236 
237 
238