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