summaryrefslogtreecommitdiff
path: root/src/engine/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/main.cpp')
-rw-r--r--src/engine/main.cpp2094
1 files changed, 1008 insertions, 1086 deletions
diff --git a/src/engine/main.cpp b/src/engine/main.cpp
index 499002f..fb32dfd 100644
--- a/src/engine/main.cpp
+++ b/src/engine/main.cpp
@@ -12,65 +12,59 @@ extern void cleargamma();
void cleanup()
{
- cleanupserver();
- SDL_ShowCursor(SDL_TRUE);
- SDL_SetRelativeMouseMode(SDL_FALSE);
- if(screen) SDL_SetWindowGrab(screen, SDL_FALSE);
- cleargamma();
- freeocta(worldroot);
- extern void clear_command(); clear_command();
- extern void clear_console(); clear_console();
- extern void clear_mdls(); clear_mdls();
- extern void clear_sound(); clear_sound();
- closelogfile();
- #ifdef __APPLE__
- if(screen) SDL_SetWindowFullscreen(screen, 0);
- #endif
- SDL_Quit();
+ cleanupserver();
+ SDL_ShowCursor(SDL_TRUE);
+ SDL_SetRelativeMouseMode(SDL_FALSE);
+ if(screen) SDL_SetWindowGrab(screen, SDL_FALSE);
+ cleargamma();
+ freeocta(worldroot);
+ extern void clear_command(); clear_command();
+ extern void clear_console(); clear_console();
+ extern void clear_mdls(); clear_mdls();
+ extern void clear_sound(); clear_sound();
+ closelogfile();
+ SDL_Quit();
}
extern void writeinitcfg();
-void quit() // normal exit
+void quit() // normal exit
{
- writeinitcfg();
- writeservercfg();
- abortconnect();
- disconnect();
- localdisconnect();
- writecfg();
- cleanup();
- exit(EXIT_SUCCESS);
+ writeinitcfg();
+ writeservercfg();
+ abortconnect();
+ disconnect();
+ localdisconnect();
+ writecfg();
+ cleanup();
+ exit(EXIT_SUCCESS);
}
-void fatal(const char *s, ...) // failure exit
+void fatal(const char *s, ...) // failure exit
{
- static int errors = 0;
- errors++;
-
- if(errors <= 2) // print up to one extra recursive error
- {
- defvformatstring(msg,s,s);
- logoutf("%s", msg);
-
- if(errors <= 1) // avoid recursion
- {
- if(SDL_WasInit(SDL_INIT_VIDEO))
- {
- SDL_ShowCursor(SDL_TRUE);
- SDL_SetRelativeMouseMode(SDL_FALSE);
- if(screen) SDL_SetWindowGrab(screen, SDL_FALSE);
- cleargamma();
- #ifdef __APPLE__
- if(screen) SDL_SetWindowFullscreen(screen, 0);
- #endif
- }
- SDL_Quit();
- SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Cube 2: Sauerbraten fatal error", msg, NULL);
- }
- }
-
- exit(EXIT_FAILURE);
+ static int errors = 0;
+ errors++;
+
+ if(errors <= 2) // print up to one extra recursive error
+ {
+ defvformatstring(msg,s,s);
+ logoutf("%s", msg);
+
+ if(errors <= 1) // avoid recursion
+ {
+ if(SDL_WasInit(SDL_INIT_VIDEO))
+ {
+ SDL_ShowCursor(SDL_TRUE);
+ SDL_SetRelativeMouseMode(SDL_FALSE);
+ if(screen) SDL_SetWindowGrab(screen, SDL_FALSE);
+ cleargamma();
+ }
+ SDL_Quit();
+ SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Cube 2: Sauerbraten fatal error", msg, NULL);
+ }
+ }
+
+ exit(EXIT_FAILURE);
}
int curtime = 0, lastmillis = 1, elapsedtime = 0, totalmillis = 1;
@@ -81,12 +75,12 @@ int initing = NOT_INITING;
bool initwarning(const char *desc, int level, int type)
{
- if(initing < level)
- {
- addchange(desc, type);
- return true;
- }
- return false;
+ if(initing < level)
+ {
+ addchange(desc, type);
+ return true;
+ }
+ return false;
}
VAR(desktopw, 1, 0, 0);
@@ -108,36 +102,36 @@ VARF(fsaa, -1, -1, 16, initwarning("anti-aliasing"));
void writeinitcfg()
{
- stream *f = openutf8file("init.cfg", "w");
- if(!f) return;
- f->printf("// automatically written on exit, DO NOT MODIFY\n// modify settings in game\n");
- extern int fullscreen, fullscreendesktop;
- f->printf("fullscreen %d\n", fullscreen);
- f->printf("fullscreendesktop %d\n", fullscreendesktop);
- f->printf("scr_w %d\n", scr_w);
- f->printf("scr_h %d\n", scr_h);
- f->printf("depthbits %d\n", depthbits);
- f->printf("fsaa %d\n", fsaa);
- extern int usesound, soundchans, soundfreq, soundbufferlen;
- extern char *audiodriver;
- f->printf("usesound %d\n", usesound);
- f->printf("soundchans %d\n", soundchans);
- f->printf("soundfreq %d\n", soundfreq);
- f->printf("soundbufferlen %d\n", soundbufferlen);
- if(audiodriver[0]) f->printf("audiodriver %s\n", escapestring(audiodriver));
- delete f;
+ stream *f = openutf8file("init.cfg", "w");
+ if(!f) return;
+ f->printf("// automatically written on exit, DO NOT MODIFY\n// modify settings in game\n");
+ extern int fullscreen, fullscreendesktop;
+ f->printf("fullscreen %d\n", fullscreen);
+ f->printf("fullscreendesktop %d\n", fullscreendesktop);
+ f->printf("scr_w %d\n", scr_w);
+ f->printf("scr_h %d\n", scr_h);
+ f->printf("depthbits %d\n", depthbits);
+ f->printf("fsaa %d\n", fsaa);
+ extern int usesound, soundchans, soundfreq, soundbufferlen;
+ extern char *audiodriver;
+ f->printf("usesound %d\n", usesound);
+ f->printf("soundchans %d\n", soundchans);
+ f->printf("soundfreq %d\n", soundfreq);
+ f->printf("soundbufferlen %d\n", soundbufferlen);
+ if(audiodriver[0]) f->printf("audiodriver %s\n", escapestring(audiodriver));
+ delete f;
}
COMMAND(quit, "");
static void getbackgroundres(int &w, int &h)
{
- float wk = 1, hk = 1;
- if(w < 1024) wk = 1024.0f/w;
- if(h < 768) hk = 768.0f/h;
- wk = hk = max(wk, hk);
- w = int(ceil(w*wk));
- h = int(ceil(h*hk));
+ float wk = 1, hk = 1;
+ if(w < 1024) wk = 1024.0f/w;
+ if(h < 768) hk = 768.0f/h;
+ wk = hk = max(wk, hk);
+ w = int(ceil(w*wk));
+ h = int(ceil(h*hk));
}
string backgroundcaption = "";
@@ -147,156 +141,156 @@ char *backgroundmapinfo = NULL;
void setbackgroundinfo(const char *caption = NULL, Texture *mapshot = NULL, const char *mapname = NULL, const char *mapinfo = NULL)
{
- renderedframe = false;
- copystring(backgroundcaption, caption ? caption : "");
- backgroundmapshot = mapshot;
- copystring(backgroundmapname, mapname ? mapname : "");
- if(mapinfo != backgroundmapinfo)
- {
- DELETEA(backgroundmapinfo);
- if(mapinfo) backgroundmapinfo = newstring(mapinfo);
- }
+ renderedframe = false;
+ copystring(backgroundcaption, caption ? caption : "");
+ backgroundmapshot = mapshot;
+ copystring(backgroundmapname, mapname ? mapname : "");
+ if(mapinfo != backgroundmapinfo)
+ {
+ DELETEA(backgroundmapinfo);
+ if(mapinfo) backgroundmapinfo = newstring(mapinfo);
+ }
}
void restorebackground(bool force = false)
{
- if(renderedframe)
- {
- if(!force) return;
- setbackgroundinfo();
- }
- renderbackground(backgroundcaption[0] ? backgroundcaption : NULL, backgroundmapshot, backgroundmapname[0] ? backgroundmapname : NULL, backgroundmapinfo, true);
+ if(renderedframe)
+ {
+ if(!force) return;
+ setbackgroundinfo();
+ }
+ renderbackground(backgroundcaption[0] ? backgroundcaption : NULL, backgroundmapshot, backgroundmapname[0] ? backgroundmapname : NULL, backgroundmapinfo, true);
}
void bgquad(float x, float y, float w, float h, float tx = 0, float ty = 0, float tw = 1, float th = 1)
{
- gle::begin(GL_TRIANGLE_STRIP);
- gle::attribf(x, y); gle::attribf(tx, ty);
- gle::attribf(x+w, y); gle::attribf(tx + tw, ty);
- gle::attribf(x, y+h); gle::attribf(tx, ty + th);
- gle::attribf(x+w, y+h); gle::attribf(tx + tw, ty + th);
- gle::end();
+ gle::begin(GL_TRIANGLE_STRIP);
+ gle::attribf(x, y); gle::attribf(tx, ty);
+ gle::attribf(x+w, y); gle::attribf(tx + tw, ty);
+ gle::attribf(x, y+h); gle::attribf(tx, ty + th);
+ gle::attribf(x+w, y+h); gle::attribf(tx + tw, ty + th);
+ gle::end();
}
void renderbackground(const char *caption, Texture *mapshot, const char *mapname, const char *mapinfo, bool restore, bool force)
{
- if(!inbetweenframes && !force) return;
-
- if(!restore || force) stopsounds(); // stop sounds while loading
-
- int w = screenw, h = screenh;
- if(forceaspect) w = int(ceil(h*forceaspect));
- getbackgroundres(w, h);
- gettextres(w, h);
-
- static int lastupdate = -1, lastw = -1, lasth = -1;
- static int numdecals = 0;
- static struct decal { float x, y, size; int side; } decals[12];
- if((renderedframe && !mainmenu && lastupdate != lastmillis) || lastw != w || lasth != h)
- {
- lastupdate = lastmillis;
- lastw = w;
- lasth = h;
-
- numdecals = sizeof(decals)/sizeof(decals[0]);
- numdecals = numdecals/3 + rnd((numdecals*2)/3 + 1);
- float maxsize = min(w, h)/16.0f;
- loopi(numdecals)
- {
- decal d = { rndscale(w), rndscale(h), maxsize/2 + rndscale(maxsize/2), rnd(2) };
- decals[i] = d;
- }
- }
- else if(lastupdate != lastmillis) lastupdate = lastmillis;
-
- loopi(restore ? 1 : 3)
- {
- hudmatrix.ortho(0, w, h, 0, -1, 1);
- resethudmatrix();
-
- hudshader->set();
- gle::colorf(1, 1, 1);
-
- gle::defvertex(2);
- gle::deftexcoord0();
-
- settexture("background/daemex.png", 0);
- bgquad(0, 0, screenw, screenh, 0, 0, 1, 1);
- glEnable(GL_BLEND);
- float lh = 0.5f*min(w, h), lw = lh*2,
- lx = 0.5f*(w - lw), ly = 0.5f*(h*0.5f - lh);
- settexture((maxtexsize ? min(maxtexsize, hwtexsize) : hwtexsize) >= 1024 && (screenw > 1280 || screenh > 800) ? "data/logo_1024.png" : "data/logo.png", 3);
- bgquad(lx, ly, lw, lh);
- if(caption)
- {
- int tw = text_width(caption);
- float tsz = 0.04f*min(w, h)/FONTH,
- tx = 0.5f*(w - tw*tsz), ty = h - 0.075f*1.5f*min(w, h) - 1.25f*FONTH*tsz;
- pushhudmatrix();
- hudmatrix.translate(tx, ty, 0);
- hudmatrix.scale(tsz, tsz, 1);
- flushhudmatrix();
- draw_text(caption, 0, 0);
- pophudmatrix();
- }
- if(mapshot || mapname)
- {
- int infowidth = 12*FONTH;
- float sz = 0.35f*min(w, h), msz = (0.75f*min(w, h) - sz)/(infowidth + FONTH), x = 0.5f*(w-sz), y = ly+lh - sz/15;
- if(mapinfo)
- {
- int mw, mh;
- text_bounds(mapinfo, mw, mh, infowidth);
- x -= 0.5f*(mw*msz + FONTH*msz);
- }
- if(mapshot && mapshot!=notexture)
- {
- glBindTexture(GL_TEXTURE_2D, mapshot->id);
- bgquad(x, y, sz, sz);
- }
- else
- {
- int qw, qh;
- text_bounds("?", qw, qh);
- float qsz = sz*0.5f/max(qw, qh);
- pushhudmatrix();
- hudmatrix.translate(x + 0.5f*(sz - qw*qsz), y + 0.5f*(sz - qh*qsz), 0);
- hudmatrix.scale(qsz, qsz, 1);
- flushhudmatrix();
- draw_text("?", 0, 0);
- pophudmatrix();
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
- settexture("data/mapshot_frame.png", 3);
- bgquad(x, y, sz, sz);
- if(mapname)
- {
- int tw = text_width(mapname);
- float tsz = sz/(8*FONTH),
- tx = 0.9f*sz - tw*tsz, ty = 0.9f*sz - FONTH*tsz;
- if(tx < 0.1f*sz) { tsz = 0.1f*sz/tw; tx = 0.1f; }
- pushhudmatrix();
- hudmatrix.translate(x+tx, y+ty, 0);
- hudmatrix.scale(tsz, tsz, 1);
- flushhudmatrix();
- draw_text(mapname, 0, 0);
- pophudmatrix();
- }
- if(mapinfo)
- {
- pushhudmatrix();
- hudmatrix.translate(x+sz+FONTH*msz, y, 0);
- hudmatrix.scale(msz, msz, 1);
- flushhudmatrix();
- draw_text(mapinfo, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, -1, infowidth);
- pophudmatrix();
- }
- }
- glDisable(GL_BLEND);
- if(!restore) swapbuffers(false);
- }
-
- if(!restore) setbackgroundinfo(caption, mapshot, mapname, mapinfo);
+ if(!inbetweenframes && !force) return;
+
+ if(!restore || force) stopsounds(); // stop sounds while loading
+
+ int w = screenw, h = screenh;
+ if(forceaspect) w = int(ceil(h*forceaspect));
+ getbackgroundres(w, h);
+ gettextres(w, h);
+
+ static int lastupdate = -1, lastw = -1, lasth = -1;
+ static int numdecals = 0;
+ static struct decal { float x, y, size; int side; } decals[12];
+ if((renderedframe && !mainmenu && lastupdate != lastmillis) || lastw != w || lasth != h)
+ {
+ lastupdate = lastmillis;
+ lastw = w;
+ lasth = h;
+
+ numdecals = sizeof(decals)/sizeof(decals[0]);
+ numdecals = numdecals/3 + rnd((numdecals*2)/3 + 1);
+ float maxsize = min(w, h)/16.0f;
+ loopi(numdecals)
+ {
+ decal d = { rndscale(w), rndscale(h), maxsize/2 + rndscale(maxsize/2), rnd(2) };
+ decals[i] = d;
+ }
+ }
+ else if(lastupdate != lastmillis) lastupdate = lastmillis;
+
+ loopi(restore ? 1 : 3)
+ {
+ hudmatrix.ortho(0, w, h, 0, -1, 1);
+ resethudmatrix();
+
+ hudshader->set();
+ gle::colorf(1, 1, 1);
+
+ gle::defvertex(2);
+ gle::deftexcoord0();
+
+ settexture("background/daemex.png", 0);
+ bgquad(0, 0, screenw, screenh, 0, 0, 1, 1);
+ glEnable(GL_BLEND);
+ float lh = 0.5f*min(w, h), lw = lh*2,
+ lx = 0.5f*(w - lw), ly = 0.5f*(h*0.5f - lh);
+ settexture((maxtexsize ? min(maxtexsize, hwtexsize) : hwtexsize) >= 1024 && (screenw > 1280 || screenh > 800) ? "data/logo_1024.png" : "data/logo.png", 3);
+ bgquad(lx, ly, lw, lh);
+ if(caption)
+ {
+ int tw = text_width(caption);
+ float tsz = 0.04f*min(w, h)/FONTH,
+ tx = 0.5f*(w - tw*tsz), ty = h - 0.075f*1.5f*min(w, h) - 1.25f*FONTH*tsz;
+ pushhudmatrix();
+ hudmatrix.translate(tx, ty, 0);
+ hudmatrix.scale(tsz, tsz, 1);
+ flushhudmatrix();
+ draw_text(caption, 0, 0);
+ pophudmatrix();
+ }
+ if(mapshot || mapname)
+ {
+ int infowidth = 12*FONTH;
+ float sz = 0.35f*min(w, h), msz = (0.75f*min(w, h) - sz)/(infowidth + FONTH), x = 0.5f*(w-sz), y = ly+lh - sz/15;
+ if(mapinfo)
+ {
+ int mw, mh;
+ text_bounds(mapinfo, mw, mh, infowidth);
+ x -= 0.5f*(mw*msz + FONTH*msz);
+ }
+ if(mapshot && mapshot!=notexture)
+ {
+ glBindTexture(GL_TEXTURE_2D, mapshot->id);
+ bgquad(x, y, sz, sz);
+ }
+ else
+ {
+ int qw, qh;
+ text_bounds("?", qw, qh);
+ float qsz = sz*0.5f/max(qw, qh);
+ pushhudmatrix();
+ hudmatrix.translate(x + 0.5f*(sz - qw*qsz), y + 0.5f*(sz - qh*qsz), 0);
+ hudmatrix.scale(qsz, qsz, 1);
+ flushhudmatrix();
+ draw_text("?", 0, 0);
+ pophudmatrix();
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+ settexture("data/mapshot_frame.png", 3);
+ bgquad(x, y, sz, sz);
+ if(mapname)
+ {
+ int tw = text_width(mapname);
+ float tsz = sz/(8*FONTH),
+ tx = 0.9f*sz - tw*tsz, ty = 0.9f*sz - FONTH*tsz;
+ if(tx < 0.1f*sz) { tsz = 0.1f*sz/tw; tx = 0.1f; }
+ pushhudmatrix();
+ hudmatrix.translate(x+tx, y+ty, 0);
+ hudmatrix.scale(tsz, tsz, 1);
+ flushhudmatrix();
+ draw_text(mapname, 0, 0);
+ pophudmatrix();
+ }
+ if(mapinfo)
+ {
+ pushhudmatrix();
+ hudmatrix.translate(x+sz+FONTH*msz, y, 0);
+ hudmatrix.scale(msz, msz, 1);
+ flushhudmatrix();
+ draw_text(mapinfo, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, -1, infowidth);
+ pophudmatrix();
+ }
+ }
+ glDisable(GL_BLEND);
+ if(!restore) swapbuffers(false);
+ }
+
+ if(!restore) setbackgroundinfo(caption, mapshot, mapname, mapinfo);
}
VAR(progressbackground, 0, 0, 1);
@@ -305,108 +299,108 @@ float loadprogress = 0;
void renderprogress(float bar, const char *text, GLuint tex, bool background) // also used during loading
{
- if(!inbetweenframes || drawtex) return;
-
- extern int menufps, maxfps;
- int fps = menufps ? (maxfps ? min(maxfps, menufps) : menufps) : maxfps;
- if(fps)
- {
- static int lastprogress = 0;
- int ticks = SDL_GetTicks(), diff = ticks - lastprogress;
- if(bar > 0 && diff >= 0 && diff < (1000 + fps-1)/fps) return;
- lastprogress = ticks;
- }
-
- clientkeepalive(); // make sure our connection doesn't time out while loading maps etc.
-
- SDL_PumpEvents(); // keep the event queue awake to avoid 'beachball' cursor
-
- extern int mesa_swap_bug, curvsync;
- bool forcebackground = progressbackground || (mesa_swap_bug && (curvsync || totalmillis==1));
- if(background || forcebackground) restorebackground(forcebackground);
-
- int w = screenw, h = screenh;
- if(forceaspect) w = int(ceil(h*forceaspect));
- getbackgroundres(w, h);
- gettextres(w, h);
-
- hudmatrix.ortho(0, w, h, 0, -1, 1);
- resethudmatrix();
-
- hudshader->set();
- gle::colorf(1, 1, 1);
-
- gle::defvertex(2);
- gle::deftexcoord0();
-
- float fh = 0.075f*min(w, h), fw = fh*10,
- fx = renderedframe ? w - fw - fh/4 : 0.5f*(w - fw),
- fy = renderedframe ? fh/4 : h - fh*1.5f,
- fu1 = 0/512.0f, fu2 = 511/512.0f,
- fv1 = 0/64.0f, fv2 = 52/64.0f;
- settexture("data/loading_frame.png", 3);
- bgquad(fx, fy, fw, fh, fu1, fv1, fu2-fu1, fv2-fv1);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- float bw = fw*(511 - 2*17)/511.0f, bh = fh*20/52.0f,
- bx = fx + fw*17/511.0f, by = fy + fh*16/52.0f,
- bv1 = 0/32.0f, bv2 = 20/32.0f,
- su1 = 0/32.0f, su2 = 7/32.0f, sw = fw*7/511.0f,
- eu1 = 23/32.0f, eu2 = 30/32.0f, ew = fw*7/511.0f,
- mw = bw - sw - ew,
- ex = bx+sw + max(mw*bar, fw*7/511.0f);
- if(bar > 0)
- {
- settexture("data/loading_bar.png", 3);
- gle::begin(GL_QUADS);
- gle::attribf(bx, by); gle::attribf(su1, bv1);
- gle::attribf(bx+sw, by); gle::attribf(su2, bv1);
- gle::attribf(bx+sw, by+bh); gle::attribf(su2, bv2);
- gle::attribf(bx, by+bh); gle::attribf(su1, bv2);
-
- gle::attribf(bx+sw, by); gle::attribf(su2, bv1);
- gle::attribf(ex, by); gle::attribf(eu1, bv1);
- gle::attribf(ex, by+bh); gle::attribf(eu1, bv2);
- gle::attribf(bx+sw, by+bh); gle::attribf(su2, bv2);
-
- gle::attribf(ex, by); gle::attribf(eu1, bv1);
- gle::attribf(ex+ew, by); gle::attribf(eu2, bv1);
- gle::attribf(ex+ew, by+bh); gle::attribf(eu2, bv2);
- gle::attribf(ex, by+bh); gle::attribf(eu1, bv2);
- gle::end();
- }
-
- if(text)
- {
- int tw = text_width(text);
- float tsz = bh*0.8f/FONTH;
- if(tw*tsz > mw) tsz = mw/tw;
- pushhudmatrix();
- hudmatrix.translate(bx+sw, by + (bh - FONTH*tsz)/2, 0);
- hudmatrix.scale(tsz, tsz, 1);
- flushhudmatrix();
- draw_text(text, 0, 0);
- pophudmatrix();
- }
-
- glDisable(GL_BLEND);
-
- if(tex)
- {
- glBindTexture(GL_TEXTURE_2D, tex);
- float sz = 0.35f*min(w, h), x = 0.5f*(w-sz), y = 0.5f*min(w, h) - sz/15;
- bgquad(x, y, sz, sz);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- settexture("data/mapshot_frame.png", 3);
- bgquad(x, y, sz, sz);
- glDisable(GL_BLEND);
- }
-
- swapbuffers(false);
+ if(!inbetweenframes || drawtex) return;
+
+ extern int menufps, maxfps;
+ int fps = menufps ? (maxfps ? min(maxfps, menufps) : menufps) : maxfps;
+ if(fps)
+ {
+ static int lastprogress = 0;
+ int ticks = SDL_GetTicks(), diff = ticks - lastprogress;
+ if(bar > 0 && diff >= 0 && diff < (1000 + fps-1)/fps) return;
+ lastprogress = ticks;
+ }
+
+ clientkeepalive(); // make sure our connection doesn't time out while loading maps etc.
+
+ SDL_PumpEvents(); // keep the event queue awake to avoid 'beachball' cursor
+
+ extern int mesa_swap_bug, curvsync;
+ bool forcebackground = progressbackground || (mesa_swap_bug && (curvsync || totalmillis==1));
+ if(background || forcebackground) restorebackground(forcebackground);
+
+ int w = screenw, h = screenh;
+ if(forceaspect) w = int(ceil(h*forceaspect));
+ getbackgroundres(w, h);
+ gettextres(w, h);
+
+ hudmatrix.ortho(0, w, h, 0, -1, 1);
+ resethudmatrix();
+
+ hudshader->set();
+ gle::colorf(1, 1, 1);
+
+ gle::defvertex(2);
+ gle::deftexcoord0();
+
+ float fh = 0.075f*min(w, h), fw = fh*10,
+ fx = renderedframe ? w - fw - fh/4 : 0.5f*(w - fw),
+ fy = renderedframe ? fh/4 : h - fh*1.5f,
+ fu1 = 0/512.0f, fu2 = 511/512.0f,
+ fv1 = 0/64.0f, fv2 = 52/64.0f;
+ settexture("data/loading_frame.png", 3);
+ bgquad(fx, fy, fw, fh, fu1, fv1, fu2-fu1, fv2-fv1);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ float bw = fw*(511 - 2*17)/511.0f, bh = fh*20/52.0f,
+ bx = fx + fw*17/511.0f, by = fy + fh*16/52.0f,
+ bv1 = 0/32.0f, bv2 = 20/32.0f,
+ su1 = 0/32.0f, su2 = 7/32.0f, sw = fw*7/511.0f,
+ eu1 = 23/32.0f, eu2 = 30/32.0f, ew = fw*7/511.0f,
+ mw = bw - sw - ew,
+ ex = bx+sw + max(mw*bar, fw*7/511.0f);
+ if(bar > 0)
+ {
+ settexture("data/loading_bar.png", 3);
+ gle::begin(GL_QUADS);
+ gle::attribf(bx, by); gle::attribf(su1, bv1);
+ gle::attribf(bx+sw, by); gle::attribf(su2, bv1);
+ gle::attribf(bx+sw, by+bh); gle::attribf(su2, bv2);
+ gle::attribf(bx, by+bh); gle::attribf(su1, bv2);
+
+ gle::attribf(bx+sw, by); gle::attribf(su2, bv1);
+ gle::attribf(ex, by); gle::attribf(eu1, bv1);
+ gle::attribf(ex, by+bh); gle::attribf(eu1, bv2);
+ gle::attribf(bx+sw, by+bh); gle::attribf(su2, bv2);
+
+ gle::attribf(ex, by); gle::attribf(eu1, bv1);
+ gle::attribf(ex+ew, by); gle::attribf(eu2, bv1);
+ gle::attribf(ex+ew, by+bh); gle::attribf(eu2, bv2);
+ gle::attribf(ex, by+bh); gle::attribf(eu1, bv2);
+ gle::end();
+ }
+
+ if(text)
+ {
+ int tw = text_width(text);
+ float tsz = bh*0.8f/FONTH;
+ if(tw*tsz > mw) tsz = mw/tw;
+ pushhudmatrix();
+ hudmatrix.translate(bx+sw, by + (bh - FONTH*tsz)/2, 0);
+ hudmatrix.scale(tsz, tsz, 1);
+ flushhudmatrix();
+ draw_text(text, 0, 0);
+ pophudmatrix();
+ }
+
+ glDisable(GL_BLEND);
+
+ if(tex)
+ {
+ glBindTexture(GL_TEXTURE_2D, tex);
+ float sz = 0.35f*min(w, h), x = 0.5f*(w-sz), y = 0.5f*min(w, h) - sz/15;
+ bgquad(x, y, sz, sz);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ settexture("data/mapshot_frame.png", 3);
+ bgquad(x, y, sz, sz);
+ glDisable(GL_BLEND);
+ }
+
+ swapbuffers(false);
}
int keyrepeatmask = 0, textinputmask = 0;
@@ -415,34 +409,29 @@ VAR(textinputfilter, 0, 5, 1000);
void keyrepeat(bool on, int mask)
{
- if(on) keyrepeatmask |= mask;
- else keyrepeatmask &= ~mask;
+ if(on) keyrepeatmask |= mask;
+ else keyrepeatmask &= ~mask;
}
void textinput(bool on, int mask)
{
- if(on)
- {
- if(!textinputmask)
- {
- SDL_StartTextInput();
- textinputtime = SDL_GetTicks();
- }
- textinputmask |= mask;
- }
- else if(textinputmask)
- {
- textinputmask &= ~mask;
- if(!textinputmask) SDL_StopTextInput();
- }
+ if(on)
+ {
+ if(!textinputmask)
+ {
+ SDL_StartTextInput();
+ textinputtime = SDL_GetTicks();
+ }
+ textinputmask |= mask;
+ }
+ else if(textinputmask)
+ {
+ textinputmask &= ~mask;
+ if(!textinputmask) SDL_StopTextInput();
+ }
}
-#ifdef WIN32
-// SDL_WarpMouseInWindow behaves erratically on Windows, so force relative mouse instead.
-VARN(relativemouse, userelativemouse, 1, 1, 0);
-#else
VARNP(relativemouse, userelativemouse, 0, 1, 1);
-#endif
bool shouldgrab = false, grabinput = false, minimized = false, canrelativemouse = true, relativemouse = false;
@@ -453,54 +442,54 @@ VAR(sdl_xgrab_bug, 0, 0, 1);
void inputgrab(bool on, bool delay = false)
{
#ifdef SDL_VIDEO_DRIVER_X11
- bool wasrelativemouse = relativemouse;
+ bool wasrelativemouse = relativemouse;
#endif
- if(on)
- {
- SDL_ShowCursor(SDL_FALSE);
- if(canrelativemouse && userelativemouse)
- {
- if(SDL_SetRelativeMouseMode(SDL_TRUE) >= 0)
- {
- SDL_SetWindowGrab(screen, SDL_TRUE);
- relativemouse = true;
- }
- else
- {
- SDL_SetWindowGrab(screen, SDL_FALSE);
- canrelativemouse = false;
- relativemouse = false;
- }
- }
- }
- else
- {
- SDL_ShowCursor(SDL_TRUE);
- if(relativemouse)
- {
- SDL_SetWindowGrab(screen, SDL_FALSE);
- SDL_SetRelativeMouseMode(SDL_FALSE);
- relativemouse = false;
- }
- }
- shouldgrab = delay;
+ if(on)
+ {
+ SDL_ShowCursor(SDL_FALSE);
+ if(canrelativemouse && userelativemouse)
+ {
+ if(SDL_SetRelativeMouseMode(SDL_TRUE) >= 0)
+ {
+ SDL_SetWindowGrab(screen, SDL_TRUE);
+ relativemouse = true;
+ }
+ else
+ {
+ SDL_SetWindowGrab(screen, SDL_FALSE);
+ canrelativemouse = false;
+ relativemouse = false;
+ }
+ }
+ }
+ else
+ {
+ SDL_ShowCursor(SDL_TRUE);
+ if(relativemouse)
+ {
+ SDL_SetWindowGrab(screen, SDL_FALSE);
+ SDL_SetRelativeMouseMode(SDL_FALSE);
+ relativemouse = false;
+ }
+ }
+ shouldgrab = delay;
#ifdef SDL_VIDEO_DRIVER_X11
- if((relativemouse || wasrelativemouse) && sdl_xgrab_bug)
- {
- // Workaround for buggy SDL X11 pointer grabbing
- union { SDL_SysWMinfo info; uchar buf[sizeof(SDL_SysWMinfo) + 128]; };
- SDL_GetVersion(&info.version);
- if(SDL_GetWindowWMInfo(screen, &info) && info.subsystem == SDL_SYSWM_X11)
- {
- if(relativemouse)
- {
- uint mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask;
- XGrabPointer(info.info.x11.display, info.info.x11.window, True, mask, GrabModeAsync, GrabModeAsync, info.info.x11.window, None, CurrentTime);
- }
- else XUngrabPointer(info.info.x11.display, CurrentTime);
- }
- }
+ if((relativemouse || wasrelativemouse) && sdl_xgrab_bug)
+ {
+ // Workaround for buggy SDL X11 pointer grabbing
+ union { SDL_SysWMinfo info; uchar buf[sizeof(SDL_SysWMinfo) + 128]; };
+ SDL_GetVersion(&info.version);
+ if(SDL_GetWindowWMInfo(screen, &info) && info.subsystem == SDL_SYSWM_X11)
+ {
+ if(relativemouse)
+ {
+ uint mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask;
+ XGrabPointer(info.info.x11.display, info.info.x11.window, True, mask, GrabModeAsync, GrabModeAsync, info.info.x11.window, None, CurrentTime);
+ }
+ else XUngrabPointer(info.info.x11.display, CurrentTime);
+ }
+ }
#endif
}
@@ -508,20 +497,20 @@ bool initwindowpos = false;
void setfullscreen(bool enable)
{
- if(!screen) return;
- //initwarning(enable ? "fullscreen" : "windowed");
- extern int fullscreendesktop;
- SDL_SetWindowFullscreen(screen, enable ? (fullscreendesktop ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN) : 0);
- if(!enable)
- {
- SDL_SetWindowSize(screen, scr_w, scr_h);
- if(initwindowpos)
- {
- int winx = SDL_WINDOWPOS_CENTERED, winy = SDL_WINDOWPOS_CENTERED;
- SDL_SetWindowPosition(screen, winx, winy);
- initwindowpos = false;
- }
- }
+ if(!screen) return;
+ //initwarning(enable ? "fullscreen" : "windowed");
+ extern int fullscreendesktop;
+ SDL_SetWindowFullscreen(screen, enable ? (fullscreendesktop ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN) : 0);
+ if(!enable)
+ {
+ SDL_SetWindowSize(screen, scr_w, scr_h);
+ if(initwindowpos)
+ {
+ int winx = SDL_WINDOWPOS_CENTERED, winy = SDL_WINDOWPOS_CENTERED;
+ SDL_SetWindowPosition(screen, winx, winy);
+ initwindowpos = false;
+ }
+ }
}
#ifdef _DEBUG
@@ -532,76 +521,76 @@ VARF(fullscreen, 0, 1, 1, setfullscreen(fullscreen!=0));
void resetfullscreen()
{
- setfullscreen(false);
- setfullscreen(true);
+ setfullscreen(false);
+ setfullscreen(true);
}
VARF(fullscreendesktop, 0, 0, 1, if(fullscreen) resetfullscreen());
void screenres(int w, int h)
{
- scr_w = clamp(w, SCR_MINW, SCR_MAXW);
- scr_h = clamp(h, SCR_MINH, SCR_MAXH);
- if(screen)
- {
- if(fullscreendesktop)
- {
- scr_w = min(scr_w, desktopw);
- scr_h = min(scr_h, desktoph);
- }
- if(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN)
- {
- if(fullscreendesktop) gl_resize();
- else resetfullscreen();
- initwindowpos = true;
- }
- else
- {
- SDL_SetWindowSize(screen, scr_w, scr_h);
- SDL_SetWindowPosition(screen, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
- initwindowpos = false;
- }
- }
- else
- {
- initwarning("screen resolution");
- }
+ scr_w = clamp(w, SCR_MINW, SCR_MAXW);
+ scr_h = clamp(h, SCR_MINH, SCR_MAXH);
+ if(screen)
+ {
+ if(fullscreendesktop)
+ {
+ scr_w = min(scr_w, desktopw);
+ scr_h = min(scr_h, desktoph);
+ }
+ if(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN)
+ {
+ if(fullscreendesktop) gl_resize();
+ else resetfullscreen();
+ initwindowpos = true;
+ }
+ else
+ {
+ SDL_SetWindowSize(screen, scr_w, scr_h);
+ SDL_SetWindowPosition(screen, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
+ initwindowpos = false;
+ }
+ }
+ else
+ {
+ initwarning("screen resolution");
+ }
}
ICOMMAND(screenres, "ii", (int *w, int *h), screenres(*w, *h));
static void setgamma(int val)
{
- if(screen && SDL_SetWindowBrightness(screen, val/100.0f) < 0) conoutf(CON_ERROR, "Could not set gamma: %s", SDL_GetError());
+ if(screen && SDL_SetWindowBrightness(screen, val/100.0f) < 0) conoutf(CON_ERROR, "Could not set gamma: %s", SDL_GetError());
}
static int curgamma = 100;
VARFNP(gamma, reqgamma, 30, 100, 300,
{
- if(initing || reqgamma == curgamma) return;
- curgamma = reqgamma;
- setgamma(curgamma);
+ if(initing || reqgamma == curgamma) return;
+ curgamma = reqgamma;
+ setgamma(curgamma);
});
void restoregamma()
{
- if(initing || reqgamma == 100) return;
- curgamma = reqgamma;
- setgamma(curgamma);
+ if(initing || reqgamma == 100) return;
+ curgamma = reqgamma;
+ setgamma(curgamma);
}
void cleargamma()
{
- if(curgamma != 100 && screen) SDL_SetWindowBrightness(screen, 1.0f);
+ if(curgamma != 100 && screen) SDL_SetWindowBrightness(screen, 1.0f);
}
int curvsync = -1;
void restorevsync()
{
- if(initing || !glcontext) return;
- extern int vsync, vsynctear;
- if(!SDL_GL_SetSwapInterval(vsync ? (vsynctear ? -1 : 1) : 0))
- curvsync = vsync;
+ if(initing || !glcontext) return;
+ extern int vsync, vsynctear;
+ if(!SDL_GL_SetSwapInterval(vsync ? (vsynctear ? -1 : 1) : 0))
+ curvsync = vsync;
}
VARFP(vsync, 0, 0, 1, restorevsync());
@@ -609,168 +598,162 @@ VARFP(vsynctear, 0, 0, 1, { if(vsync) restorevsync(); });
void setupscreen()
{
- if(glcontext)
- {
- SDL_GL_DeleteContext(glcontext);
- glcontext = NULL;
- }
- if(screen)
- {
- SDL_DestroyWindow(screen);
- screen = NULL;
- }
- curvsync = -1;
-
- SDL_Rect desktop;
- if(SDL_GetDisplayBounds(0, &desktop) < 0) fatal("failed querying desktop bounds: %s", SDL_GetError());
- desktopw = desktop.w;
- desktoph = desktop.h;
-
- if(scr_h < 0) scr_h = fullscreen ? desktoph : SCR_DEFAULTH;
- if(scr_w < 0) scr_w = (scr_h*desktopw)/desktoph;
- scr_w = clamp(scr_w, SCR_MINW, SCR_MAXW);
- scr_h = clamp(scr_h, SCR_MINH, SCR_MAXH);
- if(fullscreendesktop)
- {
- scr_w = min(scr_w, desktopw);
- scr_h = min(scr_h, desktoph);
- }
-
- int winx = SDL_WINDOWPOS_UNDEFINED, winy = SDL_WINDOWPOS_UNDEFINED, winw = scr_w, winh = scr_h, flags = SDL_WINDOW_RESIZABLE;
- if(fullscreen)
- {
- if(fullscreendesktop)
- {
- winw = desktopw;
- winh = desktoph;
- flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
- }
- else flags |= SDL_WINDOW_FULLSCREEN;
- initwindowpos = true;
- }
-
- SDL_GL_ResetAttributes();
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- #if !defined(WIN32) && !defined(__APPLE__)
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
- #endif
- static const int configs[] =
- {
- 0x3, /* try everything */
- 0x2, 0x1, /* try disabling one at a time */
- 0 /* try disabling everything */
- };
- int config = 0;
- if(!depthbits) SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
- if(!fsaa)
- {
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
- }
- loopi(sizeof(configs)/sizeof(configs[0]))
- {
- config = configs[i];
- if(!depthbits && config&1) continue;
- if(fsaa<=0 && config&2) continue;
- if(depthbits) SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, config&1 ? depthbits : 24);
- if(fsaa>0)
- {
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, config&2 ? 1 : 0);
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, config&2 ? fsaa : 0);
- }
- screen = SDL_CreateWindow("Cube 2: Sauerbraten", winx, winy, winw, winh, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_MOUSE_FOCUS | flags);
- if(!screen) continue;
-
- #ifdef __APPLE__
- static const int glversions[] = { 32, 20 };
- #else
- static const int glversions[] = { 33, 32, 31, 30, 20 };
- #endif
- loopj(sizeof(glversions)/sizeof(glversions[0]))
- {
- glcompat = glversions[j] <= 30 ? 1 : 0;
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, glversions[j] / 10);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, glversions[j] % 10);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, glversions[j] >= 32 ? SDL_GL_CONTEXT_PROFILE_CORE : 0);
- glcontext = SDL_GL_CreateContext(screen);
- if(glcontext) break;
- }
- if(glcontext) break;
- }
- if(!screen) fatal("failed to create OpenGL window: %s", SDL_GetError());
- else if(!glcontext) fatal("failed to create OpenGL context: %s", SDL_GetError());
- else
- {
- if(depthbits && (config&1)==0) conoutf(CON_WARN, "%d bit z-buffer not supported - disabling", depthbits);
- if(fsaa>0 && (config&2)==0) conoutf(CON_WARN, "%dx anti-aliasing not supported - disabling", fsaa);
- }
-
- SDL_SetWindowMinimumSize(screen, SCR_MINW, SCR_MINH);
- SDL_SetWindowMaximumSize(screen, SCR_MAXW, SCR_MAXH);
-
- SDL_GetWindowSize(screen, &screenw, &screenh);
+ if(glcontext)
+ {
+ SDL_GL_DeleteContext(glcontext);
+ glcontext = NULL;
+ }
+ if(screen)
+ {
+ SDL_DestroyWindow(screen);
+ screen = NULL;
+ }
+ curvsync = -1;
+
+ SDL_Rect desktop;
+ if(SDL_GetDisplayBounds(0, &desktop) < 0) fatal("failed querying desktop bounds: %s", SDL_GetError());
+ desktopw = desktop.w;
+ desktoph = desktop.h;
+
+ if(scr_h < 0) scr_h = fullscreen ? desktoph : SCR_DEFAULTH;
+ if(scr_w < 0) scr_w = (scr_h*desktopw)/desktoph;
+ scr_w = clamp(scr_w, SCR_MINW, SCR_MAXW);
+ scr_h = clamp(scr_h, SCR_MINH, SCR_MAXH);
+ if(fullscreendesktop)
+ {
+ scr_w = min(scr_w, desktopw);
+ scr_h = min(scr_h, desktoph);
+ }
+
+ int winx = SDL_WINDOWPOS_UNDEFINED, winy = SDL_WINDOWPOS_UNDEFINED, winw = scr_w, winh = scr_h, flags = SDL_WINDOW_RESIZABLE;
+ if(fullscreen)
+ {
+ if(fullscreendesktop)
+ {
+ winw = desktopw;
+ winh = desktoph;
+ flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
+ }
+ else flags |= SDL_WINDOW_FULLSCREEN;
+ initwindowpos = true;
+ }
+
+ SDL_GL_ResetAttributes();
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ static const int configs[] =
+ {
+ 0x3, /* try everything */
+ 0x2, 0x1, /* try disabling one at a time */
+ 0 /* try disabling everything */
+ };
+ int config = 0;
+ if(!depthbits) SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
+ if(!fsaa)
+ {
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
+ }
+ loopi(sizeof(configs)/sizeof(configs[0]))
+ {
+ config = configs[i];
+ if(!depthbits && config&1) continue;
+ if(fsaa<=0 && config&2) continue;
+ if(depthbits) SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, config&1 ? depthbits : 24);
+ if(fsaa>0)
+ {
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, config&2 ? 1 : 0);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, config&2 ? fsaa : 0);
+ }
+ screen = SDL_CreateWindow("Cube 2: Sauerbraten", winx, winy, winw, winh, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_MOUSE_FOCUS | flags);
+ if(!screen) continue;
+
+ static const int glversions[] = { 33, 32, 31, 30, 20 };
+ loopj(sizeof(glversions)/sizeof(glversions[0]))
+ {
+ glcompat = glversions[j] <= 30 ? 1 : 0;
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, glversions[j] / 10);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, glversions[j] % 10);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, glversions[j] >= 32 ? SDL_GL_CONTEXT_PROFILE_CORE : 0);
+ glcontext = SDL_GL_CreateContext(screen);
+ if(glcontext) break;
+ }
+ if(glcontext) break;
+ }
+ if(!screen) fatal("failed to create OpenGL window: %s", SDL_GetError());
+ else if(!glcontext) fatal("failed to create OpenGL context: %s", SDL_GetError());
+ else
+ {
+ if(depthbits && (config&1)==0) conoutf(CON_WARN, "%d bit z-buffer not supported - disabling", depthbits);
+ if(fsaa>0 && (config&2)==0) conoutf(CON_WARN, "%dx anti-aliasing not supported - disabling", fsaa);
+ }
+
+ SDL_SetWindowMinimumSize(screen, SCR_MINW, SCR_MINH);
+ SDL_SetWindowMaximumSize(screen, SCR_MAXW, SCR_MAXH);
+
+ SDL_GetWindowSize(screen, &screenw, &screenh);
}
void resetgl()
{
- clearchanges(CHANGE_GFX);
-
- renderbackground("resetting OpenGL");
-
- extern void cleanupva();
- extern void cleanupparticles();
- extern void cleanupdecals();
- extern void cleanupsky();
- extern void cleanupmodels();
- extern void cleanupprefabs();
- extern void cleanuplightmaps();
- extern void cleanupblendmap();
- extern void cleanshadowmap();
- extern void cleanreflections();
- extern void cleanupglare();
- extern void cleanupdepthfx();
- cleanupva();
- cleanupparticles();
- cleanupdecals();
- cleanupsky();
- cleanupmodels();
- cleanupprefabs();
- cleanuptextures();
- cleanuplightmaps();
- cleanupblendmap();
- cleanshadowmap();
- cleanreflections();
- cleanupglare();
- cleanupdepthfx();
- cleanupshaders();
- cleanupgl();
-
- setupscreen();
- inputgrab(grabinput);
- gl_init();
-
- inbetweenframes = false;
- if(!reloadtexture(*notexture) ||
- !reloadtexture("data/logo.png") ||
- !reloadtexture("data/logo_1024.png") ||
- !reloadtexture("data/background.png") ||
- !reloadtexture("data/background_detail.png") ||
- !reloadtexture("data/background_decal.png") ||
- !reloadtexture("data/mapshot_frame.png") ||
- !reloadtexture("data/loading_frame.png") ||
- !reloadtexture("data/loading_bar.png"))
- fatal("failed to reload core texture");
- reloadfonts();
- inbetweenframes = true;
- renderbackground("initializing...");
- restoregamma();
- restorevsync();
- reloadshaders();
- reloadtextures();
- initlights();
- allchanged(true);
+ clearchanges(CHANGE_GFX);
+
+ renderbackground("resetting OpenGL");
+
+ extern void cleanupva();
+ extern void cleanupparticles();
+ extern void cleanupdecals();
+ extern void cleanupsky();
+ extern void cleanupmodels();
+ extern void cleanupprefabs();
+ extern void cleanuplightmaps();
+ extern void cleanupblendmap();
+ extern void cleanshadowmap();
+ extern void cleanreflections();
+ extern void cleanupglare();
+ extern void cleanupdepthfx();
+ cleanupva();
+ cleanupparticles();
+ cleanupdecals();
+ cleanupsky();
+ cleanupmodels();
+ cleanupprefabs();
+ cleanuptextures();
+ cleanuplightmaps();
+ cleanupblendmap();
+ cleanshadowmap();
+ cleanreflections();
+ cleanupglare();
+ cleanupdepthfx();
+ cleanupshaders();
+ cleanupgl();
+
+ setupscreen();
+ inputgrab(grabinput);
+ gl_init();
+
+ inbetweenframes = false;
+ if(!reloadtexture(*notexture) ||
+ !reloadtexture("data/logo.png") ||
+ !reloadtexture("data/logo_1024.png") ||
+ !reloadtexture("data/background.png") ||
+ !reloadtexture("data/background_detail.png") ||
+ !reloadtexture("data/background_decal.png") ||
+ !reloadtexture("data/mapshot_frame.png") ||
+ !reloadtexture("data/loading_frame.png") ||
+ !reloadtexture("data/loading_bar.png"))
+ fatal("failed to reload core texture");
+ reloadfonts();
+ inbetweenframes = true;
+ renderbackground("initializing...");
+ restoregamma();
+ restorevsync();
+ reloadshaders();
+ reloadtextures();
+ initlights();
+ allchanged(true);
}
COMMAND(resetgl, "");
@@ -779,233 +762,229 @@ static queue<SDL_Event, 32> events;
static inline bool filterevent(const SDL_Event &event)
{
- switch(event.type)
- {
- case SDL_MOUSEMOTION:
- if(grabinput && !relativemouse && !(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN))
- {
- if(event.motion.x == screenw / 2 && event.motion.y == screenh / 2)
- return false; // ignore any motion events generated by SDL_WarpMouse
- #ifdef __APPLE__
- if(event.motion.y == 0)
- return false; // let mac users drag windows via the title bar
- #endif
- }
- break;
- }
- return true;
+ switch(event.type)
+ {
+ case SDL_MOUSEMOTION:
+ if(grabinput && !relativemouse && !(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN))
+ {
+ if(event.motion.x == screenw / 2 && event.motion.y == screenh / 2)
+ return false; // ignore any motion events generated by SDL_WarpMouse
+ }
+ break;
+ }
+ return true;
}
template <int SIZE> static inline bool pumpevents(queue<SDL_Event, SIZE> &events)
{
- while(events.empty())
- {
- SDL_PumpEvents();
- databuf<SDL_Event> buf = events.reserve(events.capacity());
- int n = SDL_PeepEvents(buf.getbuf(), buf.remaining(), SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
- if(n <= 0) return false;
- loopi(n) if(filterevent(buf.buf[i])) buf.put(buf.buf[i]);
- events.addbuf(buf);
- }
- return true;
+ while(events.empty())
+ {
+ SDL_PumpEvents();
+ databuf<SDL_Event> buf = events.reserve(events.capacity());
+ int n = SDL_PeepEvents(buf.getbuf(), buf.remaining(), SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
+ if(n <= 0) return false;
+ loopi(n) if(filterevent(buf.buf[i])) buf.put(buf.buf[i]);
+ events.addbuf(buf);
+ }
+ return true;
}
static int interceptkeysym = 0;
static int interceptevents(void *data, SDL_Event *event)
{
- switch(event->type)
- {
- case SDL_MOUSEMOTION: return 0;
- case SDL_KEYDOWN:
- if(event->key.keysym.sym == interceptkeysym)
- {
- interceptkeysym = -interceptkeysym;
- return 0;
- }
- break;
- }
- return 1;
+ switch(event->type)
+ {
+ case SDL_MOUSEMOTION: return 0;
+ case SDL_KEYDOWN:
+ if(event->key.keysym.sym == interceptkeysym)
+ {
+ interceptkeysym = -interceptkeysym;
+ return 0;
+ }
+ break;
+ }
+ return 1;
}
static void clearinterceptkey()
{
- SDL_DelEventWatch(interceptevents, NULL);
- interceptkeysym = 0;
+ SDL_DelEventWatch(interceptevents, NULL);
+ interceptkeysym = 0;
}
bool interceptkey(int sym)
{
- if(!interceptkeysym)
- {
- interceptkeysym = sym;
- SDL_FilterEvents(interceptevents, NULL);
- if(interceptkeysym < 0)
- {
- interceptkeysym = 0;
- return true;
- }
- SDL_AddEventWatch(interceptevents, NULL);
- }
- else if(abs(interceptkeysym) != sym) interceptkeysym = sym;
- SDL_PumpEvents();
- if(interceptkeysym < 0)
- {
- clearinterceptkey();
- interceptkeysym = sym;
- SDL_FilterEvents(interceptevents, NULL);
- interceptkeysym = 0;
- return true;
- }
- return false;
+ if(!interceptkeysym)
+ {
+ interceptkeysym = sym;
+ SDL_FilterEvents(interceptevents, NULL);
+ if(interceptkeysym < 0)
+ {
+ interceptkeysym = 0;
+ return true;
+ }
+ SDL_AddEventWatch(interceptevents, NULL);
+ }
+ else if(abs(interceptkeysym) != sym) interceptkeysym = sym;
+ SDL_PumpEvents();
+ if(interceptkeysym < 0)
+ {
+ clearinterceptkey();
+ interceptkeysym = sym;
+ SDL_FilterEvents(interceptevents, NULL);
+ interceptkeysym = 0;
+ return true;
+ }
+ return false;
}
static void ignoremousemotion()
{
- SDL_PumpEvents();
- SDL_FlushEvent(SDL_MOUSEMOTION);
+ SDL_PumpEvents();
+ SDL_FlushEvent(SDL_MOUSEMOTION);
}
static void resetmousemotion()
{
- if(grabinput && !relativemouse && !(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN))
- {
- SDL_WarpMouseInWindow(screen, screenw / 2, screenh / 2);
- }
+ if(grabinput && !relativemouse && !(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN))
+ {
+ SDL_WarpMouseInWindow(screen, screenw / 2, screenh / 2);
+ }
}
static void checkmousemotion(int &dx, int &dy)
{
- while(pumpevents(events))
- {
- SDL_Event &event = events.removing();
- if(event.type != SDL_MOUSEMOTION) return;
- dx += event.motion.xrel;
- dy += event.motion.yrel;
- events.remove();
- }
+ while(pumpevents(events))
+ {
+ SDL_Event &event = events.removing();
+ if(event.type != SDL_MOUSEMOTION) return;
+ dx += event.motion.xrel;
+ dy += event.motion.yrel;
+ events.remove();
+ }
}
void checkinput()
{
- if(interceptkeysym) clearinterceptkey();
- //int lasttype = 0, lastbut = 0;
- bool mousemoved = false;
- int focused = 0;
- while(pumpevents(events))
- {
- SDL_Event &event = events.remove();
-
- if(focused && event.type!=SDL_WINDOWEVENT) { if(grabinput != (focused>0)) inputgrab(grabinput = focused>0, shouldgrab); focused = 0; }
-
- switch(event.type)
- {
- case SDL_QUIT:
- quit();
- return;
-
- case SDL_TEXTINPUT:
- if(textinputmask && int(event.text.timestamp-textinputtime) >= textinputfilter)
- {
- uchar buf[SDL_TEXTINPUTEVENT_TEXT_SIZE+1];
- size_t len = decodeutf8(buf, sizeof(buf)-1, (const uchar *)event.text.text, strlen(event.text.text));
- if(len > 0) { buf[len] = '\0'; processtextinput((const char *)buf, len); }
- }
- break;
-
- case SDL_KEYDOWN:
- case SDL_KEYUP:
- if(keyrepeatmask || !event.key.repeat)
- processkey(event.key.keysym.sym, event.key.state==SDL_PRESSED, event.key.keysym.mod | SDL_GetModState());
- break;
-
- case SDL_WINDOWEVENT:
- switch(event.window.event)
- {
- case SDL_WINDOWEVENT_CLOSE:
- quit();
- break;
-
- case SDL_WINDOWEVENT_FOCUS_GAINED:
- shouldgrab = true;
- break;
- case SDL_WINDOWEVENT_ENTER:
- shouldgrab = false;
- focused = 1;
- break;
-
- case SDL_WINDOWEVENT_LEAVE:
- case SDL_WINDOWEVENT_FOCUS_LOST:
- shouldgrab = false;
- focused = -1;
- break;
-
- case SDL_WINDOWEVENT_MINIMIZED:
- minimized = true;
- break;
-
- case SDL_WINDOWEVENT_MAXIMIZED:
- case SDL_WINDOWEVENT_RESTORED:
- minimized = false;
- break;
-
- case SDL_WINDOWEVENT_RESIZED:
- break;
-
- case SDL_WINDOWEVENT_SIZE_CHANGED:
- {
- SDL_GetWindowSize(screen, &screenw, &screenh);
- if(!fullscreendesktop || !(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN))
- {
- scr_w = clamp(screenw, SCR_MINW, SCR_MAXW);
- scr_h = clamp(screenh, SCR_MINH, SCR_MAXH);
- }
- gl_resize();
- break;
- }
- }
- break;
-
- case SDL_MOUSEMOTION:
- if(grabinput)
- {
- int dx = event.motion.xrel, dy = event.motion.yrel;
- checkmousemotion(dx, dy);
- if(!g3d_movecursor(dx, dy)) mousemove(dx, dy);
- mousemoved = true;
- }
- else if(shouldgrab) inputgrab(grabinput = true);
- break;
-
- case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEBUTTONUP:
- //if(lasttype==event.type && lastbut==event.button.button) break; // why?? get event twice without it
- switch(event.button.button)
- {
- case SDL_BUTTON_LEFT: processkey(-1, event.button.state==SDL_PRESSED); break;
- case SDL_BUTTON_MIDDLE: processkey(-2, event.button.state==SDL_PRESSED); break;
- case SDL_BUTTON_RIGHT: processkey(-3, event.button.state==SDL_PRESSED); break;
- case SDL_BUTTON_X1: processkey(-6, event.button.state==SDL_PRESSED); break;
- case SDL_BUTTON_X2: processkey(-7, event.button.state==SDL_PRESSED); break;
- }
- //lasttype = event.type;
- //lastbut = event.button.button;
- break;
-
- case SDL_MOUSEWHEEL:
- if(event.wheel.y > 0) { processkey(-4, true); processkey(-4, false); }
- else if(event.wheel.y < 0) { processkey(-5, true); processkey(-5, false); }
- break;
- }
- }
- if(focused) { if(grabinput != (focused>0)) inputgrab(grabinput = focused>0, shouldgrab); focused = 0; }
- if(mousemoved) resetmousemotion();
+ if(interceptkeysym) clearinterceptkey();
+ //int lasttype = 0, lastbut = 0;
+ bool mousemoved = false;
+ int focused = 0;
+ while(pumpevents(events))
+ {
+ SDL_Event &event = events.remove();
+
+ if(focused && event.type!=SDL_WINDOWEVENT) { if(grabinput != (focused>0)) inputgrab(grabinput = focused>0, shouldgrab); focused = 0; }
+
+ switch(event.type)
+ {
+ case SDL_QUIT:
+ quit();
+ return;
+
+ case SDL_TEXTINPUT:
+ if(textinputmask && int(event.text.timestamp-textinputtime) >= textinputfilter)
+ {
+ uchar buf[SDL_TEXTINPUTEVENT_TEXT_SIZE+1];
+ size_t len = decodeutf8(buf, sizeof(buf)-1, (const uchar *)event.text.text, strlen(event.text.text));
+ if(len > 0) { buf[len] = '\0'; processtextinput((const char *)buf, len); }
+ }
+ break;
+
+ case SDL_KEYDOWN:
+ case SDL_KEYUP:
+ if(keyrepeatmask || !event.key.repeat)
+ processkey(event.key.keysym.sym, event.key.state==SDL_PRESSED, event.key.keysym.mod | SDL_GetModState());
+ break;
+
+ case SDL_WINDOWEVENT:
+ switch(event.window.event)
+ {
+ case SDL_WINDOWEVENT_CLOSE:
+ quit();
+ break;
+
+ case SDL_WINDOWEVENT_FOCUS_GAINED:
+ shouldgrab = true;
+ break;
+ case SDL_WINDOWEVENT_ENTER:
+ shouldgrab = false;
+ focused = 1;
+ break;
+
+ case SDL_WINDOWEVENT_LEAVE:
+ case SDL_WINDOWEVENT_FOCUS_LOST:
+ shouldgrab = false;
+ focused = -1;
+ break;
+
+ case SDL_WINDOWEVENT_MINIMIZED:
+ minimized = true;
+ break;
+
+ case SDL_WINDOWEVENT_MAXIMIZED:
+ case SDL_WINDOWEVENT_RESTORED:
+ minimized = false;
+ break;
+
+ case SDL_WINDOWEVENT_RESIZED:
+ break;
+
+ case SDL_WINDOWEVENT_SIZE_CHANGED:
+ {
+ SDL_GetWindowSize(screen, &screenw, &screenh);
+ if(!fullscreendesktop || !(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN))
+ {
+ scr_w = clamp(screenw, SCR_MINW, SCR_MAXW);
+ scr_h = clamp(screenh, SCR_MINH, SCR_MAXH);
+ }
+ gl_resize();
+ break;
+ }
+ }
+ break;
+
+ case SDL_MOUSEMOTION:
+ if(grabinput)
+ {
+ int dx = event.motion.xrel, dy = event.motion.yrel;
+ checkmousemotion(dx, dy);
+ if(!g3d_movecursor(dx, dy)) mousemove(dx, dy);
+ mousemoved = true;
+ }
+ else if(shouldgrab) inputgrab(grabinput = true);
+ break;
+
+ case SDL_MOUSEBUTTONDOWN:
+ case SDL_MOUSEBUTTONUP:
+ //if(lasttype==event.type && lastbut==event.button.button) break; // why?? get event twice without it
+ switch(event.button.button)
+ {
+ case SDL_BUTTON_LEFT: processkey(-1, event.button.state==SDL_PRESSED); break;
+ case SDL_BUTTON_MIDDLE: processkey(-2, event.button.state==SDL_PRESSED); break;
+ case SDL_BUTTON_RIGHT: processkey(-3, event.button.state==SDL_PRESSED); break;
+ case SDL_BUTTON_X1: processkey(-6, event.button.state==SDL_PRESSED); break;
+ case SDL_BUTTON_X2: processkey(-7, event.button.state==SDL_PRESSED); break;
+ }
+ //lasttype = event.type;
+ //lastbut = event.button.button;
+ break;
+
+ case SDL_MOUSEWHEEL:
+ if(event.wheel.y > 0) { processkey(-4, true); processkey(-4, false); }
+ else if(event.wheel.y < 0) { processkey(-5, true); processkey(-5, false); }
+ break;
+ }
+ }
+ if(focused) { if(grabinput != (focused>0)) inputgrab(grabinput = focused>0, shouldgrab); focused = 0; }
+ if(mousemoved) resetmousemotion();
}
void swapbuffers(bool overlay)
{
- gle::disable();
- SDL_GL_SwapWindow(screen);
+ gle::disable();
+ SDL_GL_SwapWindow(screen);
}
VAR(menufps, 0, 60, 1000);
@@ -1013,68 +992,26 @@ VARP(maxfps, 0, 200, 1000);
void limitfps(int &millis, int curmillis)
{
- int limit = (mainmenu || minimized) && menufps ? (maxfps ? min(maxfps, menufps) : menufps) : maxfps;
- if(!limit) return;
- static int fpserror = 0;
- int delay = 1000/limit - (millis-curmillis);
- if(delay < 0) fpserror = 0;
- else
- {
- fpserror += 1000%limit;
- if(fpserror >= limit)
- {
- ++delay;
- fpserror -= limit;
- }
- if(delay > 0)
- {
- SDL_Delay(delay);
- millis += delay;
- }
- }
-}
-
-#if defined(WIN32) && !defined(_DEBUG) && !defined(__GNUC__)
-void stackdumper(unsigned int type, EXCEPTION_POINTERS *ep)
-{
- if(!ep) fatal("unknown type");
- EXCEPTION_RECORD *er = ep->ExceptionRecord;
- CONTEXT *context = ep->ContextRecord;
- char out[512];
- formatstring(out, "Cube 2: Sauerbraten Win32 Exception: 0x%x [0x%x]\n\n", er->ExceptionCode, er->ExceptionCode==EXCEPTION_ACCESS_VIOLATION ? er->ExceptionInformation[1] : -1);
- SymInitialize(GetCurrentProcess(), NULL, TRUE);
-#ifdef _AMD64_
- STACKFRAME64 sf = {{context->Rip, 0, AddrModeFlat}, {}, {context->Rbp, 0, AddrModeFlat}, {context->Rsp, 0, AddrModeFlat}, 0};
- while(::StackWalk64(IMAGE_FILE_MACHINE_AMD64, GetCurrentProcess(), GetCurrentThread(), &sf, context, NULL, ::SymFunctionTableAccess, ::SymGetModuleBase, NULL))
+ int limit = (mainmenu || minimized) && menufps ? (maxfps ? min(maxfps, menufps) : menufps) : maxfps;
+ if(!limit) return;
+ static int fpserror = 0;
+ int delay = 1000/limit - (millis-curmillis);
+ if(delay < 0) fpserror = 0;
+ else
{
- union { IMAGEHLP_SYMBOL64 sym; char symext[sizeof(IMAGEHLP_SYMBOL64) + sizeof(string)]; };
- sym.SizeOfStruct = sizeof(sym);
- sym.MaxNameLength = sizeof(symext) - sizeof(sym);
- IMAGEHLP_LINE64 line;
- line.SizeOfStruct = sizeof(line);
- DWORD64 symoff;
- DWORD lineoff;
- if(SymGetSymFromAddr64(GetCurrentProcess(), sf.AddrPC.Offset, &symoff, &sym) && SymGetLineFromAddr64(GetCurrentProcess(), sf.AddrPC.Offset, &lineoff, &line))
-#else
- STACKFRAME sf = {{context->Eip, 0, AddrModeFlat}, {}, {context->Ebp, 0, AddrModeFlat}, {context->Esp, 0, AddrModeFlat}, 0};
- while(::StackWalk(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(), &sf, context, NULL, ::SymFunctionTableAccess, ::SymGetModuleBase, NULL))
- {
- union { IMAGEHLP_SYMBOL sym; char symext[sizeof(IMAGEHLP_SYMBOL) + sizeof(string)]; };
- sym.SizeOfStruct = sizeof(sym);
- sym.MaxNameLength = sizeof(symext) - sizeof(sym);
- IMAGEHLP_LINE line;
- line.SizeOfStruct = sizeof(line);
- DWORD symoff, lineoff;
- if(SymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset, &symoff, &sym) && SymGetLineFromAddr(GetCurrentProcess(), sf.AddrPC.Offset, &lineoff, &line))
-#endif
- {
- char *del = strrchr(line.FileName, '\\');
- concformatstring(out, "%s - %s [%d]\n", sym.Name, del ? del + 1 : line.FileName, line.LineNumber);
- }
- }
- fatal(out);
+ fpserror += 1000%limit;
+ if(fpserror >= limit)
+ {
+ ++delay;
+ fpserror -= limit;
+ }
+ if(delay > 0)
+ {
+ SDL_Delay(delay);
+ millis += delay;
+ }
+ }
}
-#endif
#define MAXFPSHISTORY 60
@@ -1082,38 +1019,38 @@ int fpspos = 0, fpshistory[MAXFPSHISTORY];
void resetfpshistory()
{
- loopi(MAXFPSHISTORY) fpshistory[i] = 1;
- fpspos = 0;
+ loopi(MAXFPSHISTORY) fpshistory[i] = 1;
+ fpspos = 0;
}
void updatefpshistory(int millis)
{
- fpshistory[fpspos++] = max(1, min(1000, millis));
- if(fpspos>=MAXFPSHISTORY) fpspos = 0;
+ fpshistory[fpspos++] = max(1, min(1000, millis));
+ if(fpspos>=MAXFPSHISTORY) fpspos = 0;
}
void getfps(int &fps, int &bestdiff, int &worstdiff)
{
- int total = fpshistory[MAXFPSHISTORY-1], best = total, worst = total;
- loopi(MAXFPSHISTORY-1)
- {
- int millis = fpshistory[i];
- total += millis;
- if(millis < best) best = millis;
- if(millis > worst) worst = millis;
- }
-
- fps = (1000*MAXFPSHISTORY)/total;
- bestdiff = 1000/best-fps;
- worstdiff = fps-1000/worst;
+ int total = fpshistory[MAXFPSHISTORY-1], best = total, worst = total;
+ loopi(MAXFPSHISTORY-1)
+ {
+ int millis = fpshistory[i];
+ total += millis;
+ if(millis < best) best = millis;
+ if(millis > worst) worst = millis;
+ }
+
+ fps = (1000*MAXFPSHISTORY)/total;
+ bestdiff = 1000/best-fps;
+ worstdiff = fps-1000/worst;
}
void getfps_(int *raw)
{
- int fps, bestdiff, worstdiff;
- if(*raw) fps = 1000/fpshistory[(fpspos+MAXFPSHISTORY-1)%MAXFPSHISTORY];
- else getfps(fps, bestdiff, worstdiff);
- intret(fps);
+ int fps, bestdiff, worstdiff;
+ if(*raw) fps = 1000/fpshistory[(fpspos+MAXFPSHISTORY-1)%MAXFPSHISTORY];
+ else getfps(fps, bestdiff, worstdiff);
+ intret(fps);
}
COMMANDN(getfps, getfps_, "i");
@@ -1122,8 +1059,8 @@ bool inbetweenframes = false, renderedframe = true;
static bool findarg(int argc, char **argv, const char *str)
{
- for(int i = 1; i<argc; i++) if(strstr(argv[i], str)==argv[i]) return true;
- return false;
+ for(int i = 1; i<argc; i++) if(strstr(argv[i], str)==argv[i]) return true;
+ return false;
}
static int clockrealbase = 0, clockvirtbase = 0;
@@ -1133,239 +1070,224 @@ VARFP(clockfix, 0, 0, 1, clockreset());
int getclockmillis()
{
- int millis = SDL_GetTicks() - clockrealbase;
- if(clockfix) millis = int(millis*(double(clockerror)/1000000));
- millis += clockvirtbase;
- return max(millis, totalmillis);
+ int millis = SDL_GetTicks() - clockrealbase;
+ if(clockfix) millis = int(millis*(double(clockerror)/1000000));
+ millis += clockvirtbase;
+ return max(millis, totalmillis);
}
VAR(numcpus, 1, 1, 16);
int main(int argc, char **argv)
{
- #ifdef WIN32
- //atexit((void (__cdecl *)(void))_CrtDumpMemoryLeaks);
- #ifndef _DEBUG
- #ifndef __GNUC__
- __try {
- #endif
- #endif
- #endif
-
- setlogfile(NULL);
-
- int dedicated = 0;
- char *load = NULL, *initscript = NULL;
-
- initing = INIT_RESET;
- // set home dir first
- for(int i = 1; i<argc; i++) if(argv[i][0]=='-' && argv[i][1] == 'q') { sethomedir(&argv[i][2]); break; }
- // set log after home dir, but before anything else
- for(int i = 1; i<argc; i++) if(argv[i][0]=='-' && argv[i][1] == 'g')
- {
- const char *file = argv[i][2] ? &argv[i][2] : "log.txt";
- setlogfile(file);
- logoutf("Setting log file: %s", file);
- break;
- }
- execfile("init.cfg", false);
- for(int i = 1; i<argc; i++)
- {
- if(argv[i][0]=='-') switch(argv[i][1])
- {
- case 'q': if(homedir[0]) logoutf("Using home directory: %s", homedir); break;
- case 'r': /* compat, ignore */ break;
- case 'k':
- {
- const char *dir = addpackagedir(&argv[i][2]);
- if(dir) logoutf("Adding package directory: %s", dir);
- break;
- }
- case 'g': break;
- case 'd': dedicated = atoi(&argv[i][2]); if(dedicated<=0) dedicated = 2; break;
- case 'w': scr_w = clamp(atoi(&argv[i][2]), SCR_MINW, SCR_MAXW); if(!findarg(argc, argv, "-h")) scr_h = -1; break;
- case 'h': scr_h = clamp(atoi(&argv[i][2]), SCR_MINH, SCR_MAXH); if(!findarg(argc, argv, "-w")) scr_w = -1; break;
- case 'z': depthbits = atoi(&argv[i][2]); break;
- case 'b': /* compat, ignore */ break;
- case 'a': fsaa = atoi(&argv[i][2]); break;
- case 'v': /* compat, ignore */ break;
- case 't': fullscreen = atoi(&argv[i][2]); break;
- case 's': /* compat, ignore */ break;
- case 'f': /* compat, ignore */ break;
- case 'l':
- {
- char pkgdir[] = "packages/";
- load = strstr(path(&argv[i][2]), path(pkgdir));
- if(load) load += sizeof(pkgdir)-1;
- else load = &argv[i][2];
- break;
- }
- case 'x': initscript = &argv[i][2]; break;
- default: if(!serveroption(argv[i])) gameargs.add(argv[i]); break;
- }
- else gameargs.add(argv[i]);
- }
- initing = NOT_INITING;
-
- numcpus = clamp(SDL_GetCPUCount(), 1, 16);
-
- if(dedicated <= 1)
- {
- logoutf("init: sdl");
-
- if(SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_AUDIO)<0) fatal("Unable to initialize SDL: %s", SDL_GetError());
+ setlogfile(NULL);
+
+ int dedicated = 0;
+ char *load = NULL, *initscript = NULL;
+
+ initing = INIT_RESET;
+ // set home dir first
+ for(int i = 1; i<argc; i++) if(argv[i][0]=='-' && argv[i][1] == 'q') { sethomedir(&argv[i][2]); break; }
+ // set log after home dir, but before anything else
+ for(int i = 1; i<argc; i++) if(argv[i][0]=='-' && argv[i][1] == 'g')
+ {
+ const char *file = argv[i][2] ? &argv[i][2] : "log.txt";
+ setlogfile(file);
+ logoutf("Setting log file: %s", file);
+ break;
+ }
+ execfile("init.cfg", false);
+ for(int i = 1; i<argc; i++)
+ {
+ if(argv[i][0]=='-') switch(argv[i][1])
+ {
+ case 'q': if(homedir[0]) logoutf("Using home directory: %s", homedir); break;
+ case 'r': /* compat, ignore */ break;
+ case 'k':
+ {
+ const char *dir = addpackagedir(&argv[i][2]);
+ if(dir) logoutf("Adding package directory: %s", dir);
+ break;
+ }
+ case 'g': break;
+ case 'd': dedicated = atoi(&argv[i][2]); if(dedicated<=0) dedicated = 2; break;
+ case 'w': scr_w = clamp(atoi(&argv[i][2]), SCR_MINW, SCR_MAXW); if(!findarg(argc, argv, "-h")) scr_h = -1; break;
+ case 'h': scr_h = clamp(atoi(&argv[i][2]), SCR_MINH, SCR_MAXH); if(!findarg(argc, argv, "-w")) scr_w = -1; break;
+ case 'z': depthbits = atoi(&argv[i][2]); break;
+ case 'b': /* compat, ignore */ break;
+ case 'a': fsaa = atoi(&argv[i][2]); break;
+ case 'v': /* compat, ignore */ break;
+ case 't': fullscreen = atoi(&argv[i][2]); break;
+ case 's': /* compat, ignore */ break;
+ case 'f': /* compat, ignore */ break;
+ case 'l':
+ {
+ char pkgdir[] = "packages/";
+ load = strstr(path(&argv[i][2]), path(pkgdir));
+ if(load) load += sizeof(pkgdir)-1;
+ else load = &argv[i][2];
+ break;
+ }
+ case 'x': initscript = &argv[i][2]; break;
+ default: if(!serveroption(argv[i])) gameargs.add(argv[i]); break;
+ }
+ else gameargs.add(argv[i]);
+ }
+ initing = NOT_INITING;
+
+ numcpus = clamp(SDL_GetCPUCount(), 1, 16);
+
+ if(dedicated <= 1)
+ {
+ logoutf("init: sdl");
+
+ if(SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_AUDIO)<0) fatal("Unable to initialize SDL: %s", SDL_GetError());
#ifdef SDL_VIDEO_DRIVER_X11
- SDL_version version;
- SDL_GetVersion(&version);
- if (SDL_VERSIONNUM(version.major, version.minor, version.patch) <= SDL_VERSIONNUM(2, 0, 12))
- sdl_xgrab_bug = 1;
+ SDL_version version;
+ SDL_GetVersion(&version);
+ if (SDL_VERSIONNUM(version.major, version.minor, version.patch) <= SDL_VERSIONNUM(2, 0, 12))
+ sdl_xgrab_bug = 1;
#endif
- }
-
- logoutf("init: net");
- if(enet_initialize()<0) fatal("Unable to initialise network module");
- atexit(enet_deinitialize);
- enet_time_set(0);
-
- logoutf("init: game");
- game::parseoptions(gameargs);
- initserver(dedicated>0, dedicated>1); // never returns if dedicated
- ASSERT(dedicated <= 1);
- game::initclient();
-
- logoutf("init: video");
- SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "0");
- #if !defined(WIN32) && !defined(__APPLE__)
- SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
- #endif
- setupscreen();
- SDL_ShowCursor(SDL_FALSE);
- SDL_StopTextInput(); // workaround for spurious text-input events getting sent on first text input toggle?
-
- logoutf("init: gl");
- gl_checkextensions();
- gl_init();
- notexture = textureload("packages/textures/texture_error.png");
- if(!notexture) fatal("could not find core textures");
-
- logoutf("init: console");
- if(!execfile("data/stdlib.cfg", false)) fatal("cannot find data files (you are running from the wrong folder, try .bat file in the main folder)"); // this is the first file we load.
- if(!execfile("packages/fonts/default.cfg", false)) fatal("cannot find font definitions");
- if(!setfont("default")) fatal("no default font specified");
-
- inbetweenframes = true;
- renderbackground("initializing...");
-
- logoutf("init: world");
- camera1 = player = game::iterdynents(0);
- emptymap(0, true, NULL, false);
-
- logoutf("init: sound");
- initsound();
-
- logoutf("init: cfg");
- initing = INIT_LOAD;
- execfile("data/keymap.cfg");
- execfile("data/stdedit.cfg");
- execfile("data/sounds.cfg");
- execfile("data/menus.cfg");
- execfile("data/heightmap.cfg");
- execfile("data/brushes.cfg");
- execfile("data/game.cfg");
- execfile("data/custom_maps_menu.cfg");
- if(game::savedservers()) execfile(game::savedservers(), false);
-
- identflags |= IDF_PERSIST;
-
- if(!execfile(game::savedconfig(), false))
- {
- execfile(game::defaultconfig());
- writecfg(game::restoreconfig());
- }
- execfile(game::autoexec(), false);
-
- identflags &= ~IDF_PERSIST;
-
- initing = INIT_GAME;
- game::loadconfigs();
-
- initing = NOT_INITING;
-
- logoutf("init: render");
- restoregamma();
- restorevsync();
- loadshaders();
- initparticles();
- initdecals();
-
- identflags |= IDF_PERSIST;
-
- logoutf("init: mainloop");
-
- if(execfile("once.cfg", false)) remove(findfile("once.cfg", "rb"));
-
- if(load)
- {
- logoutf("init: localconnect");
- //localconnect();
- game::changemap(load);
- }
-
- if(initscript) execute(initscript);
-
- resetfpshistory();
-
- inputgrab(grabinput = true);
- ignoremousemotion();
-
- for(;;)
- {
- static int frames = 0;
- int millis = getclockmillis();
- limitfps(millis, totalmillis);
- elapsedtime = millis - totalmillis;
- static int timeerr = 0;
- int scaledtime = game::scaletime(elapsedtime) + timeerr;
- curtime = scaledtime/100;
- timeerr = scaledtime%100;
- if(!multiplayer(false) && curtime>200) curtime = 200;
- if(game::ispaused()) curtime = 0;
- lastmillis += curtime;
- totalmillis = millis;
- updatetime();
+ }
+
+ logoutf("init: net");
+ if(enet_initialize()<0) fatal("Unable to initialise network module");
+ atexit(enet_deinitialize);
+ enet_time_set(0);
+
+ logoutf("init: game");
+ game::parseoptions(gameargs);
+ initserver(dedicated>0, dedicated>1); // never returns if dedicated
+ ASSERT(dedicated <= 1);
+ game::initclient();
+
+ logoutf("init: video");
+ SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "0");
+ SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
+ setupscreen();
+ SDL_ShowCursor(SDL_FALSE);
+ SDL_StopTextInput(); // workaround for spurious text-input events getting sent on first text input toggle?
+
+ logoutf("init: gl");
+ gl_checkextensions();
+ gl_init();
+ notexture = textureload("packages/textures/texture_error.png");
+ if(!notexture) fatal("could not find core textures");
+
+ logoutf("init: console");
+ if(!execfile("data/stdlib.cfg", false)) fatal("cannot find data files (you are running from the wrong folder, try .bat file in the main folder)"); // this is the first file we load.
+ if(!execfile("packages/fonts/default.cfg", false)) fatal("cannot find font definitions");
+ if(!setfont("default")) fatal("no default font specified");
+
+ inbetweenframes = true;
+ renderbackground("initializing...");
+
+ logoutf("init: world");
+ camera1 = player = game::iterdynents(0);
+ emptymap(0, true, NULL, false);
+
+ logoutf("init: sound");
+ initsound();
+
+ logoutf("init: cfg");
+ initing = INIT_LOAD;
+ execfile("data/keymap.cfg");
+ execfile("data/stdedit.cfg");
+ execfile("data/sounds.cfg");
+ execfile("data/menus.cfg");
+ execfile("data/heightmap.cfg");
+ execfile("data/brushes.cfg");
+ execfile("data/game.cfg");
+ execfile("data/custom_maps_menu.cfg");
+ if(game::savedservers()) execfile(game::savedservers(), false);
+
+ identflags |= IDF_PERSIST;
+
+ if(!execfile(game::savedconfig(), false))
+ {
+ execfile(game::defaultconfig());
+ writecfg(game::restoreconfig());
+ }
+ execfile(game::autoexec(), false);
+
+ identflags &= ~IDF_PERSIST;
+
+ initing = INIT_GAME;
+ game::loadconfigs();
+
+ initing = NOT_INITING;
+
+ logoutf("init: render");
+ restoregamma();
+ restorevsync();
+ loadshaders();
+ initparticles();
+ initdecals();
+
+ identflags |= IDF_PERSIST;
- checkinput();
- menuprocess();
- tryedit();
+ logoutf("init: mainloop");
+
+ if(execfile("once.cfg", false)) remove(findfile("once.cfg", "rb"));
+
+ if(load)
+ {
+ logoutf("init: localconnect");
+ //localconnect();
+ game::changemap(load);
+ }
+
+ if(initscript) execute(initscript);
+
+ resetfpshistory();
+
+ inputgrab(grabinput = true);
+ ignoremousemotion();
+
+ for(;;)
+ {
+ static int frames = 0;
+ int millis = getclockmillis();
+ limitfps(millis, totalmillis);
+ elapsedtime = millis - totalmillis;
+ static int timeerr = 0;
+ int scaledtime = game::scaletime(elapsedtime) + timeerr;
+ curtime = scaledtime/100;
+ timeerr = scaledtime%100;
+ if(!multiplayer(false) && curtime>200) curtime = 200;
+ if(game::ispaused()) curtime = 0;
+ lastmillis += curtime;
+ totalmillis = millis;
+ updatetime();
- if(lastmillis) game::updateworld();
+ checkinput();
+ menuprocess();
+ tryedit();
- checksleep(lastmillis);
+ if(lastmillis) game::updateworld();
- serverslice(false, 0);
+ checksleep(lastmillis);
- if(frames) updatefpshistory(elapsedtime);
- frames++;
+ serverslice(false, 0);
- // miscellaneous general game effects
- recomputecamera();
- updateparticles();
- updatesounds();
+ if(frames) updatefpshistory(elapsedtime);
+ frames++;
- if(minimized) continue;
+ // miscellaneous general game effects
+ recomputecamera();
+ updateparticles();
+ updatesounds();
- inbetweenframes = false;
- if(mainmenu) gl_drawmainmenu();
- else gl_drawframe();
- swapbuffers();
- renderedframe = inbetweenframes = true;
- }
+ if(minimized) continue;
- ASSERT(0);
- return EXIT_FAILURE;
+ inbetweenframes = false;
+ if(mainmenu) gl_drawmainmenu();
+ else gl_drawframe();
+ swapbuffers();
+ renderedframe = inbetweenframes = true;
+ }
- #if defined(WIN32) && !defined(_DEBUG) && !defined(__GNUC__)
- } __except(stackdumper(0, GetExceptionInformation()), EXCEPTION_CONTINUE_SEARCH) { return 0; }
- #endif
+ ASSERT(0);
+ return EXIT_FAILURE;
}