summaryrefslogtreecommitdiff
path: root/src/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/3dgui.cpp645
-rw-r--r--src/engine/animmodel.h817
-rw-r--r--src/engine/bih.cpp129
-rw-r--r--src/engine/bih.h33
-rw-r--r--src/engine/client.cpp118
-rw-r--r--src/engine/command.cpp1301
-rw-r--r--src/engine/console.cpp319
-rw-r--r--src/engine/decal.cpp281
-rw-r--r--src/engine/dynlight.cpp86
-rw-r--r--src/engine/engine.h29
-rw-r--r--src/engine/explosion.h179
-rw-r--r--src/engine/iqm.h147
-rw-r--r--src/engine/lightmap.cpp849
-rw-r--r--src/engine/lightmap.h56
-rw-r--r--src/engine/lightning.h123
-rw-r--r--src/engine/main.cpp464
-rw-r--r--src/engine/master.cpp299
-rw-r--r--src/engine/material.cpp180
-rw-r--r--src/engine/md3.h183
-rw-r--r--src/engine/md5.h214
-rw-r--r--src/engine/menus.cpp357
-rw-r--r--src/engine/model.h53
-rw-r--r--src/engine/mpr.h280
-rw-r--r--src/engine/normal.cpp151
-rw-r--r--src/engine/octa.cpp808
-rw-r--r--src/engine/octa.h93
-rw-r--r--src/engine/octaedit.cpp1033
-rw-r--r--src/engine/octarender.cpp667
-rw-r--r--src/engine/physics.cpp773
-rw-r--r--src/engine/ragdoll.h215
-rw-r--r--src/engine/rendergl.cpp516
-rw-r--r--src/engine/rendermodel.cpp450
-rw-r--r--src/engine/renderparticles.cpp675
-rw-r--r--src/engine/rendertarget.h181
-rw-r--r--src/engine/rendertext.cpp131
-rw-r--r--src/engine/renderva.cpp618
-rw-r--r--src/engine/server.cpp349
-rw-r--r--src/engine/serverbrowser.cpp310
-rw-r--r--src/engine/shader.cpp448
-rw-r--r--src/engine/shadowmap.cpp100
-rw-r--r--src/engine/skelmodel.h975
-rw-r--r--src/engine/sound.cpp395
-rw-r--r--src/engine/textedit.h337
-rw-r--r--src/engine/texture.cpp1123
-rw-r--r--src/engine/texture.h294
-rw-r--r--src/engine/vertmodel.h490
-rw-r--r--src/engine/world.cpp520
-rw-r--r--src/engine/world.h10
-rw-r--r--src/engine/worldio.cpp369
49 files changed, 5432 insertions, 13741 deletions
diff --git a/src/engine/3dgui.cpp b/src/engine/3dgui.cpp
index 1e17e78..201f9e3 100644
--- a/src/engine/3dgui.cpp
+++ b/src/engine/3dgui.cpp
@@ -36,75 +36,55 @@ VARP(guipreviewtime, 0, 15, 1000);
static int lastpreview = 0;
-static inline bool throttlepreview(bool loaded)
-{
+static inline bool throttlepreview(bool loaded) {
if(loaded) return true;
if(totalmillis - lastpreview < guipreviewtime) return false;
lastpreview = totalmillis;
return true;
}
-struct gui : g3d_gui
-{
- struct list
- {
+struct gui : g3d_gui {
+ struct list {
int parent, w, h, springs, curspring, column;
};
-
int firstlist, nextlist;
int columns[MAXCOLUMNS];
-
static vector<list> lists;
static float hitx, hity;
static int curdepth, curlist, xsize, ysize, curx, cury;
static bool shouldmergehits, shouldautotab;
-
- static void reset()
- {
+ static void reset() {
lists.setsize(0);
}
-
static int ty, tx, tpos, *tcurrent, tcolor; //tracking tab size and position since uses different layout method...
-
- bool allowautotab(bool on)
- {
+ bool allowautotab(bool on) {
bool oldval = shouldautotab;
shouldautotab = on;
return oldval;
}
-
- void autotab()
- {
- if(tcurrent)
- {
+ void autotab() {
+ if(tcurrent) {
if(layoutpass && !tpos) tcurrent = NULL; //disable tabs because you didn't start with one
if(shouldautotab && !curdepth && (layoutpass ? 0 : cury) + ysize > guiautotab*FONTH) tab(NULL, tcolor);
}
}
-
- bool shouldtab()
- {
- if(tcurrent && shouldautotab)
- {
- if(layoutpass)
- {
+ bool shouldtab() {
+ if(tcurrent && shouldautotab) {
+ if(layoutpass) {
int space = guiautotab*FONTH - ysize;
if(space < 0) return true;
int l = lists[curlist].parent;
- while(l >= 0)
- {
+ while(l >= 0) {
space -= lists[l].h;
if(space < 0) return true;
l = lists[l].parent;
}
}
- else
- {
+ else {
int space = guiautotab*FONTH - cury;
if(ysize > space) return true;
int l = lists[curlist].parent;
- while(l >= 0)
- {
+ while(l >= 0) {
if(lists[l].h > space) return true;
l = lists[l].parent;
}
@@ -112,24 +92,19 @@ struct gui : g3d_gui
}
return false;
}
-
bool visible() { return (!tcurrent || tpos==*tcurrent) && !layoutpass; }
-
//tab is always at top of page
- void tab(const char *name, int color)
- {
+ void tab(const char *name, int color) {
if(curdepth != 0) return;
if(color) tcolor = color;
tpos++;
if(!name) name = intstr(tpos);
int w = max(text_width(name) - 2*INSERT, 0);
- if(layoutpass)
- {
+ if(layoutpass) {
ty = max(ty, ysize);
ysize = 0;
}
- else
- {
+ else {
cury = -ysize;
int h = FONTH-2*INSERT,
x1 = curx + tx,
@@ -139,22 +114,16 @@ struct gui : g3d_gui
bool hit = tcurrent && windowhit==this && hitx>=x1 && hity>=y1 && hitx<x2 && hity<y2;
if(hit && (!guiclicktab || mousebuttons&G3D_DOWN))
*tcurrent = tpos; //roll-over to switch tab
-
drawskin(x1-skinx[visible()?2:6]*SKIN_SCALE, y1-skiny[1]*SKIN_SCALE, w, h, visible()?10:19, 9, gui2d ? 1 : 2, light, alpha);
text_(name, x1 + (skinx[3]-skinx[2])*SKIN_SCALE - (w ? INSERT : INSERT/2), y1 + (skiny[2]-skiny[1])*SKIN_SCALE - INSERT, tcolor, visible());
}
tx += w + ((skinx[5]-skinx[4]) + (skinx[3]-skinx[2]))*SKIN_SCALE;
}
-
bool ishorizontal() const { return curdepth&1; }
bool isvertical() const { return !ishorizontal(); }
-
- void pushlist()
- {
- if(layoutpass)
- {
- if(curlist>=0)
- {
+ void pushlist() {
+ if(layoutpass) {
+ if(curlist>=0) {
lists[curlist].w = xsize;
lists[curlist].h = ysize;
}
@@ -165,11 +134,9 @@ struct gui : g3d_gui
curlist = lists.length()-1;
xsize = ysize = 0;
}
- else
- {
+ else {
curlist = nextlist++;
- if(curlist >= lists.length()) // should never get here unless script code doesn't use same amount of lists in layout and render passes
- {
+ if(curlist >= lists.length()) { // should never get here unless script code doesn't use same amount of lists in layout and render passes {
list &l = lists.add();
l.parent = curlist;
l.springs = 0;
@@ -178,155 +145,121 @@ struct gui : g3d_gui
}
list &l = lists[curlist];
l.curspring = 0;
- if(l.springs > 0)
- {
+ if(l.springs > 0) {
if(ishorizontal()) xsize = l.w; else ysize = l.h;
}
- else
- {
+ else {
xsize = l.w;
ysize = l.h;
}
}
curdepth++;
}
-
- void poplist()
- {
+ void poplist() {
if(!lists.inrange(curlist)) return;
list &l = lists[curlist];
- if(layoutpass)
- {
+ if(layoutpass) {
l.w = xsize;
l.h = ysize;
if(l.column >= 0) columns[l.column] = max(columns[l.column], ishorizontal() ? ysize : xsize);
}
curlist = l.parent;
curdepth--;
- if(lists.inrange(curlist))
- {
+ if(lists.inrange(curlist)) {
int w = xsize, h = ysize;
if(ishorizontal()) cury -= h; else curx -= w;
list &p = lists[curlist];
xsize = p.w;
ysize = p.h;
- if(!layoutpass && p.springs > 0)
- {
+ if(!layoutpass && p.springs > 0) {
list &s = lists[p.parent];
if(ishorizontal()) xsize = s.w; else ysize = s.h;
}
layout(w, h);
}
}
-
int text (const char *text, int color, const char *icon) { autotab(); return button_(text, color, icon, false, false); }
int button(const char *text, int color, const char *icon) { autotab(); return button_(text, color, icon, true, false); }
int title (const char *text, int color, const char *icon) { autotab(); return button_(text, color, icon, false, true); }
-
void separator() { autotab(); line_(FONTH/3); }
void progress(float percent) { autotab(); line_((FONTH*4)/5, percent); }
-
//use to set min size (useful when you have progress bars)
void strut(float size) { layout(isvertical() ? int(size*FONTW) : 0, isvertical() ? 0 : int(size*FONTH)); }
//add space between list items
void space(float size) { layout(isvertical() ? 0 : int(size*FONTW), isvertical() ? int(size*FONTH) : 0); }
-
- void spring(int weight)
- {
+ void spring(int weight) {
if(curlist < 0) return;
list &l = lists[curlist];
if(layoutpass) { if(l.parent >= 0) l.springs += weight; return; }
int nextspring = min(l.curspring + weight, l.springs);
if(nextspring <= l.curspring) return;
- if(ishorizontal())
- {
+ if(ishorizontal()) {
int w = xsize - l.w;
layout((w*nextspring)/l.springs - (w*l.curspring)/l.springs, 0);
}
- else
- {
+ else {
int h = ysize - l.h;
layout(0, (h*nextspring)/l.springs - (h*l.curspring)/l.springs);
}
l.curspring = nextspring;
}
-
- void column(int col)
- {
+ void column(int col) {
if(curlist < 0 || !layoutpass || col < 0 || col >= MAXCOLUMNS) return;
list &l = lists[curlist];
l.column = col;
}
-
- int layout(int w, int h)
- {
- if(layoutpass)
- {
- if(ishorizontal())
- {
+ int layout(int w, int h) {
+ if(layoutpass) {
+ if(ishorizontal()) {
xsize += w;
ysize = max(ysize, h);
}
- else
- {
+ else {
xsize = max(xsize, w);
ysize += h;
}
return 0;
}
- else
- {
+ else {
bool hit = ishit(w, h);
if(ishorizontal()) curx += w;
else cury += h;
return (hit && visible()) ? mousebuttons|G3D_ROLLOVER : 0;
}
}
-
- bool mergehits(bool on)
- {
+ bool mergehits(bool on) {
bool oldval = shouldmergehits;
shouldmergehits = on;
return oldval;
}
-
- bool ishit(int w, int h, int x = curx, int y = cury)
- {
+ bool ishit(int w, int h, int x = curx, int y = cury) {
if(shouldmergehits) return windowhit==this && (ishorizontal() ? hitx>=x && hitx<x+w : hity>=y && hity<y+h);
if(ishorizontal()) h = ysize;
else w = xsize;
return windowhit==this && hitx>=x && hity>=y && hitx<x+w && hity<y+h;
}
-
- int image(Texture *t, float scale, const char *overlaid)
- {
+ int image(Texture *t, float scale, const char *overlaid) {
autotab();
if(scale==0) scale = 1;
int size = (int)(scale*2*FONTH)-SHADOW;
if(visible()) icon_(t, overlaid!=NULL, curx, cury, size, ishit(size+SHADOW, size+SHADOW), overlaid);
return layout(size+SHADOW, size+SHADOW);
}
-
- int texture(VSlot &vslot, float scale, bool overlaid)
- {
+ int texture(VSlot &vslot, float scale, bool overlaid) {
autotab();
if(scale==0) scale = 1;
int size = (int)(scale*2*FONTH)-SHADOW;
if(visible()) previewslot(vslot, overlaid, curx, cury, size, ishit(size+SHADOW, size+SHADOW));
return layout(size+SHADOW, size+SHADOW);
}
-
- int playerpreview(int model, int team, int weap, float sizescale, const char *overlaid)
- {
+ int playerpreview(int model, int team, int weap, float sizescale, const char *overlaid) {
autotab();
if(sizescale==0) sizescale = 1;
int size = (int)(sizescale*2*FONTH)-SHADOW;
- if(model>=0 && visible())
- {
+ if(model>=0 && visible()) {
bool hit = ishit(size+SHADOW, size+SHADOW);
float xs = size, ys = size, xi = curx, yi = cury;
- if(overlaid && hit && actionon)
- {
+ if(overlaid && hit && actionon) {
hudnotextureshader->set();
gle::colorf(0, 0, 0, 0.75f);
rect_(xi+SHADOW, yi+SHADOW, xs, ys);
@@ -341,10 +274,8 @@ struct gui : g3d_gui
hudshader->set();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
- if(overlaid)
- {
- if(hit)
- {
+ if(overlaid) {
+ if(hit) {
hudnotextureshader->set();
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
gle::colorf(1, 0.5f, 0.5f);
@@ -361,18 +292,14 @@ struct gui : g3d_gui
}
return layout(size+SHADOW, size+SHADOW);
}
-
- int modelpreview(const char *name, int anim, float sizescale, const char *overlaid, bool throttle)
- {
+ int modelpreview(const char *name, int anim, float sizescale, const char *overlaid, bool throttle) {
autotab();
if(sizescale==0) sizescale = 1;
int size = (int)(sizescale*2*FONTH)-SHADOW;
- if(name[0] && visible() && (!throttle || throttlepreview(modelloaded(name))))
- {
+ if(name[0] && visible() && (!throttle || throttlepreview(modelloaded(name)))) {
bool hit = ishit(size+SHADOW, size+SHADOW);
float xs = size, ys = size, xi = curx, yi = cury;
- if(overlaid && hit && actionon)
- {
+ if(overlaid && hit && actionon) {
hudnotextureshader->set();
gle::colorf(0, 0, 0, 0.75f);
rect_(xi+SHADOW, yi+SHADOW, xs, ys);
@@ -383,8 +310,7 @@ struct gui : g3d_gui
glDisable(GL_BLEND);
modelpreview::start(x1, y1, x2-x1, y2-y1, overlaid!=NULL);
model *m = loadmodel(name);
- if(m)
- {
+ if(m) {
entitylight light;
light.color = vec(1, 1, 1);
light.dir = vec(0, -1, 2).normalize();
@@ -398,10 +324,8 @@ struct gui : g3d_gui
hudshader->set();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
- if(overlaid)
- {
- if(hit)
- {
+ if(overlaid) {
+ if(hit) {
hudnotextureshader->set();
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
gle::colorf(1, 0.5f, 0.5f);
@@ -418,18 +342,14 @@ struct gui : g3d_gui
}
return layout(size+SHADOW, size+SHADOW);
}
-
- int prefabpreview(const char *prefab, const vec &color, float sizescale, const char *overlaid, bool throttle)
- {
+ int prefabpreview(const char *prefab, const vec &color, float sizescale, const char *overlaid, bool throttle) {
autotab();
if(sizescale==0) sizescale = 1;
int size = (int)(sizescale*2*FONTH)-SHADOW;
- if(prefab[0] && visible() && (!throttle || throttlepreview(prefabloaded(prefab))))
- {
+ if(prefab[0] && visible() && (!throttle || throttlepreview(prefabloaded(prefab)))) {
bool hit = ishit(size+SHADOW, size+SHADOW);
float xs = size, ys = size, xi = curx, yi = cury;
- if(overlaid && hit && actionon)
- {
+ if(overlaid && hit && actionon) {
hudnotextureshader->set();
gle::colorf(0, 0, 0, 0.75f);
rect_(xi+SHADOW, yi+SHADOW, xs, ys);
@@ -444,10 +364,8 @@ struct gui : g3d_gui
hudshader->set();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
- if(overlaid)
- {
- if(hit)
- {
+ if(overlaid) {
+ if(hit) {
hudnotextureshader->set();
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
gle::colorf(1, 0.5f, 0.5f);
@@ -464,37 +382,29 @@ struct gui : g3d_gui
}
return layout(size+SHADOW, size+SHADOW);
}
-
- void slider(int &val, int vmin, int vmax, int color, const char *label)
- {
+ void slider(int &val, int vmin, int vmax, int color, const char *label) {
autotab();
int x = curx;
int y = cury;
line_((FONTH*2)/3);
- if(visible())
- {
+ if(visible()) {
if(!label) label = intstr(val);
int w = text_width(label);
-
bool hit;
int px, py, offset = vmin < vmax ? clamp(val, vmin, vmax) : clamp(val, vmax, vmin);
- if(ishorizontal())
- {
+ if(ishorizontal()) {
hit = ishit(FONTH, ysize, x, y);
px = x + (FONTH-w)/2;
py = y + (ysize-FONTH) - ((ysize-FONTH)*(offset-vmin))/((vmax==vmin) ? 1 : (vmax-vmin)); //vmin at bottom
}
- else
- {
+ else {
hit = ishit(xsize, FONTH, x, y);
px = x + FONTH/2 - w/2 + ((xsize-w)*(offset-vmin))/((vmax==vmin) ? 1 : (vmax-vmin)); //vmin at left
py = y;
}
-
if(hit) color = 0xFF0000;
text_(label, px, py, color, hit && actionon, hit);
- if(hit && actionon)
- {
+ if(hit && actionon) {
int vnew = (vmin < vmax ? 1 : -1)+vmax-vmin;
if(ishorizontal()) vnew = int((vnew*(y+ysize-FONTH/2-hity))/(ysize-FONTH));
else vnew = int((vnew*(hitx-x-FONTH/2))/(xsize-w));
@@ -504,32 +414,23 @@ struct gui : g3d_gui
}
}
}
-
- char *field(const char *name, int color, int length, int height, const char *initval, int initmode)
- {
+ char *field(const char *name, int color, int length, int height, const char *initval, int initmode) {
return field_(name, color, length, height, initval, initmode, FIELDEDIT);
}
-
- char *keyfield(const char *name, int color, int length, int height, const char *initval, int initmode)
- {
+ char *keyfield(const char *name, int color, int length, int height, const char *initval, int initmode) {
return field_(name, color, length, height, initval, initmode, FIELDKEY);
}
-
- char *field_(const char *name, int color, int length, int height, const char *initval, int initmode, int fieldtype = FIELDEDIT)
- {
+ char *field_(const char *name, int color, int length, int height, const char *initval, int initmode, int fieldtype = FIELDEDIT) {
editor *e = useeditor(name, initmode, false, initval); // generate a new editor if necessary
- if(layoutpass)
- {
- if(initval && e->mode==EDITORFOCUSED && (e!=currentfocus() || fieldmode == FIELDSHOW))
- {
+ if(layoutpass) {
+ if(initval && e->mode==EDITORFOCUSED && (e!=currentfocus() || fieldmode == FIELDSHOW)) {
if(strcmp(e->lines[0].text, initval)) e->clear(initval);
}
e->linewrap = (length<0);
e->maxx = (e->linewrap) ? -1 : length;
e->maxy = (height<=0)?1:-1;
e->pixelwidth = abs(length)*FONTW;
- if(e->linewrap && e->maxy==1)
- {
+ if(e->linewrap && e->maxy==1) {
int temp;
text_bounds(e->lines[0].text, temp, e->pixelheight, e->pixelwidth); //only single line editors can have variable height
}
@@ -538,20 +439,14 @@ struct gui : g3d_gui
}
int h = e->pixelheight;
int w = e->pixelwidth + FONTW;
-
bool wasvertical = isvertical();
if(wasvertical && e->maxy != 1) pushlist();
-
char *result = NULL;
- if(visible() && !layoutpass)
- {
+ if(visible() && !layoutpass) {
e->rendered = true;
-
bool hit = ishit(w, h);
- if(hit)
- {
- if(mousebuttons&G3D_DOWN) //mouse request focus
- {
+ if(hit) {
+ if(mousebuttons&G3D_DOWN) { //mouse request focus {
if(fieldtype==FIELDKEY) e->clear();
useeditor(name, initmode, true);
e->mark(false);
@@ -560,16 +455,13 @@ struct gui : g3d_gui
}
bool editing = (fieldmode != FIELDSHOW) && (e==currentfocus());
if(hit && editing && (mousebuttons&G3D_PRESSED)!=0 && fieldtype==FIELDEDIT) e->hit(int(floor(hitx-(curx+FONTW/2))), int(floor(hity-cury)), (mousebuttons&G3D_DRAGGED)!=0); //mouse request position
- if(editing && ((fieldmode==FIELDCOMMIT) || (fieldmode==FIELDABORT) || !hit)) // commit field if user pressed enter or wandered out of focus
- {
+ if(editing && ((fieldmode==FIELDCOMMIT) || (fieldmode==FIELDABORT) || !hit)) { // commit field if user pressed enter or wandered out of focus {
if(fieldmode==FIELDCOMMIT || (fieldmode!=FIELDABORT && !hit)) result = e->currentline().text;
e->active = (e->mode!=EDITORFOCUSED);
fieldmode = FIELDSHOW;
}
else fieldsactive = true;
-
e->draw(curx+FONTW/2, cury, color, hit && editing);
-
hudnotextureshader->set();
glDisable(GL_BLEND);
if(editing) gle::colorf(1, 0, 0);
@@ -579,24 +471,18 @@ struct gui : g3d_gui
hudshader->set();
}
layout(w, h);
-
- if(e->maxy != 1)
- {
+ if(e->maxy != 1) {
int slines = e->limitscrolly();
- if(slines > 0)
- {
+ if(slines > 0) {
int pos = e->scrolly;
slider(e->scrolly, slines, 0, color, NULL);
if(pos != e->scrolly) e->cy = e->scrolly;
}
if(wasvertical) poplist();
}
-
return result;
}
-
- void rect_(float x, float y, float w, float h, bool lines = false)
- {
+ void rect_(float x, float y, float w, float h, bool lines = false) {
gle::defvertex(2);
gle::begin(lines ? GL_LINE_LOOP : GL_TRIANGLE_STRIP);
gle::attribf(x, y);
@@ -606,9 +492,7 @@ struct gui : g3d_gui
if(!lines) gle::attribf(x + w, y + h);
xtraverts += gle::end();
}
-
- void rect_(float x, float y, float w, float h, int usetc)
- {
+ void rect_(float x, float y, float w, float h, int usetc) {
gle::defvertex(2);
gle::deftexcoord0();
gle::begin(GL_TRIANGLE_STRIP);
@@ -619,29 +503,23 @@ struct gui : g3d_gui
gle::attribf(x + w, y + h); gle::attrib(tc[usetc+2]);
xtraverts += gle::end();
}
-
- void text_(const char *text, int x, int y, int color, bool shadow, bool force = false)
- {
+ void text_(const char *text, int x, int y, int color, bool shadow, bool force = false) {
if(shadow) draw_text(text, x+SHADOW, y+SHADOW, 0x00, 0x00, 0x00, -0xC0);
draw_text(text, x, y, color>>16, (color>>8)&0xFF, color&0xFF, force ? -0xFF : 0xFF);
}
-
- void background(int color, int inheritw, int inherith)
- {
+ void background(int color, int inheritw, int inherith) {
if(layoutpass) return;
hudnotextureshader->set();
gle::colorub(color>>16, (color>>8)&0xFF, color&0xFF, 0x80);
int w = xsize, h = ysize;
- if(inheritw>0)
- {
+ if(inheritw>0) {
int parentw = curlist, parentdepth = 0;
for(;parentdepth < inheritw && lists[parentw].parent>=0; parentdepth++)
parentw = lists[parentw].parent;
list &p = lists[parentw];
w = p.springs > 0 && (curdepth-parentdepth)&1 ? lists[p.parent].w : p.w;
}
- if(inherith>0)
- {
+ if(inherith>0) {
int parenth = curlist, parentdepth = 0;
for(;parentdepth < inherith && lists[parenth].parent>=0; parentdepth++)
parenth = lists[parenth].parent;
@@ -651,25 +529,20 @@ struct gui : g3d_gui
rect_(curx, cury, w, h);
hudshader->set();
}
-
- void icon_(Texture *t, bool overlaid, int x, int y, int size, bool hit, const char *title = NULL)
- {
+ void icon_(Texture *t, bool overlaid, int x, int y, int size, bool hit, const char *title = NULL) {
float scale = float(size)/max(t->xs, t->ys); //scale and preserve aspect ratio
float xs = t->xs*scale, ys = t->ys*scale;
x += int((size-xs)/2);
y += int((size-ys)/2);
const vec &color = hit ? vec(1, 0.5f, 0.5f) : (overlaid ? vec(1, 1, 1) : light);
glBindTexture(GL_TEXTURE_2D, t->id);
- if(hit && actionon)
- {
+ if(hit && actionon) {
gle::colorf(0, 0, 0, 0.75f);
rect_(x+SHADOW, y+SHADOW, xs, ys, 0);
}
gle::color(color);
rect_(x, y, xs, ys, 0);
-
- if(overlaid)
- {
+ if(overlaid) {
if(!overlaytex) overlaytex = textureload("data/guioverlay.png", 3);
glBindTexture(GL_TEXTURE_2D, overlaytex->id);
gle::color(light);
@@ -677,20 +550,15 @@ struct gui : g3d_gui
if(title) text_(title, x + xs/12, y + ys - ys/12 - FONTH, hit ? 0xFF0000 : 0xFFFFFF, hit && actionon, hit);
}
}
-
- void previewslot(VSlot &vslot, bool overlaid, int x, int y, int size, bool hit)
- {
+ void previewslot(VSlot &vslot, bool overlaid, int x, int y, int size, bool hit) {
Slot &slot = *vslot.slot;
if(slot.sts.empty()) return;
VSlot *layer = NULL;
Texture *t = NULL, *layertex = NULL;
- if(slot.loaded)
- {
+ if(slot.loaded) {
t = slot.sts[0].t;
if(t == notexture) return;
- Slot &slot = *vslot.slot;
- if(vslot.layer)
- {
+ if(vslot.layer) {
layer = &lookupvslot(vslot.layer);
if(!layer->slot->sts.empty()) layertex = layer->slot->sts[0].t;
}
@@ -698,8 +566,7 @@ struct gui : g3d_gui
else if(slot.thumbnail && slot.thumbnail != notexture) t = slot.thumbnail;
else return;
float xt = min(1.0f, t->xs/(float)t->ys), yt = min(1.0f, t->ys/(float)t->xs), xs = size, ys = size;
- if(hit && actionon)
- {
+ if(hit && actionon) {
hudnotextureshader->set();
gle::colorf(0, 0, 0, 0.75f);
rect_(x+SHADOW, y+SHADOW, xs, ys);
@@ -711,8 +578,7 @@ struct gui : g3d_gui
const vec &color = hit ? vec(1, 0.5f, 0.5f) : (overlaid ? vec(1, 1, 1) : light);
vec2 tc[4] = { vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1) };
float xoff = vslot.offset.x, yoff = vslot.offset.y;
- if(vslot.rotation)
- {
+ if(vslot.rotation) {
const texrotation &r = texrotations[vslot.rotation];
if(r.swapxy) { swap(xoff, yoff); loopk(4) swap(tc[k].x, tc[k].y); }
if(r.flipx) { xoff *= -1; loopk(4) tc[k].x *= -1; }
@@ -728,8 +594,7 @@ struct gui : g3d_gui
gle::attribf(x, y+ys); gle::attrib(tc[3]);
gle::attribf(x+xs, y+ys); gle::attrib(tc[2]);
gle::end();
- if(layertex)
- {
+ if(layertex) {
glBindTexture(GL_TEXTURE_2D, layertex->id);
gle::color(vec(color).mul(layer->colorscale));
gle::begin(GL_TRIANGLE_STRIP);
@@ -739,25 +604,19 @@ struct gui : g3d_gui
gle::attribf(x+xs, y+ys); gle::attrib(tc[2]);
gle::end();
}
-
hudshader->set();
- if(overlaid)
- {
+ if(overlaid) {
if(!overlaytex) overlaytex = textureload("data/guioverlay.png", 3);
glBindTexture(GL_TEXTURE_2D, overlaytex->id);
gle::color(light);
rect_(x, y, xs, ys, 0);
}
}
-
- void line_(int size, float percent = 1.0f)
- {
- if(visible())
- {
+ void line_(int size, float percent = 1.0f) {
+ if(visible()) {
if(!slidertex) slidertex = textureload("data/guislider.png", 3);
glBindTexture(GL_TEXTURE_2D, slidertex->id);
- if(percent < 0.99f)
- {
+ if(percent < 0.99f) {
gle::colorf(light.x, light.y, light.z, 0.375f);
if(ishorizontal())
rect_(curx + FONTH/2 - size/2, cury, size, ysize, 0);
@@ -772,9 +631,7 @@ struct gui : g3d_gui
}
layout(ishorizontal() ? FONTH : 0, ishorizontal() ? 0 : FONTH);
}
-
- void textbox(const char *text, int width, int height, int color)
- {
+ void textbox(const char *text, int width, int height, int color) {
width *= FONTW;
height *= FONTH;
int w, h;
@@ -783,26 +640,19 @@ struct gui : g3d_gui
if(visible()) draw_text(text, curx, cury, color>>16, (color>>8)&0xFF, color&0xFF, 0xFF, -1, width);
layout(width, height);
}
-
- int button_(const char *text, int color, const char *icon, bool clickable, bool center)
- {
+ int button_(const char *text, int color, const char *icon, bool clickable, bool center) {
const int padding = 10;
int w = 0;
if(icon) w += ICON_SIZE;
if(icon && text) w += padding;
if(text) w += text_width(text);
-
- if(visible())
- {
+ if(visible()) {
bool hit = ishit(w, FONTH);
if(hit && clickable) color = 0xFF0000;
int x = curx;
if(isvertical() && center) x += (xsize-w)/2;
-
- if(icon)
- {
- if(icon[0] != ' ')
- {
+ if(icon) {
+ if(icon[0] != ' ') {
const char *ext = strrchr(icon, '.');
defformatstring(tname, "packages/icons/%s%s", icon, ext ? "" : ".png");
icon_(textureload(tname, 3), false, x, cury, ICON_SIZE, clickable && hit);
@@ -814,73 +664,57 @@ struct gui : g3d_gui
}
return layout(w, FONTH);
}
-
static Texture *skintex, *overlaytex, *slidertex;
static const int skinx[], skiny[];
static const struct patch { ushort left, right, top, bottom; uchar flags; } patches[];
-
- static void drawskin(int x, int y, int gapw, int gaph, int start, int n, int passes = 1, const vec &light = vec(1, 1, 1), float alpha = 0.80f)//int vleft, int vright, int vtop, int vbottom, int start, int n)
- {
+ static void drawskin(int x, int y, int gapw, int gaph, int start, int n, int passes = 1, const vec &light = vec(1, 1, 1), float alpha = 0.80f) {//int vleft, int vright, int vtop, int vbottom, int start, int n) {
if(!skintex) skintex = textureload("data/guiskin.png", 3);
glBindTexture(GL_TEXTURE_2D, skintex->id);
int gapx1 = INT_MAX, gapy1 = INT_MAX, gapx2 = INT_MAX, gapy2 = INT_MAX;
float wscale = 1.0f/(SKIN_W*SKIN_SCALE), hscale = 1.0f/(SKIN_H*SKIN_SCALE);
-
- loopj(passes)
- {
+ loopj(passes) {
bool quads = false;
if(passes>1) glDepthFunc(j ? GL_LEQUAL : GL_GREATER);
gle::color(j ? light : vec(1, 1, 1), passes<=1 || j ? alpha : alpha/2); //ghost when its behind something in depth
- loopi(n)
- {
+ loopi(n) {
const patch &p = patches[start+i];
int left = skinx[p.left]*SKIN_SCALE, right = skinx[p.right]*SKIN_SCALE,
top = skiny[p.top]*SKIN_SCALE, bottom = skiny[p.bottom]*SKIN_SCALE;
float tleft = left*wscale, tright = right*wscale,
ttop = top*hscale, tbottom = bottom*hscale;
- if(p.flags&0x1)
- {
+ if(p.flags&0x1) {
gapx1 = left;
gapx2 = right;
}
- else if(left >= gapx2)
- {
+ else if(left >= gapx2) {
left += gapw - (gapx2-gapx1);
right += gapw - (gapx2-gapx1);
}
- if(p.flags&0x10)
- {
+ if(p.flags&0x10) {
gapy1 = top;
gapy2 = bottom;
}
- else if(top >= gapy2)
- {
+ else if(top >= gapy2) {
top += gaph - (gapy2-gapy1);
bottom += gaph - (gapy2-gapy1);
}
-
//multiple tiled quads if necessary rather than a single stretched one
int ystep = bottom-top;
int yo = y+top;
- while(ystep > 0)
- {
- if(p.flags&0x10 && yo+ystep-(y+top) > gaph)
- {
+ while(ystep > 0) {
+ if(p.flags&0x10 && yo+ystep-(y+top) > gaph) {
ystep = gaph+y+top-yo;
tbottom = ttop+ystep*hscale;
}
int xstep = right-left;
int xo = x+left;
float tright2 = tright;
- while(xstep > 0)
- {
- if(p.flags&0x01 && xo+xstep-(x+left) > gapw)
- {
+ while(xstep > 0) {
+ if(p.flags&0x01 && xo+xstep-(x+left) > gapw) {
xstep = gapw+x+left-xo;
tright = tleft+xstep*wscale;
}
- if(!quads)
- {
+ if(!quads) {
quads = true;
gle::defvertex(2);
gle::deftexcoord0();
@@ -903,34 +737,26 @@ struct gui : g3d_gui
}
if(passes>1) glDepthFunc(GL_ALWAYS);
}
-
vec origin, scale, *savedorigin;
float dist;
g3d_callback *cb;
bool gui2d;
-
static float basescale, maxscale;
static bool passthrough;
static float alpha;
static vec light;
-
- void adjustscale()
- {
+ void adjustscale() {
int w = xsize + (skinx[2]-skinx[1])*SKIN_SCALE + (skinx[10]-skinx[9])*SKIN_SCALE, h = ysize + (skiny[9]-skiny[7])*SKIN_SCALE;
if(tcurrent) h += ((skiny[5]-skiny[1])-(skiny[3]-skiny[2]))*SKIN_SCALE + FONTH-2*INSERT;
else h += (skiny[6]-skiny[3])*SKIN_SCALE;
-
float aspect = forceaspect ? 1.0f/forceaspect : float(screenh)/float(screenw), fit = 1.0f;
if(w*aspect*basescale>1.0f) fit = 1.0f/(w*aspect*basescale);
if(h*basescale*fit>maxscale) fit *= maxscale/(h*basescale*fit);
origin = vec(0.5f-((w-xsize)/2 - (skinx[2]-skinx[1])*SKIN_SCALE)*aspect*scale.x*fit, 0.5f + (0.5f*h-(skiny[9]-skiny[7])*SKIN_SCALE)*scale.y*fit, 0);
scale = vec(aspect*scale.x*fit, scale.y*fit, 1);
}
-
- void start(int starttime, float initscale, int *tab, bool allowinput)
- {
- if(gui2d)
- {
+ void start(int starttime, float initscale, int *tab, bool allowinput) {
+ if(gui2d) {
initscale *= 0.025f;
if(allowinput) hascursor = true;
}
@@ -946,53 +772,41 @@ struct gui : g3d_gui
tcurrent = tab;
tcolor = 0xFFFFFF;
pushlist();
- if(layoutpass)
- {
+ if(layoutpass) {
firstlist = nextlist = curlist;
memset(columns, 0, sizeof(columns));
}
- else
- {
+ else {
if(tcurrent && !*tcurrent) tcurrent = NULL;
cury = -ysize;
curx = -xsize/2;
-
- if(gui2d)
- {
+ if(gui2d) {
hudmatrix.ortho(0, 1, 1, 0, -1, 1);
hudmatrix.translate(origin);
hudmatrix.scale(scale);
-
light = vec(1, 1, 1);
}
- else
- {
+ else {
float yaw = atan2f(origin.y-camera1->o.y, origin.x-camera1->o.x);
hudmatrix = camprojmatrix;
hudmatrix.translate(origin);
hudmatrix.rotate_around_z(yaw - 90*RAD);
hudmatrix.rotate_around_x(-90*RAD);
hudmatrix.scale(-scale.x, scale.y, scale.z);
-
vec dir;
lightreaching(origin, light, dir, false, 0, 0.5f);
float intensity = vec(yaw, 0.0f).dot(dir);
light.mul(1.0f + max(intensity, 0.0f));
}
-
resethudmatrix();
hudshader->set();
-
drawskin(curx-skinx[2]*SKIN_SCALE, cury-skiny[6]*SKIN_SCALE, xsize, ysize, 0, 9, gui2d ? 1 : 2, light, alpha);
if(!tcurrent) drawskin(curx-skinx[5]*SKIN_SCALE, cury-skiny[6]*SKIN_SCALE, xsize, 0, 9, 1, gui2d ? 1 : 2, light, alpha);
}
}
-
- void adjusthorizontalcolumn(int col, int i)
- {
+ void adjusthorizontalcolumn(int col, int i) {
int h = columns[col], dh = 0;
- for(int d = 1; i >= 0; d ^= 1)
- {
+ for(int d = 1; i >= 0; d ^= 1) {
list &p = lists[i];
if(d&1) { dh = h - p.h; if(dh <= 0) break; p.h = h; }
else { p.h += dh; h = p.h; }
@@ -1000,12 +814,9 @@ struct gui : g3d_gui
}
ysize += max(dh, 0);
}
-
- void adjustverticalcolumn(int col, int i)
- {
+ void adjustverticalcolumn(int col, int i) {
int w = columns[col], dw = 0;
- for(int d = 0; i >= 0; d ^= 1)
- {
+ for(int d = 0; i >= 0; d ^= 1) {
list &p = lists[i];
if(d&1) { p.w += dw; w = p.w; }
else { dw = w - p.w; if(dw <= 0) break; p.w = w; }
@@ -1013,59 +824,45 @@ struct gui : g3d_gui
}
xsize = max(xsize, w);
}
-
- void adjustcolumns()
- {
- if(lists.inrange(curlist))
- {
+ void adjustcolumns() {
+ if(lists.inrange(curlist)) {
list &l = lists[curlist];
if(l.column >= 0) columns[l.column] = max(columns[l.column], ishorizontal() ? ysize : xsize);
}
int parent = -1, depth = 0;
- for(int i = firstlist; i < lists.length(); i++)
- {
+ for(int i = firstlist; i < lists.length(); i++) {
list &l = lists[i];
if(l.parent > parent) { parent = l.parent; depth++; }
- else if(l.parent < parent)
- {
- while(parent > l.parent && depth > 0)
- {
+ else if(l.parent < parent) {
+ while(parent > l.parent && depth > 0) {
parent = lists[parent].parent;
depth--;
}
}
- if(l.column >= 0)
- {
+ if(l.column >= 0) {
if(depth&1) adjusthorizontalcolumn(l.column, i);
else adjustverticalcolumn(l.column, i);
}
}
}
-
- void end()
- {
- if(layoutpass)
- {
+ void end() {
+ if(layoutpass) {
adjustcolumns();
xsize = max(tx, xsize);
ysize = max(ty, ysize);
ysize = max(ysize, (skiny[7]-skiny[6])*SKIN_SCALE);
if(tcurrent) *tcurrent = max(1, min(*tcurrent, tpos));
if(gui2d) adjustscale();
- if(!windowhit && !passthrough)
- {
+ if(!windowhit && !passthrough) {
float dist = 0;
- if(gui2d)
- {
+ if(gui2d) {
hitx = (cursorx - origin.x)/scale.x;
hity = (cursory - origin.y)/scale.y;
}
- else
- {
+ else {
plane p;
p.toplane(vec(origin).sub(camera1->o).set(2, 0).normalize(), origin);
- if(p.rayintersect(camera1->o, camdir, dist) && dist>=0)
- {
+ if(p.rayintersect(camera1->o, camdir, dist) && dist>=0) {
vec hitpos(camdir);
hitpos.mul(dist).add(camera1->o).sub(origin);
hitx = vec(-p.y, p.x, 0).dot(hitpos)/scale.x;
@@ -1073,22 +870,18 @@ struct gui : g3d_gui
}
}
if((mousebuttons & G3D_PRESSED) && (fabs(hitx-firstx) > 2 || fabs(hity - firsty) > 2)) mousebuttons |= G3D_DRAGGED;
- if(dist>=0 && hitx>=-xsize/2 && hitx<=xsize/2 && hity<=0)
- {
+ if(dist>=0 && hitx>=-xsize/2 && hitx<=xsize/2 && hity<=0) {
if(hity>=-ysize || (tcurrent && hity>=-ysize-(FONTH-2*INSERT)-((skiny[6]-skiny[1])-(skiny[3]-skiny[2]))*SKIN_SCALE && hitx<=tx-xsize/2))
windowhit = this;
}
}
}
- else
- {
+ else {
if(tcurrent && tx<xsize) drawskin(curx+tx-skinx[5]*SKIN_SCALE, -ysize-skiny[6]*SKIN_SCALE, xsize-tx, FONTH, 9, 1, gui2d ? 1 : 2, light, alpha);
}
poplist();
}
-
- void draw()
- {
+ void draw() {
cb->gui(*this, layoutpass);
}
};
@@ -1097,44 +890,39 @@ Texture *gui::skintex = NULL, *gui::overlaytex = NULL, *gui::slidertex = NULL;
//chop skin into a grid
const int gui::skiny[] = {0, 7, 21, 34, 43, 48, 56, 104, 111, 117, 128},
- gui::skinx[] = {0, 11, 23, 37, 105, 119, 137, 151, 215, 229, 246, 256};
+ gui::skinx[] = {0, 11, 23, 37, 105, 119, 137, 151, 215, 229, 246, 256};
//Note: skinx[3]-skinx[2] = skinx[7]-skinx[6]
// skinx[5]-skinx[4] = skinx[9]-skinx[8]
-const gui::patch gui::patches[] =
-{ //arguably this data can be compressed - it depends on what else needs to be skinned in the future
- {1,2,3,6, 0}, // body
- {2,9,5,6, 0x01},
- {9,10,3,6, 0},
-
- {1,2,6,7, 0x10},
- {2,9,6,7, 0x11},
- {9,10,6,7, 0x10},
-
- {1,2,7,9, 0},
- {2,9,7,9, 0x01},
- {9,10,7,9, 0},
-
- {5,6,3,5, 0x01}, // top
-
- {2,3,1,2, 0}, // selected tab
- {3,4,1,2, 0x01},
- {4,5,1,2, 0},
- {2,3,2,3, 0x10},
- {3,4,2,3, 0x11},
- {4,5,2,3, 0x10},
- {2,3,3,5, 0},
- {3,4,3,5, 0x01},
- {4,5,3,5, 0},
-
- {6,7,1,2, 0}, // deselected tab
- {7,8,1,2, 0x01},
- {8,9,1,2, 0},
- {6,7,2,3, 0x10},
- {7,8,2,3, 0x11},
- {8,9,2,3, 0x10},
- {6,7,3,5, 0},
- {7,8,3,5, 0x01},
- {8,9,3,5, 0},
+const gui::patch gui::patches[] = {
+ //arguably this data can be compressed - it depends on what else needs to be skinned in the future {
+ { 1,2,3,6, 0}, // body {
+ { 2,9,5,6, 0x01},
+ { 9,10,3,6, 0},
+ { 1,2,6,7, 0x10},
+ { 2,9,6,7, 0x11},
+ { 9,10,6,7, 0x10},
+ { 1,2,7,9, 0},
+ { 2,9,7,9, 0x01},
+ { 9,10,7,9, 0},
+ { 5,6,3,5, 0x01}, // top
+ { 2,3,1,2, 0}, // selected tab {
+ { 3,4,1,2, 0x01},
+ { 4,5,1,2, 0},
+ { 2,3,2,3, 0x10},
+ { 3,4,2,3, 0x11},
+ { 4,5,2,3, 0x10},
+ { 2,3,3,5, 0},
+ { 3,4,3,5, 0x01},
+ { 4,5,3,5, 0},
+ { 6,7,1,2, 0}, // deselected tab {
+ { 7,8,1,2, 0x01},
+ { 8,9,1,2, 0},
+ { 6,7,2,3, 0x10},
+ { 7,8,2,3, 0x11},
+ { 8,9,2,3, 0x10},
+ { 6,7,3,5, 0},
+ { 7,8,3,5, 0x01},
+ { 8,9,3,5, 0},
};
vector<gui::list> gui::lists;
@@ -1147,53 +935,40 @@ static vector<gui> guis2d, guis3d;
VARP(guipushdist, 1, 4, 64);
-bool g3d_input(const char *str, int len)
-{
+bool g3d_input(const char *str, int len) {
editor *e = currentfocus();
if(fieldmode == FIELDKEY || fieldmode == FIELDSHOW || !e) return false;
-
e->input(str, len);
return true;
}
-bool g3d_key(int code, bool isdown)
-{
+bool g3d_key(int code, bool isdown) {
editor *e = currentfocus();
- if(fieldmode == FIELDKEY)
- {
- switch(code)
- {
+ if(fieldmode == FIELDKEY) {
+ switch(code) {
case SDLK_ESCAPE:
if(isdown) fieldmode = FIELDCOMMIT;
return true;
}
const char *keyname = getkeyname(code);
- if(keyname && isdown)
- {
+ if(keyname && isdown) {
if(e->lines.length()!=1 || !e->lines[0].empty()) e->insert(" ");
e->insert(keyname);
}
return true;
}
-
if(code==-1 && g3d_windowhit(isdown, true)) return true;
else if(code==-3 && g3d_windowhit(isdown, false)) return true;
-
- if(fieldmode == FIELDSHOW || !e)
- {
- if(windowhit) switch(code)
- {
+ if(fieldmode == FIELDSHOW || !e) {
+ if(windowhit) switch(code) {
case -4: // window "management"
- if(isdown)
- {
- if(windowhit->gui2d)
- {
+ if(isdown) {
+ if(windowhit->gui2d) {
vec origin = *guis2d.last().savedorigin;
int i = windowhit - &guis2d[0];
for(int j = guis2d.length()-1; j > i; j--) *guis2d[j].savedorigin = *guis2d[j-1].savedorigin;
*windowhit->savedorigin = origin;
- if(guis2d.length() > 1)
- {
+ if(guis2d.length() > 1) {
if(camera1->o.dist(*windowhit->savedorigin) <= camera1->o.dist(*guis2d.last().savedorigin))
windowhit->savedorigin->add(camdir);
}
@@ -1202,15 +977,12 @@ bool g3d_key(int code, bool isdown)
}
return true;
case -5:
- if(isdown)
- {
- if(windowhit->gui2d)
- {
+ if(isdown) {
+ if(windowhit->gui2d) {
vec origin = *guis2d[0].savedorigin;
loopj(guis2d.length()-1) *guis2d[j].savedorigin = *guis2d[j + 1].savedorigin;
*guis2d.last().savedorigin = origin;
- if(guis2d.length() > 1)
- {
+ if(guis2d.length() > 1) {
if(camera1->o.dist(*guis2d.last().savedorigin) >= camera1->o.dist(*guis2d[0].savedorigin))
guis2d.last().savedorigin->sub(camdir);
}
@@ -1219,11 +991,9 @@ bool g3d_key(int code, bool isdown)
}
return true;
}
-
return false;
}
- switch(code)
- {
+ switch(code) {
case SDLK_ESCAPE: //cancel editing without commit
if(isdown) fieldmode = FIELDABORT;
return true;
@@ -1240,21 +1010,18 @@ bool g3d_key(int code, bool isdown)
return true;
}
-void g3d_cursorpos(float &x, float &y)
-{
+void g3d_cursorpos(float &x, float &y) {
if(guis2d.length()) { x = cursorx; y = cursory; }
else x = y = 0.5f;
}
-void g3d_resetcursor()
-{
+void g3d_resetcursor() {
cursorx = cursory = 0.5f;
}
FVARP(guisens, 1e-3f, 1, 1e3f);
-bool g3d_movecursor(int dx, int dy)
-{
+bool g3d_movecursor(int dx, int dy) {
if(!guis2d.length() || !hascursor) return false;
const float CURSORSCALE = 500.0f;
cursorx = max(0.0f, min(1.0f, cursorx+guisens*dx*(screenh/(screenw*CURSORSCALE))));
@@ -1265,8 +1032,7 @@ bool g3d_movecursor(int dx, int dy)
VARNP(guifollow, useguifollow, 0, 1, 1);
VARNP(gui2d, usegui2d, 0, 1, 1);
-void g3d_addgui(g3d_callback *cb, vec &origin, int flags)
-{
+void g3d_addgui(g3d_callback *cb, vec &origin, int flags) {
bool gui2d = flags&GUI_FORCE_2D || (flags&GUI_2D && usegui2d) || mainmenu;
if(!gui2d && flags&GUI_FOLLOW && useguifollow) origin.z = player->o.z-(player->eyeheight-1);
gui &g = (gui2d ? guis2d : guis3d).add();
@@ -1277,20 +1043,16 @@ void g3d_addgui(g3d_callback *cb, vec &origin, int flags)
g.gui2d = gui2d;
}
-void g3d_limitscale(float scale)
-{
+void g3d_limitscale(float scale) {
gui::maxscale = scale;
}
static inline bool g3d_sort(const gui &a, const gui &b) { return a.dist < b.dist; }
-bool g3d_windowhit(bool on, bool act)
-{
+bool g3d_windowhit(bool on, bool act) {
extern int cleargui(int n);
- if(act)
- {
- if(actionon || windowhit)
- {
+ if(act) {
+ if(actionon || windowhit) {
if(on) { firstx = gui::hitx; firsty = gui::hity; }
mousebuttons |= (actionon=on) ? G3D_DOWN : G3D_UP;
}
@@ -1298,76 +1060,55 @@ bool g3d_windowhit(bool on, bool act)
return (guis2d.length() && hascursor) || (windowhit && !windowhit->gui2d);
}
-void g3d_render()
-{
+void g3d_render() {
windowhit = NULL;
if(actionon) mousebuttons |= G3D_PRESSED;
-
gui::reset();
guis2d.shrink(0);
guis3d.shrink(0);
-
// call all places in the engine that may want to render a gui from here, they call g3d_addgui()
extern void g3d_texturemenu();
-
if(!mainmenu) g3d_texturemenu();
g3d_mainmenu();
if(!mainmenu) game::g3d_gamemenus();
-
guis2d.sort(g3d_sort);
guis3d.sort(g3d_sort);
-
readyeditors();
fieldsactive = false;
-
hascursor = false;
-
layoutpass = true;
loopv(guis2d) guis2d[i].draw();
loopv(guis3d) guis3d[i].draw();
layoutpass = false;
-
- if(guis3d.length())
- {
+ if(guis3d.length()) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
glDepthMask(GL_FALSE);
-
loopvrev(guis3d) guis3d[i].draw();
-
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
glDisable(GL_DEPTH_TEST);
-
glDisable(GL_BLEND);
}
}
-void g3d_render2d()
-{
- if(guis2d.length())
- {
+void g3d_render2d() {
+ if(guis2d.length()) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
loopvrev(guis2d) guis2d[i].draw();
-
glDisable(GL_BLEND);
}
-
flusheditors();
if(!fieldsactive) fieldmode = FIELDSHOW; //didn't draw any fields, so lose focus - mainly for menu closed
textinput(fieldmode!=FIELDSHOW, TI_GUI);
keyrepeat(fieldmode!=FIELDSHOW, KR_GUI);
-
mousebuttons = 0;
}
-void consolebox(int x1, int y1, int x2, int y2)
-{
+void consolebox(int x1, int y1, int x2, int y2) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
float bw = x2 - x1, bh = y2 - y1, aspect = bw/bh, sh = bh, sw = sh*aspect;
bw *= float(4*FONTH)/(SKIN_H*SKIN_SCALE);
diff --git a/src/engine/animmodel.h b/src/engine/animmodel.h
index 13705f4..51d09e8 100644
--- a/src/engine/animmodel.h
+++ b/src/engine/animmodel.h
@@ -1,93 +1,66 @@
-VARFP(bumpmodels, 0, 1, 1, preloadmodelshaders(true));
+VARFP(bumpmodels, 0, 1, 1, preloadmodelshaders());
VARP(fullbrightmodels, 0, 0, 200);
-struct animmodel : model
-{
- struct animspec
- {
+struct animmodel : model {
+ struct animspec {
int frame, range;
float speed;
int priority;
};
-
- struct animpos
- {
+ struct animpos {
int anim, fr1, fr2;
float t;
-
- void setframes(const animinfo &info)
- {
+ void setframes(const animinfo &info) {
anim = info.anim;
- if(info.range<=1)
- {
+ if(info.range<=1) {
fr1 = 0;
t = 0;
}
- else
- {
+ else {
int time = info.anim&ANIM_SETTIME ? info.basetime : lastmillis-info.basetime;
fr1 = (int)(time/info.speed); // round to full frames
t = (time-fr1*info.speed)/info.speed; // progress of the frame, value from 0.0f to 1.0f
}
- if(info.anim&ANIM_LOOP)
- {
+ if(info.anim&ANIM_LOOP) {
fr1 = fr1%info.range+info.frame;
fr2 = fr1+1;
if(fr2>=info.frame+info.range) fr2 = info.frame;
}
- else
- {
+ else {
fr1 = min(fr1, info.range-1)+info.frame;
fr2 = min(fr1+1, info.frame+info.range-1);
}
- if(info.anim&ANIM_REVERSE)
- {
+ if(info.anim&ANIM_REVERSE) {
fr1 = (info.frame+info.range-1)-(fr1-info.frame);
fr2 = (info.frame+info.range-1)-(fr2-info.frame);
}
}
-
bool operator==(const animpos &a) const { return fr1==a.fr1 && fr2==a.fr2 && (fr1==fr2 || t==a.t); }
bool operator!=(const animpos &a) const { return fr1!=a.fr1 || fr2!=a.fr2 || (fr1!=fr2 && t!=a.t); }
};
-
struct part;
-
- struct animstate
- {
+ struct animstate {
part *owner;
animpos cur, prev;
float interp;
-
bool operator==(const animstate &a) const { return cur==a.cur && (interp<1 ? interp==a.interp && prev==a.prev : a.interp>=1); }
bool operator!=(const animstate &a) const { return cur!=a.cur || (interp<1 ? interp!=a.interp || prev!=a.prev : a.interp<1); }
};
-
struct linkedpart;
struct mesh;
-
- struct shaderparams
- {
+ struct shaderparams {
float spec, ambient, fullbright, scrollu, scrollv, alphatest;
-
shaderparams() : spec(1.0f), ambient(0.3f), fullbright(0), scrollu(0), scrollv(0), alphatest(0.9f) {}
};
-
- struct shaderparamskey
- {
+ struct shaderparamskey {
static hashtable<shaderparams, shaderparamskey> keys;
static int firstversion, lastversion;
-
int version;
-
shaderparamskey() : version(-1) {}
-
- bool checkversion()
- {
+ bool checkversion() {
if(version >= firstversion) return true;
version = lastversion;
- if(++lastversion <= 0)
- {
+ if(++lastversion <= 0) {
enumerate(keys, shaderparamskey, key, key.version = -1);
firstversion = 0;
lastversion = 1;
@@ -95,67 +68,47 @@ struct animmodel : model
}
return false;
}
-
- static inline void invalidate()
- {
+ static inline void invalidate() {
firstversion = lastversion;
}
};
-
- struct skin : shaderparams
- {
+ struct skin : shaderparams {
part *owner;
Texture *tex, *masks, *normalmap;
Shader *shader;
bool alphablend, cullface;
shaderparamskey *key;
-
skin() : owner(0), tex(notexture), masks(notexture), normalmap(NULL), shader(NULL), alphablend(true), cullface(true), key(NULL) {}
-
bool masked() const { return masks != notexture; }
bool bumpmapped() { return normalmap && bumpmodels; }
bool tangents() { return bumpmapped(); }
bool alphatested() const { return alphatest > 0 && tex->type&Texture::ALPHA; }
-
- void setkey()
- {
+ void setkey() {
key = &shaderparamskey::keys[*this];
}
-
- void setshaderparams(mesh *m, const animstate *as)
- {
+ void setshaderparams(mesh *m, const animstate *as) {
if(!Shader::lastshader) return;
-
float mincolor = as->cur.anim&ANIM_FULLBRIGHT ? fullbrightmodels/100.0f : 0.0f;
- if(fullbright)
- {
+ if(fullbright) {
gle::colorf(fullbright/2, fullbright/2, fullbright/2, transparent);
}
- else
- {
+ else {
gle::color(vec(lightcolor).max(mincolor), transparent);
}
-
if(key->checkversion() && Shader::lastshader->owner == key) return;
Shader::lastshader->owner = key;
-
if(alphatested()) LOCALPARAMF(alphatest, alphatest);
-
- if(fullbright)
- {
+ if(fullbright) {
LOCALPARAMF(lightscale, 0, 0, 2);
}
- else
- {
+ else {
float bias = max(mincolor-1.0f, 0.2f), scale = 0.5f*max(0.8f-bias, 0.0f),
minshade = scale*max(ambient, mincolor);
LOCALPARAMF(lightscale, scale - minshade, scale, minshade + bias);
}
LOCALPARAMF(texscroll, scrollu*lastmillis/1000.0f, scrollv*lastmillis/1000.0f);
}
-
- Shader *loadshader()
- {
+ Shader *loadshader() {
#define DOMODELSHADER(name, body) \
do { \
static Shader *name##shader = NULL; \
@@ -165,7 +118,6 @@ struct animmodel : model
#define LOADMODELSHADER(name) DOMODELSHADER(name, return name##shader)
#define SETMODELSHADER(m, name) DOMODELSHADER(name, (m)->setshader(name##shader))
if(shader) return shader;
-
string opts;
int optslen = 0;
if(alphatested()) opts[optslen++] = 'a';
@@ -174,40 +126,27 @@ struct animmodel : model
if(masked()) opts[optslen++] = 'm';
if(!fullbright && (masked() || spec>=0.01f)) opts[optslen++] = 's';
opts[optslen++] = '\0';
-
defformatstring(name, "model%s", opts);
shader = generateshader(name, "modelshader \"%s\"", opts);
return shader;
}
-
- void cleanup()
- {
+ void cleanup() {
if(shader && shader->standard) shader = NULL;
}
-
- void preloadBIH()
- {
+ void preloadBIH() {
if(tex->type&Texture::ALPHA && !tex->alphamask) loadalphamask(tex);
}
-
- void preloadshader(bool force)
- {
- if(force) cleanup();
+ void preloadshader() {
+ //~if(force) cleanup();
loadshader();
}
-
- void setshader(mesh *m, const animstate *as)
- {
+ void setshader(mesh *m, const animstate *as) {
m->setshader(loadshader());
}
-
- void bind(mesh *b, const animstate *as)
- {
+ void bind(mesh *b, const animstate *as) {
if(!cullface && enablecullface) { glDisable(GL_CULL_FACE); enablecullface = false; }
else if(cullface && !enablecullface) { glEnable(GL_CULL_FACE); enablecullface = true; }
-
- if(as->cur.anim&ANIM_NOSKIN)
- {
+ if(as->cur.anim&ANIM_NOSKIN) {
if(enablealphablend) { glDisable(GL_BLEND); enablealphablend = false; }
if(shadowmapping) SETMODELSHADER(b, shadowmapcaster);
else /*if(as->cur.anim&ANIM_SHADOW)*/ SETMODELSHADER(b, notexturemodel);
@@ -216,24 +155,19 @@ struct animmodel : model
setshader(b, as);
setshaderparams(b, as);
int activetmu = 0;
- if(tex!=lasttex)
- {
+ if(tex!=lasttex) {
glBindTexture(GL_TEXTURE_2D, tex->id);
lasttex = tex;
}
- if(bumpmapped() && normalmap !=lastnormalmap)
- {
+ if(bumpmapped() && normalmap !=lastnormalmap) {
glActiveTexture_(GL_TEXTURE3);
activetmu = 3;
glBindTexture(GL_TEXTURE_2D, normalmap->id);
lastnormalmap = normalmap;
}
- if(tex->type&Texture::ALPHA)
- {
- if(alphablend)
- {
- if(!enablealphablend)
- {
+ if(tex->type&Texture::ALPHA) {
+ if(alphablend) {
+ if(!enablealphablend) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
enablealphablend = true;
@@ -242,8 +176,7 @@ struct animmodel : model
else if(enablealphablend) { glDisable(GL_BLEND); enablealphablend = false; }
}
else if(enablealphablend && transparent>=1) { glDisable(GL_BLEND); enablealphablend = false; }
- if(masked() && masks!=lastmasks)
- {
+ if(masked() && masks!=lastmasks) {
glActiveTexture_(GL_TEXTURE1);
activetmu = 1;
glBindTexture(GL_TEXTURE_2D, masks->id);
@@ -252,29 +185,19 @@ struct animmodel : model
if(activetmu != 0) glActiveTexture_(GL_TEXTURE0);
}
};
-
struct meshgroup;
-
- struct mesh
- {
+ struct mesh {
meshgroup *group;
char *name;
bool noclip;
-
- mesh() : group(NULL), name(NULL), noclip(false)
- {
+ mesh() : group(NULL), name(NULL), noclip(false) {
}
-
- virtual ~mesh()
- {
+ virtual ~mesh() {
DELETEA(name);
}
-
virtual void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m) {}
-
virtual void genBIH(BIH::mesh &m) {}
- void genBIH(skin &s, vector<BIH::mesh> &bih, const matrix4x3 &t)
- {
+ void genBIH(skin &s, vector<BIH::mesh> &bih, const matrix4x3 &t) {
BIH::mesh &m = bih.add();
m.xform = t;
m.tex = s.tex;
@@ -282,35 +205,28 @@ struct animmodel : model
if(noclip) m.flags |= BIH::MESH_NOCLIP;
if(s.cullface) m.flags |= BIH::MESH_CULLFACE;
genBIH(m);
- while(bih.last().numtris > BIH::mesh::MAXTRIS)
- {
+ while(bih.last().numtris > BIH::mesh::MAXTRIS) {
BIH::mesh &overflow = bih.dup();
overflow.tris += BIH::mesh::MAXTRIS;
overflow.numtris -= BIH::mesh::MAXTRIS;
bih[bih.length()-2].numtris = BIH::mesh::MAXTRIS;
}
}
-
- virtual void setshader(Shader *s)
- {
+ virtual void setshader(Shader *s) {
s->set();
}
-
- template<class V, class T> void smoothnorms(V *verts, int numverts, T *tris, int numtris, float limit, bool areaweight)
- {
+ template<class V, class T> void smoothnorms(V *verts, int numverts, T *tris, int numtris, float limit, bool areaweight) {
hashtable<vec, int> share;
int *next = new int[numverts];
for(int i=0;i<numverts;++i)next[i]=-1;
//~memset(next, -1, numverts*sizeof(int));
- loopi(numverts)
- {
+ loopi(numverts) {
V &v = verts[i];
v.norm = vec(0, 0, 0);
int idx = share.access(v.pos, i);
if(idx != i) { next[i] = next[idx]; next[idx] = i; }
}
- loopi(numtris)
- {
+ loopi(numtris) {
T &t = tris[i];
V &v1 = verts[t.vert[0]], &v2 = verts[t.vert[1]], &v3 = verts[t.vert[2]];
vec norm;
@@ -323,18 +239,14 @@ struct animmodel : model
vec *norms = new vec[numverts];
for(int i=0;i<numverts;++i)norms[i]=vec(0,0,0);
//~memclear(norms, numverts);
- loopi(numverts)
- {
+ loopi(numverts) {
V &v = verts[i];
norms[i].add(v.norm);
- if(next[i] >= 0)
- {
+ if(next[i] >= 0) {
float vlimit = limit*v.norm.magnitude();
- for(int j = next[i]; j >= 0; j = next[j])
- {
+ for(int j = next[i]; j >= 0; j = next[j]) {
V &o = verts[j];
- if(v.norm.dot(o.norm) >= vlimit*o.norm.magnitude())
- {
+ if(v.norm.dot(o.norm) >= vlimit*o.norm.magnitude()) {
norms[i].add(o.norm);
norms[j].add(v.norm);
}
@@ -345,12 +257,9 @@ struct animmodel : model
delete[] next;
delete[] norms;
}
-
- template<class V, class T> void buildnorms(V *verts, int numverts, T *tris, int numtris, bool areaweight)
- {
+ template<class V, class T> void buildnorms(V *verts, int numverts, T *tris, int numtris, bool areaweight) {
loopi(numverts) verts[i].norm = vec(0, 0, 0);
- loopi(numtris)
- {
+ loopi(numtris) {
T &t = tris[i];
V &v1 = verts[t.vert[0]], &v2 = verts[t.vert[1]], &v3 = verts[t.vert[2]];
vec norm;
@@ -362,26 +271,19 @@ struct animmodel : model
}
loopi(numverts) verts[i].norm.normalize();
}
-
- template<class V, class T> void buildnorms(V *verts, int numverts, T *tris, int numtris, bool areaweight, int numframes)
- {
+ template<class V, class T> void buildnorms(V *verts, int numverts, T *tris, int numtris, bool areaweight, int numframes) {
if(!numverts) return;
loopi(numframes) buildnorms(&verts[i*numverts], numverts, tris, numtris, areaweight);
}
-
- static inline void fixqtangent(quat &q, float bt)
- {
+ static inline void fixqtangent(quat &q, float bt) {
static const float bias = -1.5f/65535, biasscale = sqrtf(1 - bias*bias);
- if(bt < 0)
- {
+ if(bt < 0) {
if(q.w >= 0) q.neg();
if(q.w > bias) { q.mul3(biasscale); q.w = bias; }
}
else if(q.w < 0) q.neg();
}
-
- template<class V> static inline void calctangent(V &v, const vec &n, const vec &t, float bt)
- {
+ template<class V> static inline void calctangent(V &v, const vec &n, const vec &t, float bt) {
matrix3 m;
m.c = n;
m.a = t;
@@ -390,18 +292,14 @@ struct animmodel : model
fixqtangent(q, bt);
v.tangent = q;
}
-
- template<class B, class V, class TC, class T> void calctangents(B *bumpverts, V *verts, TC *tcverts, int numverts, T *tris, int numtris, bool areaweight)
- {
+ template<class B, class V, class TC, class T> void calctangents(B *bumpverts, V *verts, TC *tcverts, int numverts, T *tris, int numtris, bool areaweight) {
vec *tangent = new vec[2*numverts], *bitangent = tangent+numverts;
for(int i=0;i<2*numverts;++i)tangent[i]=vec(0,0,0);
//~memclear(tangent, 2*numverts);
- loopi(numtris)
- {
+ loopi(numtris) {
const T &t = tris[i];
const vec &e0 = verts[t.vert[0]].pos;
vec e1 = vec(verts[t.vert[1]].pos).sub(e0), e2 = vec(verts[t.vert[2]].pos).sub(e0);
-
const vec2 &tc0 = tcverts[t.vert[0]].tc,
&tc1 = tcverts[t.vert[1]].tc,
&tc2 = tcverts[t.vert[2]].tc;
@@ -410,27 +308,20 @@ struct animmodel : model
vec u(e2), v(e2);
u.mul(v1).sub(vec(e1).mul(v2));
v.mul(u1).sub(vec(e1).mul(u2));
-
- if(vec().cross(e2, e1).dot(vec().cross(v, u)) >= 0)
- {
+ if(vec().cross(e2, e1).dot(vec().cross(v, u)) >= 0) {
u.neg();
v.neg();
}
-
- if(!areaweight)
- {
+ if(!areaweight) {
u.normalize();
v.normalize();
}
-
- loopj(3)
- {
+ loopj(3) {
tangent[t.vert[j]].sub(u);
bitangent[t.vert[j]].add(v);
}
}
- loopi(numverts)
- {
+ loopi(numverts) {
const vec &n = verts[i].norm,
&t = tangent[i],
&bt = bitangent[i];
@@ -445,136 +336,97 @@ struct animmodel : model
}
delete[] tangent;
}
-
- template<class B, class V, class TC, class T> void calctangents(B *bumpverts, V *verts, TC *tcverts, int numverts, T *tris, int numtris, bool areaweight, int numframes)
- {
+ template<class B, class V, class TC, class T> void calctangents(B *bumpverts, V *verts, TC *tcverts, int numverts, T *tris, int numtris, bool areaweight, int numframes) {
loopi(numframes) calctangents(&bumpverts[i*numverts], &verts[i*numverts], tcverts, numverts, tris, numtris, areaweight);
}
};
-
- struct meshgroup
- {
+ struct meshgroup {
meshgroup *next;
int shared;
char *name;
vector<mesh *> meshes;
-
- meshgroup() : next(NULL), shared(0), name(NULL)
- {
+ meshgroup() : next(NULL), shared(0), name(NULL) {
}
-
- virtual ~meshgroup()
- {
+ virtual ~meshgroup() {
DELETEA(name);
meshes.deletecontents();
DELETEP(next);
}
-
virtual int findtag(const char *name) { return -1; }
virtual void concattagtransform(part *p, int i, const matrix4x3 &m, matrix4x3 &n) {}
-
- void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m)
- {
+ void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m) {
loopv(meshes) meshes[i]->calcbb(bbmin, bbmax, m);
}
-
- void genBIH(vector<skin> &skins, vector<BIH::mesh> &bih, const matrix4x3 &t)
- {
+ void genBIH(vector<skin> &skins, vector<BIH::mesh> &bih, const matrix4x3 &t) {
loopv(meshes) meshes[i]->genBIH(skins[i], bih, t);
}
-
virtual void *animkey() { return this; }
virtual int totalframes() const { return 1; }
bool hasframe(int i) const { return i>=0 && i<totalframes(); }
bool hasframes(int i, int n) const { return i>=0 && i+n<=totalframes(); }
int clipframes(int i, int n) const { return min(n, totalframes() - i); }
-
virtual void cleanup() {}
virtual void preload(part *p) {}
virtual void render(const animstate *as, float pitch, const vec &axis, const vec &forward, dynent *d, part *p) {}
-
- void bindpos(GLuint ebuf, GLuint vbuf, void *v, int stride)
- {
- if(lastebuf!=ebuf)
- {
+ void bindpos(GLuint ebuf, GLuint vbuf, void *v, int stride) {
+ if(lastebuf!=ebuf) {
gle::bindebo(ebuf);
lastebuf = ebuf;
}
- if(lastvbuf!=vbuf)
- {
+ if(lastvbuf!=vbuf) {
gle::bindvbo(vbuf);
if(!lastvbuf) gle::enablevertex();
gle::vertexpointer(stride, v);
lastvbuf = vbuf;
}
}
-
- void bindtc(void *v, int stride)
- {
- if(!enabletc)
- {
+ void bindtc(void *v, int stride) {
+ if(!enabletc) {
gle::enabletexcoord0();
enabletc = true;
}
- if(lasttcbuf!=lastvbuf)
- {
+ if(lasttcbuf!=lastvbuf) {
gle::texcoord0pointer(stride, v);
lasttcbuf = lastvbuf;
}
}
-
- void bindnormals(void *v, int stride)
- {
- if(!enablenormals)
- {
+ void bindnormals(void *v, int stride) {
+ if(!enablenormals) {
gle::enablenormal();
enablenormals = true;
}
- if(lastnbuf!=lastvbuf)
- {
+ if(lastnbuf!=lastvbuf) {
gle::normalpointer(stride, v);
lastnbuf = lastvbuf;
}
}
-
- void bindtangents(void *v, int stride)
- {
- if(!enabletangents)
- {
+ void bindtangents(void *v, int stride) {
+ if(!enabletangents) {
gle::enabletangent();
enabletangents = true;
}
- if(lastxbuf!=lastvbuf)
- {
+ if(lastxbuf!=lastvbuf) {
gle::tangentpointer(stride, v, GL_SHORT);
lastxbuf = lastvbuf;
}
}
-
- void bindbones(void *wv, void *bv, int stride)
- {
- if(!enablebones)
- {
+ void bindbones(void *wv, void *bv, int stride) {
+ if(!enablebones) {
gle::enableboneweight();
gle::enableboneindex();
enablebones = true;
}
- if(lastbbuf!=lastvbuf)
- {
+ if(lastbbuf!=lastvbuf) {
gle::boneweightpointer(stride, wv);
gle::boneindexpointer(stride, bv);
lastbbuf = lastvbuf;
}
}
};
-
virtual meshgroup *loadmeshes(const char *name, va_list args) { return NULL; }
-
- meshgroup *sharemeshes(const char *name, ...)
- {
+ meshgroup *sharemeshes(const char *name, ...) {
static hashnameset<meshgroup *> meshgroups;
- if(!meshgroups.access(name))
- {
+ if(!meshgroups.access(name)) {
va_list args;
va_start(args, name);
meshgroup *group = loadmeshes(name, args);
@@ -584,20 +436,15 @@ struct animmodel : model
}
return meshgroups[name];
}
-
- struct linkedpart
- {
+ struct linkedpart {
part *p;
int tag, anim, basetime;
vec translate;
vec *pos;
matrix4 matrix;
-
linkedpart() : p(NULL), tag(-1), anim(-1), basetime(0), translate(0, 0, 0), pos(NULL) {}
};
-
- struct part
- {
+ struct part {
animmodel *model;
int index;
meshgroup *meshes;
@@ -607,57 +454,43 @@ struct animmodel : model
int numanimparts;
float pitchscale, pitchoffset, pitchmin, pitchmax;
vec translate;
-
- part(animmodel *model, int index = 0) : model(model), index(index), meshes(NULL), numanimparts(1), pitchscale(1), pitchoffset(0), pitchmin(0), pitchmax(0), translate(0, 0, 0)
- {
+ part(animmodel *model, int index = 0) : model(model), index(index), meshes(NULL), numanimparts(1), pitchscale(1), pitchoffset(0), pitchmin(0), pitchmax(0), translate(0, 0, 0) {
loopk(MAXANIMPARTS) anims[k] = NULL;
}
- virtual ~part()
- {
+ virtual ~part() {
loopk(MAXANIMPARTS) DELETEA(anims[k]);
}
-
- virtual void cleanup()
- {
+ virtual void cleanup() {
if(meshes) meshes->cleanup();
loopv(skins) skins[i].cleanup();
}
-
- void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m)
- {
+ void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m) {
matrix4x3 t = m;
t.scale(model->scale);
t.translate(translate);
meshes->calcbb(bbmin, bbmax, t);
- loopv(links)
- {
+ loopv(links) {
matrix4x3 n;
meshes->concattagtransform(this, links[i].tag, m, n);
n.translate(links[i].translate, model->scale);
links[i].p->calcbb(bbmin, bbmax, n);
}
}
-
- void genBIH(vector<BIH::mesh> &bih, const matrix4x3 &m)
- {
+ void genBIH(vector<BIH::mesh> &bih, const matrix4x3 &m) {
matrix4x3 t = m;
t.scale(model->scale);
t.translate(translate);
meshes->genBIH(skins, bih, t);
- loopv(links)
- {
+ loopv(links) {
matrix4x3 n;
meshes->concattagtransform(this, links[i].tag, m, n);
n.translate(links[i].translate, model->scale);
links[i].p->genBIH(bih, n);
}
}
-
- bool link(part *p, const char *tag, const vec &translate = vec(0, 0, 0), int anim = -1, int basetime = 0, vec *pos = NULL)
- {
+ bool link(part *p, const char *tag, const vec &translate = vec(0, 0, 0), int anim = -1, int basetime = 0, vec *pos = NULL) {
int i = meshes ? meshes->findtag(tag) : -1;
- if(i<0)
- {
+ if(i<0) {
loopv(links) if(links[i].p && links[i].p->link(p, tag, translate, anim, basetime, pos)) return true;
return false;
}
@@ -670,86 +503,62 @@ struct animmodel : model
l.pos = pos;
return true;
}
-
- bool unlink(part *p)
- {
+ bool unlink(part *p) {
loopvrev(links) if(links[i].p==p) { links.remove(i, 1); return true; }
loopv(links) if(links[i].p && links[i].p->unlink(p)) return true;
return false;
}
-
- void initskins(Texture *tex = notexture, Texture *masks = notexture, int limit = 0)
- {
- if(!limit)
- {
+ void initskins(Texture *tex = notexture, Texture *masks = notexture, int limit = 0) {
+ if(!limit) {
if(!meshes) return;
limit = meshes->meshes.length();
}
- while(skins.length() < limit)
- {
+ while(skins.length() < limit) {
skin &s = skins.add();
s.owner = this;
s.tex = tex;
s.masks = masks;
}
}
-
- bool tangents()
- {
+ bool tangents() {
loopv(skins) if(skins[i].tangents()) return true;
return false;
}
-
- void preloadBIH()
- {
+ void preloadBIH() {
loopv(skins) skins[i].preloadBIH();
}
-
- void preloadshaders(bool force)
- {
- loopv(skins) skins[i].preloadshader(force);
+ void preloadshaders() {
+ loopv(skins) skins[i].preloadshader();
}
-
- void preloadmeshes()
- {
+ void preloadmeshes() {
if(meshes) meshes->preload(this);
}
-
- virtual void getdefaultanim(animinfo &info, int anim, uint varseed, dynent *d)
- {
+ virtual void getdefaultanim(animinfo &info, int anim, uint varseed, dynent *d) {
(void) anim; (void) varseed; (void) d;
info.frame = 0;
info.range = 1;
}
-
- bool calcanim(int animpart, int anim, int basetime, int basetime2, dynent *d, int interp, animinfo &info, int &aitime)
- {
+ bool calcanim(int animpart, int anim, int basetime, int basetime2, dynent *d, int interp, animinfo &info, int &aitime) {
uint varseed = uint((size_t)d);
info.anim = anim;
info.basetime = basetime;
info.varseed = varseed;
info.speed = anim&ANIM_SETSPEED ? basetime2 : 100.0f;
- if((anim&ANIM_INDEX)==ANIM_ALL)
- {
+ if((anim&ANIM_INDEX)==ANIM_ALL) {
info.frame = 0;
info.range = meshes->totalframes();
}
- else
- {
+ else {
animspec *spec = NULL;
- if(anims[animpart])
- {
+ if(anims[animpart]) {
int primaryidx = anim&ANIM_INDEX;
- if(primaryidx < NUMANIMS)
- {
+ if(primaryidx < NUMANIMS) {
vector<animspec> &primary = anims[animpart][primaryidx];
if(primary.length()) spec = &primary[uint(varseed + basetime)%primary.length()];
}
- if((anim>>ANIM_SECONDARY)&(ANIM_INDEX|ANIM_DIR))
- {
+ if((anim>>ANIM_SECONDARY)&(ANIM_INDEX|ANIM_DIR)) {
int secondaryidx = (anim>>ANIM_SECONDARY)&ANIM_INDEX;
- if(secondaryidx < NUMANIMS)
- {
+ if(secondaryidx < NUMANIMS) {
vector<animspec> &secondary = anims[animpart][secondaryidx];
if(secondary.length())
{
@@ -764,54 +573,42 @@ struct animmodel : model
}
}
}
- if(spec)
- {
+ if(spec) {
info.frame = spec->frame;
info.range = spec->range;
if(spec->speed>0) info.speed = 1000.0f/spec->speed;
}
else getdefaultanim(info, anim, uint(varseed + info.basetime), d);
}
-
info.anim &= (1<<ANIM_SECONDARY)-1;
info.anim |= anim&ANIM_FLAGS;
- if((info.anim&ANIM_CLAMP) != ANIM_CLAMP)
- {
- if(info.anim&(ANIM_LOOP|ANIM_START|ANIM_END))
- {
+ if((info.anim&ANIM_CLAMP) != ANIM_CLAMP) {
+ if(info.anim&(ANIM_LOOP|ANIM_START|ANIM_END)) {
info.anim &= ~ANIM_SETTIME;
if(!info.basetime) info.basetime = -((int)(size_t)d&0xFFF);
}
- if(info.anim&(ANIM_START|ANIM_END))
- {
+ if(info.anim&(ANIM_START|ANIM_END)) {
if(info.anim&ANIM_END) info.frame += info.range-1;
info.range = 1;
}
}
-
- if(!meshes->hasframes(info.frame, info.range))
- {
+ if(!meshes->hasframes(info.frame, info.range)) {
if(!meshes->hasframe(info.frame)) return false;
info.range = meshes->clipframes(info.frame, info.range);
}
-
- if(d && interp>=0)
- {
+ if(d && interp>=0) {
animinterpinfo &ai = d->animinterp[interp];
if((info.anim&ANIM_CLAMP)==ANIM_CLAMP) aitime = min(aitime, int(info.range*info.speed*0.5e-3f));
void *ak = meshes->animkey();
- if(d->ragdoll && !(anim&ANIM_RAGDOLL))
- {
+ if(d->ragdoll && !(anim&ANIM_RAGDOLL)) {
ai.prev.range = ai.cur.range = 0;
ai.lastswitch = -1;
}
- else if(ai.lastmodel!=ak || ai.lastswitch<0 || lastmillis-d->lastrendered>aitime)
- {
+ else if(ai.lastmodel!=ak || ai.lastswitch<0 || lastmillis-d->lastrendered>aitime) {
ai.prev = ai.cur = info;
ai.lastswitch = lastmillis-aitime*2;
}
- else if(ai.cur!=info)
- {
+ else if(ai.cur!=info) {
if(lastmillis-ai.lastswitch>aitime/2) ai.prev = ai.cur;
ai.cur = info;
ai.lastswitch = lastmillis;
@@ -821,17 +618,12 @@ struct animmodel : model
}
return true;
}
-
- void render(int anim, int basetime, int basetime2, float pitch, const vec &axis, const vec &forward, dynent *d)
- {
+ void render(int anim, int basetime, int basetime2, float pitch, const vec &axis, const vec &forward, dynent *d) {
animstate as[MAXANIMPARTS];
render(anim, basetime, basetime2, pitch, axis, forward, d, as);
}
-
- void render(int anim, int basetime, int basetime2, float pitch, const vec &axis, const vec &forward, dynent *d, animstate *as)
- {
- if(!(anim&ANIM_REUSE)) loopi(numanimparts)
- {
+ void render(int anim, int basetime, int basetime2, float pitch, const vec &axis, const vec &forward, dynent *d, animstate *as) {
+ if(!(anim&ANIM_REUSE)) loopi(numanimparts) {
animinfo info;
int interp = d && index+numanimparts<=MAXANIMPARTS ? index+i : -1, aitime = animationinterpolationtime;
if(!calcanim(i, anim, basetime, basetime2, d, interp, info, aitime)) return;
@@ -839,41 +631,33 @@ struct animmodel : model
p.owner = this;
p.cur.setframes(info);
p.interp = 1;
- if(interp>=0 && d->animinterp[interp].prev.range>0)
- {
+ if(interp>=0 && d->animinterp[interp].prev.range>0) {
int diff = lastmillis-d->animinterp[interp].lastswitch;
- if(diff<aitime)
- {
+ if(diff<aitime) {
p.prev.setframes(d->animinterp[interp].prev);
p.interp = diff/float(aitime);
}
}
}
-
vec oaxis, oforward;
matrixstack[matrixpos].transposedtransformnormal(axis, oaxis);
float pitchamount = pitchscale*pitch + pitchoffset;
if((pitchmin || pitchmax) && pitchmin <= pitchmax) pitchamount = clamp(pitchamount, pitchmin, pitchmax);
if(as->cur.anim&ANIM_NOPITCH || (as->interp < 1 && as->prev.anim&ANIM_NOPITCH))
pitchamount *= (as->cur.anim&ANIM_NOPITCH ? 0 : as->interp) + (as->interp < 1 && as->prev.anim&ANIM_NOPITCH ? 0 : 1-as->interp);
- if(pitchamount)
- {
+ if(pitchamount) {
++matrixpos;
matrixstack[matrixpos] = matrixstack[matrixpos-1];
matrixstack[matrixpos].rotate(pitchamount*RAD, oaxis);
}
matrixstack[matrixpos].transposedtransformnormal(forward, oforward);
-
- if(!(anim&ANIM_NORENDER))
- {
+ if(!(anim&ANIM_NORENDER)) {
matrix4 modelmatrix;
modelmatrix.mul(shadowmapping ? shadowmatrix : camprojmatrix, matrixstack[matrixpos]);
if(model->scale!=1) modelmatrix.scale(model->scale);
if(!translate.iszero()) modelmatrix.translate(translate);
GLOBALPARAM(modelmatrix, modelmatrix);
-
- if(!(anim&ANIM_NOSKIN))
- {
+ if(!(anim&ANIM_NOSKIN)) {
vec odir, ocampos;
matrixstack[matrixpos].transposedtransformnormal(lightdir, odir);
GLOBALPARAM(lightdir, odir);
@@ -882,48 +666,33 @@ struct animmodel : model
GLOBALPARAM(modelcamera, ocampos);
}
}
-
meshes->render(as, pitch, oaxis, oforward, d, this);
-
- if(!(anim&ANIM_REUSE))
- {
- loopv(links)
- {
+ if(!(anim&ANIM_REUSE)) {
+ loopv(links) {
linkedpart &link = links[i];
link.matrix.translate(links[i].translate, model->scale);
-
matrixpos++;
matrixstack[matrixpos].mul(matrixstack[matrixpos-1], link.matrix);
-
if(link.pos) *link.pos = matrixstack[matrixpos].gettranslation();
-
- if(!link.p)
- {
+ if(!link.p) {
matrixpos--;
continue;
}
-
int nanim = anim, nbasetime = basetime, nbasetime2 = basetime2;
- if(link.anim>=0)
- {
+ if(link.anim>=0) {
nanim = link.anim | (anim&ANIM_FLAGS);
nbasetime = link.basetime;
nbasetime2 = 0;
}
link.p->render(nanim, nbasetime, nbasetime2, pitch, axis, forward, d);
-
matrixpos--;
}
}
-
if(pitchamount) matrixpos--;
}
-
- void setanim(int animpart, int num, int frame, int range, float speed, int priority = 0)
- {
+ void setanim(int animpart, int num, int frame, int range, float speed, int priority = 0) {
if(animpart<0 || animpart>=MAXANIMPARTS) return;
- if(frame<0 || range<=0 || !meshes || !meshes->hasframes(frame, range))
- {
+ if(frame<0 || range<=0 || !meshes || !meshes->hasframes(frame, range)) {
conoutf(CON_ERROR, "invalid frame %d, range %d in model %s", frame, range, model->name);
return;
}
@@ -934,99 +703,73 @@ struct animmodel : model
spec.speed = speed;
spec.priority = priority;
}
-
- virtual void loaded()
- {
+ virtual void loaded() {
meshes->shared++;
loopv(skins) skins[i].setkey();
}
};
-
- enum
- {
+ enum {
LINK_TAG = 0,
LINK_COOP,
LINK_REUSE
};
-
virtual int linktype(animmodel *m) const { (void) m; return LINK_TAG; }
-
- void render(int anim, int basetime, int basetime2, float pitch, const vec &axis, const vec &forward, dynent *d, modelattach *a)
- {
+ void render(int anim, int basetime, int basetime2, float pitch, const vec &axis, const vec &forward, dynent *d, modelattach *a) {
int numtags = 0;
- if(a)
- {
+ if(a) {
int index = parts.last()->index + parts.last()->numanimparts;
- for(int i = 0; a[i].tag; i++)
- {
+ for(int i = 0; a[i].tag; i++) {
numtags++;
-
animmodel *m = (animmodel *)a[i].m;
- if(!m)
- {
+ if(!m) {
if(a[i].pos) link(NULL, a[i].tag, vec(0, 0, 0), 0, 0, a[i].pos);
continue;
}
part *p = m->parts[0];
- switch(linktype(m))
- {
+ switch(linktype(m)) {
case LINK_TAG:
p->index = link(p, a[i].tag, vec(0, 0, 0), a[i].anim, a[i].basetime, a[i].pos) ? index : -1;
break;
-
case LINK_COOP:
p->index = index;
break;
-
default:
continue;
}
index += p->numanimparts;
}
}
-
animstate as[MAXANIMPARTS];
parts[0]->render(anim, basetime, basetime2, pitch, axis, forward, d, as);
-
- if(a) for(int i = numtags-1; i >= 0; i--)
- {
+ if(a) for(int i = numtags-1; i >= 0; i--) {
animmodel *m = (animmodel *)a[i].m;
- if(!m)
- {
+ if(!m) {
if(a[i].pos) unlink(NULL);
continue;
}
part *p = m->parts[0];
- switch(linktype(m))
- {
+ switch(linktype(m)) {
case LINK_TAG:
if(p->index >= 0) unlink(p);
p->index = 0;
break;
-
case LINK_COOP:
p->render(anim, basetime, basetime2, pitch, axis, forward, d);
p->index = 0;
break;
-
case LINK_REUSE:
p->render(anim | ANIM_REUSE, basetime, basetime2, pitch, axis, forward, d, as);
break;
}
}
}
-
- void render(int anim, int basetime, int basetime2, const vec &o, float yaw, float pitch, dynent *d, modelattach *a, const vec &color, const vec &dir, float trans)
- {
+ void render(int anim, int basetime, int basetime2, const vec &o, float yaw, float pitch, dynent *d, modelattach *a, const vec &color, const vec &dir, float trans) {
yaw += spinyaw*lastmillis/1000.0f;
pitch += offsetpitch + spinpitch*lastmillis/1000.0f;
-
vec axis(0, -1, 0), forward(1, 0, 0);
-
matrixpos = 0;
matrixstack[0].identity();
- if(!d || !d->ragdoll || anim&ANIM_RAGDOLL)
- {
+ if(!d || !d->ragdoll || anim&ANIM_RAGDOLL) {
matrixstack[0].settranslation(o);
matrixstack[0].rotate_around_z(yaw*RAD);
matrixstack[0].transformnormal(vec(axis), axis);
@@ -1034,138 +777,96 @@ struct animmodel : model
if(offsetyaw) matrixstack[0].rotate_around_z(offsetyaw*RAD);
}
else pitch = 0;
-
- if(anim&ANIM_NORENDER)
- {
+ if(anim&ANIM_NORENDER) {
render(anim, basetime, basetime2, pitch, axis, forward, d, a);
if(d) d->lastrendered = lastmillis;
return;
}
-
- if(!(anim&ANIM_NOSKIN))
- {
+ if(!(anim&ANIM_NOSKIN)) {
transparent = trans;
lightdir = dir;
lightcolor = color;
}
-
- if(depthoffset && !enabledepthoffset)
- {
+ if(depthoffset && !enabledepthoffset) {
enablepolygonoffset(GL_POLYGON_OFFSET_FILL);
enabledepthoffset = true;
}
-
- if(transparent<1)
- {
- if(anim&ANIM_GHOST)
- {
+ if(transparent<1) {
+ if(anim&ANIM_GHOST) {
glDepthFunc(GL_GREATER);
glDepthMask(GL_FALSE);
}
- else if(alphadepth)
- {
+ else if(alphadepth) {
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
render(anim|ANIM_NOSKIN, basetime, basetime2, pitch, axis, forward, d, a);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
glDepthFunc(GL_LEQUAL);
}
-
- if(!enablealphablend)
- {
+ if(!enablealphablend) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
enablealphablend = true;
}
}
-
render(anim, basetime, basetime2, pitch, axis, forward, d, a);
-
- if(transparent<1 && (alphadepth || anim&ANIM_GHOST))
- {
+ if(transparent<1 && (alphadepth || anim&ANIM_GHOST)) {
glDepthFunc(GL_LESS);
if(anim&ANIM_GHOST) glDepthMask(GL_TRUE);
}
-
if(d) d->lastrendered = lastmillis;
}
-
vector<part *> parts;
-
- animmodel(const char *name) : model(name)
- {
+ animmodel(const char *name) : model(name) {
}
-
- ~animmodel()
- {
+ ~animmodel() {
parts.deletecontents();
}
-
- void cleanup()
- {
+ void cleanup() {
loopv(parts) parts[i]->cleanup();
}
-
virtual void flushpart() {}
-
- part &addpart()
- {
+ part &addpart() {
flushpart();
part *p = new part(this, parts.length());
parts.add(p);
return *p;
}
-
- void initmatrix(matrix4x3 &m)
- {
+ void initmatrix(matrix4x3 &m) {
m.identity();
if(offsetyaw) m.rotate_around_z(offsetyaw*RAD);
if(offsetpitch) m.rotate_around_y(-offsetpitch*RAD);
}
-
- void genBIH(vector<BIH::mesh> &bih)
- {
+ void genBIH(vector<BIH::mesh> &bih) {
if(parts.empty()) return;
matrix4x3 m;
initmatrix(m);
parts[0]->genBIH(bih, m);
}
-
- void preloadBIH()
- {
+ void preloadBIH() {
model::preloadBIH();
if(bih) loopv(parts) parts[i]->preloadBIH();
}
-
- BIH *setBIH()
- {
+ BIH *setBIH() {
if(bih) return bih;
vector<BIH::mesh> meshes;
genBIH(meshes);
bih = new BIH(meshes);
return bih;
}
-
- bool link(part *p, const char *tag, const vec &translate = vec(0, 0, 0), int anim = -1, int basetime = 0, vec *pos = NULL)
- {
+ bool link(part *p, const char *tag, const vec &translate = vec(0, 0, 0), int anim = -1, int basetime = 0, vec *pos = NULL) {
if(parts.empty()) return false;
return parts[0]->link(p, tag, translate, anim, basetime, pos);
}
-
- bool unlink(part *p)
- {
+ bool unlink(part *p) {
if(parts.empty()) return false;
return parts[0]->unlink(p);
}
-
virtual bool flipy() const { return false; }
virtual bool loadconfig() { return false; }
virtual bool loaddefaultparts() { return false; }
virtual void startload() {}
virtual void endload() {}
-
- bool load()
- {
+ bool load() {
startload();
bool success = loadconfig() && parts.length(); // configured model, will call the model commands below
if(!success)
@@ -1173,68 +874,46 @@ struct animmodel : model
flushpart();
endload();
if(flipy()) translate.y = -translate.y;
-
if(!success) return false;
loopv(parts) if(!parts[i]->meshes) return false;
-
loaded();
return true;
}
-
- void preloadshaders(bool force)
- {
- loopv(parts) parts[i]->preloadshaders(force);
+ void preloadshaders() {
+ loopv(parts) parts[i]->preloadshaders();
}
-
- void preloadmeshes()
- {
+ void preloadmeshes() {
loopv(parts) parts[i]->preloadmeshes();
}
-
- void setshader(Shader *shader)
- {
+ void setshader(Shader *shader) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].shader = shader;
}
-
- void setspec(float spec)
- {
+ void setspec(float spec) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].spec = spec;
}
-
- void setambient(float ambient)
- {
+ void setambient(float ambient) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].ambient = ambient;
}
-
- void setalphatest(float alphatest)
- {
+ void setalphatest(float alphatest) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].alphatest = alphatest;
}
-
- void setalphablend(bool alphablend)
- {
+ void setalphablend(bool alphablend) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].alphablend = alphablend;
}
-
- void setfullbright(float fullbright)
- {
+ void setfullbright(float fullbright) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].fullbright = fullbright;
}
-
- void setcullface(bool cullface)
- {
+ void setcullface(bool cullface) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].cullface = cullface;
}
-
- void calcbb(vec &center, vec &radius)
- {
+ void calcbb(vec &center, vec &radius) {
if(parts.empty()) return;
vec bbmin(1e16f, 1e16f, 1e16f), bbmax(-1e16f, -1e16f, -1e16f);
matrix4x3 m;
@@ -1246,14 +925,11 @@ struct animmodel : model
center = bbmin;
center.add(radius);
}
-
- virtual void loaded()
- {
+ virtual void loaded() {
scale /= 4;
if(parts.length()) parts[0]->translate = translate;
loopv(parts) parts[i]->loaded();
}
-
static bool enabletc, enablealphablend, enablecullface, enablenormals, enabletangents, enablebones, enabledepthoffset;
static vec lightdir, lightcolor;
static float transparent, lastalphatest;
@@ -1261,9 +937,7 @@ struct animmodel : model
static Texture *lasttex, *lastmasks, *lastnormalmap;
static int matrixpos;
static matrix4 matrixstack[64];
-
- void startrender()
- {
+ void startrender() {
enabletc = enablealphablend = enablenormals = enabletangents = enablebones = enabledepthoffset = false;
enablecullface = true;
lastalphatest = -1;
@@ -1272,37 +946,26 @@ struct animmodel : model
transparent = 1;
shaderparamskey::invalidate();
}
-
- static void disablebones()
- {
+ static void disablebones() {
gle::disableboneweight();
gle::disableboneindex();
enablebones = false;
}
-
- static void disabletangents()
- {
+ static void disabletangents() {
gle::disabletangent();
enabletangents = false;
}
-
- static void disabletc()
- {
+ static void disabletc() {
gle::disabletexcoord0();
enabletc = false;
}
-
- static void disablenormals()
- {
+ static void disablenormals() {
gle::disablenormal();
enablenormals = false;
}
-
- static void disablevbo()
- {
+ static void disablevbo() {
if(lastebuf) gle::clearebo();
- if(lastvbuf)
- {
+ if(lastvbuf) {
gle::clearvbo();
gle::disablevertex();
}
@@ -1312,9 +975,7 @@ struct animmodel : model
if(enablebones) disablebones();
lastvbuf = lasttcbuf = lastxbuf = lastnbuf = lastbbuf = lastebuf = 0;
}
-
- void endrender()
- {
+ void endrender() {
if(lastvbuf || lastebuf) disablevbo();
if(enablealphablend) glDisable(GL_BLEND);
if(!enablecullface) glEnable(GL_CULL_FACE);
@@ -1333,45 +994,33 @@ Texture *animmodel::lasttex = NULL, *animmodel::lastmasks = NULL, *animmodel::la
int animmodel::matrixpos = 0;
matrix4 animmodel::matrixstack[64];
-static inline uint hthash(const animmodel::shaderparams &k)
-{
+static inline uint hthash(const animmodel::shaderparams &k) {
return memhash(&k, sizeof(k));
}
-static inline bool htcmp(const animmodel::shaderparams &x, const animmodel::shaderparams &y)
-{
+static inline bool htcmp(const animmodel::shaderparams &x, const animmodel::shaderparams &y) {
return !memcmp(&x, &y, sizeof(animmodel::shaderparams));
}
hashtable<animmodel::shaderparams, animmodel::shaderparamskey> animmodel::shaderparamskey::keys;
int animmodel::shaderparamskey::firstversion = 0, animmodel::shaderparamskey::lastversion = 1;
-template<class MDL, class BASE> struct modelloader : BASE
-{
+template<class MDL, class BASE> struct modelloader : BASE {
static MDL *loading;
static string dir;
-
modelloader(const char *name) : BASE(name) {}
-
static bool animated() { return true; }
static bool multiparted() { return true; }
static bool multimeshed() { return true; }
-
- void startload()
- {
+ void startload() {
loading = (MDL *)this;
}
-
- void endload()
- {
+ void endload() {
loading = NULL;
}
-
- bool loadconfig()
- {
+ bool loadconfig() {
formatstring(dir, "packages/models/%s", BASE::name);
defformatstring(cfgname, "packages/models/%s/%s.cfg", BASE::name, MDL::formatname());
-
identflags &= ~IDF_PERSIST;
bool success = execfile(cfgname, false);
identflags |= IDF_PERSIST;
@@ -1382,118 +1031,84 @@ template<class MDL, class BASE> struct modelloader : BASE
template<class MDL, class BASE> MDL *modelloader<MDL, BASE>::loading = NULL;
template<class MDL, class BASE> string modelloader<MDL, BASE>::dir = {'\0'}; // crashes clang if "" is used here
-template<class MDL, class MESH> struct modelcommands
-{
+template<class MDL, class MESH> struct modelcommands {
typedef struct MDL::part part;
typedef struct MDL::skin skin;
-
- static void setdir(char *name)
- {
+ static void setdir(char *name) {
if(!MDL::loading) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
formatstring(MDL::dir, "packages/models/%s", name);
}
-
#define loopmeshes(meshname, m, body) \
if(!MDL::loading || MDL::loading->parts.empty()) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; } \
part &mdl = *MDL::loading->parts.last(); \
if(!mdl.meshes) return; \
- loopv(mdl.meshes->meshes) \
- { \
+ loopv(mdl.meshes->meshes) { \
+ \
MESH &m = *(MESH *)mdl.meshes->meshes[i]; \
- if(!strcmp(meshname, "*") || (m.name && !strcmp(m.name, meshname))) \
- { \
+ if(!strcmp(meshname, "*") || (m.name && !strcmp(m.name, meshname))) { \
+ \
body; \
} \
}
-
#define loopskins(meshname, s, body) loopmeshes(meshname, m, { skin &s = mdl.skins[i]; body; })
-
- static void setskin(char *meshname, char *tex, char *masks, float *envmapmax, float *envmapmin)
- {(void)envmapmax;(void)envmapmin;
+ static void setskin(char *meshname, char *tex, char *masks, float *envmapmax, float *envmapmin) {
+ (void)envmapmax;(void)envmapmin;
loopskins(meshname, s,
s.tex = textureload(makerelpath(MDL::dir, tex), 0, true, false);
- if(*masks)
- {
+ if(*masks) {
s.masks = textureload(makerelpath(MDL::dir, masks), 0, true, false);
}
);
}
-
- static void setspec(char *meshname, int *percent)
- {
+ static void setspec(char *meshname, int *percent) {
float spec = 1.0f;
if(*percent>0) spec = *percent/100.0f;
else if(*percent<0) spec = 0.0f;
loopskins(meshname, s, s.spec = spec);
}
-
- static void setambient(char *meshname, int *percent)
- {
+ static void setambient(char *meshname, int *percent) {
float ambient = 0.3f;
if(*percent>0) ambient = *percent/100.0f;
else if(*percent<0) ambient = 0.0f;
loopskins(meshname, s, s.ambient = ambient);
}
-
- static void setalphatest(char *meshname, float *cutoff)
- {
+ static void setalphatest(char *meshname, float *cutoff) {
loopskins(meshname, s, s.alphatest = max(0.0f, min(1.0f, *cutoff)));
}
-
- static void setalphablend(char *meshname, int *blend)
- {
+ static void setalphablend(char *meshname, int *blend) {
loopskins(meshname, s, s.alphablend = *blend!=0);
}
-
- static void setcullface(char *meshname, int *cullface)
- {
+ static void setcullface(char *meshname, int *cullface) {
loopskins(meshname, s, s.cullface = *cullface!=0);
}
-
- static void setbumpmap(char *meshname, char *normalmapfile)
- {
+ static void setbumpmap(char *meshname, char *normalmapfile) {
Texture *normalmaptex = textureload(makerelpath(MDL::dir, normalmapfile), 0, true, false);
loopskins(meshname, s, s.normalmap = normalmaptex);
}
-
- static void setfullbright(char *meshname, float *fullbright)
- {
+ static void setfullbright(char *meshname, float *fullbright) {
loopskins(meshname, s, s.fullbright = *fullbright);
}
-
- static void setshader(char *meshname, char *shader)
- {
+ static void setshader(char *meshname, char *shader) {
loopskins(meshname, s, s.shader = lookupshaderbyname(shader));
}
-
- static void setscroll(char *meshname, float *scrollu, float *scrollv)
- {
+ static void setscroll(char *meshname, float *scrollu, float *scrollv) {
loopskins(meshname, s, { s.scrollu = *scrollu; s.scrollv = *scrollv; });
}
-
- static void setnoclip(char *meshname, int *noclip)
- {
+ static void setnoclip(char *meshname, int *noclip) {
loopmeshes(meshname, m, m.noclip = *noclip!=0);
}
-
- static void setlink(int *parent, int *child, char *tagname, float *x, float *y, float *z)
- {
+ static void setlink(int *parent, int *child, char *tagname, float *x, float *y, float *z) {
if(!MDL::loading) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
if(!MDL::loading->parts.inrange(*parent) || !MDL::loading->parts.inrange(*child)) { conoutf(CON_ERROR, "no models loaded to link"); return; }
if(!MDL::loading->parts[*parent]->link(MDL::loading->parts[*child], tagname, vec(*x, *y, *z))) conoutf(CON_ERROR, "could not link model %s", MDL::loading->name);
}
-
- template<class F> void modelcommand(F *fun, const char *suffix, const char *args)
- {
+ template<class F> void modelcommand(F *fun, const char *suffix, const char *args) {
defformatstring(name, "%s%s", MDL::formatname(), suffix);
addcommand(newstring(name), (void (*)())fun, args);
}
-
- modelcommands()
- {
+ modelcommands() {
modelcommand(setdir, "dir", "s");
- if(MDL::multimeshed())
- {
+ if(MDL::multimeshed()) {
modelcommand(setskin, "skin", "sssff");
modelcommand(setspec, "spec", "si");
modelcommand(setambient, "ambient", "si");
diff --git a/src/engine/bih.cpp b/src/engine/bih.cpp
index c983805..e406008 100644
--- a/src/engine/bih.cpp
+++ b/src/engine/bih.cpp
@@ -1,13 +1,11 @@
#include "engine.h"
-bool BIH::triintersect(const mesh &m, int tidx, const vec &mo, const vec &mray, float maxdist, float &dist, int mode)
-{
+bool BIH::triintersect(const mesh &m, int tidx, const vec &mo, const vec &mray, float maxdist, float &dist, int mode) {
const tri &t = m.tris[tidx];
vec a = m.getpos(t.vert[0]), b = m.getpos(t.vert[1]).sub(a), c = m.getpos(t.vert[2]).sub(a),
n = vec().cross(b, c), r = vec(a).sub(mo), e = vec().cross(r, mray);
float det = mray.dot(n), v, w, f;
- if(det >= 0)
- {
+ if(det >= 0) {
if(!(mode&RAY_SHADOW) && m.flags&MESH_CULLFACE) return false;
v = e.dot(c);
if(v < 0 || v > det) return false;
@@ -16,8 +14,7 @@ bool BIH::triintersect(const mesh &m, int tidx, const vec &mo, const vec &mray,
f = r.dot(n)*m.scale;
if(f < 0 || f > maxdist*det || !det) return false;
}
- else
- {
+ else {
v = e.dot(c);
if(v > 0 || v < det) return false;
w = -e.dot(b);
@@ -26,8 +23,7 @@ bool BIH::triintersect(const mesh &m, int tidx, const vec &mo, const vec &mray,
if(f > 0 || f < maxdist*det) return false;
}
float invdet = 1/det;
- if(m.flags&MESH_ALPHA && (mode&RAY_ALPHAPOLY)==RAY_ALPHAPOLY && (m.tex->alphamask || (lightmapping <= 1 && loadalphamask(m.tex))))
- {
+ if(m.flags&MESH_ALPHA && (mode&RAY_ALPHAPOLY)==RAY_ALPHAPOLY && (m.tex->alphamask || (lightmapping <= 1 && loadalphamask(m.tex)))) {
vec2 at = m.gettc(t.vert[0]), bt = m.gettc(t.vert[1]).sub(at).mul(v*invdet), ct = m.gettc(t.vert[2]).sub(at).mul(w*invdet);
at.add(bt).add(ct);
int si = clamp(int(m.tex->xs * at.x), 0, m.tex->xs-1),
@@ -38,31 +34,24 @@ bool BIH::triintersect(const mesh &m, int tidx, const vec &mo, const vec &mray,
return true;
}
-struct traversestate
-{
+struct traversestate {
BIH::node *node;
float tmin, tmax;
};
-inline bool BIH::traverse(const mesh &m, const vec &o, const vec &ray, const vec &invray, float maxdist, float &dist, int mode, node *curnode, float tmin, float tmax)
-{
+inline bool BIH::traverse(const mesh &m, const vec &o, const vec &ray, const vec &invray, float maxdist, float &dist, int mode, node *curnode, float tmin, float tmax) {
traversestate stack[128];
int stacksize = 0;
ivec order(ray.x>0 ? 0 : 1, ray.y>0 ? 0 : 1, ray.z>0 ? 0 : 1);
vec mo = m.invxform.transform(o), mray = m.invxformnorm.transform(ray);
- for(;;)
- {
+ for(;;) {
int axis = curnode->axis();
int nearidx = order[axis], faridx = nearidx^1;
float nearsplit = (curnode->split[nearidx] - o[axis])*invray[axis],
farsplit = (curnode->split[faridx] - o[axis])*invray[axis];
-
- if(nearsplit <= tmin)
- {
- if(farsplit < tmax)
- {
- if(!curnode->isleaf(faridx))
- {
+ if(nearsplit <= tmin) {
+ if(farsplit < tmax) {
+ if(!curnode->isleaf(faridx)) {
curnode += curnode->childindex(faridx);
tmin = max(tmin, farsplit);
continue;
@@ -70,13 +59,10 @@ inline bool BIH::traverse(const mesh &m, const vec &o, const vec &ray, const vec
else if(triintersect(m, curnode->childindex(faridx), mo, mray, maxdist, dist, mode)) return true;
}
}
- else if(curnode->isleaf(nearidx))
- {
+ else if(curnode->isleaf(nearidx)) {
if(triintersect(m, curnode->childindex(nearidx), mo, mray, maxdist, dist, mode)) return true;
- if(farsplit < tmax)
- {
- if(!curnode->isleaf(faridx))
- {
+ if(farsplit < tmax) {
+ if(!curnode->isleaf(faridx)) {
curnode += curnode->childindex(faridx);
tmin = max(tmin, farsplit);
continue;
@@ -84,21 +70,16 @@ inline bool BIH::traverse(const mesh &m, const vec &o, const vec &ray, const vec
else if(triintersect(m, curnode->childindex(faridx), mo, mray, maxdist, dist, mode)) return true;
}
}
- else
- {
- if(farsplit < tmax)
- {
- if(!curnode->isleaf(faridx))
- {
- if(stacksize < int(sizeof(stack)/sizeof(stack[0])))
- {
+ else {
+ if(farsplit < tmax) {
+ if(!curnode->isleaf(faridx)) {
+ if(stacksize < int(sizeof(stack)/sizeof(stack[0]))) {
traversestate &save = stack[stacksize++];
save.node = curnode + curnode->childindex(faridx);
save.tmin = max(tmin, farsplit);
save.tmax = tmax;
}
- else
- {
+ else {
if(traverse(m, o, ray, invray, maxdist, dist, mode, curnode + curnode->childindex(nearidx), tmin, min(tmax, nearsplit))) return true;
curnode += curnode->childindex(faridx);
tmin = max(tmin, farsplit);
@@ -119,11 +100,9 @@ inline bool BIH::traverse(const mesh &m, const vec &o, const vec &ray, const vec
}
}
-inline bool BIH::traverse(const vec &o, const vec &ray, float maxdist, float &dist, int mode)
-{
+inline bool BIH::traverse(const vec &o, const vec &ray, float maxdist, float &dist, int mode) {
vec invray(ray.x ? 1/ray.x : 1e16f, ray.y ? 1/ray.y : 1e16f, ray.z ? 1/ray.z : 1e16f);
- loopi(nummeshes)
- {
+ loopi(nummeshes) {
mesh &m = meshes[i];
if(!(mode&RAY_SHADOW) && m.flags&MESH_NOCLIP) continue;
float t1 = (m.bbmin.x - o.x)*invray.x,
@@ -142,34 +121,28 @@ inline bool BIH::traverse(const vec &o, const vec &ray, float maxdist, float &di
return false;
}
-void BIH::build(mesh &m, ushort *indices, int numindices, const ivec &vmin, const ivec &vmax)
-{
+void BIH::build(mesh &m, ushort *indices, int numindices, const ivec &vmin, const ivec &vmax) {
int axis = 2;
loopk(2) if(vmax[k] - vmin[k] > vmax[axis] - vmin[axis]) axis = k;
-
ivec leftmin, leftmax, rightmin, rightmax;
int splitleft, splitright;
int left, right;
- loopk(3)
- {
+ loopk(3) {
leftmin = rightmin = ivec(INT_MAX, INT_MAX, INT_MAX);
leftmax = rightmax = ivec(INT_MIN, INT_MIN, INT_MIN);
int split = (vmax[axis] + vmin[axis])/2;
- for(left = 0, right = numindices, splitleft = SHRT_MIN, splitright = SHRT_MAX; left < right;)
- {
+ for(left = 0, right = numindices, splitleft = SHRT_MIN, splitright = SHRT_MAX; left < right;) {
const tribb &tri = m.tribbs[indices[left]];
ivec trimin = ivec(tri.center).sub(ivec(tri.radius)),
trimax = ivec(tri.center).add(ivec(tri.radius));
int amin = trimin[axis], amax = trimax[axis];
- if(max(split - amin, 0) > max(amax - split, 0))
- {
+ if(max(split - amin, 0) > max(amax - split, 0)) {
++left;
splitleft = max(splitleft, amax);
leftmin.min(trimin);
leftmax.max(trimax);
}
- else
- {
+ else {
--right;
swap(indices[left], indices[right]);
splitright = min(splitright, amin);
@@ -180,68 +153,55 @@ void BIH::build(mesh &m, ushort *indices, int numindices, const ivec &vmin, cons
if(left > 0 && right < numindices) break;
axis = (axis+1)%3;
}
-
- if(!left || right==numindices)
- {
+ if(!left || right==numindices) {
leftmin = rightmin = ivec(INT_MAX, INT_MAX, INT_MAX);
leftmax = rightmax = ivec(INT_MIN, INT_MIN, INT_MIN);
left = right = numindices/2;
splitleft = SHRT_MIN;
splitright = SHRT_MAX;
- loopi(numindices)
- {
+ loopi(numindices) {
const tribb &tri = m.tribbs[indices[i]];
ivec trimin = ivec(tri.center).sub(ivec(tri.radius)),
trimax = ivec(tri.center).add(ivec(tri.radius));
- if(i < left)
- {
+ if(i < left) {
splitleft = max(splitleft, trimax[axis]);
leftmin.min(trimin);
leftmax.max(trimax);
}
- else
- {
+ else {
splitright = min(splitright, trimin[axis]);
rightmin.min(trimin);
rightmax.max(trimax);
}
}
}
-
int offset = m.numnodes++;
node &curnode = m.nodes[offset];
curnode.split[0] = short(splitleft);
curnode.split[1] = short(splitright);
-
if(left==1) curnode.child[0] = (axis<<14) | indices[0];
- else
- {
+ else {
curnode.child[0] = (axis<<14) | (m.numnodes - offset);
build(m, indices, left, leftmin, leftmax);
}
-
if(numindices-right==1) curnode.child[1] = (1<<15) | (left==1 ? 1<<14 : 0) | indices[right];
- else
- {
+ else {
curnode.child[1] = (left==1 ? 1<<14 : 0) | (m.numnodes - offset);
build(m, &indices[right], numindices-right, rightmin, rightmax);
}
}
BIH::BIH(vector<mesh> &buildmeshes)
- : meshes(NULL), nummeshes(0), nodes(NULL), numnodes(0), tribbs(NULL), numtris(0), bbmin(1e16f, 1e16f, 1e16f), bbmax(-1e16f, -1e16f, -1e16f), center(0, 0, 0), radius(0), entradius(0)
-{
+ : meshes(NULL), nummeshes(0), nodes(NULL), numnodes(0), tribbs(NULL), numtris(0), bbmin(1e16f, 1e16f, 1e16f), bbmax(-1e16f, -1e16f, -1e16f), center(0, 0, 0), radius(0), entradius(0) {
if(buildmeshes.empty()) return;
loopv(buildmeshes) numtris += buildmeshes[i].numtris;
if(!numtris) return;
-
nummeshes = buildmeshes.length();
meshes = new mesh[nummeshes];
memcpy(meshes, buildmeshes.getbuf(), sizeof(mesh)*buildmeshes.length());
tribbs = new tribb[numtris];
tribb *dsttri = tribbs;
- loopi(nummeshes)
- {
+ loopi(nummeshes) {
mesh &m = meshes[i];
m.scale = m.xform.a.magnitude();
m.invscale = 1/m.scale;
@@ -253,8 +213,7 @@ BIH::BIH(vector<mesh> &buildmeshes)
m.tribbs = dsttri;
const tri *srctri = m.tris;
vec mmin(1e16f, 1e16f, 1e16f), mmax(-1e16f, -1e16f, -1e16f);
- loopj(m.numtris)
- {
+ loopj(m.numtris) {
vec s0 = m.getpos(srctri->vert[0]), s1 = m.getpos(srctri->vert[1]), s2 = m.getpos(srctri->vert[2]),
v0 = m.xform.transform(s0), v1 = m.xform.transform(s1), v2 = m.xform.transform(s2),
vmin = vec(v0).min(v1).min(v2),
@@ -267,8 +226,7 @@ BIH::BIH(vector<mesh> &buildmeshes)
++srctri;
++dsttri;
}
- loopk(3) if(fabs(mmax[k] - mmin[k]) < 0.125f)
- {
+ loopk(3) if(fabs(mmax[k] - mmin[k]) < 0.125f) {
float mid = (mmin[k] + mmax[k]) / 2;
mmin[k] = mid - 0.0625f;
mmax[k] = mid + 0.0625f;
@@ -278,16 +236,13 @@ BIH::BIH(vector<mesh> &buildmeshes)
bbmin.min(mmin);
bbmax.max(mmax);
}
-
center = vec(bbmin).add(bbmax).mul(0.5f);
radius = vec(bbmax).sub(bbmin).mul(0.5f).magnitude();
entradius = max(bbmin.squaredlen(), bbmax.squaredlen());
-
nodes = new node[numtris];
node *curnode = nodes;
ushort *indices = new ushort[numtris];
- loopi(nummeshes)
- {
+ loopi(nummeshes) {
mesh &m = meshes[i];
m.nodes = curnode;
loopj(m.numtris) indices[j] = j;
@@ -298,19 +253,16 @@ BIH::BIH(vector<mesh> &buildmeshes)
numnodes = int(curnode - nodes);
}
-BIH::~BIH()
-{
+BIH::~BIH() {
delete[] meshes;
delete[] nodes;
delete[] tribbs;
}
-bool mmintersect(const extentity &e, const vec &o, const vec &ray, float maxdist, int mode, float &dist)
-{
+bool mmintersect(const extentity &e, const vec &o, const vec &ray, float maxdist, int mode, float &dist) {
model *m = loadmapmodel(e.attr2);
if(!m) return false;
- if(mode&RAY_SHADOW)
- {
+ if(mode&RAY_SHADOW) {
if(!m->shadow || e.flags&EF_NOSHADOW) return false;
}
else if((mode&RAY_ENTS)!=RAY_ENTS && (!m->collide || e.flags&EF_NOCOLLIDE)) return false;
@@ -319,8 +271,7 @@ bool mmintersect(const extentity &e, const vec &o, const vec &ray, float maxdist
float v = mo.dot(mray), inside = m->bih->entradius - mo.squaredlen();
if((inside < 0 && v > 0) || inside + v*v < 0) return false;
int yaw = e.attr1;
- if(yaw != 0)
- {
+ if(yaw != 0) {
const vec2 &rot = sincosmod360(-yaw);
mo.rotate_around_z(rot);
mray.rotate_around_z(rot);
diff --git a/src/engine/bih.h b/src/engine/bih.h
index 16da278..ac49c66 100644
--- a/src/engine/bih.h
+++ b/src/engine/bih.h
@@ -1,38 +1,25 @@
-struct BIH
-{
- struct node
- {
+struct BIH {
+ struct node {
short split[2];
ushort child[2];
-
int axis() const { return child[0]>>14; }
int childindex(int which) const { return child[which]&0x3FFF; }
bool isleaf(int which) const { return (child[1]&(1<<(14+which)))!=0; }
};
-
- struct tri
- {
+ struct tri {
ushort vert[3];
};
-
- struct tribb
- {
+ struct tribb {
svec center, radius;
-
- bool outside(const ivec &bo, const ivec &br) const
- {
+ bool outside(const ivec &bo, const ivec &br) const {
return abs(bo.x - center.x) > br.x + radius.x ||
abs(bo.y - center.y) > br.y + radius.y ||
abs(bo.z - center.z) > br.z + radius.z;
}
};
-
enum { MESH_NOCLIP = 1<<0, MESH_ALPHA = 1<<1, MESH_CULLFACE = 1<<2 };
-
- struct mesh
- {
+ struct mesh {
enum { MAXTRIS = 1<<14 };
-
matrix4x3 xform, invxform;
matrix3 xformnorm, invxformnorm;
float scale, invscale;
@@ -46,13 +33,10 @@ struct BIH
Texture *tex;
int flags;
vec bbmin, bbmax;
-
mesh() : numnodes(0), numtris(0), tex(NULL), flags(0) {}
-
vec getpos(int i) const { return *(const vec *)(pos + i*posstride); }
vec2 gettc(int i) const { return *(const vec2 *)(tc + i*tcstride); }
};
-
mesh *meshes;
int nummeshes;
node *nodes;
@@ -61,17 +45,12 @@ struct BIH
int numtris;
vec bbmin, bbmax, center;
float radius, entradius;
-
BIH(vector<mesh> &buildmeshes);
-
~BIH();
-
void build(mesh &m, ushort *indices, int numindices, const ivec &vmin, const ivec &vmax);
-
bool traverse(const vec &o, const vec &ray, float maxdist, float &dist, int mode);
bool traverse(const mesh &m, const vec &o, const vec &ray, const vec &invray, float maxdist, float &dist, int mode, node *curnode, float tmin, float tmax);
bool triintersect(const mesh &m, int tidx, const vec &mo, const vec &mray, float maxdist, float &dist, int mode);
-
void preload();
};
diff --git a/src/engine/client.cpp b/src/engine/client.cpp
index bd46b24..6ae6c27 100644
--- a/src/engine/client.cpp
+++ b/src/engine/client.cpp
@@ -6,15 +6,13 @@ ENetHost *clienthost = NULL;
ENetPeer *curpeer = NULL, *connpeer = NULL;
int connmillis = 0, connattempts = 0, discmillis = 0;
-bool multiplayer(bool msg)
-{
+bool multiplayer(bool msg) {
bool val = curpeer || hasnonlocalclients();
if(val && msg) conoutf(CON_ERROR, "operation not available in multiplayer");
return val;
}
-void setrate(int rate)
-{
+void setrate(int rate) {
if(!curpeer) return;
enet_host_bandwidth_limit(clienthost, rate*1024, rate*1024);
}
@@ -27,40 +25,34 @@ VARF(throttle_interval, 0, 5, 30, throttle());
VARF(throttle_accel, 0, 2, 32, throttle());
VARF(throttle_decel, 0, 2, 32, throttle());
-void throttle()
-{
+void throttle() {
if(!curpeer) return;
ASSERT(ENET_PEER_PACKET_THROTTLE_SCALE==32);
enet_peer_throttle_configure(curpeer, throttle_interval*1000, throttle_accel, throttle_decel);
}
-bool isconnected(bool attempt, bool local)
-{
+bool isconnected(bool attempt, bool local) {
return curpeer || (attempt && connpeer) || (local && haslocalclients());
}
ICOMMAND(isconnected, "bb", (int *attempt, int *local), intret(isconnected(*attempt > 0, *local != 0) ? 1 : 0));
-const ENetAddress *connectedpeer()
-{
+const ENetAddress *connectedpeer() {
return curpeer ? &curpeer->address : NULL;
}
-ICOMMAND(connectedip, "", (),
-{
+ICOMMAND(connectedip, "", (), {
const ENetAddress *address = connectedpeer();
string hostname;
result(address && enet_address_get_host_ip(address, hostname, sizeof(hostname)) >= 0 ? hostname : "");
});
-ICOMMAND(connectedport, "", (),
-{
+ICOMMAND(connectedport, "", (), {
const ENetAddress *address = connectedpeer();
intret(address ? address->port : -1);
});
-void abortconnect()
-{
+void abortconnect() {
if(!connpeer) return;
game::connectfail();
if(connpeer->state!=ENET_PEER_STATE_DISCONNECTED) enet_peer_reset(connpeer);
@@ -73,81 +65,61 @@ void abortconnect()
SVARP(connectname, "");
VARP(connectport, 0, 0, 0xFFFF);
-void connectserv(const char *servername, int serverport, const char *serverpassword)
-{
- if(connpeer)
- {
+void connectserv(const char *servername, int serverport, const char *serverpassword) {
+ if(connpeer) {
conoutf("aborting connection attempt");
abortconnect();
}
-
if(serverport <= 0) serverport = server::serverport();
-
ENetAddress address;
address.port = serverport;
-
- if(servername)
- {
+ if(servername) {
if(strcmp(servername, connectname)) setsvar("connectname", servername);
if(serverport != connectport) setvar("connectport", serverport);
addserver(servername, serverport, serverpassword && serverpassword[0] ? serverpassword : NULL);
conoutf("attempting to connect to %s:%d", servername, serverport);
- if(!resolverwait(servername, &address))
- {
+ if(!resolverwait(servername, &address)) {
conoutf(CON_ERROR, "\f3could not resolve server %s", servername);
return;
}
}
- else
- {
+ else {
setsvar("connectname", "");
setvar("connectport", 0);
conoutf("attempting to connect over LAN");
address.host = ENET_HOST_BROADCAST;
}
-
- if(!clienthost)
- {
+ if(!clienthost) {
clienthost = enet_host_create(NULL, 2, server::numchannels(), rate*1024, rate*1024);
- if(!clienthost)
- {
+ if(!clienthost) {
conoutf(CON_ERROR, "\f3could not connect to server");
return;
}
clienthost->duplicatePeers = 0;
}
-
connpeer = enet_host_connect(clienthost, &address, server::numchannels(), 0);
enet_host_flush(clienthost);
connmillis = totalmillis;
connattempts = 0;
-
game::connectattempt(servername ? servername : "", serverpassword ? serverpassword : "", address);
}
-void reconnect(const char *serverpassword)
-{
- if(!connectname[0] || connectport <= 0)
- {
+void reconnect(const char *serverpassword) {
+ if(!connectname[0] || connectport <= 0) {
conoutf(CON_ERROR, "no previous connection");
return;
}
-
connectserv(connectname, connectport, serverpassword);
}
-void disconnect(bool async, bool cleanup)
-{
- if(curpeer)
- {
- if(!discmillis)
- {
+void disconnect(bool async, bool cleanup) {
+ if(curpeer) {
+ if(!discmillis) {
enet_peer_disconnect(curpeer, DISC_NONE);
enet_host_flush(clienthost);
discmillis = totalmillis;
}
- if(curpeer->state!=ENET_PEER_STATE_DISCONNECTED)
- {
+ if(curpeer->state!=ENET_PEER_STATE_DISCONNECTED) {
if(async) return;
enet_peer_reset(curpeer);
}
@@ -157,22 +129,18 @@ void disconnect(bool async, bool cleanup)
game::gamedisconnect(cleanup);
mainmenu = 1;
}
- if(!connpeer && clienthost)
- {
+ if(!connpeer && clienthost) {
enet_host_destroy(clienthost);
clienthost = NULL;
}
}
-void trydisconnect(bool local)
-{
- if(connpeer)
- {
+void trydisconnect(bool local) {
+ if(connpeer) {
conoutf("aborting connection attempt");
abortconnect();
}
- else if(curpeer)
- {
+ else if(curpeer) {
conoutf("attempting to disconnect...");
disconnect(!discmillis);
}
@@ -187,50 +155,42 @@ ICOMMAND(disconnect, "b", (int *local), trydisconnect(*local != 0));
ICOMMAND(localconnect, "", (), { if(!isconnected()) localconnect(); });
ICOMMAND(localdisconnect, "", (), { if(haslocalclients()) localdisconnect(); });
-void sendclientpacket(ENetPacket *packet, int chan)
-{
+void sendclientpacket(ENetPacket *packet, int chan) {
if(curpeer) enet_peer_send(curpeer, chan, packet);
else localclienttoserver(chan, packet);
}
-void flushclient()
-{
+void flushclient() {
if(clienthost) enet_host_flush(clienthost);
}
-void neterr(const char *s, bool disc)
-{
+void neterr(const char *s, bool disc) {
conoutf(CON_ERROR, "\f3illegal network message (%s)", s);
if(disc) disconnect();
}
-void localservertoclient(int chan, ENetPacket *packet) // processes any updates from the server
-{
+void localservertoclient(int chan, ENetPacket *packet) { // processes any updates from the server {
packetbuf p(packet);
game::parsepacketclient(chan, p);
}
void clientkeepalive() { if(clienthost) enet_host_service(clienthost, NULL, 0); }
-void gets2c() // get updates from the server
-{
+void gets2c() { // get updates from the server {
ENetEvent event;
if(!clienthost) return;
- if(connpeer && totalmillis/3000 > connmillis/3000)
- {
+ if(connpeer && totalmillis/3000 > connmillis/3000) {
conoutf("attempting to connect...");
connmillis = totalmillis;
++connattempts;
- if(connattempts > 3)
- {
+ if(connattempts > 3) {
conoutf(CON_ERROR, "\f3could not connect to server");
abortconnect();
return;
}
}
while(clienthost && enet_host_service(clienthost, &event, 0)>0)
- switch(event.type)
- {
+ switch(event.type) {
case ENET_EVENT_TYPE_CONNECT:
disconnect(false, false);
localdisconnect(false);
@@ -241,24 +201,19 @@ void gets2c() // get updates from the server
if(rate) setrate(rate);
game::gameconnect(true);
break;
-
case ENET_EVENT_TYPE_RECEIVE:
if(discmillis) conoutf("attempting to disconnect...");
else localservertoclient(event.channelID, event.packet);
enet_packet_destroy(event.packet);
break;
-
case ENET_EVENT_TYPE_DISCONNECT:
if(event.data>=DISC_NUM) event.data = DISC_NONE;
- if(event.peer==connpeer)
- {
+ if(event.peer==connpeer) {
conoutf(CON_ERROR, "\f3could not connect to server");
abortconnect();
}
- else
- {
- if(!discmillis || event.data)
- {
+ else {
+ if(!discmillis || event.data) {
const char *msg = disconnectreason(event.data);
if(msg) conoutf(CON_ERROR, "\f3server network error, disconnecting (%s) ...", msg);
else conoutf(CON_ERROR, "\f3server network error, disconnecting...");
@@ -266,7 +221,6 @@ void gets2c() // get updates from the server
disconnect();
}
return;
-
default:
break;
}
diff --git a/src/engine/command.cpp b/src/engine/command.cpp
index 012b8c1..5248899 100644
--- a/src/engine/command.cpp
+++ b/src/engine/command.cpp
@@ -9,38 +9,31 @@ ident *dummyident = NULL;
int identflags = 0;
-enum
-{
+enum {
MAXARGS = 25,
MAXCOMARGS = 12
};
VARN(numargs, _numargs, MAXARGS, 0, 0);
-static inline void freearg(tagval &v)
-{
- switch(v.type)
- {
+static inline void freearg(tagval &v) {
+ switch(v.type) {
case VAL_STR: delete[] v.s; break;
case VAL_CODE: if(v.code[-1] == CODE_START) delete[] (uchar *)&v.code[-1]; break;
}
}
-static inline void forcenull(tagval &v)
-{
- switch(v.type)
- {
+static inline void forcenull(tagval &v) {
+ switch(v.type) {
case VAL_NULL: return;
}
freearg(v);
v.setnull();
}
-static inline float forcefloat(tagval &v)
-{
+static inline float forcefloat(tagval &v) {
float f = 0.0f;
- switch(v.type)
- {
+ switch(v.type) {
case VAL_INT: f = v.i; break;
case VAL_STR: f = parsefloat(v.s); break;
case VAL_MACRO: f = parsefloat(v.s); break;
@@ -51,11 +44,9 @@ static inline float forcefloat(tagval &v)
return f;
}
-static inline int forceint(tagval &v)
-{
+static inline int forceint(tagval &v) {
int i = 0;
- switch(v.type)
- {
+ switch(v.type) {
case VAL_FLOAT: i = v.f; break;
case VAL_STR: i = parseint(v.s); break;
case VAL_MACRO: i = parseint(v.s); break;
@@ -66,11 +57,9 @@ static inline int forceint(tagval &v)
return i;
}
-static inline const char *forcestr(tagval &v)
-{
+static inline const char *forcestr(tagval &v) {
const char *s = "";
- switch(v.type)
- {
+ switch(v.type) {
case VAL_FLOAT: s = floatstr(v.f); break;
case VAL_INT: s = intstr(v.i); break;
case VAL_STR:
@@ -82,29 +71,23 @@ static inline const char *forcestr(tagval &v)
return s;
}
-static inline void forcearg(tagval &v, int type)
-{
- switch(type)
- {
+static inline void forcearg(tagval &v, int type) {
+ switch(type) {
case RET_STR: if(v.type != VAL_STR) forcestr(v); break;
case RET_INT: if(v.type != VAL_INT) forceint(v); break;
case RET_FLOAT: if(v.type != VAL_FLOAT) forcefloat(v); break;
}
}
-static inline ident *forceident(tagval &v)
-{
- switch(v.type)
- {
+static inline ident *forceident(tagval &v) {
+ switch(v.type) {
case VAL_IDENT: return v.id;
- case VAL_MACRO:
- {
+ case VAL_MACRO: {
ident *id = newident(v.s, IDF_UNKNOWN);
v.setident(id);
return id;
}
- case VAL_STR:
- {
+ case VAL_STR: {
ident *id = newident(v.s, IDF_UNKNOWN);
delete[] v.s;
v.setident(id);
@@ -116,39 +99,31 @@ static inline ident *forceident(tagval &v)
return dummyident;
}
-void tagval::cleanup()
-{
+void tagval::cleanup() {
freearg(*this);
}
-static inline void freeargs(tagval *args, int &oldnum, int newnum)
-{
+static inline void freeargs(tagval *args, int &oldnum, int newnum) {
for(int i = newnum; i < oldnum; i++) freearg(args[i]);
oldnum = newnum;
}
-static inline void cleancode(ident &id)
-{
- if(id.code)
- {
+static inline void cleancode(ident &id) {
+ if(id.code) {
id.code[0] -= 0x100;
if(int(id.code[0]) < 0x100) delete[] id.code;
id.code = NULL;
}
}
-struct nullval : tagval
-{
+struct nullval : tagval {
nullval() { setnull(); }
} nullval;
tagval noret = nullval, *commandret = &noret;
-void clear_command()
-{
- enumerate(idents, ident, i,
- {
- if(i.type==ID_ALIAS)
- {
+void clear_command() {
+ enumerate(idents, ident, i, {
+ if(i.type==ID_ALIAS) {
DELETEA(i.name);
i.forcenull();
DELETEA(i.code);
@@ -156,14 +131,11 @@ void clear_command()
});
}
-void clearoverride(ident &i)
-{
+void clearoverride(ident &i) {
if(!(i.flags&IDF_OVERRIDDEN)) return;
- switch(i.type)
- {
+ switch(i.type) {
case ID_ALIAS:
- if(i.valtype==VAL_STR)
- {
+ if(i.valtype==VAL_STR) {
if(!i.val.s[0]) break;
delete[] i.val.s;
}
@@ -188,18 +160,15 @@ void clearoverride(ident &i)
i.flags &= ~IDF_OVERRIDDEN;
}
-void clearoverrides()
-{
+void clearoverrides() {
enumerate(idents, ident, i, clearoverride(i));
}
static bool initedidents = false;
static vector<ident> *identinits = NULL;
-static inline ident *addident(const ident &id)
-{
- if(!initedidents)
- {
+static inline ident *addident(const ident &id) {
+ if(!initedidents) {
if(!identinits) identinits = new vector<ident>;
identinits->add(id);
return NULL;
@@ -209,17 +178,14 @@ static inline ident *addident(const ident &id)
return identmap.add(&def);
}
-static bool initidents()
-{
+static bool initidents() {
initedidents = true;
- for(int i = 0; i < MAXARGS; i++)
- {
+ for(int i = 0; i < MAXARGS; i++) {
defformatstring(argname, "arg%d", i+1);
newident(argname, IDF_ARG);
}
dummyident = newident("//dummy", IDF_UNKNOWN);
- if(identinits)
- {
+ if(identinits) {
loopv(*identinits) addident((*identinits)[i]);
DELETEP(identinits);
}
@@ -229,17 +195,14 @@ UNUSED static bool forceinitidents = initidents();
static const char *sourcefile = NULL, *sourcestr = NULL;
-static const char *debugline(const char *p, const char *fmt)
-{
+static const char *debugline(const char *p, const char *fmt) {
if(!sourcestr) return fmt;
int num = 1;
const char *line = sourcestr;
- for(;;)
- {
+ for(;;) {
const char *end = strchr(line, '\n');
if(!end) end = line + strlen(line);
- if(p >= line && p <= end)
- {
+ if(p >= line && p <= end) {
static string buf;
if(sourcefile) formatstring(buf, "%s:%d: %s", sourcefile, num, fmt);
else formatstring(buf, "%d: %s", num, fmt);
@@ -252,8 +215,7 @@ static const char *debugline(const char *p, const char *fmt)
return fmt;
}
-static struct identlink
-{
+static struct identlink {
ident *id;
identlink *next;
int usedargs;
@@ -262,13 +224,11 @@ static struct identlink
VAR(dbgalias, 0, 4, 1000);
-static void debugalias()
-{
+static void debugalias() {
if(!dbgalias) return;
int total = 0, depth = 0;
for(identlink *l = aliasstack; l != &noalias; l = l->next) total++;
- for(identlink *l = aliasstack; l != &noalias; l = l->next)
- {
+ for(identlink *l = aliasstack; l != &noalias; l = l->next) {
ident *id = l->id;
++depth;
if(depth < dbgalias) conoutf(CON_ERROR, " %d) %s", total-depth+1, id->name);
@@ -280,41 +240,33 @@ static int nodebug = 0;
static void debugcode(const char *fmt, ...) PRINTFARGS(1, 2);
-static void debugcode(const char *fmt, ...)
-{
+static void debugcode(const char *fmt, ...) {
if(nodebug) return;
-
va_list args;
va_start(args, fmt);
conoutfv(CON_ERROR, fmt, args);
va_end(args);
-
debugalias();
}
static void debugcodeline(const char *p, const char *fmt, ...) PRINTFARGS(2, 3);
-static void debugcodeline(const char *p, const char *fmt, ...)
-{
+static void debugcodeline(const char *p, const char *fmt, ...) {
if(nodebug) return;
-
va_list args;
va_start(args, fmt);
conoutfv(CON_ERROR, debugline(p, fmt), args);
va_end(args);
-
debugalias();
}
ICOMMAND(nodebug, "e", (uint *body), { nodebug++; executeret(body, *commandret); nodebug--; });
-void addident(ident *id)
-{
+void addident(ident *id) {
addident(*id);
}
-static inline void pusharg(ident &id, const tagval &v, identstack &stack)
-{
+static inline void pusharg(ident &id, const tagval &v, identstack &stack) {
stack.val = id.val;
stack.valtype = id.valtype;
stack.next = id.stack;
@@ -323,8 +275,7 @@ static inline void pusharg(ident &id, const tagval &v, identstack &stack)
cleancode(id);
}
-static inline void poparg(ident &id)
-{
+static inline void poparg(ident &id) {
if(!id.stack) return;
identstack *stack = id.stack;
if(id.valtype == VAL_STR) delete[] id.val.s;
@@ -333,8 +284,7 @@ static inline void poparg(ident &id)
id.stack = stack->next;
}
-ICOMMAND(push, "rte", (ident *id, tagval *v, uint *code),
-{
+ICOMMAND(push, "rte", (ident *id, tagval *v, uint *code), {
if(id->type != ID_ALIAS || id->index < MAXARGS) return;
identstack stack;
pusharg(*id, *v, stack);
@@ -344,40 +294,32 @@ ICOMMAND(push, "rte", (ident *id, tagval *v, uint *code),
poparg(*id);
});
-static inline void pushalias(ident &id, identstack &stack)
-{
- if(id.type == ID_ALIAS && id.index >= MAXARGS)
- {
+static inline void pushalias(ident &id, identstack &stack) {
+ if(id.type == ID_ALIAS && id.index >= MAXARGS) {
pusharg(id, nullval, stack);
id.flags &= ~IDF_UNKNOWN;
}
}
-static inline void popalias(ident &id)
-{
+static inline void popalias(ident &id) {
if(id.type == ID_ALIAS && id.index >= MAXARGS) poparg(id);
}
KEYWORD(local, ID_LOCAL);
-static inline bool checknumber(const char *s)
-{
+static inline bool checknumber(const char *s) {
if(isdigit(s[0])) return true;
- else switch(s[0])
- {
+ else switch(s[0]) {
case '+': case '-': return isdigit(s[1]) || (s[1] == '.' && isdigit(s[2]));
case '.': return isdigit(s[1]) != 0;
default: return false;
}
}
-ident *newident(const char *name, int flags)
-{
+ident *newident(const char *name, int flags) {
ident *id = idents.access(name);
- if(!id)
- {
- if(checknumber(name))
- {
+ if(!id) {
+ if(checknumber(name)) {
debugcode("number %s is not a valid identifier name", name);
return dummyident;
}
@@ -386,27 +328,23 @@ ident *newident(const char *name, int flags)
return id;
}
-ident *writeident(const char *name, int flags)
-{
+ident *writeident(const char *name, int flags) {
ident *id = newident(name, flags);
- if(id->index < MAXARGS && !(aliasstack->usedargs&(1<<id->index)))
- {
+ if(id->index < MAXARGS && !(aliasstack->usedargs&(1<<id->index))) {
pusharg(*id, nullval, aliasstack->argstack[id->index]);
aliasstack->usedargs |= 1<<id->index;
}
return id;
}
-ident *readident(const char *name)
-{
+ident *readident(const char *name) {
ident *id = idents.access(name);
if(id && id->index < MAXARGS && !(aliasstack->usedargs&(1<<id->index)))
return NULL;
return id;
}
-void resetvar(char *name)
-{
+void resetvar(char *name) {
ident *id = idents.access(name);
if(!id) return;
if(id->flags&IDF_READONLY) debugcode("variable %s is read-only", id->name);
@@ -415,89 +353,73 @@ void resetvar(char *name)
COMMAND(resetvar, "s");
-static inline void setarg(ident &id, tagval &v)
-{
- if(aliasstack->usedargs&(1<<id.index))
- {
+static inline void setarg(ident &id, tagval &v) {
+ if(aliasstack->usedargs&(1<<id.index)) {
if(id.valtype == VAL_STR) delete[] id.val.s;
id.setval(v);
cleancode(id);
}
- else
- {
+ else {
pusharg(id, v, aliasstack->argstack[id.index]);
aliasstack->usedargs |= 1<<id.index;
}
}
-static inline void setalias(ident &id, tagval &v)
-{
+static inline void setalias(ident &id, tagval &v) {
if(id.valtype == VAL_STR) delete[] id.val.s;
id.setval(v);
cleancode(id);
id.flags = (id.flags & identflags) | identflags;
}
-static void setalias(const char *name, tagval &v)
-{
+static void setalias(const char *name, tagval &v) {
ident *id = idents.access(name);
- if(id)
- {
- if(id->type == ID_ALIAS)
- {
+ if(id) {
+ if(id->type == ID_ALIAS) {
if(id->index < MAXARGS) setarg(*id, v); else setalias(*id, v);
}
- else
- {
+ else {
debugcode("cannot redefine builtin %s with an alias", id->name);
freearg(v);
}
}
- else if(checknumber(name))
- {
+ else if(checknumber(name)) {
debugcode("cannot alias number %s", name);
freearg(v);
}
- else
- {
+ else {
addident(ident(ID_ALIAS, newstring(name), v, identflags));
}
}
-void alias(const char *name, const char *str)
-{
+void alias(const char *name, const char *str) {
tagval v;
v.setstr(newstring(str));
setalias(name, v);
}
-void alias(const char *name, tagval &v)
-{
+void alias(const char *name, tagval &v) {
setalias(name, v);
}
-ICOMMAND(alias, "st", (const char *name, tagval *v),
-{
+ICOMMAND(alias, "st", (const char *name, tagval *v), {
setalias(name, *v);
v->type = VAL_NULL;
});
// variable's and commands are registered through globals, see cube.h
-int variable(const char *name, int min, int cur, int max, int *storage, identfun fun, int flags)
-{
+int variable(const char *name, int min, int cur, int max, int *storage, identfun fun, int flags) {
addident(ident(ID_VAR, name, min, max, storage, (void *)fun, flags));
return cur;
}
-float fvariable(const char *name, float min, float cur, float max, float *storage, identfun fun, int flags)
-{
+float fvariable(const char *name, float min, float cur, float max, float *storage, identfun fun, int flags) {
addident(ident(ID_FVAR, name, min, max, storage, (void *)fun, flags));
return cur;
}
-char *svariable(const char *name, const char *cur, char **storage, identfun fun, int flags)
-{
+char *svariable(const char *name, const char *cur, char **storage, identfun fun, int flags) {
addident(ident(ID_SVAR, name, storage, (void *)fun, flags));
return newstring(cur);
}
@@ -507,67 +429,59 @@ char *svariable(const char *name, const char *cur, char **storage, identfun fun,
if(!id || id->type!=vartype) return retval;
#define GETVAR(id, name, retval) _GETVAR(id, ID_VAR, name, retval)
#define OVERRIDEVAR(errorval, saveval, resetval, clearval) \
- if(identflags&IDF_OVERRIDDEN || id->flags&IDF_OVERRIDE) \
- { \
- if(id->flags&IDF_PERSIST) \
- { \
+ if(identflags&IDF_OVERRIDDEN || id->flags&IDF_OVERRIDE) { \
+ \
+ if(id->flags&IDF_PERSIST) { \
+ \
debugcode("cannot override persistent variable %s", id->name); \
errorval; \
} \
if(!(id->flags&IDF_OVERRIDDEN)) { saveval; id->flags |= IDF_OVERRIDDEN; } \
else { clearval; } \
} \
- else \
- { \
+ else { \
+ \
if(id->flags&IDF_OVERRIDDEN) { resetval; id->flags &= ~IDF_OVERRIDDEN; } \
clearval; \
}
-void setvar(const char *name, int i, bool dofunc, bool doclamp)
-{
+void setvar(const char *name, int i, bool dofunc, bool doclamp) {
GETVAR(id, name, );
OVERRIDEVAR(return, id->overrideval.i = *id->storage.i, , )
if(doclamp) *id->storage.i = clamp(i, id->minval, id->maxval);
else *id->storage.i = i;
if(dofunc) id->changed();
}
-void setfvar(const char *name, float f, bool dofunc, bool doclamp)
-{
+void setfvar(const char *name, float f, bool dofunc, bool doclamp) {
_GETVAR(id, ID_FVAR, name, );
OVERRIDEVAR(return, id->overrideval.f = *id->storage.f, , );
if(doclamp) *id->storage.f = clamp(f, id->minvalf, id->maxvalf);
else *id->storage.f = f;
if(dofunc) id->changed();
}
-void setsvar(const char *name, const char *str, bool dofunc)
-{
+void setsvar(const char *name, const char *str, bool dofunc) {
_GETVAR(id, ID_SVAR, name, );
OVERRIDEVAR(return, id->overrideval.s = *id->storage.s, delete[] id->overrideval.s, delete[] *id->storage.s);
*id->storage.s = newstring(str);
if(dofunc) id->changed();
}
-int getvar(const char *name)
-{
+int getvar(const char *name) {
GETVAR(id, name, 0);
return *id->storage.i;
}
-int getvarmin(const char *name)
-{
+int getvarmin(const char *name) {
GETVAR(id, name, 0);
return id->minval;
}
-int getvarmax(const char *name)
-{
+int getvarmax(const char *name) {
GETVAR(id, name, 0);
return id->maxval;
}
-float getfvarmin(const char *name)
-{
+float getfvarmin(const char *name) {
_GETVAR(id, ID_FVAR, name, 0);
return id->minvalf;
}
-float getfvarmax(const char *name)
-{
+float getfvarmax(const char *name) {
_GETVAR(id, ID_FVAR, name, 0);
return id->maxvalf;
}
@@ -580,11 +494,9 @@ ICOMMAND(getfvarmax, "s", (char *s), floatret(getfvarmax(s)));
bool identexists(const char *name) { return idents.access(name)!=NULL; }
ident *getident(const char *name) { return idents.access(name); }
-void touchvar(const char *name)
-{
+void touchvar(const char *name) {
ident *id = idents.access(name);
- if(id) switch(id->type)
- {
+ if(id) switch(id->type) {
case ID_VAR:
case ID_FVAR:
case ID_SVAR:
@@ -593,16 +505,14 @@ void touchvar(const char *name)
}
}
-const char *getalias(const char *name)
-{
+const char *getalias(const char *name) {
ident *i = idents.access(name);
return i && i->type==ID_ALIAS && (i->index >= MAXARGS || aliasstack->usedargs&(1<<i->index)) ? i->getstr() : "";
}
ICOMMAND(getalias, "s", (char *s), result(getalias(s)));
-int clampvar(ident *id, int val, int minval, int maxval)
-{
+int clampvar(ident *id, int val, int minval, int maxval) {
if(val < minval) val = minval;
else if(val > maxval) val = maxval;
else return val;
@@ -613,15 +523,13 @@ int clampvar(ident *id, int val, int minval, int maxval)
return val;
}
-void setvarchecked(ident *id, int val)
-{
+void setvarchecked(ident *id, int val) {
if(id->flags&IDF_READONLY) debugcode("variable %s is read-only", id->name);
#ifndef STANDALONE
- else if(!(id->flags&IDF_OVERRIDE) || identflags&IDF_OVERRIDDEN || game::allowedittoggle())
+ else if(!(id->flags&IDF_OVERRIDE) || identflags&IDF_OVERRIDDEN || game::allowedittoggle()) {
#else
- else
+ else {
#endif
- {
OVERRIDEVAR(return, id->overrideval.i = *id->storage.i, , )
if(val < id->minval || val > id->maxval) val = clampvar(id, val, id->minval, id->maxval);
*id->storage.i = val;
@@ -632,19 +540,16 @@ void setvarchecked(ident *id, int val)
}
}
-static inline void setvarchecked(ident *id, tagval *args, int numargs)
-{
+static inline void setvarchecked(ident *id, tagval *args, int numargs) {
int val = forceint(args[0]);
- if(id->flags&IDF_HEX && numargs > 1)
- {
+ if(id->flags&IDF_HEX && numargs > 1) {
val = (val << 16) | (forceint(args[1])<<8);
if(numargs > 2) val |= forceint(args[2]);
}
setvarchecked(id, val);
}
-float clampfvar(ident *id, float val, float minval, float maxval)
-{
+float clampfvar(ident *id, float val, float minval, float maxval) {
if(val < minval) val = minval;
else if(val > maxval) val = maxval;
else return val;
@@ -652,15 +557,13 @@ float clampfvar(ident *id, float val, float minval, float maxval)
return val;
}
-void setfvarchecked(ident *id, float val)
-{
+void setfvarchecked(ident *id, float val) {
if(id->flags&IDF_READONLY) debugcode("variable %s is read-only", id->name);
#ifndef STANDALONE
- else if(!(id->flags&IDF_OVERRIDE) || identflags&IDF_OVERRIDDEN || game::allowedittoggle())
+ else if(!(id->flags&IDF_OVERRIDE) || identflags&IDF_OVERRIDDEN || game::allowedittoggle()) {
#else
- else
+ else {
#endif
- {
OVERRIDEVAR(return, id->overrideval.f = *id->storage.f, , );
if(val < id->minvalf || val > id->maxvalf) val = clampfvar(id, val, id->minvalf, id->maxvalf);
*id->storage.f = val;
@@ -671,15 +574,13 @@ void setfvarchecked(ident *id, float val)
}
}
-void setsvarchecked(ident *id, const char *val)
-{
+void setsvarchecked(ident *id, const char *val) {
if(id->flags&IDF_READONLY) debugcode("variable %s is read-only", id->name);
#ifndef STANDALONE
- else if(!(id->flags&IDF_OVERRIDE) || identflags&IDF_OVERRIDDEN || game::allowedittoggle())
+ else if(!(id->flags&IDF_OVERRIDE) || identflags&IDF_OVERRIDDEN || game::allowedittoggle()) {
#else
- else
+ else {
#endif
- {
OVERRIDEVAR(return, id->overrideval.s = *id->storage.s, delete[] id->overrideval.s, delete[] *id->storage.s);
*id->storage.s = newstring(val);
id->changed();
@@ -689,10 +590,8 @@ void setsvarchecked(ident *id, const char *val)
}
}
-ICOMMAND(set, "rt", (ident *id, tagval *v),
-{
- switch(id->type)
- {
+ICOMMAND(set, "rt", (ident *id, tagval *v), {
+ switch(id->type) {
case ID_ALIAS:
if(id->index < MAXARGS) setarg(*id, *v); else setalias(*id, *v);
v->type = VAL_NULL;
@@ -707,8 +606,7 @@ ICOMMAND(set, "rt", (ident *id, tagval *v),
setsvarchecked(id, forcestr(*v));
break;
case ID_COMMAND:
- if(id->flags&IDF_EMUVAR)
- {
+ if(id->flags&IDF_EMUVAR) {
execute(id, v, 1);
v->type = VAL_NULL;
break;
@@ -720,13 +618,11 @@ ICOMMAND(set, "rt", (ident *id, tagval *v),
}
});
-bool addcommand(const char *name, identfun fun, const char *args)
-{
+bool addcommand(const char *name, identfun fun, const char *args) {
uint argmask = 0;
int numargs = 0, flags = 0;
bool limit = true;
- for(const char *fmt = args; *fmt; fmt++) switch(*fmt)
- {
+ for(const char *fmt = args; *fmt; fmt++) switch(*fmt) {
case 'i': case 'b': case 'f': case 't': case 'N': case 'D': if(numargs < MAXARGS) numargs++; break;
case '$': flags |= IDF_EMUVAR; // fall through
case 's': case 'e': case 'r': if(numargs < MAXARGS) { argmask |= 1<<numargs; numargs++; } break;
@@ -739,16 +635,13 @@ bool addcommand(const char *name, identfun fun, const char *args)
return false;
}
-bool addkeyword(int type, const char *name)
-{
+bool addkeyword(int type, const char *name) {
addident(ident(type, name, "", 0, 0, NULL));
return true;
}
-const char *parsestring(const char *p)
-{
- for(; *p; p++) switch(*p)
- {
+const char *parsestring(const char *p) {
+ for(; *p; p++) switch(*p) {
case '\r':
case '\n':
case '\"':
@@ -760,18 +653,14 @@ const char *parsestring(const char *p)
return p;
}
-int unescapestring(char *dst, const char *src, const char *end)
-{
+int unescapestring(char *dst, const char *src, const char *end) {
char *start = dst;
- while(src < end)
- {
+ while(src < end) {
int c = *src++;
- if(c == '^')
- {
+ if(c == '^') {
if(src >= end) break;
int e = *src++;
- switch(e)
- {
+ switch(e) {
case 'n': *dst++ = '\n'; break;
case 't': *dst++ = '\t'; break;
case 'f': *dst++ = '\f'; break;
@@ -783,19 +672,15 @@ int unescapestring(char *dst, const char *src, const char *end)
return dst - start;
}
-static char *conc(vector<char> &buf, tagval *v, int n, bool space, const char *prefix = NULL, int prefixlen = 0)
-{
- if(prefix)
- {
+static char *conc(vector<char> &buf, tagval *v, int n, bool space, const char *prefix = NULL, int prefixlen = 0) {
+ if(prefix) {
buf.put(prefix, prefixlen);
if(space && n) buf.add(' ');
}
- loopi(n)
- {
+ loopi(n) {
const char *s = "";
int len = 0;
- switch(v[i].type)
- {
+ switch(v[i].type) {
case VAL_INT: s = intstr(v[i].i); break;
case VAL_FLOAT: s = floatstr(v[i].f); break;
case VAL_STR: s = v[i].s; break;
@@ -811,13 +696,11 @@ static char *conc(vector<char> &buf, tagval *v, int n, bool space, const char *p
return buf.getbuf();
}
-static char *conc(tagval *v, int n, bool space, const char *prefix, int prefixlen)
-{
+static char *conc(tagval *v, int n, bool space, const char *prefix, int prefixlen) {
static int vlen[MAXARGS];
static char numbuf[3*MAXSTRLEN];
int len = prefixlen, numlen = 0, i = 0;
- for(; i < n; i++) switch(v[i].type)
- {
+ for(; i < n; i++) switch(v[i].type) {
case VAL_MACRO: len += (vlen[i] = v[i].code[-1]>>8); break;
case VAL_STR: len += (vlen[i] = int(strlen(v[i].s))); break;
case VAL_INT:
@@ -836,16 +719,13 @@ overflow:
if(space) len += max(prefix ? i : i-1, 0);
char *buf = newstring(len + numlen);
int offset = 0, numoffset = 0;
- if(prefix)
- {
+ if(prefix) {
memcpy(buf, prefix, prefixlen);
offset += prefixlen;
if(space && i) buf[offset++] = ' ';
}
- loopj(i)
- {
- if(v[j].type == VAL_INT || v[j].type == VAL_FLOAT)
- {
+ loopj(i) {
+ if(v[j].type == VAL_INT || v[j].type == VAL_FLOAT) {
memcpy(&buf[offset], &numbuf[numoffset], vlen[j]);
numoffset += vlen[j];
}
@@ -855,8 +735,7 @@ overflow:
if(space) buf[offset++] = ' ';
}
buf[offset] = '\0';
- if(i < n)
- {
+ if(i < n) {
char *morebuf = conc(&v[i], n-i, space, buf, offset);
delete[] buf;
return morebuf;
@@ -864,28 +743,23 @@ overflow:
return buf;
}
-static inline char *conc(tagval *v, int n, bool space)
-{
+static inline char *conc(tagval *v, int n, bool space) {
return conc(v, n, space, NULL, 0);
}
-static inline char *conc(tagval *v, int n, bool space, const char *prefix)
-{
+static inline char *conc(tagval *v, int n, bool space, const char *prefix) {
return conc(v, n, space, prefix, strlen(prefix));
}
-static inline void skipcomments(const char *&p)
-{
- for(;;)
- {
+static inline void skipcomments(const char *&p) {
+ for(;;) {
p += strspn(p, " \t\r");
if(p[0]!='/' || p[1]!='/') break;
p += strcspn(p, "\n\0");
}
}
-static inline char *cutstring(const char *&p, int &len)
-{
+static inline char *cutstring(const char *&p, int &len) {
p++;
const char *end = parsestring(p);
char *s = newstring(end - p);
@@ -896,16 +770,13 @@ static inline char *cutstring(const char *&p, int &len)
return s;
}
-static inline const char *parseword(const char *p)
-{
+static inline const char *parseword(const char *p) {
const int maxbrak = 100;
static char brakstack[maxbrak];
int brakdepth = 0;
- for(;; p++)
- {
+ for(;; p++) {
p += strcspn(p, "\"/;()[] \t\r\n\0");
- switch(p[0])
- {
+ switch(p[0]) {
case '"': case ';': case ' ': case '\t': case '\r': case '\n': case '\0': return p;
case '/': if(p[1] == '/') return p; break;
case '[': case '(': if(brakdepth >= maxbrak) return p; brakstack[brakdepth++] = p[0]; break;
@@ -916,8 +787,7 @@ static inline const char *parseword(const char *p)
return p;
}
-static inline char *cutword(const char *&p, int &len)
-{
+static inline char *cutword(const char *&p, int &len) {
const char *word = p;
p = parseword(p);
len = p-word;
@@ -925,10 +795,8 @@ static inline char *cutword(const char *&p, int &len)
return newstring(word, len);
}
-static inline void compilestr(vector<uint> &code, const char *word, int len, bool macro = false)
-{
- if(len <= 3 && !macro)
- {
+static inline void compilestr(vector<uint> &code, const char *word, int len, bool macro = false) {
+ if(len <= 3 && !macro) {
uint op = CODE_VALI|RET_STR;
for(int i = 0; i < len; i++) op |= uint(uchar(word[i]))<<((i+1)*8);
code.add(op);
@@ -937,8 +805,7 @@ static inline void compilestr(vector<uint> &code, const char *word, int len, boo
code.add((macro ? CODE_MACRO : CODE_VAL|RET_STR)|(len<<8));
code.put((const uint *)word, len/sizeof(uint));
size_t endlen = len%sizeof(uint);
- union
- {
+ union {
char c[sizeof(uint)];
uint u;
} end;
@@ -947,30 +814,25 @@ static inline void compilestr(vector<uint> &code, const char *word, int len, boo
code.add(end.u);
}
-static inline void compilestr(vector<uint> &code, const char *word = NULL)
-{
+static inline void compilestr(vector<uint> &code, const char *word = NULL) {
if(!word) { code.add(CODE_VALI|RET_STR); return; }
compilestr(code, word, int(strlen(word)));
}
-static inline void compileint(vector<uint> &code, int i)
-{
+static inline void compileint(vector<uint> &code, int i) {
if(i >= -0x800000 && i <= 0x7FFFFF)
code.add(CODE_VALI|RET_INT|(i<<8));
- else
- {
+ else {
code.add(CODE_VAL|RET_INT);
code.add(i);
}
}
-static inline void compilenull(vector<uint> &code)
-{
+static inline void compilenull(vector<uint> &code) {
code.add(CODE_VALI|RET_NULL);
}
-static inline void compileblock(vector<uint> &code)
-{
+static inline void compileblock(vector<uint> &code) {
int start = code.length();
code.add(CODE_BLOCK);
code.add(CODE_OFFSET|((start+2)<<8));
@@ -978,27 +840,22 @@ static inline void compileblock(vector<uint> &code)
code[start] |= uint(code.length() - (start + 1))<<8;
}
-static inline void compileident(vector<uint> &code, ident *id)
-{
+static inline void compileident(vector<uint> &code, ident *id) {
code.add((id->index < MAXARGS ? CODE_IDENTARG : CODE_IDENT)|(id->index<<8));
}
-static inline void compileident(vector<uint> &code, const char *word = NULL)
-{
+static inline void compileident(vector<uint> &code, const char *word = NULL) {
compileident(code, word ? newident(word, IDF_UNKNOWN) : dummyident);
}
-static inline void compileint(vector<uint> &code, const char *word = NULL)
-{
+static inline void compileint(vector<uint> &code, const char *word = NULL) {
return compileint(code, word ? parseint(word) : 0);
}
-static inline void compilefloat(vector<uint> &code, float f)
-{
+static inline void compilefloat(vector<uint> &code, float f) {
if(int(f) == f && f >= -0x800000 && f <= 0x7FFFFF)
code.add(CODE_VALI|RET_FLOAT|(int(f)<<8));
- else
- {
+ else {
union { float f; uint u; } conv;
conv.f = f;
code.add(CODE_VAL|RET_FLOAT);
@@ -1006,24 +863,20 @@ static inline void compilefloat(vector<uint> &code, float f)
}
}
-static inline void compilefloat(vector<uint> &code, const char *word = NULL)
-{
+static inline void compilefloat(vector<uint> &code, const char *word = NULL) {
return compilefloat(code, word ? parsefloat(word) : 0.0f);
}
static bool compilearg(vector<uint> &code, const char *&p, int wordtype);
static void compilestatements(vector<uint> &code, const char *&p, int rettype, int brak = '\0');
-static inline void compileval(vector<uint> &code, int wordtype, char *word, int wordlen)
-{
- switch(wordtype)
- {
+static inline void compileval(vector<uint> &code, int wordtype, char *word, int wordlen) {
+ switch(wordtype) {
case VAL_STR: compilestr(code, word, wordlen, true); break;
case VAL_ANY: compilestr(code, word, wordlen); break;
case VAL_FLOAT: compilefloat(code, word); break;
case VAL_INT: compileint(code, word); break;
- case VAL_CODE:
- {
+ case VAL_CODE: {
int start = code.length();
code.add(CODE_BLOCK);
code.add(CODE_OFFSET|((start+2)<<8));
@@ -1041,12 +894,10 @@ static inline void compileval(vector<uint> &code, int wordtype, char *word, int
static bool compileword(vector<uint> &code, const char *&p, int wordtype, char *&word, int &wordlen);
-static void compilelookup(vector<uint> &code, const char *&p, int ltype)
-{
+static void compilelookup(vector<uint> &code, const char *&p, int ltype) {
char *lookup = NULL;
int lookuplen = 0;
- switch(*++p)
- {
+ switch(*++p) {
case '(':
case '[':
if(!compileword(code, p, VAL_STR, lookup, lookuplen)) goto invalid;
@@ -1057,24 +908,20 @@ static void compilelookup(vector<uint> &code, const char *&p, int ltype)
case '\"':
lookup = cutstring(p, lookuplen);
goto lookupid;
- default:
- {
+ default: {
lookup = cutword(p, lookuplen);
if(!lookup) goto invalid;
lookupid:
ident *id = newident(lookup, IDF_UNKNOWN);
- if(id) switch(id->type)
- {
+ if(id) switch(id->type) {
case ID_VAR: code.add(CODE_IVAR|((ltype >= VAL_ANY ? VAL_INT : ltype)<<CODE_RET)|(id->index<<8)); goto done;
case ID_FVAR: code.add(CODE_FVAR|((ltype >= VAL_ANY ? VAL_FLOAT : ltype)<<CODE_RET)|(id->index<<8)); goto done;
case ID_SVAR: code.add(CODE_SVAR|((ltype >= VAL_ANY ? VAL_STR : ltype)<<CODE_RET)|(id->index<<8)); goto done;
case ID_ALIAS: code.add((id->index < MAXARGS ? CODE_LOOKUPARG : CODE_LOOKUP)|((ltype >= VAL_ANY ? VAL_STR : ltype)<<CODE_RET)|(id->index<<8)); goto done;
- case ID_COMMAND:
- {
+ case ID_COMMAND: {
int comtype = CODE_COM, numargs = 0;
code.add(CODE_ENTER);
- for(const char *fmt = id->args; *fmt; fmt++) switch(*fmt)
- {
+ for(const char *fmt = id->args; *fmt; fmt++) switch(*fmt) {
case 's': compilestr(code, NULL, 0, true); numargs++; break;
case 'i': compileint(code); numargs++; break;
case 'b': compileint(code, INT_MIN); numargs++; break;
@@ -1105,37 +952,31 @@ static void compilelookup(vector<uint> &code, const char *&p, int ltype)
code.add(CODE_LOOKUPU|((ltype < VAL_ANY ? ltype<<CODE_RET : 0)));
done:
delete[] lookup;
- switch(ltype)
- {
+ switch(ltype) {
case VAL_CODE: code.add(CODE_COMPILE); break;
case VAL_IDENT: code.add(CODE_IDENTU); break;
}
return;
invalid:
- switch(ltype)
- {
+ switch(ltype) {
case VAL_NULL: case VAL_ANY: compilenull(code); break;
default: compileval(code, ltype, NULL, 0); break;
}
}
-static bool compileblockstr(vector<uint> &code, const char *str, const char *end, bool macro)
-{
+static bool compileblockstr(vector<uint> &code, const char *str, const char *end, bool macro) {
int start = code.length();
code.add(macro ? CODE_MACRO : CODE_VAL|RET_STR);
char *buf = (char *)code.reserve((end-str)/sizeof(uint)+1).buf;
int len = 0;
- while(str < end)
- {
+ while(str < end) {
int n = strcspn(str, "\r/\"@]\0");
memcpy(&buf[len], str, n);
len += n;
str += n;
- switch(*str)
- {
+ switch(*str) {
case '\r': str++; break;
- case '\"':
- {
+ case '\"': {
const char *start = str;
str = parsestring(str+1);
if(*str=='\"') str++;
@@ -1144,11 +985,9 @@ static bool compileblockstr(vector<uint> &code, const char *str, const char *end
break;
}
case '/':
- if(str[1] == '/')
- {
+ if(str[1] == '/') {
size_t comment = strcspn(str, "\n\0");
- if (iscubepunct(str[2]))
- {
+ if (iscubepunct(str[2])) {
memcpy(&buf[len], str, comment);
len += comment;
}
@@ -1171,12 +1010,10 @@ done:
return true;
}
-static bool compileblocksub(vector<uint> &code, const char *&p)
-{
+static bool compileblocksub(vector<uint> &code, const char *&p) {
char *lookup = NULL;
int lookuplen = 0;
- switch(*p)
- {
+ switch(*p) {
case '(':
if(!compilearg(code, p, VAL_STR)) return false;
break;
@@ -1187,9 +1024,8 @@ static bool compileblocksub(vector<uint> &code, const char *&p)
case '\"':
lookup = cutstring(p, lookuplen);
goto lookupid;
- default:
- {
- {
+ default: {
+ {
const char *start = p;
while(iscubealnum(*p) || *p=='_') p++;
lookuplen = p-start;
@@ -1198,8 +1034,7 @@ static bool compileblocksub(vector<uint> &code, const char *&p)
}
lookupid:
ident *id = newident(lookup, IDF_UNKNOWN);
- if(id) switch(id->type)
- {
+ if(id) switch(id->type) {
case ID_VAR: code.add(CODE_IVAR|RET_STR|(id->index<<8)); goto done;
case ID_FVAR: code.add(CODE_FVAR|RET_STR|(id->index<<8)); goto done;
case ID_SVAR: code.add(CODE_SVAR|RET_STR|(id->index<<8)); goto done;
@@ -1215,16 +1050,13 @@ static bool compileblocksub(vector<uint> &code, const char *&p)
return true;
}
-static void compileblock(vector<uint> &code, const char *&p, int wordtype)
-{
+static void compileblock(vector<uint> &code, const char *&p, int wordtype) {
const char *line = p, *start = p;
int concs = 0;
- for(int brak = 1; brak;)
- {
+ for(int brak = 1; brak;) {
p += strcspn(p, "@\"/[]\0");
int c = *p++;
- switch(c)
- {
+ switch(c) {
case '\0':
debugcodeline(line, "missing \"]\"");
p--;
@@ -1238,16 +1070,14 @@ static void compileblock(vector<uint> &code, const char *&p, int wordtype)
break;
case '[': brak++; break;
case ']': brak--; break;
- case '@':
- {
+ case '@': {
const char *esc = p;
while(*p == '@') p++;
int level = p - (esc - 1);
if(brak > level) continue;
else if(brak < level) debugcodeline(line, "too many @s");
if(!concs) code.add(CODE_ENTER);
- if(concs + 2 > MAXARGS)
- {
+ if(concs + 2 > MAXARGS) {
code.add(CODE_CONCW|RET_STR|(concs<<8));
concs = 1;
}
@@ -1260,12 +1090,9 @@ static void compileblock(vector<uint> &code, const char *&p, int wordtype)
}
}
done:
- if(p-1 > start)
- {
- if(!concs) switch(wordtype)
- {
- case VAL_CODE:
- {
+ if(p-1 > start) {
+ if(!concs) switch(wordtype) {
+ case VAL_CODE: {
p = start;
int inst = code.length();
code.add(CODE_BLOCK);
@@ -1275,8 +1102,7 @@ done:
code[inst] |= uint(code.length() - (inst + 1))<<8;
return;
}
- case VAL_IDENT:
- {
+ case VAL_IDENT: {
char *name = newstring(start, p-1-start);
compileident(code, name);
delete[] name;
@@ -1286,21 +1112,18 @@ done:
compileblockstr(code, start, p-1, concs > 0);
if(concs > 1) concs++;
}
- if(concs)
- {
+ if(concs) {
code.add(CODE_CONCM|(wordtype < VAL_ANY ? wordtype<<CODE_RET : RET_STR)|(concs<<8));
code.add(CODE_EXIT|(wordtype < VAL_ANY ? wordtype<<CODE_RET : RET_STR));
}
- switch(wordtype)
- {
+ switch(wordtype) {
case VAL_CODE: if(!concs && p-1 <= start) compileblock(code); else code.add(CODE_COMPILE); break;
case VAL_IDENT: if(!concs && p-1 <= start) compileident(code); else code.add(CODE_IDENTU); break;
case VAL_STR: case VAL_NULL: case VAL_ANY:
if(!concs && p-1 <= start) compilestr(code);
break;
default:
- if(!concs)
- {
+ if(!concs) {
if(p-1 <= start) compileval(code, wordtype, NULL, 0);
else code.add(CODE_FORCE|(wordtype<<CODE_RET));
}
@@ -1308,11 +1131,9 @@ done:
}
}
-static bool compileword(vector<uint> &code, const char *&p, int wordtype, char *&word, int &wordlen)
-{
+static bool compileword(vector<uint> &code, const char *&p, int wordtype, char *&word, int &wordlen) {
skipcomments(p);
- switch(*p)
- {
+ switch(*p) {
case '\"': word = cutstring(p, wordlen); break;
case '$': compilelookup(code, p, wordtype); return true;
case '(':
@@ -1320,8 +1141,7 @@ static bool compileword(vector<uint> &code, const char *&p, int wordtype, char *
code.add(CODE_ENTER);
compilestatements(code, p, VAL_ANY, ')');
code.add(CODE_EXIT|(wordtype < VAL_ANY ? wordtype<<CODE_RET : 0));
- switch(wordtype)
- {
+ switch(wordtype) {
case VAL_CODE: code.add(CODE_COMPILE); break;
case VAL_IDENT: code.add(CODE_IDENTU); break;
}
@@ -1335,36 +1155,31 @@ static bool compileword(vector<uint> &code, const char *&p, int wordtype, char *
return word!=NULL;
}
-static inline bool compilearg(vector<uint> &code, const char *&p, int wordtype)
-{
+static inline bool compilearg(vector<uint> &code, const char *&p, int wordtype) {
char *word = NULL;
int wordlen = 0;
bool more = compileword(code, p, wordtype, word, wordlen);
if(!more) return false;
- if(word)
- {
+ if(word) {
compileval(code, wordtype, word, wordlen);
delete[] word;
}
return true;
}
-static void compilestatements(vector<uint> &code, const char *&p, int rettype, int brak)
-{
+static void compilestatements(vector<uint> &code, const char *&p, int rettype, int brak) {
const char *line = p;
char *idname = NULL;
int idlen = 0;
ident *id = NULL;
int numargs = 0;
- for(;;)
- {
+ for(;;) {
skipcomments(p);
idname = NULL;
bool more = compileword(code, p, VAL_ANY, idname, idlen);
if(!more) goto endstatement;
skipcomments(p);
- if(p[0] == '=') switch(p[1])
- {
+ if(p[0] == '=') switch(p[1]) {
case '/':
if(p[2] != '/') break;
[[fallthrough]];
@@ -1380,11 +1195,9 @@ static void compilestatements(vector<uint> &code, const char *&p, int rettype, i
[[fallthrough]];
case '\0':
p++;
- if(idname)
- {
+ if(idname) {
id = newident(idname, IDF_UNKNOWN);
- if(id) switch(id->type)
- {
+ if(id) switch(id->type) {
case ID_ALIAS:
if(!(more = compilearg(code, p, VAL_ANY))) compilestr(code);
code.add((id->index < MAXARGS ? CODE_ALIASARG : CODE_ALIAS)|(id->index<<8));
@@ -1414,17 +1227,14 @@ static void compilestatements(vector<uint> &code, const char *&p, int rettype, i
}
compilecommand:
numargs = 0;
- if(!idname)
- {
+ if(!idname) {
noid:
while(numargs < MAXARGS && (more = compilearg(code, p, VAL_ANY))) numargs++;
code.add(CODE_CALLU);
}
- else
- {
+ else {
id = idents.access(idname);
- if(!id)
- {
+ if(!id) {
if(!checknumber(idname)) { compilestr(code, idname, idlen); delete[] idname; goto noid; }
char *end = idname;
int val = int(strtoul(idname, &end, 0));
@@ -1432,28 +1242,23 @@ static void compilestatements(vector<uint> &code, const char *&p, int rettype, i
else compileint(code, val);
code.add(CODE_RESULT);
}
- else switch(id->type)
- {
+ else switch(id->type) {
case ID_ALIAS:
while(numargs < MAXARGS && (more = compilearg(code, p, VAL_ANY))) numargs++;
code.add((id->index < MAXARGS ? CODE_CALLARG : CODE_CALL)|(id->index<<8));
break;
- case ID_COMMAND:
- {
+ case ID_COMMAND: {
int comtype = CODE_COM, fakeargs = 0;
bool rep = false;
- for(const char *fmt = id->args; *fmt; fmt++) switch(*fmt)
- {
+ for(const char *fmt = id->args; *fmt; fmt++) switch(*fmt) {
case 's':
if(more) more = compilearg(code, p, VAL_STR);
- if(!more)
- {
+ if(!more) {
if(rep) break;
compilestr(code, NULL, 0, true);
fakeargs++;
}
- else if(!fmt[1])
- {
+ else if(!fmt[1]) {
int numconc = 0;
while(numargs + numconc < MAXARGS && (more = compilearg(code, p, VAL_STR))) numconc++;
if(numconc > 0) code.add(CODE_CONC|RET_STR|((numconc+1)<<8));
@@ -1474,8 +1279,7 @@ static void compilestatements(vector<uint> &code, const char *&p, int rettype, i
case 'C': comtype = CODE_COMC; if(more) while(numargs < MAXARGS && (more = compilearg(code, p, VAL_ANY))) numargs++; numargs = 1; goto endfmt;
case 'V': comtype = CODE_COMV; if(more) while(numargs < MAXARGS && (more = compilearg(code, p, VAL_ANY))) numargs++; numargs = 2; goto endfmt;
case '1': case '2': case '3': case '4':
- if(more && numargs < MAXARGS)
- {
+ if(more && numargs < MAXARGS) {
int numrep = *fmt-'0'+1;
fmt -= numrep;
rep = true;
@@ -1504,8 +1308,7 @@ static void compilestatements(vector<uint> &code, const char *&p, int rettype, i
break;
case ID_SVAR:
if(!(more = compilearg(code, p, VAL_STR))) code.add(CODE_PRINT|(id->index<<8));
- else
- {
+ else {
int numconc = 0;
while(numconc+1 < MAXARGS && (more = compilearg(code, p, VAL_ANY))) numconc++;
if(numconc > 0) code.add(CODE_CONC|RET_STR|((numconc+1)<<8));
@@ -1520,19 +1323,16 @@ static void compilestatements(vector<uint> &code, const char *&p, int rettype, i
if(more) while(compilearg(code, p, VAL_ANY)) code.add(CODE_POP);
p += strcspn(p, ")];/\n\0");
int c = *p++;
- switch(c)
- {
+ switch(c) {
case '\0':
if(c != brak) debugcodeline(line, "missing \"%c\"", brak);
p--;
return;
-
case ')':
case ']':
if(c == brak) return;
debugcodeline(line, "unexpected \"%c\"", c);
break;
-
case '/':
if(*p == '/') p += strcspn(p, "\n\0");
goto endstatement;
@@ -1540,15 +1340,13 @@ static void compilestatements(vector<uint> &code, const char *&p, int rettype, i
}
}
-static void compilemain(vector<uint> &code, const char *p, int rettype = VAL_ANY)
-{
+static void compilemain(vector<uint> &code, const char *p, int rettype = VAL_ANY) {
code.add(CODE_START);
compilestatements(code, p, VAL_ANY);
code.add(CODE_EXIT|(rettype < VAL_ANY ? rettype<<CODE_RET : 0));
}
-uint *compilecode(const char *p)
-{
+uint *compilecode(const char *p) {
vector<uint> buf;
buf.reserve(64);
compilemain(buf, p);
@@ -1558,17 +1356,14 @@ uint *compilecode(const char *p)
return code;
}
-void keepcode(uint *code)
-{
+void keepcode(uint *code) {
if(!code) return;
- switch(*code&CODE_OP_MASK)
- {
+ switch(*code&CODE_OP_MASK) {
case CODE_START:
*code += 0x100;
return;
}
- switch(code[-1]&CODE_OP_MASK)
- {
+ switch(code[-1]&CODE_OP_MASK) {
case CODE_START:
code[-1] += 0x100;
break;
@@ -1579,18 +1374,15 @@ void keepcode(uint *code)
}
}
-void freecode(uint *code)
-{
+void freecode(uint *code) {
if(!code) return;
- switch(*code&CODE_OP_MASK)
- {
+ switch(*code&CODE_OP_MASK) {
case CODE_START:
*code -= 0x100;
if(int(*code) < 0x100) delete[] code;
return;
}
- switch(code[-1]&CODE_OP_MASK)
- {
+ switch(code[-1]&CODE_OP_MASK) {
case CODE_START:
code[-1] -= 0x100;
if(int(code[-1]) < 0x100) delete[] &code[-1];
@@ -1603,8 +1395,7 @@ void freecode(uint *code)
}
}
-void printvar(ident *id, int i)
-{
+void printvar(ident *id, int i) {
if(i < 0) conoutf(CON_INFO, id->index, "%s = %d", id->name, i);
else if(id->flags&IDF_HEX && id->maxval==0xFFFFFF)
conoutf(CON_INFO, id->index, "%s = 0x%.6X (%d, %d, %d)", id->name, i, (i>>16)&0xFF, (i>>8)&0xFF, i&0xFF);
@@ -1612,38 +1403,31 @@ void printvar(ident *id, int i)
conoutf(CON_INFO, id->index, id->flags&IDF_HEX ? "%s = 0x%X" : "%s = %d", id->name, i);
}
-void printfvar(ident *id, float f)
-{
+void printfvar(ident *id, float f) {
conoutf(CON_INFO, id->index, "%s = %s", id->name, floatstr(f));
}
-void printsvar(ident *id, const char *s)
-{
+void printsvar(ident *id, const char *s) {
conoutf(CON_INFO, id->index, strchr(s, '"') ? "%s = [%s]" : "%s = \"%s\"", id->name, s);
}
template <class V>
-static void printvar(ident *id, int type, V &val)
-{
- switch(type)
- {
+static void printvar(ident *id, int type, V &val) {
+ switch(type) {
case VAL_INT: printvar(id, val.getint()); break;
case VAL_FLOAT: printfvar(id, val.getfloat()); break;
default: printsvar(id, val.getstr()); break;
}
}
-void printvar(ident *id)
-{
- switch(id->type)
- {
+void printvar(ident *id) {
+ switch(id->type) {
case ID_VAR: printvar(id, *id->storage.i); break;
case ID_FVAR: printfvar(id, *id->storage.f); break;
case ID_SVAR: printsvar(id, *id->storage.s); break;
case ID_ALIAS: printvar(id, id->valtype, *id); break;
case ID_COMMAND:
- if(id->flags&IDF_EMUVAR)
- {
+ if(id->flags&IDF_EMUVAR) {
tagval result;
executeret(id, NULL, 0, true, result);
printvar(id, result.type, result);
@@ -1669,23 +1453,18 @@ typedef void (__cdecl *comfun11)(void *, void *, void *, void *, void *, void *,
typedef void (__cdecl *comfun12)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *);
typedef void (__cdecl *comfunv)(tagval *, int);
-static const uint *skipcode(const uint *code, tagval &result)
-{
+static const uint *skipcode(const uint *code, tagval &result) {
int depth = 0;
- for(;;)
- {
+ for(;;) {
uint op = *code++;
- switch(op&0xFF)
- {
+ switch(op&0xFF) {
case CODE_MACRO:
- case CODE_VAL|RET_STR:
- {
+ case CODE_VAL|RET_STR: {
uint len = op>>8;
code += len/sizeof(uint) + 1;
continue;
}
- case CODE_BLOCK:
- {
+ case CODE_BLOCK: {
uint len = op>>8;
code += len;
continue;
@@ -1694,8 +1473,7 @@ static const uint *skipcode(const uint *code, tagval &result)
++depth;
continue;
case CODE_EXIT|RET_NULL: case CODE_EXIT|RET_STR: case CODE_EXIT|RET_INT: case CODE_EXIT|RET_FLOAT:
- if(depth <= 0)
- {
+ if(depth <= 0) {
forcearg(result, op&CODE_RET_MASK);
return code;
}
@@ -1705,27 +1483,23 @@ static const uint *skipcode(const uint *code, tagval &result)
}
}
-static inline void callcommand(ident *id, tagval *args, int numargs, bool lookup = false)
-{
+static inline void callcommand(ident *id, tagval *args, int numargs, bool lookup = false) {
int i = -1, fakeargs = 0;
bool rep = false;
- for(const char *fmt = id->args; *fmt; fmt++) switch(*fmt)
- {
+ for(const char *fmt = id->args; *fmt; fmt++) switch(*fmt) {
case 'i': if(++i >= numargs) { if(rep) break; args[i].setint(0); fakeargs++; } else forceint(args[i]); break;
case 'b': if(++i >= numargs) { if(rep) break; args[i].setint(INT_MIN); fakeargs++; } else forceint(args[i]); break;
case 'f': if(++i >= numargs) { if(rep) break; args[i].setfloat(0.0f); fakeargs++; } else forcefloat(args[i]); break;
case 's': if(++i >= numargs) { if(rep) break; args[i].setstr(newstring("")); fakeargs++; } else forcestr(args[i]); break;
case 't': if(++i >= numargs) { if(rep) break; args[i].setnull(); fakeargs++; } break;
case 'e':
- if(++i >= numargs)
- {
+ if(++i >= numargs) {
if(rep) break;
static uint buf[2] = { CODE_START + 0x100, CODE_EXIT };
args[i].setcode(buf);
fakeargs++;
}
- else
- {
+ else {
vector<uint> buf;
buf.reserve(64);
compilemain(buf, numargs <= i ? "" : args[i].getstr());
@@ -1746,8 +1520,8 @@ static inline void callcommand(ident *id, tagval *args, int numargs, bool lookup
}
#define ARG(n) (id->argmask&(1<<n) ? (void *)args[n].s : (void *)&args[n].i)
#define CALLCOM(n) \
- switch(n) \
- { \
+ switch(n) { \
+ \
case 0: ((comfun)id->fun)(); break; \
case 1: ((comfun1)id->fun)(ARG(0)); break; \
case 2: ((comfun2)id->fun)(ARG(0), ARG(1)); break; \
@@ -1772,11 +1546,9 @@ cleanup:
#define MAXRUNDEPTH 255
static int rundepth = 0;
-static const uint *runcode(const uint *code, tagval &result)
-{
+static const uint *runcode(const uint *code, tagval &result) {
result.setnull();
- if(rundepth >= MAXRUNDEPTH)
- {
+ if(rundepth >= MAXRUNDEPTH) {
debugcode("exceeded recursion limit");
return skipcode(code, result);
}
@@ -1785,13 +1557,10 @@ static const uint *runcode(const uint *code, tagval &result)
int numargs = 0;
tagval args[MAXARGS+1], *prevret = commandret;
commandret = &result;
- for(;;)
- {
+ for(;;) {
uint op = *code++;
- switch(op&0xFF)
- {
+ switch(op&0xFF) {
case CODE_START: case CODE_OFFSET: continue;
-
case CODE_POP:
freearg(args[--numargs]);
continue;
@@ -1804,8 +1573,7 @@ static const uint *runcode(const uint *code, tagval &result)
case CODE_PRINT:
printvar(identmap[op>>8]);
continue;
- case CODE_LOCAL:
- {
+ case CODE_LOCAL: {
identstack locals[MAXARGS];
freearg(result);
loopi(numargs) pushalias(*args[i].id, locals[i]);
@@ -1813,24 +1581,19 @@ static const uint *runcode(const uint *code, tagval &result)
loopi(numargs) popalias(*args[i].id);
goto exit;
}
-
- case CODE_MACRO:
- {
+ case CODE_MACRO: {
uint len = op>>8;
args[numargs++].setmacro(code);
code += len/sizeof(uint) + 1;
continue;
}
-
- case CODE_VAL|RET_STR:
- {
+ case CODE_VAL|RET_STR: {
uint len = op>>8;
args[numargs++].setstr(newstring((const char *)code, len));
code += len/sizeof(uint) + 1;
continue;
}
- case CODE_VALI|RET_STR:
- {
+ case CODE_VALI|RET_STR: {
char s[4] = { char((op>>8)&0xFF), char((op>>16)&0xFF), char((op>>24)&0xFF), '\0' };
args[numargs++].setstr(newstring(s));
continue;
@@ -1841,11 +1604,9 @@ static const uint *runcode(const uint *code, tagval &result)
case CODE_VALI|RET_INT: args[numargs++].setint(int(op)>>8); continue;
case CODE_VAL|RET_FLOAT: args[numargs++].setfloat(*(const float *)code++); continue;
case CODE_VALI|RET_FLOAT: args[numargs++].setfloat(float(int(op)>>8)); continue;
-
case CODE_FORCE|RET_STR: forcestr(args[numargs-1]); continue;
case CODE_FORCE|RET_INT: forceint(args[numargs-1]); continue;
case CODE_FORCE|RET_FLOAT: forcefloat(args[numargs-1]); continue;
-
case CODE_RESULT|RET_NULL: case CODE_RESULT|RET_STR: case CODE_RESULT|RET_INT: case CODE_RESULT|RET_FLOAT:
litval:
freearg(result);
@@ -1854,20 +1615,16 @@ static const uint *runcode(const uint *code, tagval &result)
args[0].setnull();
freeargs(args, numargs, 0);
continue;
-
- case CODE_BLOCK:
- {
+ case CODE_BLOCK: {
uint len = op>>8;
args[numargs++].setcode(code+1);
code += len;
continue;
}
- case CODE_COMPILE:
- {
+ case CODE_COMPILE: {
tagval &arg = args[numargs-1];
vector<uint> buf;
- switch(arg.type)
- {
+ switch(arg.type) {
case VAL_INT: buf.reserve(8); buf.add(CODE_START); compileint(buf, arg.i); buf.add(CODE_RESULT); buf.add(CODE_EXIT); break;
case VAL_FLOAT: buf.reserve(8); buf.add(CODE_START); compilefloat(buf, arg.f); buf.add(CODE_RESULT); buf.add(CODE_EXIT); break;
case VAL_STR: case VAL_MACRO: buf.reserve(64); compilemain(buf, arg.s); freearg(arg); break;
@@ -1877,27 +1634,22 @@ static const uint *runcode(const uint *code, tagval &result)
buf.disown();
continue;
}
-
case CODE_IDENT:
args[numargs++].setident(identmap[op>>8]);
continue;
- case CODE_IDENTARG:
- {
+ case CODE_IDENTARG: {
ident *id = identmap[op>>8];
- if(!(aliasstack->usedargs&(1<<id->index)))
- {
+ if(!(aliasstack->usedargs&(1<<id->index))) {
pusharg(*id, nullval, aliasstack->argstack[id->index]);
aliasstack->usedargs |= 1<<id->index;
}
args[numargs++].setident(id);
continue;
}
- case CODE_IDENTU:
- {
+ case CODE_IDENTU: {
tagval &arg = args[numargs-1];
ident *id = arg.type == VAL_STR || arg.type == VAL_MACRO ? newident(arg.s, IDF_UNKNOWN) : dummyident;
- if(id->index < MAXARGS && !(aliasstack->usedargs&(1<<id->index)))
- {
+ if(id->index < MAXARGS && !(aliasstack->usedargs&(1<<id->index))) {
pusharg(*id, nullval, aliasstack->argstack[id->index]);
aliasstack->usedargs |= 1<<id->index;
}
@@ -1905,14 +1657,13 @@ static const uint *runcode(const uint *code, tagval &result)
arg.setident(id);
continue;
}
-
case CODE_LOOKUPU|RET_STR:
#define LOOKUPU(aval, sval, ival, fval, nval) { \
tagval &arg = args[numargs-1]; \
if(arg.type != VAL_STR && arg.type != VAL_MACRO) continue; \
id = idents.access(arg.s); \
- if(id) switch(id->type) \
- { \
+ if(id) switch(id->type) { \
+ \
case ID_ALIAS: \
if(id->flags&IDF_UNKNOWN) break; \
freearg(arg); \
@@ -1922,8 +1673,8 @@ static const uint *runcode(const uint *code, tagval &result)
case ID_SVAR: freearg(arg); sval; continue; \
case ID_VAR: freearg(arg); ival; continue; \
case ID_FVAR: freearg(arg); fval; continue; \
- case ID_COMMAND: \
- { \
+ case ID_COMMAND: { \
+ \
freearg(arg); \
arg.setnull(); \
commandret = &arg; \
@@ -1991,24 +1742,20 @@ static const uint *runcode(const uint *code, tagval &result)
LOOKUP(id->getval(args[numargs++]));
case CODE_LOOKUPARG|RET_NULL:
LOOKUPARG(id->getval(args[numargs++]), args[numargs++].setnull());
-
case CODE_SVAR|RET_STR: case CODE_SVAR|RET_NULL: args[numargs++].setstr(newstring(*identmap[op>>8]->storage.s)); continue;
case CODE_SVAR|RET_INT: args[numargs++].setint(parseint(*identmap[op>>8]->storage.s)); continue;
case CODE_SVAR|RET_FLOAT: args[numargs++].setfloat(parsefloat(*identmap[op>>8]->storage.s)); continue;
case CODE_SVAR1: setsvarchecked(identmap[op>>8], args[0].s); freeargs(args, numargs, 0); continue;
-
case CODE_IVAR|RET_INT: case CODE_IVAR|RET_NULL: args[numargs++].setint(*identmap[op>>8]->storage.i); continue;
case CODE_IVAR|RET_STR: args[numargs++].setstr(newstring(intstr(*identmap[op>>8]->storage.i))); continue;
case CODE_IVAR|RET_FLOAT: args[numargs++].setfloat(float(*identmap[op>>8]->storage.i)); continue;
case CODE_IVAR1: setvarchecked(identmap[op>>8], args[0].i); numargs = 0; continue;
case CODE_IVAR2: setvarchecked(identmap[op>>8], (args[0].i<<16)|(args[1].i<<8)); numargs = 0; continue;
case CODE_IVAR3: setvarchecked(identmap[op>>8], (args[0].i<<16)|(args[1].i<<8)|args[2].i); numargs = 0; continue;
-
case CODE_FVAR|RET_FLOAT: case CODE_FVAR|RET_NULL: args[numargs++].setfloat(*identmap[op>>8]->storage.f); continue;
case CODE_FVAR|RET_STR: args[numargs++].setstr(newstring(floatstr(*identmap[op>>8]->storage.f))); continue;
case CODE_FVAR|RET_INT: args[numargs++].setint(int(*identmap[op>>8]->storage.f)); continue;
case CODE_FVAR1: setfvarchecked(identmap[op>>8], args[0].f); numargs = 0; continue;
-
case CODE_COM|RET_NULL: case CODE_COM|RET_STR: case CODE_COM|RET_FLOAT: case CODE_COM|RET_INT:
id = identmap[op>>8];
#ifndef STANDALONE
@@ -2034,17 +1781,14 @@ static const uint *runcode(const uint *code, tagval &result)
goto forceresult;
case CODE_COMC|RET_NULL: case CODE_COMC|RET_STR: case CODE_COMC|RET_FLOAT: case CODE_COMC|RET_INT:
id = identmap[op>>8];
- forcenull(result);
- {
+ forcenull(result); {
vector<char> buf;
buf.reserve(MAXSTRLEN);
((comfun1)id->fun)(conc(buf, args, numargs, true));
}
goto forceresult;
-
case CODE_CONC|RET_NULL: case CODE_CONC|RET_STR: case CODE_CONC|RET_FLOAT: case CODE_CONC|RET_INT:
- case CODE_CONCW|RET_NULL: case CODE_CONCW|RET_STR: case CODE_CONCW|RET_FLOAT: case CODE_CONCW|RET_INT:
- {
+ case CODE_CONCW|RET_NULL: case CODE_CONCW|RET_STR: case CODE_CONCW|RET_FLOAT: case CODE_CONCW|RET_INT: {
int numconc = op>>8;
char *s = conc(&args[numargs-numconc], numconc, (op&CODE_OP_MASK)==CODE_CONC);
freeargs(args, numargs, numargs-numconc);
@@ -2052,9 +1796,7 @@ static const uint *runcode(const uint *code, tagval &result)
forcearg(args[numargs-1], op&CODE_RET_MASK);
continue;
}
-
- case CODE_CONCM|RET_NULL: case CODE_CONCM|RET_STR: case CODE_CONCM|RET_FLOAT: case CODE_CONCM|RET_INT:
- {
+ case CODE_CONCM|RET_NULL: case CODE_CONCM|RET_STR: case CODE_CONCM|RET_FLOAT: case CODE_CONCM|RET_INT: {
int numconc = op>>8;
char *s = conc(&args[numargs-numconc], numconc, false);
freeargs(args, numargs, numargs-numconc);
@@ -2062,7 +1804,6 @@ static const uint *runcode(const uint *code, tagval &result)
forcearg(result, op&CODE_RET_MASK);
continue;
}
-
case CODE_ALIAS:
setalias(*identmap[op>>8], args[--numargs]);
freeargs(args, numargs, 0);
@@ -2076,7 +1817,6 @@ static const uint *runcode(const uint *code, tagval &result)
setalias(args[0].s, args[--numargs]);
freeargs(args, numargs, 0);
continue;
-
case CODE_CALL|RET_NULL: case CODE_CALL|RET_STR: case CODE_CALL|RET_FLOAT: case CODE_CALL|RET_INT:
#define CALLALIAS(offset) { \
identstack argstack[MAXARGS]; \
@@ -2106,8 +1846,7 @@ static const uint *runcode(const uint *code, tagval &result)
}
forcenull(result);
id = identmap[op>>8];
- if(id->flags&IDF_UNKNOWN)
- {
+ if(id->flags&IDF_UNKNOWN) {
debugcode("unknown command: %s", id->name);
goto forceresult;
}
@@ -2119,12 +1858,10 @@ static const uint *runcode(const uint *code, tagval &result)
if(!(aliasstack->usedargs&(1<<id->index))) goto forceresult;
CALLALIAS(0);
continue;
-
case CODE_CALLU|RET_NULL: case CODE_CALLU|RET_STR: case CODE_CALLU|RET_FLOAT: case CODE_CALLU|RET_INT:
if(args[0].type != VAL_STR) goto litval;
id = idents.access(args[0].s);
- if(!id)
- {
+ if(!id) {
noid:
if(checknumber(args[0].s)) goto litval;
debugcode("unknown command: %s", args[0].s);
@@ -2132,16 +1869,14 @@ static const uint *runcode(const uint *code, tagval &result)
goto forceresult;
}
forcenull(result);
- switch(id->type)
- {
+ switch(id->type) {
case ID_COMMAND:
freearg(args[0]);
callcommand(id, args+1, numargs-1);
forcearg(result, op&CODE_RET_MASK);
numargs = 0;
continue;
- case ID_LOCAL:
- {
+ case ID_LOCAL: {
identstack locals[MAXARGS];
freearg(args[0]);
loopj(numargs-1) pushalias(*forceident(args[j+1]), locals[j]);
@@ -2175,13 +1910,11 @@ exit:
return code;
}
-void executeret(const uint *code, tagval &result)
-{
+void executeret(const uint *code, tagval &result) {
runcode(code, result);
}
-void executeret(const char *p, tagval &result)
-{
+void executeret(const char *p, tagval &result) {
vector<uint> code;
code.reserve(64);
compilemain(code, p, VAL_ANY);
@@ -2189,21 +1922,18 @@ void executeret(const char *p, tagval &result)
if(int(code[0]) >= 0x100) code.disown();
}
-void executeret(ident *id, tagval *args, int numargs, bool lookup, tagval &result)
-{
+void executeret(ident *id, tagval *args, int numargs, bool lookup, tagval &result) {
result.setnull();
++rundepth;
tagval *prevret = commandret;
commandret = &result;
if(rundepth > MAXRUNDEPTH) debugcode("exceeded recursion limit");
- else if(id) switch(id->type)
- {
+ else if(id) switch(id->type) {
default:
if(!id->fun) break;
// fall-through
case ID_COMMAND:
- if(numargs < id->numargs)
- {
+ if(numargs < id->numargs) {
tagval buf[MAXARGS];
memcpy(buf, args, numargs*sizeof(tagval));
callcommand(id, buf, numargs, lookup);
@@ -2233,8 +1963,7 @@ void executeret(ident *id, tagval *args, int numargs, bool lookup, tagval &resul
--rundepth;
}
-char *executestr(const uint *code)
-{
+char *executestr(const uint *code) {
tagval result;
runcode(code, result);
if(result.type == VAL_NULL) return NULL;
@@ -2242,8 +1971,7 @@ char *executestr(const uint *code)
return result.s;
}
-char *executestr(const char *p)
-{
+char *executestr(const char *p) {
tagval result;
executeret(p, result);
if(result.type == VAL_NULL) return NULL;
@@ -2251,8 +1979,7 @@ char *executestr(const char *p)
return result.s;
}
-char *executestr(ident *id, tagval *args, int numargs, bool lookup)
-{
+char *executestr(ident *id, tagval *args, int numargs, bool lookup) {
tagval result;
executeret(id, args, numargs, lookup, result);
if(result.type == VAL_NULL) return NULL;
@@ -2260,14 +1987,12 @@ char *executestr(ident *id, tagval *args, int numargs, bool lookup)
return result.s;
}
-char *execidentstr(const char *name, bool lookup)
-{
+char *execidentstr(const char *name, bool lookup) {
ident *id = idents.access(name);
return id ? executestr(id, NULL, 0, lookup) : NULL;
}
-int execute(const uint *code)
-{
+int execute(const uint *code) {
tagval result;
runcode(code, result);
int i = result.getint();
@@ -2275,8 +2000,7 @@ int execute(const uint *code)
return i;
}
-int execute(const char *p)
-{
+int execute(const char *p) {
vector<uint> code;
code.reserve(64);
compilemain(code, p, VAL_INT);
@@ -2288,8 +2012,7 @@ int execute(const char *p)
return i;
}
-int execute(ident *id, tagval *args, int numargs, bool lookup)
-{
+int execute(ident *id, tagval *args, int numargs, bool lookup) {
tagval result;
executeret(id, args, numargs, lookup, result);
int i = result.getint();
@@ -2297,31 +2020,25 @@ int execute(ident *id, tagval *args, int numargs, bool lookup)
return i;
}
-int execident(const char *name, int noid, bool lookup)
-{
+int execident(const char *name, int noid, bool lookup) {
ident *id = idents.access(name);
return id ? execute(id, NULL, 0, lookup) : noid;
}
-static inline bool getbool(const char *s)
-{
- switch(s[0])
- {
+static inline bool getbool(const char *s) {
+ switch(s[0]) {
case '+': case '-':
- switch(s[1])
- {
+ switch(s[1]) {
case '0': break;
case '.': return !isdigit(s[2]) || parsefloat(s) != 0;
default: return true;
}
// fall through
- case '0':
- {
+ case '0': {
char *end;
int val = int(strtoul((char *)s, &end, 0));
if(val) return true;
- switch(*end)
- {
+ switch(*end) {
case 'e': case '.': return parsefloat(s) != 0;
default: return false;
}
@@ -2332,10 +2049,8 @@ static inline bool getbool(const char *s)
}
}
-static inline bool getbool(const tagval &v)
-{
- switch(v.type)
- {
+static inline bool getbool(const tagval &v) {
+ switch(v.type) {
case VAL_FLOAT: return v.f!=0;
case VAL_INT: return v.i!=0;
case VAL_STR: case VAL_MACRO: return getbool(v.s);
@@ -2343,8 +2058,7 @@ static inline bool getbool(const tagval &v)
}
}
-bool executebool(const uint *code)
-{
+bool executebool(const uint *code) {
tagval result;
runcode(code, result);
bool b = getbool(result);
@@ -2352,8 +2066,7 @@ bool executebool(const uint *code)
return b;
}
-bool executebool(const char *p)
-{
+bool executebool(const char *p) {
tagval result;
executeret(p, result);
bool b = getbool(result);
@@ -2361,8 +2074,7 @@ bool executebool(const char *p)
return b;
}
-bool executebool(ident *id, tagval *args, int numargs, bool lookup)
-{
+bool executebool(ident *id, tagval *args, int numargs, bool lookup) {
tagval result;
executeret(id, args, numargs, lookup, result);
bool b = getbool(result);
@@ -2370,19 +2082,16 @@ bool executebool(ident *id, tagval *args, int numargs, bool lookup)
return b;
}
-bool execidentbool(const char *name, bool noid, bool lookup)
-{
+bool execidentbool(const char *name, bool noid, bool lookup) {
ident *id = idents.access(name);
return id ? executebool(id, NULL, 0, lookup) : noid;
}
-bool execfile(const char *cfgfile, bool msg)
-{
+bool execfile(const char *cfgfile, bool msg) {
string s;
copystring(s, cfgfile);
char *buf = loadfile(path(s), NULL);
- if(!buf)
- {
+ if(!buf) {
if(msg) conoutf(CON_ERROR, "could not read \"%s\"", cfgfile);
return false;
}
@@ -2397,16 +2106,14 @@ bool execfile(const char *cfgfile, bool msg)
}
ICOMMAND(exec, "sb", (char *file, int *msg), intret(execfile(file, *msg != 0) ? 1 : 0));
-const char *escapestring(const char *s)
-{
+const char *escapestring(const char *s) {
static vector<char> strbuf[3];
static int stridx = 0;
stridx = (stridx + 1)%3;
vector<char> &buf = strbuf[stridx];
buf.setsize(0);
buf.add('"');
- for(; *s; s++) switch(*s)
- {
+ for(; *s; s++) switch(*s) {
case '\n': buf.put("^n", 2); break;
case '\t': buf.put("^t", 2); break;
case '\f': buf.put("^f", 2); break;
@@ -2419,27 +2126,23 @@ const char *escapestring(const char *s)
}
ICOMMAND(escape, "s", (char *s), result(escapestring(s)));
-ICOMMAND(unescape, "s", (char *s),
-{
+ICOMMAND(unescape, "s", (char *s), {
int len = strlen(s);
char *d = newstring(len);
d[unescapestring(d, s, &s[len])] = '\0';
stringret(d);
});
-const char *escapeid(const char *s)
-{
+const char *escapeid(const char *s) {
const char *end = s + strcspn(s, "\"/;()[]@ \f\t\r\n\0");
return *end ? escapestring(s) : s;
}
-bool validateblock(const char *s)
-{
+bool validateblock(const char *s) {
const int maxbrak = 100;
static char brakstack[maxbrak];
int brakdepth = 0;
- for(; *s; s++) switch(*s)
- {
+ for(; *s; s++) switch(*s) {
case '[': case '(': if(brakdepth >= maxbrak) return false; brakstack[brakdepth++] = *s; break;
case ']': if(brakdepth <= 0 || brakstack[--brakdepth] != '[') return false; break;
case ')': if(brakdepth <= 0 || brakstack[--brakdepth] != '(') return false; break;
@@ -2451,8 +2154,7 @@ bool validateblock(const char *s)
}
#ifndef STANDALONE
-void writecfg(const char *name)
-{
+void writecfg(const char *name) {
stream *f = openutf8file(path(name && name[0] ? name : game::savedconfig(), true), "w");
if(!f) return;
f->printf("// automatically written on exit, DO NOT MODIFY\n// delete this file to have %s overwrite these settings\n// modify settings in game, or put settings in %s to override anything\n\n", game::defaultconfig(), game::autoexec());
@@ -2462,11 +2164,9 @@ void writecfg(const char *name)
vector<ident *> ids;
enumerate(idents, ident, id, ids.add(&id));
ids.sortname();
- loopv(ids)
- {
+ loopv(ids) {
ident &id = *ids[i];
- if(id.flags&IDF_PERSIST) switch(id.type)
- {
+ if(id.flags&IDF_PERSIST) switch(id.type) {
case ID_VAR: f->printf("%s %d\n", escapeid(id), *id.storage.i); break;
case ID_FVAR: f->printf("%s %s\n", escapeid(id), floatstr(*id.storage.f)); break;
case ID_SVAR: f->printf("%s %s\n", escapeid(id), escapestring(*id.storage.s)); break;
@@ -2475,11 +2175,9 @@ void writecfg(const char *name)
f->printf("\n");
writebinds(f);
f->printf("\n");
- loopv(ids)
- {
+ loopv(ids) {
ident &id = *ids[i];
- if(id.type==ID_ALIAS && id.flags&IDF_PERSIST && !(id.flags&IDF_OVERRIDDEN)) switch(id.valtype)
- {
+ if(id.type==ID_ALIAS && id.flags&IDF_PERSIST && !(id.flags&IDF_OVERRIDDEN)) switch(id.valtype) {
case VAL_STR:
if(!id.val.s[0]) break;
if(!validateblock(id.val.s)) { f->printf("%s = %s\n", escapeid(id), escapestring(id.val.s)); break; }
@@ -2498,8 +2196,7 @@ void writecfg(const char *name)
COMMAND(writecfg, "s");
#endif
-void changedvars()
-{
+void changedvars() {
vector<ident *> ids;
enumerate(idents, ident, id, if(id.flags&IDF_OVERRIDDEN) ids.add(&id));
ids.sortname();
@@ -2513,27 +2210,23 @@ COMMAND(changedvars, "");
static string retbuf[4];
static int retidx = 0;
-const char *intstr(int v)
-{
+const char *intstr(int v) {
retidx = (retidx + 1)%4;
intformat(retbuf[retidx], v);
return retbuf[retidx];
}
-void intret(int v)
-{
+void intret(int v) {
commandret->setint(v);
}
-const char *floatstr(float v)
-{
+const char *floatstr(float v) {
retidx = (retidx + 1)%4;
floatformat(retbuf[retidx], v);
return retbuf[retidx];
}
-void floatret(float v)
-{
+void floatret(float v) {
commandret->setfloat(v);
}
@@ -2544,11 +2237,9 @@ ICOMMAND(do, "e", (uint *body), executeret(body, *commandret));
ICOMMAND(if, "tee", (tagval *cond, uint *t, uint *f), executeret(getbool(*cond) ? t : f, *commandret));
ICOMMAND(?, "ttt", (tagval *cond, tagval *t, tagval *f), result(*(getbool(*cond) ? t : f)));
-ICOMMAND(pushif, "rte", (ident *id, tagval *v, uint *code),
-{
+ICOMMAND(pushif, "rte", (ident *id, tagval *v, uint *code), {
if(id->type != ID_ALIAS || id->index < MAXARGS) return;
- if(getbool(*v))
- {
+ if(getbool(*v)) {
identstack stack;
pusharg(*id, *v, stack);
v->type = VAL_NULL;
@@ -2558,63 +2249,51 @@ ICOMMAND(pushif, "rte", (ident *id, tagval *v, uint *code),
}
});
-void loopiter(ident *id, identstack &stack, const tagval &v)
-{
- if(id->stack != &stack)
- {
+void loopiter(ident *id, identstack &stack, const tagval &v) {
+ if(id->stack != &stack) {
pusharg(*id, v, stack);
id->flags &= ~IDF_UNKNOWN;
}
- else
- {
+ else {
if(id->valtype == VAL_STR) delete[] id->val.s;
cleancode(*id);
id->setval(v);
}
}
-void loopend(ident *id, identstack &stack)
-{
+void loopend(ident *id, identstack &stack) {
if(id->stack == &stack) poparg(*id);
}
-static inline void setiter(ident &id, int i, identstack &stack)
-{
- if(id.stack == &stack)
- {
- if(id.valtype != VAL_INT)
- {
+static inline void setiter(ident &id, int i, identstack &stack) {
+ if(id.stack == &stack) {
+ if(id.valtype != VAL_INT) {
if(id.valtype == VAL_STR) delete[] id.val.s;
cleancode(id);
id.valtype = VAL_INT;
}
id.val.i = i;
}
- else
- {
+ else {
tagval t;
t.setint(i);
pusharg(id, t, stack);
id.flags &= ~IDF_UNKNOWN;
}
}
-ICOMMAND(loop, "rie", (ident *id, int *n, uint *body),
-{
+ICOMMAND(loop, "rie", (ident *id, int *n, uint *body), {
if(*n <= 0 || id->type!=ID_ALIAS) return;
identstack stack;
- loopi(*n)
- {
+ loopi(*n) {
setiter(*id, i, stack);
execute(body);
}
poparg(*id);
});
-ICOMMAND(loopwhile, "riee", (ident *id, int *n, uint *cond, uint *body),
-{
+ICOMMAND(loopwhile, "riee", (ident *id, int *n, uint *cond, uint *body), {
if(*n <= 0 || id->type!=ID_ALIAS) return;
identstack stack;
- loopi(*n)
- {
+ loopi(*n) {
setiter(*id, i, stack);
if(!executebool(cond)) break;
execute(body);
@@ -2623,12 +2302,10 @@ ICOMMAND(loopwhile, "riee", (ident *id, int *n, uint *cond, uint *body),
});
ICOMMAND(while, "ee", (uint *cond, uint *body), while(executebool(cond)) execute(body));
-char *loopconc(ident *id, int n, uint *body, bool space)
-{
+char *loopconc(ident *id, int n, uint *body, bool space) {
identstack stack;
vector<char> s;
- loopi(n)
- {
+ loopi(n) {
setiter(*id, i, stack);
tagval v;
executeret(body, v);
@@ -2643,39 +2320,32 @@ char *loopconc(ident *id, int n, uint *body, bool space)
return newstring(s.getbuf(), s.length()-1);
}
-ICOMMAND(loopconcat, "rie", (ident *id, int *n, uint *body),
-{
+ICOMMAND(loopconcat, "rie", (ident *id, int *n, uint *body), {
if(*n > 0 && id->type==ID_ALIAS) commandret->setstr(loopconc(id, *n, body, true));
});
-ICOMMAND(loopconcatword, "rie", (ident *id, int *n, uint *body),
-{
+ICOMMAND(loopconcatword, "rie", (ident *id, int *n, uint *body), {
if(*n > 0 && id->type==ID_ALIAS) commandret->setstr(loopconc(id, *n, body, false));
});
-void concat(tagval *v, int n)
-{
+void concat(tagval *v, int n) {
commandret->setstr(conc(v, n, true));
}
COMMAND(concat, "V");
-void concatword(tagval *v, int n)
-{
+void concatword(tagval *v, int n) {
commandret->setstr(conc(v, n, false));
}
COMMAND(concatword, "V");
-void append(ident *id, tagval *v, bool space)
-{
+void append(ident *id, tagval *v, bool space) {
if(id->type != ID_ALIAS || v->type == VAL_NULL) return;
- if(id->valtype == VAL_NULL)
- {
+ if(id->valtype == VAL_NULL) {
noprefix:
if(id->index < MAXARGS) setarg(*id, *v); else setalias(*id, *v);
v->type = VAL_NULL;
}
- else
- {
+ else {
const char *prefix = id->getstr();
if(!prefix[0]) goto noprefix;
tagval r;
@@ -2686,40 +2356,32 @@ void append(ident *id, tagval *v, bool space)
ICOMMAND(append, "rt", (ident *id, tagval *v), append(id, v, true));
ICOMMAND(appendword, "rt", (ident *id, tagval *v), append(id, v, false));
-void result(tagval &v)
-{
+void result(tagval &v) {
*commandret = v;
v.type = VAL_NULL;
}
-void stringret(char *s)
-{
+void stringret(char *s) {
commandret->setstr(s);
}
-void result(const char *s)
-{
+void result(const char *s) {
commandret->setstr(newstring(s));
}
-ICOMMAND(result, "t", (tagval *v),
-{
+ICOMMAND(result, "t", (tagval *v), {
*commandret = *v;
v->type = VAL_NULL;
});
-void format(tagval *args, int numargs)
-{
+void format(tagval *args, int numargs) {
vector<char> s;
const char *f = args[0].getstr();
- while(*f)
- {
+ while(*f) {
int c = *f++;
- if(c == '%')
- {
+ if(c == '%') {
int i = *f++;
- if(i >= '1' && i <= '9')
- {
+ if(i >= '1' && i <= '9') {
i -= '0';
const char *sub = i < numargs ? args[i].getstr() : "";
while(*sub) s.add(*sub++);
@@ -2735,31 +2397,25 @@ COMMAND(format, "V");
static const char *liststart = NULL, *listend = NULL, *listquotestart = NULL, *listquoteend = NULL;
-static inline void skiplist(const char *&p)
-{
- for(;;)
- {
+static inline void skiplist(const char *&p) {
+ for(;;) {
p += strspn(p, " \t\r\n");
if(p[0]!='/' || p[1]!='/') break;
p += strcspn(p, "\n\0");
}
}
-static bool parselist(const char *&s, const char *&start = liststart, const char *&end = listend, const char *&quotestart = listquotestart, const char *&quoteend = listquoteend)
-{
+static bool parselist(const char *&s, const char *&start = liststart, const char *&end = listend, const char *&quotestart = listquotestart, const char *&quoteend = listquoteend) {
skiplist(s);
- switch(*s)
- {
+ switch(*s) {
case '"': quotestart = s++; start = s; s = parsestring(s); end = s; if(*s == '"') s++; quoteend = s; break;
case '(': case '[':
quotestart = s;
start = s+1;
- for(int braktype = *s++, brak = 1;;)
- {
+ for(int braktype = *s++, brak = 1;;) {
s += strcspn(s, "\"/;()[]\0");
int c = *s++;
- switch(c)
- {
+ switch(c) {
case '\0': s--; quoteend = end = s; return true;
case '"': s = parsestring(s); if(*s == '"') s++; break;
case '/': if(*s == '/') s += strcspn(s, "\n\0"); break;
@@ -2780,34 +2436,29 @@ static bool parselist(const char *&s, const char *&start = liststart, const char
return true;
}
-void explodelist(const char *s, vector<char *> &elems, int limit)
-{
+void explodelist(const char *s, vector<char *> &elems, int limit) {
const char *start, *end;
while((limit < 0 || elems.length() < limit) && parselist(s, start, end))
elems.add(newstring(start, end-start));
}
-char *indexlist(const char *s, int pos)
-{
+char *indexlist(const char *s, int pos) {
loopi(pos) if(!parselist(s)) return newstring("");
const char *start, *end;
return parselist(s, start, end) ? newstring(start, end-start) : newstring("");
}
-int listlen(const char *s)
-{
+int listlen(const char *s) {
int n = 0;
while(parselist(s)) n++;
return n;
}
ICOMMAND(listlen, "s", (char *s), intret(listlen(s)));
-void at(tagval *args, int numargs)
-{
+void at(tagval *args, int numargs) {
if(!numargs) return;
const char *start = args[0].getstr(), *end = start + strlen(start);
- for(int i = 1; i < numargs; i++)
- {
+ for(int i = 1; i < numargs; i++) {
const char *list = start;
int pos = args[i].getint();
for(; pos > 0; pos--) if(!parselist(list)) break;
@@ -2817,28 +2468,23 @@ void at(tagval *args, int numargs)
}
COMMAND(at, "si1V");
-void substr(char *s, int *start, int *count, int *numargs)
-{
+void substr(char *s, int *start, int *count, int *numargs) {
int len = strlen(s), offset = clamp(*start, 0, len);
commandret->setstr(newstring(&s[offset], *numargs >= 3 ? clamp(*count, 0, len - offset) : len - offset));
}
COMMAND(substr, "siiN");
-void chopstr(char *s, int *lim, char *ellipsis)
-{
+void chopstr(char *s, int *lim, char *ellipsis) {
int len = strlen(s), maxlen = abs(*lim);
- if(len > maxlen)
- {
+ if(len > maxlen) {
int elen = strlen(ellipsis);
maxlen = max(maxlen, elen);
char *chopped = newstring(maxlen);
- if(*lim < 0)
- {
+ if(*lim < 0) {
memcpy(chopped, ellipsis, elen);
memcpy(&chopped[elen], &s[len - (maxlen - elen)], maxlen - elen);
}
- else
- {
+ else {
memcpy(chopped, s, maxlen - elen);
memcpy(&chopped[maxlen - elen], ellipsis, elen);
}
@@ -2849,8 +2495,7 @@ void chopstr(char *s, int *lim, char *ellipsis)
}
COMMAND(chopstr, "sis");
-void sublist(const char *s, int *skip, int *count, int *numargs)
-{
+void sublist(const char *s, int *skip, int *count, int *numargs) {
int offset = max(*skip, 0), len = *numargs >= 3 ? max(*count, 0) : -1;
loopi(offset) if(!parselist(s)) break;
if(len < 0) { if(offset > 0) skiplist(s); commandret->setstr(newstring(s)); return; }
@@ -2860,25 +2505,21 @@ void sublist(const char *s, int *skip, int *count, int *numargs)
}
COMMAND(sublist, "siiN");
-ICOMMAND(stripcolors, "s", (char *s),
-{
+ICOMMAND(stripcolors, "s", (char *s), {
int len = strlen(s);
char *d = newstring(len);
filtertext(d, s, true, false, len);
stringret(d);
});
-static inline void setiter(ident &id, char *val, identstack &stack)
-{
- if(id.stack == &stack)
- {
+static inline void setiter(ident &id, char *val, identstack &stack) {
+ if(id.stack == &stack) {
if(id.valtype == VAL_STR) delete[] id.val.s;
else id.valtype = VAL_STR;
cleancode(id);
id.val.s = val;
}
- else
- {
+ else {
tagval t;
t.setstr(val);
pusharg(id, t, stack);
@@ -2886,13 +2527,11 @@ static inline void setiter(ident &id, char *val, identstack &stack)
}
}
-void listfind(ident *id, const char *list, const uint *body)
-{
+void listfind(ident *id, const char *list, const uint *body) {
if(id->type!=ID_ALIAS) { intret(-1); return; }
identstack stack;
int n = -1;
- for(const char *s = list, *start, *end; parselist(s, start, end);)
- {
+ for(const char *s = list, *start, *end; parselist(s, start, end);) {
++n;
char *val = newstring(start, end-start);
setiter(*id, val, stack);
@@ -2904,13 +2543,11 @@ found:
}
COMMAND(listfind, "rse");
-void looplist(ident *id, const char *list, const uint *body)
-{
+void looplist(ident *id, const char *list, const uint *body) {
if(id->type!=ID_ALIAS) return;
identstack stack;
int n = 0;
- for(const char *s = list, *start, *end; parselist(s, start, end); n++)
- {
+ for(const char *s = list, *start, *end; parselist(s, start, end); n++) {
char *val = newstring(start, end-start);
setiter(*id, val, stack);
execute(body);
@@ -2919,13 +2556,11 @@ void looplist(ident *id, const char *list, const uint *body)
}
COMMAND(looplist, "rse");
-void loopsublist(ident *id, const char *list, int *skip, int *count, const uint *body)
-{
+void loopsublist(ident *id, const char *list, int *skip, int *count, const uint *body) {
if(id->type!=ID_ALIAS) return;
identstack stack;
int n = 0, offset = max(*skip, 0), len = *count < 0 ? INT_MAX : offset + *count;
- for(const char *s = list, *start, *end; parselist(s, start, end) && n < len; n++) if(n >= offset)
- {
+ for(const char *s = list, *start, *end; parselist(s, start, end) && n < len; n++) if(n >= offset) {
char *val = newstring(start, end-start);
setiter(*id, val, stack);
execute(body);
@@ -2934,19 +2569,15 @@ void loopsublist(ident *id, const char *list, int *skip, int *count, const uint
}
COMMAND(loopsublist, "rsiie");
-void looplistconc(ident *id, const char *list, const uint *body, bool space)
-{
+void looplistconc(ident *id, const char *list, const uint *body, bool space) {
if(id->type!=ID_ALIAS) return;
identstack stack;
vector<char> r;
int n = 0;
- for(const char *s = list, *start, *end; parselist(s, start, end); n++)
- {
+ for(const char *s = list, *start, *end; parselist(s, start, end); n++) {
char *val = newstring(start, end-start);
setiter(*id, val, stack);
-
if(n && space) r.add(' ');
-
tagval v;
executeret(body, v);
const char *vstr = v.getstr();
@@ -2961,19 +2592,15 @@ void looplistconc(ident *id, const char *list, const uint *body, bool space)
ICOMMAND(looplistconcat, "rse", (ident *id, char *list, uint *body), looplistconc(id, list, body, true));
ICOMMAND(looplistconcatword, "rse", (ident *id, char *list, uint *body), looplistconc(id, list, body, false));
-void listfilter(ident *id, const char *list, const uint *body)
-{
+void listfilter(ident *id, const char *list, const uint *body) {
if(id->type!=ID_ALIAS) return;
identstack stack;
vector<char> r;
int n = 0;
- for(const char *s = list, *start, *end, *quotestart, *quoteend; parselist(s, start, end, quotestart, quoteend); n++)
- {
+ for(const char *s = list, *start, *end, *quotestart, *quoteend; parselist(s, start, end, quotestart, quoteend); n++) {
char *val = newstring(start, end-start);
setiter(*id, val, stack);
-
- if(executebool(body))
- {
+ if(executebool(body)) {
if(r.length()) r.add(' ');
r.put(quotestart, quoteend-quotestart);
}
@@ -2984,18 +2611,14 @@ void listfilter(ident *id, const char *list, const uint *body)
}
COMMAND(listfilter, "rse");
-void prettylist(const char *s, const char *conj)
-{
+void prettylist(const char *s, const char *conj) {
vector<char> p;
const char *start, *end;
- for(int len = listlen(s), n = 0; parselist(s, start, end); n++)
- {
+ for(int len = listlen(s), n = 0; parselist(s, start, end); n++) {
p.put(start, end - start);
- if(n+1 < len)
- {
+ if(n+1 < len) {
if(len > 2 || !conj[0]) p.add(',');
- if(n+2 == len && conj[0])
- {
+ if(n+2 == len && conj[0]) {
p.add(' ');
p.put(conj, strlen(conj));
}
@@ -3007,11 +2630,9 @@ void prettylist(const char *s, const char *conj)
}
COMMAND(prettylist, "ss");
-int listincludes(const char *list, const char *needle, int needlelen)
-{
+int listincludes(const char *list, const char *needle, int needlelen) {
int offset = 0;
- for(const char *s = list, *start, *end; parselist(s, start, end);)
- {
+ for(const char *s = list, *start, *end; parselist(s, start, end);) {
int len = end - start;
if(needlelen == len && !strncmp(needle, start, len)) return offset;
offset++;
@@ -3020,13 +2641,10 @@ int listincludes(const char *list, const char *needle, int needlelen)
}
ICOMMAND(indexof, "ss", (char *list, char *elem), intret(listincludes(list, elem, strlen(elem))));
-char *listdel(const char *s, const char *del)
-{
+char *listdel(const char *s, const char *del) {
vector<char> p;
- for(const char *start, *end, *qstart, *qend; parselist(s, start, end, qstart, qend);)
- {
- if(listincludes(del, start, end-start) < 0)
- {
+ for(const char *start, *end, *qstart, *qend; parselist(s, start, end, qstart, qend);) {
+ if(listincludes(del, start, end-start) < 0) {
if(!p.empty()) p.add(' ');
p.put(qstart, qend-qstart);
}
@@ -3036,22 +2654,19 @@ char *listdel(const char *s, const char *del)
}
ICOMMAND(listdel, "ss", (char *list, char *del), commandret->setstr(listdel(list, del)));
-void listsplice(const char *s, const char *vals, int *skip, int *count)
-{
+void listsplice(const char *s, const char *vals, int *skip, int *count) {
int offset = max(*skip, 0), len = max(*count, 0);
const char *list = s, *start, *end, *qstart, *qend = s;
loopi(offset) if(!parselist(s, start, end, qstart, qend)) break;
vector<char> p;
if(qend > list) p.put(list, qend-list);
- if(*vals)
- {
+ if(*vals) {
if(!p.empty()) p.add(' ');
p.put(vals, strlen(vals));
}
loopi(len) if(!parselist(s)) break;
skiplist(s);
- switch(*s)
- {
+ switch(*s) {
case '\0': case ')': case ']': break;
default:
if(!p.empty()) p.add(' ');
@@ -3063,30 +2678,25 @@ void listsplice(const char *s, const char *vals, int *skip, int *count)
}
COMMAND(listsplice, "ssii");
-ICOMMAND(loopfiles, "rsse", (ident *id, char *dir, char *ext, uint *body),
-{
+ICOMMAND(loopfiles, "rsse", (ident *id, char *dir, char *ext, uint *body), {
if(id->type!=ID_ALIAS) return;
identstack stack;
vector<char *> files;
listfiles(dir, ext[0] ? ext : NULL, files);
- loopvrev(files)
- {
+ loopvrev(files) {
char *file = files[i];
bool redundant = false;
loopj(i) if(!strcmp(files[j], file)) { redundant = true; break; }
if(redundant) delete[] files.removeunordered(i);
}
- loopv(files)
- {
+ loopv(files) {
char *file = files[i];
- if(i)
- {
+ if(i) {
if(id->valtype == VAL_STR) delete[] id->val.s;
else id->valtype = VAL_STR;
id->val.s = file;
}
- else
- {
+ else {
tagval t;
t.setstr(file);
pusharg(*id, t, stack);
@@ -3097,8 +2707,7 @@ ICOMMAND(loopfiles, "rsse", (ident *id, char *dir, char *ext, uint *body),
if(files.length()) poparg(*id);
});
-void findfile_(char *name)
-{
+void findfile_(char *name) {
string fname;
copystring(fname, name);
path(fname);
@@ -3111,18 +2720,14 @@ void findfile_(char *name)
}
COMMANDN(findfile, findfile_, "s");
-struct sortitem
-{
+struct sortitem {
const char *str, *quotestart, *quoteend;
};
-struct sortfun
-{
+struct sortfun {
ident *x, *y;
uint *body;
-
- bool operator()(const sortitem &xval, const sortitem &yval)
- {
+ bool operator()(const sortitem &xval, const sortitem &yval) {
if(x->valtype != VAL_MACRO) x->valtype = VAL_MACRO;
cleancode(*x);
x->val.code = (const uint *)xval.str;
@@ -3133,43 +2738,33 @@ struct sortfun
}
};
-void sortlist(char *list, ident *x, ident *y, uint *body)
-{
+void sortlist(char *list, ident *x, ident *y, uint *body) {
if(x == y || x->type != ID_ALIAS || y->type != ID_ALIAS) return;
-
vector<sortitem> items;
int macrolen = strlen(list), total = 0;
char *macros = newstring(list, macrolen);
const char *curlist = list, *start, *end, *quotestart, *quoteend;
- while(parselist(curlist, start, end, quotestart, quoteend))
- {
+ while(parselist(curlist, start, end, quotestart, quoteend)) {
macros[end - list] = '\0';
sortitem item = { &macros[start - list], quotestart, quoteend };
items.add(item);
total += int(quoteend - quotestart);
}
-
identstack xstack, ystack;
pusharg(*x, nullval, xstack); x->flags &= ~IDF_UNKNOWN;
pusharg(*y, nullval, ystack); y->flags &= ~IDF_UNKNOWN;
-
sortfun f = { x, y, body };
items.sort(f);
-
poparg(*x);
poparg(*y);
-
char *sorted = macros;
int sortedlen = total + max(items.length() - 1, 0);
- if(macrolen < sortedlen)
- {
+ if(macrolen < sortedlen) {
delete[] macros;
sorted = newstring(sortedlen);
}
-
int offset = 0;
- loopv(items)
- {
+ loopv(items) {
sortitem &item = items[i];
int len = int(item.quoteend - item.quotestart);
if(i) sorted[offset++] = ' ';
@@ -3177,7 +2772,6 @@ void sortlist(char *list, ident *x, ident *y, uint *body)
offset += len;
}
sorted[offset] = '\0';
-
commandret->setstr(sorted);
}
COMMAND(sortlist, "srre");
@@ -3210,21 +2804,17 @@ ICOMMAND(&~, "ii", (int *a, int *b), intret(*a & ~*b));
ICOMMAND(|~, "ii", (int *a, int *b), intret(*a | ~*b));
ICOMMAND(<<, "ii", (int *a, int *b), intret(*b < 32 ? *a << max(*b, 0) : 0));
ICOMMAND(>>, "ii", (int *a, int *b), intret(*a >> clamp(*b, 0, 31)));
-ICOMMAND(&&, "e1V", (tagval *args, int numargs),
-{
+ICOMMAND(&&, "e1V", (tagval *args, int numargs), {
if(!numargs) intret(1);
- else loopi(numargs)
- {
+ else loopi(numargs) {
if(i) freearg(*commandret);
executeret(args[i].code, *commandret);
if(!getbool(*commandret)) break;
}
});
-ICOMMAND(||, "e1V", (tagval *args, int numargs),
-{
+ICOMMAND(||, "e1V", (tagval *args, int numargs), {
if(!numargs) intret(0);
- else loopi(numargs)
- {
+ else loopi(numargs) {
if(i) freearg(*commandret);
executeret(args[i].code, *commandret);
if(getbool(*commandret)) break;
@@ -3248,26 +2838,22 @@ ICOMMAND(loge, "f", (float *a), floatret(log(*a)));
ICOMMAND(log2, "f", (float *a), floatret(log(*a)/M_LN2));
ICOMMAND(log10, "f", (float *a), floatret(log10(*a)));
ICOMMAND(exp, "f", (float *a), floatret(exp(*a)));
-ICOMMAND(min, "V", (tagval *args, int numargs),
-{
+ICOMMAND(min, "V", (tagval *args, int numargs), {
int val = numargs > 0 ? args[numargs - 1].getint() : 0;
loopi(numargs - 1) val = min(val, args[i].getint());
intret(val);
});
-ICOMMAND(max, "V", (tagval *args, int numargs),
-{
+ICOMMAND(max, "V", (tagval *args, int numargs), {
int val = numargs > 0 ? args[numargs - 1].getint() : 0;
loopi(numargs - 1) val = max(val, args[i].getint());
intret(val);
});
-ICOMMAND(minf, "V", (tagval *args, int numargs),
-{
+ICOMMAND(minf, "V", (tagval *args, int numargs), {
float val = numargs > 0 ? args[numargs - 1].getfloat() : 0.0f;
loopi(numargs - 1) val = min(val, args[i].getfloat());
floatret(val);
});
-ICOMMAND(maxf, "V", (tagval *args, int numargs),
-{
+ICOMMAND(maxf, "V", (tagval *args, int numargs), {
float val = numargs > 0 ? args[numargs - 1].getfloat() : 0.0f;
loopi(numargs - 1) val = max(val, args[i].getfloat());
floatret(val);
@@ -3277,12 +2863,10 @@ ICOMMAND(absf, "f", (float *n), floatret(fabs(*n)));
ICOMMAND(floor, "f", (float *n), floatret(floor(*n)));
ICOMMAND(ceil, "f", (float *n), floatret(ceil(*n)));
-ICOMMAND(round, "ff", (float *n, float *k),
-{
+ICOMMAND(round, "ff", (float *n, float *k), {
double step = *k;
double r = *n;
- if(step > 0)
- {
+ if(step > 0) {
r += step * (r < 0 ? -0.5 : 0.5);
r -= fmod(r, step);
}
@@ -3290,34 +2874,29 @@ ICOMMAND(round, "ff", (float *n, float *k),
floatret(float(r));
});
-ICOMMAND(cond, "ee2V", (tagval *args, int numargs),
-{
- for(int i = 0; i < numargs; i += 2)
- {
- if(i+1 < numargs)
- {
- if(executebool(args[i].code))
- {
+ICOMMAND(cond, "ee2V", (tagval *args, int numargs), {
+ for(int i = 0; i < numargs; i += 2) {
+ if(i+1 < numargs) {
+ if(executebool(args[i].code)) {
executeret(args[i+1].code, *commandret);
break;
}
}
- else
- {
+ else {
executeret(args[i].code, *commandret);
break;
}
}
});
#define CASECOMMAND(name, fmt, type, acc, compare) \
- ICOMMAND(name, fmt "te2V", (tagval *args, int numargs), \
- { \
+ ICOMMAND(name, fmt "te2V", (tagval *args, int numargs), { \
+ \
type val = acc; \
int i; \
- for(i = 1; i+1 < numargs; i += 2) \
- { \
- if(compare) \
- { \
+ for(i = 1; i+1 < numargs; i += 2) { \
+ \
+ if(compare) { \
+ \
executeret(args[i+1].code, *commandret); \
return; \
} \
@@ -3328,15 +2907,12 @@ CASECOMMAND(casef, "f", float, args[0].getfloat(), args[i].type == VAL_NULL || a
CASECOMMAND(cases, "s", const char *, args[0].getstr(), args[i].type == VAL_NULL || !strcmp(args[i].getstr(), val));
ICOMMAND(rnd, "ii", (int *a, int *b), intret(*a - *b > 0 ? rnd(*a - *b) + *b : *b));
-ICOMMAND(rndstr, "i", (int *len),
-{
+ICOMMAND(rndstr, "i", (int *len), {
int n = clamp(*len, 0, 10000);
char *s = newstring(n);
- for(int i = 0; i < n;)
- {
+ for(int i = 0; i < n;) {
uint r = randomMT();
- for(int j = min(i + 4, n); i < j; i++)
- {
+ for(int j = min(i + 4, n); i < j; i++) {
s[i] = (r%255) + 1;
r /= 255;
}
@@ -3361,15 +2937,12 @@ ICOMMAND(codestr, "i", (int *i), { char *s = newstring(1); s[0] = char(*i); s[1]
ICOMMAND(struni, "si", (char *s, int *i), intret(*i > 0 ? (memchr(s, 0, *i) ? 0 : cube2uni(s[*i])) : cube2uni(s[0])));
ICOMMAND(unistr, "i", (int *i), { char *s = newstring(1); s[0] = uni2cube(*i); s[1] = '\0'; stringret(s); });
-int naturalsort(const char *a, const char *b)
-{
- for(;;)
- {
+int naturalsort(const char *a, const char *b) {
+ for(;;) {
int ac = *a, bc = *b;
if(!ac) return bc ? -1 : 0;
else if(!bc) return 1;
- else if(isdigit(ac) && isdigit(bc))
- {
+ else if(isdigit(ac) && isdigit(bc)) {
while(*a == '0') a++;
while(*b == '0') b++;
const char *a0 = a, *b0 = b;
@@ -3388,8 +2961,8 @@ int naturalsort(const char *a, const char *b)
ICOMMAND(naturalsort, "ss", (char *a, char *b), intret(naturalsort(a,b)<=0));
#define STRMAPCOMMAND(name, map) \
- ICOMMAND(name, "s", (char *s), \
- { \
+ ICOMMAND(name, "s", (char *s), { \
+ \
int len = strlen(s); \
char *m = newstring(len); \
loopi(len) m[i] = map(s[i]); \
@@ -3400,23 +2973,18 @@ ICOMMAND(naturalsort, "ss", (char *a, char *b), intret(naturalsort(a,b)<=0));
STRMAPCOMMAND(strlower, cubelower);
STRMAPCOMMAND(strupper, cubeupper);
-char *strreplace(const char *s, const char *oldval, const char *newval)
-{
+char *strreplace(const char *s, const char *oldval, const char *newval) {
vector<char> buf;
-
int oldlen = strlen(oldval);
if(!oldlen) return newstring(s);
- for(;;)
- {
+ for(;;) {
const char *found = strstr(s, oldval);
- if(found)
- {
+ if(found) {
while(s < found) buf.add(*s++);
for(const char *n = newval; *n; n++) buf.add(*n);
s = found + oldlen;
}
- else
- {
+ else {
while(*s) buf.add(*s++);
buf.add('\0');
return newstring(buf.getbuf(), buf.length());
@@ -3426,8 +2994,7 @@ char *strreplace(const char *s, const char *oldval, const char *newval)
ICOMMAND(strreplace, "sss", (char *s, char *o, char *n), commandret->setstr(strreplace(s, o, n)));
-void strsplice(const char *s, const char *vals, int *skip, int *count)
-{
+void strsplice(const char *s, const char *vals, int *skip, int *count) {
int slen = strlen(s), vlen = strlen(vals),
offset = clamp(*skip, 0, slen),
len = clamp(*count, 0, slen - offset);
@@ -3443,15 +3010,13 @@ COMMAND(strsplice, "ssii");
#ifndef STANDALONE
ICOMMAND(getmillis, "i", (int *total), intret(*total ? totalmillis : lastmillis));
-struct sleepcmd
-{
+struct sleepcmd {
int delay, millis, flags;
char *command;
};
vector<sleepcmd> sleepcmds;
-void addsleep(int *msec, char *cmd)
-{
+void addsleep(int *msec, char *cmd) {
sleepcmd &s = sleepcmds.add();
s.delay = max(*msec, 1);
s.millis = lastmillis;
@@ -3461,13 +3026,10 @@ void addsleep(int *msec, char *cmd)
COMMANDN(sleep, addsleep, "is");
-void checksleep(int millis)
-{
- loopv(sleepcmds)
- {
+void checksleep(int millis) {
+ loopv(sleepcmds) {
sleepcmd &s = sleepcmds[i];
- if(millis - s.millis >= s.delay)
- {
+ if(millis - s.millis >= s.delay) {
char *cmd = s.command; // execute might create more sleep commands
s.command = NULL;
int oldflags = identflags;
@@ -3480,19 +3042,16 @@ void checksleep(int millis)
}
}
-void clearsleep(bool clearoverrides)
-{
+void clearsleep(bool clearoverrides) {
int len = 0;
- loopv(sleepcmds) if(sleepcmds[i].command)
- {
+ loopv(sleepcmds) if(sleepcmds[i].command) {
if(clearoverrides && !(sleepcmds[i].flags&IDF_OVERRIDDEN)) sleepcmds[len++] = sleepcmds[i];
else delete[] sleepcmds[i].command;
}
sleepcmds.shrink(len);
}
-void clearsleep_(int *clearoverrides)
-{
+void clearsleep_(int *clearoverrides) {
clearsleep(*clearoverrides!=0 || identflags&IDF_OVERRIDDEN);
}
diff --git a/src/engine/console.cpp b/src/engine/console.cpp
index c979215..1386570 100644
--- a/src/engine/console.cpp
+++ b/src/engine/console.cpp
@@ -18,15 +18,12 @@ VARFP(maxcon, 10, 200, MAXCONLINES, { while(conlines.length() > maxcon) delete[]
VARP(contags, 0, 3, 3);
-void conline(int type, const char *sf) // add a line to the console buffer
-{
+void conline(int type, const char *sf) { // add a line to the console buffer {
char *buf = NULL;
- if(type&CON_TAG_MASK) for(int i = conlines.length()-1; i >= max(conlines.length()-contags, 0); i--)
- {
+ if(type&CON_TAG_MASK) for(int i = conlines.length()-1; i >= max(conlines.length()-contags, 0); i--) {
int prev = conlines.removing(i).type;
if(!(prev&CON_TAG_MASK)) break;
- if(type == prev)
- {
+ if(type == prev) {
buf = conlines.remove(i).line;
break;
}
@@ -39,8 +36,7 @@ void conline(int type, const char *sf) // add a line to the console buffer
copystring(cl.line, sf, CONSTRLEN);
}
-void conoutfv(int type, const char *fmt, va_list args)
-{
+void conoutfv(int type, const char *fmt, va_list args) {
static char buf[CONSTRLEN];
vformatstring(buf, fmt, args, sizeof(buf));
conline(type, buf);
@@ -50,10 +46,8 @@ void conoutfv(int type, const char *fmt, va_list args)
VAR(fullconsole, 0, 0, 1);
ICOMMAND(toggleconsole, "", (), { fullconsole ^= 1; });
-int rendercommand(int x, int y, int w)
-{
+int rendercommand(int x, int y, int w) {
if(commandmillis < 0) return 0;
-
defformatstring(s, "%s %s", commandprompt ? commandprompt : ">", commandbuf);
int width, height;
text_bounds(s, width, height, w);
@@ -74,16 +68,13 @@ HVARP(miniconfilter, 0, 0, 0x7FFFFFF);
int conskip = 0, miniconskip = 0;
-void setconskip(int &skip, int filter, int n)
-{
+void setconskip(int &skip, int filter, int n) {
filter &= CON_FLAGS;
int offset = abs(n), dir = n < 0 ? -1 : 1;
skip = clamp(skip, 0, conlines.length()-1);
- while(offset)
- {
+ while(offset) {
skip += dir;
- if(!conlines.inrange(skip))
- {
+ if(!conlines.inrange(skip)) {
skip = clamp(skip, 0, conlines.length()-1);
return;
}
@@ -96,24 +87,18 @@ ICOMMAND(miniconskip, "i", (int *n), setconskip(miniconskip, miniconfilter, *n))
ICOMMAND(clearconsole, "", (), { while(conlines.length()) delete[] conlines.pop().line; });
-int drawconlines(int conskip, int confade, int conwidth, int conheight, int conoff, int filter, int y = 0, int dir = 1)
-{
+int drawconlines(int conskip, int confade, int conwidth, int conheight, int conoff, int filter, int y = 0, int dir = 1) {
filter &= CON_FLAGS;
int numl = conlines.length(), offset = min(conskip, numl);
-
- if(confade)
- {
- if(!conskip)
- {
+ if(confade) {
+ if(!conskip) {
numl = 0;
loopvrev(conlines) if(totalmillis-conlines[i].outtime < confade*1000) { numl = i+1; break; }
}
else offset--;
}
-
int totalheight = 0;
- loopi(numl) //determine visible height
- {
+ loopi(numl) { //determine visible height {
// shuffle backwards to fill if necessary
int idx = offset+i < numl ? offset+i : --offset;
if(!(conlines[idx].type&filter)) continue;
@@ -124,8 +109,7 @@ int drawconlines(int conskip, int confade, int conwidth, int conheight, int cono
totalheight += height;
}
if(dir > 0) y = conoff;
- loopi(numl)
- {
+ loopi(numl) {
int idx = offset + (dir > 0 ? numl-i-1 : i);
if(!(conlines[idx].type&filter)) continue;
char *line = conlines[idx].line;
@@ -138,16 +122,13 @@ int drawconlines(int conskip, int confade, int conwidth, int conheight, int cono
return y+conoff;
}
-int renderconsole(int w, int h, int abovehud) // render buffer taking into account time & scrolling
-{
+int renderconsole(int w, int h, int abovehud) { // render buffer taking into account time & scrolling {
int conpad = fullconsole ? 0 : FONTH/4,
conoff = fullconsole ? FONTH : FONTH/3,
conheight = min(fullconsole ? ((h*fullconsize/100)/FONTH)*FONTH : FONTH*consize, h - 2*(conpad + conoff)),
conwidth = w - 2*(conpad + conoff) - (fullconsole ? 0 : game::clipconsole(w, h));
-
extern void consolebox(int x1, int y1, int x2, int y2);
if(fullconsole) consolebox(conpad, conpad, conwidth+conpad+2*conoff, conheight+conpad+2*conoff);
-
int y = drawconlines(conskip, fullconsole ? 0 : confade, conwidth, conheight, conpad+conoff, fullconsole ? fullconfilter : confilter);
if(!fullconsole && (miniconsize && miniconwidth))
drawconlines(miniconskip, miniconfade, (miniconwidth*(w - 2*(conpad + conoff)))/100, min(FONTH*miniconsize, abovehud - y), conpad+conoff, miniconfilter, abovehud, -1);
@@ -156,29 +137,24 @@ int renderconsole(int w, int h, int abovehud) // render buffer taking into
// keymap is defined externally in keymap.cfg
-struct keym
-{
- enum
- {
+struct keym {
+ enum {
ACTION_DEFAULT = 0,
ACTION_SPECTATOR,
ACTION_EDITING,
NUMACTIONS
};
-
int code;
char *name;
char *actions[NUMACTIONS];
bool pressed;
-
keym() : code(-1), name(NULL), pressed(false) { loopi(NUMACTIONS) actions[i] = newstring(""); }
~keym() { DELETEA(name); loopi(NUMACTIONS) DELETEA(actions[i]); }
};
hashtable<int, keym> keyms(128);
-void keymap(int *code, char *key)
-{
+void keymap(int *code, char *key) {
if(identflags&IDF_OVERRIDDEN) { conoutf(CON_ERROR, "cannot override keymap %d", *code); return; }
keym &km = keyms[*code];
km.code = *code;
@@ -191,19 +167,15 @@ COMMAND(keymap, "is");
keym *keypressed = NULL;
char *keyaction = NULL;
-const char *getkeyname(int code)
-{
+const char *getkeyname(int code) {
keym *km = keyms.access(code);
return km ? km->name : NULL;
}
-void searchbinds(char *action, int type)
-{
+void searchbinds(char *action, int type) {
vector<char> names;
- enumerate(keyms, keym, km,
- {
- if(!strcmp(km.actions[type], action))
- {
+ enumerate(keyms, keym, km, {
+ if(!strcmp(km.actions[type], action)) {
if(names.length()) names.add(' ');
names.put(km.name, strlen(km.name));
}
@@ -212,23 +184,19 @@ void searchbinds(char *action, int type)
result(names.getbuf());
}
-keym *findbind(char *key)
-{
- enumerate(keyms, keym, km,
- {
+keym *findbind(char *key) {
+ enumerate(keyms, keym, km, {
if(!strcasecmp(km.name, key)) return &km;
});
return NULL;
}
-void getbind(char *key, int type)
-{
+void getbind(char *key, int type) {
keym *km = findbind(key);
result(km ? km->actions[type] : "");
}
-void bindkey(char *key, char *action, int state, const char *cmd)
-{
+void bindkey(char *key, char *action, int state, const char *cmd) {
if(identflags&IDF_OVERRIDDEN) { conoutf(CON_ERROR, "cannot override %s \"%s\"", cmd, key); return; }
keym *km = findbind(key);
if(!km) { conoutf(CON_ERROR, "unknown key \"%s\"", key); return; }
@@ -251,8 +219,7 @@ ICOMMAND(searchbinds, "s", (char *action), searchbinds(action, keym::ACTION_DEF
ICOMMAND(searchspecbinds, "s", (char *action), searchbinds(action, keym::ACTION_SPECTATOR));
ICOMMAND(searcheditbinds, "s", (char *action), searchbinds(action, keym::ACTION_EDITING));
-void inputcommand(char *init, char *action = NULL, char *prompt = NULL, char *flags = NULL) // turns input to the command line on or off
-{
+void inputcommand(char *init, char *action = NULL, char *prompt = NULL, char *flags = NULL) { // turns input to the command line on or off {
commandmillis = init ? totalmillis : -1;
textinput(commandmillis >= 0, TI_CONSOLE);
keyrepeat(commandmillis >= 0, KR_CONSOLE);
@@ -263,8 +230,7 @@ void inputcommand(char *init, char *action = NULL, char *prompt = NULL, char *fl
if(action && action[0]) commandaction = newstring(action);
if(prompt && prompt[0]) commandprompt = newstring(prompt);
commandflags = 0;
- if(flags) while(*flags) switch(*flags++)
- {
+ if(flags) while(*flags) switch(*flags++) {
case 'c': commandflags |= CF_COMPLETE; break;
case 'x': commandflags |= CF_EXECUTE; break;
case 's': commandflags |= CF_COMPLETE|CF_EXECUTE; break;
@@ -275,8 +241,7 @@ void inputcommand(char *init, char *action = NULL, char *prompt = NULL, char *fl
ICOMMAND(saycommand, "C", (char *init), inputcommand(init));
COMMAND(inputcommand, "ssss");
-void pasteconsole()
-{
+void pasteconsole() {
if(!SDL_HasClipboardText()) return;
char *cb = SDL_GetClipboardText();
if(!cb) return;
@@ -287,21 +252,16 @@ void pasteconsole()
SDL_free(cb);
}
-struct hline
-{
+struct hline {
char *buf, *action, *prompt;
int flags;
-
hline() : buf(NULL), action(NULL), prompt(NULL), flags(0) {}
- ~hline()
- {
+ ~hline() {
DELETEA(buf);
DELETEA(action);
DELETEA(prompt);
}
-
- void restore()
- {
+ void restore() {
copystring(commandbuf, buf);
if(commandpos >= (int)strlen(commandbuf)) commandpos = -1;
DELETEA(commandaction);
@@ -310,28 +270,21 @@ struct hline
if(prompt) commandprompt = newstring(prompt);
commandflags = flags;
}
-
- bool shouldsave()
- {
+ bool shouldsave() {
return strcmp(commandbuf, buf) ||
(commandaction ? !action || strcmp(commandaction, action) : action!=NULL) ||
(commandprompt ? !prompt || strcmp(commandprompt, prompt) : prompt!=NULL) ||
commandflags != flags;
}
-
- void save()
- {
+ void save() {
buf = newstring(commandbuf);
if(commandaction) action = newstring(commandaction);
if(commandprompt) prompt = newstring(commandprompt);
flags = commandflags;
}
-
- void run()
- {
+ void run() {
if(flags&CF_EXECUTE && buf[0]=='/') execute(buf+1);
- else if(action)
- {
+ else if(action) {
alias("commandbuf", buf);
execute(action);
}
@@ -343,11 +296,9 @@ int histpos = 0;
VARP(maxhistory, 0, 1000, 10000);
-void history_(int *n)
-{
+void history_(int *n) {
static bool inhistory = false;
- if(!inhistory && history.inrange(*n))
- {
+ if(!inhistory && history.inrange(*n)) {
inhistory = true;
history[history.length()-*n-1]->run();
inhistory = false;
@@ -356,15 +307,13 @@ void history_(int *n)
COMMANDN(history, history_, "i");
-struct releaseaction
-{
+struct releaseaction {
keym *key;
char *action;
};
vector<releaseaction> releaseactions;
-const char *addreleaseaction(char *s)
-{
+const char *addreleaseaction(char *s) {
if(!keypressed) { delete[] s; return NULL; }
releaseaction &ra = releaseactions.add();
ra.key = keypressed;
@@ -372,30 +321,24 @@ const char *addreleaseaction(char *s)
return keypressed->name;
}
-void onrelease(const char *s)
-{
+void onrelease(const char *s) {
addreleaseaction(newstring(s));
}
COMMAND(onrelease, "s");
-void execbind(keym &k, bool isdown)
-{
- loopv(releaseactions)
- {
+void execbind(keym &k, bool isdown) {
+ loopv(releaseactions) {
releaseaction &ra = releaseactions[i];
- if(ra.key==&k)
- {
+ if(ra.key==&k) {
if(!isdown) execute(ra.action);
delete[] ra.action;
releaseactions.remove(i--);
}
}
- if(isdown)
- {
+ if(isdown) {
int state = keym::ACTION_DEFAULT;
- if(!mainmenu)
- {
+ if(!mainmenu) {
if(editmode) state = keym::ACTION_EDITING;
else if(player->state==CS_SPECTATOR) state = keym::ACTION_SPECTATOR;
}
@@ -409,52 +352,39 @@ void execbind(keym &k, bool isdown)
k.pressed = isdown;
}
-bool consoleinput(const char *str, int len)
-{
+bool consoleinput(const char *str, int len) {
if(commandmillis < 0) return false;
-
resetcomplete();
int cmdlen = (int)strlen(commandbuf), cmdspace = int(sizeof(commandbuf)) - (cmdlen+1);
len = min(len, cmdspace);
- if(commandpos<0)
- {
+ if(commandpos<0) {
memcpy(&commandbuf[cmdlen], str, len);
}
- else
- {
+ else {
memmove(&commandbuf[commandpos+len], &commandbuf[commandpos], cmdlen - commandpos);
memcpy(&commandbuf[commandpos], str, len);
commandpos += len;
}
commandbuf[cmdlen + len] = '\0';
-
return true;
}
-bool consolekey(int code, bool isdown)
-{
+bool consolekey(int code, bool isdown) {
if(commandmillis < 0) return false;
#define MOD_KEYS (KMOD_LCTRL|KMOD_RCTRL)
-
- if(isdown)
- {
- switch(code)
- {
+ if(isdown) {
+ switch(code) {
case SDLK_RETURN:
case SDLK_KP_ENTER:
break;
-
case SDLK_HOME:
if(strlen(commandbuf)) commandpos = 0;
break;
-
case SDLK_END:
commandpos = -1;
break;
-
- case SDLK_DELETE:
- {
+ case SDLK_DELETE: {
int len = (int)strlen(commandbuf);
if(commandpos<0) break;
memmove(&commandbuf[commandpos], &commandbuf[commandpos+1], len - commandpos);
@@ -462,9 +392,7 @@ bool consolekey(int code, bool isdown)
if(commandpos>=len-1) commandpos = -1;
break;
}
-
- case SDLK_BACKSPACE:
- {
+ case SDLK_BACKSPACE: {
int len = (int)strlen(commandbuf), i = commandpos>=0 ? commandpos : len;
if(i<1) break;
memmove(&commandbuf[i-1], &commandbuf[i], len - i + 1);
@@ -473,49 +401,37 @@ bool consolekey(int code, bool isdown)
else if(!commandpos && len<=1) commandpos = -1;
break;
}
-
case SDLK_LEFT:
if(commandpos>0) commandpos--;
else if(commandpos<0) commandpos = (int)strlen(commandbuf)-1;
break;
-
case SDLK_RIGHT:
if(commandpos>=0 && ++commandpos>=(int)strlen(commandbuf)) commandpos = -1;
break;
-
case SDLK_UP:
if(histpos > history.length()) histpos = history.length();
if(histpos > 0) history[--histpos]->restore();
break;
-
case SDLK_DOWN:
if(histpos + 1 < history.length()) history[++histpos]->restore();
break;
-
case SDLK_TAB:
- if(commandflags&CF_COMPLETE)
- {
+ if(commandflags&CF_COMPLETE) {
complete(commandbuf, sizeof(commandbuf), commandflags&CF_EXECUTE ? "/" : NULL);
if(commandpos>=0 && commandpos>=(int)strlen(commandbuf)) commandpos = -1;
}
break;
-
case SDLK_v:
if(SDL_GetModState()&MOD_KEYS) pasteconsole();
break;
}
}
- else
- {
- if(code==SDLK_RETURN || code==SDLK_KP_ENTER)
- {
+ else {
+ if(code==SDLK_RETURN || code==SDLK_KP_ENTER) {
hline *h = NULL;
- if(commandbuf[0])
- {
- if(history.empty() || history.last()->shouldsave())
- {
- if(maxhistory && history.length() >= maxhistory)
- {
+ if(commandbuf[0]) {
+ if(history.empty() || history.last()->shouldsave()) {
+ if(maxhistory && history.length() >= maxhistory) {
loopi(history.length()-maxhistory+1) delete history[i];
history.remove(0, history.length()-maxhistory+1);
}
@@ -527,59 +443,47 @@ bool consolekey(int code, bool isdown)
inputcommand(NULL);
if(h) h->run();
}
- else if(code==SDLK_ESCAPE)
- {
+ else if(code==SDLK_ESCAPE) {
histpos = history.length();
inputcommand(NULL);
}
}
-
return true;
}
-void processtextinput(const char *str, int len)
-{
+void processtextinput(const char *str, int len) {
if(!g3d_input(str, len))
consoleinput(str, len);
}
-void processkey(int code, bool isdown, int modstate)
-{
- switch(code)
- {
+void processkey(int code, bool isdown, int modstate) {
+ switch(code) {
case SDLK_LGUI: case SDLK_RGUI:
return;
}
keym *haskey = keyms.access(code);
if(haskey && haskey->pressed) execbind(*haskey, isdown); // allow pressed keys to release
- else if(!g3d_key(code, isdown)) // 3D GUI mouse button intercept
- {
- if(!consolekey(code, isdown))
- {
+ else if(!g3d_key(code, isdown)) { // 3D GUI mouse button intercept {
+ if(!consolekey(code, isdown)) {
if(modstate&KMOD_GUI) return;
if(haskey) execbind(*haskey, isdown);
}
}
}
-void clear_console()
-{
+void clear_console() {
keyms.clear();
}
-void writebinds(stream *f)
-{
+void writebinds(stream *f) {
static const char * const cmds[3] = { "bind", "specbind", "editbind" };
vector<keym *> binds;
enumerate(keyms, keym, km, binds.add(&km));
binds.sortname();
- loopj(3)
- {
- loopv(binds)
- {
+ loopj(3) {
+ loopv(binds) {
keym &km = *binds[i];
- if(*km.actions[j])
- {
+ if(*km.actions[j]) {
if(validateblock(km.actions[j])) f->printf("%s %s [%s]\n", cmds[j], escapestring(km.name), km.actions[j]);
else f->printf("%s %s %s\n", cmds[j], escapestring(km.name), escapestring(km.actions[j]));
}
@@ -591,42 +495,33 @@ void writebinds(stream *f)
enum { FILES_DIR = 0, FILES_VAR, FILES_LIST };
-struct fileskey
-{
+struct fileskey {
int type;
const char *dir, *ext;
-
fileskey() {}
fileskey(int type, const char *dir, const char *ext) : type(type), dir(dir), ext(ext) {}
};
-static void cleanfilesdir(char *dir)
-{
+static void cleanfilesdir(char *dir) {
int dirlen = (int)strlen(dir);
while(dirlen > 0 && (dir[dirlen-1] == '/' || dir[dirlen-1] == '\\'))
dir[--dirlen] = '\0';
}
-struct filesval
-{
+struct filesval {
int type;
char *dir, *ext;
vector<char *> files;
int millis;
-
filesval(int type, const char *dir, const char *ext) : type(type), dir(newstring(dir)), ext(ext && ext[0] ? newstring(ext) : NULL), millis(-1) {}
~filesval() { DELETEA(dir); DELETEA(ext); files.deletearrays(); }
-
- void update()
- {
+ void update() {
if((type!=FILES_DIR && type!=FILES_VAR) || millis >= commandmillis) return;
files.deletearrays();
- if(type==FILES_VAR)
- {
+ if(type==FILES_VAR) {
string buf;
buf[0] = '\0';
- if(ident *id = readident(dir)) switch(id->type)
- {
+ if(ident *id = readident(dir)) switch(id->type) {
case ID_SVAR: copystring(buf, *id->storage.s); break;
case ID_ALIAS: copystring(buf, id->getstr()); break;
}
@@ -641,13 +536,11 @@ struct filesval
}
};
-static inline bool htcmp(const fileskey &x, const fileskey &y)
-{
+static inline bool htcmp(const fileskey &x, const fileskey &y) {
return x.type==y.type && !strcmp(x.dir, y.dir) && (x.ext == y.ext || (x.ext && y.ext && !strcmp(x.ext, y.ext)));
}
-static inline uint hthash(const fileskey &k)
-{
+static inline uint hthash(const fileskey &k) {
return hthash(k.dir);
}
@@ -659,29 +552,24 @@ char *lastcomplete = NULL;
void resetcomplete() { completesize = 0; }
-void addcomplete(char *command, int type, char *dir, char *ext)
-{
- if(identflags&IDF_OVERRIDDEN)
- {
+void addcomplete(char *command, int type, char *dir, char *ext) {
+ if(identflags&IDF_OVERRIDDEN) {
conoutf(CON_ERROR, "cannot override complete %s", command);
return;
}
- if(!dir[0])
- {
+ if(!dir[0]) {
filesval **hasfiles = completions.access(command);
if(hasfiles) *hasfiles = NULL;
return;
}
if(type==FILES_DIR) cleanfilesdir(dir);
- if(ext)
- {
+ if(ext) {
if(strchr(ext, '*')) ext[0] = '\0';
if(!ext[0]) ext = NULL;
}
fileskey key(type, dir, ext);
filesval **val = completefiles.access(key);
- if(!val)
- {
+ if(!val) {
filesval *f = new filesval(type, dir, ext);
if(type==FILES_LIST) explodelist(dir, f->files);
val = &completefiles[fileskey(type, f->dir, f->ext)];
@@ -692,18 +580,15 @@ void addcomplete(char *command, int type, char *dir, char *ext)
else completions[newstring(command)] = *val;
}
-void addfilecomplete(char *command, char *dir, char *ext)
-{
+void addfilecomplete(char *command, char *dir, char *ext) {
addcomplete(command, FILES_DIR, dir, ext);
}
-void addvarcomplete(char *command, char *var, char *ext)
-{
+void addvarcomplete(char *command, char *var, char *ext) {
addcomplete(command, FILES_VAR, var, ext);
}
-void addlistcomplete(char *command, char *list)
-{
+void addlistcomplete(char *command, char *list) {
addcomplete(command, FILES_LIST, list, NULL);
}
@@ -711,31 +596,24 @@ COMMANDN(complete, addfilecomplete, "sss");
COMMANDN(varcomplete, addvarcomplete, "sss");
COMMANDN(listcomplete, addlistcomplete, "ss");
-void complete(char *s, int maxlen, const char *cmdprefix)
-{
+void complete(char *s, int maxlen, const char *cmdprefix) {
int cmdlen = 0;
- if(cmdprefix)
- {
+ if(cmdprefix) {
cmdlen = strlen(cmdprefix);
if(strncmp(s, cmdprefix, cmdlen)) prependstring(s, cmdprefix, maxlen);
}
if(!s[cmdlen]) return;
if(!completesize) { completesize = (int)strlen(&s[cmdlen]); DELETEA(lastcomplete); }
-
filesval *f = NULL;
- if(completesize)
- {
+ if(completesize) {
char *end = strchr(&s[cmdlen], ' ');
if(end) f = completions.find(stringslice(&s[cmdlen], end), NULL);
}
-
const char *nextcomplete = NULL;
- if(f) // complete using filenames
- {
+ if(f) { // complete using filenames {
int commandsize = strchr(&s[cmdlen], ' ')+1-s;
f->update();
- loopv(f->files)
- {
+ loopv(f->files) {
if(strncmp(f->files[i], &s[commandsize], completesize+cmdlen-commandsize)==0 &&
(!lastcomplete || strcmp(f->files[i], lastcomplete) > 0) && (!nextcomplete || strcmp(f->files[i], nextcomplete) < 0))
nextcomplete = f->files[i];
@@ -743,8 +621,7 @@ void complete(char *s, int maxlen, const char *cmdprefix)
cmdprefix = s;
cmdlen = commandsize;
}
- else // complete using command names
- {
+ else { // complete using command names {
enumerate(idents, ident, id,
if(strncmp(id.name, &s[cmdlen], completesize)==0 &&
(!lastcomplete || strcmp(id.name, lastcomplete) > 0) && (!nextcomplete || strcmp(id.name, nextcomplete) < 0))
@@ -752,8 +629,7 @@ void complete(char *s, int maxlen, const char *cmdprefix)
);
}
DELETEA(lastcomplete);
- if(nextcomplete)
- {
+ if(nextcomplete) {
cmdlen = min(cmdlen, maxlen-1);
if(cmdlen) memmove(s, cmdprefix, cmdlen);
copystring(&s[cmdlen], nextcomplete, maxlen-cmdlen);
@@ -761,17 +637,14 @@ void complete(char *s, int maxlen, const char *cmdprefix)
}
}
-void writecompletions(stream *f)
-{
+void writecompletions(stream *f) {
vector<char *> cmds;
enumeratekt(completions, char *, k, filesval *, v, { if(v) cmds.add(k); });
cmds.sort();
- loopv(cmds)
- {
+ loopv(cmds) {
char *k = cmds[i];
filesval *v = completions[k];
- if(v->type==FILES_LIST)
- {
+ if(v->type==FILES_LIST) {
if(validateblock(v->dir)) f->printf("listcomplete %s [%s]\n", escapeid(k), v->dir);
else f->printf("listcomplete %s %s\n", escapeid(k), escapestring(v->dir));
}
diff --git a/src/engine/decal.cpp b/src/engine/decal.cpp
index 43ef667..bc39c1f 100644
--- a/src/engine/decal.cpp
+++ b/src/engine/decal.cpp
@@ -1,21 +1,18 @@
#include "engine.h"
-struct decalvert
-{
+struct decalvert {
vec pos;
bvec4 color;
vec2 tc;
};
-struct decalinfo
-{
+struct decalinfo {
int millis;
bvec color;
ushort startvert, endvert;
};
-enum
-{
+enum {
DF_RND4 = 1<<0,
DF_ROTATE = 1<<1,
DF_INVMOD = 1<<2,
@@ -27,8 +24,7 @@ enum
VARFP(maxdecaltris, 1, 1024, 16384, initdecals());
VARP(decalfade, 1000, 10000, 60000);
-struct decalrenderer
-{
+struct decalrenderer {
const char *texname;
int flags, fadeintime, fadeouttime, timetolive;
Texture *tex;
@@ -38,7 +34,6 @@ struct decalrenderer
int maxverts, startvert, endvert, lastvert, availverts;
GLuint vbo;
bool dirty;
-
decalrenderer(const char *texname, int flags = 0, int fadeintime = 0, int fadeouttime = 1000, int timetolive = -1)
: texname(texname), flags(flags),
fadeintime(fadeintime), fadeouttime(fadeouttime), timetolive(timetolive),
@@ -46,25 +41,18 @@ struct decalrenderer
decals(NULL), maxdecals(0), startdecal(0), enddecal(0),
verts(NULL), maxverts(0), startvert(0), endvert(0), lastvert(0), availverts(0),
vbo(0), dirty(false),
- decalu(0), decalv(0)
- {
+ decalu(0), decalv(0) {
}
-
- ~decalrenderer()
- {
+ ~decalrenderer() {
DELETEA(decals);
DELETEA(verts);
}
-
- void init(int tris)
- {
- if(decals)
- {
+ void init(int tris) {
+ if(decals) {
DELETEA(decals);
maxdecals = startdecal = enddecal = 0;
}
- if(verts)
- {
+ if(verts) {
DELETEA(verts);
maxverts = startvert = endvert = lastvert = availverts = 0;
}
@@ -75,80 +63,59 @@ struct decalrenderer
availverts = maxverts - 3;
verts = new decalvert[maxverts];
}
-
- int hasdecals()
- {
+ int hasdecals() {
return enddecal < startdecal ? maxdecals - (startdecal - enddecal) : enddecal - startdecal;
}
-
- void cleanup()
- {
+ void cleanup() {
if(vbo) { glDeleteBuffers_(1, &vbo); vbo = 0; }
}
-
- void cleardecals()
- {
+ void cleardecals() {
startdecal = enddecal = 0;
startvert = endvert = lastvert = 0;
availverts = maxverts - 3;
dirty = true;
}
-
- int freedecal()
- {
+ int freedecal() {
if(startdecal==enddecal) return 0;
-
decalinfo &d = decals[startdecal];
startdecal++;
if(startdecal >= maxdecals) startdecal = 0;
-
int removed = d.endvert < d.startvert ? maxverts - (d.startvert - d.endvert) : d.endvert - d.startvert;
startvert = d.endvert;
if(startvert==endvert) startvert = endvert = lastvert = 0;
availverts += removed;
-
return removed;
}
-
- void fadedecal(decalinfo &d, uchar alpha)
- {
+ void fadedecal(decalinfo &d, uchar alpha) {
bvec rgb;
if(flags&DF_OVERBRIGHT) rgb = bvec(128, 128, 128);
- else
- {
+ else {
rgb = d.color;
if(flags&(DF_ADD|DF_INVMOD)) rgb.scale(alpha, 255);
}
bvec4 color(rgb, alpha);
-
decalvert *vert = &verts[d.startvert],
*end = &verts[d.endvert < d.startvert ? maxverts : d.endvert];
- while(vert < end)
- {
+ while(vert < end) {
vert->color = color;
vert++;
}
- if(d.endvert < d.startvert)
- {
+ if(d.endvert < d.startvert) {
vert = verts;
end = &verts[d.endvert];
- while(vert < end)
- {
+ while(vert < end) {
vert->color = color;
vert++;
}
}
dirty = true;
}
-
- void clearfadeddecals()
- {
+ void clearfadeddecals() {
int threshold = lastmillis - (timetolive>=0 ? timetolive : decalfade) - fadeouttime;
decalinfo *d = &decals[startdecal],
*end = &decals[enddecal < startdecal ? maxdecals : enddecal];
while(d < end && d->millis <= threshold) d++;
- if(d >= end && enddecal < startdecal)
- {
+ if(d >= end && enddecal < startdecal) {
d = decals;
end = &decals[enddecal];
while(d < end && d->millis <= threshold) d++;
@@ -161,25 +128,20 @@ struct decalrenderer
availverts = endvert < startvert ? startvert - endvert - 3 : maxverts - 3 - (endvert - startvert);
dirty = true;
}
-
- void fadeindecals()
- {
+ void fadeindecals() {
if(!fadeintime) return;
decalinfo *d = &decals[enddecal],
*end = &decals[enddecal < startdecal ? 0 : startdecal];
- while(d > end)
- {
+ while(d > end) {
d--;
int fade = lastmillis - d->millis;
if(fade >= fadeintime) return;
fadedecal(*d, (fade<<8)/fadeintime);
}
- if(enddecal < startdecal)
- {
+ if(enddecal < startdecal) {
d = &decals[maxdecals];
end = &decals[startdecal];
- while(d > end)
- {
+ while(d > end) {
d--;
int fade = lastmillis - d->millis;
if(fade >= fadeintime) return;
@@ -187,25 +149,20 @@ struct decalrenderer
}
}
}
-
- void fadeoutdecals()
- {
+ void fadeoutdecals() {
decalinfo *d = &decals[startdecal],
*end = &decals[enddecal < startdecal ? maxdecals : enddecal];
int offset = (timetolive>=0 ? timetolive : decalfade) + fadeouttime - lastmillis;
- while(d < end)
- {
+ while(d < end) {
int fade = d->millis + offset;
if(fade >= fadeouttime) return;
fadedecal(*d, (fade<<8)/fadeouttime);
d++;
}
- if(enddecal < startdecal)
- {
+ if(enddecal < startdecal) {
d = decals;
end = &decals[enddecal];
- while(d < end)
- {
+ while(d < end) {
int fade = d->millis + offset;
if(fade >= fadeouttime) return;
fadedecal(*d, (fade<<8)/fadeouttime);
@@ -213,84 +170,59 @@ struct decalrenderer
}
}
}
-
- static void setuprenderstate()
- {
+ static void setuprenderstate() {
enablepolygonoffset(GL_POLYGON_OFFSET_FILL);
-
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
-
gle::enablevertex();
gle::enabletexcoord0();
gle::enablecolor();
}
-
- static void cleanuprenderstate()
- {
+ static void cleanuprenderstate() {
gle::clearvbo();
-
gle::disablevertex();
gle::disabletexcoord0();
gle::disablecolor();
-
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
-
disablepolygonoffset(GL_POLYGON_OFFSET_FILL);
}
-
- void render()
- {
+ void render() {
if(startvert==endvert) return;
-
- if(flags&DF_OVERBRIGHT)
- {
+ if(flags&DF_OVERBRIGHT) {
glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
SETSHADER(overbrightdecal);
}
- else
- {
+ else {
if(flags&DF_INVMOD) { glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); }
else if(flags&DF_ADD) { glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); }
else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
if(flags&DF_SATURATE) SETSHADER(saturatedecal);
}
-
glBindTexture(GL_TEXTURE_2D, tex->id);
-
if(!vbo) { glGenBuffers_(1, &vbo); dirty = true; }
gle::bindvbo(vbo);
-
int count = endvert < startvert ? maxverts - startvert : endvert - startvert;
- if(dirty)
- {
+ if(dirty) {
glBufferData_(GL_ARRAY_BUFFER, maxverts*sizeof(decalvert), NULL, GL_STREAM_DRAW);
glBufferSubData_(GL_ARRAY_BUFFER, 0, count*sizeof(decalvert), &verts[startvert]);
- if(endvert < startvert)
- {
+ if(endvert < startvert) {
glBufferSubData_(GL_ARRAY_BUFFER, count*sizeof(decalvert), endvert*sizeof(decalvert), verts);
count += endvert;
}
dirty = false;
}
else if(endvert < startvert) count += endvert;
-
const decalvert *ptr = 0;
gle::vertexpointer(sizeof(decalvert), ptr->pos.v);
gle::texcoord0pointer(sizeof(decalvert), ptr->tc.v);
gle::colorpointer(sizeof(decalvert), ptr->color.v);
-
glDrawArrays(GL_TRIANGLES, 0, count);
xtravertsva += count;
-
extern int intel_vertexarray_bug;
if(intel_vertexarray_bug) glFlush();
}
-
- decalinfo &newdecal()
- {
+ decalinfo &newdecal() {
decalinfo &d = decals[enddecal];
int next = enddecal + 1;
if(next>=maxdecals) next = 0;
@@ -299,20 +231,15 @@ struct decalrenderer
dirty = true;
return d;
}
-
ivec bbmin, bbmax;
vec decalcenter, decalnormal, decaltangent, decalbitangent;
float decalradius, decalu, decalv;
bvec4 decalcolor;
-
- void adddecal(const vec &center, const vec &dir, float radius, const bvec &color, int info)
- {
+ void adddecal(const vec &center, const vec &dir, float radius, const bvec &color, int info) {
if(dir.iszero()) return;
-
int bbradius = int(ceil(radius));
bbmin = ivec(center).sub(bbradius);
bbmax = ivec(center).add(bbradius);
-
decalcolor = bvec4(color, 255);
decalcenter = center;
decalradius = radius;
@@ -326,46 +253,36 @@ struct decalrenderer
if(flags&DF_ROTATE) decaltangent.rotate(rnd(360)*RAD, dir);
decaltangent.normalize();
decalbitangent.cross(decaltangent, dir);
- if(flags&DF_RND4)
- {
+ if(flags&DF_RND4) {
decalu = 0.5f*(info&1);
decalv = 0.5f*((info>>1)&1);
}
-
lastvert = endvert;
gentris(worldroot, ivec(0, 0, 0), worldsize>>1);
if(endvert==lastvert) return;
-
decalinfo &d = newdecal();
d.color = color;
d.millis = lastmillis;
d.startvert = lastvert;
d.endvert = endvert;
}
-
- static int clip(const vec *in, int numin, const vec &dir, float below, float above, vec *out)
- {
+ static int clip(const vec *in, int numin, const vec &dir, float below, float above, vec *out) {
int numout = 0;
const vec *p = &in[numin-1];
float pc = dir.dot(*p);
- loopi(numin)
- {
+ loopi(numin) {
const vec &v = in[i];
float c = dir.dot(v);
- if(c < below)
- {
+ if(c < below) {
if(pc > above) out[numout++] = vec(*p).sub(v).mul((above - c)/(pc - c)).add(v);
if(pc > below) out[numout++] = vec(*p).sub(v).mul((below - c)/(pc - c)).add(v);
}
- else if(c > above)
- {
+ else if(c > above) {
if(pc < below) out[numout++] = vec(*p).sub(v).mul((below - c)/(pc - c)).add(v);
if(pc < above) out[numout++] = vec(*p).sub(v).mul((above - c)/(pc - c)).add(v);
}
- else
- {
- if(pc < below)
- {
+ else {
+ if(pc < below) {
if(c > below) out[numout++] = vec(*p).sub(v).mul((below - c)/(pc - c)).add(v);
}
else if(pc > above && c < above) out[numout++] = vec(*p).sub(v).mul((above - c)/(pc - c)).add(v);
@@ -376,17 +293,13 @@ struct decalrenderer
}
return numout;
}
-
- void gentris(cube &cu, int orient, const ivec &o, int size, materialsurface *mat = NULL, int vismask = 0)
- {
+ void gentris(cube &cu, int orient, const ivec &o, int size, materialsurface *mat = NULL, int vismask = 0) {
vec pos[MAXFACEVERTS+4] = { vec(0, 0, 0) };
int numverts = 0, numplanes = 1;
vec planes[2] = { vec(0, 0, 0) };
- if(mat)
- {
+ if(mat) {
planes[0] = vec(0, 0, 0);
- switch(orient)
- {
+ switch(orient) {
#define GENFACEORIENT(orient, v0, v1, v2, v3) \
case orient: \
planes[0][dimension(orient)] = dimcoord(orient) ? 1 : -1; \
@@ -399,21 +312,18 @@ struct decalrenderer
#undef GENFACEVERT
}
}
- else if(cu.ext && (numverts = cu.ext->surfaces[orient].numverts&MAXFACEVERTS))
- {
+ else if(cu.ext && (numverts = cu.ext->surfaces[orient].numverts&MAXFACEVERTS)) {
vertinfo *verts = cu.ext->verts() + cu.ext->surfaces[orient].verts;
ivec vo = ivec(o).mask(~0xFFF).shl(3);
loopj(numverts) pos[j] = vec(verts[j].getxyz().add(vo)).mul(1/8.0f);
planes[0].cross(pos[0], pos[1], pos[2]).normalize();
- if(numverts >= 4 && !(cu.merged&(1<<orient)) && !flataxisface(cu, orient) && faceconvexity(verts, numverts, size))
- {
+ if(numverts >= 4 && !(cu.merged&(1<<orient)) && !flataxisface(cu, orient) && faceconvexity(verts, numverts, size)) {
planes[1].cross(pos[0], pos[2], pos[3]).normalize();
numplanes++;
}
}
else if(cu.merged&(1<<orient)) return;
- else if(!vismask || (vismask&0x40 && visibleface(cu, orient, o, size, MAT_AIR, (cu.material&MAT_ALPHA)^MAT_ALPHA, MAT_ALPHA)))
- {
+ else if(!vismask || (vismask&0x40 && visibleface(cu, orient, o, size, MAT_AIR, (cu.material&MAT_ALPHA)^MAT_ALPHA, MAT_ALPHA))) {
ivec v[4];
genfaceverts(cu, orient, v);
int vis = 3, convex = faceconvexity(v, vis), order = convex < 0 ? 1 : 0;
@@ -426,9 +336,7 @@ struct decalrenderer
if(convex) { planes[1].cross(pos[0], pos[2], pos[3]).normalize(); numplanes++; }
}
else return;
-
- loopl(numplanes)
- {
+ loopl(numplanes) {
const vec &n = planes[l];
float facing = n.dot(decalnormal);
if(facing <= 0) continue;
@@ -455,14 +363,12 @@ struct decalrenderer
vec v1[MAXFACEVERTS+4], v2[MAXFACEVERTS+4];
float ptc = pt.dot(pcenter), pbc = pb.dot(pcenter);
int numv;
- if(numplanes >= 2)
- {
+ if(numplanes >= 2) {
if(l) { pos[1] = pos[2]; pos[2] = pos[3]; }
numv = clip(pos, 3, pt, ptc - decalradius, ptc + decalradius, v1);
if(numv<3) continue;
}
- else
- {
+ else {
numv = clip(pos, numverts, pt, ptc - decalradius, ptc + decalradius, v1);
if(numv<3) continue;
}
@@ -475,13 +381,11 @@ struct decalrenderer
dv2 = { v2[1], decalcolor, vec2(pt.dot(v2[1]) + tu, pb.dot(v2[1]) + tv) };
int totalverts = 3*(numv-2);
if(totalverts > maxverts-3) return;
- while(availverts < totalverts)
- {
+ while(availverts < totalverts) {
if(!freedecal()) return;
}
availverts -= totalverts;
- loopk(numv-2)
- {
+ loopk(numv-2) {
verts[endvert++] = dv1;
verts[endvert++] = dv2;
dv2.pos = v2[k+2];
@@ -491,25 +395,20 @@ struct decalrenderer
}
}
}
-
- void findmaterials(vtxarray *va)
- {
+ void findmaterials(vtxarray *va) {
materialsurface *matbuf = va->matbuf;
int matsurfs = va->matsurfs;
- loopi(matsurfs)
- {
+ loopi(matsurfs) {
materialsurface &m = matbuf[i];
if(1) { i += m.skip; continue; }
int dim = dimension(m.orient), dc = dimcoord(m.orient);
if(dc ? decalnormal[dim] <= 0 : decalnormal[dim] >= 0) { i += m.skip; continue; }
int c = C[dim], r = R[dim];
- for(;;)
- {
+ for(;;) {
materialsurface &m = matbuf[i];
if(m.o[dim] >= bbmin[dim] && m.o[dim] <= bbmax[dim] &&
m.o[c] + m.csize >= bbmin[c] && m.o[c] <= bbmax[c] &&
- m.o[r] + m.rsize >= bbmin[r] && m.o[r] <= bbmax[r])
- {
+ m.o[r] + m.rsize >= bbmin[r] && m.o[r] <= bbmax[r]) {
static cube dummy;
gentris(dummy, m.orient, m.o, max(m.csize, m.rsize), &m);
}
@@ -520,51 +419,38 @@ struct decalrenderer
}
}
}
-
- void findescaped(cube *cu, const ivec &o, int size, int escaped)
- {
- loopi(8)
- {
- if(escaped&(1<<i))
- {
+ void findescaped(cube *cu, const ivec &o, int size, int escaped) {
+ loopi(8) {
+ if(escaped&(1<<i)) {
ivec co(i, o, size);
if(cu[i].children) findescaped(cu[i].children, co, size>>1, cu[i].escaped);
- else
- {
+ else {
int vismask = cu[i].merged;
if(vismask) loopj(6) if(vismask&(1<<j)) gentris(cu[i], j, co, size);
}
}
}
}
-
- void gentris(cube *cu, const ivec &o, int size, int escaped = 0)
- {
+ void gentris(cube *cu, const ivec &o, int size, int escaped = 0) {
int overlap = octaboxoverlap(o, size, bbmin, bbmax);
- loopi(8)
- {
- if(overlap&(1<<i))
- {
+ loopi(8) {
+ if(overlap&(1<<i)) {
ivec co(i, o, size);
if(cu[i].ext && cu[i].ext->va && cu[i].ext->va->matsurfs)
findmaterials(cu[i].ext->va);
if(cu[i].children) gentris(cu[i].children, co, size>>1, cu[i].escaped);
- else
- {
+ else {
int vismask = cu[i].visible;
- if(vismask&0xC0)
- {
+ if(vismask&0xC0) {
if(vismask&0x80) loopj(6) gentris(cu[i], j, co, size, NULL, vismask);
else loopj(6) if(vismask&(1<<j)) gentris(cu[i], j, co, size);
}
}
}
- else if(escaped&(1<<i))
- {
+ else if(escaped&(1<<i)) {
ivec co(i, o, size);
if(cu[i].children) findescaped(cu[i].children, co, size>>1, cu[i].escaped);
- else
- {
+ else {
int vismask = cu[i].merged;
if(vismask) loopj(6) if(vismask&(1<<j)) gentris(cu[i], j, co, size);
}
@@ -573,45 +459,37 @@ struct decalrenderer
}
};
-decalrenderer decals[] =
-{
+decalrenderer decals[] = {
decalrenderer("<grey>packages/particles/scorch.png", DF_ROTATE, 500),
decalrenderer("<grey>packages/particles/blood.png", DF_RND4|DF_ROTATE|DF_INVMOD),
decalrenderer("<grey>packages/particles/bullet.png", DF_OVERBRIGHT)
};
-void initdecals()
-{
+void initdecals() {
loopi(sizeof(decals)/sizeof(decals[0])) decals[i].init(maxdecaltris);
}
-void cleardecals()
-{
+void cleardecals() {
loopi(sizeof(decals)/sizeof(decals[0])) decals[i].cleardecals();
}
-void cleanupdecals()
-{
+void cleanupdecals() {
loopi(sizeof(decals)/sizeof(decals[0])) decals[i].cleanup();
}
VARNP(decals, showdecals, 0, 1, 1);
-void renderdecals(bool mainpass)
-{
+void renderdecals(bool mainpass) {
bool rendered = false;
- loopi(sizeof(decals)/sizeof(decals[0]))
- {
+ loopi(sizeof(decals)/sizeof(decals[0])) {
decalrenderer &d = decals[i];
- if(mainpass)
- {
+ if(mainpass) {
d.clearfadeddecals();
d.fadeindecals();
d.fadeoutdecals();
}
if(!showdecals || !d.hasdecals()) continue;
- if(!rendered)
- {
+ if(!rendered) {
rendered = true;
decalrenderer::setuprenderstate();
}
@@ -623,8 +501,7 @@ void renderdecals(bool mainpass)
VARP(maxdecaldistance, 1, 512, 10000);
-void adddecal(int type, const vec &center, const vec &surface, float radius, const bvec &color, int info)
-{
+void adddecal(int type, const vec &center, const vec &surface, float radius, const bvec &color, int info) {
if(!showdecals || type<0 || (size_t)type>=sizeof(decals)/sizeof(decals[0]) || center.dist(camera1->o) - radius > maxdecaldistance) return;
decalrenderer &d = decals[type];
d.adddecal(center, surface, radius, color, info);
diff --git a/src/engine/dynlight.cpp b/src/engine/dynlight.cpp
index d018480..0c2a08d 100644
--- a/src/engine/dynlight.cpp
+++ b/src/engine/dynlight.cpp
@@ -3,18 +3,14 @@
VARP(maxdynlights, 0, min(3, MAXDYNLIGHTS), MAXDYNLIGHTS);
VARP(dynlightdist, 0, 1024, 10000);
-struct dynlight
-{
+struct dynlight {
vec o, hud;
float radius, initradius, curradius, dist;
vec color, initcolor, curcolor;
int fade, peak, expire, flags;
physent *owner;
-
- void calcradius()
- {
- if(fade + peak > 0)
- {
+ void calcradius() {
+ if(fade + peak > 0) {
int remaining = expire - lastmillis;
if(flags&DL_EXPAND)
curradius = initradius + (radius - initradius) * (1.0f - remaining/float(fade + peak));
@@ -26,20 +22,15 @@ struct dynlight
}
else curradius = radius;
}
-
- void calccolor()
- {
+ void calccolor() {
if(flags&DL_FLASH || peak <= 0) curcolor = color;
- else
- {
+ else {
int peaking = expire - lastmillis - fade;
if(peaking <= 0) curcolor = color;
else curcolor.lerp(initcolor, color, 1.0f - float(peaking)/peak);
}
-
float intensity = 1.0f;
- if(fade > 0)
- {
+ if(fade > 0) {
int fading = expire - lastmillis;
if(fading < fade) intensity = float(fading)/fade;
}
@@ -52,11 +43,9 @@ struct dynlight
vector<dynlight> dynlights;
vector<dynlight *> closedynlights;
-void adddynlight(const vec &o, float radius, const vec &color, int fade, int peak, int flags, float initradius, const vec &initcolor, physent *owner)
-{
+void adddynlight(const vec &o, float radius, const vec &color, int fade, int peak, int flags, float initradius, const vec &initcolor, physent *owner) {
if(!maxdynlights) return;
if(o.dist(camera1->o) > dynlightdist || radius <= 0) return;
-
int insert = 0, expire = fade + peak + lastmillis;
loopvrev(dynlights) if(expire>=dynlights[i].expire) { insert = i+1; break; }
dynlight d;
@@ -73,26 +62,21 @@ void adddynlight(const vec &o, float radius, const vec &color, int fade, int pea
dynlights.insert(insert, d);
}
-void cleardynlights()
-{
+void cleardynlights() {
int faded = -1;
loopv(dynlights) if(lastmillis<dynlights[i].expire) { faded = i; break; }
if(faded<0) dynlights.setsize(0);
else if(faded>0) dynlights.remove(0, faded);
}
-void removetrackeddynlights(physent *owner)
-{
+void removetrackeddynlights(physent *owner) {
loopvrev(dynlights) if(owner ? dynlights[i].owner == owner : dynlights[i].owner != NULL) dynlights.remove(i);
}
-void updatedynlights()
-{
+void updatedynlights() {
cleardynlights();
game::adddynlights();
-
- loopv(dynlights)
- {
+ loopv(dynlights) {
dynlight &d = dynlights[i];
if(d.owner) game::dynlighttrack(d.owner, d.o, d.hud);
d.calcradius();
@@ -100,14 +84,12 @@ void updatedynlights()
}
}
-int finddynlights()
-{
+int finddynlights() {
closedynlights.setsize(0);
if(!maxdynlights) return 0;
physent e;
e.type = ENT_CAMERA;
- loopvj(dynlights)
- {
+ loopvj(dynlights) {
dynlight &d = dynlights[j];
if(d.curradius <= 0) continue;
d.dist = camera1->o.dist(d.o) - d.curradius;
@@ -116,7 +98,6 @@ int finddynlights()
e.o = d.o;
e.radius = e.xradius = e.yradius = e.eyeheight = e.aboveeye = d.curradius;
if(!collide(&e, vec(0, 0, 0), 0, false)) continue;
-
int insert = 0;
loopvrev(closedynlights) if(d.dist >= closedynlights[i]->dist) { insert = i+1; break; }
closedynlights.insert(insert, &d);
@@ -125,8 +106,7 @@ int finddynlights()
return closedynlights.length();
}
-bool getdynlight(int n, vec &o, float &radius, vec &color)
-{
+bool getdynlight(int n, vec &o, float &radius, vec &color) {
if(!closedynlights.inrange(n)) return false;
dynlight &d = *closedynlights[n];
o = d.o;
@@ -135,31 +115,25 @@ bool getdynlight(int n, vec &o, float &radius, vec &color)
return true;
}
-void dynlightreaching(const vec &target, vec &color, vec &dir, bool hud)
-{
+void dynlightreaching(const vec &target, vec &color, vec &dir, bool hud) {
vec dyncolor(0, 0, 0);//, dyndir(0, 0, 0);
- loopv(dynlights)
- {
+ loopv(dynlights) {
dynlight &d = dynlights[i];
if(d.curradius<=0) continue;
-
vec ray(hud ? d.hud : d.o);
ray.sub(target);
float mag = ray.squaredlen();
if(mag >= d.curradius*d.curradius) continue;
-
vec color = d.curcolor;
color.mul(1 - sqrtf(mag)/d.curradius);
dyncolor.add(color);
//dyndir.add(ray.mul(intensity/mag));
}
#if 0
- if(!dyndir.iszero())
- {
+ if(!dyndir.iszero()) {
dyndir.normalize();
float x = dyncolor.magnitude(), y = color.magnitude();
- if(x+y>0)
- {
+ if(x+y>0) {
dir.mul(x);
dyndir.mul(y);
dir.add(dyndir).div(x+y);
@@ -171,15 +145,12 @@ void dynlightreaching(const vec &target, vec &color, vec &dir, bool hud)
color.add(dyncolor);
}
-void calcdynlightmask(vtxarray *va)
-{
+void calcdynlightmask(vtxarray *va) {
uint mask = 0;
int offset = 0;
- loopv(closedynlights)
- {
+ loopv(closedynlights) {
dynlight &d = *closedynlights[i];
if(d.o.dist_to_bb(va->geommin, va->geommax) >= d.curradius) continue;
-
mask |= (i+1)<<offset;
offset += DYNLIGHTBITS;
if(offset >= maxdynlights*DYNLIGHTBITS) break;
@@ -187,35 +158,24 @@ void calcdynlightmask(vtxarray *va)
va->dynlightmask = mask;
}
-int setdynlights(vtxarray *va)
-{
+int setdynlights(vtxarray *va) {
if(closedynlights.empty() || !va->dynlightmask) return 0;
-
extern bool minimizedynlighttcusage();
-
static vec4 posv[MAXDYNLIGHTS];
static vec colorv[MAXDYNLIGHTS];
-
int index = 0;
- for(uint mask = va->dynlightmask; mask; mask >>= DYNLIGHTBITS, index++)
- {
+ for(uint mask = va->dynlightmask; mask; mask >>= DYNLIGHTBITS, index++) {
dynlight &d = *closedynlights[(mask&DYNLIGHTMASK)-1];
-
float scale = 1.0f/d.curradius;
vec origin = vec(d.o).mul(-scale);
-
- if(index>0 && minimizedynlighttcusage())
- {
+ if(index>0 && minimizedynlighttcusage()) {
scale /= posv[0].w;
origin.sub(vec(posv[0]).mul(scale));
}
-
posv[index] = vec4(origin, scale);
colorv[index] = d.curcolor;
}
-
GLOBALPARAMV(dynlightpos, posv, index);
GLOBALPARAMV(dynlightcolor, colorv, index);
-
return index;
}
diff --git a/src/engine/engine.h b/src/engine/engine.h
index e37ac4f..7bc0ef1 100644
--- a/src/engine/engine.h
+++ b/src/engine/engine.h
@@ -34,18 +34,14 @@ extern int zpass;
extern vector<int> entgroup;
// rendertext
-struct font
-{
- struct charinfo
- {
+struct font {
+ struct charinfo {
short x, y, w, h, offsetx, offsety, advance, tex;
};
-
char *name;
vector<Texture *> texs;
vector<charinfo> chars;
int charoffset, defaultw, defaulth, scale;
-
font() : name(NULL) {}
~font() { DELETEA(name); }
};
@@ -97,7 +93,6 @@ extern bool addshadowmapcaster(const vec &o, float xyrad, float zrad);
extern bool isshadowmapreceiver(vtxarray *va);
extern void rendershadowmap();
extern void pushshadowmap();
-extern void popshadowmap();
extern void rendershadowmapreceivers();
extern void guessshadowdir();
@@ -137,8 +132,7 @@ extern void screenquadoffset(float x, float y, float w, float h, float x2, float
extern void hudquad(float x, float y, float w, float h, float tx = 0, float ty = 0, float tw = 1, float th = 1);
extern void writecrosshairs(stream *f);
-namespace modelpreview
-{
+namespace modelpreview {
extern void start(int x, int y, int w, int h, bool background = true);
extern void end();
}
@@ -195,8 +189,7 @@ extern void calcmerges();
extern int mergefaces(int orient, facebounds *m, int sz);
extern void mincubeface(const cube &cu, int orient, const ivec &o, int size, const facebounds &orig, facebounds &cf, ushort nmat = MAT_AIR, ushort matmask = 0);
-static inline cubeext &ext(cube &c)
-{
+static inline cubeext &ext(cube &c) {
return *(c.ext ? c.ext : newcubeext(c));
}
@@ -336,8 +329,7 @@ extern void writebinds(stream *f);
extern void writecompletions(stream *f);
// main
-enum
-{
+enum {
NOT_INITING = 0,
INIT_GAME,
INIT_LOAD,
@@ -345,8 +337,7 @@ enum
};
extern int initing, numcpus;
-enum
-{
+enum {
CHANGE_GFX = 1<<0,
CHANGE_SOUND = 1<<1
};
@@ -410,14 +401,12 @@ extern void loadskin(const char *dir, const char *altdir, Texture *&skin, Textur
extern mapmodelinfo *getmminfo(int i);
extern void startmodelquery(occludequery *query);
extern void endmodelquery();
-extern void preloadmodelshaders(bool force = false);
+extern void preloadmodelshaders();
extern void preloadusedmapmodels(bool msg = false, bool bih = false);
-static inline model *loadmapmodel(int n)
-{
+static inline model *loadmapmodel(int n) {
extern vector<mapmodelinfo> mapmodels;
- if(mapmodels.inrange(n))
- {
+ if(mapmodels.inrange(n)) {
model *m = mapmodels[n].m;
return m ? m : loadmodel(NULL, n);
}
diff --git a/src/engine/explosion.h b/src/engine/explosion.h
deleted file mode 100644
index 819b0a3..0000000
--- a/src/engine/explosion.h
+++ /dev/null
@@ -1,179 +0,0 @@
-namespace sphere
-{
- struct vert
- {
- vec pos;
- ushort s, t;
- } *verts = NULL;
- GLushort *indices = NULL;
- int numverts = 0, numindices = 0;
- GLuint vbuf = 0, ebuf = 0;
-
- void init(int slices, int stacks)
- {
- numverts = (stacks+1)*(slices+1);
- verts = new vert[numverts];
- float ds = 1.0f/slices, dt = 1.0f/stacks, t = 1.0f;
- loopi(stacks+1)
- {
- float rho = M_PI*(1-t), s = 0.0f, sinrho = i && i < stacks ? sin(rho) : 0, cosrho = !i ? 1 : (i < stacks ? cos(rho) : -1);
- loopj(slices+1)
- {
- float theta = j==slices ? 0 : 2*M_PI*s;
- vert &v = verts[i*(slices+1) + j];
- v.pos = vec(-sin(theta)*sinrho, cos(theta)*sinrho, cosrho);
- v.s = ushort(s*0xFFFF);
- v.t = ushort(t*0xFFFF);
- s += ds;
- }
- t -= dt;
- }
-
- numindices = (stacks-1)*slices*3*2;
- indices = new ushort[numindices];
- GLushort *curindex = indices;
- loopi(stacks)
- {
- loopk(slices)
- {
- int j = i%2 ? slices-k-1 : k;
- if(i)
- {
- *curindex++ = i*(slices+1)+j;
- *curindex++ = (i+1)*(slices+1)+j;
- *curindex++ = i*(slices+1)+j+1;
- }
- if(i+1 < stacks)
- {
- *curindex++ = i*(slices+1)+j+1;
- *curindex++ = (i+1)*(slices+1)+j;
- *curindex++ = (i+1)*(slices+1)+j+1;
- }
- }
- }
-
- if(!vbuf) glGenBuffers_(1, &vbuf);
- gle::bindvbo(vbuf);
- glBufferData_(GL_ARRAY_BUFFER, numverts*sizeof(vert), verts, GL_STATIC_DRAW);
- DELETEA(verts);
-
- if(!ebuf) glGenBuffers_(1, &ebuf);
- gle::bindebo(ebuf);
- glBufferData_(GL_ELEMENT_ARRAY_BUFFER, numindices*sizeof(GLushort), indices, GL_STATIC_DRAW);
- DELETEA(indices);
- }
-
- void enable()
- {
- if(!vbuf) init(12, 6);
-
- gle::bindvbo(vbuf);
- gle::bindebo(ebuf);
-
- gle::vertexpointer(sizeof(vert), &verts->pos);
- gle::texcoord0pointer(sizeof(vert), &verts->s, GL_UNSIGNED_SHORT, 2, GL_TRUE);
- gle::enablevertex();
- gle::enabletexcoord0();
- }
-
- void draw()
- {
- glDrawRangeElements_(GL_TRIANGLES, 0, numverts-1, numindices, GL_UNSIGNED_SHORT, indices);
- xtraverts += numindices;
- glde++;
- }
-
- void disable()
- {
- gle::disablevertex();
- gle::disabletexcoord0();
-
- gle::clearvbo();
- gle::clearebo();
- }
-
- void cleanup()
- {
- if(vbuf) { glDeleteBuffers_(1, &vbuf); vbuf = 0; }
- if(ebuf) { glDeleteBuffers_(1, &ebuf); ebuf = 0; }
- }
-}
-
-static const float WOBBLE = 1.25f;
-
-struct fireballrenderer : listrenderer
-{
- fireballrenderer(const char *texname)
- : listrenderer(texname, 0, PT_FIREBALL|PT_GLARE|PT_SHADER)
- {}
-
- void startrender()
- {
- SETSHADER(explosion);
- sphere::enable();
- }
-
- void endrender()
- {
- sphere::disable();
- }
-
- void cleanup()
- {
- sphere::cleanup();
- }
-
- void seedemitter(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int gravity)
- {
- pe.maxfade = max(pe.maxfade, fade);
- pe.extendbb(o, (size+1+pe.ent->attr2)*WOBBLE);
- }
-
- void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts)
- {
- float pmax = p->val, size = p->fade ? float(ts)/p->fade : 1, psize = p->size + pmax * size;
-
- vec dir = vec(o).sub(camera1->o), s, t;
- float dist = dir.magnitude();
- bool inside = dist <= psize*WOBBLE;
- if(inside)
- {
- s = camright;
- t = camup;
- }
- else
- {
- float mag2 = dir.magnitude2();
- dir.x /= mag2;
- dir.y /= mag2;
- dir.z /= dist;
- s = vec(dir.y, -dir.x, 0);
- t = vec(dir.x*dir.z, dir.y*dir.z, -mag2/dist);
- }
-
- matrix3 rot(lastmillis/1000.0f*143*RAD, vec(1/SQRT3, 1/SQRT3, 1/SQRT3));
- LOCALPARAM(texgenS, rot.transposedtransform(s));
- LOCALPARAM(texgenT, rot.transposedtransform(t));
-
- matrix4 m(rot, o);
- m.scale(psize, psize, inside ? -psize : psize);
- m.mul(camprojmatrix, m);
- LOCALPARAM(explosionmatrix, m);
-
- LOCALPARAM(center, o);
- LOCALPARAMF(millis, lastmillis/1000.0f);
- LOCALPARAMF(blendparams, inside ? 0.5f : 4, inside ? 0.25f : 0);
-
- int passes = inside ? 2 : 1;
- loopi(passes)
- {
- gle::color(p->color, i ? blend/2 : blend);
- if(i) glDepthFunc(GL_GEQUAL);
- sphere::draw();
- if(i) glDepthFunc(GL_LESS);
- }
- }
-};
-
-static fireballrenderer fireballs("packages/particles/explosion.png"), bluefireballs("packages/particles/plasma.png");
-
diff --git a/src/engine/iqm.h b/src/engine/iqm.h
index e36a628..5e7323f 100644
--- a/src/engine/iqm.h
+++ b/src/engine/iqm.h
@@ -1,7 +1,6 @@
struct iqm;
-struct iqmheader
-{
+struct iqmheader {
char magic[16];
uint version;
uint filesize;
@@ -18,16 +17,14 @@ struct iqmheader
uint num_extensions, ofs_extensions;
};
-struct iqmmesh
-{
+struct iqmmesh {
uint name;
uint material;
uint first_vertex, num_vertexes;
uint first_triangle, num_triangles;
};
-enum
-{
+enum {
IQM_POSITION = 0,
IQM_TEXCOORD = 1,
IQM_NORMAL = 2,
@@ -38,8 +35,7 @@ enum
IQM_CUSTOM = 0x10
};
-enum
-{
+enum {
IQM_BYTE = 0,
IQM_UBYTE = 1,
IQM_SHORT = 2,
@@ -51,13 +47,11 @@ enum
IQM_DOUBLE = 8,
};
-struct iqmtriangle
-{
+struct iqmtriangle {
uint vertex[3];
};
-struct iqmjoint
-{
+struct iqmjoint {
uint name;
int parent;
vec pos;
@@ -65,8 +59,7 @@ struct iqmjoint
vec size;
};
-struct iqmpose
-{
+struct iqmpose {
int parent;
uint mask;
vec offsetpos;
@@ -77,16 +70,14 @@ struct iqmpose
vec scalesize;
};
-struct iqmanim
-{
+struct iqmanim {
uint name;
uint first_frame, num_frames;
float framerate;
uint flags;
};
-struct iqmvertexarray
-{
+struct iqmvertexarray {
uint type;
uint flags;
uint format;
@@ -94,35 +85,25 @@ struct iqmvertexarray
uint offset;
};
-struct iqm : skelloader<iqm>
-{
+struct iqm : skelloader<iqm> {
iqm(const char *name) : skelloader(name) {}
-
static const char *formatname() { return "iqm"; }
int type() const { return MDL_IQM; }
-
- struct iqmmeshgroup : skelmeshgroup
- {
- iqmmeshgroup()
- {
+ struct iqmmeshgroup : skelmeshgroup {
+ iqmmeshgroup() {
}
-
- bool loadiqmmeshes(const char *filename, const iqmheader &hdr, uchar *buf)
- {
+ bool loadiqmmeshes(const char *filename, const iqmheader &hdr, uchar *buf) {
lilswap((uint *)&buf[hdr.ofs_vertexarrays], hdr.num_vertexarrays*sizeof(iqmvertexarray)/sizeof(uint));
lilswap((uint *)&buf[hdr.ofs_triangles], hdr.num_triangles*sizeof(iqmtriangle)/sizeof(uint));
lilswap((uint *)&buf[hdr.ofs_meshes], hdr.num_meshes*sizeof(iqmmesh)/sizeof(uint));
lilswap((uint *)&buf[hdr.ofs_joints], hdr.num_joints*sizeof(iqmjoint)/sizeof(uint));
-
const char *str = hdr.ofs_text ? (char *)&buf[hdr.ofs_text] : "";
float *vpos = NULL, *vnorm = NULL, *vtan = NULL, *vtc = NULL;
uchar *vindex = NULL, *vweight = NULL;
iqmvertexarray *vas = (iqmvertexarray *)&buf[hdr.ofs_vertexarrays];
- loopi(hdr.num_vertexarrays)
- {
+ loopi(hdr.num_vertexarrays) {
iqmvertexarray &va = vas[i];
- switch(va.type)
- {
+ switch(va.type) {
case IQM_POSITION: if(va.format != IQM_FLOAT || va.size != 3) return false; vpos = (float *)&buf[va.offset]; lilswap(vpos, 3*hdr.num_vertexes); break;
case IQM_NORMAL: if(va.format != IQM_FLOAT || va.size != 3) return false; vnorm = (float *)&buf[va.offset]; lilswap(vnorm, 3*hdr.num_vertexes); break;
case IQM_TANGENT: if(va.format != IQM_FLOAT || va.size != 4) return false; vtan = (float *)&buf[va.offset]; lilswap(vtan, 4*hdr.num_vertexes); break;
@@ -132,25 +113,19 @@ struct iqm : skelloader<iqm>
}
}
if(!vpos) return false;
-
iqmtriangle *tris = (iqmtriangle *)&buf[hdr.ofs_triangles];
iqmmesh *imeshes = (iqmmesh *)&buf[hdr.ofs_meshes];
iqmjoint *joints = (iqmjoint *)&buf[hdr.ofs_joints];
-
- if(hdr.num_joints)
- {
- if(skel->numbones <= 0)
- {
+ if(hdr.num_joints) {
+ if(skel->numbones <= 0) {
skel->numbones = hdr.num_joints;
skel->bones = new boneinfo[skel->numbones];
- loopi(hdr.num_joints)
- {
+ loopi(hdr.num_joints) {
iqmjoint &j = joints[i];
boneinfo &b = skel->bones[i];
if(!b.name) b.name = newstring(&str[j.name]);
b.parent = j.parent;
- if(skel->shared <= 1)
- {
+ if(skel->shared <= 1) {
j.pos.y = -j.pos.y;
j.orient.x = -j.orient.x;
j.orient.z = -j.orient.z;
@@ -161,13 +136,10 @@ struct iqm : skelloader<iqm>
}
}
}
-
if(skel->shared <= 1)
skel->linkchildren();
}
-
- loopi(hdr.num_meshes)
- {
+ loopi(hdr.num_meshes) {
iqmmesh &im = imeshes[i];
skelmesh *m = new skelmesh;
m->group = this;
@@ -175,12 +147,10 @@ struct iqm : skelloader<iqm>
m->name = newstring(&str[im.name]);
m->numverts = im.num_vertexes;
int noblend = -1;
- if(m->numverts)
- {
+ if(m->numverts) {
m->verts = new vert[m->numverts];
if(vtan) m->bumpverts = new bumpvert[m->numverts];
- if(!vindex || !vweight)
- {
+ if(!vindex || !vweight) {
blendcombo c;
c.finalize(0);
noblend = m->addblendcombo(c);
@@ -192,30 +162,25 @@ struct iqm : skelloader<iqm>
*mtan = vtan ? vtan + 4*fv : NULL,
*mtc = vtc ? vtc + 2*fv : NULL;
uchar *mindex = vindex ? vindex + 4*fv : NULL, *mweight = vweight ? vweight + 4*fv : NULL;
- loopj(im.num_vertexes)
- {
+ loopj(im.num_vertexes) {
vert &v = m->verts[j];
v.pos = vec(mpos[0], -mpos[1], mpos[2]);
mpos += 3;
- if(mtc)
- {
+ if(mtc) {
v.tc = vec2(mtc[0], mtc[1]);
mtc += 2;
}
else v.tc = vec2(0, 0);
- if(mnorm)
- {
+ if(mnorm) {
v.norm = vec(mnorm[0], -mnorm[1], mnorm[2]);
mnorm += 3;
- if(mtan)
- {
+ if(mtan) {
m->calctangent(m->bumpverts[j], v.norm, vec(mtan[0], -mtan[1], mtan[2]), mtan[3]);
mtan += 4;
}
}
else v.norm = vec(0, 0, 0);
- if(noblend < 0)
- {
+ if(noblend < 0) {
blendcombo c;
int sorted = 0;
loopk(4) sorted = c.addweight(sorted, mweight[k], mindex[k]);
@@ -229,39 +194,31 @@ struct iqm : skelloader<iqm>
m->numtris = im.num_triangles;
if(m->numtris) m->tris = new tri[m->numtris];
iqmtriangle *mtris = tris + im.first_triangle;
- loopj(im.num_triangles)
- {
+ loopj(im.num_triangles) {
tri &t = m->tris[j];
t.vert[0] = mtris->vertex[0] - fv;
t.vert[1] = mtris->vertex[1] - fv;
t.vert[2] = mtris->vertex[2] - fv;
++mtris;
}
- if(!m->numtris || !m->numverts)
- {
+ if(!m->numtris || !m->numverts) {
conoutf(CON_WARN, "empty mesh in %s", filename);
meshes.removeobj(m);
delete m;
}
}
-
sortblendcombos();
-
return true;
}
-
- bool loadiqmanims(const char *filename, const iqmheader &hdr, uchar *buf)
- {
+ bool loadiqmanims(const char *filename, const iqmheader &hdr, uchar *buf) {
lilswap((uint *)&buf[hdr.ofs_poses], hdr.num_poses*sizeof(iqmpose)/sizeof(uint));
lilswap((uint *)&buf[hdr.ofs_anims], hdr.num_anims*sizeof(iqmanim)/sizeof(uint));
lilswap((ushort *)&buf[hdr.ofs_frames], hdr.num_frames*hdr.num_framechannels);
-
const char *str = hdr.ofs_text ? (char *)&buf[hdr.ofs_text] : "";
iqmpose *poses = (iqmpose *)&buf[hdr.ofs_poses];
iqmanim *anims = (iqmanim *)&buf[hdr.ofs_anims];
ushort *frames = (ushort *)&buf[hdr.ofs_frames];
- loopi(hdr.num_anims)
- {
+ loopi(hdr.num_anims) {
iqmanim &a = anims[i];
string name;
copystring(name, filename);
@@ -273,8 +230,7 @@ struct iqm : skelloader<iqm>
sa->frame = skel->numframes;
sa->range = a.num_frames;
dualquat *animbones = new dualquat[(skel->numframes+a.num_frames)*skel->numbones];
- if(skel->bones)
- {
+ if(skel->bones) {
memcpy(animbones, skel->framebones, skel->numframes*skel->numbones*sizeof(dualquat));
delete[] skel->framebones;
}
@@ -282,11 +238,9 @@ struct iqm : skelloader<iqm>
animbones += skel->numframes*skel->numbones;
skel->numframes += a.num_frames;
ushort *animdata = &frames[a.first_frame*hdr.num_framechannels];
- loopj(a.num_frames)
- {
+ loopj(a.num_frames) {
dualquat *frame = &animbones[j*skel->numbones];
- loopk(skel->numbones)
- {
+ loopk(skel->numbones) {
iqmpose &p = poses[k];
vec pos;
quat orient;
@@ -298,8 +252,7 @@ struct iqm : skelloader<iqm>
orient.z = -p.offsetorient.z; if(p.mask&0x20) orient.z -= *animdata++ * p.scaleorient.z;
orient.w = p.offsetorient.w; if(p.mask&0x40) orient.w += *animdata++ * p.scaleorient.w;
orient.normalize();
- if(p.mask&0x380)
- {
+ if(p.mask&0x380) {
if(p.mask&0x80) animdata++;
if(p.mask&0x100) animdata++;
if(p.mask&0x200) animdata++;
@@ -313,15 +266,11 @@ struct iqm : skelloader<iqm>
}
}
}
-
return true;
}
-
- bool loadiqm(const char *filename, bool doloadmesh, bool doloadanim)
- {
+ bool loadiqm(const char *filename, bool doloadmesh, bool doloadanim) {
stream *f = openfile(filename, "rb");
if(!f) return false;
-
uchar *buf = NULL;
iqmheader hdr;
if(f->read(&hdr, sizeof(hdr)) != sizeof(hdr) || memcmp(hdr.magic, "INTERQUAKEMODEL", sizeof(hdr.magic))) goto error;
@@ -330,33 +279,24 @@ struct iqm : skelloader<iqm>
if(hdr.filesize > (16<<20)) goto error; // sanity check... don't load files bigger than 16 MB
buf = new (false) uchar[hdr.filesize];
if(!buf || f->read(buf + sizeof(hdr), hdr.filesize - sizeof(hdr)) != hdr.filesize - sizeof(hdr)) goto error;
-
if(doloadmesh && !loadiqmmeshes(filename, hdr, buf)) goto error;
if(doloadanim && !loadiqmanims(filename, hdr, buf)) goto error;
-
delete[] buf;
delete f;
return true;
-
error:
if(buf) delete[] buf;
delete f;
return false;
}
-
- bool loadmesh(const char *filename)
- {
+ bool loadmesh(const char *filename) {
name = newstring(filename);
-
return loadiqm(filename, true, false);
}
-
- skelanimspec *loadanim(const char *animname)
- {
+ skelanimspec *loadanim(const char *animname) {
const char *sep = strchr(animname, ':');
skelanimspec *sa = skel->findskelanim(animname, sep ? '\0' : ':');
- if(!sa)
- {
+ if(!sa) {
string filename;
copystring(filename, animname);
if(sep) filename[sep - animname] = '\0';
@@ -366,17 +306,13 @@ struct iqm : skelloader<iqm>
return sa;
}
};
-
- meshgroup *loadmeshes(const char *name, va_list args)
- {
+ meshgroup *loadmeshes(const char *name, va_list args) {
iqmmeshgroup *group = new iqmmeshgroup;
group->shareskeleton(va_arg(args, char *));
if(!group->loadmesh(name)) { delete group; return NULL; }
return group;
}
-
- bool loaddefaultparts()
- {
+ bool loaddefaultparts() {
skelpart &mdl = addpart();
mdl.pitchscale = mdl.pitchoffset = mdl.pitchmin = mdl.pitchmax = 0;
adjustments.setsize(0);
@@ -393,4 +329,3 @@ struct iqm : skelloader<iqm>
};
skelcommands<iqm> iqmcommands;
-
diff --git a/src/engine/lightmap.cpp b/src/engine/lightmap.cpp
index a317dd5..1481de9 100644
--- a/src/engine/lightmap.cpp
+++ b/src/engine/lightmap.cpp
@@ -6,8 +6,7 @@
struct lightmapinfo;
struct lightmaptask;
-struct lightmapworker
-{
+struct lightmapworker {
uchar *buf;
int bufstart, bufused;
lightmapinfo *firstlightmap, *lastlightmap, *curlightmaps;
@@ -25,19 +24,15 @@ struct lightmapworker
bool needspace, doneworking;
SDL_cond *spacecond;
SDL_Thread *thread;
-
lightmapworker();
~lightmapworker();
-
void reset();
bool setupthread();
void cleanupthread();
-
static int work(void *data);
};
-struct lightmapinfo
-{
+struct lightmapinfo {
lightmapinfo *next;
cube *c;
uchar *colorbuf;
@@ -46,8 +41,7 @@ struct lightmapinfo
int type, w, h, bpp, bufsize, surface, layers;
};
-struct lightmaptask
-{
+struct lightmaptask {
ivec o;
int size, usefaces, progress;
cube *c;
@@ -56,8 +50,7 @@ struct lightmaptask
lightmapworker *worker;
};
-struct lightmapext
-{
+struct lightmapext {
cube *c;
cubeext *ext;
};
@@ -78,14 +71,12 @@ VARR(lighterror, 1, 8, 16);
VARR(bumperror, 1, 3, 16);
VARR(lightlod, 0, 0, 10);
bvec ambientcolor(36, 24, 12);
-HVARFR(ambient, 1, 0x191919, 0xFFFFFF,
-{
+HVARFR(ambient, 1, 0x191919, 0xFFFFFF, {
if(ambient <= 255) ambient |= (ambient<<8) | (ambient<<16);
ambientcolor = bvec((ambient>>16)&0xFF, (ambient>>8)&0xFF, ambient&0xFF);
});
-static const surfaceinfo brightsurfaces[6] =
-{
+static const surfaceinfo brightsurfaces[6] = {
brightsurface,
brightsurface,
brightsurface,
@@ -94,28 +85,23 @@ static const surfaceinfo brightsurfaces[6] =
brightsurface
};
-void brightencube(cube &c)
-{
+void brightencube(cube &c) {
if(!c.ext) newcubeext(c, 0, false);
memcpy(c.ext->surfaces, brightsurfaces, sizeof(brightsurfaces));
}
-void setsurfaces(cube &c, const surfaceinfo *surfs, const vertinfo *verts, int numverts)
-{
+void setsurfaces(cube &c, const surfaceinfo *surfs, const vertinfo *verts, int numverts) {
if(!c.ext || c.ext->maxverts < numverts) newcubeext(c, numverts, false);
memcpy(c.ext->surfaces, surfs, sizeof(c.ext->surfaces));
memcpy(c.ext->verts(), verts, numverts*sizeof(vertinfo));
}
-void setsurface(cube &c, int orient, const surfaceinfo &src, const vertinfo *srcverts, int numsrcverts)
-{
+void setsurface(cube &c, int orient, const surfaceinfo &src, const vertinfo *srcverts, int numsrcverts) {
int dstoffset = 0;
if(!c.ext) newcubeext(c, numsrcverts, true);
- else
- {
+ else {
int numbefore = 0, beforeoffset = 0;
- loopi(orient)
- {
+ loopi(orient) {
surfaceinfo &surf = c.ext->surfaces[i];
int numverts = surf.totalverts();
if(!numverts) continue;
@@ -123,8 +109,7 @@ void setsurface(cube &c, int orient, const surfaceinfo &src, const vertinfo *src
beforeoffset = surf.verts + numverts;
}
int numafter = 0, afteroffset = c.ext->maxverts;
- for(int i = 5; i > orient; i--)
- {
+ for(int i = 5; i > orient; i--) {
surfaceinfo &surf = c.ext->surfaces[i];
int numverts = surf.totalverts();
if(!numverts) continue;
@@ -132,22 +117,18 @@ void setsurface(cube &c, int orient, const surfaceinfo &src, const vertinfo *src
afteroffset = surf.verts;
}
if(afteroffset - beforeoffset >= numsrcverts) dstoffset = beforeoffset;
- else
- {
+ else {
cubeext *ext = c.ext;
- if(numbefore + numsrcverts + numafter > c.ext->maxverts)
- {
+ if(numbefore + numsrcverts + numafter > c.ext->maxverts) {
ext = growcubeext(c.ext, numbefore + numsrcverts + numafter);
memcpy(ext->surfaces, c.ext->surfaces, sizeof(ext->surfaces));
}
int offset = 0;
- if(numbefore == beforeoffset)
- {
+ if(numbefore == beforeoffset) {
if(numbefore && c.ext != ext) memcpy(ext->verts(), c.ext->verts(), numbefore*sizeof(vertinfo));
offset = numbefore;
}
- else loopi(orient)
- {
+ else loopi(orient) {
surfaceinfo &surf = ext->surfaces[i];
int numverts = surf.totalverts();
if(!numverts) continue;
@@ -157,11 +138,9 @@ void setsurface(cube &c, int orient, const surfaceinfo &src, const vertinfo *src
}
dstoffset = offset;
offset += numsrcverts;
- if(numafter && offset > afteroffset)
- {
+ if(numafter && offset > afteroffset) {
offset += numafter;
- for(int i = 5; i > orient; i--)
- {
+ for(int i = 5; i > orient; i--) {
surfaceinfo &surf = ext->surfaces[i];
int numverts = surf.totalverts();
if(!numverts) continue;
@@ -192,30 +171,23 @@ static int progresstexticks = 0, progresslightmap = -1;
bool calclight_canceled = false;
volatile bool check_calclight_progress = false;
-void check_calclight_canceled()
-{
- if(interceptkey(SDLK_ESCAPE))
- {
+void check_calclight_canceled() {
+ if(interceptkey(SDLK_ESCAPE)) {
calclight_canceled = true;
loopv(lightmapworkers) lightmapworkers[i]->doneworking = true;
}
if(!calclight_canceled) check_calclight_progress = false;
}
-void show_calclight_progress()
-{
+void show_calclight_progress() {
float bar1 = float(progress) / float(allocnodes);
defformatstring(text1, "%d%% using %d textures", int(bar1 * 100), lightmaps.length());
-
- if(LM_PACKW <= hwtexsize && !progresstex)
- {
+ if(LM_PACKW <= hwtexsize && !progresstex) {
glGenTextures(1, &progresstex);
createtexture(progresstex, LM_PACKW, LM_PACKH, NULL, 3, 1, GL_RGB);
}
-
// only update once a sec (4 * 250 ms ticks) to not kill performance
- if(progresstex && !calclight_canceled && progresslightmap >= 0 && !(progresstexticks++ % 4))
- {
+ if(progresstex && !calclight_canceled && progresslightmap >= 0 && !(progresstexticks++ % 4)) {
if(tasklock) SDL_LockMutex(tasklock);
LightMap &lm = lightmaps[progresslightmap];
uchar *data = lm.data;
@@ -231,56 +203,45 @@ void show_calclight_progress()
#define CHECK_PROGRESS_LOCKED(exit, before, after) CHECK_CALCLIGHT_PROGRESS_LOCKED(exit, show_calclight_progress, before, after)
#define CHECK_PROGRESS(exit) CHECK_PROGRESS_LOCKED(exit, , )
-bool PackNode::insert(ushort &tx, ushort &ty, ushort tw, ushort th)
-{
+bool PackNode::insert(ushort &tx, ushort &ty, ushort tw, ushort th) {
if((available < tw && available < th) || w < tw || h < th)
return false;
- if(child1)
- {
+ if(child1) {
bool inserted = child1->insert(tx, ty, tw, th) ||
child2->insert(tx, ty, tw, th);
available = max(child1->available, child2->available);
if(!available) clear();
return inserted;
}
- if(w == tw && h == th)
- {
+ if(w == tw && h == th) {
available = 0;
tx = x;
ty = y;
return true;
}
-
- if(w - tw > h - th)
- {
+ if(w - tw > h - th) {
child1 = new PackNode(x, y, tw, h);
child2 = new PackNode(x + tw, y, w - tw, h);
}
- else
- {
+ else {
child1 = new PackNode(x, y, w, th);
child2 = new PackNode(x, y + th, w, h - th);
}
-
bool inserted = child1->insert(tx, ty, tw, th);
available = max(child1->available, child2->available);
return inserted;
}
-bool LightMap::insert(ushort &tx, ushort &ty, uchar *src, ushort tw, ushort th)
-{
+bool LightMap::insert(ushort &tx, ushort &ty, uchar *src, ushort tw, ushort th) {
if((type&LM_TYPE) != LM_BUMPMAP1 && !packroot.insert(tx, ty, tw, th))
return false;
-
copy(tx, ty, src, tw, th);
return true;
}
-void LightMap::copy(ushort tx, ushort ty, uchar *src, ushort tw, ushort th)
-{
+void LightMap::copy(ushort tx, ushort ty, uchar *src, ushort tw, ushort th) {
uchar *dst = data + bpp * tx + ty * bpp * LM_PACKW;
- loopi(th)
- {
+ loopi(th) {
memcpy(dst, src, bpp * tw);
dst += bpp * LM_PACKW;
src += bpp * tw;
@@ -289,20 +250,16 @@ void LightMap::copy(ushort tx, ushort ty, uchar *src, ushort tw, ushort th)
lumels += tw * th;
}
-static void insertunlit(int i)
-{
+static void insertunlit(int i) {
LightMap &l = lightmaps[i];
- if((l.type&LM_TYPE) == LM_BUMPMAP1)
- {
+ if((l.type&LM_TYPE) == LM_BUMPMAP1) {
l.unlitx = l.unlity = -1;
return;
}
ushort x, y;
uchar unlit[4] = { ambientcolor[0], ambientcolor[1], ambientcolor[2], 255 };
- if(l.insert(x, y, unlit, 1, 1))
- {
- if((l.type&LM_TYPE) == LM_BUMPMAP0)
- {
+ if(l.insert(x, y, unlit, 1, 1)) {
+ if((l.type&LM_TYPE) == LM_BUMPMAP0) {
bvec front(128, 128, 255);
ASSERT(lightmaps[i+1].insert(x, y, front.v, 1, 1));
}
@@ -311,26 +268,20 @@ static void insertunlit(int i)
}
}
-struct layoutinfo
-{
+struct layoutinfo {
ushort x, y, lmid;
uchar w, h;
};
-static void insertlightmap(lightmapinfo &li, layoutinfo &si)
-{
- loopv(lightmaps)
- {
- if(lightmaps[i].type == li.type && lightmaps[i].insert(si.x, si.y, li.colorbuf, si.w, si.h))
- {
+static void insertlightmap(lightmapinfo &li, layoutinfo &si) {
+ loopv(lightmaps) {
+ if(lightmaps[i].type == li.type && lightmaps[i].insert(si.x, si.y, li.colorbuf, si.w, si.h)) {
si.lmid = i + LMID_RESERVED;
if((li.type&LM_TYPE) == LM_BUMPMAP0) ASSERT(lightmaps[i+1].insert(si.x, si.y, (uchar *)li.raybuf, si.w, si.h));
return;
}
}
-
progresslightmap = lightmaps.length();
-
si.lmid = lightmaps.length() + LMID_RESERVED;
LightMap &l = lightmaps.add();
l.type = li.type;
@@ -338,8 +289,7 @@ static void insertlightmap(lightmapinfo &li, layoutinfo &si)
l.data = new uchar[li.bpp*LM_PACKW*LM_PACKH];
memset(l.data, 0, li.bpp*LM_PACKW*LM_PACKH);
ASSERT(l.insert(si.x, si.y, li.colorbuf, si.w, si.h));
- if((li.type&LM_TYPE) == LM_BUMPMAP0)
- {
+ if((li.type&LM_TYPE) == LM_BUMPMAP0) {
LightMap &r = lightmaps.add();
r.type = LM_BUMPMAP1 | (li.type&~LM_TYPE);
r.bpp = 3;
@@ -349,8 +299,7 @@ static void insertlightmap(lightmapinfo &li, layoutinfo &si)
}
}
-static inline bool htcmp(const lightmapinfo &k, const layoutinfo &v)
-{
+static inline bool htcmp(const lightmapinfo &k, const layoutinfo &v) {
int kw = k.w, kh = k.h;
if(kw != v.w || kh != v.h) return false;
LightMap &vlm = lightmaps[v.lmid - LMID_RESERVED];
@@ -358,16 +307,14 @@ static inline bool htcmp(const lightmapinfo &k, const layoutinfo &v)
if(ktype != vlm.type) return false;
int kbpp = k.bpp;
const uchar *kcolor = k.colorbuf, *vcolor = vlm.data + kbpp*(v.x + v.y*LM_PACKW);
- loopi(kh)
- {
+ loopi(kh) {
if(memcmp(kcolor, vcolor, kbpp*kw)) return false;
kcolor += kbpp*kw;
vcolor += kbpp*LM_PACKW;
}
if((ktype&LM_TYPE) != LM_BUMPMAP0) return true;
const bvec *kdir = k.raybuf, *vdir = (const bvec *)lightmaps[v.lmid+1 - LMID_RESERVED].data + (v.x + v.y*LM_PACKW);
- loopi(kh)
- {
+ loopi(kh) {
if(memcmp(kdir, vdir, kw*sizeof(bvec))) return false;
kdir += kw;
vdir += LM_PACKW;
@@ -375,13 +322,11 @@ static inline bool htcmp(const lightmapinfo &k, const layoutinfo &v)
return true;
}
-static inline uint hthash(const lightmapinfo &k)
-{
+static inline uint hthash(const lightmapinfo &k) {
int kw = k.w, kh = k.h, kbpp = k.bpp;
uint hash = kw + (kh<<8);
const uchar *color = k.colorbuf;
- loopi(kw*kh)
- {
+ loopi(kw*kh) {
hash ^= color[0] + (color[1] << 4) + (color[2] << 8);
color += kbpp;
}
@@ -392,20 +337,16 @@ static hashset<layoutinfo> compressed;
VAR(lightcompress, 0, 3, 6);
-static bool packlightmap(lightmapinfo &l, layoutinfo &surface)
-{
+static bool packlightmap(lightmapinfo &l, layoutinfo &surface) {
surface.w = l.w;
surface.h = l.h;
- if((int)l.w <= lightcompress && (int)l.h <= lightcompress)
- {
+ if((int)l.w <= lightcompress && (int)l.h <= lightcompress) {
layoutinfo *val = compressed.access(l);
- if(!val)
- {
+ if(!val) {
insertlightmap(l, surface);
compressed[l] = surface;
}
- else
- {
+ else {
surface.x = val->x;
surface.y = val->y;
surface.lmid = val->lmid;
@@ -416,13 +357,11 @@ static bool packlightmap(lightmapinfo &l, layoutinfo &surface)
return true;
}
-static uint generatelumel(lightmapworker *w, const float tolerance, uint lightmask, const vector<const extentity *> &lights, const vec &target, const vec &normal, vec &sample, int x, int y)
-{
+static uint generatelumel(lightmapworker *w, const float tolerance, uint lightmask, const vector<const extentity *> &lights, const vec &target, const vec &normal, vec &sample, int x, int y) {
vec avgray(0, 0, 0);
float r = 0, g = 0, b = 0;
uint lightused = 0;
- loopv(lights)
- {
+ loopv(lights) {
if(lightmask&(1<<i)) continue;
const extentity &light = *lights[i];
vec ray = target;
@@ -430,30 +369,26 @@ static uint generatelumel(lightmapworker *w, const float tolerance, uint lightma
float mag = ray.magnitude();
if(!mag) continue;
float attenuation = 1;
- if(light.attr1)
- {
+ if(light.attr1) {
attenuation -= mag / float(light.attr1);
if(attenuation <= 0) continue;
}
ray.mul(1.0f / mag);
float angle = -ray.dot(normal);
if(angle <= 0) continue;
- if(light.attached && light.attached->type==ET_SPOTLIGHT)
- {
+ if(light.attached && light.attached->type==ET_SPOTLIGHT) {
vec spot = vec(light.attached->o).sub(light.o).normalize();
float maxatten = sincos360[clamp(int(light.attached->attr1), 1, 89)].x, spotatten = (ray.dot(spot) - maxatten) / (1 - maxatten);
if(spotatten <= 0) continue;
attenuation *= spotatten;
}
- if(lmshadows && mag)
- {
+ if(lmshadows && mag) {
float dist = shadowray(w->shadowraycache, light.o, ray, mag - tolerance, RAY_SHADOW | (lmshadows > 1 ? RAY_ALPHAPOLY : 0));
if(dist < mag - tolerance) continue;
}
lightused |= 1<<i;
float intensity;
- switch(w->type&LM_TYPE)
- {
+ switch(w->type&LM_TYPE) {
case LM_BUMPMAP0:
intensity = attenuation;
avgray.add(ray.mul(-attenuation));
@@ -466,8 +401,7 @@ static uint generatelumel(lightmapworker *w, const float tolerance, uint lightma
g += intensity * float(light.attr3);
b += intensity * float(light.attr4);
}
- switch(w->type&LM_TYPE)
- {
+ switch(w->type&LM_TYPE) {
case LM_BUMPMAP0:
if(avgray.iszero()) break;
// transform to tangent space
@@ -486,8 +420,7 @@ static uint generatelumel(lightmapworker *w, const float tolerance, uint lightma
return lightused;
}
-static bool lumelsample(const vec &sample, int aasample, int stride)
-{
+static bool lumelsample(const vec &sample, int aasample, int stride) {
if(sample.x >= int(ambientcolor[0])+1 || sample.y >= int(ambientcolor[1])+1 || sample.z >= int(ambientcolor[2])+1) return true;
#define NCHECK(n) \
if((n).x >= int(ambientcolor[0])+1 || (n).y >= int(ambientcolor[1])+1 || (n).z >= int(ambientcolor[2])+1) \
@@ -501,11 +434,9 @@ static bool lumelsample(const vec &sample, int aasample, int stride)
return false;
}
-static inline void generatealpha(lightmapworker *w, float tolerance, const vec &pos, uchar &alpha)
-{
+static inline void generatealpha(lightmapworker *w, float tolerance, const vec &pos, uchar &alpha) {
alpha = 0;
- if(w->slot->layermask)
- {
+ if(w->slot->layermask) {
static const int sdim[] = { 1, 0, 0 }, tdim[] = { 2, 2, 1 };
int dim = dimension(w->orient);
float k = 8.0f/w->vslot->scale,
@@ -520,8 +451,7 @@ static inline void generatealpha(lightmapworker *w, float tolerance, const vec &
if(mx < 0) mx += mask.w;
if(my < 0) my += mask.h;
uchar maskval = mask.data[mask.bpp*(mx + 1) - 1 + mask.pitch*my];
- switch(w->slot->layermaskmode)
- {
+ switch(w->slot->layermaskmode) {
case 2: alpha = min(alpha, maskval); break;
case 3: alpha = max(alpha, maskval); break;
case 4: alpha = min(alpha, uchar(0xFF - maskval)); break;
@@ -534,8 +464,7 @@ static inline void generatealpha(lightmapworker *w, float tolerance, const vec &
VAR(edgetolerance, 1, 4, 64);
VAR(adaptivesample, 0, 2, 2);
-enum
-{
+enum {
NO_SURFACE = 0,
SURFACE_AMBIENT_BOTTOM,
SURFACE_AMBIENT_TOP,
@@ -547,33 +476,29 @@ enum
#define SURFACE_AMBIENT SURFACE_AMBIENT_BOTTOM
#define SURFACE_LIGHTMAP SURFACE_LIGHTMAP_BOTTOM
-static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, int numv, vec origin1, const vec &xstep1, const vec &ystep1, vec origin2, const vec &xstep2, const vec &ystep2, float side0, float sidestep)
-{
- static const float aacoords[8][2] =
- {
- {0.0f, 0.0f},
- {-0.5f, -0.5f},
- {0.0f, -0.5f},
- {-0.5f, 0.0f},
-
- {0.3f, -0.6f},
- {0.6f, 0.3f},
- {-0.3f, 0.6f},
- {-0.6f, -0.3f},
+static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, int numv, vec origin1, const vec &xstep1, const vec &ystep1, vec origin2, const vec &xstep2, const vec &ystep2, float side0, float sidestep) {
+ static const float aacoords[8][2] = {
+ {
+ 0.0f, 0.0f}, {
+ -0.5f, -0.5f}, {
+ 0.0f, -0.5f}, {
+ -0.5f, 0.0f},
+ {
+ 0.3f, -0.6f}, {
+ 0.6f, 0.3f}, {
+ -0.3f, 0.6f}, {
+ -0.6f, -0.3f},
};
float tolerance = 0.5 / lpu;
uint lightmask = 0, lightused = 0;
vec offsets1[8], offsets2[8];
- loopi(8)
- {
+ loopi(8) {
offsets1[i] = vec(xstep1).mul(aacoords[i][0]).add(vec(ystep1).mul(aacoords[i][1]));
offsets2[i] = vec(xstep2).mul(aacoords[i][0]).add(vec(ystep2).mul(aacoords[i][1]));
}
if((w->type&LM_TYPE) == LM_BUMPMAP0) memclear(w->raydata, (LM_MAXW + 4)*(LM_MAXH + 4));
-
origin1.sub(vec(ystep1).add(xstep1).mul(0));
origin2.sub(vec(ystep2).add(xstep2).mul(0));
-
int aasample = min(1 << lmaa, 4);
int stride = aasample*(w->w+1);
vec *sample = w->colordata;
@@ -581,13 +506,10 @@ static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, i
lerpbounds start, end;
initlerpbounds(-0, -0, lv, numv, start, end);
float sidex = side0 + 0*sidestep;
- for(int y = 0; y < w->h; ++y, sidex += sidestep)
- {
+ for(int y = 0; y < w->h; ++y, sidex += sidestep) {
vec normal, nstep;
lerpnormal(-0, y - 0, lv, numv, start, end, normal, nstep);
-
- for(int x = 0; x < w->w; ++x, normal.add(nstep), amb += w->bpp)
- {
+ for(int x = 0; x < w->w; ++x, normal.add(nstep), amb += w->bpp) {
#define EDGE_TOLERANCE(x, y) \
(x < 0 \
|| x+1 > w->w - 0 \
@@ -605,28 +527,22 @@ static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, i
sample = w->colordata;
initlerpbounds(-0, -0, lv, numv, start, end);
sidex = side0 + 0*sidestep;
- for(int y = 0; y < w->h; ++y, sidex += sidestep)
- {
+ for(int y = 0; y < w->h; ++y, sidex += sidestep) {
vec normal, nstep;
lerpnormal(-0, y - 0, lv, numv, start, end, normal, nstep);
-
- for(int x = 0; x < w->w; ++x, normal.add(nstep))
- {
+ for(int x = 0; x < w->w; ++x, normal.add(nstep)) {
vec &center = *sample++;
if(adaptivesample && x > 0 && x+1 < w->w && y > 0 && y+1 < w->h && !lumelsample(center, aasample, stride))
loopi(aasample-1) *sample++ = center;
- else
- {
+ else {
#define AA_EDGE_TOLERANCE(x, y, i) EDGE_TOLERANCE(x + aacoords[i][0], y + aacoords[i][1])
vec u = x < sidex ? vec(xstep1).mul(x).add(vec(ystep1).mul(y)).add(origin1) : vec(xstep2).mul(x).add(vec(ystep2).mul(y)).add(origin2);
const vec *offsets = x < sidex ? offsets1 : offsets2;
vec n = vec(normal).normalize();
loopi(aasample-1)
generatelumel(w, AA_EDGE_TOLERANCE(x, y, i+1) * tolerance, lightmask, w->lights, vec(u).add(offsets[i+1]), n, *sample++, x, y);
- if(lmaa == 3)
- {
- loopi(4)
- {
+ if(lmaa == 3) {
+ loopi(4) {
vec s;
generatelumel(w, AA_EDGE_TOLERANCE(x, y, i+4) * tolerance, lightmask, w->lights, vec(u).add(offsets[i+4]), n, s, x, y);
center.add(s);
@@ -635,8 +551,7 @@ static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, i
}
}
}
- if(aasample > 1)
- {
+ if(aasample > 1) {
vec u = w->w < sidex ? vec(xstep1).mul(w->w).add(vec(ystep1).mul(y)).add(origin1) : vec(xstep2).mul(w->w).add(vec(ystep2).mul(y)).add(origin2);
const vec *offsets = w->w < sidex ? offsets1 : offsets2;
vec n = vec(normal).normalize();
@@ -646,14 +561,10 @@ static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, i
}
sample += aasample;
}
-
- if(aasample > 1)
- {
+ if(aasample > 1) {
vec normal, nstep;
lerpnormal(-0, w->h - 0, lv, numv, start, end, normal, nstep);
-
- for(int x = 0; x <= w->w; ++x, normal.add(nstep))
- {
+ for(int x = 0; x <= w->w; ++x, normal.add(nstep)) {
vec u = x < sidex ? vec(xstep1).mul(x).add(vec(ystep1).mul(w->h)).add(origin1) : vec(xstep2).mul(x).add(vec(ystep2).mul(w->h)).add(origin2);
const vec *offsets = x < sidex ? offsets1 : offsets2;
vec n = vec(normal).normalize();
@@ -666,8 +577,7 @@ static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, i
return true;
}
-static int finishlightmap(lightmapworker *w)
-{
+static int finishlightmap(lightmapworker *w) {
vec *sample = w->colordata;
int aasample = min(1 << lmaa, 4), stride = aasample*(w->w+1);
float weight = 1.0f / (1.0f + 4.0f*lmaa),
@@ -677,26 +587,21 @@ static int finishlightmap(lightmapworker *w)
uchar mincolor[4] = { 255, 255, 255, 255 }, maxcolor[4] = { 0, 0, 0, 0 };
bvec *dstray = 0 && (w->w > 1 || w->h > 1) ? (bvec *)w->raydata : w->raybuf;
bvec minray(255, 255, 255), maxray(0, 0, 0);
- loop(y, w->h)
- {
- loop(x, w->w)
- {
+ loop(y, w->h) {
+ loop(x, w->w) {
vec l(0, 0, 0);
const vec &center = *sample++;
loopi(aasample-1) l.add(*sample++);
- if(aasample > 1)
- {
+ if(aasample > 1) {
l.add(sample[1]);
if(aasample > 2) l.add(sample[3]);
}
vec *next = sample + stride - aasample;
- if(aasample > 1)
- {
+ if(aasample > 1) {
l.add(next[1]);
if(aasample > 2) l.add(next[2]);
l.add(next[aasample+1]);
}
-
int r = int(center.x*cweight + l.x*weight),
g = int(center.y*cweight + l.y*weight),
b = int(center.z*cweight + l.z*weight),
@@ -704,30 +609,25 @@ static int finishlightmap(lightmapworker *w)
dstcolor[0] = max(ar, r);
dstcolor[1] = max(ag, g);
dstcolor[2] = max(ab, b);
- loopk(3)
- {
+ loopk(3) {
mincolor[k] = min(mincolor[k], dstcolor[k]);
maxcolor[k] = max(maxcolor[k], dstcolor[k]);
}
- if(w->type&LM_ALPHA)
- {
+ if(w->type&LM_ALPHA) {
dstcolor[3] = 127;///TODO
mincolor[3] = min(mincolor[3], dstcolor[3]);
maxcolor[3] = max(maxcolor[3], dstcolor[3]);
}
- if((w->type&LM_TYPE) == LM_BUMPMAP0)
- {
+ if((w->type&LM_TYPE) == LM_BUMPMAP0) {
if(ray->iszero()) dstray[0] = bvec(128, 128, 255);
- else
- {
+ else {
ray->normalize();
int l = max(r, max(g, b)), a = max(ar, max(ag, ab));
ray->mul(max(l-a, 0));
ray->z += a;
dstray[0] = bvec(ray->normalize());
}
- loopk(3)
- {
+ loopk(3) {
minray[k] = min(minray[k], dstray[0][k]);
maxray[k] = max(maxray[k], dstray[0][k]);
}
@@ -741,8 +641,7 @@ static int finishlightmap(lightmapworker *w)
if(int(maxcolor[0]) - int(mincolor[0]) <= lighterror &&
int(maxcolor[1]) - int(mincolor[1]) <= lighterror &&
int(maxcolor[2]) - int(mincolor[2]) <= lighterror &&
- mincolor[3] >= maxcolor[3])
- {
+ mincolor[3] >= maxcolor[3]) {
uchar color[3];
loopk(3) color[k] = (int(maxcolor[k]) + int(mincolor[k])) / 2;
if(color[0] <= int(ambientcolor[0]) + lighterror &&
@@ -754,12 +653,10 @@ static int finishlightmap(lightmapworker *w)
(int(maxray.x) - int(minray.x) <= bumperror &&
int(maxray.y) - int(minray.z) <= bumperror &&
int(maxray.z) - int(minray.z) <= bumperror))
-
- {
+ {
memcpy(w->colorbuf, color, 3);
if(w->type&LM_ALPHA) w->colorbuf[3] = mincolor[3];
- if((w->type&LM_TYPE) == LM_BUMPMAP0)
- {
+ if((w->type&LM_TYPE) == LM_BUMPMAP0) {
loopk(3) w->raybuf[0][k] = uchar((int(maxray[k])+int(minray[k]))/2);
}
w->lastlightmap->w = w->w = 1;
@@ -771,17 +668,14 @@ static int finishlightmap(lightmapworker *w)
else return SURFACE_LIGHTMAP_BLEND;
}
-static int previewlightmapalpha(lightmapworker *w, float lpu, const vec &origin1, const vec &xstep1, const vec &ystep1, const vec &origin2, const vec &xstep2, const vec &ystep2, float side0, float sidestep)
-{
+static int previewlightmapalpha(lightmapworker *w, float lpu, const vec &origin1, const vec &xstep1, const vec &ystep1, const vec &origin2, const vec &xstep2, const vec &ystep2, float side0, float sidestep) {
extern int fullbrightlevel;
float tolerance = 0.5 / lpu;
uchar *dst = w->colorbuf;
uchar minalpha = 255, maxalpha = 0;
float sidex = side0;
- for(int y = 0; y < w->h; ++y, sidex += sidestep)
- {
- for(int x = 0; x < w->w; ++x, dst += 4)
- {
+ for(int y = 0; y < w->h; ++y, sidex += sidestep) {
+ for(int x = 0; x < w->w; ++x, dst += 4) {
vec u = x < sidex ?
vec(xstep1).mul(x).add(vec(ystep1).mul(y)).add(origin1) :
vec(xstep2).mul(x).add(vec(ystep2).mul(y)).add(origin2);
@@ -798,25 +692,18 @@ static int previewlightmapalpha(lightmapworker *w, float lpu, const vec &origin1
return SURFACE_LIGHTMAP_BLEND;
}
-static void clearsurfaces(cube *c)
-{
- loopi(8)
- {
- if(c[i].ext)
- {
- loopj(6)
- {
+static void clearsurfaces(cube *c) {
+ loopi(8) {
+ if(c[i].ext) {
+ loopj(6) {
surfaceinfo &surf = c[i].ext->surfaces[j];
if(!surf.used()) continue;
surf.clear();
int numverts = surf.numverts&MAXFACEVERTS;
- if(numverts)
- {
+ if(numverts) {
if(!(c[i].merged&(1<<j))) { surf.numverts &= ~MAXFACEVERTS; continue; }
-
vertinfo *verts = c[i].ext->verts() + surf.verts;
- loopk(numverts)
- {
+ loopk(numverts) {
vertinfo &v = verts[k];
v.u = 0;
v.v = 0;
@@ -831,8 +718,7 @@ static void clearsurfaces(cube *c)
#define LIGHTCACHESIZE 1024
-static struct lightcacheentry
-{
+static struct lightcacheentry {
int x, y;
vector<int> lights;
} lightcache[LIGHTCACHESIZE];
@@ -841,17 +727,13 @@ static struct lightcacheentry
VARF(lightcachesize, 4, 6, 12, clearlightcache());
-void clearlightcache(int id)
-{
- if(id >= 0)
- {
+void clearlightcache(int id) {
+ if(id >= 0) {
const extentity &light = *entities::getents()[id];
int radius = light.attr1;
- if(radius)
- {
+ if(radius) {
for(int x = int(max(light.o.x-radius, 0.0f))>>lightcachesize, ex = int(min(light.o.x+radius, worldsize-1.0f))>>lightcachesize; x <= ex; x++)
- for(int y = int(max(light.o.y-radius, 0.0f))>>lightcachesize, ey = int(min(light.o.y+radius, worldsize-1.0f))>>lightcachesize; y <= ey; y++)
- {
+ for(int y = int(max(light.o.y-radius, 0.0f))>>lightcachesize, ey = int(min(light.o.y+radius, worldsize-1.0f))>>lightcachesize; y <= ey; y++) {
lightcacheentry &lce = lightcache[LIGHTCACHEHASH(x, y)];
if(lce.x != x || lce.y != y) continue;
lce.x = -1;
@@ -860,34 +742,26 @@ void clearlightcache(int id)
return;
}
}
-
- for(lightcacheentry *lce = lightcache; lce < &lightcache[LIGHTCACHESIZE]; lce++)
- {
+ for(lightcacheentry *lce = lightcache; lce < &lightcache[LIGHTCACHESIZE]; lce++) {
lce->x = -1;
lce->lights.setsize(0);
}
}
-const vector<int> &checklightcache(int x, int y)
-{
+const vector<int> &checklightcache(int x, int y) {
x >>= lightcachesize;
y >>= lightcachesize;
lightcacheentry &lce = lightcache[LIGHTCACHEHASH(x, y)];
if(lce.x == x && lce.y == y) return lce.lights;
-
lce.lights.setsize(0);
int csize = 1<<lightcachesize, cx = x<<lightcachesize, cy = y<<lightcachesize;
const vector<extentity *> &ents = entities::getents();
- loopv(ents)
- {
+ loopv(ents) {
const extentity &light = *ents[i];
- switch(light.type)
- {
- case ET_LIGHT:
- {
+ switch(light.type) {
+ case ET_LIGHT: {
int radius = light.attr1;
- if(radius > 0)
- {
+ if(radius > 0) {
if(light.o.x + radius < cx || light.o.x - radius > cx + csize ||
light.o.y + radius < cy || light.o.y - radius > cy + csize)
continue;
@@ -898,60 +772,48 @@ const vector<int> &checklightcache(int x, int y)
}
lce.lights.add(i);
}
-
lce.x = x;
lce.y = y;
return lce.lights;
}
-static inline void addlight(lightmapworker *w, const extentity &light, int cx, int cy, int cz, int size, const vec *v, const vec *n, int numv)
-{
+static inline void addlight(lightmapworker *w, const extentity &light, int cx, int cy, int cz, int size, const vec *v, const vec *n, int numv) {
int radius = light.attr1;
- if(radius > 0)
- {
+ if(radius > 0) {
if(light.o.x + radius < cx || light.o.x - radius > cx + size ||
light.o.y + radius < cy || light.o.y - radius > cy + size ||
light.o.z + radius < cz || light.o.z - radius > cz + size)
return;
}
-
- loopi(4)
- {
+ loopi(4) {
vec p(light.o);
p.sub(v[i]);
float dist = p.dot(n[i]);
- if(dist >= 0 && (!radius || dist < radius))
- {
+ if(dist >= 0 && (!radius || dist < radius)) {
w->lights.add(&light);
break;
}
}
}
-static bool findlights(lightmapworker *w, int cx, int cy, int cz, int size, const vec *v, const vec *n, int numv, const Slot &slot, const VSlot &vslot)
-{
+static bool findlights(lightmapworker *w, int cx, int cy, int cz, int size, const vec *v, const vec *n, int numv, const Slot &slot, const VSlot &vslot) {
w->lights.setsize(0);
const vector<extentity *> &ents = entities::getents();
static volatile bool usinglightcache = false;
- if(size <= 1<<lightcachesize && (!lightlock || !usinglightcache))
- {
+ if(size <= 1<<lightcachesize && (!lightlock || !usinglightcache)) {
if(lightlock) { SDL_LockMutex(lightlock); usinglightcache = true; }
const vector<int> &lights = checklightcache(cx, cy);
- loopv(lights)
- {
+ loopv(lights) {
const extentity &light = *ents[lights[i]];
- switch(light.type)
- {
+ switch(light.type) {
case ET_LIGHT: addlight(w, light, cx, cy, cz, size, v, n, numv); break;
}
}
if(lightlock) { usinglightcache = false; SDL_UnlockMutex(lightlock); }
}
- else loopv(ents)
- {
+ else loopv(ents) {
const extentity &light = *ents[i];
- switch(light.type)
- {
+ switch(light.type) {
case ET_LIGHT: addlight(w, light, cx, cy, cz, size, v, n, numv); break;
}
}
@@ -959,15 +821,12 @@ static bool findlights(lightmapworker *w, int cx, int cy, int cz, int size, cons
return w->lights.length();
}
-static int packlightmaps(lightmapworker *w = NULL)
-{
+static int packlightmaps(lightmapworker *w = NULL) {
int numpacked = 0;
- for(; packidx < lightmaptasks[0].length(); packidx++, numpacked++)
- {
+ for(; packidx < lightmaptasks[0].length(); packidx++, numpacked++) {
lightmaptask &t = lightmaptasks[0][packidx];
if(!t.lightmaps) break;
- if(t.ext && t.c->ext != t.ext)
- {
+ if(t.ext && t.c->ext != t.ext) {
lightmapext &e = lightmapexts.add();
e.c = t.c;
e.ext = t.ext;
@@ -976,8 +835,7 @@ static int packlightmaps(lightmapworker *w = NULL)
lightmapinfo *l = t.lightmaps;
if(l == (lightmapinfo *)-1) continue;
int space = 0;
- for(; l && l->c == t.c; l = l->next)
- {
+ for(; l && l->c == t.c; l = l->next) {
l->packed = true;
space += l->bufsize;
if(l->surface < 0 || !t.ext) continue;
@@ -986,31 +844,26 @@ static int packlightmaps(lightmapworker *w = NULL)
packlightmap(*l, layout);
int numverts = surf.numverts&MAXFACEVERTS;
vertinfo *verts = t.ext->verts() + surf.verts;
- if(l->layers&LAYER_DUP)
- {
+ if(l->layers&LAYER_DUP) {
if(l->type&LM_ALPHA) surf.lmid[0] = layout.lmid;
else { surf.lmid[1] = layout.lmid; verts += numverts; }
}
- else
- {
+ else {
if(l->layers&LAYER_TOP) surf.lmid[0] = layout.lmid;
if(l->layers&LAYER_BOTTOM) surf.lmid[1] = layout.lmid;
}
ushort offsetx = layout.x*((USHRT_MAX+1)/LM_PACKW), offsety = layout.y*((USHRT_MAX+1)/LM_PACKH);
- loopk(numverts)
- {
+ loopk(numverts) {
vertinfo &v = verts[k];
v.u += offsetx;
v.v += offsety;
}
}
- if(t.worker == w)
- {
+ if(t.worker == w) {
w->bufused -= space;
w->bufstart = (w->bufstart + space)%LIGHTMAPBUFSIZE;
w->firstlightmap = l;
- if(!l)
- {
+ if(!l) {
w->lastlightmap = NULL;
w->bufstart = w->bufused = 0;
}
@@ -1020,8 +873,7 @@ static int packlightmaps(lightmapworker *w = NULL)
return numpacked;
}
-static lightmapinfo *alloclightmap(lightmapworker *w)
-{
+static lightmapinfo *alloclightmap(lightmapworker *w) {
int needspace1 = sizeof(lightmapinfo) + w->w*w->h*w->bpp,
needspace2 = (w->type&LM_TYPE) == LM_BUMPMAP0 ? w->w*w->h*3 : 0,
needspace = needspace1 + needspace2,
@@ -1029,20 +881,16 @@ static lightmapinfo *alloclightmap(lightmapworker *w)
availspace = LIGHTMAPBUFSIZE - w->bufused,
availspace1 = min(availspace, LIGHTMAPBUFSIZE - bufend),
availspace2 = min(availspace, w->bufstart);
- if(availspace < needspace || (max(availspace1, availspace2) < needspace && (availspace1 < needspace1 || availspace2 < needspace2)))
- {
+ if(availspace < needspace || (max(availspace1, availspace2) < needspace && (availspace1 < needspace1 || availspace2 < needspace2))) {
if(tasklock) SDL_LockMutex(tasklock);
- while(!w->doneworking)
- {
+ while(!w->doneworking) {
lightmapinfo *l = w->firstlightmap;
- for(; l && l->packed; l = l->next)
- {
+ for(; l && l->packed; l = l->next) {
w->bufused -= l->bufsize;
w->bufstart = (w->bufstart + l->bufsize)%LIGHTMAPBUFSIZE;
}
w->firstlightmap = l;
- if(!l)
- {
+ if(!l) {
w->lastlightmap = NULL;
w->bufstart = w->bufused = 0;
}
@@ -1061,20 +909,17 @@ static lightmapinfo *alloclightmap(lightmapworker *w)
}
int usedspace = needspace;
lightmapinfo *l = NULL;
- if(availspace1 >= needspace1)
- {
+ if(availspace1 >= needspace1) {
l = (lightmapinfo *)&w->buf[bufend];
w->colorbuf = (uchar *)(l + 1);
if((w->type&LM_TYPE) != LM_BUMPMAP0) w->raybuf = NULL;
else if(availspace1 >= needspace) w->raybuf = (bvec *)&w->buf[bufend + needspace1];
- else
- {
+ else {
w->raybuf = (bvec *)w->buf;
usedspace += availspace1 - needspace1;
}
}
- else if(availspace2 >= needspace)
- {
+ else if(availspace2 >= needspace) {
usedspace += availspace1;
l = (lightmapinfo *)w->buf;
w->colorbuf = (uchar *)(l + 1);
@@ -1101,17 +946,14 @@ static lightmapinfo *alloclightmap(lightmapworker *w)
return l;
}
-static void freelightmap(lightmapworker *w)
-{
+static void freelightmap(lightmapworker *w) {
lightmapinfo *l = w->lastlightmap;
if(!l || l->surface >= 0) return;
- if(w->firstlightmap == w->lastlightmap)
- {
+ if(w->firstlightmap == w->lastlightmap) {
w->firstlightmap = w->lastlightmap = w->curlightmaps = NULL;
w->bufstart = w->bufused = 0;
}
- else
- {
+ else {
w->bufused -= l->bufsize - sizeof(lightmapinfo);
l->bufsize = sizeof(lightmapinfo);
l->packed = true;
@@ -1119,11 +961,9 @@ static void freelightmap(lightmapworker *w)
if(w->curlightmaps == l) w->curlightmaps = NULL;
}
-static int setupsurface(lightmapworker *w, plane planes[2], int numplanes, const vec *p, const vec *n, int numverts, vertinfo *litverts, bool preview = false)
-{
+static int setupsurface(lightmapworker *w, plane planes[2], int numplanes, const vec *p, const vec *n, int numverts, vertinfo *litverts, bool preview = false) {
vec u, v, t;
vec2 c[MAXFACEVERTS];
-
u = vec(p[2]).sub(p[0]).normalize();
v.cross(planes[0], u);
c[0] = vec2(0, 0);
@@ -1131,24 +971,20 @@ static int setupsurface(lightmapworker *w, plane planes[2], int numplanes, const
vec r1 = vec(p[1]).sub(p[0]);
c[1] = vec2(r1.dot(u), min(r1.dot(v), 0.0f));
c[2] = vec2(vec(p[2]).sub(p[0]).dot(u), 0);
- for(int i = 3; i < numverts; i++)
- {
+ for(int i = 3; i < numverts; i++) {
vec r = vec(p[i]).sub(p[0]);
c[i] = vec2(r.dot(u), max(r.dot(t), 0.0f));
}
-
float carea = 1e16f;
vec2 cx(0, 0), cy(0, 0), co(0, 0), cmin(0, 0), cmax(0, 0);
- loopi(numverts)
- {
+ loopi(numverts) {
vec2 px = vec2(c[i+1 < numverts ? i+1 : 0]).sub(c[i]);
float len = px.squaredlen();
if(!len) continue;
px.mul(1/sqrtf(len));
vec2 py(-px.y, px.x), pmin(0, 0), pmax(0, 0);
if(numplanes >= 2 && (i == 0 || i >= 3)) px.neg();
- loopj(numverts)
- {
+ loopj(numverts) {
vec2 rj = vec2(c[j]).sub(c[i]), pj(rj.dot(px), rj.dot(py));
pmin.x = min(pmin.x, pj.x);
pmin.y = min(pmin.y, pj.y);
@@ -1158,29 +994,24 @@ static int setupsurface(lightmapworker *w, plane planes[2], int numplanes, const
float area = (pmax.x-pmin.x)*(pmax.y-pmin.y);
if(area < carea) { carea = area; cx = px; cy = py; co = c[i]; cmin = pmin; cmax = pmax; }
}
-
int scale = int(min(cmax.x - cmin.x, cmax.y - cmin.y));
float lpu = 16.0f / float(lightlod && scale < (1 << lightlod) ? max(lightprecision / 2, 1) : lightprecision);
int lw = clamp(int(ceil((cmax.x - cmin.x + 1)*lpu)), LM_MINW, LM_MAXW), lh = clamp(int(ceil((cmax.y - cmin.y + 1)*lpu)), LM_MINH, LM_MAXH);
w->w = lw;
w->h = lh;
if(!alloclightmap(w)) return NO_SURFACE;
-
vec2 cscale = vec2(cmax).sub(cmin).div(vec2(lw-1, lh-1)),
comin = vec2(cx).mul(cmin.x).add(vec2(cy).mul(cmin.y)).add(co);
- loopi(numverts)
- {
+ loopi(numverts) {
vec2 ri = vec2(c[i]).sub(comin);
c[i] = vec2(ri.dot(cx)/cscale.x, ri.dot(cy)/cscale.y);
}
-
vec xstep1 = vec(v).mul(cx.y).add(vec(u).mul(cx.x)).mul(cscale.x),
ystep1 = vec(v).mul(cy.y).add(vec(u).mul(cy.x)).mul(cscale.y),
origin1 = vec(v).mul(comin.y).add(vec(u).mul(comin.x)).add(p[0]),
xstep2 = xstep1, ystep2 = ystep1, origin2 = origin1;
float side0 = LM_MAXW + 1, sidestep = 0;
- if(numplanes >= 2)
- {
+ if(numplanes >= 2) {
xstep2 = vec(t).mul(cx.y).add(vec(u).mul(cx.x)).mul(cscale.x);
ystep2 = vec(t).mul(cy.y).add(vec(u).mul(cy.x)).mul(cscale.y);
origin2 = vec(t).mul(comin.y).add(vec(u).mul(comin.x)).add(p[0]);
@@ -1188,41 +1019,33 @@ static int setupsurface(lightmapworker *w, plane planes[2], int numplanes, const
else if(cy.y) { side0 = ceil(comin.y/-(cy.y*cscale.y))*(LM_MAXW + 1); sidestep = -(LM_MAXW + 1); if(cy.y < 0) { side0 = (LM_MAXW + 1) - side0; sidestep = -sidestep; } }
else side0 = comin.y <= 0 ? LM_MAXW + 1 : -1;
}
-
int surftype = NO_SURFACE;
- if(preview)
- {
+ if(preview) {
surftype = previewlightmapalpha(w, lpu, origin1, xstep1, ystep1, origin2, xstep2, ystep2, side0, sidestep);
}
- else
- {
+ else {
lerpvert lv[MAXFACEVERTS];
int numv = numverts;
calclerpverts(c, n, lv, numv);
-
if(!generatelightmap(w, lpu, lv, numv, origin1, xstep1, ystep1, origin2, xstep2, ystep2, side0, sidestep)) return NO_SURFACE;
surftype = finishlightmap(w);
}
if(surftype<SURFACE_LIGHTMAP) return surftype;
-
vec2 texscale(float(USHRT_MAX+1)/LM_PACKW, float(USHRT_MAX+1)/LM_PACKH);
if(lw != w->w) texscale.x *= float(w->w - 1) / (lw - 1);
if(lh != w->h) texscale.y *= float(w->h - 1) / (lh - 1);
- loopk(numverts)
- {
+ loopk(numverts) {
litverts[k].u = ushort(floor(clamp(c[k].x*texscale.x, 0.0f, float(USHRT_MAX))));
litverts[k].v = ushort(floor(clamp(c[k].y*texscale.y, 0.0f, float(USHRT_MAX))));
}
return surftype;
}
-static void removelmalpha(lightmapworker *w)
-{
+static void removelmalpha(lightmapworker *w) {
if(!(w->type&LM_ALPHA)) return;
for(uchar *dst = w->colorbuf, *src = w->colorbuf, *end = &src[w->w*w->h*4];
src < end;
- dst += 3, src += 4)
- {
+ dst += 3, src += 4) {
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
@@ -1233,60 +1056,48 @@ static void removelmalpha(lightmapworker *w)
w->lastlightmap->bpp = w->bpp;
}
-static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task)
-{
+static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task) {
cube &c = *task.c;
const ivec &co = task.o;
int size = task.size, usefacemask = task.usefaces;
-
w->curlightmaps = NULL;
w->c = &c;
-
surfaceinfo surfaces[6];
vertinfo litverts[6*2*MAXFACEVERTS];
int numlitverts = 0;
memclear(surfaces);
- loopi(6)
- {
+ loopi(6) {
int usefaces = usefacemask&0xF;
usefacemask >>= 4;
- if(!usefaces)
- {
+ if(!usefaces) {
if(!c.ext) continue;
surfaceinfo &surf = surfaces[i];
surf = c.ext->surfaces[i];
int numverts = surf.totalverts();
- if(numverts)
- {
+ if(numverts) {
memcpy(&litverts[numlitverts], c.ext->verts() + surf.verts, numverts*sizeof(vertinfo));
surf.verts = numlitverts;
numlitverts += numverts;
}
continue;
}
-
VSlot &vslot = lookupvslot(c.texture[i], false),
*layer = vslot.layer && !(c.material&MAT_ALPHA) ? &lookupvslot(vslot.layer, false) : NULL;
Shader *shader = vslot.slot->shader;
int shadertype = shader->type;
if(layer) shadertype |= layer->slot->shader->type;
-
surfaceinfo &surf = surfaces[i];
vertinfo *curlitverts = &litverts[numlitverts];
int numverts = c.ext ? c.ext->surfaces[i].numverts&MAXFACEVERTS : 0;
ivec mo(co);
int msz = size, convex = 0;
- if(numverts)
- {
+ if(numverts) {
vertinfo *verts = c.ext->verts() + c.ext->surfaces[i].verts;
loopj(numverts) curlitverts[j].set(verts[j].getxyz());
- if(c.merged&(1<<i))
- {
+ if(c.merged&(1<<i)) {
msz = 1<<calcmergedsize(i, mo, size, verts, numverts);
mo.mask(~(msz-1));
-
- if(!(surf.numverts&MAXFACEVERTS))
- {
+ if(!(surf.numverts&MAXFACEVERTS)) {
surf.verts = numlitverts;
surf.numverts |= numverts;
numlitverts += numverts;
@@ -1294,8 +1105,7 @@ static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task)
}
else if(!flataxisface(c, i)) convex = faceconvexity(verts, numverts, size);
}
- else
- {
+ else {
ivec v[4];
genfaceverts(c, i, v);
if(!flataxisface(c, i)) convex = faceconvexity(v);
@@ -1306,16 +1116,13 @@ static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task)
curlitverts[numverts++].set(v[order+2].mul(size).add(vo));
if(usefaces&2) curlitverts[numverts++].set(v[(order+3)&3].mul(size).add(vo));
}
-
vec pos[MAXFACEVERTS], n[MAXFACEVERTS], po(ivec(co).mask(~0xFFF));
loopj(numverts) pos[j] = vec(curlitverts[j].getxyz()).mul(1.0f/8).add(po);
-
plane planes[2];
int numplanes = 0;
planes[numplanes++].toplane(pos[0], pos[1], pos[2]);
if(numverts < 4 || !convex) loopk(numverts) findnormal(pos[k], planes[0], n[k]);
- else
- {
+ else {
planes[numplanes++].toplane(pos[0], pos[2], pos[3]);
vec avg = vec(planes[0]).add(planes[1]).normalize();
findnormal(pos[0], avg, n[0]);
@@ -1323,24 +1130,18 @@ static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task)
findnormal(pos[2], avg, n[2]);
for(int k = 3; k < numverts; k++) findnormal(pos[k], planes[1], n[k]);
}
-
- if(shadertype&SHADER_NORMALSLMS)
- {
+ if(shadertype&SHADER_NORMALSLMS) {
loopk(numverts) curlitverts[k].norm = encodenormal(n[k]);
- if(!(surf.numverts&MAXFACEVERTS))
- {
+ if(!(surf.numverts&MAXFACEVERTS)) {
surf.verts = numlitverts;
surf.numverts |= numverts;
numlitverts += numverts;
}
}
-
- if(!findlights(w, mo.x, mo.y, mo.z, msz, pos, n, numverts, *vslot.slot, vslot))
- {
+ if(!findlights(w, mo.x, mo.y, mo.z, msz, pos, n, numverts, *vslot.slot, vslot)) {
if(surf.numverts&MAXFACEVERTS) surf.numverts |= LAYER_TOP;
continue;
}
-
w->slot = vslot.slot;
w->vslot = &vslot;
w->type = shader->type&SHADER_NORMALSLMS ? LM_BUMPMAP0 : LM_DIFFUSE;
@@ -1349,30 +1150,24 @@ static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task)
w->orient = i;
w->rotate = vslot.rotation;
int surftype = setupsurface(w, planes, numplanes, pos, n, numverts, curlitverts);
- switch(surftype)
- {
+ switch(surftype) {
case SURFACE_LIGHTMAP_BOTTOM:
if((shader->type^layer->slot->shader->type)&SHADER_NORMALSLMS ||
- (shader->type&SHADER_NORMALSLMS && vslot.rotation!=layer->rotation))
- {
+ (shader->type&SHADER_NORMALSLMS && vslot.rotation!=layer->rotation)) {
freelightmap(w);
break;
}
// fall through
case SURFACE_LIGHTMAP_BLEND:
- case SURFACE_LIGHTMAP_TOP:
- {
- if(!(surf.numverts&MAXFACEVERTS))
- {
+ case SURFACE_LIGHTMAP_TOP: {
+ if(!(surf.numverts&MAXFACEVERTS)) {
surf.verts = numlitverts;
surf.numverts |= numverts;
numlitverts += numverts;
}
-
w->lastlightmap->surface = i;
w->lastlightmap->layers = (surftype==SURFACE_LIGHTMAP_BOTTOM ? LAYER_BOTTOM : LAYER_TOP);
- if(surftype==SURFACE_LIGHTMAP_BLEND)
- {
+ if(surftype==SURFACE_LIGHTMAP_BLEND) {
surf.numverts |= LAYER_BLEND;
w->lastlightmap->layers = LAYER_TOP;
if((shader->type^layer->slot->shader->type)&SHADER_NORMALSLMS ||
@@ -1380,15 +1175,12 @@ static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task)
break;
w->lastlightmap->layers |= LAYER_BOTTOM;
}
- else
- {
- if(surftype==SURFACE_LIGHTMAP_BOTTOM)
- {
+ else {
+ if(surftype==SURFACE_LIGHTMAP_BOTTOM) {
surf.numverts |= LAYER_BOTTOM;
w->lastlightmap->layers = LAYER_BOTTOM;
}
- else
- {
+ else {
surf.numverts |= LAYER_TOP;
w->lastlightmap->layers = LAYER_TOP;
}
@@ -1396,44 +1188,35 @@ static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task)
}
continue;
}
-
case SURFACE_AMBIENT_BOTTOM:
freelightmap(w);
surf.numverts |= layer ? LAYER_BOTTOM : LAYER_TOP;
continue;
-
case SURFACE_AMBIENT_TOP:
freelightmap(w);
surf.numverts |= LAYER_TOP;
continue;
-
default:
freelightmap(w);
continue;
}
-
w->slot = layer->slot;
w->vslot = layer;
w->type = layer->slot->shader->type&SHADER_NORMALSLMS ? LM_BUMPMAP0 : LM_DIFFUSE;
w->bpp = 3;
w->rotate = layer->rotation;
vertinfo *blendverts = surf.numverts&MAXFACEVERTS ? &curlitverts[numverts] : curlitverts;
- switch(setupsurface(w, planes, numplanes, pos, n, numverts, blendverts))
- {
- case SURFACE_LIGHTMAP_TOP:
- {
- if(!(surf.numverts&MAXFACEVERTS))
- {
+ switch(setupsurface(w, planes, numplanes, pos, n, numverts, blendverts)) {
+ case SURFACE_LIGHTMAP_TOP: {
+ if(!(surf.numverts&MAXFACEVERTS)) {
surf.verts = numlitverts;
surf.numverts |= numverts;
numlitverts += numverts;
}
- else if(!(surf.numverts&LAYER_DUP))
- {
+ else if(!(surf.numverts&LAYER_DUP)) {
surf.numverts |= LAYER_DUP;
w->lastlightmap->layers |= LAYER_DUP;
- loopk(numverts)
- {
+ loopk(numverts) {
vertinfo &src = curlitverts[k];
vertinfo &dst = blendverts[k];
dst.setxyz(src.getxyz());
@@ -1443,26 +1226,20 @@ static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task)
}
surf.numverts |= LAYER_BOTTOM;
w->lastlightmap->layers |= LAYER_BOTTOM;
-
w->lastlightmap->surface = i;
break;
}
-
- case SURFACE_AMBIENT_TOP:
- {
+ case SURFACE_AMBIENT_TOP: {
freelightmap(w);
surf.numverts |= LAYER_BOTTOM;
break;
}
-
default: freelightmap(w); break;
}
}
- loopk(6)
- {
+ loopk(6) {
surfaceinfo &surf = surfaces[k];
- if(surf.used())
- {
+ if(surf.used()) {
cubeext *ext = c.ext && c.ext->maxverts >= numlitverts ? c.ext : growcubeext(c.ext, numlitverts);
memcpy(ext->surfaces, surfaces, sizeof(ext->surfaces));
memcpy(ext->verts(), litverts, numlitverts*sizeof(vertinfo));
@@ -1473,14 +1250,11 @@ static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task)
return w->curlightmaps ? w->curlightmaps : (lightmapinfo *)-1;
}
-int lightmapworker::work(void *data)
-{
+int lightmapworker::work(void *data) {
lightmapworker *w = (lightmapworker *)data;
SDL_LockMutex(tasklock);
- while(!w->doneworking)
- {
- if(allocidx < lightmaptasks[0].length())
- {
+ while(!w->doneworking) {
+ if(allocidx < lightmaptasks[0].length()) {
lightmaptask &t = lightmaptasks[0][allocidx++];
t.worker = w;
SDL_UnlockMutex(tasklock);
@@ -1489,8 +1263,7 @@ int lightmapworker::work(void *data)
t.lightmaps = l;
packlightmaps(w);
}
- else
- {
+ else {
if(packidx >= lightmaptasks[0].length()) SDL_CondSignal(emptycond);
SDL_CondWait(fullcond, tasklock);
}
@@ -1499,28 +1272,22 @@ int lightmapworker::work(void *data)
return 0;
}
-static bool processtasks(bool finish = false)
-{
+static bool processtasks(bool finish = false) {
if(tasklock) SDL_LockMutex(tasklock);
- while(finish || lightmaptasks[1].length())
- {
- if(packidx >= lightmaptasks[0].length())
- {
+ while(finish || lightmaptasks[1].length()) {
+ if(packidx >= lightmaptasks[0].length()) {
if(lightmaptasks[1].empty()) break;
lightmaptasks[0].setsize(0);
lightmaptasks[0].move(lightmaptasks[1]);
packidx = allocidx = 0;
if(fullcond) SDL_CondBroadcast(fullcond);
}
- else if(lightmapping > 1)
- {
+ else if(lightmapping > 1) {
SDL_CondWaitTimeout(emptycond, tasklock, 250);
CHECK_PROGRESS_LOCKED({ SDL_UnlockMutex(tasklock); return false; }, SDL_UnlockMutex(tasklock), SDL_LockMutex(tasklock));
}
- else
- {
- while(allocidx < lightmaptasks[0].length())
- {
+ else {
+ while(allocidx < lightmaptasks[0].length()) {
lightmaptask &t = lightmaptasks[0][allocidx++];
t.worker = lightmapworkers[0];
t.lightmaps = setupsurfaces(lightmapworkers[0], t);
@@ -1533,35 +1300,26 @@ static bool processtasks(bool finish = false)
return true;
}
-static void generatelightmaps(cube *c, const ivec &co, int size)
-{
+static void generatelightmaps(cube *c, const ivec &co, int size) {
CHECK_PROGRESS(return);
-
taskprogress++;
-
- loopi(8)
- {
+ loopi(8) {
ivec o(i, co, size);
if(c[i].children)
generatelightmaps(c[i].children, o, size >> 1);
- else if(!isempty(c[i]))
- {
- if(c[i].ext)
- {
- loopj(6)
- {
+ else if(!isempty(c[i])) {
+ if(c[i].ext) {
+ loopj(6) {
surfaceinfo &surf = c[i].ext->surfaces[j];
if(surf.lmid[0] >= LMID_RESERVED || surf.lmid[1] >= LMID_RESERVED) goto nextcube;
surf.clear();
}
}
int usefacemask = 0;
- loopj(6) if(!(c[i].merged&(1<<j)) || (c[i].ext && c[i].ext->surfaces[j].numverts&MAXFACEVERTS))
- {
+ loopj(6) if(!(c[i].merged&(1<<j)) || (c[i].ext && c[i].ext->surfaces[j].numverts&MAXFACEVERTS)) {
usefacemask |= visibletris(c[i], j, o, size)<<(4*j);
}
- if(usefacemask)
- {
+ if(usefacemask) {
lightmaptask &t = lightmaptasks[1].add();
t.o = o;
t.size = size;
@@ -1577,10 +1335,8 @@ static void generatelightmaps(cube *c, const ivec &co, int size)
}
}
-void cleanuplightmaps()
-{
- loopv(lightmaps)
- {
+void cleanuplightmaps() {
+ loopv(lightmaps) {
LightMap &lm = lightmaps[i];
lm.tex = lm.offsetx = lm.offsety = -1;
}
@@ -1589,8 +1345,7 @@ void cleanuplightmaps()
if(progresstex) { glDeleteTextures(1, &progresstex); progresstex = 0; }
}
-void resetlightmaps(bool fullclean)
-{
+void resetlightmaps(bool fullclean) {
cleanuplightmaps();
lightmaps.shrink(0);
compressed.clear();
@@ -1598,8 +1353,7 @@ void resetlightmaps(bool fullclean)
if(fullclean) while(lightmapworkers.length()) delete lightmapworkers.pop();
}
-lightmapworker::lightmapworker()
-{
+lightmapworker::lightmapworker() {
buf = new uchar[LIGHTMAPBUFSIZE];
bufstart = bufused = 0;
firstlightmap = lastlightmap = curlightmaps = NULL;
@@ -1613,8 +1367,7 @@ lightmapworker::lightmapworker()
thread = NULL;
}
-lightmapworker::~lightmapworker()
-{
+lightmapworker::~lightmapworker() {
cleanupthread();
delete[] buf;
delete[] ambient;
@@ -1624,38 +1377,32 @@ lightmapworker::~lightmapworker()
freeshadowraycache(shadowraycache);
}
-void lightmapworker::cleanupthread()
-{
+void lightmapworker::cleanupthread() {
if(spacecond) { SDL_DestroyCond(spacecond); spacecond = NULL; }
thread = NULL;
}
-void lightmapworker::reset()
-{
+void lightmapworker::reset() {
bufstart = bufused = 0;
firstlightmap = lastlightmap = curlightmaps = NULL;
needspace = doneworking = false;
resetshadowraycache(shadowraycache);
}
-bool lightmapworker::setupthread()
-{
+bool lightmapworker::setupthread() {
if(!spacecond) spacecond = SDL_CreateCond();
if(!spacecond) return false;
thread = SDL_CreateThread(work, "lightmap worker", this);
return thread!=NULL;
}
-static Uint32 calclighttimer(Uint32 interval, void *param)
-{
+static Uint32 calclighttimer(Uint32 interval, void *param) {
check_calclight_progress = true;
return interval;
}
-bool setlightmapquality(int quality)
-{
- switch(quality)
- {
+bool setlightmapquality(int quality) {
+ switch(quality) {
case 1: lmshadows = 2; lmaa = 3; lerptjoints = 1; break;
case 0: lmshadows = lmshadows_; lmaa = lmaa_; lerptjoints = lerptjoints_; break;
case -1: lmshadows = 1; lmaa = 0; lerptjoints = 0; break;
@@ -1669,30 +1416,26 @@ VARP(lightthreads, 0, 0, 16);
#define ALLOCLOCK(name, init) { if(lightmapping > 1) name = init(); if(!name) lightmapping = 1; }
#define FREELOCK(name, destroy) { if(name) { destroy(name); name = NULL; } }
-static void cleanuplocks()
-{
+static void cleanuplocks() {
FREELOCK(lightlock, SDL_DestroyMutex);
FREELOCK(tasklock, SDL_DestroyMutex);
FREELOCK(fullcond, SDL_DestroyCond);
FREELOCK(emptycond, SDL_DestroyCond);
}
-static void setupthreads(int numthreads)
-{
+static void setupthreads(int numthreads) {
loopi(2) lightmaptasks[i].setsize(0);
lightmapexts.setsize(0);
packidx = allocidx = 0;
lightmapping = numthreads;
- if(lightmapping > 1)
- {
+ if(lightmapping > 1) {
ALLOCLOCK(lightlock, SDL_CreateMutex);
ALLOCLOCK(tasklock, SDL_CreateMutex);
ALLOCLOCK(fullcond, SDL_CreateCond);
ALLOCLOCK(emptycond, SDL_CreateCond);
}
while(lightmapworkers.length() < lightmapping) lightmapworkers.add(new lightmapworker);
- loopi(lightmapping)
- {
+ loopi(lightmapping) {
lightmapworker *w = lightmapworkers[i];
w->reset();
if(lightmapping <= 1 || w->setupthread()) continue;
@@ -1703,28 +1446,23 @@ static void setupthreads(int numthreads)
if(lightmapping <= 1) cleanuplocks();
}
-static void cleanupthreads()
-{
+static void cleanupthreads() {
processtasks(true);
- if(lightmapping > 1)
- {
+ if(lightmapping > 1) {
SDL_LockMutex(tasklock);
loopv(lightmapworkers) lightmapworkers[i]->doneworking = true;
SDL_CondBroadcast(fullcond);
- loopv(lightmapworkers)
- {
+ loopv(lightmapworkers) {
lightmapworker *w = lightmapworkers[i];
if(w->needspace && w->spacecond) SDL_CondSignal(w->spacecond);
}
SDL_UnlockMutex(tasklock);
- loopv(lightmapworkers)
- {
+ loopv(lightmapworkers) {
lightmapworker *w = lightmapworkers[i];
if(w->thread) SDL_WaitThread(w->thread, NULL);
}
}
- loopv(lightmapexts)
- {
+ loopv(lightmapexts) {
lightmapext &e = lightmapexts[i];
setcubeext(*e.c, e.ext);
}
@@ -1733,10 +1471,8 @@ static void cleanupthreads()
lightmapping = 0;
}
-void calclight(int *quality)
-{
- if(!setlightmapquality(*quality))
- {
+void calclight(int *quality) {
+ if(!setlightmapquality(*quality)) {
conoutf(CON_ERROR, "valid range for calclight quality is -1..1");
return;
}
@@ -1763,8 +1499,7 @@ void calclight(int *quality)
Uint32 end = SDL_GetTicks();
if(timer) SDL_RemoveTimer(timer);
uint total = 0, lumels = 0;
- loopv(lightmaps)
- {
+ loopv(lightmaps) {
insertunlit(i);
if(!editmode) lightmaps[i].finalize();
total += lightmaps[i].lightmaps;
@@ -1786,8 +1521,7 @@ void calclight(int *quality)
COMMAND(calclight, "i");
-void clearlightmaps()
-{
+void clearlightmaps() {
if(noedit(true)) return;
renderprogress(0, "clearing lightmaps...");
resetlightmaps(false);
@@ -1798,10 +1532,8 @@ void clearlightmaps()
COMMAND(clearlightmaps, "");
-void setfullbrightlevel(int fullbrightlevel)
-{
- if(lightmaptexs.length() > LMID_BRIGHT)
- {
+void setfullbrightlevel(int fullbrightlevel) {
+ if(lightmaptexs.length() > LMID_BRIGHT) {
uchar bright[3] = { uchar(fullbrightlevel), uchar(fullbrightlevel), uchar(fullbrightlevel) };
createtexture(lightmaptexs[LMID_BRIGHT].id, 1, 1, bright, 0, 1);
}
@@ -1813,21 +1545,17 @@ VARF(fullbrightlevel, 0, 128, 255, setfullbrightlevel(fullbrightlevel));
vector<LightMapTexture> lightmaptexs;
-static void copylightmap(LightMap &lm, uchar *dst, size_t stride)
-{
+static void copylightmap(LightMap &lm, uchar *dst, size_t stride) {
const uchar *c = lm.data;
- loopi(LM_PACKH)
- {
+ loopi(LM_PACKH) {
memcpy(dst, c, lm.bpp*LM_PACKW);
c += lm.bpp*LM_PACKW;
dst += stride;
}
}
-void genreservedlightmaptexs()
-{
- while(lightmaptexs.length() < LMID_RESERVED)
- {
+void genreservedlightmaptexs() {
+ while(lightmaptexs.length() < LMID_RESERVED) {
LightMapTexture &tex = lightmaptexs.add();
tex.type = lightmaptexs.length()&1 ? LM_DIFFUSE : LM_BUMPMAP1;
glGenTextures(1, &tex.id);
@@ -1844,30 +1572,24 @@ void genreservedlightmaptexs()
createtexture(lightmaptexs[LMID_DARK1].id, 1, 1, &front, 0, 1);
}
-static void findunlit(int i)
-{
+static void findunlit(int i) {
LightMap &lm = lightmaps[i];
if(lm.unlitx>=0) return;
- else if((lm.type&LM_TYPE)==LM_BUMPMAP0)
- {
+ else if((lm.type&LM_TYPE)==LM_BUMPMAP0) {
if(i+1>=lightmaps.length() || (lightmaps[i+1].type&LM_TYPE)!=LM_BUMPMAP1) return;
}
else if((lm.type&LM_TYPE)!=LM_DIFFUSE) return;
uchar *data = lm.data;
- loop(y, 2) loop(x, LM_PACKW)
- {
- if(!data[0] && !data[1] && !data[2])
- {
+ loop(y, 2) loop(x, LM_PACKW) {
+ if(!data[0] && !data[1] && !data[2]) {
memcpy(data, ambientcolor.v, 3);
if((lm.type&LM_TYPE)==LM_BUMPMAP0) ((bvec *)lightmaps[i+1].data)[y*LM_PACKW + x] = bvec(128, 128, 255);
lm.unlitx = x;
lm.unlity = y;
return;
}
- if(data[0]==ambientcolor[0] && data[1]==ambientcolor[1] && data[2]==ambientcolor[2])
- {
- if((lm.type&LM_TYPE)!=LM_BUMPMAP0 || ((bvec *)lightmaps[i+1].data)[y*LM_PACKW + x] == bvec(128, 128, 255))
- {
+ if(data[0]==ambientcolor[0] && data[1]==ambientcolor[1] && data[2]==ambientcolor[2]) {
+ if((lm.type&LM_TYPE)!=LM_BUMPMAP0 || ((bvec *)lightmaps[i+1].data)[y*LM_PACKW + x] == bvec(128, 128, 255)) {
lm.unlitx = x;
lm.unlity = y;
return;
@@ -1880,13 +1602,10 @@ static void findunlit(int i)
VARF(roundlightmaptex, 0, 4, 16, { cleanuplightmaps(); initlights(); allchanged(); });
VARF(batchlightmaps, 0, 4, 256, { cleanuplightmaps(); initlights(); allchanged(); });
-void genlightmaptexs(int flagmask, int flagval)
-{
+void genlightmaptexs(int flagmask, int flagval) {
if(lightmaptexs.length() < LMID_RESERVED) genreservedlightmaptexs();
-
int remaining[LM_TYPE+1] = { 0 }, total = 0;
- loopv(lightmaps)
- {
+ loopv(lightmaps) {
LightMap &lm = lightmaps[i];
if(lm.tex >= 0 || (lm.type&flagmask)!=flagval) continue;
int type = lm.type&LM_TYPE;
@@ -1894,15 +1613,12 @@ void genlightmaptexs(int flagmask, int flagval)
total++;
if(lm.unlitx < 0) findunlit(i);
}
-
int sizelimit = (maxtexsize ? min(maxtexsize, hwtexsize) : hwtexsize)/max(LM_PACKW, LM_PACKH);
sizelimit = min(batchlightmaps, sizelimit*sizelimit);
- while(total)
- {
+ while(total) {
int type = LM_DIFFUSE;
LightMap *firstlm = NULL;
- loopv(lightmaps)
- {
+ loopv(lightmaps) {
LightMap &lm = lightmaps[i];
if(lm.tex >= 0 || (lm.type&flagmask) != flagval) continue;
type = lm.type&LM_TYPE;
@@ -1915,8 +1631,7 @@ void genlightmaptexs(int flagmask, int flagval)
used--;
int oldval = remaining[type];
remaining[type] -= 1<<used;
- if(remaining[type] && (2<<used) <= min(roundlightmaptex, sizelimit))
- {
+ if(remaining[type] && (2<<used) <= min(roundlightmaptex, sizelimit)) {
remaining[type] -= min(remaining[type], 1<<used);
used++;
}
@@ -1928,27 +1643,21 @@ void genlightmaptexs(int flagmask, int flagval)
int bpp = firstlm->bpp;
uchar *data = used ? new uchar[bpp*tex.w*tex.h] : NULL;
int offsetx = 0, offsety = 0;
- loopv(lightmaps)
- {
+ loopv(lightmaps) {
LightMap &lm = lightmaps[i];
if(lm.tex >= 0 || (lm.type&flagmask) != flagval || (lm.type&LM_TYPE) != type) continue;
-
lm.tex = lightmaptexs.length()-1;
lm.offsetx = offsetx;
lm.offsety = offsety;
- if(tex.unlitx < 0 && lm.unlitx >= 0)
- {
+ if(tex.unlitx < 0 && lm.unlitx >= 0) {
tex.unlitx = offsetx + lm.unlitx;
tex.unlity = offsety + lm.unlity;
}
-
if(data) copylightmap(lm, &data[bpp*(offsety*tex.w + offsetx)], bpp*tex.w);
-
offsetx += LM_PACKW;
if(offsetx >= tex.w) { offsetx = 0; offsety += LM_PACKH; }
if(offsety >= tex.h) break;
}
-
glGenTextures(1, &tex.id);
createtexture(tex.id, tex.w, tex.h, data ? data : firstlm->data, 3, 1, bpp==4 ? GL_RGBA : GL_RGB);
if(data) delete[] data;
@@ -1957,29 +1666,24 @@ void genlightmaptexs(int flagmask, int flagval)
bool brightengeom = false, shouldlightents = false;
-void clearlights()
-{
+void clearlights() {
clearlightcache();
const vector<extentity *> &ents = entities::getents();
- loopv(ents)
- {
+ loopv(ents) {
extentity &e = *ents[i];
e.light.color = vec(1, 1, 1);
e.light.dir = vec(0, 0, 1);
}
shouldlightents = false;
-
genlightmaptexs(LM_ALPHA, 0);
genlightmaptexs(LM_ALPHA, LM_ALPHA);
brightengeom = true;
}
-void lightent(extentity &e, float height)
-{
+void lightent(extentity &e, float height) {
if(e.type==ET_LIGHT) return;
float ambient = 0.0f;
- if(e.type==ET_MAPMODEL)
- {
+ if(e.type==ET_MAPMODEL) {
model *m = loadmodel(NULL, e.attr2);
if(m) height = m->above()*0.75f;
}
@@ -1988,24 +1692,18 @@ void lightent(extentity &e, float height)
lightreaching(target, e.light.color, e.light.dir, false, &e, ambient);
}
-void lightents(bool force)
-{
+void lightents(bool force) {
if(!force && !shouldlightents) return;
-
const vector<extentity *> &ents = entities::getents();
loopv(ents) lightent(*ents[i]);
-
shouldlightents = false;
}
-void initlights()
-{
- if((fullbright && editmode) || lightmaps.empty())
- {
+void initlights() {
+ if((fullbright && editmode) || lightmaps.empty()) {
clearlights();
return;
}
-
clearlightcache();
genlightmaptexs(LM_ALPHA, 0);
genlightmaptexs(LM_ALPHA, LM_ALPHA);
@@ -2013,49 +1711,39 @@ void initlights()
shouldlightents = true;
}
-void lightreaching(const vec &target, vec &color, vec &dir, bool fast, extentity *t, float ambient)
-{
- if((fullbright && editmode) || lightmaps.empty())
- {
+void lightreaching(const vec &target, vec &color, vec &dir, bool fast, extentity *t, float ambient) {
+ if((fullbright && editmode) || lightmaps.empty()) {
color = vec(1, 1, 1);
dir = vec(0, 0, 1);
return;
}
-
color = dir = vec(0, 0, 0);
const vector<extentity *> &ents = entities::getents();
const vector<int> &lights = checklightcache(int(target.x), int(target.y));
- loopv(lights)
- {
+ loopv(lights) {
extentity &e = *ents[lights[i]];
if(e.type != ET_LIGHT)
continue;
-
vec ray(target);
ray.sub(e.o);
float mag = ray.magnitude();
if(e.attr1 && mag >= float(e.attr1))
continue;
-
if(mag < 1e-4f) ray = vec(0, 0, -1);
- else
- {
+ else {
ray.div(mag);
if(shadowray(e.o, ray, mag, RAY_SHADOW | RAY_POLY, t) < mag)
continue;
}
-
float intensity = 1;
if(e.attr1)
intensity -= mag / float(e.attr1);
- if(e.attached && e.attached->type==ET_SPOTLIGHT)
- {
+ if(e.attached && e.attached->type==ET_SPOTLIGHT) {
vec spot = vec(e.attached->o).sub(e.o).normalize();
float maxatten = sincos360[clamp(int(e.attached->attr1), 1, 89)].x, spotatten = (ray.dot(spot) - maxatten) / (1 - maxatten);
if(spotatten <= 0) continue;
intensity *= spotatten;
}
-
vec lightcol = vec(e.attr2, e.attr3, e.attr4).mul(1.0f/255);
color.add(vec(lightcol).mul(intensity));
dir.add(vec(ray).mul(-intensity*lightcol.x*lightcol.y*lightcol.z));
@@ -2065,40 +1753,33 @@ void lightreaching(const vec &target, vec &color, vec &dir, bool fast, extentity
else dir.normalize();
}
-entity *brightestlight(const vec &target, const vec &dir)
-{
+entity *brightestlight(const vec &target, const vec &dir) {
const vector<extentity *> &ents = entities::getents();
const vector<int> &lights = checklightcache(int(target.x), int(target.y));
extentity *brightest = NULL;
float bintensity = 0;
- loopv(lights)
- {
+ loopv(lights) {
extentity &e = *ents[lights[i]];
if(e.type != ET_LIGHT || vec(e.o).sub(target).dot(dir)<0)
continue;
-
vec ray(target);
ray.sub(e.o);
float mag = ray.magnitude();
if(e.attr1 && mag >= float(e.attr1))
continue;
-
ray.div(mag);
if(shadowray(e.o, ray, mag, RAY_SHADOW | RAY_POLY) < mag)
continue;
float intensity = 1;
if(e.attr1)
intensity -= mag / float(e.attr1);
- if(e.attached && e.attached->type==ET_SPOTLIGHT)
- {
+ if(e.attached && e.attached->type==ET_SPOTLIGHT) {
vec spot = vec(e.attached->o).sub(e.o).normalize();
float maxatten = sincos360[clamp(int(e.attached->attr1), 1, 89)].x, spotatten = (ray.dot(spot) - maxatten) / (1 - maxatten);
if(spotatten <= 0) continue;
intensity *= spotatten;
}
-
- if(!brightest || intensity > bintensity)
- {
+ if(!brightest || intensity > bintensity) {
brightest = &e;
bintensity = intensity;
}
@@ -2106,10 +1787,8 @@ entity *brightestlight(const vec &target, const vec &dir)
return brightest;
}
-void dumplms()
-{
- loopv(lightmaps)
- {
+void dumplms() {
+ loopv(lightmaps) {
ImageData temp(LM_PACKW, LM_PACKH, lightmaps[i].bpp, lightmaps[i].data);
const char *map = game::getclientmap(), *name = strrchr(map, '/');
defformatstring(buf, "lightmap_%s_%d.png", name ? name+1 : map, i);
diff --git a/src/engine/lightmap.h b/src/engine/lightmap.h
index 0f00d61..d15c6a7 100644
--- a/src/engine/lightmap.h
+++ b/src/engine/lightmap.h
@@ -5,81 +5,62 @@
#define LM_PACKW 512
#define LM_PACKH 512
-struct PackNode
-{
+struct PackNode {
PackNode *child1, *child2;
ushort x, y, w, h;
int available;
-
PackNode() : child1(0), child2(0), x(0), y(0), w(LM_PACKW), h(LM_PACKH), available(min(LM_PACKW, LM_PACKH)) {}
PackNode(ushort x, ushort y, ushort w, ushort h) : child1(0), child2(0), x(x), y(y), w(w), h(h), available(min(w, h)) {}
-
- void clear()
- {
+ void clear() {
DELETEP(child1);
DELETEP(child2);
}
-
- ~PackNode()
- {
+ ~PackNode() {
clear();
}
-
bool insert(ushort &tx, ushort &ty, ushort tw, ushort th);
};
-enum
-{
+enum {
LM_DIFFUSE = 0,
LM_BUMPMAP0,
LM_BUMPMAP1,
LM_TYPE = 0x0F,
-
LM_ALPHA = 1<<4,
LM_FLAGS = 0xF0
};
-struct LightMap
-{
+struct LightMap {
int type, bpp, tex, offsetx, offsety;
PackNode packroot;
uint lightmaps, lumels;
int unlitx, unlity;
uchar *data;
-
LightMap()
: type(LM_DIFFUSE), bpp(3), tex(-1), offsetx(-1), offsety(-1),
lightmaps(0), lumels(0), unlitx(-1), unlity(-1),
- data(NULL)
- {
+ data(NULL) {
}
-
- ~LightMap()
- {
+ ~LightMap() {
if(data) delete[] data;
}
-
- void finalize()
- {
+ void finalize() {
packroot.clear();
packroot.available = 0;
}
-
void copy(ushort tx, ushort ty, uchar *src, ushort tw, ushort th);
bool insert(ushort &tx, ushort &ty, uchar *src, ushort tw, ushort th);
};
extern vector<LightMap> lightmaps;
-struct LightMapTexture
-{
+struct LightMapTexture {
int w, h, type;
GLuint id;
int unlitx, unlity;
-
LightMapTexture()
- : w(0), h(0), type(LM_DIFFUSE), id(0), unlitx(-1), unlity(-1)
- {}
+ : w(0), h(0), type(LM_DIFFUSE), id(0), unlitx(-1), unlity(-1) {
+ }
};
extern vector<LightMapTexture> lightmaptexs;
@@ -95,17 +76,14 @@ extern void brightencube(cube &c);
extern void setsurfaces(cube &c, const surfaceinfo *surfs, const vertinfo *verts, int numverts);
extern void setsurface(cube &c, int orient, const surfaceinfo &surf, const vertinfo *verts, int numverts);
-struct lerpvert
-{
+struct lerpvert {
vec normal;
vec2 tc;
-
bool operator==(const lerpvert &l) const { return tc == l.tc;; }
bool operator!=(const lerpvert &l) const { return tc != l.tc; }
};
-struct lerpbounds
-{
+struct lerpbounds {
const lerpvert *min;
const lerpvert *max;
float u, ustep;
@@ -121,10 +99,10 @@ extern void initlerpbounds(float u, float v, const lerpvert *lv, int numv, lerpb
extern void lerpnormal(float u, float v, const lerpvert *lv, int numv, lerpbounds &start, lerpbounds &end, vec &normal, vec &nstep);
#define CHECK_CALCLIGHT_PROGRESS_LOCKED(exit, show_calclight_progress, before, after) \
- if(check_calclight_progress) \
- { \
- if(!calclight_canceled) \
- { \
+ if(check_calclight_progress) { \
+ \
+ if(!calclight_canceled) { \
+ \
before; \
show_calclight_progress(); \
check_calclight_canceled(); \
diff --git a/src/engine/lightning.h b/src/engine/lightning.h
deleted file mode 100644
index cec993a..0000000
--- a/src/engine/lightning.h
+++ /dev/null
@@ -1,123 +0,0 @@
-#define MAXLIGHTNINGSTEPS 64
-#define LIGHTNINGSTEP 8
-int lnjitterx[2][MAXLIGHTNINGSTEPS], lnjittery[2][MAXLIGHTNINGSTEPS];
-int lnjitterframe = 0, lastlnjitter = 0;
-
-VAR(lnjittermillis, 0, 100, 1000);
-VAR(lnjitterradius, 0, 4, 100);
-FVAR(lnjitterscale, 0, 0.5f, 10);
-VAR(lnscrollmillis, 1, 300, 5000);
-FVAR(lnscrollscale, 0, 0.125f, 10);
-FVAR(lnblendpower, 0, 0.25f, 1000);
-
-static void calclightningjitter(int frame)
-{
- loopi(MAXLIGHTNINGSTEPS)
- {
- lnjitterx[lnjitterframe][i] = -lnjitterradius + rnd(2*lnjitterradius + 1);
- lnjittery[lnjitterframe][i] = -lnjitterradius + rnd(2*lnjitterradius + 1);
- }
-}
-
-static void setuplightning()
-{
- if(!lastlnjitter || lastmillis-lastlnjitter > lnjittermillis)
- {
- if(!lastlnjitter) calclightningjitter(lnjitterframe);
- lastlnjitter = lastmillis - (lastmillis%lnjittermillis);
- calclightningjitter(lnjitterframe ^= 1);
- }
-}
-
-static void renderlightning(Texture *tex, const vec &o, const vec &d, float sz)
-{
- vec step(d);
- step.sub(o);
- float len = step.magnitude();
- int numsteps = clamp(int(ceil(len/LIGHTNINGSTEP)), 2, MAXLIGHTNINGSTEPS);
- step.div(numsteps+1);
- int jitteroffset = detrnd(int(d.x+d.y+d.z), MAXLIGHTNINGSTEPS);
- vec cur(o), up, right;
- up.orthogonal(step);
- up.normalize();
- right.cross(up, step);
- right.normalize();
- float scroll = -float(lastmillis%lnscrollmillis)/lnscrollmillis,
- scrollscale = lnscrollscale*(LIGHTNINGSTEP*tex->ys)/(sz*tex->xs),
- blend = pow(clamp(float(lastmillis - lastlnjitter)/lnjittermillis, 0.0f, 1.0f), lnblendpower),
- jitter0 = (1-blend)*lnjitterscale*sz/lnjitterradius, jitter1 = blend*lnjitterscale*sz/lnjitterradius;
- gle::begin(GL_TRIANGLE_STRIP);
- loopj(numsteps)
- {
- vec next(cur);
- next.add(step);
- if(j+1==numsteps) next = d;
- else
- {
- int lj = (j+jitteroffset)%MAXLIGHTNINGSTEPS;
- next.add(vec(right).mul((jitter1*lnjitterx[lnjitterframe][lj] + jitter0*lnjitterx[lnjitterframe^1][lj])));
- next.add(vec(up).mul((jitter1*lnjittery[lnjitterframe][lj] + jitter0*lnjittery[lnjitterframe^1][lj])));
- }
- vec dir1 = next, dir2 = next, across;
- dir1.sub(cur);
- dir2.sub(camera1->o);
- across.cross(dir2, dir1).normalize().mul(sz);
- gle::attribf(cur.x-across.x, cur.y-across.y, cur.z-across.z);
- gle::attribf(scroll, 1);
- gle::attribf(cur.x+across.x, cur.y+across.y, cur.z+across.z);
- gle::attribf(scroll, 0);
- scroll += scrollscale;
- if(j+1==numsteps)
- {
- gle::attribf(next.x-across.x, next.y-across.y, next.z-across.z);
- gle::attribf(scroll, 1);
- gle::attribf(next.x+across.x, next.y+across.y, next.z+across.z);
- gle::attribf(scroll, 0);
- }
- cur = next;
- }
- gle::end();
-}
-
-struct lightningrenderer : listrenderer
-{
- lightningrenderer()
- : listrenderer("packages/particles/lightning.png", 2, PT_LIGHTNING|PT_TRACK|PT_GLARE)
- {}
-
- void startrender()
- {
- glDisable(GL_CULL_FACE);
- gle::defattrib(gle::ATTRIB_VERTEX, 3, GL_FLOAT);
- gle::defattrib(gle::ATTRIB_TEXCOORD0, 2, GL_FLOAT);
- }
-
- void endrender()
- {
- glEnable(GL_CULL_FACE);
- }
-
- void update()
- {
- setuplightning();
- }
-
- void seedemitter(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int gravity)
- {
- pe.maxfade = max(pe.maxfade, fade);
- pe.extendbb(o, size);
- pe.extendbb(d, size);
- }
-
- void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts)
- {
- blend = min(blend<<2, 255);
- if(type&PT_MOD) //multiply alpha into color
- gle::colorub((p->color.r*blend)>>8, (p->color.g*blend)>>8, (p->color.b*blend)>>8);
- else
- gle::color(p->color, blend);
- renderlightning(tex, o, d, p->size);
- }
-};
-static lightningrenderer lightnings;
-
diff --git a/src/engine/main.cpp b/src/engine/main.cpp
index 5d264ed..a059c13 100644
--- a/src/engine/main.cpp
+++ b/src/engine/main.cpp
@@ -10,8 +10,7 @@ float speedmodifier = 0.0f;
extern void cleargamma();
-void cleanup()
-{
+void cleanup() {
cleanupserver();
SDL_ShowCursor(SDL_TRUE);
SDL_SetRelativeMouseMode(SDL_FALSE);
@@ -28,8 +27,7 @@ void cleanup()
extern void writeinitcfg();
-void quit() // normal exit
-{
+void quit() { // normal exit {
writeinitcfg();
writeservercfg();
abortconnect();
@@ -40,20 +38,14 @@ void quit() // normal exit
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
- {
+ 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))
- {
+ 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);
@@ -63,7 +55,6 @@ void fatal(const char *s, ...) // failure exit
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Cube 2: Sauerbraten fatal error", msg, NULL);
}
}
-
exit(EXIT_FAILURE);
}
@@ -73,10 +64,8 @@ dynent *player = NULL;
int initing = NOT_INITING;
-bool initwarning(const char *desc, int level, int type)
-{
- if(initing < level)
- {
+bool initwarning(const char *desc, int level, int type) {
+ if(initing < level) {
addchange(desc, type);
return true;
}
@@ -100,8 +89,7 @@ VARF(scr_h, SCR_MINH, -1, SCR_MAXH, initwarning("screen resolution"));
VARF(depthbits, 0, 0, 32, initwarning("depth-buffer precision"));
VARF(fsaa, -1, -1, 16, initwarning("anti-aliasing"));
-void writeinitcfg()
-{
+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");
@@ -124,8 +112,7 @@ void writeinitcfg()
COMMAND(quit, "");
-static void getbackgroundres(int &w, int &h)
-{
+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;
@@ -139,31 +126,26 @@ Texture *backgroundmapshot = NULL;
string backgroundmapname = "";
char *backgroundmapinfo = NULL;
-void setbackgroundinfo(const char *caption = NULL, Texture *mapshot = NULL, const char *mapname = NULL, const char *mapinfo = 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)
- {
+ if(mapinfo != backgroundmapinfo) {
DELETEA(backgroundmapinfo);
if(mapinfo) backgroundmapinfo = newstring(mapinfo);
}
}
-void restorebackground(bool force = false)
-{
- if(renderedframe)
- {
+void restorebackground(bool force = false) {
+ 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)
-{
+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);
@@ -172,48 +154,36 @@ void bgquad(float x, float y, float w, float h, float tx = 0, float ty = 0, floa
gle::end();
}
-void renderbackground(const char *caption, Texture *mapshot, const char *mapname, const char *mapinfo, bool restore, bool force)
-{
+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)
- {
+ 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)
- {
+ 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)
- {
+ 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);
@@ -221,8 +191,7 @@ void renderbackground(const char *caption, Texture *mapshot, const char *mapname
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)
- {
+ 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;
@@ -233,23 +202,19 @@ void renderbackground(const char *caption, Texture *mapshot, const char *mapname
draw_text(caption, 0, 0);
pophudmatrix();
}
- if(mapshot || mapname)
- {
+ 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)
- {
+ if(mapinfo) {
int mw, mh;
text_bounds(mapinfo, mw, mh, infowidth);
x -= 0.5f*(mw*msz + FONTH*msz);
}
- if(mapshot && mapshot!=notexture)
- {
+ if(mapshot && mapshot!=notexture) {
glBindTexture(GL_TEXTURE_2D, mapshot->id);
bgquad(x, y, sz, sz);
}
- else
- {
+ else {
int qw, qh;
text_bounds("?", qw, qh);
float qsz = sz*0.5f/max(qw, qh);
@@ -263,8 +228,7 @@ void renderbackground(const char *caption, Texture *mapshot, const char *mapname
}
settexture("data/mapshot_frame.png", 3);
bgquad(x, y, sz, sz);
- if(mapname)
- {
+ if(mapname) {
int tw = text_width(mapname);
float tsz = sz/(8*FONTH),
tx = 0.9f*sz - tw*tsz, ty = 0.9f*sz - FONTH*tsz;
@@ -276,8 +240,7 @@ void renderbackground(const char *caption, Texture *mapshot, const char *mapname
draw_text(mapname, 0, 0);
pophudmatrix();
}
- if(mapinfo)
- {
+ if(mapinfo) {
pushhudmatrix();
hudmatrix.translate(x+sz+FONTH*msz, y, 0);
hudmatrix.scale(msz, msz, 1);
@@ -289,7 +252,6 @@ void renderbackground(const char *caption, Texture *mapshot, const char *mapname
glDisable(GL_BLEND);
if(!restore) swapbuffers(false);
}
-
if(!restore) setbackgroundinfo(caption, mapshot, mapname, mapinfo);
}
@@ -297,42 +259,31 @@ VAR(progressbackground, 0, 0, 1);
float loadprogress = 0;
-void renderprogress(float bar, const char *text, GLuint tex, bool background) // also used during loading
-{
+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)
- {
+ 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,
@@ -340,10 +291,8 @@ void renderprogress(float bar, const char *text, GLuint tex, bool background)
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,
@@ -351,29 +300,24 @@ void renderprogress(float bar, const char *text, GLuint tex, bool background)
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)
- {
+ 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)
- {
+ if(text) {
int tw = text_width(text);
float tsz = bh*0.8f/FONTH;
if(tw*tsz > mw) tsz = mw/tw;
@@ -384,22 +328,17 @@ void renderprogress(float bar, const char *text, GLuint tex, bool background)
draw_text(text, 0, 0);
pophudmatrix();
}
-
glDisable(GL_BLEND);
-
- if(tex)
- {
+ 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);
}
@@ -407,25 +346,20 @@ int keyrepeatmask = 0, textinputmask = 0;
Uint32 textinputtime = 0;
VAR(textinputfilter, 0, 5, 1000);
-void keyrepeat(bool on, int mask)
-{
+void keyrepeat(bool on, int mask) {
if(on) keyrepeatmask |= mask;
else keyrepeatmask &= ~mask;
}
-void textinput(bool on, int mask)
-{
- if(on)
- {
- if(!textinputmask)
- {
+void textinput(bool on, int mask) {
+ if(on) {
+ if(!textinputmask) {
SDL_StartTextInput();
textinputtime = SDL_GetTicks();
}
textinputmask |= mask;
}
- else if(textinputmask)
- {
+ else if(textinputmask) {
textinputmask &= ~mask;
if(!textinputmask) SDL_StopTextInput();
}
@@ -439,34 +373,27 @@ bool shouldgrab = false, grabinput = false, minimized = false, canrelativemouse
VAR(sdl_xgrab_bug, 0, 0, 1);
#endif
-void inputgrab(bool on, bool delay = false)
-{
+void inputgrab(bool on, bool delay = false) {
#ifdef SDL_VIDEO_DRIVER_X11
bool wasrelativemouse = relativemouse;
#endif
- if(on)
- {
+ if(on) {
SDL_ShowCursor(SDL_FALSE);
- if(canrelativemouse && userelativemouse)
- {
- if(SDL_SetRelativeMouseMode(SDL_TRUE) >= 0)
- {
+ if(canrelativemouse && userelativemouse) {
+ if(SDL_SetRelativeMouseMode(SDL_TRUE) >= 0) {
SDL_SetWindowGrab(screen, SDL_TRUE);
relativemouse = true;
}
- else
- {
+ else {
SDL_SetWindowGrab(screen, SDL_FALSE);
canrelativemouse = false;
relativemouse = false;
}
}
}
- else
- {
+ else {
SDL_ShowCursor(SDL_TRUE);
- if(relativemouse)
- {
+ if(relativemouse) {
SDL_SetWindowGrab(screen, SDL_FALSE);
SDL_SetRelativeMouseMode(SDL_FALSE);
relativemouse = false;
@@ -475,15 +402,12 @@ void inputgrab(bool on, bool delay = false)
shouldgrab = delay;
#ifdef SDL_VIDEO_DRIVER_X11
- if((relativemouse || wasrelativemouse) && sdl_xgrab_bug)
- {
+ 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)
- {
+ 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);
}
@@ -495,17 +419,14 @@ void inputgrab(bool on, bool delay = false)
bool initwindowpos = false;
-void setfullscreen(bool enable)
-{
+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)
- {
+ if(!enable) {
SDL_SetWindowSize(screen, scr_w, scr_h);
- if(initwindowpos)
- {
+ if(initwindowpos) {
int winx = SDL_WINDOWPOS_CENTERED, winy = SDL_WINDOWPOS_CENTERED;
SDL_SetWindowPosition(screen, winx, winy);
initwindowpos = false;
@@ -519,74 +440,62 @@ VARF(fullscreen, 0, 0, 1, setfullscreen(fullscreen!=0));
VARF(fullscreen, 0, 1, 1, setfullscreen(fullscreen!=0));
#endif
-void resetfullscreen()
-{
+void resetfullscreen() {
setfullscreen(false);
setfullscreen(true);
}
VARF(fullscreendesktop, 0, 0, 1, if(fullscreen) resetfullscreen());
-void screenres(int w, int h)
-{
+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)
- {
+ if(screen) {
+ if(fullscreendesktop) {
scr_w = min(scr_w, desktopw);
scr_h = min(scr_h, desktoph);
}
- if(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN)
- {
+ if(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN) {
if(fullscreendesktop) gl_resize();
else resetfullscreen();
initwindowpos = true;
}
- else
- {
+ else {
SDL_SetWindowSize(screen, scr_w, scr_h);
SDL_SetWindowPosition(screen, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
initwindowpos = false;
}
}
- else
- {
+ else {
initwarning("screen resolution");
}
}
ICOMMAND(screenres, "ii", (int *w, int *h), screenres(*w, *h));
-static void setgamma(int val)
-{
+static void setgamma(int val) {
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,
-{
+VARFNP(gamma, reqgamma, 30, 100, 300, {
if(initing || reqgamma == curgamma) return;
curgamma = reqgamma;
setgamma(curgamma);
});
-void restoregamma()
-{
+void restoregamma() {
if(initing || reqgamma == 100) return;
curgamma = reqgamma;
setgamma(curgamma);
}
-void cleargamma()
-{
+void cleargamma() {
if(curgamma != 100 && screen) SDL_SetWindowBrightness(screen, 1.0f);
}
int curvsync = -1;
-void restorevsync()
-{
+void restorevsync() {
if(initing || !glcontext) return;
extern int vsync, vsynctear;
if(!SDL_GL_SetSwapInterval(vsync ? (vsynctear ? -1 : 1) : 0))
@@ -596,40 +505,31 @@ void restorevsync()
VARFP(vsync, 0, 0, 1, restorevsync());
VARFP(vsynctear, 0, 0, 1, { if(vsync) restorevsync(); });
-void setupscreen()
-{
- if(glcontext)
- {
+void setupscreen() {
+ if(glcontext) {
SDL_GL_DeleteContext(glcontext);
glcontext = NULL;
}
- if(screen)
- {
+ 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)
- {
+ 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)
- {
+ if(fullscreen) {
+ if(fullscreendesktop) {
winw = desktopw;
winh = desktoph;
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
@@ -637,42 +537,35 @@ void setupscreen()
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[] =
- {
+ 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)
- {
+ if(!fsaa) {
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
}
- loopi(sizeof(configs)/sizeof(configs[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)
- {
+ 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]))
- {
+ 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);
@@ -684,24 +577,18 @@ void setupscreen()
}
if(!screen) fatal("failed to create OpenGL window: %s", SDL_GetError());
else if(!glcontext) fatal("failed to create OpenGL context: %s", SDL_GetError());
- else
- {
+ 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()
-{
+void resetgl() {
clearchanges(CHANGE_GFX);
-
renderbackground("resetting OpenGL");
-
extern void cleanupva();
extern void cleanupparticles();
extern void cleanupdecals();
@@ -719,11 +606,9 @@ void resetgl()
cleanshadowmap();
cleanupshaders();
cleanupgl();
-
setupscreen();
inputgrab(grabinput);
gl_init();
-
inbetweenframes = false;
if(!reloadtexture(*notexture) ||
!reloadtexture("data/logo.png") ||
@@ -750,13 +635,10 @@ COMMAND(resetgl, "");
static queue<SDL_Event, 32> events;
-static inline bool filterevent(const SDL_Event &event)
-{
- switch(event.type)
- {
+static inline bool filterevent(const SDL_Event &event) {
+ switch(event.type) {
case SDL_MOUSEMOTION:
- if(grabinput && !relativemouse && !(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN))
- {
+ 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
}
@@ -765,10 +647,8 @@ static inline bool filterevent(const SDL_Event &event)
return true;
}
-template <int SIZE> static inline bool pumpevents(queue<SDL_Event, SIZE> &events)
-{
- while(events.empty())
- {
+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);
@@ -781,14 +661,11 @@ template <int SIZE> static inline bool pumpevents(queue<SDL_Event, SIZE> &events
static int interceptkeysym = 0;
-static int interceptevents(void *data, SDL_Event *event)
-{
- switch(event->type)
- {
+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)
- {
+ if(event->key.keysym.sym == interceptkeysym) {
interceptkeysym = -interceptkeysym;
return 0;
}
@@ -797,20 +674,16 @@ static int interceptevents(void *data, SDL_Event *event)
return 1;
}
-static void clearinterceptkey()
-{
+static void clearinterceptkey() {
SDL_DelEventWatch(interceptevents, NULL);
interceptkeysym = 0;
}
-bool interceptkey(int sym)
-{
- if(!interceptkeysym)
- {
+bool interceptkey(int sym) {
+ if(!interceptkeysym) {
interceptkeysym = sym;
SDL_FilterEvents(interceptevents, NULL);
- if(interceptkeysym < 0)
- {
+ if(interceptkeysym < 0) {
interceptkeysym = 0;
return true;
}
@@ -818,8 +691,7 @@ bool interceptkey(int sym)
}
else if(abs(interceptkeysym) != sym) interceptkeysym = sym;
SDL_PumpEvents();
- if(interceptkeysym < 0)
- {
+ if(interceptkeysym < 0) {
clearinterceptkey();
interceptkeysym = sym;
SDL_FilterEvents(interceptevents, NULL);
@@ -829,24 +701,19 @@ bool interceptkey(int sym)
return false;
}
-static void ignoremousemotion()
-{
+static void ignoremousemotion() {
SDL_PumpEvents();
SDL_FlushEvent(SDL_MOUSEMOTION);
}
-static void resetmousemotion()
-{
- if(grabinput && !relativemouse && !(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN))
- {
+static void resetmousemotion() {
+ 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))
- {
+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;
@@ -855,46 +722,35 @@ static void checkmousemotion(int &dx, int &dy)
}
}
-void checkinput()
-{
+void checkinput() {
if(interceptkeysym) clearinterceptkey();
//int lasttype = 0, lastbut = 0;
bool mousemoved = false;
int focused = 0;
- while(pumpevents(events))
- {
+ 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)
- {
+ switch(event.type) {
case SDL_QUIT:
quit();
return;
-
case SDL_TEXTINPUT:
- if(textinputmask && int(event.text.timestamp-textinputtime) >= textinputfilter)
- {
+ 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)
- {
+ switch(event.window.event) {
case SDL_WINDOWEVENT_CLOSE:
quit();
break;
-
case SDL_WINDOWEVENT_FOCUS_GAINED:
shouldgrab = true;
break;
@@ -902,30 +758,23 @@ void checkinput()
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:
- {
+ case SDL_WINDOWEVENT_SIZE_CHANGED: {
SDL_GetWindowSize(screen, &screenw, &screenh);
- if(!fullscreendesktop || !(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN))
- {
+ if(!fullscreendesktop || !(SDL_GetWindowFlags(screen) & SDL_WINDOW_FULLSCREEN)) {
scr_w = clamp(screenw, SCR_MINW, SCR_MAXW);
scr_h = clamp(screenh, SCR_MINH, SCR_MAXH);
}
@@ -934,10 +783,8 @@ void checkinput()
}
}
break;
-
case SDL_MOUSEMOTION:
- if(grabinput)
- {
+ if(grabinput) {
int dx = event.motion.xrel, dy = event.motion.yrel;
checkmousemotion(dx, dy);
if(!g3d_movecursor(dx, dy)) mousemove(dx, dy);
@@ -945,12 +792,10 @@ void checkinput()
}
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)
- {
+ 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;
@@ -960,7 +805,6 @@ void checkinput()
//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); }
@@ -971,8 +815,7 @@ void checkinput()
if(mousemoved) resetmousemotion();
}
-void swapbuffers(bool overlay)
-{
+void swapbuffers(bool overlay) {
gle::disable();
SDL_GL_SwapWindow(screen);
}
@@ -980,23 +823,19 @@ void swapbuffers(bool overlay)
VAR(menufps, 0, 60, 1000);
VARP(maxfps, 0, 200, 1000);
-void limitfps(int &millis, int curmillis)
-{
+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
- {
+ else {
fpserror += 1000%limit;
- if(fpserror >= limit)
- {
+ if(fpserror >= limit) {
++delay;
fpserror -= limit;
}
- if(delay > 0)
- {
+ if(delay > 0) {
SDL_Delay(delay);
millis += delay;
}
@@ -1007,36 +846,30 @@ void limitfps(int &millis, int curmillis)
int fpspos = 0, fpshistory[MAXFPSHISTORY];
-void resetfpshistory()
-{
+void resetfpshistory() {
loopi(MAXFPSHISTORY) fpshistory[i] = 1;
fpspos = 0;
}
-void updatefpshistory(int millis)
-{
+void updatefpshistory(int millis) {
fpshistory[fpspos++] = max(1, min(1000, millis));
if(fpspos>=MAXFPSHISTORY) fpspos = 0;
}
-void getfps(int &fps, int &bestdiff, int &worstdiff)
-{
+void getfps(int &fps, int &bestdiff, int &worstdiff) {
int total = fpshistory[MAXFPSHISTORY-1], best = total, worst = total;
- loopi(MAXFPSHISTORY-1)
- {
+ 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)
-{
+void getfps_(int *raw) {
int fps, bestdiff, worstdiff;
if(*raw) fps = 1000/fpshistory[(fpspos+MAXFPSHISTORY-1)%MAXFPSHISTORY];
else getfps(fps, bestdiff, worstdiff);
@@ -1047,8 +880,7 @@ COMMANDN(getfps, getfps_, "i");
bool inbetweenframes = false, renderedframe = true;
-static bool findarg(int argc, char **argv, const char *str)
-{
+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;
}
@@ -1058,8 +890,7 @@ static void clockreset() { clockrealbase = SDL_GetTicks(); clockvirtbase = total
VARFP(clockerror, 990000, 1000000, 1010000, clockreset());
VARFP(clockfix, 0, 0, 1, clockreset());
-int getclockmillis()
-{
+int getclockmillis() {
int millis = SDL_GetTicks() - clockrealbase;
if(clockfix) millis = int(millis*(double(clockerror)/1000000));
millis += clockvirtbase;
@@ -1068,33 +899,26 @@ int getclockmillis()
VAR(numcpus, 1, 1, 16);
-int main(int argc, char **argv)
-{
+int main(int argc, char **argv) {
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')
- {
+ 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])
- {
+ 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':
- {
+ case 'k': {
const char *dir = addpackagedir(&argv[i][2]);
if(dir) logoutf("Adding package directory: %s", dir);
break;
@@ -1110,8 +934,7 @@ int main(int argc, char **argv)
case 't': fullscreen = atoi(&argv[i][2]); break;
case 's': /* compat, ignore */ break;
case 'f': /* compat, ignore */ break;
- case 'l':
- {
+ case 'l': {
char pkgdir[] = "packages/";
load = strstr(path(&argv[i][2]), path(pkgdir));
if(load) load += sizeof(pkgdir)-1;
@@ -1124,13 +947,9 @@ int main(int argc, char **argv)
else gameargs.add(argv[i]);
}
initing = NOT_INITING;
-
numcpus = clamp(SDL_GetCPUCount(), 1, 16);
-
- if(dedicated <= 1)
- {
+ 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
@@ -1140,46 +959,37 @@ int main(int argc, char **argv)
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");
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");
@@ -1189,52 +999,35 @@ int main(int argc, char **argv)
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))
- {
+ 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)
- {
+ if(load) {
logoutf("init: localconnect");
//localconnect();
game::changemap(load);
}
-
if(initscript) execute(initscript);
-
resetfpshistory();
-
inputgrab(grabinput = true);
ignoremousemotion();
-
- for(;;)
- {
+ for(;;) {
static int frames = 0;
int millis = getclockmillis();
limitfps(millis, totalmillis);
@@ -1248,37 +1041,26 @@ int main(int argc, char **argv)
lastmillis += curtime;
totalmillis = millis;
updatetime();
-
checkinput();
menuprocess();
tryedit();
-
if(lastmillis) game::updateworld();
-
checksleep(lastmillis);
-
serverslice(false, 0);
-
if(frames) updatefpshistory(elapsedtime);
frames++;
-
// miscellaneous general game effects
recomputecamera();
updateparticles();
updatesounds();
-
if(minimized) continue;
-
inbetweenframes = false;
-
glClearColor(0,0,0,1);///TODO
-
if(mainmenu) gl_drawmainmenu();
else gl_drawframe();
swapbuffers();
renderedframe = inbetweenframes = true;
}
-
ASSERT(0);
return EXIT_FAILURE;
}
diff --git a/src/engine/master.cpp b/src/engine/master.cpp
index 2bf1dba..c1d3e20 100644
--- a/src/engine/master.cpp
+++ b/src/engine/master.cpp
@@ -22,15 +22,13 @@
FILE *logfile = NULL;
-struct userinfo
-{
+struct userinfo {
char *name;
void *pubkey;
};
hashnameset<userinfo> users;
-void adduser(char *name, char *pubkey)
-{
+void adduser(char *name, char *pubkey) {
name = newstring(name);
userinfo &u = users[name];
u.name = name;
@@ -38,8 +36,7 @@ void adduser(char *name, char *pubkey)
}
COMMAND(adduser, "ss");
-void clearusers()
-{
+void clearusers() {
enumerate(users, userinfo, u, { delete[] u.name; freepubkey(u.pubkey); });
users.clear();
}
@@ -47,16 +44,14 @@ COMMAND(clearusers, "");
vector<ipmask> bans, servbans, gbans;
-void clearbans()
-{
+void clearbans() {
bans.shrink(0);
servbans.shrink(0);
gbans.shrink(0);
}
COMMAND(clearbans, "");
-void addban(vector<ipmask> &bans, const char *name)
-{
+void addban(vector<ipmask> &bans, const char *name) {
ipmask ban;
ban.parse(name);
bans.add(ban);
@@ -65,21 +60,18 @@ ICOMMAND(ban, "s", (char *name), addban(bans, name));
ICOMMAND(servban, "s", (char *name), addban(servbans, name));
ICOMMAND(gban, "s", (char *name), addban(gbans, name));
-bool checkban(vector<ipmask> &bans, enet_uint32 host)
-{
+bool checkban(vector<ipmask> &bans, enet_uint32 host) {
loopv(bans) if(bans[i].check(host)) return true;
return false;
}
-struct authreq
-{
+struct authreq {
enet_uint32 reqtime;
uint id;
void *answer;
};
-struct gameserver
-{
+struct gameserver {
ENetAddress address;
string ip;
int port, numpings;
@@ -87,30 +79,21 @@ struct gameserver
};
vector<gameserver *> gameservers;
-struct messagebuf
-{
+struct messagebuf {
vector<messagebuf *> &owner;
vector<char> buf;
int refs;
-
messagebuf(vector<messagebuf *> &owner) : owner(owner), refs(0) {}
-
const char *getbuf() { return buf.getbuf(); }
int length() { return buf.length(); }
void purge();
-
- bool equals(const messagebuf &m) const
- {
+ bool equals(const messagebuf &m) const {
return buf.length() == m.buf.length() && !memcmp(buf.getbuf(), m.buf.getbuf(), buf.length());
}
-
- bool endswith(const messagebuf &m) const
- {
+ bool endswith(const messagebuf &m) const {
return buf.length() >= m.buf.length() && !memcmp(&buf[buf.length() - m.buf.length()], m.buf.getbuf(), m.buf.length());
}
-
- void concat(const messagebuf &m)
- {
+ void concat(const messagebuf &m) {
if(buf.length() && buf.last() == '\0') buf.pop();
buf.put(m.buf.getbuf(), m.buf.length());
}
@@ -118,8 +101,7 @@ struct messagebuf
vector<messagebuf *> gameserverlists, gbanlists;
bool updateserverlist = true;
-struct client
-{
+struct client {
ENetAddress address;
ENetSocket socket;
char input[INPUT_LIMIT];
@@ -132,7 +114,6 @@ struct client
vector<authreq> authreqs;
bool shouldpurge;
bool registeredserver;
-
client() : message(NULL), inputpos(0), outputpos(0), servport(-1), lastauth(0), shouldpurge(false), registeredserver(false) {}
};
vector<client *> clients;
@@ -142,8 +123,7 @@ ENetSocket serversocket = ENET_SOCKET_NULL;
time_t starttime;
enet_uint32 servtime = 0;
-void fatal(const char *fmt, ...)
-{
+void fatal(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
vfprintf(logfile, fmt, args);
@@ -152,14 +132,12 @@ void fatal(const char *fmt, ...)
exit(EXIT_FAILURE);
}
-void conoutfv(int type, const char *fmt, va_list args)
-{
+void conoutfv(int type, const char *fmt, va_list args) {
vfprintf(logfile, fmt, args);
fputc('\n', logfile);
}
-void purgeclient(int n)
-{
+void purgeclient(int n) {
client &c = *clients[n];
if(c.message) c.message->purge();
enet_socket_destroy(c.socket);
@@ -167,27 +145,23 @@ void purgeclient(int n)
clients.remove(n);
}
-void output(client &c, const char *msg, int len = 0)
-{
+void output(client &c, const char *msg, int len = 0) {
if(!len) len = strlen(msg);
c.output.put(msg, len);
}
-void outputf(client &c, const char *fmt, ...)
-{
+void outputf(client &c, const char *fmt, ...) {
string msg;
va_list args;
va_start(args, fmt);
vformatstring(msg, fmt, args);
va_end(args);
-
output(c, msg);
}
ENetSocket pingsocket = ENET_SOCKET_NULL;
-bool setuppingsocket(ENetAddress *address)
-{
+bool setuppingsocket(ENetAddress *address) {
if(pingsocket != ENET_SOCKET_NULL) return true;
pingsocket = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
if(pingsocket == ENET_SOCKET_NULL) return false;
@@ -196,14 +170,11 @@ bool setuppingsocket(ENetAddress *address)
return true;
}
-void setupserver(int port, const char *ip = NULL)
-{
+void setupserver(int port, const char *ip = NULL) {
ENetAddress address;
address.host = ENET_HOST_ANY;
address.port = port;
-
- if(ip)
- {
+ if(ip) {
if(enet_address_set_host(&address, ip)<0)
fatal("failed to resolve server address: %s", ip);
}
@@ -217,23 +188,19 @@ void setupserver(int port, const char *ip = NULL)
fatal("failed to make server socket non-blocking");
if(!setuppingsocket(&address))
fatal("failed to create ping socket");
-
enet_time_set(0);
-
starttime = time(NULL);
char *ct = ctime(&starttime);
if(strchr(ct, '\n')) *strchr(ct, '\n') = '\0';
conoutf("*** Starting master server on %s %d at %s ***", ip ? ip : "localhost", port, ct);
}
-void genserverlist()
-{
+void genserverlist() {
if(!updateserverlist) return;
while(gameserverlists.length() && gameserverlists.last()->refs<=0)
delete gameserverlists.pop();
messagebuf *l = new messagebuf(gameserverlists);
- loopv(gameservers)
- {
+ loopv(gameservers) {
gameserver &s = *gameservers[i];
if(!s.lastpong) continue;
defformatstring(cmd, "addserver %s %d\n", s.ip, s.port);
@@ -244,67 +211,56 @@ void genserverlist()
updateserverlist = false;
}
-void gengbanlist()
-{
+void gengbanlist() {
messagebuf *l = new messagebuf(gbanlists);
const char *header = "cleargbans\n";
l->buf.put(header, strlen(header));
string cmd = "addgban ";
int cmdlen = strlen(cmd);
- loopv(gbans)
- {
+ loopv(gbans) {
ipmask &b = gbans[i];
l->buf.put(cmd, cmdlen + b.print(&cmd[cmdlen]));
l->buf.add('\n');
}
- if(gbanlists.length() && gbanlists.last()->equals(*l))
- {
+ if(gbanlists.length() && gbanlists.last()->equals(*l)) {
delete l;
return;
}
while(gbanlists.length() && gbanlists.last()->refs<=0)
delete gbanlists.pop();
- loopv(gbanlists)
- {
+ loopv(gbanlists) {
messagebuf *m = gbanlists[i];
if(m->refs > 0 && !m->endswith(*l)) m->concat(*l);
}
gbanlists.add(l);
- loopv(clients)
- {
+ loopv(clients) {
client &c = *clients[i];
- if(c.servport >= 0 && !c.message)
- {
+ if(c.servport >= 0 && !c.message) {
c.message = l;
c.message->refs++;
}
}
}
-void addgameserver(client &c)
-{
+void addgameserver(client &c) {
if(gameservers.length() >= SERVER_LIMIT) return;
int dups = 0;
- loopv(gameservers)
- {
+ loopv(gameservers) {
gameserver &s = *gameservers[i];
if(s.address.host != c.address.host) continue;
++dups;
- if(s.port == c.servport)
- {
+ if(s.port == c.servport) {
s.lastping = 0;
s.numpings = 0;
return;
}
}
- if(dups >= SERVER_DUP_LIMIT)
- {
+ if(dups >= SERVER_DUP_LIMIT) {
outputf(c, "failreg too many servers on ip\n");
return;
}
string hostname;
- if(enet_address_get_host_ip(&c.address, hostname, sizeof(hostname)) < 0)
- {
+ if(enet_address_get_host_ip(&c.address, hostname, sizeof(hostname)) < 0) {
outputf(c, "failreg failed resolving ip\n");
return;
}
@@ -317,10 +273,8 @@ void addgameserver(client &c)
s.lastping = s.lastpong = 0;
}
-client *findclient(gameserver &s)
-{
- loopv(clients)
- {
+client *findclient(gameserver &s) {
+ loopv(clients) {
client &c = *clients[i];
if(s.address.host == c.address.host && s.port == c.servport)
return &c;
@@ -328,37 +282,29 @@ client *findclient(gameserver &s)
return NULL;
}
-void servermessage(gameserver &s, const char *msg)
-{
+void servermessage(gameserver &s, const char *msg) {
client *c = findclient(s);
if(c) outputf(*c, msg);
}
-void checkserverpongs()
-{
+void checkserverpongs() {
ENetBuffer buf;
ENetAddress addr;
static uchar pong[MAXTRANS];
- for(;;)
- {
+ for(;;) {
buf.data = pong;
buf.dataLength = sizeof(pong);
int len = enet_socket_receive(pingsocket, &addr, &buf, 1);
if(len <= 0) break;
- loopv(gameservers)
- {
+ loopv(gameservers) {
gameserver &s = *gameservers[i];
- if(s.address.host == addr.host && s.address.port == addr.port)
- {
- if(s.lastping && (!s.lastpong || ENET_TIME_GREATER(s.lastping, s.lastpong)))
- {
+ if(s.address.host == addr.host && s.address.port == addr.port) {
+ if(s.lastping && (!s.lastpong || ENET_TIME_GREATER(s.lastping, s.lastpong))) {
client *c = findclient(s);
- if(c)
- {
+ if(c) {
c->registeredserver = true;
outputf(*c, "succreg\n");
- if(!c->message && gbanlists.length())
- {
+ if(!c->message && gbanlists.length()) {
c->message = gbanlists.last();
c->message->refs++;
}
@@ -372,39 +318,30 @@ void checkserverpongs()
}
}
-void bangameservers()
-{
- loopvrev(gameservers) if(checkban(servbans, gameservers[i]->address.host))
- {
+void bangameservers() {
+ loopvrev(gameservers) if(checkban(servbans, gameservers[i]->address.host)) {
delete gameservers.remove(i);
updateserverlist = true;
}
}
-void checkgameservers()
-{
+void checkgameservers() {
ENetBuffer buf;
- loopv(gameservers)
- {
+ loopv(gameservers) {
gameserver &s = *gameservers[i];
- if(s.lastping && s.lastpong && ENET_TIME_LESS_EQUAL(s.lastping, s.lastpong))
- {
- if(ENET_TIME_DIFFERENCE(servtime, s.lastpong) > KEEPALIVE_TIME)
- {
+ if(s.lastping && s.lastpong && ENET_TIME_LESS_EQUAL(s.lastping, s.lastpong)) {
+ if(ENET_TIME_DIFFERENCE(servtime, s.lastpong) > KEEPALIVE_TIME) {
delete gameservers.remove(i--);
updateserverlist = true;
}
}
- else if(!s.lastping || ENET_TIME_DIFFERENCE(servtime, s.lastping) > PING_TIME)
- {
- if(s.numpings >= PING_RETRY)
- {
+ else if(!s.lastping || ENET_TIME_DIFFERENCE(servtime, s.lastping) > PING_TIME) {
+ if(s.numpings >= PING_RETRY) {
servermessage(s, "failreg failed pinging server\n");
delete gameservers.remove(i--);
updateserverlist = true;
}
- else
- {
+ else {
static const uchar ping[] = { 1 };
buf.data = (void *)ping;
buf.dataLength = sizeof(ping);
@@ -416,23 +353,18 @@ void checkgameservers()
}
}
-void messagebuf::purge()
-{
+void messagebuf::purge() {
refs = max(refs - 1, 0);
- if(refs<=0 && owner.last()!=this)
- {
+ if(refs<=0 && owner.last()!=this) {
owner.removeobj(this);
delete this;
}
}
-void purgeauths(client &c)
-{
+void purgeauths(client &c) {
int expired = 0;
- loopv(c.authreqs)
- {
- if(ENET_TIME_DIFFERENCE(servtime, c.authreqs[i].reqtime) >= AUTH_TIME)
- {
+ loopv(c.authreqs) {
+ if(ENET_TIME_DIFFERENCE(servtime, c.authreqs[i].reqtime) >= AUTH_TIME) {
outputf(c, "failauth %u\n", c.authreqs[i].id);
freechallenge(c.authreqs[i].answer);
expired = i + 1;
@@ -442,40 +374,30 @@ void purgeauths(client &c)
if(expired > 0) c.authreqs.remove(0, expired);
}
-void reqauth(client &c, uint id, char *name)
-{
+void reqauth(client &c, uint id, char *name) {
if(ENET_TIME_DIFFERENCE(servtime, c.lastauth) < AUTH_THROTTLE)
return;
-
c.lastauth = servtime;
-
purgeauths(c);
-
time_t t = time(NULL);
char *ct = ctime(&t);
- if(ct)
- {
+ if(ct) {
char *newline = strchr(ct, '\n');
if(newline) *newline = '\0';
}
string ip;
if(enet_address_get_host_ip(&c.address, ip, sizeof(ip)) < 0) copystring(ip, "-");
conoutf("%s: attempting \"%s\" as %u from %s", ct ? ct : "-", name, id, ip);
-
userinfo *u = users.access(name);
- if(!u)
- {
+ if(!u) {
outputf(c, "failauth %u\n", id);
return;
}
-
- if(c.authreqs.length() >= AUTH_LIMIT)
- {
+ if(c.authreqs.length() >= AUTH_LIMIT) {
outputf(c, "failauth %u\n", c.authreqs[0].id);
freechallenge(c.authreqs[0].answer);
c.authreqs.remove(0);
}
-
authreq &a = c.authreqs.add();
a.reqtime = servtime;
a.id = id;
@@ -483,25 +405,19 @@ void reqauth(client &c, uint id, char *name)
static vector<char> buf;
buf.setsize(0);
a.answer = genchallenge(u->pubkey, seed, sizeof(seed), buf);
-
outputf(c, "chalauth %u %s\n", id, buf.getbuf());
}
-void confauth(client &c, uint id, const char *val)
-{
+void confauth(client &c, uint id, const char *val) {
purgeauths(c);
-
- loopv(c.authreqs) if(c.authreqs[i].id == id)
- {
+ loopv(c.authreqs) if(c.authreqs[i].id == id) {
string ip;
if(enet_address_get_host_ip(&c.address, ip, sizeof(ip)) < 0) copystring(ip, "-");
- if(checkchallenge(val, c.authreqs[i].answer))
- {
+ if(checkchallenge(val, c.authreqs[i].answer)) {
outputf(c, "succauth %u\n", id);
conoutf("succeeded %u from %s", id, ip);
}
- else
- {
+ else {
outputf(c, "failauth %u\n", id);
conoutf("failed %u from %s", id, ip);
}
@@ -512,20 +428,16 @@ void confauth(client &c, uint id, const char *val)
outputf(c, "failauth %u\n", id);
}
-bool checkclientinput(client &c)
-{
+bool checkclientinput(client &c) {
if(c.inputpos<0) return true;
char *end = (char *)memchr(c.input, '\n', c.inputpos);
- while(end)
- {
+ while(end) {
*end++ = '\0';
c.lastinput = servtime;
-
int port;
uint id;
string user, val;
- if(!strncmp(c.input, "list", 4) && (!c.input[4] || c.input[4] == '\n' || c.input[4] == '\r'))
- {
+ if(!strncmp(c.input, "list", 4) && (!c.input[4] || c.input[4] == '\n' || c.input[4] == '\r')) {
genserverlist();
if(gameserverlists.empty() || c.message) return false;
c.message = gameserverlists.last();
@@ -535,27 +447,22 @@ bool checkclientinput(client &c)
c.shouldpurge = true;
return true;
}
- else if(sscanf(c.input, "regserv %d", &port) == 1)
- {
+ else if(sscanf(c.input, "regserv %d", &port) == 1) {
if(checkban(servbans, c.address.host)) return false;
if(port < 0 || port > 0xFFFF-1 || (c.servport >= 0 && port != c.servport)) outputf(c, "failreg invalid port\n");
- else
- {
+ else {
c.servport = port;
addgameserver(c);
}
}
- else if(sscanf(c.input, "reqauth %u %100s", &id, user) == 2)
- {
+ else if(sscanf(c.input, "reqauth %u %100s", &id, user) == 2) {
reqauth(c, id, user);
}
- else if(sscanf(c.input, "confauth %u %100s", &id, val) == 2)
- {
+ else if(sscanf(c.input, "confauth %u %100s", &id, val) == 2) {
confauth(c, id, val);
}
c.inputpos = &c.input[c.inputpos] - end;
memmove(c.input, end, c.inputpos);
-
end = (char *)memchr(c.input, '\n', c.inputpos);
}
return c.inputpos<(int)sizeof(c.input);
@@ -563,16 +470,14 @@ bool checkclientinput(client &c)
ENetSocketSet readset, writeset;
-void checkclients()
-{
+void checkclients() {
ENetSocketSet readset, writeset;
ENetSocket maxsock = max(serversocket, pingsocket);
ENET_SOCKETSET_EMPTY(readset);
ENET_SOCKETSET_EMPTY(writeset);
ENET_SOCKETSET_ADD(readset, serversocket);
ENET_SOCKETSET_ADD(readset, pingsocket);
- loopv(clients)
- {
+ loopv(clients) {
client &c = *clients[i];
if(c.authreqs.length()) purgeauths(c);
if(c.message || c.output.length()) ENET_SOCKETSET_ADD(writeset, c.socket);
@@ -580,23 +485,18 @@ void checkclients()
maxsock = max(maxsock, c.socket);
}
if(enet_socketset_select(maxsock, &readset, &writeset, 1000)<=0) return;
-
if(ENET_SOCKETSET_CHECK(readset, pingsocket)) checkserverpongs();
- if(ENET_SOCKETSET_CHECK(readset, serversocket))
- {
+ if(ENET_SOCKETSET_CHECK(readset, serversocket)) {
ENetAddress address;
ENetSocket clientsocket = enet_socket_accept(serversocket, &address);
if(clients.length()>=CLIENT_LIMIT || checkban(bans, address.host)) enet_socket_destroy(clientsocket);
- else if(clientsocket!=ENET_SOCKET_NULL)
- {
+ else if(clientsocket!=ENET_SOCKET_NULL) {
int dups = 0, oldest = -1;
- loopv(clients) if(clients[i]->address.host == address.host)
- {
+ loopv(clients) if(clients[i]->address.host == address.host) {
dups++;
if(oldest<0 || clients[i]->connecttime < clients[oldest]->connecttime) oldest = i;
}
if(dups >= DUP_LIMIT) purgeclient(oldest);
-
client *c = new client;
c->address = address;
c->socket = clientsocket;
@@ -605,32 +505,25 @@ void checkclients()
clients.add(c);
}
}
-
- loopv(clients)
- {
+ loopv(clients) {
client &c = *clients[i];
- if((c.message || c.output.length()) && ENET_SOCKETSET_CHECK(writeset, c.socket))
- {
+ if((c.message || c.output.length()) && ENET_SOCKETSET_CHECK(writeset, c.socket)) {
const char *data = c.output.length() ? c.output.getbuf() : c.message->getbuf();
int len = c.output.length() ? c.output.length() : c.message->length();
ENetBuffer buf;
buf.data = (void *)&data[c.outputpos];
buf.dataLength = len-c.outputpos;
int res = enet_socket_send(c.socket, NULL, &buf, 1);
- if(res>=0)
- {
+ if(res>=0) {
c.outputpos += res;
- if(c.outputpos>=len)
- {
+ if(c.outputpos>=len) {
if(c.output.length()) c.output.setsize(0);
- else
- {
+ else {
c.message->purge();
c.message = NULL;
}
c.outputpos = 0;
- if(!c.message && c.output.empty() && c.shouldpurge)
- {
+ if(!c.message && c.output.empty() && c.shouldpurge) {
purgeclient(i--);
continue;
}
@@ -638,14 +531,12 @@ void checkclients()
}
else { purgeclient(i--); continue; }
}
- if(ENET_SOCKETSET_CHECK(readset, c.socket))
- {
+ if(ENET_SOCKETSET_CHECK(readset, c.socket)) {
ENetBuffer buf;
buf.data = &c.input[c.inputpos];
buf.dataLength = sizeof(c.input) - c.inputpos;
int res = enet_socket_receive(c.socket, NULL, &buf, 1);
- if(res>0)
- {
+ if(res>0) {
c.inputpos += res;
c.input[min(c.inputpos, (int)sizeof(c.input)-1)] = '\0';
if(!checkclientinput(c)) { purgeclient(i--); continue; }
@@ -657,23 +548,19 @@ void checkclients()
}
}
-void banclients()
-{
+void banclients() {
loopvrev(clients) if(checkban(bans, clients[i]->address.host)) purgeclient(i);
}
volatile int reloadcfg = 1;
-void reloadsignal(int signum)
-{
+void reloadsignal(int signum) {
reloadcfg = 1;
}
-int main(int argc, char **argv)
-{
+int main(int argc, char **argv) {
if(enet_initialize()<0) fatal("Unable to initialise network module");
atexit(enet_deinitialize);
-
const char *dir = "", *ip = NULL;
int port = 28787;
if(argc>=2) dir = argv[1];
@@ -688,10 +575,8 @@ int main(int argc, char **argv)
setvbuf(logfile, NULL, _IOLBF, BUFSIZ);
signal(SIGUSR1, reloadsignal);
setupserver(port, ip);
- for(;;)
- {
- if(reloadcfg)
- {
+ for(;;) {
+ if(reloadcfg) {
conoutf("reloading master.cfg");
execfile(cfgname);
bangameservers();
@@ -699,12 +584,10 @@ int main(int argc, char **argv)
gengbanlist();
reloadcfg = 0;
}
-
servtime = enet_time_get();
checkclients();
checkgameservers();
}
-
return EXIT_SUCCESS;
}
diff --git a/src/engine/material.cpp b/src/engine/material.cpp
index e29ccf5..55151a1 100644
--- a/src/engine/material.cpp
+++ b/src/engine/material.cpp
@@ -4,13 +4,9 @@ struct QuadNode {
int x, y, size;
uint filled;
QuadNode *child[4];
-
QuadNode(int x, int y, int size) : x(x), y(y), size(size), filled(0) { loopi(4) child[i] = 0; }
-
void clear() { loopi(4) DELETEP(child[i]); }
-
~QuadNode() { clear(); }
-
void insert(int mx, int my, int msize) {
if(size == msize) {
filled = 0xF;
@@ -25,15 +21,13 @@ struct QuadNode {
}
if(!child[i]) child[i] = new QuadNode(i&1 ? x+csize : x, i&2 ? y+csize : y, csize);
child[i]->insert(mx, my, msize);
- loopj(4) if(child[j])
- {
+ loopj(4) if(child[j]) {
if(child[j]->filled == 0xF) {
DELETEP(child[j]);
filled |= (1 << j);
}
}
}
-
void genmatsurf(ushort mat, uchar orient, uchar visible, int x, int y, int z, int size, materialsurface *&matbuf) {
materialsurface &m = *matbuf++;
m.material = mat;
@@ -46,11 +40,9 @@ struct QuadNode {
m.o[R[dim]] = y;
m.o[dim] = z;
}
-
void genmatsurfs(ushort mat, uchar orient, uchar flags, int z, materialsurface *&matbuf) {
if(filled == 0xF) genmatsurf(mat, orient, flags, x, y, z, size, matbuf);
- else if(filled)
- {
+ else if(filled) {
int csize = size>>1;
loopi(4) if(filled & (1 << i))
genmatsurf(mat, orient, flags, i&1 ? x+csize : x, i&2 ? y+csize : y, z, csize, matbuf);
@@ -68,21 +60,18 @@ static const bvec4 matnormals[6] = {
bvec4(0, 0, 0x7F)
};
-static void drawmaterial(const materialsurface &m, float offset, const bvec4 &color)
-{
- if(gle::attribbuf.empty())
- {
+static void drawmaterial(const materialsurface &m, float offset, const bvec4 &color) {
+ if(gle::attribbuf.empty()) {
gle::defvertex();
gle::defcolor(4, GL_UNSIGNED_BYTE);
gle::begin(GL_QUADS);
}
float x = m.o.x, y = m.o.y, z = m.o.z, csize = m.csize, rsize = m.rsize;
- switch(m.orient)
- {
+ switch(m.orient) {
#define GENFACEORIENT(orient, v0, v1, v2, v3) \
case orient: v0 v1 v2 v3 break;
- #define GENFACEVERT(orient, vert, mx,my,mz, sx,sy,sz) \
- { \
+ #define GENFACEVERT(orient, vert, mx,my,mz, sx,sy,sz) { \
+ \
gle::attribf(mx sx, my sy, mz sz); \
gle::attrib(color); \
}
@@ -92,45 +81,38 @@ static void drawmaterial(const materialsurface &m, float offset, const bvec4 &co
}
}
-const struct material
-{
+const struct material {
const char *name;
ushort id;
-} materials[] =
-{
- {"air", MAT_AIR},
- {"clip", MAT_CLIP},
- {"noclip", MAT_NOCLIP},
- {"gameclip", MAT_GAMECLIP},
- {"death", MAT_DEATH},
- {"alpha", MAT_ALPHA}
+} materials[] = {
+ {
+ "air", MAT_AIR}, {
+ "clip", MAT_CLIP}, {
+ "noclip", MAT_NOCLIP}, {
+ "gameclip", MAT_GAMECLIP}, {
+ "death", MAT_DEATH}, {
+ "alpha", MAT_ALPHA}
};
-int findmaterial(const char *name)
-{
- loopi(sizeof(materials)/sizeof(material))
- {
+int findmaterial(const char *name) {
+ loopi(sizeof(materials)/sizeof(material)) {
if(!strcmp(materials[i].name, name)) return materials[i].id;
}
return -1;
}
-const char *findmaterialname(int mat)
-{
+const char *findmaterialname(int mat) {
loopi(sizeof(materials)/sizeof(materials[0])) if(materials[i].id == mat) return materials[i].name;
return NULL;
}
-const char *getmaterialdesc(int mat, const char *prefix)
-{
+const char *getmaterialdesc(int mat, const char *prefix) {
static const ushort matmasks[] = { MATF_INDEX, MATF_CLIP, MAT_DEATH, MAT_ALPHA };
static string desc;
desc[0] = '\0';
- loopi(sizeof(matmasks)/sizeof(matmasks[0])) if(mat&matmasks[i])
- {
+ loopi(sizeof(matmasks)/sizeof(matmasks[0])) if(mat&matmasks[i]) {
const char *matname = findmaterialname(mat&matmasks[i]);
- if(matname)
- {
+ if(matname) {
concatstring(desc, desc[0] ? ", " : prefix);
concatstring(desc, matname);
}
@@ -138,14 +120,11 @@ const char *getmaterialdesc(int mat, const char *prefix)
return desc;
}
-int visiblematerial(const cube &c, int orient, const ivec &co, int size, ushort matmask)
-{
+int visiblematerial(const cube &c, int orient, const ivec &co, int size, ushort matmask) {
ushort mat = c.material&matmask;
- switch(mat)
- {
+ switch(mat) {
case MAT_AIR:
break;
-
default:
if(visibleface(c, orient, co, size, mat, MAT_AIR, matmask))
return MATSURF_EDIT_ONLY;
@@ -154,17 +133,13 @@ int visiblematerial(const cube &c, int orient, const ivec &co, int size, ushort
return MATSURF_NOT_VISIBLE;
}
-void genmatsurfs(const cube &c, const ivec &co, int size, vector<materialsurface> &matsurfs)
-{
- loopi(6)
- {
+void genmatsurfs(const cube &c, const ivec &co, int size, vector<materialsurface> &matsurfs) {
+ loopi(6) {
static const ushort matmasks[] = { MATF_INDEX, MATF_CLIP, MAT_DEATH, MAT_ALPHA };
- loopj(sizeof(matmasks)/sizeof(matmasks[0]))
- {
+ loopj(sizeof(matmasks)/sizeof(matmasks[0])) {
int matmask = matmasks[j];
int vis = visiblematerial(c, i, co, size, matmask&~MATF_INDEX);
- if(vis != MATSURF_NOT_VISIBLE)
- {
+ if(vis != MATSURF_NOT_VISIBLE) {
materialsurface m;
m.material = c.material&matmask;
m.orient = i;
@@ -179,22 +154,18 @@ void genmatsurfs(const cube &c, const ivec &co, int size, vector<materialsurface
}
}
-static inline bool mergematcmp(const materialsurface &x, const materialsurface &y)
-{
+static inline bool mergematcmp(const materialsurface &x, const materialsurface &y) {
int dim = dimension(x.orient), c = C[dim], r = R[dim];
if(x.o[r] + x.rsize < y.o[r] + y.rsize) return true;
if(x.o[r] + x.rsize > y.o[r] + y.rsize) return false;
return x.o[c] < y.o[c];
}
-static int mergematr(materialsurface *m, int sz, materialsurface &n)
-{
+static int mergematr(materialsurface *m, int sz, materialsurface &n) {
int dim = dimension(n.orient), c = C[dim], r = R[dim];
- for(int i = sz-1; i >= 0; --i)
- {
+ for(int i = sz-1; i >= 0; --i) {
if(m[i].o[r] + m[i].rsize < n.o[r]) break;
- if(m[i].o[r] + m[i].rsize == n.o[r] && m[i].o[c] == n.o[c] && m[i].csize == n.csize)
- {
+ if(m[i].o[r] + m[i].rsize == n.o[r] && m[i].o[c] == n.o[c] && m[i].csize == n.csize) {
n.o[r] = m[i].o[r];
n.rsize += m[i].rsize;
memmove(&m[i], &m[i+1], (sz - (i+1)) * sizeof(materialsurface));
@@ -204,11 +175,9 @@ static int mergematr(materialsurface *m, int sz, materialsurface &n)
return 0;
}
-static int mergematc(materialsurface &m, materialsurface &n)
-{
+static int mergematc(materialsurface &m, materialsurface &n) {
int dim = dimension(n.orient), c = C[dim], r = R[dim];
- if(m.o[r] == n.o[r] && m.rsize == n.rsize && m.o[c] + m.csize == n.o[c])
- {
+ if(m.o[r] == n.o[r] && m.rsize == n.rsize && m.o[c] + m.csize == n.o[c]) {
n.o[c] = m.o[c];
n.csize += m.csize;
return 1;
@@ -216,10 +185,8 @@ static int mergematc(materialsurface &m, materialsurface &n)
return 0;
}
-static int mergemat(materialsurface *m, int sz, materialsurface &n)
-{
- for(bool merged = false; sz; merged = true)
- {
+static int mergemat(materialsurface *m, int sz, materialsurface &n) {
+ for(bool merged = false; sz; merged = true) {
int rmerged = mergematr(m, sz, n);
sz -= rmerged;
if(!rmerged && merged) break;
@@ -232,17 +199,14 @@ static int mergemat(materialsurface *m, int sz, materialsurface &n)
return sz;
}
-static int mergemats(materialsurface *m, int sz)
-{
+static int mergemats(materialsurface *m, int sz) {
quicksort(m, sz, mergematcmp);
-
int nsz = 0;
loopi(sz) nsz = mergemat(m, nsz, m[i]);
return nsz;
}
-static inline bool optmatcmp(const materialsurface &x, const materialsurface &y)
-{
+static inline bool optmatcmp(const materialsurface &x, const materialsurface &y) {
if(x.material < y.material) return true;
if(x.material > y.material) return false;
if(x.orient > y.orient) return true;
@@ -253,13 +217,11 @@ static inline bool optmatcmp(const materialsurface &x, const materialsurface &y)
VARF(optmats, 0, 1, 1, allchanged());
-int optimizematsurfs(materialsurface *matbuf, int matsurfs)
-{
+int optimizematsurfs(materialsurface *matbuf, int matsurfs) {
quicksort(matbuf, matsurfs, optmatcmp);
if(!optmats) return matsurfs;
materialsurface *cur = matbuf, *end = matbuf+matsurfs;
- while(cur < end)
- {
+ while(cur < end) {
materialsurface *start = cur++;
int dim = dimension(start->orient);
while(cur < end &&
@@ -288,17 +250,14 @@ int optimizematsurfs(materialsurface *matbuf, int matsurfs)
return matsurfs - (end-matbuf);
}
-void setupmaterials(int start, int len)
-{
+void setupmaterials(int start, int len) {
int hasmat = 0;
unionfind uf;
if(!len) len = valist.length();
- for(int i = start; i < len; i++)
- {
+ for(int i = start; i < len; i++) {
vtxarray *va = valist[i];
materialsurface *skip = NULL;
- loopj(va->matsurfs)
- {
+ loopj(va->matsurfs) {
materialsurface &m = va->matbuf[j];
int matvol = 0;
if(matvol) hasmat |= 1<<m.material;
@@ -317,12 +276,10 @@ static int sortdim[3];
static ivec sortorigin;
static bool sortedit;
-static inline bool vismatcmp(const materialsurface *xm, const materialsurface *ym)
-{
+static inline bool vismatcmp(const materialsurface *xm, const materialsurface *ym) {
const materialsurface &x = *xm, &y = *ym;
int xdim = dimension(x.orient), ydim = dimension(y.orient);
- loopi(3)
- {
+ loopi(3) {
int dim = sortdim[i], xmin, xmax, ymin, ymax;
xmin = xmax = x.o[dim];
if(dim==C[xdim]) xmax += x.csize;
@@ -346,8 +303,7 @@ static inline bool vismatcmp(const materialsurface *xm, const materialsurface *y
return false;
}
-void sortmaterials(vector<materialsurface *> &vismats)
-{
+void sortmaterials(vector<materialsurface *> &vismats) {
sortorigin = ivec(camera1->o);
vec dir;
vecfromyawpitch(camera1->yaw, camera1->pitch, 1, 0, dir);
@@ -355,15 +311,11 @@ void sortmaterials(vector<materialsurface *> &vismats)
if(dir[sortdim[2]] > dir[sortdim[1]]) swap(sortdim[2], sortdim[1]);
if(dir[sortdim[1]] > dir[sortdim[0]]) swap(sortdim[1], sortdim[0]);
if(dir[sortdim[2]] > dir[sortdim[1]]) swap(sortdim[2], sortdim[1]);
-
- for(vtxarray *va = visibleva; va; va = va->next)
- {
+ for(vtxarray *va = visibleva; va; va = va->next) {
if(!va->matsurfs || va->occluded >= OCCLUDE_BB) continue;
- loopi(va->matsurfs)
- {
+ loopi(va->matsurfs) {
materialsurface &m = va->matbuf[i];
- if(!editmode || !showmat || drawtex)
- {
+ if(!editmode || !showmat || drawtex) {
if(m.visible == MATSURF_EDIT_ONLY) { i += m.skip; continue; }
}
vismats.add(&m);
@@ -373,19 +325,15 @@ void sortmaterials(vector<materialsurface *> &vismats)
vismats.sort(vismatcmp);
}
-void rendermatgrid(vector<materialsurface *> &vismats)
-{
+void rendermatgrid(vector<materialsurface *> &vismats) {
enablepolygonoffset(GL_POLYGON_OFFSET_LINE);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
int lastmat = -1;
bvec4 color(0, 0, 0, 0);
- loopvrev(vismats)
- {
+ loopvrev(vismats) {
materialsurface &m = *vismats[i];
- if(m.material != lastmat)
- {
- switch(m.material&~MATF_INDEX)
- {
+ if(m.material != lastmat) {
+ switch(m.material&~MATF_INDEX) {
case MAT_CLIP: color = bvec4(85, 0, 0, 255); break; // red
case MAT_NOCLIP: color = bvec4( 0, 85, 0, 255); break; // green
case MAT_GAMECLIP: color = bvec4(85, 85, 0, 255); break; // yellow
@@ -402,31 +350,22 @@ void rendermatgrid(vector<materialsurface *> &vismats)
disablepolygonoffset(GL_POLYGON_OFFSET_LINE);
}
-void rendermaterials()
-{
+void rendermaterials() {
vector<materialsurface *> vismats;
sortmaterials(vismats);
if(vismats.empty()) return;
-
glDisable(GL_CULL_FACE);
-
int lastorient = -1, lastmat = -1;
bool depth = true, blended = false;
-
GLOBALPARAM(camera, camera1->o);
-
- if(editmode && showmat && !drawtex)
- {
+ if(editmode && showmat && !drawtex) {
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
glEnable(GL_BLEND); blended = true;
bvec4 color(0, 0, 0, 0);
- loopv(vismats)
- {
+ loopv(vismats) {
const materialsurface &m = *vismats[i];
- if(lastmat!=m.material)
- {
- switch(m.material&~MATF_INDEX)
- {
+ if(lastmat!=m.material) {
+ switch(m.material&~MATF_INDEX) {
case MAT_CLIP: color = bvec4( 0, 255, 255, 255); break; // red
case MAT_NOCLIP: color = bvec4(255, 0, 255, 255); break; // green
case MAT_GAMECLIP: color = bvec4( 0, 0, 255, 255); break; // yellow
@@ -440,16 +379,13 @@ void rendermaterials()
}
xtraverts += gle::end();
}
-
if(lastorient >= 0)
if(lastmat&~MATF_INDEX)
xtraverts += gle::end();
-
if(!depth) glDepthMask(GL_TRUE);
if(blended) glDisable(GL_BLEND);
extern int wireframe;
if(editmode && showmat && !drawtex && !wireframe)
rendermatgrid(vismats);
-
glEnable(GL_CULL_FACE);
}
diff --git a/src/engine/md3.h b/src/engine/md3.h
deleted file mode 100644
index 7296055..0000000
--- a/src/engine/md3.h
+++ /dev/null
@@ -1,183 +0,0 @@
-struct md3;
-
-struct md3frame
-{
- vec bbmin, bbmax, origin;
- float radius;
- uchar name[16];
-};
-
-struct md3tag
-{
- char name[64];
- float translation[3];
- float rotation[3][3];
-};
-
-struct md3vertex
-{
- short vertex[3];
- short normal;
-};
-
-struct md3triangle
-{
- int vertexindices[3];
-};
-
-struct md3header
-{
- char id[4];
- int version;
- char name[64];
- int flags;
- int numframes, numtags, nummeshes, numskins;
- int ofs_frames, ofs_tags, ofs_meshes, ofs_eof; // offsets
-};
-
-struct md3meshheader
-{
- char id[4];
- char name[64];
- int flags;
- int numframes, numshaders, numvertices, numtriangles;
- int ofs_triangles, ofs_shaders, ofs_uv, ofs_vertices, meshsize; // offsets
-};
-
-struct md3 : vertloader<md3>
-{
- md3(const char *name) : vertloader(name) {}
-
- static const char *formatname() { return "md3"; }
- bool flipy() const { return true; }
- int type() const { return MDL_MD3; }
-
- struct md3meshgroup : vertmeshgroup
- {
- bool load(const char *path)
- {
- stream *f = openfile(path, "rb");
- if(!f) return false;
- md3header header;
- f->read(&header, sizeof(md3header));
- lilswap(&header.version, 1);
- lilswap(&header.flags, 9);
- if(strncmp(header.id, "IDP3", 4) != 0 || header.version != 15) // header check
- {
- delete f;
- conoutf(CON_ERROR, "md3: corrupted header");
- return false;
- }
-
- name = newstring(path);
-
- numframes = header.numframes;
-
- int mesh_offset = header.ofs_meshes;
- loopi(header.nummeshes)
- {
- vertmesh &m = *new vertmesh;
- m.group = this;
- meshes.add(&m);
-
- md3meshheader mheader;
- f->seek(mesh_offset, SEEK_SET);
- f->read(&mheader, sizeof(md3meshheader));
- lilswap(&mheader.flags, 10);
-
- m.name = newstring(mheader.name);
-
- m.numtris = mheader.numtriangles;
- m.tris = new tri[m.numtris];
- f->seek(mesh_offset + mheader.ofs_triangles, SEEK_SET);
- loopj(m.numtris)
- {
- md3triangle tri = { 0 };
- f->read(&tri, sizeof(md3triangle)); // read the triangles
- lilswap(tri.vertexindices, 3);
- loopk(3) m.tris[j].vert[k] = (ushort)tri.vertexindices[k];
- }
-
- m.numverts = mheader.numvertices;
- m.tcverts = new tcvert[m.numverts];
- f->seek(mesh_offset + mheader.ofs_uv , SEEK_SET);
- f->read(m.tcverts, m.numverts*2*sizeof(float)); // read the UV data
- lilswap(&m.tcverts[0].tc.x, 2*m.numverts);
-
- m.verts = new vert[numframes*m.numverts];
- f->seek(mesh_offset + mheader.ofs_vertices, SEEK_SET);
- loopj(numframes*m.numverts)
- {
- md3vertex v = { {0}, 0 };
- f->read(&v, sizeof(md3vertex)); // read the vertices
- lilswap(v.vertex, 4);
-
- m.verts[j].pos = vec(v.vertex[0]/64.0f, -v.vertex[1]/64.0f, v.vertex[2]/64.0f);
-
- float lng = (v.normal&0xFF)*2*M_PI/255.0f; // decode vertex normals
- float lat = ((v.normal>>8)&0xFF)*2*M_PI/255.0f;
- m.verts[j].norm = vec(cosf(lat)*sinf(lng), -sinf(lat)*sinf(lng), cosf(lng));
- }
-
- mesh_offset += mheader.meshsize;
- }
-
- numtags = header.numtags;
- if(numtags)
- {
- tags = new tag[numframes*numtags];
- f->seek(header.ofs_tags, SEEK_SET);
- md3tag tag;
-
- loopi(header.numframes*header.numtags)
- {
- f->read(&tag, sizeof(md3tag));
- lilswap(tag.translation, 12);
- if(tag.name[0] && i<header.numtags) tags[i].name = newstring(tag.name);
- matrix4x3 &m = tags[i].transform;
- tag.translation[1] *= -1;
- // undo the -y
- loopj(3) tag.rotation[1][j] *= -1;
- // then restore it
- loopj(3) tag.rotation[j][1] *= -1;
- m.a = vec(tag.rotation[0]);
- m.b = vec(tag.rotation[1]);
- m.c = vec(tag.rotation[2]);
- m.d = vec(tag.translation);
- }
- }
-
- delete f;
- return true;
- }
- };
-
- meshgroup *loadmeshes(const char *name, va_list args)
- {
- md3meshgroup *group = new md3meshgroup;
- if(!group->load(name)) { delete group; return NULL; }
- return group;
- }
-
- bool loaddefaultparts()
- {
- const char *pname = parentdir(name);
- part &mdl = addpart();
- defformatstring(name1, "packages/models/%s/tris.md3", name);
- mdl.meshes = sharemeshes(path(name1));
- if(!mdl.meshes)
- {
- defformatstring(name2, "packages/models/%s/tris.md3", pname); // try md3 in parent folder (vert sharing)
- mdl.meshes = sharemeshes(path(name2));
- if(!mdl.meshes) return false;
- }
- Texture *tex, *masks;
- loadskin(name, pname, tex, masks);
- mdl.initskins(tex, masks);
- if(tex==notexture) conoutf(CON_ERROR, "could not load model skin for %s", name1);
- return true;
- }
-};
-
-vertcommands<md3> md3commands;
-
diff --git a/src/engine/md5.h b/src/engine/md5.h
index d948ccf..e508cb3 100644
--- a/src/engine/md5.h
+++ b/src/engine/md5.h
@@ -1,66 +1,48 @@
struct md5;
-struct md5joint
-{
+struct md5joint {
vec pos;
quat orient;
};
-struct md5weight
-{
+struct md5weight {
int joint;
float bias;
vec pos;
};
-struct md5vert
-{
+struct md5vert {
vec2 tc;
ushort start, count;
};
-struct md5hierarchy
-{
+struct md5hierarchy {
string name;
int parent, flags, start;
};
-struct md5 : skelloader<md5>
-{
+struct md5 : skelloader<md5> {
md5(const char *name) : skelloader(name) {}
-
static const char *formatname() { return "md5"; }
int type() const { return MDL_MD5; }
-
- struct md5mesh : skelmesh
- {
+ struct md5mesh : skelmesh {
md5weight *weightinfo;
int numweights;
md5vert *vertinfo;
-
- md5mesh() : weightinfo(NULL), numweights(0), vertinfo(NULL)
- {
+ md5mesh() : weightinfo(NULL), numweights(0), vertinfo(NULL) {
}
-
- ~md5mesh()
- {
+ ~md5mesh() {
cleanup();
}
-
- void cleanup()
- {
+ void cleanup() {
DELETEA(weightinfo);
DELETEA(vertinfo);
}
-
- void buildverts(vector<md5joint> &joints)
- {
- loopi(numverts)
- {
+ void buildverts(vector<md5joint> &joints) {
+ loopi(numverts) {
md5vert &v = vertinfo[i];
vec pos(0, 0, 0);
- loopk(v.count)
- {
+ loopk(v.count) {
md5weight &w = weightinfo[v.start+k];
md5joint &j = joints[w.joint];
vec wpos = j.orient.rotate(w.pos);
@@ -71,11 +53,9 @@ struct md5 : skelloader<md5>
vert &vv = verts[i];
vv.pos = pos;
vv.tc = v.tc;
-
blendcombo c;
int sorted = 0;
- loopj(v.count)
- {
+ loopj(v.count) {
md5weight &w = weightinfo[v.start+j];
sorted = c.addweight(sorted, w.bias, w.joint);
}
@@ -83,29 +63,22 @@ struct md5 : skelloader<md5>
vv.blend = addblendcombo(c);
}
}
-
- void load(stream *f, char *buf, size_t bufsize)
- {
+ void load(stream *f, char *buf, size_t bufsize) {
md5weight w;
md5vert v;
tri t;
int index;
-
- while(f->getline(buf, bufsize) && buf[0]!='}')
- {
- if(strstr(buf, "// meshes:"))
- {
+ while(f->getline(buf, bufsize) && buf[0]!='}') {
+ if(strstr(buf, "// meshes:")) {
char *start = strchr(buf, ':')+1;
if(*start==' ') start++;
char *end = start + strlen(start)-1;
while(end >= start && isspace(*end)) end--;
name = newstring(start, end+1-start);
}
- else if(strstr(buf, "shader"))
- {
+ else if(strstr(buf, "shader")) {
char *start = strchr(buf, '"'), *end = start ? strchr(start+1, '"') : NULL;
- if(start && end)
- {
+ if(start && end) {
char *texname = newstring(start+1, end-(start+1));
part *p = loading->parts.last();
p->initskins(notexture, notexture, group->meshes.length());
@@ -114,86 +87,66 @@ struct md5 : skelloader<md5>
delete[] texname;
}
}
- else if(sscanf(buf, " numverts %d", &numverts)==1)
- {
+ else if(sscanf(buf, " numverts %d", &numverts)==1) {
numverts = max(numverts, 0);
- if(numverts)
- {
+ if(numverts) {
vertinfo = new md5vert[numverts];
verts = new vert[numverts];
}
}
- else if(sscanf(buf, " numtris %d", &numtris)==1)
- {
+ else if(sscanf(buf, " numtris %d", &numtris)==1) {
numtris = max(numtris, 0);
if(numtris) tris = new tri[numtris];
}
- else if(sscanf(buf, " numweights %d", &numweights)==1)
- {
+ else if(sscanf(buf, " numweights %d", &numweights)==1) {
numweights = max(numweights, 0);
if(numweights) weightinfo = new md5weight[numweights];
}
- else if(sscanf(buf, " vert %d ( %f %f ) %hu %hu", &index, &v.tc.x, &v.tc.y, &v.start, &v.count)==5)
- {
+ else if(sscanf(buf, " vert %d ( %f %f ) %hu %hu", &index, &v.tc.x, &v.tc.y, &v.start, &v.count)==5) {
if(index>=0 && index<numverts) vertinfo[index] = v;
}
- else if(sscanf(buf, " tri %d %hu %hu %hu", &index, &t.vert[0], &t.vert[1], &t.vert[2])==4)
- {
+ else if(sscanf(buf, " tri %d %hu %hu %hu", &index, &t.vert[0], &t.vert[1], &t.vert[2])==4) {
if(index>=0 && index<numtris) tris[index] = t;
}
- else if(sscanf(buf, " weight %d %d %f ( %f %f %f ) ", &index, &w.joint, &w.bias, &w.pos.x, &w.pos.y, &w.pos.z)==6)
- {
+ else if(sscanf(buf, " weight %d %d %f ( %f %f %f ) ", &index, &w.joint, &w.bias, &w.pos.x, &w.pos.y, &w.pos.z)==6) {
w.pos.y = -w.pos.y;
if(index>=0 && index<numweights) weightinfo[index] = w;
}
}
}
};
-
- struct md5meshgroup : skelmeshgroup
- {
- md5meshgroup()
- {
+ struct md5meshgroup : skelmeshgroup {
+ md5meshgroup() {
}
-
- bool loadmesh(const char *filename, float smooth)
- {
+ bool loadmesh(const char *filename, float smooth) {
stream *f = openfile(filename, "r");
if(!f) return false;
-
char buf[512];
vector<md5joint> basejoints;
- while(f->getline(buf, sizeof(buf)))
- {
+ while(f->getline(buf, sizeof(buf))) {
int tmp;
- if(sscanf(buf, " MD5Version %d", &tmp)==1)
- {
+ if(sscanf(buf, " MD5Version %d", &tmp)==1) {
if(tmp!=10) { delete f; return false; }
}
- else if(sscanf(buf, " numJoints %d", &tmp)==1)
- {
+ else if(sscanf(buf, " numJoints %d", &tmp)==1) {
if(tmp<1) { delete f; return false; }
if(skel->numbones>0) continue;
skel->numbones = tmp;
skel->bones = new boneinfo[skel->numbones];
}
- else if(sscanf(buf, " numMeshes %d", &tmp)==1)
- {
+ else if(sscanf(buf, " numMeshes %d", &tmp)==1) {
if(tmp<1) { delete f; return false; }
}
- else if(strstr(buf, "joints {"))
- {
+ else if(strstr(buf, "joints {")) {
string name;
int parent;
md5joint j;
- while(f->getline(buf, sizeof(buf)) && buf[0]!='}')
- {
+ while(f->getline(buf, sizeof(buf)) && buf[0]!='}') {
char *curbuf = buf, *curname = name;
bool allowspace = false;
while(*curbuf && isspace(*curbuf)) curbuf++;
if(*curbuf == '"') { curbuf++; allowspace = true; }
- while(*curbuf && curname < &name[sizeof(name)-1])
- {
+ while(*curbuf && curname < &name[sizeof(name)-1]) {
char c = *curbuf++;
if(c == '"') break;
if(isspace(c) && !allowspace) break;
@@ -202,8 +155,7 @@ struct md5 : skelloader<md5>
*curname = '\0';
if(sscanf(curbuf, " %d ( %f %f %f ) ( %f %f %f )",
&parent, &j.pos.x, &j.pos.y, &j.pos.z,
- &j.orient.x, &j.orient.y, &j.orient.z)==7)
- {
+ &j.orient.x, &j.orient.y, &j.orient.z)==7) {
j.pos.y = -j.pos.y;
j.orient.x = -j.orient.x;
j.orient.z = -j.orient.z;
@@ -219,101 +171,77 @@ struct md5 : skelloader<md5>
}
if(basejoints.length()!=skel->numbones) { delete f; return false; }
}
- else if(strstr(buf, "mesh {"))
- {
+ else if(strstr(buf, "mesh {")) {
md5mesh *m = new md5mesh;
m->group = this;
meshes.add(m);
m->load(f, buf, sizeof(buf));
- if(!m->numtris || !m->numverts)
- {
+ if(!m->numtris || !m->numverts) {
conoutf(CON_WARN, "empty mesh in %s", filename);
meshes.removeobj(m);
delete m;
}
}
}
-
- if(skel->shared <= 1)
- {
+ if(skel->shared <= 1) {
skel->linkchildren();
- loopv(basejoints)
- {
+ loopv(basejoints) {
boneinfo &b = skel->bones[i];
b.base = dualquat(basejoints[i].orient, basejoints[i].pos);
(b.invbase = b.base).invert();
}
}
-
- loopv(meshes)
- {
+ loopv(meshes) {
md5mesh &m = *(md5mesh *)meshes[i];
m.buildverts(basejoints);
if(smooth <= 1) m.smoothnorms(smooth);
else m.buildnorms();
m.cleanup();
}
-
sortblendcombos();
-
delete f;
return true;
}
-
- skelanimspec *loadanim(const char *filename)
- {
+ skelanimspec *loadanim(const char *filename) {
skelanimspec *sa = skel->findskelanim(filename);
if(sa) return sa;
-
stream *f = openfile(filename, "r");
if(!f) return NULL;
-
vector<md5hierarchy> hierarchy;
vector<md5joint> basejoints;
int animdatalen = 0, animframes = 0;
float *animdata = NULL;
dualquat *animbones = NULL;
char buf[512];
- while(f->getline(buf, sizeof(buf)))
- {
+ while(f->getline(buf, sizeof(buf))) {
int tmp;
- if(sscanf(buf, " MD5Version %d", &tmp)==1)
- {
+ if(sscanf(buf, " MD5Version %d", &tmp)==1) {
if(tmp!=10) { delete f; return NULL; }
}
- else if(sscanf(buf, " numJoints %d", &tmp)==1)
- {
+ else if(sscanf(buf, " numJoints %d", &tmp)==1) {
if(tmp!=skel->numbones) { delete f; return NULL; }
}
- else if(sscanf(buf, " numFrames %d", &animframes)==1)
- {
+ else if(sscanf(buf, " numFrames %d", &animframes)==1) {
if(animframes<1) { delete f; return NULL; }
}
else if(sscanf(buf, " frameRate %d", &tmp)==1);
- else if(sscanf(buf, " numAnimatedComponents %d", &animdatalen)==1)
- {
+ else if(sscanf(buf, " numAnimatedComponents %d", &animdatalen)==1) {
if(animdatalen>0) animdata = new float[animdatalen];
}
- else if(strstr(buf, "bounds {"))
- {
+ else if(strstr(buf, "bounds {")) {
while(f->getline(buf, sizeof(buf)) && buf[0]!='}');
}
- else if(strstr(buf, "hierarchy {"))
- {
- while(f->getline(buf, sizeof(buf)) && buf[0]!='}')
- {
+ else if(strstr(buf, "hierarchy {")) {
+ while(f->getline(buf, sizeof(buf)) && buf[0]!='}') {
md5hierarchy h;
if(sscanf(buf, " %100s %d %d %d", h.name, &h.parent, &h.flags, &h.start)==4)
hierarchy.add(h);
}
}
- else if(strstr(buf, "baseframe {"))
- {
- while(f->getline(buf, sizeof(buf)) && buf[0]!='}')
- {
+ else if(strstr(buf, "baseframe {")) {
+ while(f->getline(buf, sizeof(buf)) && buf[0]!='}') {
md5joint j;
- if(sscanf(buf, " ( %f %f %f ) ( %f %f %f )", &j.pos.x, &j.pos.y, &j.pos.z, &j.orient.x, &j.orient.y, &j.orient.z)==6)
- {
+ if(sscanf(buf, " ( %f %f %f ) ( %f %f %f )", &j.pos.x, &j.pos.y, &j.pos.z, &j.orient.x, &j.orient.y, &j.orient.z)==6) {
j.pos.y = -j.pos.y;
j.orient.x = -j.orient.x;
j.orient.z = -j.orient.z;
@@ -323,37 +251,29 @@ struct md5 : skelloader<md5>
}
if(basejoints.length()!=skel->numbones) { delete f; if(animdata) delete[] animdata; return NULL; }
animbones = new dualquat[(skel->numframes+animframes)*skel->numbones];
- if(skel->framebones)
- {
+ if(skel->framebones) {
memcpy(animbones, skel->framebones, skel->numframes*skel->numbones*sizeof(dualquat));
delete[] skel->framebones;
}
skel->framebones = animbones;
animbones += skel->numframes*skel->numbones;
-
sa = &skel->addskelanim(filename);
sa->frame = skel->numframes;
sa->range = animframes;
-
skel->numframes += animframes;
}
- else if(sscanf(buf, " frame %d", &tmp)==1)
- {
- for(int numdata = 0; f->getline(buf, sizeof(buf)) && buf[0]!='}';)
- {
- for(char *src = buf, *next = src; numdata < animdatalen; numdata++, src = next)
- {
+ else if(sscanf(buf, " frame %d", &tmp)==1) {
+ for(int numdata = 0; f->getline(buf, sizeof(buf)) && buf[0]!='}';) {
+ for(char *src = buf, *next = src; numdata < animdatalen; numdata++, src = next) {
animdata[numdata] = strtod(src, &next);
if(next <= src) break;
}
}
dualquat *frame = &animbones[tmp*skel->numbones];
- loopv(basejoints)
- {
+ loopv(basejoints) {
md5hierarchy &h = hierarchy[i];
md5joint j = basejoints[i];
- if(h.start < animdatalen && h.flags)
- {
+ if(h.start < animdatalen && h.flags) {
float *jdata = &animdata[h.start];
if(h.flags&1) j.pos.x = *jdata++;
if(h.flags&2) j.pos.y = -*jdata++;
@@ -371,33 +291,23 @@ struct md5 : skelloader<md5>
}
}
}
-
if(animdata) delete[] animdata;
delete f;
-
return sa;
}
-
- bool load(const char *meshfile, float smooth)
- {
+ bool load(const char *meshfile, float smooth) {
name = newstring(meshfile);
-
if(!loadmesh(meshfile, smooth)) return false;
-
return true;
}
};
-
- meshgroup *loadmeshes(const char *name, va_list args)
- {
+ meshgroup *loadmeshes(const char *name, va_list args) {
md5meshgroup *group = new md5meshgroup;
group->shareskeleton(va_arg(args, char *));
if(!group->load(name, va_arg(args, double))) { delete group; return NULL; }
return group;
}
-
- bool loaddefaultparts()
- {
+ bool loaddefaultparts() {
skelpart &mdl = addpart();
mdl.pitchscale = mdl.pitchoffset = mdl.pitchmin = mdl.pitchmax = 0;
adjustments.setsize(0);
diff --git a/src/engine/menus.cpp b/src/engine/menus.cpp
index 805a79b..e2bd266 100644
--- a/src/engine/menus.cpp
+++ b/src/engine/menus.cpp
@@ -12,17 +12,13 @@ static g3d_gui *cgui = NULL;
VAR(guitabnum, 1, 0, 0);
-struct menu : g3d_callback
-{
+struct menu : g3d_callback {
char *name, *header;
uint *contents, *init, *onclear;
bool showtab, keeptab;
int menutab;
-
menu() : name(NULL), header(NULL), contents(NULL), init(NULL), onclear(NULL), showtab(true), keeptab(false), menutab(1) {}
-
- void gui(g3d_gui &g, bool firstpass)
- {
+ void gui(g3d_gui &g, bool firstpass) {
cgui = &g;
guitabnum = menutab;
cgui->start(menustart, 0.03f, showtab ? &menutab : NULL);
@@ -32,75 +28,57 @@ struct menu : g3d_callback
cgui = NULL;
guitabnum = 0;
}
-
- virtual void clear()
- {
+ virtual void clear() {
if(onclear) { freecode(onclear); onclear = NULL; }
}
};
-struct delayedupdate
-{
- enum
- {
+struct delayedupdate {
+ enum {
INT,
FLOAT,
STRING,
ACTION
} type;
ident *id;
- union
- {
+ union {
int i;
float f;
char *s;
} val;
delayedupdate() : type(ACTION), id(NULL) { val.s = NULL; }
~delayedupdate() { if(type == STRING || type == ACTION) DELETEA(val.s); }
-
void schedule(const char *s) { type = ACTION; val.s = newstring(s); }
void schedule(ident *var, int i) { type = INT; id = var; val.i = i; }
void schedule(ident *var, float f) { type = FLOAT; id = var; val.f = f; }
void schedule(ident *var, char *s) { type = STRING; id = var; val.s = newstring(s); }
-
- int getint() const
- {
- switch(type)
- {
+ int getint() const {
+ switch(type) {
case INT: return val.i;
case FLOAT: return int(val.f);
case STRING: return int(strtol(val.s, NULL, 0));
default: return 0;
}
}
-
- float getfloat() const
- {
- switch(type)
- {
+ float getfloat() const {
+ switch(type) {
case INT: return float(val.i);
case FLOAT: return val.f;
case STRING: return float(parsefloat(val.s));
default: return 0;
}
}
-
- const char *getstring() const
- {
- switch(type)
- {
+ const char *getstring() const {
+ switch(type) {
case INT: return intstr(val.i);
case FLOAT: return intstr(int(floor(val.f)));
case STRING: return val.s;
default: return "";
}
}
-
- void run()
- {
+ void run() {
if(type == ACTION) { if(val.s) execute(val.s); }
- else if(id) switch(id->type)
- {
+ else if(id) switch(id->type) {
case ID_VAR: setvarchecked(id, getint()); break;
case ID_FVAR: setfvarchecked(id, getfloat()); break;
case ID_SVAR: setsvarchecked(id, getstring()); break;
@@ -117,8 +95,7 @@ static bool shouldclearmenu = true, clearlater = false;
VARP(menudistance, 16, 40, 256);
VARP(menuautoclose, 32, 120, 4096);
-vec menuinfrontofplayer()
-{
+vec menuinfrontofplayer() {
vec dir;
vecfromyawpitch(camera1->yaw, 0, 1, 0, dir);
dir.mul(menudistance).add(camera1->o);
@@ -126,48 +103,40 @@ vec menuinfrontofplayer()
return dir;
}
-void popgui()
-{
+void popgui() {
menu *m = guistack.pop();
m->clear();
}
-void removegui(menu *m)
-{
- loopv(guistack) if(guistack[i]==m)
- {
+void removegui(menu *m) {
+ loopv(guistack) if(guistack[i]==m) {
guistack.remove(i);
m->clear();
return;
}
}
-void pushgui(menu *m, int pos = -1)
-{
- if(guistack.empty())
- {
+void pushgui(menu *m, int pos = -1) {
+ if(guistack.empty()) {
menupos = menuinfrontofplayer();
g3d_resetcursor();
}
if(pos < 0) guistack.add(m);
else guistack.insert(pos, m);
- if(pos < 0 || pos==guistack.length()-1)
- {
+ if(pos < 0 || pos==guistack.length()-1) {
if(!m->keeptab) m->menutab = 1;
menustart = totalmillis;
}
if(m->init) execute(m->init);
}
-void restoregui(int pos)
-{
+void restoregui(int pos) {
int clear = guistack.length()-pos-1;
loopi(clear) popgui();
menustart = totalmillis;
}
-void showgui(const char *name)
-{
+void showgui(const char *name) {
menu *m = guis.access(name);
if(!m) return;
int pos = guistack.find(m);
@@ -175,17 +144,14 @@ void showgui(const char *name)
else restoregui(pos);
}
-void hidegui(const char *name)
-{
+void hidegui(const char *name) {
menu *m = guis.access(name);
if(m) removegui(m);
}
-int cleargui(int n)
-{
+int cleargui(int n) {
int clear = guistack.length();
- if(mainmenu && !isconnected(true) && clear > 0 && guistack[0]->name && !strcmp(guistack[0]->name, "main"))
- {
+ if(mainmenu && !isconnected(true) && clear > 0 && guistack[0]->name && !strcmp(guistack[0]->name, "main")) {
clear--;
if(!clear) return 1;
}
@@ -195,14 +161,12 @@ int cleargui(int n)
return clear;
}
-void clearguis(int level = -1)
-{
+void clearguis(int level = -1) {
if(level < 0) level = guistack.length();
- loopvrev(guistack)
- {
+ loopvrev(guistack) {
menu *m = guistack[i];
if(m->onclear)
- {
+ {
uint *action = m->onclear;
m->onclear = NULL;
execute(action);
@@ -212,32 +176,28 @@ void clearguis(int level = -1)
cleargui(level);
}
-void guionclear(char *action)
-{
+void guionclear(char *action) {
if(guistack.empty()) return;
menu *m = guistack.last();
if(m->onclear) { freecode(m->onclear); m->onclear = NULL; }
if(action[0]) m->onclear = compilecode(action);
}
-void guistayopen(uint *contents)
-{
+void guistayopen(uint *contents) {
bool oldclearmenu = shouldclearmenu;
shouldclearmenu = false;
execute(contents);
shouldclearmenu = oldclearmenu;
}
-void guinoautotab(uint *contents)
-{
+void guinoautotab(uint *contents) {
if(!cgui) return;
bool oldval = cgui->allowautotab(false);
execute(contents);
cgui->allowautotab(oldval);
}
-void guimerge(uint *contents)
-{
+void guimerge(uint *contents) {
if(!cgui) return;
bool oldval = cgui->mergehits(true);
execute(contents);
@@ -245,114 +205,92 @@ void guimerge(uint *contents)
}
//@DOC name and icon are optional
-void guibutton(char *name, char *action, char *icon)
-{
+void guibutton(char *name, char *action, char *icon) {
if(!cgui) return;
bool hideicon = !strcmp(icon, "0");
int ret = cgui->button(name, GUI_BUTTON_COLOR, hideicon ? NULL : (icon[0] ? icon : (strstr(action, "showgui") ? "menu" : "action")));
- if(ret&G3D_UP)
- {
+ if(ret&G3D_UP) {
updatelater.add().schedule(action[0] ? action : name);
if(shouldclearmenu) clearlater = true;
}
- else if(ret&G3D_ROLLOVER)
- {
+ else if(ret&G3D_ROLLOVER) {
alias("guirollovername", name);
alias("guirolloveraction", action);
}
}
-void guiimage(char *path, char *action, float *scale, int *overlaid, char *alt, char *title)
-{
+void guiimage(char *path, char *action, float *scale, int *overlaid, char *alt, char *title) {
if(!cgui) return;
Texture *t = textureload(path, 0, true, false);
- if(t==notexture)
- {
+ if(t==notexture) {
if(alt[0]) t = textureload(alt, 0, true, false);
if(t==notexture) return;
}
int ret = cgui->image(t, *scale, *overlaid!=0 ? title : NULL);
- if(ret&G3D_UP)
- {
- if(*action)
- {
+ if(ret&G3D_UP) {
+ if(*action) {
updatelater.add().schedule(action);
if(shouldclearmenu) clearlater = true;
}
}
- else if(ret&G3D_ROLLOVER)
- {
+ else if(ret&G3D_ROLLOVER) {
alias("guirolloverimgpath", path);
alias("guirolloverimgaction", action);
}
}
-void guicolor(int *color)
-{
- if(cgui)
- {
+void guicolor(int *color) {
+ if(cgui) {
defformatstring(desc, "0x%06X", *color);
cgui->text(desc, *color, NULL);
}
}
-void guitextbox(char *text, int *width, int *height, int *color)
-{
+void guitextbox(char *text, int *width, int *height, int *color) {
if(cgui && text[0]) cgui->textbox(text, *width ? *width : 12, *height ? *height : 1, *color ? *color : 0xFFFFFF);
}
-void guitext(char *name, char *icon)
-{
+void guitext(char *name, char *icon) {
bool hideicon = !strcmp(icon, "0");
if(cgui) cgui->text(name, !hideicon && icon[0] ? GUI_BUTTON_COLOR : GUI_TEXT_COLOR, hideicon ? NULL : (icon[0] ? icon : "info"));
}
-void guititle(char *name)
-{
+void guititle(char *name) {
if(cgui) cgui->title(name, GUI_TITLE_COLOR);
}
-void guitab(char *name)
-{
+void guitab(char *name) {
if(cgui) cgui->tab(name, GUI_TITLE_COLOR);
}
-void guibar()
-{
+void guibar() {
if(cgui) cgui->separator();
}
-void guistrut(float *strut, int *alt)
-{
- if(cgui)
- {
+void guistrut(float *strut, int *alt) {
+ if(cgui) {
if(*alt) cgui->strut(*strut); else cgui->space(*strut);
}
}
-void guispring(int *weight)
-{
+void guispring(int *weight) {
if(cgui) cgui->spring(max(*weight, 1));
}
-void guicolumn(int *col)
-{
+void guicolumn(int *col) {
if(cgui) cgui->column(*col);
}
-template<class T> static void updateval(char *var, T val, char *onchange)
-{
+template<class T> static void updateval(char *var, T val, char *onchange) {
ident *id = writeident(var);
updatelater.add().schedule(id, val);
if(onchange[0]) updatelater.add().schedule(onchange);
}
-static int getval(char *var)
-{
+static int getval(char *var) {
ident *id = readident(var);
if(!id) return 0;
- switch(id->type)
- {
+ switch(id->type) {
case ID_VAR: return *id->storage.i;
case ID_FVAR: return int(*id->storage.f);
case ID_SVAR: return parseint(*id->storage.s);
@@ -361,12 +299,10 @@ static int getval(char *var)
}
}
-static float getfval(char *var)
-{
+static float getfval(char *var) {
ident *id = readident(var);
if(!id) return 0;
- switch(id->type)
- {
+ switch(id->type) {
case ID_VAR: return *id->storage.i;
case ID_FVAR: return *id->storage.f;
case ID_SVAR: return parsefloat(*id->storage.s);
@@ -375,12 +311,10 @@ static float getfval(char *var)
}
}
-static const char *getsval(char *var)
-{
+static const char *getsval(char *var) {
ident *id = readident(var);
if(!id) return "";
- switch(id->type)
- {
+ switch(id->type) {
case ID_VAR: return intstr(*id->storage.i);
case ID_FVAR: return floatstr(*id->storage.f);
case ID_SVAR: return *id->storage.s;
@@ -389,21 +323,18 @@ static const char *getsval(char *var)
}
}
-void guislider(char *var, int *min, int *max, char *onchange)
-{
+void guislider(char *var, int *min, int *max, char *onchange) {
if(!cgui) return;
int oldval = getval(var), val = oldval, vmin = *max > INT_MIN ? *min : getvarmin(var), vmax = *max > INT_MIN ? *max : getvarmax(var);
cgui->slider(val, vmin, vmax, GUI_TITLE_COLOR);
if(val != oldval) updateval(var, val, onchange);
}
-void guilistslider(char *var, char *list, char *onchange)
-{
+void guilistslider(char *var, char *list, char *onchange) {
if(!cgui) return;
vector<int> vals;
list += strspn(list, "\n\t ");
- while(*list)
- {
+ while(*list) {
vals.add(parseint(list));
list += strcspn(list, "\n\t \0");
list += strspn(list, "\n\t ");
@@ -415,13 +346,11 @@ void guilistslider(char *var, char *list, char *onchange)
if(offset != oldoffset) updateval(var, vals[offset], onchange);
}
-void guinameslider(char *var, char *names, char *list, char *onchange)
-{
+void guinameslider(char *var, char *names, char *list, char *onchange) {
if(!cgui) return;
vector<int> vals;
list += strspn(list, "\n\t ");
- while(*list)
- {
+ while(*list) {
vals.add(parseint(list));
list += strcspn(list, "\n\t \0");
list += strspn(list, "\n\t ");
@@ -435,37 +364,30 @@ void guinameslider(char *var, char *names, char *list, char *onchange)
delete[] label;
}
-void guicheckbox(char *name, char *var, float *on, float *off, char *onchange)
-{
+void guicheckbox(char *name, char *var, float *on, float *off, char *onchange) {
bool enabled = getfval(var)!=*off;
- if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "checkbox_on" : "checkbox_off")&G3D_UP)
- {
+ if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "checkbox_on" : "checkbox_off")&G3D_UP) {
updateval(var, enabled ? *off : (*on || *off ? *on : 1.0f), onchange);
}
}
-void guiradio(char *name, char *var, float *n, char *onchange)
-{
+void guiradio(char *name, char *var, float *n, char *onchange) {
bool enabled = getfval(var)==*n;
- if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "radio_on" : "radio_off")&G3D_UP)
- {
+ if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "radio_on" : "radio_off")&G3D_UP) {
if(!enabled) updateval(var, *n, onchange);
}
}
-void guibitfield(char *name, char *var, int *mask, char *onchange)
-{
+void guibitfield(char *name, char *var, int *mask, char *onchange) {
int val = getval(var);
bool enabled = (val & *mask) != 0;
- if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "checkbox_on" : "checkbox_off")&G3D_UP)
- {
+ if(cgui && cgui->button(name, GUI_BUTTON_COLOR, enabled ? "checkbox_on" : "checkbox_off")&G3D_UP) {
updateval(var, enabled ? val & ~*mask : val | *mask, onchange);
}
}
//-ve length indicates a wrapped text field of any (approx 260 chars) length, |length| is the field width
-void guifield(char *var, int *maxlength, char *onchange)
-{
+void guifield(char *var, int *maxlength, char *onchange) {
if(!cgui) return;
const char *initval = getsval(var);
char *result = cgui->field(var, GUI_BUTTON_COLOR, *maxlength ? *maxlength : 12, 0, initval);
@@ -473,16 +395,14 @@ void guifield(char *var, int *maxlength, char *onchange)
}
//-ve maxlength indicates a wrapped text field of any (approx 260 chars) length, |maxlength| is the field width
-void guieditor(char *name, int *maxlength, int *height, int *mode)
-{
+void guieditor(char *name, int *maxlength, int *height, int *mode) {
if(!cgui) return;
cgui->field(name, GUI_BUTTON_COLOR, *maxlength ? *maxlength : 12, *height, NULL, *mode<=0 ? EDITORFOREVER : *mode);
//returns a non-NULL pointer (the currentline) when the user commits, could then manipulate via text* commands
}
//-ve length indicates a wrapped text field of any (approx 260 chars) length, |length| is the field width
-void guikeyfield(char *var, int *maxlength, char *onchange)
-{
+void guikeyfield(char *var, int *maxlength, char *onchange) {
if(!cgui) return;
const char *initval = getsval(var);
char *result = cgui->keyfield(var, GUI_BUTTON_COLOR, *maxlength ? *maxlength : -8, 0, initval);
@@ -492,16 +412,14 @@ void guikeyfield(char *var, int *maxlength, char *onchange)
//use text<action> to do more...
-void guilist(uint *contents)
-{
+void guilist(uint *contents) {
if(!cgui) return;
cgui->pushlist();
execute(contents);
cgui->poplist();
}
-void guialign(int *align, uint *contents)
-{
+void guialign(int *align, uint *contents) {
if(!cgui) return;
cgui->pushlist();
if(*align >= 0) cgui->spring();
@@ -510,38 +428,31 @@ void guialign(int *align, uint *contents)
cgui->poplist();
}
-void newgui(char *name, char *contents, char *header, char *init)
-{
+void newgui(char *name, char *contents, char *header, char *init) {
menu *m = guis.access(name);
- if(!m)
- {
+ if(!m) {
name = newstring(name);
m = &guis[name];
m->name = name;
}
- else
- {
+ else {
DELETEA(m->header);
freecode(m->contents);
freecode(m->init);
}
- if(header && header[0])
- {
+ if(header && header[0]) {
char *end = NULL;
int val = strtol(header, &end, 0);
- if(end && !*end)
- {
+ if(end && !*end) {
m->header = NULL;
m->showtab = val != 0;
}
- else
- {
+ else {
m->header = newstring(header);
m->showtab = true;
}
}
- else
- {
+ else {
m->header = NULL;
m->showtab = true;
}
@@ -551,14 +462,11 @@ void newgui(char *name, char *contents, char *header, char *init)
menu *guiserversmenu = NULL;
-void guiservers(uint *header, int *pagemin, int *pagemax)
-{
+void guiservers(uint *header, int *pagemin, int *pagemax) {
extern const char *showservers(g3d_gui *cgui, uint *header, int pagemin, int pagemax);
- if(cgui)
- {
+ if(cgui) {
const char *command = showservers(cgui, header, *pagemin, *pagemax > 0 ? *pagemax : INT_MAX);
- if(command)
- {
+ if(command) {
updatelater.add().schedule(command);
if(shouldclearmenu) clearlater = true;
guiserversmenu = clearlater || guistack.empty() ? NULL : guistack.last();
@@ -566,10 +474,8 @@ void guiservers(uint *header, int *pagemin, int *pagemax)
}
}
-void notifywelcome()
-{
- if(guiserversmenu)
- {
+void notifywelcome() {
+ if(guiserversmenu) {
if(guistack.length() && guistack.last() == guiserversmenu) clearguis();
guiserversmenu = NULL;
}
@@ -608,14 +514,11 @@ COMMAND(guieditor, "siii");
COMMAND(guicolor, "i");
COMMAND(guitextbox, "siii");
-void guiplayerpreview(int *model, int *team, int *weap, char *action, float *scale, int *overlaid, char *title)
-{
+void guiplayerpreview(int *model, int *team, int *weap, char *action, float *scale, int *overlaid, char *title) {
if(!cgui) return;
int ret = cgui->playerpreview(*model, *team, *weap, *scale, *overlaid!=0 ? title : NULL);
- if(ret&G3D_UP)
- {
- if(*action)
- {
+ if(ret&G3D_UP) {
+ if(*action) {
updatelater.add().schedule(action);
if(shouldclearmenu) clearlater = true;
}
@@ -623,84 +526,68 @@ void guiplayerpreview(int *model, int *team, int *weap, char *action, float *sca
}
COMMAND(guiplayerpreview, "iiisfis");
-void guimodelpreview(char *model, char *animspec, char *action, float *scale, int *overlaid, char *title, int *throttle)
-{
+void guimodelpreview(char *model, char *animspec, char *action, float *scale, int *overlaid, char *title, int *throttle) {
if(!cgui) return;
int anim = ANIM_ALL;
- if(animspec[0])
- {
- if(isdigit(animspec[0]))
- {
+ if(animspec[0]) {
+ if(isdigit(animspec[0])) {
anim = parseint(animspec);
if(anim >= 0) anim %= ANIM_INDEX;
else anim = ANIM_ALL;
}
- else
- {
+ else {
vector<int> anims;
findanims(animspec, anims);
if(anims.length()) anim = anims[0];
}
}
int ret = cgui->modelpreview(model, anim|ANIM_LOOP, *scale, *overlaid!=0 ? title : NULL, *throttle!=0);
- if(ret&G3D_UP)
- {
- if(*action)
- {
+ if(ret&G3D_UP) {
+ if(*action) {
updatelater.add().schedule(action);
if(shouldclearmenu) clearlater = true;
}
}
- else if(ret&G3D_ROLLOVER)
- {
+ else if(ret&G3D_ROLLOVER) {
alias("guirolloverpreviewname", model);
alias("guirolloverpreviewaction", action);
}
}
COMMAND(guimodelpreview, "sssfisi");
-void guiprefabpreview(char *prefab, int *color, char *action, float *scale, int *overlaid, char *title, int *throttle)
-{
+void guiprefabpreview(char *prefab, int *color, char *action, float *scale, int *overlaid, char *title, int *throttle) {
if(!cgui) return;
int ret = cgui->prefabpreview(prefab, vec::hexcolor(*color), *scale, *overlaid!=0 ? title : NULL, *throttle!=0);
- if(ret&G3D_UP)
- {
- if(*action)
- {
+ if(ret&G3D_UP) {
+ if(*action) {
updatelater.add().schedule(action);
if(shouldclearmenu) clearlater = true;
}
}
- else if(ret&G3D_ROLLOVER)
- {
+ else if(ret&G3D_ROLLOVER) {
alias("guirolloverpreviewname", prefab);
alias("guirolloverpreviewaction", action);
}
}
COMMAND(guiprefabpreview, "sisfisi");
-struct change
-{
+struct change {
int type;
const char *desc;
-
change() {}
change(int type, const char *desc) : type(type), desc(desc) {}
};
static vector<change> needsapply;
-static struct applymenu : menu
-{
- void gui(g3d_gui &g, bool firstpass)
- {
+static struct applymenu : menu {
+ void gui(g3d_gui &g, bool firstpass) {
if(guistack.empty()) return;
g.start(menustart, 0.03f);
g.text("the following settings have changed:", GUI_TEXT_COLOR, "info");
loopv(needsapply) g.text(needsapply[i].desc, GUI_TEXT_COLOR, "info");
g.separator();
g.text("apply changes now?", GUI_TEXT_COLOR, "info");
- if(g.button("yes", GUI_BUTTON_COLOR, "action")&G3D_UP)
- {
+ if(g.button("yes", GUI_BUTTON_COLOR, "action")&G3D_UP) {
int changetypes = 0;
loopv(needsapply) changetypes |= needsapply[i].type;
if(changetypes&CHANGE_GFX) updatelater.add().schedule("resetgl");
@@ -711,9 +598,7 @@ static struct applymenu : menu
clearlater = true;
g.end();
}
-
- void clear()
- {
+ void clear() {
menu::clear();
needsapply.shrink(0);
}
@@ -723,8 +608,7 @@ VARP(applydialog, 0, 1, 1);
static bool processingmenu = false;
-void addchange(const char *desc, int type)
-{
+void addchange(const char *desc, int type) {
if(!applydialog) return;
loopv(needsapply) if(!strcmp(needsapply[i].desc, desc)) return;
needsapply.add(change(type, desc));
@@ -732,12 +616,9 @@ void addchange(const char *desc, int type)
pushgui(&applymenu, processingmenu ? max(guistack.length()-1, 0) : -1);
}
-void clearchanges(int type)
-{
- loopv(needsapply)
- {
- if(needsapply[i].type&type)
- {
+void clearchanges(int type) {
+ loopv(needsapply) {
+ if(needsapply[i].type&type) {
needsapply[i].type &= ~type;
if(!needsapply[i].type) needsapply.remove(i--);
}
@@ -745,14 +626,12 @@ void clearchanges(int type)
if(needsapply.empty()) removegui(&applymenu);
}
-void menuprocess()
-{
+void menuprocess() {
processingmenu = true;
int wasmain = mainmenu, level = guistack.length();
loopv(updatelater) updatelater[i].run();
updatelater.shrink(0);
- if(wasmain > mainmenu || clearlater)
- {
+ if(wasmain > mainmenu || clearlater) {
if(wasmain > mainmenu || level==guistack.length()) clearguis(level);
clearlater = false;
}
@@ -762,19 +641,15 @@ void menuprocess()
VAR(mainmenu, 1, 1, 0);
-void clearmainmenu()
-{
- if(mainmenu && isconnected())
- {
+void clearmainmenu() {
+ if(mainmenu && isconnected()) {
mainmenu = 0;
if(!processingmenu) cleargui();
}
}
-void g3d_mainmenu()
-{
- if(!guistack.empty())
- {
+void g3d_mainmenu() {
+ if(!guistack.empty()) {
extern int usegui2d;
if(!mainmenu && !usegui2d && camera1->o.dist(menupos) > menuautoclose) cleargui();
else g3d_addgui(guistack.last(), menupos, GUI_2D | GUI_FOLLOW);
diff --git a/src/engine/model.h b/src/engine/model.h
index 82aea40..16f1629 100644
--- a/src/engine/model.h
+++ b/src/engine/model.h
@@ -1,7 +1,6 @@
-enum { MDL_MD3, MDL_MD5, MDL_IQM, NUMMODELTYPES };
+enum { MDL_MD5, MDL_IQM, NUMMODELTYPES };
-struct model
-{
+struct model {
char *name;
float spinyaw, spinpitch, offsetyaw, offsetpitch;
bool collide, ellipsecollide, shadow, alphadepth, depthoffset;
@@ -11,7 +10,6 @@ struct model
vec bbcenter, bbradius, bbextend, collidecenter, collideradius;
float rejectradius, eyeheight, collidexyradius, collideheight;
int batch;
-
model(const char *name) : name(name ? newstring(name) : NULL), spinyaw(0), spinpitch(0), offsetyaw(0), offsetpitch(0), collide(true), ellipsecollide(false), shadow(true), alphadepth(true), depthoffset(false), scale(1.0f), translate(0, 0, 0), bih(0), bbcenter(0, 0, 0), bbradius(-1, -1, -1), bbextend(0, 0, 0), collidecenter(0, 0, 0), collideradius(-1, -1, -1), rejectradius(-1), eyeheight(0.9f), collidexyradius(0), collideheight(0), batch(-1) {}
virtual ~model() { DELETEA(name); DELETEP(bih); }
virtual void calcbb(vec &center, vec &radius) = 0;
@@ -20,46 +18,35 @@ struct model
virtual int type() const = 0;
virtual BIH *setBIH() { return 0; }
virtual bool skeletal() const { return false; }
-
- virtual void setshader(Shader *shader) {}
- virtual void setspec(float spec) {}
- virtual void setambient(float ambient) {}
- virtual void setalphatest(float alpha) {}
- virtual void setalphablend(bool blend) {}
- virtual void setfullbright(float fullbright) {}
- virtual void setcullface(bool cullface) {}
-
+ virtual void setshader(Shader *) {}
+ virtual void setspec(float) {}
+ virtual void setambient(float) {}
+ virtual void setalphatest(float) {}
+ virtual void setalphablend(bool) {}
+ virtual void setfullbright(float) {}
+ virtual void setcullface(bool) {}
virtual void preloadBIH() { if(!bih) setBIH(); }
- virtual void preloadshaders(bool force = false) {}
+ virtual void preloadshaders() {}
virtual void preloadmeshes() {}
virtual void cleanup() {}
-
virtual void startrender() {}
virtual void endrender() {}
-
- void boundbox(vec &center, vec &radius)
- {
- if(bbradius.x < 0)
- {
+ void boundbox(vec &center, vec &radius) {
+ if(bbradius.x < 0) {
calcbb(bbcenter, bbradius);
bbradius.add(bbextend);
}
center = bbcenter;
radius = bbradius;
}
-
- float collisionbox(vec &center, vec &radius)
- {
- if(collideradius.x < 0)
- {
+ float collisionbox(vec &center, vec &radius) {
+ if(collideradius.x < 0) {
boundbox(collidecenter, collideradius);
- if(collidexyradius)
- {
+ if(collidexyradius) {
collidecenter.x = collidecenter.y = 0;
collideradius.x = collideradius.y = collidexyradius;
}
- if(collideheight)
- {
+ if(collideheight) {
collidecenter.z = collideradius.z = collideheight/2;
}
rejectradius = vec(collidecenter).abs().add(collideradius).magnitude();
@@ -68,16 +55,12 @@ struct model
radius = collideradius;
return rejectradius;
}
-
- float boundsphere(vec &center)
- {
+ float boundsphere(vec &center) {
vec radius;
boundbox(center, radius);
return radius.magnitude();
}
-
- float above()
- {
+ float above() {
vec center, radius;
boundbox(center, radius);
return center.z+radius.z;
diff --git a/src/engine/mpr.h b/src/engine/mpr.h
index 6288e4f..6c20869 100644
--- a/src/engine/mpr.h
+++ b/src/engine/mpr.h
@@ -1,41 +1,28 @@
// This code is based off the Minkowski Portal Refinement algorithm by Gary Snethen in XenoCollide & Game Programming Gems 7.
-namespace mpr
-{
- struct CubePlanes
- {
+namespace mpr {
+ struct CubePlanes {
const clipplanes &p;
-
CubePlanes(const clipplanes &p) : p(p) {}
-
vec center() const { return p.o; }
-
- vec supportpoint(const vec &n) const
- {
+ vec supportpoint(const vec &n) const {
int besti = 7;
float bestd = n.dot(p.v[7]);
- loopi(7)
- {
+ loopi(7) {
float d = n.dot(p.v[i]);
if(d > bestd) { besti = i; bestd = d; }
}
return p.v[besti];
}
};
-
- struct SolidCube
- {
+ struct SolidCube {
vec o;
int size;
-
SolidCube(float x, float y, float z, int size) : o(x, y, z), size(size) {}
SolidCube(const vec &o, int size) : o(o), size(size) {}
SolidCube(const ivec &o, int size) : o(o), size(size) {}
-
vec center() const { return vec(o).add(size/2); }
-
- vec supportpoint(const vec &n) const
- {
+ vec supportpoint(const vec &n) const {
vec p(o);
if(n.x > 0) p.x += size;
if(n.y > 0) p.y += size;
@@ -43,36 +30,24 @@ namespace mpr
return p;
}
};
-
- struct Ent
- {
+ struct Ent {
physent *ent;
-
Ent(physent *ent) : ent(ent) {}
-
vec center() const { return vec(ent->o.x, ent->o.y, ent->o.z + (ent->aboveeye - ent->eyeheight)/2); }
};
-
- struct EntOBB : Ent
- {
+ struct EntOBB : Ent {
matrix3 orient;
float zmargin;
-
- EntOBB(physent *ent, float zmargin = 0) : Ent(ent), zmargin(zmargin)
- {
+ EntOBB(physent *ent, float zmargin = 0) : Ent(ent), zmargin(zmargin) {
orient.setyaw(ent->yaw*RAD);
}
-
vec center() const { return vec(ent->o.x, ent->o.y, ent->o.z + (ent->aboveeye - ent->eyeheight - zmargin)/2); }
-
- vec contactface(const vec &wn, const vec &wdir) const
- {
+ vec contactface(const vec &wn, const vec &wdir) const {
vec n = orient.transform(wn).div(vec(ent->xradius, ent->yradius, (ent->aboveeye + ent->eyeheight + zmargin)/2)),
dir = orient.transform(wdir),
an(fabs(n.x), fabs(n.y), dir.z ? fabs(n.z) : 0),
fn(0, 0, 0);
- if(an.x > an.y)
- {
+ if(an.x > an.y) {
if(an.x > an.z) fn.x = n.x*dir.x < 0 ? (n.x > 0 ? 1 : -1) : 0;
else if(an.z > 0) fn.z = n.z*dir.z < 0 ? (n.z > 0 ? 1 : -1) : 0;
}
@@ -80,28 +55,20 @@ namespace mpr
else if(an.z > 0) fn.z = n.z*dir.z < 0 ? (n.z > 0 ? 1 : -1) : 0;
return orient.transposedtransform(fn);
}
-
- vec localsupportpoint(const vec &ln) const
- {
+ vec localsupportpoint(const vec &ln) const {
return vec(ln.x > 0 ? ent->xradius : -ent->xradius,
ln.y > 0 ? ent->yradius : -ent->yradius,
ln.z > 0 ? ent->aboveeye : -ent->eyeheight - zmargin);
}
-
- vec supportpoint(const vec &n) const
- {
+ vec supportpoint(const vec &n) const {
return orient.transposedtransform(localsupportpoint(orient.transform(n))).add(ent->o);
}
-
- float supportcoordneg(float a, float b, float c) const
- {
+ float supportcoordneg(float a, float b, float c) const {
return localsupportpoint(vec(-a, -b, -c)).dot(vec(a, b, c));
}
- float supportcoord(float a, float b, float c) const
- {
+ float supportcoord(float a, float b, float c) const {
return localsupportpoint(vec(a, b, c)).dot(vec(a, b, c));
}
-
float left() const { return supportcoordneg(orient.a.x, orient.b.x, orient.c.x) + ent->o.x; }
float right() const { return supportcoord(orient.a.x, orient.b.x, orient.c.x) + ent->o.x; }
float back() const { return supportcoordneg(orient.a.y, orient.b.y, orient.c.y) + ent->o.y; }
@@ -109,11 +76,8 @@ namespace mpr
float bottom() const { return ent->o.z - ent->eyeheight - zmargin; }
float top() const { return ent->o.z + ent->aboveeye; }
};
-
- struct EntFuzzy : Ent
- {
+ struct EntFuzzy : Ent {
EntFuzzy(physent *ent) : Ent(ent) {}
-
float left() const { return ent->o.x - ent->radius; }
float right() const { return ent->o.x + ent->radius; }
float back() const { return ent->o.y - ent->radius; }
@@ -121,38 +85,27 @@ namespace mpr
float bottom() const { return ent->o.z - ent->eyeheight; }
float top() const { return ent->o.z + ent->aboveeye; }
};
-
- struct EntCylinder : EntFuzzy
- {
+ struct EntCylinder : EntFuzzy {
float zmargin;
-
EntCylinder(physent *ent, float zmargin = 0) : EntFuzzy(ent), zmargin(zmargin) {}
-
vec center() const { return vec(ent->o.x, ent->o.y, ent->o.z + (ent->aboveeye - ent->eyeheight - zmargin)/2); }
-
float bottom() const { return ent->o.z - ent->eyeheight - zmargin; }
-
- vec contactface(const vec &n, const vec &dir) const
- {
+ vec contactface(const vec &n, const vec &dir) const {
float dxy = n.dot2(n)/(ent->radius*ent->radius), dz = n.z*n.z*4/(ent->aboveeye + ent->eyeheight + zmargin);
vec fn(0, 0, 0);
if(dz > dxy && dir.z) fn.z = n.z*dir.z < 0 ? (n.z > 0 ? 1 : -1) : 0;
- else if(n.dot2(dir) < 0)
- {
+ else if(n.dot2(dir) < 0) {
fn.x = n.x;
fn.y = n.y;
fn.normalize();
}
return fn;
}
-
- vec supportpoint(const vec &n) const
- {
+ vec supportpoint(const vec &n) const {
vec p(ent->o);
if(n.z > 0) p.z += ent->aboveeye;
else p.z -= ent->eyeheight + zmargin;
- if(n.x || n.y)
- {
+ if(n.x || n.y) {
float r = ent->radius / n.magnitude2();
p.x += n.x*r;
p.y += n.y*r;
@@ -160,13 +113,9 @@ namespace mpr
return p;
}
};
-
- struct EntCapsule : EntFuzzy
- {
+ struct EntCapsule : EntFuzzy {
EntCapsule(physent *ent) : EntFuzzy(ent) {}
-
- vec supportpoint(const vec &n) const
- {
+ vec supportpoint(const vec &n) const {
vec p(ent->o);
if(n.z > 0) p.z += ent->aboveeye - ent->radius;
else p.z -= ent->eyeheight - ent->radius;
@@ -174,13 +123,9 @@ namespace mpr
return p;
}
};
-
- struct EntEllipsoid : EntFuzzy
- {
+ struct EntEllipsoid : EntFuzzy {
EntEllipsoid(physent *ent) : EntFuzzy(ent) {}
-
- vec supportpoint(const vec &dir) const
- {
+ vec supportpoint(const vec &dir) const {
vec p(ent->o), n = vec(dir).normalize();
p.x += ent->radius*n.x;
p.y += ent->radius*n.y;
@@ -188,34 +133,24 @@ namespace mpr
return p;
}
};
-
- struct Model
- {
+ struct Model {
vec o, radius;
matrix3 orient;
-
- Model(const vec &ent, const vec &center, const vec &radius, int yaw) : o(ent), radius(radius)
- {
+ Model(const vec &ent, const vec &center, const vec &radius, int yaw) : o(ent), radius(radius) {
orient.setyaw(yaw*RAD);
o.add(orient.transposedtransform(center));
}
-
vec center() const { return o; }
};
-
- struct ModelOBB : Model
- {
+ struct ModelOBB : Model {
ModelOBB(const vec &ent, const vec &center, const vec &radius, int yaw) :
- Model(ent, center, radius, yaw)
- {}
-
- vec contactface(const vec &wn, const vec &wdir) const
- {
+ Model(ent, center, radius, yaw) {
+ }
+ vec contactface(const vec &wn, const vec &wdir) const {
vec n = orient.transform(wn).div(radius), dir = orient.transform(wdir),
an(fabs(n.x), fabs(n.y), dir.z ? fabs(n.z) : 0),
fn(0, 0, 0);
- if(an.x > an.y)
- {
+ if(an.x > an.y) {
if(an.x > an.z) fn.x = n.x*dir.x < 0 ? (n.x > 0 ? 1 : -1) : 0;
else if(an.z > 0) fn.z = n.z*dir.z < 0 ? (n.z > 0 ? 1 : -1) : 0;
}
@@ -223,9 +158,7 @@ namespace mpr
else if(an.z > 0) fn.z = n.z*dir.z < 0 ? (n.z > 0 ? 1 : -1) : 0;
return orient.transposedtransform(fn);
}
-
- vec supportpoint(const vec &n) const
- {
+ vec supportpoint(const vec &n) const {
vec ln = orient.transform(n), p(0, 0, 0);
if(ln.x > 0) p.x += radius.x;
else p.x -= radius.x;
@@ -236,35 +169,27 @@ namespace mpr
return orient.transposedtransform(p).add(o);
}
};
-
- struct ModelEllipse : Model
- {
+ struct ModelEllipse : Model {
ModelEllipse(const vec &ent, const vec &center, const vec &radius, int yaw) :
- Model(ent, center, radius, yaw)
- {}
-
- vec contactface(const vec &wn, const vec &wdir) const
- {
+ Model(ent, center, radius, yaw) {
+ }
+ vec contactface(const vec &wn, const vec &wdir) const {
vec n = orient.transform(wn).div(radius), dir = orient.transform(wdir);
float dxy = n.dot2(n), dz = n.z*n.z;
vec fn(0, 0, 0);
if(dz > dxy && dir.z) fn.z = n.z*dir.z < 0 ? (n.z > 0 ? 1 : -1) : 0;
- else if(n.dot2(dir) < 0)
- {
+ else if(n.dot2(dir) < 0) {
fn.x = n.x*radius.y;
fn.y = n.y*radius.x;
fn.normalize();
}
return orient.transposedtransform(fn);
}
-
- vec supportpoint(const vec &n) const
- {
+ vec supportpoint(const vec &n) const {
vec ln = orient.transform(n), p(0, 0, 0);
if(ln.z > 0) p.z += radius.z;
else p.z -= radius.z;
- if(ln.x || ln.y)
- {
+ if(ln.x || ln.y) {
float r = ln.magnitude2();
p.x += ln.x*radius.x/r;
p.y += ln.y*radius.y/r;
@@ -272,83 +197,60 @@ namespace mpr
return orient.transposedtransform(p).add(o);
}
};
-
const float boundarytolerance = 1e-3f;
-
template<class T, class U>
- bool collide(const T &p1, const U &p2)
- {
+ bool collide(const T &p1, const U &p2) {
// v0 = center of Minkowski difference
vec v0 = p2.center().sub(p1.center());
if(v0.iszero()) return true; // v0 and origin overlap ==> hit
-
// v1 = support in direction of origin
vec n = vec(v0).neg();
vec v1 = p2.supportpoint(n).sub(p1.supportpoint(vec(n).neg()));
if(v1.dot(n) <= 0) return false; // origin outside v1 support plane ==> miss
-
// v2 = support perpendicular to plane containing origin, v0 and v1
n.cross(v1, v0);
if(n.iszero()) return true; // v0, v1 and origin colinear (and origin inside v1 support plane) == > hit
vec v2 = p2.supportpoint(n).sub(p1.supportpoint(vec(n).neg()));
if(v2.dot(n) <= 0) return false; // origin outside v2 support plane ==> miss
-
// v3 = support perpendicular to plane containing v0, v1 and v2
n.cross(v0, v1, v2);
-
// If the origin is on the - side of the plane, reverse the direction of the plane
- if(n.dot(v0) > 0)
- {
+ if(n.dot(v0) > 0) {
swap(v1, v2);
n.neg();
}
-
///
// Phase One: Find a valid portal
-
- loopi(100)
- {
+ loopi(100) {
// Obtain the next support point
vec v3 = p2.supportpoint(n).sub(p1.supportpoint(vec(n).neg()));
if(v3.dot(n) <= 0) return false; // origin outside v3 support plane ==> miss
-
// If origin is outside (v1,v0,v3), then portal is invalid -- eliminate v2 and find new support outside face
vec v3xv0;
v3xv0.cross(v3, v0);
- if(v1.dot(v3xv0) < 0)
- {
+ if(v1.dot(v3xv0) < 0) {
v2 = v3;
n.cross(v0, v1, v3);
continue;
}
-
// If origin is outside (v3,v0,v2), then portal is invalid -- eliminate v1 and find new support outside face
- if(v2.dot(v3xv0) > 0)
- {
+ if(v2.dot(v3xv0) > 0) {
v1 = v3;
n.cross(v0, v3, v2);
continue;
}
-
///
// Phase Two: Refine the portal
-
- for(int j = 0;; j++)
- {
+ for(int j = 0;; j++) {
// Compute outward facing normal of the portal
n.cross(v1, v2, v3);
-
// If the origin is inside the portal, we have a hit
if(n.dot(v1) >= 0) return true;
-
n.normalize();
-
// Find the support point in the direction of the portal's normal
vec v4 = p2.supportpoint(n).sub(p1.supportpoint(vec(n).neg()));
-
// If the origin is outside the support plane or the boundary is thin enough, we have a miss
if(v4.dot(n) <= 0 || vec(v4).sub(v3).dot(n) <= boundarytolerance || j > 100) return false;
-
// Test origin against the three planes that separate the new portal candidates: (v1,v4,v0) (v2,v4,v0) (v3,v4,v0)
// Note: We're taking advantage of the triple product identities here as an optimization
// (v1 % v4) * v0 == v1 * (v4 % v0) > 0 if origin inside (v1, v4, v0)
@@ -356,13 +258,11 @@ namespace mpr
// (v3 % v4) * v0 == v3 * (v4 % v0) > 0 if origin inside (v3, v4, v0)
vec v4xv0;
v4xv0.cross(v4, v0);
- if(v1.dot(v4xv0) > 0)
- {
+ if(v1.dot(v4xv0) > 0) {
if(v2.dot(v4xv0) > 0) v1 = v4; // Inside v1 & inside v2 ==> eliminate v1
else v3 = v4; // Inside v1 & outside v2 ==> eliminate v3
}
- else
- {
+ else {
if(v3.dot(v4xv0) > 0) v2 = v4; // Outside v1 & inside v3 ==> eliminate v2
else v1 = v4; // Outside v1 & outside v3 ==> eliminate v1
}
@@ -370,33 +270,26 @@ namespace mpr
}
return false;
}
-
template<class T, class U>
- bool collide(const T &p1, const U &p2, vec *contactnormal, vec *contactpoint1, vec *contactpoint2)
- {
+ bool collide(const T &p1, const U &p2, vec *contactnormal, vec *contactpoint1, vec *contactpoint2) {
// v0 = center of Minkowski sum
vec v01 = p1.center();
vec v02 = p2.center();
vec v0 = vec(v02).sub(v01);
-
// Avoid case where centers overlap -- any direction is fine in this case
if(v0.iszero()) v0 = vec(0, 0, 1e-5f);
-
// v1 = support in direction of origin
vec n = vec(v0).neg();
vec v11 = p1.supportpoint(vec(n).neg());
vec v12 = p2.supportpoint(n);
vec v1 = vec(v12).sub(v11);
- if(v1.dot(n) <= 0)
- {
+ if(v1.dot(n) <= 0) {
if(contactnormal) *contactnormal = n;
return false;
}
-
// v2 - support perpendicular to v1,v0
n.cross(v1, v0);
- if(n.iszero())
- {
+ if(n.iszero()) {
n = vec(v1).sub(v0);
n.normalize();
if(contactnormal) *contactnormal = n;
@@ -407,97 +300,74 @@ namespace mpr
vec v21 = p1.supportpoint(vec(n).neg());
vec v22 = p2.supportpoint(n);
vec v2 = vec(v22).sub(v21);
- if(v2.dot(n) <= 0)
- {
+ if(v2.dot(n) <= 0) {
if(contactnormal) *contactnormal = n;
return false;
}
-
// Determine whether origin is on + or - side of plane (v1,v0,v2)
n.cross(v0, v1, v2);
ASSERT( !n.iszero() );
// If the origin is on the - side of the plane, reverse the direction of the plane
- if(n.dot(v0) > 0)
- {
+ if(n.dot(v0) > 0) {
swap(v1, v2);
swap(v11, v21);
swap(v12, v22);
n.neg();
}
-
///
// Phase One: Identify a portal
-
- loopi(100)
- {
+ loopi(100) {
// Obtain the support point in a direction perpendicular to the existing plane
// Note: This point is guaranteed to lie off the plane
vec v31 = p1.supportpoint(vec(n).neg());
vec v32 = p2.supportpoint(n);
vec v3 = vec(v32).sub(v31);
- if(v3.dot(n) <= 0)
- {
+ if(v3.dot(n) <= 0) {
if(contactnormal) *contactnormal = n;
return false;
}
-
// If origin is outside (v1,v0,v3), then eliminate v2 and loop
vec v3xv0;
v3xv0.cross(v3, v0);
- if(v1.dot(v3xv0) < 0)
- {
+ if(v1.dot(v3xv0) < 0) {
v2 = v3;
v21 = v31;
v22 = v32;
n.cross(v0, v1, v3);
continue;
}
-
// If origin is outside (v3,v0,v2), then eliminate v1 and loop
- if(v2.dot(v3xv0) > 0)
- {
+ if(v2.dot(v3xv0) > 0) {
v1 = v3;
v11 = v31;
v12 = v32;
n.cross(v0, v3, v2);
continue;
}
-
bool hit = false;
-
///
// Phase Two: Refine the portal
-
// We are now inside of a wedge...
- for(int j = 0;; j++)
- {
+ for(int j = 0;; j++) {
// Compute normal of the wedge face
n.cross(v1, v2, v3);
-
// Can this happen??? Can it be handled more cleanly?
- if(n.iszero())
- {
+ if(n.iszero()) {
ASSERT(0);
return true;
}
-
n.normalize();
-
// If the origin is inside the wedge, we have a hit
- if(n.dot(v1) >= 0 && !hit)
- {
+ if(n.dot(v1) >= 0 && !hit) {
if(contactnormal) *contactnormal = n;
-
// Compute the barycentric coordinates of the origin
- if(contactpoint1 || contactpoint2)
- {
+ if(contactpoint1 || contactpoint2) {
float b0 = v3.scalartriple(v1, v2),
b1 = v0.scalartriple(v3, v2),
b2 = v3.scalartriple(v0, v1),
b3 = v0.scalartriple(v2, v1),
sum = b0 + b1 + b2 + b3;
- if(sum <= 0)
- {
+ if(sum <= 0) {
b0 = 0;
b1 = n.scalartriple(v2, v3);
b2 = n.scalartriple(v3, v1);
@@ -509,23 +379,18 @@ namespace mpr
if(contactpoint2)
*contactpoint2 = (vec(v02).mul(b0).add(vec(v12).mul(b1)).add(vec(v22).mul(b2)).add(vec(v32).mul(b3))).mul(1.0f/sum);
}
-
// HIT!!!
hit = true;
}
-
// Find the support point in the direction of the wedge face
vec v41 = p1.supportpoint(vec(n).neg());
vec v42 = p2.supportpoint(n);
vec v4 = vec(v42).sub(v41);
-
// If the boundary is thin enough or the origin is outside the support plane for the newly discovered vertex, then we can terminate
- if(v4.dot(n) <= 0 || vec(v4).sub(v3).dot(n) <= boundarytolerance || j > 100)
- {
+ if(v4.dot(n) <= 0 || vec(v4).sub(v3).dot(n) <= boundarytolerance || j > 100) {
if(contactnormal) *contactnormal = n;
return hit;
}
-
// Test origin against the three planes that separate the new portal candidates: (v1,v4,v0) (v2,v4,v0) (v3,v4,v0)
// Note: We're taking advantage of the triple product identities here as an optimization
// (v1 % v4) * v0 == v1 * (v4 % v0) > 0 if origin inside (v1, v4, v0)
@@ -533,34 +398,28 @@ namespace mpr
// (v3 % v4) * v0 == v3 * (v4 % v0) > 0 if origin inside (v3, v4, v0)
vec v4xv0;
v4xv0.cross(v4, v0);
- if(v1.dot(v4xv0) > 0) // Compute the tetrahedron dividing face d1 = (v4,v0,v1)
- {
- if(v2.dot(v4xv0) > 0) // Compute the tetrahedron dividing face d2 = (v4,v0,v2)
- {
+ if(v1.dot(v4xv0) > 0) { // Compute the tetrahedron dividing face d1 = (v4,v0,v1) {
+ if(v2.dot(v4xv0) > 0) { // Compute the tetrahedron dividing face d2 = (v4,v0,v2) {
// Inside d1 & inside d2 ==> eliminate v1
v1 = v4;
v11 = v41;
v12 = v42;
}
- else
- {
+ else {
// Inside d1 & outside d2 ==> eliminate v3
v3 = v4;
v31 = v41;
v32 = v42;
}
}
- else
- {
- if(v3.dot(v4xv0) > 0) // Compute the tetrahedron dividing face d3 = (v4,v0,v3)
- {
+ else {
+ if(v3.dot(v4xv0) > 0) { // Compute the tetrahedron dividing face d3 = (v4,v0,v3) {
// Outside d1 & inside d3 ==> eliminate v2
v2 = v4;
v21 = v41;
v22 = v42;
}
- else
- {
+ else {
// Outside d1 & outside d3 ==> eliminate v1
v1 = v4;
v11 = v41;
@@ -572,4 +431,3 @@ namespace mpr
return false;
}
}
-
diff --git a/src/engine/normal.cpp b/src/engine/normal.cpp
index cba6777..64c21c6 100644
--- a/src/engine/normal.cpp
+++ b/src/engine/normal.cpp
@@ -1,24 +1,20 @@
#include "engine.h"
-struct normalgroup
-{
+struct normalgroup {
vec pos;
int flat, normals, tnormals;
-
normalgroup() : flat(0), normals(-1), tnormals(-1) {}
normalgroup(const vec &pos) : pos(pos), flat(0), normals(-1), tnormals(-1) {}
};
static inline bool htcmp(const vec &v, const normalgroup &n) { return v == n.pos; }
-struct normal
-{
+struct normal {
int next;
vec surface;
};
-struct tnormal
-{
+struct tnormal {
int next;
float offset;
int normals[2];
@@ -34,8 +30,7 @@ VARR(lerpangle, 0, 44, 180);
static float lerpthreshold = 0;
static bool usetnormals = true;
-static int addnormal(const vec &key, const vec &surface)
-{
+static int addnormal(const vec &key, const vec &surface) {
normalgroup &g = normalgroups.access(key, key);
normal &n = normals.add();
n.next = g.normals;
@@ -43,8 +38,7 @@ static int addnormal(const vec &key, const vec &surface)
return g.normals = normals.length()-1;
}
-static void addtnormal(const vec &key, float offset, int normal1, int normal2, normalgroup *group1, normalgroup *group2)
-{
+static void addtnormal(const vec &key, float offset, int normal1, int normal2, normalgroup *group1, normalgroup *group2) {
normalgroup &g = normalgroups.access(key, key);
tnormal &n = tnormals.add();
n.next = g.tnormals;
@@ -56,15 +50,13 @@ static void addtnormal(const vec &key, float offset, int normal1, int normal2, n
g.tnormals = tnormals.length()-1;
}
-static int addnormal(const vec &key, int axis)
-{
+static int addnormal(const vec &key, int axis) {
normalgroup &g = normalgroups.access(key, key);
g.flat += 1<<(4*axis);
return axis - 6;
}
-static inline void findnormal(const normalgroup &g, const vec &surface, vec &v)
-{
+static inline void findnormal(const normalgroup &g, const vec &surface, vec &v) {
v = vec(0, 0, 0);
int total = 0;
if(surface.x >= lerpthreshold) { int n = (g.flat>>4)&0xF; v.x += n; total += n; }
@@ -73,11 +65,9 @@ static inline void findnormal(const normalgroup &g, const vec &surface, vec &v)
else if(surface.y <= -lerpthreshold) { int n = (g.flat>>8)&0xF; v.y -= n; total += n; }
if(surface.z >= lerpthreshold) { int n = (g.flat>>20)&0xF; v.z += n; total += n; }
else if(surface.z <= -lerpthreshold) { int n = (g.flat>>16)&0xF; v.z -= n; total += n; }
- for(int cur = g.normals; cur >= 0;)
- {
+ for(int cur = g.normals; cur >= 0;) {
normal &o = normals[cur];
- if(o.surface.dot(surface) >= lerpthreshold)
- {
+ if(o.surface.dot(surface) >= lerpthreshold) {
v.add(o.surface);
total++;
}
@@ -87,12 +77,10 @@ static inline void findnormal(const normalgroup &g, const vec &surface, vec &v)
else if(!total) v = surface;
}
-static inline bool findtnormal(const normalgroup &g, const vec &surface, vec &v)
-{
+static inline bool findtnormal(const normalgroup &g, const vec &surface, vec &v) {
float bestangle = lerpthreshold;
tnormal *bestnorm = NULL;
- for(int cur = g.tnormals; cur >= 0;)
- {
+ for(int cur = g.tnormals; cur >= 0;) {
tnormal &o = tnormals[cur];
static const vec flats[6] = { vec(-1, 0, 0), vec(1, 0, 0), vec(0, -1, 0), vec(0, 1, 0), vec(0, 0, -1), vec(0, 0, 1) };
vec n1 = o.normals[0] < 0 ? flats[o.normals[0]+6] : normals[o.normals[0]].surface,
@@ -100,8 +88,7 @@ static inline bool findtnormal(const normalgroup &g, const vec &surface, vec &v)
nt;
nt.lerp(n1, n2, o.offset).normalize();
float tangle = nt.dot(surface);
- if(tangle >= bestangle)
- {
+ if(tangle >= bestangle) {
bestangle = tangle;
bestnorm = &o;
}
@@ -115,8 +102,7 @@ static inline bool findtnormal(const normalgroup &g, const vec &surface, vec &v)
return true;
}
-void findnormal(const vec &key, const vec &surface, vec &v)
-{
+void findnormal(const vec &key, const vec &surface, vec &v) {
const normalgroup *g = normalgroups.access(key);
if(!g) v = surface;
else if(g->tnormals < 0 || !findtnormal(*g, surface, v))
@@ -128,48 +114,38 @@ VARR(lerpsubdivsize, 4, 4, 128);
static uint progress = 0;
-void show_addnormals_progress()
-{
+void show_addnormals_progress() {
float bar1 = float(progress) / float(allocnodes);
renderprogress(bar1, "computing normals...");
}
-void addnormals(cube &c, const ivec &o, int size)
-{
+void addnormals(cube &c, const ivec &o, int size) {
CHECK_CALCLIGHT_PROGRESS(return, show_addnormals_progress);
-
- if(c.children)
- {
+ if(c.children) {
progress++;
size >>= 1;
loopi(8) addnormals(c.children[i], ivec(i, o, size), size);
return;
}
else if(isempty(c)) return;
-
vec pos[MAXFACEVERTS];
int norms[MAXFACEVERTS];
int tj = usetnormals && c.ext ? c.ext->tjoints : -1, vis;
- loopi(6) if((vis = visibletris(c, i, o, size)))
- {
+ loopi(6) if((vis = visibletris(c, i, o, size))) {
CHECK_CALCLIGHT_PROGRESS(return, show_addnormals_progress);
-
vec planes[2];
int numverts = c.ext ? c.ext->surfaces[i].numverts&MAXFACEVERTS : 0, convex = 0, numplanes = 0;
- if(numverts)
- {
+ if(numverts) {
vertinfo *verts = c.ext->verts() + c.ext->surfaces[i].verts;
vec vo(ivec(o).mask(~0xFFF));
- loopj(numverts)
- {
+ loopj(numverts) {
vertinfo &v = verts[j];
pos[j] = vec(v.x, v.y, v.z).mul(1.0f/8).add(vo);
}
if(!(c.merged&(1<<i)) && !flataxisface(c, i)) convex = faceconvexity(verts, numverts, size);
}
else if(c.merged&(1<<i)) continue;
- else
- {
+ else {
ivec v[4];
genfaceverts(c, i, v);
if(!flataxisface(c, i)) convex = faceconvexity(v);
@@ -180,27 +156,21 @@ void addnormals(cube &c, const ivec &o, int size)
pos[numverts++] = vec(v[order+2]).mul(size/8.0f).add(vo);
if(vis&2) pos[numverts++] = vec(v[(order+3)&3]).mul(size/8.0f).add(vo);
}
-
- if(!flataxisface(c, i))
- {
+ if(!flataxisface(c, i)) {
planes[numplanes++].cross(pos[0], pos[1], pos[2]).normalize();
if(convex) planes[numplanes++].cross(pos[0], pos[2], pos[3]).normalize();
}
-
if(!numplanes) loopk(numverts) norms[k] = addnormal(pos[k], i);
else if(numplanes==1) loopk(numverts) norms[k] = addnormal(pos[k], planes[0]);
- else
- {
+ else {
vec avg = vec(planes[0]).add(planes[1]).normalize();
norms[0] = addnormal(pos[0], avg);
norms[1] = addnormal(pos[1], planes[0]);
norms[2] = addnormal(pos[2], avg);
for(int k = 3; k < numverts; k++) norms[k] = addnormal(pos[k], planes[1]);
}
-
while(tj >= 0 && tjoints[tj].edge < i*(MAXFACEVERTS+1)) tj = tjoints[tj].next;
- while(tj >= 0 && tjoints[tj].edge < (i+1)*(MAXFACEVERTS+1))
- {
+ while(tj >= 0 && tjoints[tj].edge < (i+1)*(MAXFACEVERTS+1)) {
int edge = tjoints[tj].edge, e1 = edge%(MAXFACEVERTS+1), e2 = (e1+1)%numverts;
const vec &v1 = pos[e1], &v2 = pos[e2];
ivec d(vec(v2).sub(v1).mul(8));
@@ -212,9 +182,7 @@ void addnormals(cube &c, const ivec &o, int size)
offset2 = (int(v2[axis]*8) - origin) / d[axis];
vec o = vec(v1).sub(vec(d).mul(offset1/8.0f)), n1, n2;
float doffset = 1.0f / (offset2 - offset1);
-
- while(tj >= 0)
- {
+ while(tj >= 0) {
tjoint &t = tjoints[tj];
if(t.edge != edge) break;
float offset = (t.offset - offset1) * doffset;
@@ -226,8 +194,7 @@ void addnormals(cube &c, const ivec &o, int size)
}
}
-void calcnormals(bool lerptjoints)
-{
+void calcnormals(bool lerptjoints) {
if(!lerpangle) return;
usetnormals = lerptjoints;
if(usetnormals) findtjoints();
@@ -236,20 +203,16 @@ void calcnormals(bool lerptjoints)
loopi(8) addnormals(worldroot[i], ivec(i, ivec(0, 0, 0), worldsize/2), worldsize/2);
}
-void clearnormals()
-{
+void clearnormals() {
normalgroups.clear();
normals.setsize(0);
tnormals.setsize(0);
}
-void calclerpverts(const vec2 *c, const vec *n, lerpvert *lv, int &numv)
-{
+void calclerpverts(const vec2 *c, const vec *n, lerpvert *lv, int &numv) {
int i = 0;
- loopj(numv)
- {
- if(j)
- {
+ loopj(numv) {
+ if(j) {
if(c[j] == c[j-1] && n[j] == n[j-1]) continue;
if(j == numv-1 && c[j] == c[0] && n[j] == n[0]) continue;
}
@@ -260,14 +223,11 @@ void calclerpverts(const vec2 *c, const vec *n, lerpvert *lv, int &numv)
numv = i;
}
-void setlerpstep(float v, lerpbounds &bounds)
-{
- if(bounds.min->tc.y + 1 > bounds.max->tc.y)
- {
+void setlerpstep(float v, lerpbounds &bounds) {
+ if(bounds.min->tc.y + 1 > bounds.max->tc.y) {
bounds.nstep = vec(0, 0, 0);
bounds.normal = bounds.min->normal;
- if(bounds.min->normal != bounds.max->normal)
- {
+ if(bounds.min->normal != bounds.max->normal) {
bounds.normal.add(bounds.max->normal);
bounds.normal.normalize();
}
@@ -275,70 +235,55 @@ void setlerpstep(float v, lerpbounds &bounds)
bounds.u = bounds.min->tc.x;
return;
}
-
bounds.nstep = bounds.max->normal;
bounds.nstep.sub(bounds.min->normal);
bounds.nstep.div(bounds.max->tc.y-bounds.min->tc.y);
-
bounds.normal = bounds.nstep;
bounds.normal.mul(v - bounds.min->tc.y);
bounds.normal.add(bounds.min->normal);
-
bounds.ustep = (bounds.max->tc.x-bounds.min->tc.x) / (bounds.max->tc.y-bounds.min->tc.y);
bounds.u = bounds.ustep * (v-bounds.min->tc.y) + bounds.min->tc.x;
}
-void initlerpbounds(float u, float v, const lerpvert *lv, int numv, lerpbounds &start, lerpbounds &end)
-{
+void initlerpbounds(float u, float v, const lerpvert *lv, int numv, lerpbounds &start, lerpbounds &end) {
const lerpvert *first = &lv[0], *second = NULL;
- loopi(numv-1)
- {
+ loopi(numv-1) {
if(lv[i+1].tc.y < first->tc.y) { second = first; first = &lv[i+1]; }
else if(!second || lv[i+1].tc.y < second->tc.y) second = &lv[i+1];
}
-
if(int(first->tc.y) < int(second->tc.y)) { start.min = end.min = first; }
else if(first->tc.x > second->tc.x) { start.min = second; end.min = first; }
else { start.min = first; end.min = second; }
-
- if((lv[1].tc.x - lv->tc.x)*(lv[2].tc.y - lv->tc.y) > (lv[1].tc.y - lv->tc.y)*(lv[2].tc.x - lv->tc.x))
- {
+ if((lv[1].tc.x - lv->tc.x)*(lv[2].tc.y - lv->tc.y) > (lv[1].tc.y - lv->tc.y)*(lv[2].tc.x - lv->tc.x)) {
start.winding = end.winding = 1;
start.max = (start.min == lv ? &lv[numv-1] : start.min-1);
end.max = (end.min == &lv[numv-1] ? lv : end.min+1);
}
- else
- {
+ else {
start.winding = end.winding = -1;
start.max = (start.min == &lv[numv-1] ? lv : start.min+1);
end.max = (end.min == lv ? &lv[numv-1] : end.min-1);
}
-
setlerpstep(v, start);
setlerpstep(v, end);
}
-void updatelerpbounds(float v, const lerpvert *lv, int numv, lerpbounds &start, lerpbounds &end)
-{
- if(v >= start.max->tc.y)
- {
+void updatelerpbounds(float v, const lerpvert *lv, int numv, lerpbounds &start, lerpbounds &end) {
+ if(v >= start.max->tc.y) {
const lerpvert *next = start.winding > 0 ?
(start.max == lv ? &lv[numv-1] : start.max-1) :
(start.max == &lv[numv-1] ? lv : start.max+1);
- if(next->tc.y > start.max->tc.y)
- {
+ if(next->tc.y > start.max->tc.y) {
start.min = start.max;
start.max = next;
setlerpstep(v, start);
}
}
- if(v >= end.max->tc.y)
- {
+ if(v >= end.max->tc.y) {
const lerpvert *next = end.winding > 0 ?
(end.max == &lv[numv-1] ? lv : end.max+1) :
(end.max == lv ? &lv[numv-1] : end.max-1);
- if(next->tc.y > end.max->tc.y)
- {
+ if(next->tc.y > end.max->tc.y) {
end.min = end.max;
end.max = next;
setlerpstep(v, end);
@@ -346,36 +291,28 @@ void updatelerpbounds(float v, const lerpvert *lv, int numv, lerpbounds &start,
}
}
-void lerpnormal(float u, float v, const lerpvert *lv, int numv, lerpbounds &start, lerpbounds &end, vec &normal, vec &nstep)
-{
+void lerpnormal(float u, float v, const lerpvert *lv, int numv, lerpbounds &start, lerpbounds &end, vec &normal, vec &nstep) {
updatelerpbounds(v, lv, numv, start, end);
-
- if(start.u + 1 > end.u)
- {
+ if(start.u + 1 > end.u) {
nstep = vec(0, 0, 0);
normal = start.normal;
normal.add(end.normal);
normal.normalize();
}
- else
- {
+ else {
vec nstart(start.normal), nend(end.normal);
nstart.normalize();
nend.normalize();
-
nstep = nend;
nstep.sub(nstart);
nstep.div(end.u-start.u);
-
normal = nstep;
normal.mul(u-start.u);
normal.add(nstart);
normal.normalize();
}
-
start.normal.add(start.nstep);
start.u += start.ustep;
-
end.normal.add(end.nstep);
end.u += end.ustep;
}
diff --git a/src/engine/octa.cpp b/src/engine/octa.cpp
index 3d47cd3..21a3938 100644
--- a/src/engine/octa.cpp
+++ b/src/engine/octa.cpp
@@ -5,17 +5,14 @@
cube *worldroot = newcubes(F_SOLID);
int allocnodes = 0;
-cubeext *growcubeext(cubeext *old, int maxverts)
-{
+cubeext *growcubeext(cubeext *old, int maxverts) {
cubeext *ext = (cubeext *)new uchar[sizeof(cubeext) + maxverts*sizeof(vertinfo)];
- if(old)
- {
+ if(old) {
ext->va = old->va;
ext->ents = old->ents;
ext->tjoints = old->tjoints;
}
- else
- {
+ else {
ext->va = NULL;
ext->ents = NULL;
ext->tjoints = -1;
@@ -24,22 +21,18 @@ cubeext *growcubeext(cubeext *old, int maxverts)
return ext;
}
-void setcubeext(cube &c, cubeext *ext)
-{
+void setcubeext(cube &c, cubeext *ext) {
cubeext *old = c.ext;
if(old == ext) return;
c.ext = ext;
if(old) delete[] (uchar *)old;
}
-cubeext *newcubeext(cube &c, int maxverts, bool init)
-{
+cubeext *newcubeext(cube &c, int maxverts, bool init) {
if(c.ext && c.ext->maxverts >= maxverts) return c.ext;
cubeext *ext = growcubeext(c.ext, maxverts);
- if(init)
- {
- if(c.ext)
- {
+ if(init) {
+ if(c.ext) {
memcpy(ext->surfaces, c.ext->surfaces, sizeof(ext->surfaces));
memcpy(ext->verts(), c.ext->verts(), c.ext->maxverts*sizeof(vertinfo));
}
@@ -49,11 +42,9 @@ cubeext *newcubeext(cube &c, int maxverts, bool init)
return ext;
}
-cube *newcubes(uint face, int mat)
-{
+cube *newcubes(uint face, int mat) {
cube *c = new cube[8];
- loopi(8)
- {
+ loopi(8) {
c->children = NULL;
c->ext = NULL;
c->visible = 0;
@@ -67,53 +58,44 @@ cube *newcubes(uint face, int mat)
return c-8;
}
-int familysize(const cube &c)
-{
+int familysize(const cube &c) {
int size = 1;
if(c.children) loopi(8) size += familysize(c.children[i]);
return size;
}
-void freeocta(cube *c)
-{
+void freeocta(cube *c) {
if(!c) return;
loopi(8) discardchildren(c[i]);
delete[] c;
allocnodes--;
}
-void freecubeext(cube &c)
-{
- if(c.ext)
- {
+void freecubeext(cube &c) {
+ if(c.ext) {
delete[] (uchar *)c.ext;
c.ext = NULL;
}
}
-void discardchildren(cube &c, bool fixtex, int depth)
-{
+void discardchildren(cube &c, bool fixtex, int depth) {
c.material = MAT_AIR;
c.visible = 0;
c.merged = 0;
- if(c.ext)
- {
+ if(c.ext) {
if(c.ext->va) destroyva(c.ext->va);
c.ext->va = NULL;
c.ext->tjoints = -1;
freeoctaentities(c);
freecubeext(c);
}
- if(c.children)
- {
+ if(c.children) {
uint filled = F_EMPTY;
- loopi(8)
- {
+ loopi(8) {
discardchildren(c.children[i], fixtex, depth+1);
filled |= c.children[i].faces[0];
}
- if(fixtex)
- {
+ if(fixtex) {
loopi(6) c.texture[i] = getmippedtexture(c, i);
if(depth > 0 && filled != F_EMPTY) c.faces[0] = F_SOLID;
}
@@ -122,44 +104,36 @@ void discardchildren(cube &c, bool fixtex, int depth)
}
}
-void getcubevector(cube &c, int d, int x, int y, int z, ivec &p)
-{
+void getcubevector(cube &c, int d, int x, int y, int z, ivec &p) {
ivec v(d, x, y, z);
-
loopi(3)
p[i] = edgeget(cubeedge(c, i, v[R[i]], v[C[i]]), v[D[i]]);
}
-void setcubevector(cube &c, int d, int x, int y, int z, const ivec &p)
-{
+void setcubevector(cube &c, int d, int x, int y, int z, const ivec &p) {
ivec v(d, x, y, z);
-
loopi(3)
edgeset(cubeedge(c, i, v[R[i]], v[C[i]]), v[D[i]], p[i]);
}
-static inline void getcubevector(cube &c, int i, ivec &p)
-{
+static inline void getcubevector(cube &c, int i, ivec &p) {
p.x = edgeget(cubeedge(c, 0, (i>>R[0])&1, (i>>C[0])&1), (i>>D[0])&1);
p.y = edgeget(cubeedge(c, 1, (i>>R[1])&1, (i>>C[1])&1), (i>>D[1])&1);
p.z = edgeget(cubeedge(c, 2, (i>>R[2])&1, (i>>C[2])&1), (i>>D[2])&1);
}
-static inline void setcubevector(cube &c, int i, const ivec &p)
-{
+static inline void setcubevector(cube &c, int i, const ivec &p) {
edgeset(cubeedge(c, 0, (i>>R[0])&1, (i>>C[0])&1), (i>>D[0])&1, p.x);
edgeset(cubeedge(c, 1, (i>>R[1])&1, (i>>C[1])&1), (i>>D[1])&1, p.y);
edgeset(cubeedge(c, 2, (i>>R[2])&1, (i>>C[2])&1), (i>>D[2])&1, p.z);
}
-void optiface(uchar *p, cube &c)
-{
+void optiface(uchar *p, cube &c) {
uint f = *(uint *)p;
if(((f>>4)&0x0F0F0F0FU) == (f&0x0F0F0F0FU)) emptyfaces(c);
}
-void printcube()
-{
+void printcube() {
cube &c = lookupcube(lu); // assume this is cube being pointed at
conoutf(CON_DEBUG, "= %p = (%d, %d, %d) @ %d", (void *)&c, lu.x, lu.y, lu.z, lusize);
conoutf(CON_DEBUG, " x %.8x", c.faces[0]);
@@ -169,43 +143,33 @@ void printcube()
COMMAND(printcube, "");
-bool isvalidcube(const cube &c)
-{
+bool isvalidcube(const cube &c) {
clipplanes p;
genclipplanes(c, ivec(0, 0, 0), 256, p);
- loopi(8) // test that cube is convex
- {
+ loopi(8) { // test that cube is convex {
vec v = p.v[i];
loopj(p.size) if(p.p[j].dist(v)>1e-3f) return false;
}
return true;
}
-void validatec(cube *c, int size)
-{
- loopi(8)
- {
- if(c[i].children)
- {
- if(size<=1)
- {
+void validatec(cube *c, int size) {
+ loopi(8) {
+ if(c[i].children) {
+ if(size<=1) {
solidfaces(c[i]);
discardchildren(c[i], true);
}
else validatec(c[i].children, size>>1);
}
- else if(size > 0x1000)
- {
+ else if(size > 0x1000) {
subdividecube(c[i], true, false);
validatec(c[i].children, size>>1);
}
- else
- {
- loopj(3)
- {
+ else {
+ loopj(3) {
uint f = c[i].faces[j], e0 = f&0x0F0F0F0FU, e1 = (f>>4)&0x0F0F0F0FU;
- if(e0 == e1 || ((e1+0x07070707U)|(e1-e0))&0xF0F0F0F0U)
- {
+ if(e0 == e1 || ((e1+0x07070707U)|(e1-e0))&0xF0F0F0F0U) {
emptyfaces(c[i]);
break;
}
@@ -216,19 +180,15 @@ void validatec(cube *c, int size)
ivec lu;
int lusize;
-cube &lookupcube(const ivec &to, int tsize, ivec &ro, int &rsize)
-{
+cube &lookupcube(const ivec &to, int tsize, ivec &ro, int &rsize) {
int tx = clamp(to.x, 0, worldsize-1),
ty = clamp(to.y, 0, worldsize-1),
tz = clamp(to.z, 0, worldsize-1);
int scale = worldscale-1, csize = abs(tsize);
cube *c = &worldroot[octastep(tx, ty, tz, scale)];
- if(!(csize>>scale)) do
- {
- if(!c->children)
- {
- if(tsize > 0) do
- {
+ if(!(csize>>scale)) do {
+ if(!c->children) {
+ if(tsize > 0) do {
subdividecube(*c);
scale--;
c = &c->children[octastep(tx, ty, tz, scale)];
@@ -243,14 +203,12 @@ cube &lookupcube(const ivec &to, int tsize, ivec &ro, int &rsize)
return *c;
}
-int lookupmaterial(const vec &v)
-{
+int lookupmaterial(const vec &v) {
ivec o(v);
if(!insideworld(o)) return MAT_AIR;
int scale = worldscale-1;
cube *c = &worldroot[octastep(o.x, o.y, o.z, scale)];
- while(c->children)
- {
+ while(c->children) {
scale--;
c = &c->children[octastep(o.x, o.y, o.z, scale)];
}
@@ -260,8 +218,7 @@ int lookupmaterial(const vec &v)
const cube *neighbourstack[32];
int neighbourdepth = -1;
-const cube &neighbourcube(const cube &c, int orient, const ivec &co, int size, ivec &ro, int &rsize)
-{
+const cube &neighbourcube(const cube &c, int orient, const ivec &co, int size, ivec &ro, int &rsize) {
ivec n = co;
int dim = dimension(orient);
uint diff = n[dim];
@@ -270,8 +227,7 @@ const cube &neighbourcube(const cube &c, int orient, const ivec &co, int size, i
if(diff >= uint(worldsize)) { ro = n; rsize = size; return c; }
int scale = worldscale;
const cube *nc = worldroot;
- if(neighbourdepth >= 0)
- {
+ if(neighbourdepth >= 0) {
scale -= neighbourdepth + 1;
diff >>= scale;
do { scale++; diff >>= 1; } while(diff);
@@ -279,8 +235,7 @@ const cube &neighbourcube(const cube &c, int orient, const ivec &co, int size, i
}
scale--;
nc = &nc[octastep(n.x, n.y, n.z, scale)];
- if(!(size>>scale) && nc->children) do
- {
+ if(!(size>>scale) && nc->children) do {
scale--;
nc = &nc->children[octastep(n.x, n.y, n.z, scale)];
} while(!(size>>scale) && nc->children);
@@ -291,15 +246,12 @@ const cube &neighbourcube(const cube &c, int orient, const ivec &co, int size, i
////////// (re)mip //////////
-int getmippedtexture(const cube &p, int orient)
-{
+int getmippedtexture(const cube &p, int orient) {
cube *c = p.children;
int d = dimension(orient), dc = dimcoord(orient), texs[4] = { -1, -1, -1, -1 }, numtexs = 0;
- loop(x, 2) loop(y, 2)
- {
+ loop(x, 2) loop(y, 2) {
int n = octaindex(d, x, y, dc);
- if(isempty(c[n]))
- {
+ if(isempty(c[n])) {
n = oppositeocta(d, n);
if(isempty(c[n]))
continue;
@@ -312,16 +264,12 @@ int getmippedtexture(const cube &p, int orient)
return DEFAULT_GEOM;
}
-void forcemip(cube &c, bool fixtex)
-{
+void forcemip(cube &c, bool fixtex) {
cube *ch = c.children;
emptyfaces(c);
-
- loopi(8) loopj(8)
- {
+ loopi(8) loopj(8) {
int n = i^(j==3 ? 4 : (j==4 ? 3 : j));
- if(!isempty(ch[n])) // breadth first search for cube near vert
- {
+ if(!isempty(ch[n])) { // breadth first search for cube near vert {
ivec v;
getcubevector(ch[n], i, v);
// adjust vert to parent size
@@ -329,13 +277,11 @@ void forcemip(cube &c, bool fixtex)
break;
}
}
-
if(fixtex) loopj(6)
c.texture[j] = getmippedtexture(c, j);
}
-static int midedge(const ivec &a, const ivec &b, int xd, int yd, bool &perfect)
-{
+static int midedge(const ivec &a, const ivec &b, int xd, int yd, bool &perfect) {
int ax = a[xd], ay = a[yd], bx = b[xd], by = b[yd];
if(ay==by) return ay;
if(ax==bx) { perfect = false; return ay; }
@@ -353,23 +299,19 @@ static int midedge(const ivec &a, const ivec &b, int xd, int yd, bool &perfect)
return crossy ? 8 : min(max(y, 0), 16);
}
-static inline bool crosscenter(const ivec &a, const ivec &b, int xd, int yd)
-{
+static inline bool crosscenter(const ivec &a, const ivec &b, int xd, int yd) {
int ax = a[xd], ay = a[yd], bx = b[xd], by = b[yd];
return (((ax <= 8 && bx <= 8) || (ax >= 8 && bx >= 8)) &&
((ay <= 8 && by <= 8) || (ay >= 8 && by >= 8))) ||
(ax + bx == 16 && ay + by == 16);
}
-bool subdividecube(cube &c, bool fullcheck, bool brighten)
-{
+bool subdividecube(cube &c, bool fullcheck, bool brighten) {
if(c.children) return true;
if(c.ext) memset(c.ext->surfaces, 0, sizeof(c.ext->surfaces));
- if(isempty(c) || isentirelysolid(c))
- {
+ if(isempty(c) || isentirelysolid(c)) {
c.children = newcubes(isempty(c) ? F_EMPTY : F_SOLID, c.material);
- loopi(8)
- {
+ loopi(8) {
loopl(6) c.children[i].texture[l] = c.texture[l];
if(brighten && !isempty(c)) brightencube(c.children[i]);
}
@@ -378,14 +320,11 @@ bool subdividecube(cube &c, bool fullcheck, bool brighten)
cube *ch = c.children = newcubes(F_SOLID, c.material);
bool perfect = true;
ivec v[8];
- loopi(8)
- {
+ loopi(8) {
getcubevector(c, i, v[i]);
v[i].mul(2);
}
-
- loopj(6)
- {
+ loopj(6) {
int d = dimension(j), z = dimcoord(j);
const ivec &v00 = v[octaindex(d, 0, 0, z)],
&v10 = v[octaindex(d, 1, 0, z)],
@@ -406,19 +345,15 @@ bool subdividecube(cube &c, bool fullcheck, bool brighten)
bool p1 = perfect, p2 = perfect;
int c1 = midedge(v00, v11, R[d], d, p1);
int c2 = midedge(v01, v10, R[d], d, p2);
- if(z ? c1 > c2 : c1 < c2)
- {
+ if(z ? c1 > c2 : c1 < c2) {
e[1][1] = c1;
perfect = p1 && (c1 == c2 || crosscenter(v00, v11, C[d], R[d]));
}
- else
- {
+ else {
e[1][1] = c2;
perfect = p2 && (c1 == c2 || crosscenter(v01, v10, C[d], R[d]));
}
-
- loopi(8)
- {
+ loopi(8) {
ch[i].texture[j] = c.texture[j];
int rd = (i>>R[d])&1, cd = (i>>C[d])&1, dd = (i>>D[d])&1;
edgeset(cubeedge(ch[i], d, 0, 0), z, clamp(e[rd][cd] - dd*8, 0, 8));
@@ -427,10 +362,8 @@ bool subdividecube(cube &c, bool fullcheck, bool brighten)
edgeset(cubeedge(ch[i], d, 1, 1), z, clamp(e[1+rd][1+cd] - dd*8, 0, 8));
}
}
-
validatec(ch);
- if(fullcheck) loopi(8) if(!isvalidcube(ch[i])) // not so good...
- {
+ if(fullcheck) loopi(8) if(!isvalidcube(ch[i])) { // not so good... {
emptyfaces(ch[i]);
perfect=false;
}
@@ -440,14 +373,11 @@ bool subdividecube(cube &c, bool fullcheck, bool brighten)
bool crushededge(uchar e, int dc) { return dc ? e==0 : e==0x88; }
-int visibleorient(const cube &c, int orient)
-{
- loopi(2)
- {
+int visibleorient(const cube &c, int orient) {
+ loopi(2) {
int a = faceedgesidx[orient][i*2 + 0];
int b = faceedgesidx[orient][i*2 + 1];
- loopj(2)
- {
+ loopj(2) {
if(crushededge(c.edges[a],j) &&
crushededge(c.edges[b],j) &&
touchingface(c, orient)) return ((a>>2)<<1) + j;
@@ -460,85 +390,66 @@ VAR(mipvis, 0, 0, 1);
static int remipprogress = 0, remiptotal = 0;
-bool remip(cube &c, const ivec &co, int size)
-{
+bool remip(cube &c, const ivec &co, int size) {
cube *ch = c.children;
- if(!ch)
- {
+ if(!ch) {
if(size<<1 <= 0x1000) return true;
subdividecube(c);
ch = c.children;
}
else if((remipprogress++&0xFFF)==1) renderprogress(float(remipprogress)/remiptotal, "remipping...");
-
bool perfect = true;
- loopi(8)
- {
+ loopi(8) {
ivec o(i, co, size);
if(!remip(ch[i], o, size>>1)) perfect = false;
}
-
solidfaces(c); // so texmip is more consistent
loopj(6)
c.texture[j] = getmippedtexture(c, j); // parents get child texs regardless
-
if(!perfect) return false;
if(size<<1 > 0x1000) return false;
-
ushort mat = MAT_AIR;
- loopi(8)
- {
+ loopi(8) {
mat = ch[i].material;
- if((mat&MATF_CLIP) == MAT_NOCLIP || mat&MAT_ALPHA)
- {
+ if((mat&MATF_CLIP) == MAT_NOCLIP || mat&MAT_ALPHA) {
if(i > 0) return false;
while(++i < 8) if(ch[i].material != mat) return false;
break;
}
- else if(!isentirelysolid(ch[i]))
- {
- while(++i < 8)
- {
+ else if(!isentirelysolid(ch[i])) {
+ while(++i < 8) {
int omat = ch[i].material;
if(isentirelysolid(ch[i]) ? (omat&MATF_CLIP) == MAT_NOCLIP || omat&MAT_ALPHA : mat != omat) return false;
}
break;
}
}
-
cube n = c;
n.ext = NULL;
forcemip(n);
n.children = NULL;
- if(!subdividecube(n, false, false))
- { freeocta(n.children); return false; }
-
+ if(!subdividecube(n, false, false)) {
+ freeocta(n.children); return false; }
cube *nh = n.children;
uchar vis[6] = {0, 0, 0, 0, 0, 0};
- loopi(8)
- {
+ loopi(8) {
if(ch[i].faces[0] != nh[i].faces[0] ||
ch[i].faces[1] != nh[i].faces[1] ||
- ch[i].faces[2] != nh[i].faces[2])
- { freeocta(nh); return false; }
-
+ ch[i].faces[2] != nh[i].faces[2]) {
+ freeocta(nh); return false; }
if(isempty(ch[i]) && isempty(nh[i])) continue;
-
ivec o(i, co, size);
loop(orient, 6)
- if(visibleface(ch[i], orient, o, size, MAT_AIR, (mat&MAT_ALPHA)^MAT_ALPHA, MAT_ALPHA))
- {
+ if(visibleface(ch[i], orient, o, size, MAT_AIR, (mat&MAT_ALPHA)^MAT_ALPHA, MAT_ALPHA)) {
if(ch[i].texture[orient] != n.texture[orient]) { freeocta(nh); return false; }
vis[orient] |= 1<<i;
}
}
- if(mipvis) loop(orient, 6)
- {
+ if(mipvis) loop(orient, 6) {
int mask = 0;
loop(x, 2) loop(y, 2) mask |= 1<<octaindex(dimension(orient), x, y, dimcoord(orient));
if(vis[orient]&mask && (vis[orient]&mask)!=mask) { freeocta(nh); return false; }
}
-
freeocta(nh);
discardchildren(c);
loopi(3) c.faces[i] = n.faces[i];
@@ -549,14 +460,12 @@ bool remip(cube &c, const ivec &co, int size)
return true;
}
-void mpremip(bool local)
-{
+void mpremip(bool local) {
extern selinfo sel;
if(local) game::edittrigger(sel, EDIT_REMIP);
remipprogress = 1;
remiptotal = allocnodes;
- loopi(8)
- {
+ loopi(8) {
ivec o(i, ivec(0, 0, 0), worldsize>>1);
remip(worldroot[i], o, worldsize>>2);
}
@@ -564,36 +473,30 @@ void mpremip(bool local)
if(!local) allchanged();
}
-void remip_()
-{
+void remip_() {
mpremip(true);
allchanged();
}
COMMANDN(remip, remip_, "");
-static inline int edgeval(cube &c, const ivec &p, int dim, int coord)
-{
+static inline int edgeval(cube &c, const ivec &p, int dim, int coord) {
return edgeget(cubeedge(c, dim, p[R[dim]]>>3, p[C[dim]]>>3), coord);
}
-void genvertp(cube &c, ivec &p1, ivec &p2, ivec &p3, plane &pl, bool solid = false)
-{
+void genvertp(cube &c, ivec &p1, ivec &p2, ivec &p3, plane &pl, bool solid = false) {
int dim = 0;
if(p1.y==p2.y && p2.y==p3.y) dim = 1;
else if(p1.z==p2.z && p2.z==p3.z) dim = 2;
-
int coord = p1[dim];
ivec v1(p1), v2(p2), v3(p3);
v1[dim] = solid ? coord*8 : edgeval(c, p1, dim, coord);
v2[dim] = solid ? coord*8 : edgeval(c, p2, dim, coord);
v3[dim] = solid ? coord*8 : edgeval(c, p3, dim, coord);
-
pl.toplane(vec(v1), vec(v2), vec(v3));
}
-static bool threeplaneintersect(plane &pl1, plane &pl2, plane &pl3, vec &dest)
-{
+static bool threeplaneintersect(plane &pl1, plane &pl2, plane &pl3, vec &dest) {
vec &t1 = dest, t2, t3, t4;
t1.cross(pl1, pl2); t4 = t1; t1.mul(pl3.offset);
t2.cross(pl3, pl1); t2.mul(pl2.offset);
@@ -607,12 +510,10 @@ static bool threeplaneintersect(plane &pl1, plane &pl2, plane &pl3, vec &dest)
return true;
}
-static void genedgespanvert(ivec &p, cube &c, vec &v)
-{
+static void genedgespanvert(ivec &p, cube &c, vec &v) {
ivec p1(8-p.x, p.y, p.z);
ivec p2(p.x, 8-p.y, p.z);
ivec p3(p.x, p.y, 8-p.z);
-
plane plane1, plane2, plane3;
genvertp(c, p, p1, p2, plane1);
genvertp(c, p, p2, p3, plane2);
@@ -620,7 +521,6 @@ static void genedgespanvert(ivec &p, cube &c, vec &v)
if(plane1==plane2) genvertp(c, p, p1, p2, plane1, true);
if(plane1==plane3) genvertp(c, p, p1, p2, plane1, true);
if(plane2==plane3) genvertp(c, p, p2, p3, plane2, true);
-
ASSERT(threeplaneintersect(plane1, plane2, plane3, v));
//ASSERT(v.x>=0 && v.x<=8);
//ASSERT(v.y>=0 && v.y<=8);
@@ -630,34 +530,28 @@ static void genedgespanvert(ivec &p, cube &c, vec &v)
v.z = max(0.0f, min(8.0f, v.z));
}
-void edgespan2vectorcube(cube &c)
-{
+void edgespan2vectorcube(cube &c) {
if(isentirelysolid(c) || isempty(c)) return;
cube o = c;
- loop(x, 2) loop(y, 2) loop(z, 2)
- {
+ loop(x, 2) loop(y, 2) loop(z, 2) {
ivec p(8*x, 8*y, 8*z);
vec v;
genedgespanvert(p, o, v);
-
edgeset(cubeedge(c, 0, y, z), x, int(v.x+0.49f));
edgeset(cubeedge(c, 1, z, x), y, int(v.y+0.49f));
edgeset(cubeedge(c, 2, x, y), z, int(v.z+0.49f));
}
}
-const ivec cubecoords[8] = // verts of bounding cube
-{
+const ivec cubecoords[8] = {// verts of bounding cube {
#define GENCUBEVERT(n, x, y, z) ivec(x, y, z),
GENCUBEVERTS(0, 8, 0, 8, 0, 8)
#undef GENCUBEVERT
};
template<class T>
-static inline void gencubevert(const cube &c, int i, T &v)
-{
- switch(i)
- {
+static inline void gencubevert(const cube &c, int i, T &v) {
+ switch(i) {
default:
#define GENCUBEVERT(n, x, y, z) \
case n: \
@@ -670,10 +564,8 @@ static inline void gencubevert(const cube &c, int i, T &v)
}
}
-void genfaceverts(const cube &c, int orient, ivec v[4])
-{
- switch(orient)
- {
+void genfaceverts(const cube &c, int orient, ivec v[4]) {
+ switch(orient) {
default:
#define GENFACEORIENT(o, v0, v1, v2, v3) \
case o: v0 v1 v2 v3 break;
@@ -687,10 +579,9 @@ void genfaceverts(const cube &c, int orient, ivec v[4])
}
}
-const ivec facecoords[6][4] =
-{
-#define GENFACEORIENT(o, v0, v1, v2, v3) \
- { v0, v1, v2, v3 },
+const ivec facecoords[6][4] = {
+#define GENFACEORIENT(o, v0, v1, v2, v3) { \
+ v0, v1, v2, v3 },
#define GENFACEVERT(o, n, x,y,z, xv,yv,zv) \
ivec(x,y,z)
GENFACEVERTS(0, 8, 0, 8, 0, 8, , , , , , )
@@ -698,8 +589,7 @@ const ivec facecoords[6][4] =
#undef GENFACEVERT
};
-const uchar fv[6][4] = // indexes for cubecoords, per each vert of a face orientation
-{
+const uchar fv[6][4] = { // indexes for cubecoords, per each vert of a face orientation {
{ 2, 1, 6, 5 },
{ 3, 4, 7, 0 },
{ 4, 5, 6, 7 },
@@ -708,8 +598,7 @@ const uchar fv[6][4] = // indexes for cubecoords, per each vert of a face orient
{ 5, 4, 3, 2 },
};
-const uchar fvmasks[64] = // mask of verts used given a mask of visible face orientations
-{
+const uchar fvmasks[64] = { // mask of verts used given a mask of visible face orientations {
0x00, 0x66, 0x99, 0xFF, 0xF0, 0xF6, 0xF9, 0xFF,
0x0F, 0x6F, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xC3, 0xE7, 0xDB, 0xFF, 0xF3, 0xF7, 0xFB, 0xFF,
@@ -720,8 +609,8 @@ const uchar fvmasks[64] = // mask of verts used given a mask of visible face ori
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
-const uchar faceedgesidx[6][4] = // ordered edges surrounding each orient
-{//0..1 = row edges, 2..3 = column edges
+const uchar faceedgesidx[6][4] = { // ordered edges surrounding each orient {
+//0..1 = row edges, 2..3 = column edges {
{ 4, 5, 8, 10 },
{ 6, 7, 9, 11 },
{ 8, 9, 0, 2 },
@@ -730,17 +619,14 @@ const uchar faceedgesidx[6][4] = // ordered edges surrounding each orient
{ 2, 3, 5, 7 },
};
-bool flataxisface(const cube &c, int orient)
-{
+bool flataxisface(const cube &c, int orient) {
uint face = c.faces[dimension(orient)];
if(dimcoord(orient)) face >>= 4;
return (face&0x0F0F0F0F) == 0x01010101*(face&0x0F);
}
-bool collideface(const cube &c, int orient)
-{
- if(flataxisface(c, orient))
- {
+bool collideface(const cube &c, int orient) {
+ if(flataxisface(c, orient)) {
uchar r1 = c.edges[faceedgesidx[orient][0]], r2 = c.edges[faceedgesidx[orient][1]];
if(uchar((r1>>4)|(r2&0xF0)) == uchar((r1&0x0F)|(r2<<4))) return false;
uchar c1 = c.edges[faceedgesidx[orient][2]], c2 = c.edges[faceedgesidx[orient][3]];
@@ -749,35 +635,30 @@ bool collideface(const cube &c, int orient)
return true;
}
-bool touchingface(const cube &c, int orient)
-{
+bool touchingface(const cube &c, int orient) {
uint face = c.faces[dimension(orient)];
return dimcoord(orient) ? (face&0xF0F0F0F0)==0x80808080 : (face&0x0F0F0F0F)==0;
}
-bool notouchingface(const cube &c, int orient)
-{
+bool notouchingface(const cube &c, int orient) {
uint face = c.faces[dimension(orient)];
return dimcoord(orient) ? (face&0x80808080)==0 : ((0x88888888-face)&0x08080808) == 0;
}
-int faceconvexity(const ivec v[4])
-{
+int faceconvexity(const ivec v[4]) {
ivec n;
n.cross(ivec(v[1]).sub(v[0]), ivec(v[2]).sub(v[0]));
return ivec(v[0]).sub(v[3]).dot(n);
// 1 if convex, -1 if concave, 0 if flat
}
-int faceconvexity(const vertinfo *verts, int numverts, int size)
-{
+int faceconvexity(const vertinfo *verts, int numverts, int size) {
if(numverts < 4) return 0;
ivec v0 = verts[0].getxyz(),
e1 = verts[1].getxyz().sub(v0),
e2 = verts[2].getxyz().sub(v0),
n;
- if(size >= (8<<5))
- {
+ if(size >= (8<<5)) {
if(size >= (8<<10)) n.cross(e1.shr(10), e2.shr(10));
else n.cross(e1, e2).shr(10);
}
@@ -785,13 +666,11 @@ int faceconvexity(const vertinfo *verts, int numverts, int size)
return verts[3].getxyz().sub(v0).dot(n);
}
-int faceconvexity(const ivec v[4], int &vis)
-{
+int faceconvexity(const ivec v[4], int &vis) {
ivec e1, e2, e3, n;
n.cross((e1 = v[1]).sub(v[0]), (e2 = v[2]).sub(v[0]));
int convex = (e3 = v[0]).sub(v[3]).dot(n);
- if(!convex)
- {
+ if(!convex) {
if(ivec().cross(e3, e2).iszero()) { if(!n.iszero()) vis = 1; }
else if(n.iszero()) { vis = 2; }
return 0;
@@ -799,46 +678,39 @@ int faceconvexity(const ivec v[4], int &vis)
return convex;
}
-int faceconvexity(const cube &c, int orient)
-{
+int faceconvexity(const cube &c, int orient) {
if(flataxisface(c, orient)) return 0;
ivec v[4];
genfaceverts(c, orient, v);
return faceconvexity(v);
}
-int faceorder(const cube &c, int orient) // gets above 'fv' so that each face is convex
-{
+int faceorder(const cube &c, int orient) { // gets above 'fv' so that each face is convex {
return faceconvexity(c, orient)<0 ? 1 : 0;
}
-static inline void faceedges(const cube &c, int orient, uchar edges[4])
-{
+static inline void faceedges(const cube &c, int orient, uchar edges[4]) {
loopk(4) edges[k] = c.edges[faceedgesidx[orient][k]];
}
-uint faceedges(const cube &c, int orient)
-{
+uint faceedges(const cube &c, int orient) {
union { uchar edges[4]; uint face; } u;
faceedges(c, orient, u.edges);
return u.face;
}
-static inline int genfacevecs(const cube &cu, int orient, const ivec &pos, int size, bool solid, ivec2 *fvecs, const ivec *v = NULL)
-{
+static inline int genfacevecs(const cube &cu, int orient, const ivec &pos, int size, bool solid, ivec2 *fvecs, const ivec *v = NULL) {
int i = 0;
- if(solid)
- {
- switch(orient)
- {
+ if(solid) {
+ switch(orient) {
#define GENFACEORIENT(orient, v0, v1, v2, v3) \
- case orient: \
- { \
+ case orient: { \
+ \
if(dimcoord(orient)) { v0 v1 v2 v3 } else { v3 v2 v1 v0 } \
break; \
}
- #define GENFACEVERT(orient, vert, xv,yv,zv, x,y,z) \
- { ivec2 &f = fvecs[i]; x ((xv)<<3); y ((yv)<<3); z ((zv)<<3); i++; }
+ #define GENFACEVERT(orient, vert, xv,yv,zv, x,y,z) { \
+ ivec2 &f = fvecs[i]; x ((xv)<<3); y ((yv)<<3); z ((zv)<<3); i++; }
GENFACEVERTS(pos.x, pos.x+size, pos.y, pos.y+size, pos.z, pos.z+size, f.x = , f.x = , f.y = , f.y = , (void), (void))
#undef GENFACEVERT
}
@@ -847,15 +719,14 @@ static inline int genfacevecs(const cube &cu, int orient, const ivec &pos, int s
ivec buf[4];
if(!v) { genfaceverts(cu, orient, buf); v = buf; }
ivec2 prev(INT_MAX, INT_MAX);
- switch(orient)
- {
- #define GENFACEVERT(orient, vert, sx,sy,sz, dx,dy,dz) \
- { \
+ switch(orient) {
+ #define GENFACEVERT(orient, vert, sx,sy,sz, dx,dy,dz) { \
+ \
const ivec &e = v[vert]; \
ivec ef; \
ef.dx = e.sx; ef.dy = e.sy; ef.dz = e.sz; \
- if(ef.z == dimcoord(orient)*8) \
- { \
+ if(ef.z == dimcoord(orient)*8) { \
+ \
ivec2 &f = fvecs[i]; \
ivec pf; \
pf.dx = pos.sx; pf.dy = pos.sy; pf.dz = pos.sz; \
@@ -871,66 +742,51 @@ static inline int genfacevecs(const cube &cu, int orient, const ivec &pos, int s
return i;
}
-static inline int clipfacevecy(const ivec2 &o, const ivec2 &dir, int cx, int cy, int size, ivec2 &r)
-{
- if(dir.x >= 0)
- {
+static inline int clipfacevecy(const ivec2 &o, const ivec2 &dir, int cx, int cy, int size, ivec2 &r) {
+ if(dir.x >= 0) {
if(cx <= o.x || cx >= o.x+dir.x) return 0;
}
else if(cx <= o.x+dir.x || cx >= o.x) return 0;
-
int t = (o.y-cy) + (cx-o.x)*dir.y/dir.x;
if(t <= 0 || t >= size) return 0;
-
r.x = cx;
r.y = cy + t;
return 1;
}
-static inline int clipfacevecx(const ivec2 &o, const ivec2 &dir, int cx, int cy, int size, ivec2 &r)
-{
- if(dir.y >= 0)
- {
+static inline int clipfacevecx(const ivec2 &o, const ivec2 &dir, int cx, int cy, int size, ivec2 &r) {
+ if(dir.y >= 0) {
if(cy <= o.y || cy >= o.y+dir.y) return 0;
}
else if(cy <= o.y+dir.y || cy >= o.y) return 0;
-
int t = (o.x-cx) + (cy-o.y)*dir.x/dir.y;
if(t <= 0 || t >= size) return 0;
-
r.x = cx + t;
r.y = cy;
return 1;
}
-static inline int clipfacevec(const ivec2 &o, const ivec2 &dir, int cx, int cy, int size, ivec2 *rvecs)
-{
+static inline int clipfacevec(const ivec2 &o, const ivec2 &dir, int cx, int cy, int size, ivec2 *rvecs) {
int r = 0;
-
if(o.x >= cx && o.x <= cx+size &&
o.y >= cy && o.y <= cy+size &&
- ((o.x != cx && o.x != cx+size) || (o.y != cy && o.y != cy+size)))
- {
+ ((o.x != cx && o.x != cx+size) || (o.y != cy && o.y != cy+size))) {
rvecs[0].x = o.x;
rvecs[0].y = o.y;
r++;
}
-
r += clipfacevecx(o, dir, cx, cy, size, rvecs[r]);
r += clipfacevecx(o, dir, cx, cy+size, size, rvecs[r]);
r += clipfacevecy(o, dir, cx, cy, size, rvecs[r]);
r += clipfacevecy(o, dir, cx+size, cy, size, rvecs[r]);
-
ASSERT(r <= 2);
return r;
}
-static inline bool insideface(const ivec2 *p, int nump, const ivec2 *o, int numo)
-{
+static inline bool insideface(const ivec2 *p, int nump, const ivec2 *o, int numo) {
int bounds = 0;
ivec2 prev = o[numo-1];
- loopi(numo)
- {
+ loopi(numo) {
const ivec2 &cur = o[i];
ivec2 dir(cur.x-prev.x, cur.y-prev.y);
int offset = dir.x*prev.y - dir.y*prev.x;
@@ -941,16 +797,13 @@ static inline bool insideface(const ivec2 *p, int nump, const ivec2 *o, int numo
return bounds>=3;
}
-static inline int clipfacevecs(const ivec2 *o, int numo, int cx, int cy, int size, ivec2 *rvecs)
-{
+static inline int clipfacevecs(const ivec2 *o, int numo, int cx, int cy, int size, ivec2 *rvecs) {
cx <<= 3;
cy <<= 3;
size <<= 3;
-
int r = 0;
ivec2 prev = o[numo-1];
- loopi(numo)
- {
+ loopi(numo) {
const ivec2 &cur = o[i];
r += clipfacevec(prev, ivec2(cur.x-prev.x, cur.y-prev.y), cx, cy, size, &rvecs[r]);
prev = cur;
@@ -961,8 +814,7 @@ static inline int clipfacevecs(const ivec2 *o, int numo, int cx, int cy, int siz
return r;
}
-bool collapsedface(const cube &c, int orient)
-{
+bool collapsedface(const cube &c, int orient) {
int e0 = c.edges[faceedgesidx[orient][0]], e1 = c.edges[faceedgesidx[orient][1]],
e2 = c.edges[faceedgesidx[orient][2]], e3 = c.edges[faceedgesidx[orient][3]],
face = dimension(orient)*4,
@@ -978,11 +830,9 @@ bool collapsedface(const cube &c, int orient)
ivec().cross(v2, v3.sub(v0)).iszero();
}
-static inline bool occludesface(const cube &c, int orient, const ivec &o, int size, const ivec &vo, int vsize, ushort vmat, ushort nmat, ushort matmask, const ivec2 *vf, int numv)
-{
+static inline bool occludesface(const cube &c, int orient, const ivec &o, int size, const ivec &vo, int vsize, ushort vmat, ushort nmat, ushort matmask, const ivec2 *vf, int numv) {
int dim = dimension(orient);
- if(!c.children)
- {
+ if(!c.children) {
if(nmat != MAT_AIR && (c.material&matmask) == nmat)
{
ivec2 nf[8];
@@ -999,42 +849,32 @@ static inline bool occludesface(const cube &c, int orient, const ivec &o, int si
int numo = genfacevecs(c, orient, o, size, false, of);
return numo >= 3 && insideface(cf, numc, of, numo);
}
-
size >>= 1;
int coord = dimcoord(orient);
- loopi(8) if(octacoord(dim, i) == coord)
- {
+ loopi(8) if(octacoord(dim, i) == coord) {
if(!occludesface(c.children[i], orient, ivec(i, o, size), size, vo, vsize, vmat, nmat, matmask, vf, numv)) return false;
}
-
return true;
}
-bool visibleface(const cube &c, int orient, const ivec &co, int size, ushort mat, ushort nmat, ushort matmask)
-{
- if(mat != MAT_AIR)
- {
+bool visibleface(const cube &c, int orient, const ivec &co, int size, ushort mat, ushort nmat, ushort matmask) {
+ if(mat != MAT_AIR) {
if(faceedges(c, orient)==F_SOLID && touchingface(c, orient)) return false;
}
- else
- {
+ else {
if(collapsedface(c, orient)) return false;
if(!touchingface(c, orient)) return true;
}
-
ivec no;
int nsize;
const cube &o = neighbourcube(c, orient, co, size, no, nsize);
if(&o==&c) return false;
-
int opp = opposite(orient);
- if(nsize > size || (nsize == size && !o.children))
- {
+ if(nsize > size || (nsize == size && !o.children)) {
if(nmat != MAT_AIR && (o.material&matmask) == nmat) return true;
if(isentirelysolid(o)) return false;
if(isempty(o) || notouchingface(o, opp)) return true;
if(touchingface(o, opp) && faceedges(o, opp) == F_SOLID) return false;
-
ivec vo = ivec(co).mask(0xFFF);
no.mask(0xFFF);
ivec2 cf[4], of[4];
@@ -1043,7 +883,6 @@ bool visibleface(const cube &c, int orient, const ivec &co, int size, ushort mat
return numo < 3 || !insideface(cf, numc, of, numo);
}
-
ivec vo = ivec(co).mask(0xFFF);
no.mask(0xFFF);
ivec2 cf[4];
@@ -1051,26 +890,21 @@ bool visibleface(const cube &c, int orient, const ivec &co, int size, ushort mat
return !occludesface(o, opp, no, nsize, vo, size, mat, nmat, matmask, cf, numc);
}
-int classifyface(const cube &c, int orient, const ivec &co, int size)
-{
+int classifyface(const cube &c, int orient, const ivec &co, int size) {
if(collapsedface(c, orient)) return 0;
int vismask = (c.material&MATF_CLIP) == MAT_NOCLIP ? 1 : 3;
if(!touchingface(c, orient)) return vismask;
-
ivec no;
int nsize;
const cube &o = neighbourcube(c, orient, co, size, no, nsize);
if(&o==&c) return 0;
-
int vis = 0, opp = opposite(orient);
- if(nsize > size || (nsize == size && !o.children))
- {
+ if(nsize > size || (nsize == size && !o.children)) {
if((~c.material & o.material) & MAT_ALPHA) vis |= 1;
if((o.material&MATF_CLIP) == MAT_NOCLIP) vis |= vismask&2;
if(vis == vismask || isentirelysolid(o)) return vis;
if(isempty(o) || notouchingface(o, opp)) return vismask;
if(touchingface(o, opp) && faceedges(o, opp) == F_SOLID) return vis;
-
ivec vo = ivec(co).mask(0xFFF);
no.mask(0xFFF);
ivec2 cf[4], of[4];
@@ -1079,7 +913,6 @@ int classifyface(const cube &c, int orient, const ivec &co, int size)
if(numo < 3 || !insideface(cf, numc, of, numo)) return vismask;
return vis;
}
-
ivec vo = ivec(co).mask(0xFFF);
no.mask(0xFFF);
ivec2 cf[4];
@@ -1090,79 +923,67 @@ int classifyface(const cube &c, int orient, const ivec &co, int size)
}
// more expensive version that checks both triangles of a face independently
-int visibletris(const cube &c, int orient, const ivec &co, int size, ushort nmat, ushort matmask)
-{
+int visibletris(const cube &c, int orient, const ivec &co, int size, ushort nmat, ushort matmask) {
int vis = 3, touching = 0xF;
ivec v[4], e1, e2, e3, n;
genfaceverts(c, orient, v);
n.cross((e1 = v[1]).sub(v[0]), (e2 = v[2]).sub(v[0]));
int convex = (e3 = v[0]).sub(v[3]).dot(n);
- if(!convex)
- {
+ if(!convex) {
if(ivec().cross(e3, e2).iszero() || v[1] == v[3]) { if(n.iszero()) return 0; vis = 1; touching = 0xF&~(1<<3); }
else if(n.iszero()) { vis = 2; touching = 0xF&~(1<<1); }
}
-
int dim = dimension(orient), coord = dimcoord(orient);
if(v[0][dim] != coord*8) touching &= ~(1<<0);
if(v[1][dim] != coord*8) touching &= ~(1<<1);
if(v[2][dim] != coord*8) touching &= ~(1<<2);
if(v[3][dim] != coord*8) touching &= ~(1<<3);
- static const int notouchmasks[2][16] = // mask of triangles not touching
- { // order 0: flat or convex
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- { 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 1, 3, 0 },
- // order 1: concave
- { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 2, 0 },
+ static const int notouchmasks[2][16] = { // mask of triangles not touching {
+ // order 0: flat or convex
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 {
+ { 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 1, 3, 0 },
+ // order 1: concave {
+ { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 2, 0 },
};
int order = convex < 0 ? 1 : 0, notouch = notouchmasks[order][touching];
if((vis&notouch)==vis) return vis;
-
ivec no;
int nsize;
const cube &o = neighbourcube(c, orient, co, size, no, nsize);
if(&o==&c) return 0;
-
if((c.material&matmask) == nmat) nmat = MAT_AIR;
-
ivec vo = ivec(co).mask(0xFFF);
no.mask(0xFFF);
ivec2 cf[4], of[4];
int opp = opposite(orient), numo = 0, numc;
- if(nsize > size || (nsize == size && !o.children))
- {
+ if(nsize > size || (nsize == size && !o.children)) {
if(isempty(o) || notouchingface(o, opp)) return vis;
if(nmat != MAT_AIR && (o.material&matmask) == nmat) return vis;
if(isentirelysolid(o) || (touchingface(o, opp) && faceedges(o, opp) == F_SOLID)) return vis&notouch;
-
numc = genfacevecs(c, orient, vo, size, false, cf, v);
numo = genfacevecs(o, opp, no, nsize, false, of);
if(numo < 3) return vis;
if(insideface(cf, numc, of, numo)) return vis&notouch;
}
- else
- {
+ else {
numc = genfacevecs(c, orient, vo, size, false, cf, v);
if(occludesface(o, opp, no, nsize, vo, size, MAT_AIR, nmat, matmask, cf, numc)) return vis&notouch;
}
if(vis != 3 || notouch) return vis;
-
- static const int triverts[2][2][2][3] =
- { // order
- { // coord
- { { 1, 2, 3 }, { 0, 1, 3 } }, // verts
- { { 0, 1, 2 }, { 0, 2, 3 } }
- },
- { // coord
- { { 0, 1, 2 }, { 3, 0, 2 } }, // verts
- { { 1, 2, 3 }, { 1, 3, 0 } }
+ static const int triverts[2][2][2][3] = {
+ // order {
+ // coord {
+ {
+ { { 1, 2, 3 }, { 0, 1, 3 } }, // verts {
+ { { 0, 1, 2 }, { 0, 2, 3 } }
+ }, {
+ // coord {
+ { { 0, 1, 2 }, { 3, 0, 2 } }, // verts {
+ { { 1, 2, 3 }, { 1, 3, 0 } }
}
};
-
- do
- {
- loopi(2)
- {
+ do {
+ loopi(2) {
const int *verts = triverts[order][coord][i];
ivec2 tf[3] = { cf[verts[0]], cf[verts[1]], cf[verts[2]] };
if(numo > 0) { if(!insideface(tf, 3, of, numo)) continue; }
@@ -1171,12 +992,10 @@ int visibletris(const cube &c, int orient, const ivec &co, int size, ushort nmat
}
vis |= 4;
} while(++order <= 1);
-
return 3;
}
-void calcvert(const cube &c, const ivec &co, int size, ivec &v, int i, bool solid)
-{
+void calcvert(const cube &c, const ivec &co, int size, ivec &v, int i, bool solid) {
if(solid) v = cubecoords[i]; else gencubevert(c, i, v);
// avoid overflow
if(size>=8) v.mul(size/8);
@@ -1184,14 +1003,12 @@ void calcvert(const cube &c, const ivec &co, int size, ivec &v, int i, bool soli
v.add(ivec(co).shl(3));
}
-void calcvert(const cube &c, const ivec &co, int size, vec &v, int i, bool solid)
-{
+void calcvert(const cube &c, const ivec &co, int size, vec &v, int i, bool solid) {
if(solid) v = vec(cubecoords[i]); else gencubevert(c, i, v);
v.mul(size/8.0f).add(vec(co));
}
-int genclipplane(const cube &c, int orient, vec *v, plane *clip)
-{
+int genclipplane(const cube &c, int orient, vec *v, plane *clip) {
int planes = 0, convex = faceconvexity(c, orient), order = convex < 0 ? 1 : 0;
const vec &v0 = v[fv[orient][order]], &v1 = v[fv[orient][order+1]], &v2 = v[fv[orient][order+2]], &v3 = v[fv[orient][(order+3)&3]];
if(v0==v2) return 0;
@@ -1200,31 +1017,24 @@ int genclipplane(const cube &c, int orient, vec *v, plane *clip)
return planes;
}
-void genclipplanes(const cube &c, const ivec &co, int size, clipplanes &p, bool collide)
-{
+void genclipplanes(const cube &c, const ivec &co, int size, clipplanes &p, bool collide) {
// generate tight bounding box
calcvert(c, co, size, p.v[0], 0);
vec mx = p.v[0], mn = p.v[0];
- for(int i = 1; i < 8; i++)
- {
+ for(int i = 1; i < 8; i++) {
calcvert(c, co, size, p.v[i], i);
mx.max(p.v[i]);
mn.min(p.v[i]);
}
-
p.r = mx.sub(mn).mul(0.5f);
p.o = mn.add(p.r);
-
p.size = 0;
p.visible = 0;
- if(collide || (c.visible&0xC0) == 0x40)
- {
- loopi(6) if(c.visible&(1<<i))
- {
+ if(collide || (c.visible&0xC0) == 0x40) {
+ loopi(6) if(c.visible&(1<<i)) {
int vis;
if(flataxisface(c, i)) p.visible |= 1<<i;
- else if((vis = visibletris(c, i, co, size, MAT_NOCLIP, MATF_CLIP)))
- {
+ else if((vis = visibletris(c, i, co, size, MAT_NOCLIP, MATF_CLIP))) {
int convex = faceconvexity(c, i), order = vis&4 || convex < 0 ? 1 : 0;
const vec &v0 = p.v[fv[i][order]], &v1 = p.v[fv[i][order+1]], &v2 = p.v[fv[i][order+2]], &v3 = p.v[fv[i][(order+3)&3]];
if(vis&1) { p.side[p.size] = i; p.p[p.size++].toplane(v0, v1, v2); }
@@ -1232,14 +1042,11 @@ void genclipplanes(const cube &c, const ivec &co, int size, clipplanes &p, bool
}
}
}
- else if(c.visible&0x80)
- {
+ else if(c.visible&0x80) {
int vis;
- loopi(6) if((vis = visibletris(c, i, co, size)))
- {
+ loopi(6) if((vis = visibletris(c, i, co, size))) {
if(flataxisface(c, i)) p.visible |= 1<<i;
- else
- {
+ else {
int convex = faceconvexity(c, i), order = vis&4 || convex < 0 ? 1 : 0;
const vec &v0 = p.v[fv[i][order]], &v1 = p.v[fv[i][order+1]], &v2 = p.v[fv[i][order+2]], &v3 = p.v[fv[i][(order+3)&3]];
if(vis&1) { p.side[p.size] = i; p.p[p.size++].toplane(v0, v1, v2); }
@@ -1249,8 +1056,7 @@ void genclipplanes(const cube &c, const ivec &co, int size, clipplanes &p, bool
}
}
-static inline bool mergefacecmp(const facebounds &x, const facebounds &y)
-{
+static inline bool mergefacecmp(const facebounds &x, const facebounds &y) {
if(x.v2 < y.v2) return true;
if(x.v2 > y.v2) return false;
if(x.u1 < y.u1) return true;
@@ -1258,13 +1064,10 @@ static inline bool mergefacecmp(const facebounds &x, const facebounds &y)
return false;
}
-static int mergefacev(int orient, facebounds *m, int sz, facebounds &n)
-{
- for(int i = sz-1; i >= 0; --i)
- {
+static int mergefacev(int orient, facebounds *m, int sz, facebounds &n) {
+ for(int i = sz-1; i >= 0; --i) {
if(m[i].v2 < n.v1) break;
- if(m[i].v2 == n.v1 && m[i].u1 == n.u1 && m[i].u2 == n.u2)
- {
+ if(m[i].v2 == n.v1 && m[i].u1 == n.u1 && m[i].u2 == n.u2) {
n.v1 = m[i].v1;
memmove(&m[i], &m[i+1], (sz - (i+1)) * sizeof(facebounds));
return 1;
@@ -1273,20 +1076,16 @@ static int mergefacev(int orient, facebounds *m, int sz, facebounds &n)
return 0;
}
-static int mergefaceu(int orient, facebounds &m, facebounds &n)
-{
- if(m.v1 == n.v1 && m.v2 == n.v2 && m.u2 == n.u1)
- {
+static int mergefaceu(int orient, facebounds &m, facebounds &n) {
+ if(m.v1 == n.v1 && m.v2 == n.v2 && m.u2 == n.u1) {
n.u1 = m.u1;
return 1;
}
return 0;
}
-static int mergeface(int orient, facebounds *m, int sz, facebounds &n)
-{
- for(bool merged = false; sz; merged = true)
- {
+static int mergeface(int orient, facebounds *m, int sz, facebounds &n) {
+ for(bool merged = false; sz; merged = true) {
int vmerged = mergefacev(orient, m, sz, n);
sz -= vmerged;
if(!vmerged && merged) break;
@@ -1299,38 +1098,31 @@ static int mergeface(int orient, facebounds *m, int sz, facebounds &n)
return sz;
}
-int mergefaces(int orient, facebounds *m, int sz)
-{
+int mergefaces(int orient, facebounds *m, int sz) {
quicksort(m, sz, mergefacecmp);
-
int nsz = 0;
loopi(sz) nsz = mergeface(orient, m, nsz, m[i]);
return nsz;
}
-struct cfkey
-{
+struct cfkey {
uchar orient;
ushort material, tex;
ivec n;
int offset;
};
-static inline bool htcmp(const cfkey &x, const cfkey &y)
-{
+static inline bool htcmp(const cfkey &x, const cfkey &y) {
return x.orient == y.orient && x.tex == y.tex && x.n == y.n && x.offset == y.offset && x.material==y.material;
}
-static inline uint hthash(const cfkey &k)
-{
+static inline uint hthash(const cfkey &k) {
return hthash(k.n)^k.offset^k.tex^k.orient^k.material;
}
-void mincubeface(const cube &cu, int orient, const ivec &o, int size, const facebounds &orig, facebounds &cf, ushort nmat, ushort matmask)
-{
+void mincubeface(const cube &cu, int orient, const ivec &o, int size, const facebounds &orig, facebounds &cf, ushort nmat, ushort matmask) {
int dim = dimension(orient);
- if(cu.children)
- {
+ if(cu.children) {
size >>= 1;
int coord = dimcoord(orient);
loopi(8) if(octacoord(dim, i) == coord)
@@ -1344,8 +1136,7 @@ void mincubeface(const cube &cu, int orient, const ivec &o, int size, const face
uc2 = min(uc2, orig.u2);
vc1 = max(vc1, orig.v1);
vc2 = min(vc2, orig.v2);
- if(!isempty(cu) && touchingface(cu, orient) && !(nmat!=MAT_AIR && (cu.material&matmask)==nmat))
- {
+ if(!isempty(cu) && touchingface(cu, orient) && !(nmat!=MAT_AIR && (cu.material&matmask)==nmat)) {
uchar r1 = cu.edges[faceedgesidx[orient][0]], r2 = cu.edges[faceedgesidx[orient][1]],
c1 = cu.edges[faceedgesidx[orient][2]], c2 = cu.edges[faceedgesidx[orient][3]];
ushort u1 = max(c1&0xF, c2&0xF)*size+uco, u2 = min(c1>>4, c2>>4)*size+uco,
@@ -1354,14 +1145,12 @@ void mincubeface(const cube &cu, int orient, const ivec &o, int size, const face
u2 = min(u2, orig.u2);
v1 = max(v1, orig.v1);
v2 = min(v2, orig.v2);
- if(v2-v1==vc2-vc1)
- {
+ if(v2-v1==vc2-vc1) {
if(u2-u1==uc2-uc1) return;
if(u1==uc1) uc1 = u2;
if(u2==uc2) uc2 = u1;
}
- else if(u2-u1==uc2-uc1)
- {
+ else if(u2-u1==uc2-uc1) {
if(v1==vc1) vc1 = v2;
if(v2==vc2) vc2 = v1;
}
@@ -1373,8 +1162,7 @@ void mincubeface(const cube &cu, int orient, const ivec &o, int size, const face
cf.v2 = max(cf.v2, vc2);
}
-bool mincubeface(const cube &cu, int orient, const ivec &co, int size, facebounds &orig)
-{
+bool mincubeface(const cube &cu, int orient, const ivec &co, int size, facebounds &orig) {
ivec no;
int nsize;
const cube &nc = neighbourcube(cu, orient, co, size, no, nsize);
@@ -1395,24 +1183,18 @@ bool mincubeface(const cube &cu, int orient, const ivec &co, int size, facebound
VAR(maxmerge, 0, 6, 12);
VAR(minface, 0, 4, 12);
-struct pvert
-{
+struct pvert {
ushort x, y;
-
pvert() {}
pvert(ushort x, ushort y) : x(x), y(y) {}
-
bool operator==(const pvert &o) const { return x == o.x && y == o.y; }
bool operator!=(const pvert &o) const { return x != o.x || y != o.y; }
};
-struct pedge
-{
+struct pedge {
pvert from, to;
-
pedge() {}
pedge(const pvert &from, const pvert &to) : from(from), to(to) {}
-
bool operator==(const pedge &o) const { return from == o.from && to == o.to; }
bool operator!=(const pedge &o) const { return from != o.from || to != o.to; }
};
@@ -1420,35 +1202,28 @@ struct pedge
static inline uint hthash(const pedge &x) { return uint(x.from.x)^(uint(x.from.y)<<8); }
static inline bool htcmp(const pedge &x, const pedge &y) { return x == y; }
-struct poly
-{
+struct poly {
cube *c;
int numverts;
bool merged;
pvert verts[MAXFACEVERTS];
};
-bool clippoly(poly &p, const facebounds &b)
-{
+bool clippoly(poly &p, const facebounds &b) {
pvert verts1[MAXFACEVERTS+4], verts2[MAXFACEVERTS+4];
int numverts1 = 0, numverts2 = 0, px = p.verts[p.numverts-1].x, py = p.verts[p.numverts-1].y;
- loopi(p.numverts)
- {
+ loopi(p.numverts) {
int x = p.verts[i].x, y = p.verts[i].y;
- if(x < b.u1)
- {
+ if(x < b.u1) {
if(px > b.u2) verts1[numverts1++] = pvert(b.u2, y + ((y - py)*(b.u2 - x))/(x - px));
if(px > b.u1) verts1[numverts1++] = pvert(b.u1, y + ((y - py)*(b.u1 - x))/(x - px));
}
- else if(x > b.u2)
- {
+ else if(x > b.u2) {
if(px < b.u1) verts1[numverts1++] = pvert(b.u1, y + ((y - py)*(b.u1 - x))/(x - px));
if(px < b.u2) verts1[numverts1++] = pvert(b.u2, y + ((y - py)*(b.u2 - x))/(x - px));
}
- else
- {
- if(px < b.u1)
- {
+ else {
+ if(px < b.u1) {
if(x > b.u1) verts1[numverts1++] = pvert(b.u1, y + ((y - py)*(b.u1 - x))/(x - px));
}
else if(px > b.u2 && x < b.u2) verts1[numverts1++] = pvert(b.u2, y + ((y - py)*(b.u2 - x))/(x - px));
@@ -1460,23 +1235,18 @@ bool clippoly(poly &p, const facebounds &b)
if(numverts1 < 3) return false;
px = verts1[numverts1-1].x;
py = verts1[numverts1-1].y;
- loopi(numverts1)
- {
+ loopi(numverts1) {
int x = verts1[i].x, y = verts1[i].y;
- if(y < b.v1)
- {
+ if(y < b.v1) {
if(py > b.v2) verts2[numverts2++] = pvert(x + ((x - px)*(b.v2 - y))/(y - py), b.v2);
if(py > b.v1) verts2[numverts2++] = pvert(x + ((x - px)*(b.v1 - y))/(y - py), b.v1);
}
- else if(y > b.v2)
- {
+ else if(y > b.v2) {
if(py < b.v1) verts2[numverts2++] = pvert(x + ((x - px)*(b.v1 - y))/(y - py), b.v1);
if(py < b.v2) verts2[numverts2++] = pvert(x + ((x - px)*(b.v2 - y))/(y - py), b.v2);
}
- else
- {
- if(py < b.v1)
- {
+ else {
+ if(py < b.v1) {
if(y > b.v1) verts2[numverts2++] = pvert(x + ((x - px)*(b.v1 - y))/(y - py), b.v1);
}
else if(py > b.v2 && y < b.v2) verts2[numverts2++] = pvert(x + ((x - px)*(b.v2 - y))/(y - py), b.v2);
@@ -1492,47 +1262,38 @@ bool clippoly(poly &p, const facebounds &b)
return true;
}
-bool genpoly(cube &cu, int orient, const ivec &o, int size, int vis, ivec &n, int &offset, poly &p)
-{
+bool genpoly(cube &cu, int orient, const ivec &o, int size, int vis, ivec &n, int &offset, poly &p) {
int dim = dimension(orient), coord = dimcoord(orient);
ivec v[4];
genfaceverts(cu, orient, v);
- if(flataxisface(cu, orient))
- {
+ if(flataxisface(cu, orient)) {
n = ivec(0, 0, 0);
n[dim] = coord ? 1 : -1;
}
- else
- {
+ else {
if(faceconvexity(v)) return false;
n.cross(ivec(v[1]).sub(v[0]), ivec(v[2]).sub(v[0]));
if(n.iszero()) n.cross(ivec(v[2]).sub(v[0]), ivec(v[3]).sub(v[0]));
reduceslope(n);
}
-
ivec po = ivec(o).mask(0xFFF).shl(3);
loopk(4) v[k].mul(size).add(po);
offset = -n.dot(v[3]);
-
int r = R[dim], c = C[dim], order = vis&4 ? 1 : 0;
p.numverts = 0;
- if(coord)
- {
+ if(coord) {
const ivec &v0 = v[order]; p.verts[p.numverts++] = pvert(v0[c], v0[r]);
if(vis&1) { const ivec &v1 = v[order+1]; p.verts[p.numverts++] = pvert(v1[c], v1[r]); }
const ivec &v2 = v[order+2]; p.verts[p.numverts++] = pvert(v2[c], v2[r]);
if(vis&2) { const ivec &v3 = v[(order+3)&3]; p.verts[p.numverts++] = pvert(v3[c], v3[r]); }
}
- else
- {
+ else {
if(vis&2) { const ivec &v3 = v[(order+3)&3]; p.verts[p.numverts++] = pvert(v3[c], v3[r]); }
const ivec &v2 = v[order+2]; p.verts[p.numverts++] = pvert(v2[c], v2[r]);
if(vis&1) { const ivec &v1 = v[order+1]; p.verts[p.numverts++] = pvert(v1[c], v1[r]); }
const ivec &v0 = v[order]; p.verts[p.numverts++] = pvert(v0[c], v0[r]);
}
-
- if(faceedges(cu, orient)!=F_SOLID)
- {
+ if(faceedges(cu, orient)!=F_SOLID) {
int px = int(p.verts[p.numverts-2].x) - int(p.verts[p.numverts-3].x), py = int(p.verts[p.numverts-2].y) - int(p.verts[p.numverts-3].y),
cx = int(p.verts[p.numverts-1].x) - int(p.verts[p.numverts-2].x), cy = int(p.verts[p.numverts-1].y) - int(p.verts[p.numverts-2].y),
dir = px*cy - py*cx;
@@ -1554,17 +1315,13 @@ bool genpoly(cube &cu, int orient, const ivec &o, int size, int vis, ivec &n, in
if(dir > 0) return false;
if(!dir) { if(p.numverts < 4) return false; p.verts[1] = p.verts[2]; p.verts[2] = p.verts[3]; p.numverts--; }
}
-
p.c = &cu;
p.merged = false;
-
- if(minface && size >= 1<<minface && touchingface(cu, orient))
- {
+ if(minface && size >= 1<<minface && touchingface(cu, orient)) {
facebounds b;
b.u1 = b.u2 = p.verts[0].x;
b.v1 = b.v2 = p.verts[0].y;
- for(int i = 1; i < p.numverts; i++)
- {
+ for(int i = 1; i < p.numverts; i++) {
const pvert &v = p.verts[i];
b.u1 = min(b.u1, v.x);
b.u2 = max(b.u2, v.x);
@@ -1574,22 +1331,17 @@ bool genpoly(cube &cu, int orient, const ivec &o, int size, int vis, ivec &n, in
if(mincubeface(cu, orient, o, size, b) && clippoly(p, b))
p.merged = true;
}
-
return true;
}
-struct plink : pedge
-{
+struct plink : pedge {
int polys[2];
-
plink() { clear(); }
plink(const pedge &p) : pedge(p) { clear(); }
-
void clear() { polys[0] = polys[1] = -1; }
};
-bool mergepolys(int orient, hashset<plink> &links, vector<plink *> &queue, int owner, poly &p, poly &q, const pedge &e)
-{
+bool mergepolys(int orient, hashset<plink> &links, vector<plink *> &queue, int owner, poly &p, poly &q, const pedge &e) {
int pe = -1, qe = -1;
loopi(p.numverts) if(p.verts[i] == e.from) { pe = i; break; }
loopi(q.numverts) if(q.verts[i] == e.to) { qe = i; break; }
@@ -1604,15 +1356,13 @@ bool mergepolys(int orient, hashset<plink> &links, vector<plink *> &queue, int o
*/
pvert verts[2*MAXFACEVERTS];
int numverts = 0, index = pe+2; // starts at A = T+1, ends at F = T+p.numverts
- loopi(p.numverts-1)
- {
+ loopi(p.numverts-1) {
if(index >= p.numverts) index -= p.numverts;
verts[numverts++] = p.verts[index++];
}
index = qe+2; // starts at C = T+2 = F+1, ends at T = T+q.numverts
int px = int(verts[numverts-1].x) - int(verts[numverts-2].x), py = int(verts[numverts-1].y) - int(verts[numverts-2].y);
- loopi(q.numverts-1)
- {
+ loopi(q.numverts-1) {
if(index >= q.numverts) index -= q.numverts;
pvert &src = q.verts[index++];
int cx = int(src.x) - int(verts[numverts-1].x), cy = int(src.y) - int(verts[numverts-1].y),
@@ -1627,19 +1377,14 @@ bool mergepolys(int orient, hashset<plink> &links, vector<plink *> &queue, int o
dir = px*cy - py*cx;
if(dir > 0) return false;
if(!dir) numverts--;
-
if(numverts > MAXFACEVERTS) return false;
-
q.merged = true;
q.numverts = 0;
-
p.merged = true;
p.numverts = numverts;
memcpy(p.verts, verts, numverts*sizeof(pvert));
-
int prev = p.numverts-1;
- loopj(p.numverts)
- {
+ loopj(p.numverts) {
pedge e(p.verts[prev], p.verts[j]);
int order = e.from.x > e.to.x || (e.from.x == e.to.x && e.from.y > e.to.y) ? 1 : 0;
if(order) swap(e.from, e.to);
@@ -1649,15 +1394,12 @@ bool mergepolys(int orient, hashset<plink> &links, vector<plink *> &queue, int o
if(shouldqueue) queue.add(&l);
prev = j;
}
-
return true;
}
-void addmerge(cube &cu, int orient, const ivec &co, const ivec &n, int offset, poly &p)
-{
+void addmerge(cube &cu, int orient, const ivec &co, const ivec &n, int offset, poly &p) {
cu.merged |= 1<<orient;
- if(!p.numverts)
- {
+ if(!p.numverts) {
if(cu.ext) cu.ext->surfaces[orient] = ambientsurface;
return;
}
@@ -1665,8 +1407,7 @@ void addmerge(cube &cu, int orient, const ivec &co, const ivec &n, int offset, p
vertinfo verts[MAXFACEVERTS];
surf.numverts |= p.numverts;
int dim = dimension(orient), coord = dimcoord(orient), c = C[dim], r = R[dim];
- loopk(p.numverts)
- {
+ loopk(p.numverts) {
pvert &src = p.verts[coord ? k : p.numverts-1-k];
vertinfo &dst = verts[k];
ivec v;
@@ -1675,18 +1416,14 @@ void addmerge(cube &cu, int orient, const ivec &co, const ivec &n, int offset, p
v[dim] = -(offset + n[c]*src.x + n[r]*src.y)/n[dim];
dst.set(v);
}
- if(cu.ext)
- {
+ if(cu.ext) {
const surfaceinfo &oldsurf = cu.ext->surfaces[orient];
int numverts = oldsurf.numverts&MAXFACEVERTS;
- if(numverts == p.numverts)
- {
+ if(numverts == p.numverts) {
ivec v0 = verts[0].getxyz();
const vertinfo *oldverts = cu.ext->verts() + oldsurf.verts;
- loopj(numverts) if(v0 == oldverts[j].getxyz())
- {
- for(int k = 1; k < numverts; k++)
- {
+ loopj(numverts) if(v0 == oldverts[j].getxyz()) {
+ for(int k = 1; k < numverts; k++) {
if(++j >= numverts) j = 0;
if(verts[k].getxyz() != oldverts[j].getxyz()) goto nomatch;
}
@@ -1698,36 +1435,29 @@ void addmerge(cube &cu, int orient, const ivec &co, const ivec &n, int offset, p
setsurface(cu, orient, surf, verts, p.numverts);
}
-static inline void clearmerge(cube &c, int orient)
-{
- if(c.merged&(1<<orient))
- {
+static inline void clearmerge(cube &c, int orient) {
+ if(c.merged&(1<<orient)) {
c.merged &= ~(1<<orient);
if(c.ext) c.ext->surfaces[orient] = brightsurface;
}
}
-void addmerges(int orient, const ivec &co, const ivec &n, int offset, vector<poly> &polys)
-{
- loopv(polys)
- {
+void addmerges(int orient, const ivec &co, const ivec &n, int offset, vector<poly> &polys) {
+ loopv(polys) {
poly &p = polys[i];
if(p.merged) addmerge(*p.c, orient, co, n, offset, p);
else clearmerge(*p.c, orient);
}
}
-void mergepolys(int orient, const ivec &co, const ivec &n, int offset, vector<poly> &polys)
-{
+void mergepolys(int orient, const ivec &co, const ivec &n, int offset, vector<poly> &polys) {
if(polys.length() <= 1) { addmerges(orient, co, n, offset, polys); return; }
hashset<plink> links(polys.length() <= 32 ? 128 : 1024);
vector<plink *> queue;
- loopv(polys)
- {
+ loopv(polys) {
poly &p = polys[i];
int prev = p.numverts-1;
- loopj(p.numverts)
- {
+ loopj(p.numverts) {
pedge e(p.verts[prev], p.verts[j]);
int order = e.from.x > e.to.x || (e.from.x == e.to.x && e.from.y > e.to.y) ? 1 : 0;
if(order) swap(e.from, e.to);
@@ -1738,10 +1468,8 @@ void mergepolys(int orient, const ivec &co, const ivec &n, int offset, vector<po
}
}
vector<plink *> nextqueue;
- while(queue.length())
- {
- loopv(queue)
- {
+ while(queue.length()) {
+ loopv(queue) {
plink &l = *queue[i];
if(l.polys[0] >= 0 && l.polys[1] >= 0)
mergepolys(orient, links, nextqueue, l.polys[0], polys[l.polys[0]], polys[l.polys[1]], l);
@@ -1754,30 +1482,24 @@ void mergepolys(int orient, const ivec &co, const ivec &n, int offset, vector<po
static int genmergeprogress = 0;
-struct cfpolys
-{
+struct cfpolys {
vector<poly> polys;
};
static hashtable<cfkey, cfpolys> cpolys;
-void genmerges(cube *c = worldroot, const ivec &o = ivec(0, 0, 0), int size = worldsize>>1)
-{
+void genmerges(cube *c = worldroot, const ivec &o = ivec(0, 0, 0), int size = worldsize>>1) {
if((genmergeprogress++&0xFFF)==0) renderprogress(float(genmergeprogress)/allocnodes, "merging faces...");
neighbourstack[++neighbourdepth] = c;
- loopi(8)
- {
+ loopi(8) {
ivec co(i, o, size);
int vis;
if(c[i].children) genmerges(c[i].children, co, size>>1);
- else if(!isempty(c[i])) loopj(6) if((vis = visibletris(c[i], j, co, size)))
- {
+ else if(!isempty(c[i])) loopj(6) if((vis = visibletris(c[i], j, co, size))) {
cfkey k;
poly p;
- if(size < 1<<maxmerge && c != worldroot)
- {
- if(genpoly(c[i], j, co, size, vis, k.n, k.offset, p))
- {
+ if(size < 1<<maxmerge && c != worldroot) {
+ if(genpoly(c[i], j, co, size, vis, k.n, k.offset, p)) {
k.orient = j;
k.tex = c[i].texture[j];
k.material = c[i].material&MAT_ALPHA;
@@ -1785,20 +1507,16 @@ void genmerges(cube *c = worldroot, const ivec &o = ivec(0, 0, 0), int size = wo
continue;
}
}
- else if(minface && size >= 1<<minface && touchingface(c[i], j))
- {
- if(genpoly(c[i], j, co, size, vis, k.n, k.offset, p) && p.merged)
- {
+ else if(minface && size >= 1<<minface && touchingface(c[i], j)) {
+ if(genpoly(c[i], j, co, size, vis, k.n, k.offset, p) && p.merged) {
addmerge(c[i], j, co, k.n, k.offset, p);
continue;
}
}
clearmerge(c[i], j);
}
- if((size == 1<<maxmerge || c == worldroot) && cpolys.numelems)
- {
- enumeratekt(cpolys, cfkey, key, cfpolys, val,
- {
+ if((size == 1<<maxmerge || c == worldroot) && cpolys.numelems) {
+ enumeratekt(cpolys, cfkey, key, cfpolys, val, {
mergepolys(key.orient, co, key.n, key.offset, val.polys);
});
cpolys.clear();
@@ -1807,12 +1525,10 @@ void genmerges(cube *c = worldroot, const ivec &o = ivec(0, 0, 0), int size = wo
--neighbourdepth;
}
-int calcmergedsize(int orient, const ivec &co, int size, const vertinfo *verts, int numverts)
-{
+int calcmergedsize(int orient, const ivec &co, int size, const vertinfo *verts, int numverts) {
ushort x1 = verts[0].x, y1 = verts[0].y, z1 = verts[0].z,
x2 = x1, y2 = y1, z2 = z1;
- for(int i = 1; i < numverts; i++)
- {
+ for(int i = 1; i < numverts; i++) {
const vertinfo &v = verts[i];
x1 = min(x1, v.x);
x2 = max(x2, v.x);
@@ -1827,8 +1543,7 @@ int calcmergedsize(int orient, const ivec &co, int size, const vertinfo *verts,
ivec mo(co);
mo.mask(0xFFF);
mo.shl(3);
- while(bits<15)
- {
+ while(bits<15) {
mo.mask(~((1<<bits)-1));
if(mo.x <= x1 && mo.x + (1<<bits) >= x2 &&
mo.y <= y1 && mo.y + (1<<bits) >= y2 &&
@@ -1839,17 +1554,13 @@ int calcmergedsize(int orient, const ivec &co, int size, const vertinfo *verts,
return bits-3;
}
-static void invalidatemerges(cube &c)
-{
- if(c.merged)
- {
+static void invalidatemerges(cube &c) {
+ if(c.merged) {
brightencube(c);
c.merged = 0;
}
- if(c.ext)
- {
- if(c.ext->va)
- {
+ if(c.ext) {
+ if(c.ext->va) {
if(!(c.ext->va->hasmerges&(MERGE_PART | MERGE_ORIGIN))) return;
destroyva(c.ext->va);
c.ext->va = NULL;
@@ -1861,18 +1572,15 @@ static void invalidatemerges(cube &c)
static int invalidatedmerges = 0;
-void invalidatemerges(cube &c, const ivec &co, int size, bool msg)
-{
- if(msg && invalidatedmerges!=totalmillis)
- {
+void invalidatemerges(cube &c, const ivec &co, int size, bool msg) {
+ if(msg && invalidatedmerges!=totalmillis) {
renderprogress(0, "invalidating merged surfaces...");
invalidatedmerges = totalmillis;
}
invalidatemerges(c);
}
-void calcmerges()
-{
+void calcmerges() {
genmergeprogress = 0;
genmerges();
}
diff --git a/src/engine/octa.h b/src/engine/octa.h
index 9452ad0..d8a2c45 100644
--- a/src/engine/octa.h
+++ b/src/engine/octa.h
@@ -1,34 +1,28 @@
// 6-directional octree heightfield map format
-struct elementset
-{
+struct elementset {
ushort texture, lmid;
uchar dim, layer;
ushort length[2], minvert[2], maxvert[2];
};
-struct materialsurface
-{
+struct materialsurface {
ivec o;
ushort csize, rsize;
ushort material, skip;
uchar orient, visible;
- union
- {
+ union {
short index;
short depth;
};
- union
- {
+ union {
entity *light;
uchar ends;
};
};
-struct vertinfo
-{
+struct vertinfo {
ushort x, y, z, u, v, norm;
-
void setxyz(ushort a, ushort b, ushort c) { x = a; y = b; z = c; }
void setxyz(const ivec &v) { setxyz(v.x, v.y, v.z); }
void set(ushort a, ushort b, ushort c, ushort s = 0, ushort t = 0, ushort n = 0) { setxyz(a, b, c); u = s; v = t; norm = n; }
@@ -36,24 +30,19 @@ struct vertinfo
ivec getxyz() const { return ivec(x, y, z); }
};
-enum
-{
+enum {
LAYER_TOP = (1<<5),
LAYER_BOTTOM = (1<<6),
LAYER_DUP = (1<<7),
-
LAYER_BLEND = LAYER_TOP|LAYER_BOTTOM,
-
MAXFACEVERTS = 15
};
enum { LMID_AMBIENT = 0, LMID_AMBIENT1, LMID_BRIGHT, LMID_BRIGHT1, LMID_DARK, LMID_DARK1, LMID_RESERVED };
-struct surfaceinfo
-{
+struct surfaceinfo {
uchar lmid[2];
uchar verts, numverts;
-
int totalverts() const { return numverts&LAYER_DUP ? (numverts&MAXFACEVERTS)*2 : numverts&MAXFACEVERTS; }
bool used() const { return lmid[0] != LMID_AMBIENT || lmid[1] != LMID_AMBIENT || numverts&~LAYER_TOP; }
void clear() { lmid[0] = LMID_AMBIENT; lmid[1] = LMID_AMBIENT; numverts = (numverts&MAXFACEVERTS) | LAYER_TOP; }
@@ -64,8 +53,7 @@ static const surfaceinfo ambientsurface = {{LMID_AMBIENT, LMID_AMBIENT}, 0, LAYE
static const surfaceinfo brightsurface = {{LMID_BRIGHT, LMID_AMBIENT}, 0, LAYER_TOP};
static const surfaceinfo brightbottomsurface = {{LMID_AMBIENT, LMID_BRIGHT}, 0, LAYER_BOTTOM};
-struct occludequery
-{
+struct occludequery {
void *owner;
GLuint id;
int fragments;
@@ -73,8 +61,7 @@ struct occludequery
struct vtxarray;
-struct octaentities
-{
+struct octaentities {
vector<int> mapmodels;
vector<int> other;
occludequery *query;
@@ -83,30 +70,25 @@ struct octaentities
ivec o;
int size;
ivec bbmin, bbmax;
-
- octaentities(const ivec &o, int size) : query(0), o(o), size(size), bbmin(o), bbmax(o)
- {
+ octaentities(const ivec &o, int size) : query(0), o(o), size(size), bbmin(o), bbmax(o) {
bbmin.add(size);
}
};
-enum
-{
+enum {
OCCLUDE_NOTHING = 0,
OCCLUDE_GEOM,
OCCLUDE_BB,
OCCLUDE_PARENT
};
-enum
-{
+enum {
MERGE_ORIGIN = 1<<0,
MERGE_PART = 1<<1,
MERGE_USE = 1<<2
};
-struct vtxarray
-{
+struct vtxarray {
vtxarray *parent;
vector<vtxarray *> children;
vtxarray *next, *rnext; // linked list of visible VOBs
@@ -134,8 +116,7 @@ struct vtxarray
struct cube;
-struct clipplanes
-{
+struct clipplanes {
vec o, r, v[8];
plane p[12];
uchar side[12];
@@ -144,37 +125,30 @@ struct clipplanes
int version;
};
-struct facebounds
-{
+struct facebounds {
ushort u1, u2, v1, v2;
-
bool empty() const { return u1 >= u2 || v1 >= v2; }
};
-struct tjoint
-{
+struct tjoint {
int next;
ushort offset;
uchar edge;
};
-struct cubeext
-{
+struct cubeext {
vtxarray *va; // vertex array for children, or NULL
octaentities *ents; // map entities inside cube
surfaceinfo surfaces[6]; // render info for each surface
int tjoints; // linked list of t-joints
uchar maxverts; // allocated space for verts
-
vertinfo *verts() { return (vertinfo *)(this+1); }
};
-struct cube
-{
+struct cube {
cube *children; // points to 8 cube structures which are its children, or NULL. -Z first, then -Y, -X
cubeext *ext; // extended info for the cube
- union
- {
+ union {
uchar edges[12]; // edges of the cube, each uchar is 2 4bit values denoting the range.
// see documentation jpgs for more info.
uint faces[3]; // 4 edges of each dimension together representing 2 perpendicular faces
@@ -182,38 +156,32 @@ struct cube
ushort texture[6]; // one for each face. same order as orient.
ushort material; // empty-space material
uchar merged; // merged faces of the cube
- union
- {
+ union {
uchar escaped; // mask of which children have escaped merges
uchar visible; // visibility info for faces
};
};
-struct block3
-{
+struct block3 {
ivec o, s;
int grid, orient;
block3() {}
block3(const selinfo &sel) : o(sel.o), s(sel.s), grid(sel.grid), orient(sel.orient) {}
- cube *c() { return (cube *)(this+1); }
+ cube *c() { return (cube *)(this+1); }
int size() const { return s.x*s.y*s.z; }
};
-struct editinfo
-{
+struct editinfo {
block3 *copy;
editinfo() : copy(NULL) {}
};
-struct undoent { int i; entity e; };
-struct undoblock // undo header, all data sits in payload
-{
+struct undoent { int i; entity e; };
+struct undoblock { // undo header, all data sits in payload {
undoblock *prev, *next;
int size, timestamp, numents; // if numents is 0, is a cube undo record, otherwise an entity undo record
-
block3 *block() { return (block3 *)(this + 1); }
- uchar *gridmap()
- {
+ uchar *gridmap() {
block3 *ub = block();
return (uchar *)(ub->c() + ub->size());
}
@@ -245,8 +213,7 @@ const uint F_SOLID = 0x80808080; // all edges in the range (0,8)
#define octaindex(d,x,y,z) (((z)<<D[d])+((y)<<C[d])+((x)<<R[d]))
#define octastep(x, y, z, scale) (((((z)>>(scale))&1)<<2) | ((((y)>>(scale))&1)<<1) | (((x)>>(scale))&1))
-static inline uchar octaboxoverlap(const ivec &o, int size, const ivec &bbmin, const ivec &bbmax)
-{
+static inline uchar octaboxoverlap(const ivec &o, int size, const ivec &bbmin, const ivec &bbmax) {
uchar p = 0xFF; // bitmask of possible collisions with octants. 0 bit = 0 octant, etc
ivec mid = ivec(o).add(size);
if(mid.z <= bbmin.z) p &= 0xF0; // not in a -ve Z octant
@@ -261,8 +228,7 @@ static inline uchar octaboxoverlap(const ivec &o, int size, const ivec &bbmin, c
#define loopoctabox(o, size, bbmin, bbmax) uchar possible = octaboxoverlap(o, size, bbmin, bbmax); loopi(8) if(possible&(1<<i))
#define loopoctaboxsize(o, size, bborigin, bbsize) uchar possible = octaboxoverlap(o, size, bborigin, ivec(bborigin).add(bbsize)); loopi(8) if(possible&(1<<i))
-enum
-{
+enum {
O_LEFT = 0,
O_RIGHT,
O_BACK,
@@ -275,8 +241,7 @@ enum
#define dimcoord(orient) ((orient)&1)
#define opposite(orient) ((orient)^1)
-enum
-{
+enum {
VFC_FULL_VISIBLE = 0,
VFC_PART_VISIBLE,
VFC_NOT_VISIBLE,
diff --git a/src/engine/octaedit.cpp b/src/engine/octaedit.cpp
index fb37088..0da305d 100644
--- a/src/engine/octaedit.cpp
+++ b/src/engine/octaedit.cpp
@@ -4,21 +4,16 @@ extern int outline;
bool boxoutline = false;
-void boxs(int orient, vec o, const vec &s, float size)
-{
+void boxs(int orient, vec o, const vec &s, float size) {
int d = dimension(orient), dc = dimcoord(orient);
float f = boxoutline ? (dc>0 ? 0.2f : -0.2f) : 0;
o[D[d]] += dc * s[D[d]] + f;
-
vec r(0, 0, 0), c(0, 0, 0);
r[R[d]] = s[R[d]];
c[C[d]] = s[C[d]];
-
vec v1 = o, v2 = vec(o).add(r), v3 = vec(o).add(r).add(c), v4 = vec(o).add(c);
-
r[R[d]] = 0.5f*size;
c[C[d]] = 0.5f*size;
-
gle::defvertex();
gle::begin(GL_TRIANGLE_STRIP);
gle::attrib(vec(v1).sub(r).sub(c));
@@ -34,53 +29,43 @@ void boxs(int orient, vec o, const vec &s, float size)
xtraverts += gle::end();
}
-void boxs(int orient, vec o, const vec &s)
-{
+void boxs(int orient, vec o, const vec &s) {
int d = dimension(orient), dc = dimcoord(orient);
float f = boxoutline ? (dc>0 ? 0.2f : -0.2f) : 0;
o[D[d]] += dc * s[D[d]] + f;
-
gle::defvertex();
gle::begin(GL_LINE_LOOP);
-
gle::attrib(o); o[R[d]] += s[R[d]];
gle::attrib(o); o[C[d]] += s[C[d]];
gle::attrib(o); o[R[d]] -= s[R[d]];
gle::attrib(o);
-
xtraverts += gle::end();
}
-void boxs3D(const vec &o, vec s, int g)
-{
+void boxs3D(const vec &o, vec s, int g) {
s.mul(g);
loopi(6)
boxs(i, o, s);
}
-void boxsgrid(int orient, vec o, vec s, int g)
-{
+void boxsgrid(int orient, vec o, vec s, int g) {
int d = dimension(orient), dc = dimcoord(orient);
float ox = o[R[d]],
oy = o[C[d]],
xs = s[R[d]],
ys = s[C[d]],
f = boxoutline ? (dc>0 ? 0.2f : -0.2f) : 0;
-
o[D[d]] += dc * s[D[d]]*g + f;
-
gle::defvertex();
gle::begin(GL_LINES);
- loop(x, xs)
- {
+ loop(x, xs) {
o[R[d]] += g;
gle::attrib(o);
o[C[d]] += ys*g;
gle::attrib(o);
o[C[d]] = oy;
}
- loop(y, ys)
- {
+ loop(y, ys) {
o[C[d]] += g;
o[R[d]] = ox;
gle::attrib(o);
@@ -112,18 +97,15 @@ VARF(dragging, 0, 0, 1,
);
int moving = 0;
-ICOMMAND(moving, "b", (int *n),
-{
- if(*n >= 0)
- {
+ICOMMAND(moving, "b", (int *n), {
+ if(*n >= 0) {
if(!*n || (moving<=1 && !pointinsel(sel, vec(cur).add(1)))) moving = 0;
else if(!moving) moving = 1;
}
intret(moving);
});
-VARF(gridpower, 0, 3, 12,
-{
+VARF(gridpower, 0, 3, 12, {
if(dragging) return;
gridsize = 1<<gridpower;
if(gridsize>=worldsize) gridsize = worldsize/2;
@@ -136,35 +118,29 @@ VAR(selectcorners, 0, 0, 1);
void forcenextundo() { lastsel.orient = -1; }
-void cubecancel()
-{
+void cubecancel() {
havesel = false;
moving = dragging = passthroughsel = 0;
forcenextundo();
}
-void cancelsel()
-{
+void cancelsel() {
cubecancel();
entcancel();
}
-void toggleedit(bool force)
-{
- if(!force)
- {
+void toggleedit(bool force) {
+ if(!force) {
if(!isconnected()) return;
if(player->state!=CS_ALIVE && player->state!=CS_DEAD && player->state!=CS_EDITING) return; // do not allow dead players to edit to avoid state confusion
if(!game::allowedittoggle()) return; // not in most multiplayer modes
}
- if(!(editmode = !editmode))
- {
+ if(!(editmode = !editmode)) {
player->state = player->editstate;
player->o.z -= player->eyeheight; // entinmap wants feet pos
entinmap(player); // find spawn closest to current floating pos
}
- else
- {
+ else {
game::resetgamestate();
player->editstate = player->state;
player->state = CS_EDITING;
@@ -179,8 +155,7 @@ void toggleedit(bool force)
VARP(editinview, 0, 1, 1);
-bool noedit(bool view, bool msg)
-{
+bool noedit(bool view, bool msg) {
if(!editmode) { if(msg) conoutf(CON_ERROR, "operation only allowed in edit mode"); return true; }
if(view || haveselent()) return false;
float r = 1.0f;
@@ -194,8 +169,7 @@ bool noedit(bool view, bool msg)
return true;
}
-void reorient()
-{
+void reorient() {
sel.cx = 0;
sel.cy = 0;
sel.cxs = sel.s[R[dimension(orient)]]*2;
@@ -203,18 +177,14 @@ void reorient()
sel.orient = orient;
}
-void selextend()
-{
+void selextend() {
if(noedit(true)) return;
- loopi(3)
- {
- if(cur[i]<sel.o[i])
- {
+ loopi(3) {
+ if(cur[i]<sel.o[i]) {
sel.s[i] += (sel.o[i]-cur[i])/sel.grid;
sel.o[i] = cur[i];
}
- else if(cur[i]>=sel.o[i]+sel.s[i]*sel.grid)
- {
+ else if(cur[i]>=sel.o[i]+sel.s[i]*sel.grid) {
sel.s[i] = (cur[i]-sel.o[i])/sel.grid+1;
}
}
@@ -232,23 +202,20 @@ ICOMMAND(selsave, "", (), { if(noedit(true)) return; savedsel = sel; });
ICOMMAND(selrestore, "", (), { if(noedit(true)) return; sel = savedsel; });
ICOMMAND(selswap, "", (), { if(noedit(true)) return; swap(sel, savedsel); });
-ICOMMAND(getselpos, "", (),
-{
+ICOMMAND(getselpos, "", (), {
if(noedit(true)) return;
defformatstring(pos, "%s %s %s", floatstr(sel.o.x), floatstr(sel.o.y), floatstr(sel.o.z));
result(pos);
});
-void setselpos(int *x, int *y, int *z)
-{
+void setselpos(int *x, int *y, int *z) {
if(noedit(moving!=0)) return;
havesel = true;
sel.o = ivec(*x, *y, *z).mask(~(gridsize-1));
}
COMMAND(setselpos, "iii");
-void movesel(int *dir, int *dim)
-{
+void movesel(int *dir, int *dim) {
if(noedit(moving!=0)) return;
if(*dim < 0 || *dim > 2) return;
sel.o[*dim] += *dir * sel.grid;
@@ -257,8 +224,7 @@ COMMAND(movesel, "ii");
///////// selection support /////////////
-cube &blockcube(int x, int y, int z, const block3 &b, int rgrid) // looks up a world cube, based on coordinates mapped by the block
-{
+cube &blockcube(int x, int y, int z, const block3 &b, int rgrid) { // looks up a world cube, based on coordinates mapped by the block {
int dim = dimension(b.orient), dc = dimcoord(b.orient);
ivec s(dim, x*b.grid, y*b.grid, dc*(b.s[dim]-1)*b.grid);
s.add(b.o);
@@ -277,18 +243,14 @@ int selchildcount = 0, selchildmat = -1;
ICOMMAND(havesel, "", (), intret(havesel ? selchildcount : 0));
-void countselchild(cube *c, const ivec &cor, int size)
-{
+void countselchild(cube *c, const ivec &cor, int size) {
ivec ss = ivec(sel.s).mul(sel.grid);
- loopoctaboxsize(cor, size, sel.o, ss)
- {
+ loopoctaboxsize(cor, size, sel.o, ss) {
ivec o(i, cor, size);
if(c[i].children) countselchild(c[i].children, o, size/2);
- else
- {
+ else {
selchildcount++;
- if(c[i].material != MAT_AIR && selchildmat != MAT_AIR)
- {
+ if(c[i].material != MAT_AIR && selchildmat != MAT_AIR) {
if(selchildmat < 0) selchildmat = c[i].material;
else if(selchildmat != c[i].material) selchildmat = MAT_AIR;
}
@@ -296,16 +258,13 @@ void countselchild(cube *c, const ivec &cor, int size)
}
}
-void normalizelookupcube(const ivec &o)
-{
- if(lusize>gridsize)
- {
+void normalizelookupcube(const ivec &o) {
+ if(lusize>gridsize) {
lu.x += (o.x-lu.x)/gridsize*gridsize;
lu.y += (o.y-lu.y)/gridsize*gridsize;
lu.z += (o.z-lu.z)/gridsize*gridsize;
}
- else if(gridsize>lusize)
- {
+ else if(gridsize>lusize) {
lu.x &= ~(gridsize-1);
lu.y &= ~(gridsize-1);
lu.z &= ~(gridsize-1);
@@ -313,8 +272,7 @@ void normalizelookupcube(const ivec &o)
lusize = gridsize;
}
-void updateselection()
-{
+void updateselection() {
sel.o.x = min(lastcur.x, cur.x);
sel.o.y = min(lastcur.y, cur.y);
sel.o.z = min(lastcur.z, cur.z);
@@ -323,13 +281,11 @@ void updateselection()
sel.s.z = abs(lastcur.z-cur.z)/sel.grid+1;
}
-bool editmoveplane(const vec &o, const vec &ray, int d, float off, vec &handle, vec &dest, bool first)
-{
+bool editmoveplane(const vec &o, const vec &ray, int d, float off, vec &handle, vec &dest, bool first) {
plane pl(d, off);
float dist = 0.0f;
if(!pl.rayintersect(player->o, ray, dist))
return false;
-
dest = vec(ray).mul(dist).add(player->o);
if(first) handle = vec(dest).sub(o);
dest.sub(handle);
@@ -338,7 +294,7 @@ bool editmoveplane(const vec &o, const vec &ray, int d, float off, vec &handle,
extern void entdrag(const vec &ray);
extern bool hoveringonent(int ent, int orient);
-extern void renderentselection(const vec &o, const vec &ray, bool entmoving);
+extern void renderentselection(const vec &o, bool entmoving);
extern float rayent(const vec &o, const vec &ray, float radius, int mode, int size, int &orient, int &ent);
VAR(gridlookup, 0, 0, 1);
@@ -346,21 +302,15 @@ VAR(passthroughcube, 0, 1, 1);
VAR(passthroughent, 0, 1, 1);
VARF(passthrough, 0, 0, 1, { passthroughsel = passthrough; entcancel(); });
-void rendereditcursor()
-{
+void rendereditcursor() {
int d = dimension(sel.orient),
od = dimension(orient),
odc = dimcoord(orient);
-
bool hidecursor = g3d_windowhit(true, false), hovering = false;
-
- if(moving)
- {
+ if(moving) {
static vec dest, handle;
- if(editmoveplane(vec(sel.o), camdir, od, sel.o[D[od]]+odc*sel.grid*sel.s[D[od]], handle, dest, moving==1))
- {
- if(moving==1)
- {
+ if(editmoveplane(vec(sel.o), camdir, od, sel.o[D[od]]+odc*sel.grid*sel.s[D[od]], handle, dest, moving==1)) {
+ if(moving==1) {
dest.add(handle);
handle = vec(ivec(handle).mask(~(sel.grid-1)));
dest.sub(handle);
@@ -372,50 +322,40 @@ void rendereditcursor()
}
}
else
- if(entmoving)
- {
+ if(entmoving) {
entdrag(camdir);
}
- else
- {
+ else {
ivec w;
float sdist = 0, wdist = 0, t;
int entorient = 0, ent = -1;
-
wdist = rayent(player->o, camdir, 1e16f,
(editmode && showmat ? RAY_EDITMAT : 0) // select cubes first
| (!dragging && entediting && (!passthrough || !passthroughent) ? RAY_ENTS : 0)
| RAY_SKIPFIRST
| (passthroughcube || passthrough ? RAY_PASS : 0), gridsize, entorient, ent);
-
if((havesel || dragging) && !passthroughsel) // now try selecting the selection
- if(rayboxintersect(vec(sel.o), vec(sel.s).mul(sel.grid), player->o, camdir, sdist, orient))
- { // and choose the nearest of the two
- if(sdist < wdist)
- {
+ if(rayboxintersect(vec(sel.o), vec(sel.s).mul(sel.grid), player->o, camdir, sdist, orient)) {
+ // and choose the nearest of the two
+ if(sdist < wdist) {
wdist = sdist;
ent = -1;
}
}
-
- if((hovering = hoveringonent(hidecursor ? -1 : ent, entorient)))
- {
+ if((hovering = hoveringonent(hidecursor ? -1 : ent, entorient))) {
if(!havesel)
- {
+ {
selchildcount = 0;
selchildmat = -1;
sel.s = ivec(0, 0, 0);
}
}
- else
- {
+ else {
vec w = vec(camdir).mul(wdist+0.05f).add(player->o);
- if(!insideworld(w))
- {
+ if(!insideworld(w)) {
loopi(3) wdist = min(wdist, ((camdir[i] > 0 ? worldsize : 0) - player->o[i]) / camdir[i]);
w = vec(camdir).mul(wdist-0.05f).add(player->o);
- if(!insideworld(w))
- {
+ if(!insideworld(w)) {
wdist = 0;
loopi(3) w[i] = clamp(player->o[i], 0.0f, float(worldsize));
}
@@ -429,17 +369,13 @@ void rendereditcursor()
cor = ivec(vec(w).mul(2).div(gridsize));
od = dimension(orient);
d = dimension(sel.orient);
-
- if(dragging)
- {
+ if(dragging) {
updateselection();
sel.cx = min(cor[R[d]], lastcor[R[d]]);
sel.cy = min(cor[C[d]], lastcor[C[d]]);
sel.cxs = max(cor[R[d]], lastcor[R[d]]);
sel.cys = max(cor[C[d]], lastcor[C[d]]);
-
- if(!selectcorners)
- {
+ if(!selectcorners) {
sel.cx &= ~1;
sel.cy &= ~1;
sel.cxs &= ~1;
@@ -447,18 +383,15 @@ void rendereditcursor()
sel.cxs -= sel.cx-2;
sel.cys -= sel.cy-2;
}
- else
- {
+ else {
sel.cxs -= sel.cx-1;
sel.cys -= sel.cy-1;
}
-
sel.cx &= 1;
sel.cy &= 1;
havesel = true;
}
- else if(!havesel)
- {
+ else if(!havesel) {
sel.o = lu;
sel.s.x = sel.s.y = sel.s.z = 1;
sel.cx = sel.cy = 0;
@@ -467,41 +400,29 @@ void rendereditcursor()
sel.orient = orient;
d = od;
}
-
sel.corner = (cor[R[d]]-(lu[R[d]]*2)/gridsize)+(cor[C[d]]-(lu[C[d]]*2)/gridsize)*2;
selchildcount = 0;
selchildmat = -1;
countselchild(worldroot, ivec(0, 0, 0), worldsize/2);
- if(mag>=1 && selchildcount==1)
- {
+ if(mag>=1 && selchildcount==1) {
selchildmat = c->material;
if(mag>1) selchildcount = -mag;
}
}
}
-
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
-
// cursors
-
notextureshader->set();
-
- renderentselection(player->o, camdir, entmoving!=0);
-
+ renderentselection(player->o, entmoving!=0);
boxoutline = outline!=0;
-
enablepolygonoffset(GL_POLYGON_OFFSET_LINE);
-
- if(!moving && !hovering && !hidecursor)
- {
+ if(!moving && !hovering && !hidecursor) {
gle::colorub(120,120,120);
boxs(orient, vec(lu), vec(lusize));
}
-
// selections
- if(havesel || moving)
- {
+ if(havesel || moving) {
d = dimension(sel.orient);
gle::colorub(50,50,50); // grid
boxsgrid(sel.orient, vec(sel.o), vec(sel.s), sel.grid);
@@ -518,16 +439,12 @@ void rendereditcursor()
gle::colorub(0,0,120);
boxs3D(vec(sel.o), vec(sel.s), sel.grid);
}
-
disablepolygonoffset(GL_POLYGON_OFFSET_LINE);
-
boxoutline = false;
-
glDisable(GL_BLEND);
}
-void tryedit()
-{
+void tryedit() {
extern int hidehud;
if(!editmode || hidehud || mainmenu) return;
}
@@ -536,15 +453,11 @@ void tryedit()
static bool haschanged = false;
-void readychanges(const ivec &bbmin, const ivec &bbmax, cube *c, const ivec &cor, int size)
-{
- loopoctabox(cor, size, bbmin, bbmax)
- {
+void readychanges(const ivec &bbmin, const ivec &bbmax, cube *c, const ivec &cor, int size) {
+ loopoctabox(cor, size, bbmin, bbmax) {
ivec o(i, cor, size);
- if(c[i].ext)
- {
- if(c[i].ext->va) // removes va s so that octarender will recreate
- {
+ if(c[i].ext) {
+ if(c[i].ext->va) { // removes va s so that octarender will recreate {
int hasmerges = c[i].ext->va->hasmerges;
destroyva(c[i].ext->va);
c[i].ext->va = NULL;
@@ -553,10 +466,8 @@ void readychanges(const ivec &bbmin, const ivec &bbmax, cube *c, const ivec &cor
freeoctaentities(c[i]);
c[i].ext->tjoints = -1;
}
- if(c[i].children)
- {
- if(size<=1)
- {
+ if(c[i].children) {
+ if(size<=1) {
solidfaces(c[i]);
discardchildren(c[i], true);
brightencube(c[i]);
@@ -567,11 +478,9 @@ void readychanges(const ivec &bbmin, const ivec &bbmax, cube *c, const ivec &cor
}
}
-void commitchanges(bool force)
-{
+void commitchanges(bool force) {
if(!force && !haschanged) return;
haschanged = false;
-
int oldlen = valist.length();
resetclipplanes();
entitiesinoctanodes();
@@ -582,44 +491,37 @@ void commitchanges(bool force)
updatevabbs();
}
-void changed(const block3 &sel, bool commit = true)
-{
+void changed(const block3 &sel, bool commit = true) {
if(sel.s.iszero()) return;
readychanges(ivec(sel.o).sub(1), ivec(sel.s).mul(sel.grid).add(sel.o).add(1), worldroot, ivec(0, 0, 0), worldsize/2);
haschanged = true;
-
if(commit) commitchanges();
}
//////////// copy and undo /////////////
-static inline void copycube(const cube &src, cube &dst)
-{
+static inline void copycube(const cube &src, cube &dst) {
dst = src;
dst.visible = 0;
dst.merged = 0;
dst.ext = NULL; // src cube is responsible for va destruction
- if(src.children)
- {
+ if(src.children) {
dst.children = newcubes(F_EMPTY);
loopi(8) copycube(src.children[i], dst.children[i]);
}
}
-static inline void pastecube(const cube &src, cube &dst)
-{
+static inline void pastecube(const cube &src, cube &dst) {
discardchildren(dst);
copycube(src, dst);
}
-void blockcopy(const block3 &s, int rgrid, block3 *b)
-{
+void blockcopy(const block3 &s, int rgrid, block3 *b) {
*b = s;
cube *q = b->c();
loopxyz(s, rgrid, copycube(c, *q++));
}
-block3 *blockcopy(const block3 &s, int rgrid)
-{
+block3 *blockcopy(const block3 &s, int rgrid) {
int bsize = sizeof(block3)+sizeof(cube)*s.size();
if(bsize <= 0 || bsize > (100<<20)) return NULL;
block3 *b = (block3 *)new (false) uchar[bsize];
@@ -627,41 +529,34 @@ block3 *blockcopy(const block3 &s, int rgrid)
return b;
}
-void freeblock(block3 *b, bool alloced = true)
-{
+void freeblock(block3 *b, bool alloced = true) {
cube *q = b->c();
loopi(b->size()) discardchildren(*q++);
if(alloced) delete[] b;
}
-void selgridmap(selinfo &sel, uchar *g) // generates a map of the cube sizes at each grid point
-{
+void selgridmap(selinfo &sel, uchar *g) { // generates a map of the cube sizes at each grid point {
loopxyz(sel, -sel.grid, (*g++ = bitscan(lusize), (void)c));
}
-void freeundo(undoblock *u)
-{
+void freeundo(undoblock *u) {
if(!u->numents) freeblock(u->block(), false);
delete[] (uchar *)u;
}
-void pasteundoblock(block3 *b, uchar *g)
-{
+void pasteundoblock(block3 *b, uchar *g) {
cube *s = b->c();
loopxyz(*b, 1<<min(int(*g++), worldscale-1), pastecube(*s++, c));
}
-void pasteundo(undoblock *u)
-{
+void pasteundo(undoblock *u) {
if(u->numents) pasteundoents(u);
else pasteundoblock(u->block(), u->gridmap());
}
-static inline int undosize(undoblock *u)
-{
+static inline int undosize(undoblock *u) {
if(u->numents) return u->numents*sizeof(undoent);
- else
- {
+ else {
block3 *b = u->block();
cube *q = b->c();
int size = b->size(), total = size;
@@ -670,37 +565,27 @@ static inline int undosize(undoblock *u)
}
}
-struct undolist
-{
+struct undolist {
undoblock *first, *last;
-
undolist() : first(NULL), last(NULL) {}
-
bool empty() { return !first; }
-
- void add(undoblock *u)
- {
+ void add(undoblock *u) {
u->next = NULL;
u->prev = last;
if(!first) first = last = u;
- else
- {
+ else {
last->next = u;
last = u;
}
}
-
- undoblock *popfirst()
- {
+ undoblock *popfirst() {
undoblock *u = first;
first = first->next;
if(first) first->prev = NULL;
else last = NULL;
return u;
}
-
- undoblock *poplast()
- {
+ undoblock *poplast() {
undoblock *u = last;
last = last->prev;
if(last) last->next = NULL;
@@ -713,17 +598,14 @@ undolist undos, redos;
VARP(undomegs, 0, 8, 100); // bounded by n megs
int totalundos = 0;
-void pruneundos(int maxremain) // bound memory
-{
- while(totalundos > maxremain && !undos.empty())
- {
+void pruneundos(int maxremain) { // bound memory {
+ while(totalundos > maxremain && !undos.empty()) {
undoblock *u = undos.popfirst();
totalundos -= u->size;
freeundo(u);
}
//conoutf(CON_DEBUG, "undo: %d of %d(%%%d)", totalundos, undomegs<<20, totalundos*100/(undomegs<<20));
- while(!redos.empty())
- {
+ while(!redos.empty()) {
undoblock *u = redos.popfirst();
totalundos -= u->size;
freeundo(u);
@@ -734,8 +616,7 @@ void clearundos() { pruneundos(0); }
COMMAND(clearundos, "");
-undoblock *newundocube(selinfo &s)
-{
+undoblock *newundocube(selinfo &s) {
int ssize = s.size(),
selgridsize = ssize,
blocksize = sizeof(block3)+ssize*sizeof(cube);
@@ -750,8 +631,7 @@ undoblock *newundocube(selinfo &s)
return u;
}
-void addundo(undoblock *u)
-{
+void addundo(undoblock *u) {
u->size = undosize(u);
u->timestamp = totalmillis;
undos.add(u);
@@ -761,21 +641,18 @@ void addundo(undoblock *u)
VARP(nompedit, 0, 1, 1);
-void makeundo(selinfo &s)
-{
+void makeundo(selinfo &s) {
undoblock *u = newundocube(s);
if(u) addundo(u);
}
-void makeundo() // stores state of selected cubes before editing
-{
+void makeundo() { // stores state of selected cubes before editing {
if(lastsel==sel || sel.s.iszero()) return;
lastsel=sel;
makeundo(sel);
}
-static inline int countblock(cube *c, int n = 8)
-{
+static inline int countblock(cube *c, int n = 8) {
int r = 0;
loopi(n) if(c[i].children) r += countblock(c[i].children); else ++r;
return r;
@@ -783,20 +660,16 @@ static inline int countblock(cube *c, int n = 8)
static int countblock(block3 *b) { return countblock(b->c(), b->size()); }
-void swapundo(undolist &a, undolist &b, int op)
-{
+void swapundo(undolist &a, undolist &b, int op) {
if(noedit()) return;
if(a.empty()) { conoutf(CON_WARN, "nothing more to %s", op == EDIT_REDO ? "redo" : "undo"); return; }
int ts = a.last->timestamp;
- if(multiplayer(false))
- {
+ if(multiplayer(false)) {
int n = 0, ops = 0;
- for(undoblock *u = a.last; u && ts==u->timestamp; u = u->prev)
- {
+ for(undoblock *u = a.last; u && ts==u->timestamp; u = u->prev) {
++ops;
n += u->numents ? u->numents : countblock(u->block());
- if(ops > 10 || n > 2500)
- {
+ if(ops > 10 || n > 2500) {
conoutf(CON_WARN, "undo too big for multiplayer");
if(nompedit) { multiplayer(); return; }
op = -1;
@@ -805,13 +678,11 @@ void swapundo(undolist &a, undolist &b, int op)
}
}
selinfo l = sel;
- while(!a.empty() && ts==a.last->timestamp)
- {
+ while(!a.empty() && ts==a.last->timestamp) {
if(op >= 0) game::edittrigger(sel, op);
undoblock *u = a.poplast(), *r;
if(u->numents) r = copyundoents(u);
- else
- {
+ else {
block3 *ub = u->block();
l.o = ub->o;
l.s = ub->s;
@@ -819,8 +690,7 @@ void swapundo(undolist &a, undolist &b, int op)
l.orient = ub->orient;
r = newundocube(l);
}
- if(r)
- {
+ if(r) {
r->size = u->size;
r->timestamp = totalmillis;
b.add(r);
@@ -845,15 +715,12 @@ vector<editinfo *> editinfos;
editinfo *localedit = NULL;
template<class B>
-static void packcube(cube &c, B &buf)
-{
- if(c.children)
- {
+static void packcube(cube &c, B &buf) {
+ if(c.children) {
buf.put(0xFF);
loopi(8) packcube(c.children[i], buf);
}
- else
- {
+ else {
cube data = c;
lilswap(data.texture, 6);
buf.put(c.material&0xFF);
@@ -864,8 +731,7 @@ static void packcube(cube &c, B &buf)
}
template<class B>
-static bool packblock(block3 &b, B &buf)
-{
+static bool packblock(block3 &b, B &buf) {
if(b.size() <= 0 || b.size() > (1<<20)) return false;
block3 hdr = b;
lilswap(hdr.o.v, 3);
@@ -878,23 +744,18 @@ static bool packblock(block3 &b, B &buf)
return true;
}
-struct vslothdr
-{
+struct vslothdr {
ushort index;
ushort slot;
};
-static void packvslots(cube &c, vector<uchar> &buf, vector<ushort> &used)
-{
- if(c.children)
- {
+static void packvslots(cube &c, vector<uchar> &buf, vector<ushort> &used) {
+ if(c.children) {
loopi(8) packvslots(c.children[i], buf, used);
}
- else loopi(6)
- {
+ else loopi(6) {
ushort index = c.texture[i];
- if(vslots.inrange(index) && vslots[index]->changed && used.find(index) < 0)
- {
+ if(vslots.inrange(index) && vslots[index]->changed && used.find(index) < 0) {
used.add(index);
VSlot &vs = *vslots[index];
vslothdr &hdr = *(vslothdr *)buf.pad(sizeof(vslothdr));
@@ -906,8 +767,7 @@ static void packvslots(cube &c, vector<uchar> &buf, vector<ushort> &used)
}
}
-static void packvslots(block3 &b, vector<uchar> &buf)
-{
+static void packvslots(block3 &b, vector<uchar> &buf) {
vector<ushort> used;
cube *c = b.c();
loopi(b.size()) packvslots(c[i], buf, used);
@@ -915,16 +775,13 @@ static void packvslots(block3 &b, vector<uchar> &buf)
}
template<class B>
-static void unpackcube(cube &c, B &buf)
-{
+static void unpackcube(cube &c, B &buf) {
int mat = buf.get();
- if(mat == 0xFF)
- {
+ if(mat == 0xFF) {
c.children = newcubes(F_EMPTY);
loopi(8) unpackcube(c.children[i], buf);
}
- else
- {
+ else {
c.material = mat | (buf.get()<<8);
buf.get(c.edges, sizeof(c.edges));
buf.get((uchar *)c.texture, sizeof(c.texture));
@@ -933,8 +790,7 @@ static void unpackcube(cube &c, B &buf)
}
template<class B>
-static bool unpackblock(block3 *&b, B &buf)
-{
+static bool unpackblock(block3 *&b, B &buf) {
if(b) { freeblock(b); b = NULL; }
block3 hdr;
if(buf.get((uchar *)&hdr, sizeof(hdr)) < int(sizeof(hdr))) return false;
@@ -952,33 +808,26 @@ static bool unpackblock(block3 *&b, B &buf)
return true;
}
-struct vslotmap
-{
+struct vslotmap {
int index;
VSlot *vslot;
-
vslotmap() {}
vslotmap(int index, VSlot *vslot) : index(index), vslot(vslot) {}
};
static vector<vslotmap> unpackingvslots;
-static void unpackvslots(cube &c, ucharbuf &buf)
-{
- if(c.children)
- {
+static void unpackvslots(cube &c, ucharbuf &buf) {
+ if(c.children) {
loopi(8) unpackvslots(c.children[i], buf);
}
- else loopi(6)
- {
+ else loopi(6) {
ushort tex = c.texture[i];
loopvj(unpackingvslots) if(unpackingvslots[j].index == tex) { c.texture[i] = unpackingvslots[j].vslot->index; break; }
}
}
-static void unpackvslots(block3 &b, ucharbuf &buf)
-{
- while(buf.remaining() >= int(sizeof(vslothdr)))
- {
+static void unpackvslots(block3 &b, ucharbuf &buf) {
+ while(buf.remaining() >= int(sizeof(vslothdr))) {
vslothdr &hdr = *(vslothdr *)buf.pad(sizeof(vslothdr));
lilswap(&hdr.index, 2);
if(!hdr.index) break;
@@ -989,20 +838,16 @@ static void unpackvslots(block3 &b, ucharbuf &buf)
VSlot *edit = editvslot(vs, ds);
unpackingvslots.add(vslotmap(hdr.index, edit ? edit : &vs));
}
-
cube *c = b.c();
loopi(b.size()) unpackvslots(c[i], buf);
-
unpackingvslots.setsize(0);
}
-static bool compresseditinfo(const uchar *inbuf, int inlen, uchar *&outbuf, int &outlen)
-{
+static bool compresseditinfo(const uchar *inbuf, int inlen, uchar *&outbuf, int &outlen) {
uLongf len = compressBound(inlen);
if(len > (1<<20)) return false;
outbuf = new (false) uchar[len];
- if(!outbuf || compress2((Bytef *)outbuf, &len, (const Bytef *)inbuf, inlen, Z_BEST_COMPRESSION) != Z_OK || len > (1<<16))
- {
+ if(!outbuf || compress2((Bytef *)outbuf, &len, (const Bytef *)inbuf, inlen, Z_BEST_COMPRESSION) != Z_OK || len > (1<<16)) {
delete[] outbuf;
outbuf = NULL;
return false;
@@ -1011,13 +856,11 @@ static bool compresseditinfo(const uchar *inbuf, int inlen, uchar *&outbuf, int
return true;
}
-static bool uncompresseditinfo(const uchar *inbuf, int inlen, uchar *&outbuf, int &outlen)
-{
+static bool uncompresseditinfo(const uchar *inbuf, int inlen, uchar *&outbuf, int &outlen) {
if(compressBound(outlen) > (1<<20)) return false;
uLongf len = outlen;
outbuf = new (false) uchar[len];
- if(!outbuf || uncompress((Bytef *)outbuf, &len, (const Bytef *)inbuf, inlen) != Z_OK)
- {
+ if(!outbuf || uncompress((Bytef *)outbuf, &len, (const Bytef *)inbuf, inlen) != Z_OK) {
delete[] outbuf;
outbuf = NULL;
return false;
@@ -1026,8 +869,7 @@ static bool uncompresseditinfo(const uchar *inbuf, int inlen, uchar *&outbuf, in
return true;
}
-bool packeditinfo(editinfo *e, int &inlen, uchar *&outbuf, int &outlen)
-{
+bool packeditinfo(editinfo *e, int &inlen, uchar *&outbuf, int &outlen) {
vector<uchar> buf;
if(!e || !e->copy || !packblock(*e->copy, buf)) return false;
packvslots(*e->copy, buf);
@@ -1035,15 +877,13 @@ bool packeditinfo(editinfo *e, int &inlen, uchar *&outbuf, int &outlen)
return compresseditinfo(buf.getbuf(), buf.length(), outbuf, outlen);
}
-bool unpackeditinfo(editinfo *&e, const uchar *inbuf, int inlen, int outlen)
-{
+bool unpackeditinfo(editinfo *&e, const uchar *inbuf, int inlen, int outlen) {
if(e && e->copy) { freeblock(e->copy); e->copy = NULL; }
uchar *outbuf = NULL;
if(!uncompresseditinfo(inbuf, inlen, outbuf, outlen)) return false;
ucharbuf buf(outbuf, outlen);
if(!e) e = editinfos.add(new editinfo);
- if(!unpackblock(e->copy, buf))
- {
+ if(!unpackblock(e->copy, buf)) {
delete[] outbuf;
return false;
}
@@ -1052,8 +892,7 @@ bool unpackeditinfo(editinfo *&e, const uchar *inbuf, int inlen, int outlen)
return true;
}
-void freeeditinfo(editinfo *&e)
-{
+void freeeditinfo(editinfo *&e) {
if(!e) return;
editinfos.removeobj(e);
if(e->copy) freeblock(e->copy);
@@ -1061,16 +900,13 @@ void freeeditinfo(editinfo *&e)
e = NULL;
}
-bool packundo(undoblock *u, int &inlen, uchar *&outbuf, int &outlen)
-{
+bool packundo(undoblock *u, int &inlen, uchar *&outbuf, int &outlen) {
vector<uchar> buf;
buf.reserve(512);
*(ushort *)buf.pad(2) = lilswap(ushort(u->numents));
- if(u->numents)
- {
+ if(u->numents) {
undoent *ue = u->ents();
- loopi(u->numents)
- {
+ loopi(u->numents) {
*(ushort *)buf.pad(2) = lilswap(ushort(ue[i].i));
entity &e = *(entity *)buf.pad(sizeof(entity));
e = ue[i].e;
@@ -1078,8 +914,7 @@ bool packundo(undoblock *u, int &inlen, uchar *&outbuf, int &outlen)
lilswap(&e.attr1, 5);
}
}
- else
- {
+ else {
block3 &b = *u->block();
if(!packblock(b, buf)) return false;
buf.put(u->gridmap(), b.size());
@@ -1089,26 +924,21 @@ bool packundo(undoblock *u, int &inlen, uchar *&outbuf, int &outlen)
return compresseditinfo(buf.getbuf(), buf.length(), outbuf, outlen);
}
-bool unpackundo(const uchar *inbuf, int inlen, int outlen)
-{
+bool unpackundo(const uchar *inbuf, int inlen, int outlen) {
uchar *outbuf = NULL;
if(!uncompresseditinfo(inbuf, inlen, outbuf, outlen)) return false;
ucharbuf buf(outbuf, outlen);
- if(buf.remaining() < 2)
- {
+ if(buf.remaining() < 2) {
delete[] outbuf;
return false;
}
int numents = lilswap(*(const ushort *)buf.pad(2));
- if(numents)
- {
- if(buf.remaining() < numents*int(2 + sizeof(entity)))
- {
+ if(numents) {
+ if(buf.remaining() < numents*int(2 + sizeof(entity))) {
delete[] outbuf;
return false;
}
- loopi(numents)
- {
+ loopi(numents) {
int idx = lilswap(*(const ushort *)buf.pad(2));
entity &e = *(entity *)buf.pad(sizeof(entity));
lilswap(&e.o.x, 3);
@@ -1116,11 +946,9 @@ bool unpackundo(const uchar *inbuf, int inlen, int outlen)
pasteundoent(idx, e);
}
}
- else
- {
+ else {
block3 *b = NULL;
- if(!unpackblock(b, buf) || b->grid >= worldsize || buf.remaining() < b->size())
- {
+ if(!unpackblock(b, buf) || b->grid >= worldsize || buf.remaining() < b->size()) {
freeblock(b);
delete[] outbuf;
return false;
@@ -1136,33 +964,26 @@ bool unpackundo(const uchar *inbuf, int inlen, int outlen)
return true;
}
-bool packundo(int op, int &inlen, uchar *&outbuf, int &outlen)
-{
- switch(op)
- {
+bool packundo(int op, int &inlen, uchar *&outbuf, int &outlen) {
+ switch(op) {
case EDIT_UNDO: return !undos.empty() && packundo(undos.last, inlen, outbuf, outlen);
case EDIT_REDO: return !redos.empty() && packundo(redos.last, inlen, outbuf, outlen);
default: return false;
}
}
-struct prefabheader
-{
+struct prefabheader {
char magic[4];
int version;
};
-struct prefab : editinfo
-{
+struct prefab : editinfo {
char *name;
GLuint ebo, vbo;
int numtris, numverts;
-
prefab() : name(NULL), ebo(0), vbo(0), numtris(0), numverts(0) {}
~prefab() { DELETEA(name); if(copy) freeblock(copy); }
-
- void cleanup()
- {
+ void cleanup() {
if(ebo) { glDeleteBuffers_(1, &ebo); ebo = 0; }
if(vbo) { glDeleteBuffers_(1, &vbo); vbo = 0; }
numtris = numverts = 0;
@@ -1171,16 +992,13 @@ struct prefab : editinfo
static hashnameset<prefab> prefabs;
-void cleanupprefabs()
-{
+void cleanupprefabs() {
enumerate(prefabs, prefab, p, p.cleanup());
}
-void delprefab(char *name)
-{
+void delprefab(char *name) {
prefab *p = prefabs.access(name);
- if(p)
- {
+ if(p) {
p->cleanup();
prefabs.remove(name);
conoutf("deleted prefab %s", name);
@@ -1188,12 +1006,10 @@ void delprefab(char *name)
}
COMMAND(delprefab, "s");
-void saveprefab(char *name)
-{
+void saveprefab(char *name) {
if(!name[0] || noedit(true) || (nompedit && multiplayer())) return;
prefab *b = prefabs.access(name);
- if(!b)
- {
+ if(!b) {
b = &prefabs[name];
b->name = newstring(name);
}
@@ -1216,8 +1032,7 @@ void saveprefab(char *name)
}
COMMAND(saveprefab, "s");
-void pasteblock(block3 &b, selinfo &sel, bool local)
-{
+void pasteblock(block3 &b, selinfo &sel, bool local) {
sel.s = b.s;
int o = sel.orient;
sel.orient = b.orient;
@@ -1226,13 +1041,11 @@ void pasteblock(block3 &b, selinfo &sel, bool local)
sel.orient = o;
}
-bool prefabloaded(const char *name)
-{
+bool prefabloaded(const char *name) {
return prefabs.access(name) != NULL;
}
-prefab *loadprefab(const char *name, bool msg = true)
-{
+prefab *loadprefab(const char *name, bool msg = true) {
prefab *b = prefabs.access(name);
if(b) return b;
@@ -1256,31 +1069,24 @@ prefab *loadprefab(const char *name, bool msg = true)
return b;
}
-void pasteprefab(char *name)
-{
+void pasteprefab(char *name) {
if(!name[0] || noedit() || (nompedit && multiplayer())) return;
prefab *b = loadprefab(name, true);
if(b) pasteblock(*b->copy, sel, true);
}
COMMAND(pasteprefab, "s");
-struct prefabmesh
-{
+struct prefabmesh {
struct vertex { vec pos; bvec4 norm; };
-
static const int SIZE = 1<<9;
int table[SIZE];
vector<vertex> verts;
vector<int> chain;
vector<ushort> tris;
-
prefabmesh() { memset(table, -1, sizeof(table)); }
-
- int addvert(const vertex &v)
- {
+ int addvert(const vertex &v) {
uint h = hthash(v.pos)&(SIZE-1);
- for(int i = table[h]; i>=0; i = chain[i])
- {
+ for(int i = table[h]; i>=0; i = chain[i]) {
const vertex &c = verts[i];
if(c.pos==v.pos && c.norm==v.norm) return i;
}
@@ -1289,28 +1095,21 @@ struct prefabmesh
chain.add(table[h]);
return table[h] = verts.length()-1;
}
-
- int addvert(const vec &pos, const bvec &norm)
- {
+ int addvert(const vec &pos, const bvec &norm) {
vertex vtx;
vtx.pos = pos;
vtx.norm = norm;
return addvert(vtx);
}
-
- void setup(prefab &p)
- {
+ void setup(prefab &p) {
if(tris.empty()) return;
-
p.cleanup();
-
loopv(verts) verts[i].norm.flip();
if(!p.vbo) glGenBuffers_(1, &p.vbo);
gle::bindvbo(p.vbo);
glBufferData_(GL_ARRAY_BUFFER, verts.length()*sizeof(vertex), verts.getbuf(), GL_STATIC_DRAW);
gle::clearvbo();
p.numverts = verts.length();
-
if(!p.ebo) glGenBuffers_(1, &p.ebo);
gle::bindebo(p.ebo);
glBufferData_(GL_ELEMENT_ARRAY_BUFFER, tris.length()*sizeof(ushort), tris.getbuf(), GL_STATIC_DRAW);
@@ -1320,23 +1119,18 @@ struct prefabmesh
};
-static void genprefabmesh(prefabmesh &r, cube &c, const ivec &co, int size)
-{
- if(c.children)
- {
+static void genprefabmesh(prefabmesh &r, cube &c, const ivec &co, int size) {
+ if(c.children) {
neighbourstack[++neighbourdepth] = c.children;
- loopi(8)
- {
+ loopi(8) {
ivec o(i, co, size/2);
genprefabmesh(r, c.children[i], o, size/2);
}
--neighbourdepth;
}
- else if(!isempty(c))
- {
+ else if(!isempty(c)) {
int vis;
- loopi(6) if((vis = visibletris(c, i, co, size)))
- {
+ loopi(6) if((vis = visibletris(c, i, co, size))) {
ivec v[4];
genfaceverts(c, i, v);
int convex = 0;
@@ -1350,8 +1144,7 @@ static void genprefabmesh(prefabmesh &r, cube &c, const ivec &co, int size)
guessnormals(pos, numverts, norm);
int index[4];
loopj(numverts) index[j] = r.addvert(pos[j], bvec(norm[j]));
- loopj(numverts-2) if(index[0]!=index[j+1] && index[j+1]!=index[j+2] && index[j+2]!=index[0])
- {
+ loopj(numverts-2) if(index[0]!=index[j+1] && index[j+1]!=index[j+2] && index[j+2]!=index[0]) {
r.tris.add(index[0]);
r.tris.add(index[j+1]);
r.tris.add(index[j+2]);
@@ -1360,53 +1153,40 @@ static void genprefabmesh(prefabmesh &r, cube &c, const ivec &co, int size)
}
}
-void genprefabmesh(prefab &p)
-{
+void genprefabmesh(prefab &p) {
block3 b = *p.copy;
b.o = ivec(0, 0, 0);
-
cube *oldworldroot = worldroot;
int oldworldscale = worldscale, oldworldsize = worldsize;
-
worldroot = newcubes();
worldscale = 1;
worldsize = 2;
- while(worldsize < max(max(b.s.x, b.s.y), b.s.z)*b.grid)
- {
+ while(worldsize < max(max(b.s.x, b.s.y), b.s.z)*b.grid) {
worldscale++;
worldsize *= 2;
}
-
cube *s = p.copy->c();
loopxyz(b, b.grid, if(!isempty(*s) || s->children) pastecube(*s, c); s++);
-
prefabmesh r;
neighbourstack[++neighbourdepth] = worldroot;
loopi(8) genprefabmesh(r, worldroot[i], ivec(i, ivec(0, 0, 0), worldsize/2), worldsize/2);
--neighbourdepth;
r.setup(p);
-
freeocta(worldroot);
-
worldroot = oldworldroot;
worldscale = oldworldscale;
worldsize = oldworldsize;
-
useshaderbyname("prefab");
}
extern int outlinecolour;
-static void renderprefab(prefab &p, const vec &o, float yaw, float pitch, float roll, float size, const vec &color)
-{
- if(!p.numtris)
- {
+static void renderprefab(prefab &p, const vec &o, float yaw, float pitch, float roll, float size, const vec &color) {
+ if(!p.numtris) {
genprefabmesh(p);
if(!p.numtris) return;
}
-
block3 &b = *p.copy;
-
matrix4 m;
m.identity();
m.settranslation(o);
@@ -1416,7 +1196,6 @@ static void renderprefab(prefab &p, const vec &o, float yaw, float pitch, float
matrix3 w(m);
if(size > 0 && size != 1) m.scale(size);
m.translate(vec(b.s).mul(-b.grid*0.5f));
-
gle::bindvbo(p.vbo);
gle::bindebo(p.ebo);
gle::enablevertex();
@@ -1424,7 +1203,6 @@ static void renderprefab(prefab &p, const vec &o, float yaw, float pitch, float
prefabmesh::vertex *v = (prefabmesh::vertex *)0;
gle::vertexpointer(sizeof(prefabmesh::vertex), v->pos.v);
gle::normalpointer(sizeof(prefabmesh::vertex), v->norm.v, GL_BYTE);
-
matrix4 pm;
pm.mul(camprojmatrix, m);
GLOBALPARAM(prefabmatrix, pm);
@@ -1432,36 +1210,29 @@ static void renderprefab(prefab &p, const vec &o, float yaw, float pitch, float
SETSHADER(prefab);
gle::color(color);
glDrawRangeElements_(GL_TRIANGLES, 0, p.numverts-1, p.numtris*3, GL_UNSIGNED_SHORT, (ushort *)0);
-
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
enablepolygonoffset(GL_POLYGON_OFFSET_LINE);
-
pm.mul(camprojmatrix, m);
GLOBALPARAM(prefabmatrix, pm);
SETSHADER(prefab);
gle::color(vec::hexcolor(outlinecolour));
glDrawRangeElements_(GL_TRIANGLES, 0, p.numverts-1, p.numtris*3, GL_UNSIGNED_SHORT, (ushort *)0);
-
disablepolygonoffset(GL_POLYGON_OFFSET_LINE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
gle::disablevertex();
gle::disablenormal();
gle::clearebo();
gle::clearvbo();
}
-void renderprefab(const char *name, const vec &o, float yaw, float pitch, float roll, float size, const vec &color)
-{
+void renderprefab(const char *name, const vec &o, float yaw, float pitch, float roll, float size, const vec &color) {
prefab *p = loadprefab(name, false);
if(p) renderprefab(*p, o, yaw, pitch, roll, size, color);
}
-void previewprefab(const char *name, const vec &color)
-{
+void previewprefab(const char *name, const vec &color) {
prefab *p = loadprefab(name, false);
- if(p)
- {
+ if(p) {
block3 &b = *p->copy;
float yaw;
vec o = calcmodelpreviewpos(vec(b.s).mul(b.grid*0.5f), yaw);
@@ -1469,8 +1240,7 @@ void previewprefab(const char *name, const vec &color)
}
}
-void mpcopy(editinfo *&e, selinfo &sel, bool local)
-{
+void mpcopy(editinfo *&e, selinfo &sel, bool local) {
if(local) game::edittrigger(sel, EDIT_COPY);
if(e==NULL) e = editinfos.add(new editinfo);
if(e->copy) freeblock(e->copy);
@@ -1479,29 +1249,25 @@ void mpcopy(editinfo *&e, selinfo &sel, bool local)
changed(sel);
}
-void mppaste(editinfo *&e, selinfo &sel, bool local)
-{
+void mppaste(editinfo *&e, selinfo &sel, bool local) {
if(e==NULL) return;
if(local) game::edittrigger(sel, EDIT_PASTE);
if(e->copy) pasteblock(*e->copy, sel, local);
}
-void copy()
-{
+void copy() {
if(noedit(true)) return;
mpcopy(localedit, sel, true);
}
-void pastehilite()
-{
+void pastehilite() {
if(!localedit) return;
sel.s = localedit->copy->s;
reorient();
havesel = true;
}
-void paste()
-{
+void paste() {
if(noedit(true)) return;
mppaste(localedit, sel, true);
}
@@ -1513,19 +1279,16 @@ COMMANDN(undo, editundo, "");
COMMANDN(redo, editredo, "");
static vector<int *> editingvslots;
-struct vslotref
-{
+struct vslotref {
vslotref(int &index) { editingvslots.add(&index); }
~vslotref() { editingvslots.pop(); }
};
#define editingvslot(...) vslotref vslotrefs[] = { __VA_ARGS__ }; (void)vslotrefs;
-void compacteditvslots()
-{
+void compacteditvslots() {
loopv(editingvslots) if(*editingvslots[i]) compactvslot(*editingvslots[i]);
loopv(unpackingvslots) compactvslot(*unpackingvslots[i].vslot);
- loopv(editinfos)
- {
+ loopv(editinfos) {
editinfo *e = editinfos[i];
compactvslots(e->copy->c(), e->copy->size());
}
@@ -1541,31 +1304,25 @@ void compacteditvslots()
int bounded(int n) { return n<0 ? 0 : (n>8 ? 8 : n); }
-void pushedge(uchar &edge, int dir, int dc)
-{
+void pushedge(uchar &edge, int dir, int dc) {
int ne = bounded(edgeget(edge, dc)+dir);
edgeset(edge, dc, ne);
int oe = edgeget(edge, 1-dc);
if((dir<0 && dc && oe>ne) || (dir>0 && dc==0 && oe<ne)) edgeset(edge, 1-dc, ne);
}
-void linkedpush(cube &c, int d, int x, int y, int dc, int dir)
-{
+void linkedpush(cube &c, int d, int x, int y, int dc, int dir) {
ivec v, p;
getcubevector(c, d, x, y, dc, v);
-
- loopi(2) loopj(2)
- {
+ loopi(2) loopj(2) {
getcubevector(c, d, i, j, dc, p);
if(v==p)
pushedge(cubeedge(c, d, i, j), dir, dc);
}
}
-static ushort getmaterial(cube &c)
-{
- if(c.children)
- {
+static ushort getmaterial(cube &c) {
+ if(c.children) {
ushort mat = getmaterial(c.children[7]);
loopi(7) if(mat != getmaterial(c.children[i])) return MAT_AIR;
return mat;
@@ -1575,35 +1332,27 @@ static ushort getmaterial(cube &c)
VAR(invalidcubeguard, 0, 1, 1);
-void mpeditface(int dir, int mode, selinfo &sel, bool local)
-{
+void mpeditface(int dir, int mode, selinfo &sel, bool local) {
if(mode==1 && (sel.cx || sel.cy || sel.cxs&1 || sel.cys&1)) mode = 0;
int d = dimension(sel.orient);
int dc = dimcoord(sel.orient);
int seldir = dc ? -dir : dir;
-
if(local)
game::edittrigger(sel, EDIT_FACE, dir, mode);
-
- if(mode==1)
- {
+ if(mode==1) {
int h = sel.o[d]+dc*sel.grid;
if(((dir>0) == dc && h<=0) || ((dir<0) == dc && h>=worldsize)) return;
if(dir<0) sel.o[d] += sel.grid * seldir;
}
-
if(dc) sel.o[d] += sel.us(d)-sel.grid;
sel.s[d] = 1;
-
loopselxyz(
if(c.children) solidfaces(c);
ushort mat = getmaterial(c);
discardchildren(c, true);
c.material = mat;
- if(mode==1) // fill command
- {
- if(dir<0)
- {
+ if(mode==1) { // fill command {
+ if(dir<0) {
solidfaces(c);
cube &o = blockcube(x, y, 1, sel, -sel.grid);
loopi(6)
@@ -1612,35 +1361,27 @@ void mpeditface(int dir, int mode, selinfo &sel, bool local)
else
emptyfaces(c);
}
- else
- {
+ else {
uint bak = c.faces[d];
uchar *p = (uchar *)&c.faces[d];
-
if(mode==2)
linkedpush(c, d, sel.corner&1, sel.corner>>1, dc, seldir); // corner command
- else
- {
- loop(mx,2) loop(my,2) // pull/push edges command
- {
+ else {
+ loop(mx,2) loop(my,2) { // pull/push edges command {
if(x==0 && mx==0 && sel.cx) continue;
if(y==0 && my==0 && sel.cy) continue;
if(x==sel.s[R[d]]-1 && mx==1 && (sel.cx+sel.cxs)&1) continue;
if(y==sel.s[C[d]]-1 && my==1 && (sel.cy+sel.cys)&1) continue;
if(p[mx+my*2] != ((uchar *)&bak)[mx+my*2]) continue;
-
linkedpush(c, d, mx, my, dc, seldir);
}
}
-
optiface(p, c);
- if(invalidcubeguard==1 && !isvalidcube(c))
- {
+ if(invalidcubeguard==1 && !isvalidcube(c)) {
uint newbak = c.faces[d];
uchar *m = (uchar *)&bak;
uchar *n = (uchar *)&newbak;
- loopk(4) if(n[k] != m[k]) // tries to find partial edit that is valid
- {
+ loopk(4) if(n[k] != m[k]) { // tries to find partial edit that is valid {
c.faces[d] = bak;
c.edges[d*4+k] = n[k];
if(isvalidcube(c))
@@ -1654,35 +1395,30 @@ void mpeditface(int dir, int mode, selinfo &sel, bool local)
sel.o[d] += sel.grid * seldir;
}
-void editface(int *dir, int *mode)
-{
+void editface(int *dir, int *mode) {
if(noedit(moving!=0)) return;
mpeditface(*dir, *mode, sel, true);
}
VAR(selectionsurf, 0, 0, 1);
-void pushsel(int *dir)
-{
+void pushsel(int *dir) {
if(noedit(moving!=0)) return;
int d = dimension(orient);
int s = dimcoord(orient) ? -*dir : *dir;
sel.o[d] += s*sel.grid;
- if(selectionsurf==1)
- {
+ if(selectionsurf==1) {
player->o[d] += s*sel.grid;
player->resetinterp();
}
}
-void mpdelcube(selinfo &sel, bool local)
-{
+void mpdelcube(selinfo &sel, bool local) {
if(local) game::edittrigger(sel, EDIT_DELCUBE);
loopselxyz(discardchildren(c, true); emptyfaces(c));
}
-void delcube()
-{
+void delcube() {
if(noedit(true)) return;
mpdelcube(sel, true);
}
@@ -1697,11 +1433,9 @@ int curtexindex = -1, lasttex = 0, lasttexmillis = -1;
int texpaneltimer = 0;
vector<ushort> texmru;
-void tofronttex() // maintain most recently used of the texture lists when applying texture
-{
+void tofronttex() { // maintain most recently used of the texture lists when applying texture {
int c = curtexindex;
- if(texmru.inrange(c))
- {
+ if(texmru.inrange(c)) {
texmru.insert(0, texmru.remove(c));
curtexindex = -1;
}
@@ -1714,14 +1448,12 @@ static vector<vslotmap> remappedvslots;
VAR(usevdelta, 1, 0, 0);
-static VSlot *remapvslot(int index, bool delta, const VSlot &ds)
-{
+static VSlot *remapvslot(int index, bool delta, const VSlot &ds) {
loopv(remappedvslots) if(remappedvslots[i].index == index) return remappedvslots[i].vslot;
VSlot &vs = lookupvslot(index, false);
if(vs.index < 0) return NULL;
VSlot *edit = NULL;
- if(delta)
- {
+ if(delta) {
VSlot ms;
mergevslot(ms, vs, ds);
edit = ms.changed ? editvslot(vs, ms) : vs.slot->variants;
@@ -1732,31 +1464,24 @@ static VSlot *remapvslot(int index, bool delta, const VSlot &ds)
return edit;
}
-static void remapvslots(cube &c, bool delta, const VSlot &ds, int orient, bool &findrep, VSlot *&findedit)
-{
- if(c.children)
- {
+static void remapvslots(cube &c, bool delta, const VSlot &ds, int orient, bool &findrep, VSlot *&findedit) {
+ if(c.children) {
loopi(8) remapvslots(c.children[i], delta, ds, orient, findrep, findedit);
return;
}
static VSlot ms;
- if(orient<0) loopi(6)
- {
+ if(orient<0) loopi(6) {
VSlot *edit = remapvslot(c.texture[i], delta, ds);
- if(edit)
- {
+ if(edit) {
c.texture[i] = edit->index;
if(!findedit) findedit = edit;
}
}
- else
- {
+ else {
int i = visibleorient(c, orient);
VSlot *edit = remapvslot(c.texture[i], delta, ds);
- if(edit)
- {
- if(findrep)
- {
+ if(edit) {
+ if(findrep) {
if(reptex < 0) reptex = c.texture[i];
else if(reptex != c.texture[i]) findrep = false;
}
@@ -1766,14 +1491,11 @@ static void remapvslots(cube &c, bool delta, const VSlot &ds, int orient, bool &
}
}
-void edittexcube(cube &c, int tex, int orient, bool &findrep)
-{
+void edittexcube(cube &c, int tex, int orient, bool &findrep) {
if(orient<0) loopi(6) c.texture[i] = tex;
- else
- {
+ else {
int i = visibleorient(c, orient);
- if(findrep)
- {
+ if(findrep) {
if(reptex < 0) reptex = c.texture[i];
else if(reptex != c.texture[i]) findrep = false;
}
@@ -1784,10 +1506,8 @@ void edittexcube(cube &c, int tex, int orient, bool &findrep)
VAR(allfaces, 0, 0, 1);
-void mpeditvslot(int delta, VSlot &ds, int allfaces, selinfo &sel, bool local)
-{
- if(local)
- {
+void mpeditvslot(int delta, VSlot &ds, int allfaces, selinfo &sel, bool local) {
+ if(local) {
game::edittrigger(sel, EDIT_VSLOT, delta, allfaces, 0, &ds);
if(!(lastsel==sel)) tofronttex();
if(allfaces || !(repsel == sel)) reptex = -1;
@@ -1797,21 +1517,18 @@ void mpeditvslot(int delta, VSlot &ds, int allfaces, selinfo &sel, bool local)
VSlot *findedit = NULL;
loopselxyz(remapvslots(c, delta != 0, ds, allfaces ? -1 : sel.orient, findrep, findedit));
remappedvslots.setsize(0);
- if(local && findedit)
- {
+ if(local && findedit) {
lasttex = findedit->index;
lasttexmillis = totalmillis;
curtexindex = texmru.find(lasttex);
- if(curtexindex < 0)
- {
+ if(curtexindex < 0) {
curtexindex = texmru.length();
texmru.add(lasttex);
}
}
}
-bool mpeditvslot(int delta, int allfaces, selinfo &sel, ucharbuf &buf)
-{
+bool mpeditvslot(int delta, int allfaces, selinfo &sel, ucharbuf &buf) {
VSlot ds;
if(!unpackvslot(buf, ds, delta != 0)) return false;
editingvslot(ds.layer);
@@ -1819,8 +1536,7 @@ bool mpeditvslot(int delta, int allfaces, selinfo &sel, ucharbuf &buf)
return true;
}
-void vdelta(char *body)
-{
+void vdelta(char *body) {
if(noedit()) return;
usevdelta++;
execute(body);
@@ -1828,8 +1544,7 @@ void vdelta(char *body)
}
COMMAND(vdelta, "s");
-void vrotate(int *n)
-{
+void vrotate(int *n) {
if(noedit()) return;
VSlot ds;
ds.changed = 1<<VSLOT_ROTATION;
@@ -1839,8 +1554,7 @@ void vrotate(int *n)
COMMAND(vrotate, "i");
ICOMMAND(getvrotate, "i", (int *tex), intret(lookupvslot(*tex, false).rotation));
-void voffset(int *x, int *y)
-{
+void voffset(int *x, int *y) {
if(noedit()) return;
VSlot ds;
ds.changed = 1<<VSLOT_OFFSET;
@@ -1848,15 +1562,13 @@ void voffset(int *x, int *y)
mpeditvslot(usevdelta, ds, allfaces, sel, true);
}
COMMAND(voffset, "ii");
-ICOMMAND(getvoffset, "i", (int *tex),
-{
+ICOMMAND(getvoffset, "i", (int *tex), {
VSlot &vslot = lookupvslot(*tex, false);
defformatstring(str, "%d %d", vslot.offset.x, vslot.offset.y);
result(str);
});
-void vscroll(float *s, float *t)
-{
+void vscroll(float *s, float *t) {
if(noedit()) return;
VSlot ds;
ds.changed = 1<<VSLOT_SCROLL;
@@ -1864,15 +1576,13 @@ void vscroll(float *s, float *t)
mpeditvslot(usevdelta, ds, allfaces, sel, true);
}
COMMAND(vscroll, "ff");
-ICOMMAND(getvscroll, "i", (int *tex),
-{
+ICOMMAND(getvscroll, "i", (int *tex), {
VSlot &vslot = lookupvslot(*tex, false);
defformatstring(str, "%s %s", floatstr(vslot.scroll.x), floatstr(vslot.scroll.y));
result(str);
});
-void vscale(float *scale)
-{
+void vscale(float *scale) {
if(noedit()) return;
VSlot ds;
ds.changed = 1<<VSLOT_SCALE;
@@ -1882,13 +1592,11 @@ void vscale(float *scale)
COMMAND(vscale, "f");
ICOMMAND(getvscale, "i", (int *tex), floatret(lookupvslot(*tex, false).scale));
-void vlayer(int *n)
-{
+void vlayer(int *n) {
if(noedit()) return;
VSlot ds;
ds.changed = 1<<VSLOT_LAYER;
- if(vslots.inrange(*n))
- {
+ if(vslots.inrange(*n)) {
ds.layer = *n;
if(vslots[ds.layer]->changed && nompedit && multiplayer()) return;
}
@@ -1898,8 +1606,7 @@ void vlayer(int *n)
COMMAND(vlayer, "i");
ICOMMAND(getvlayer, "i", (int *tex), intret(lookupvslot(*tex, false).layer));
-void valpha(float *front, float *back)
-{
+void valpha(float *front, float *back) {
if(noedit()) return;
VSlot ds;
ds.changed = 1<<VSLOT_ALPHA;
@@ -1908,15 +1615,13 @@ void valpha(float *front, float *back)
mpeditvslot(usevdelta, ds, allfaces, sel, true);
}
COMMAND(valpha, "ff");
-ICOMMAND(getvalpha, "i", (int *tex),
-{
+ICOMMAND(getvalpha, "i", (int *tex), {
VSlot &vslot = lookupvslot(*tex, false);
defformatstring(str, "%s %s", floatstr(vslot.alphafront), floatstr(vslot.alphaback));
result(str);
});
-void vcolor(float *r, float *g, float *b)
-{
+void vcolor(float *r, float *g, float *b) {
if(noedit()) return;
VSlot ds;
ds.changed = 1<<VSLOT_COLOR;
@@ -1924,54 +1629,45 @@ void vcolor(float *r, float *g, float *b)
mpeditvslot(usevdelta, ds, allfaces, sel, true);
}
COMMAND(vcolor, "fff");
-ICOMMAND(getvcolor, "i", (int *tex),
-{
+ICOMMAND(getvcolor, "i", (int *tex), {
VSlot &vslot = lookupvslot(*tex, false);
defformatstring(str, "%s %s %s", floatstr(vslot.colorscale.r), floatstr(vslot.colorscale.g), floatstr(vslot.colorscale.b));
result(str);
});
-void vreset()
-{
+void vreset() {
if(noedit()) return;
VSlot ds;
mpeditvslot(usevdelta, ds, allfaces, sel, true);
}
COMMAND(vreset, "");
-void vshaderparam(const char *name, float *x, float *y, float *z, float *w)
-{
+void vshaderparam(const char *name, float *x, float *y, float *z, float *w) {
if(noedit()) return;
VSlot ds;
ds.changed = 1<<VSLOT_SHPARAM;
- if(name[0])
- {
+ if(name[0]) {
SlotShaderParam p = { getshaderparamname(name), -1, {*x, *y, *z, *w} };
ds.params.add(p);
}
mpeditvslot(usevdelta, ds, allfaces, sel, true);
}
COMMAND(vshaderparam, "sffff");
-ICOMMAND(getvshaderparam, "is", (int *tex, const char *name),
-{
+ICOMMAND(getvshaderparam, "is", (int *tex, const char *name), {
VSlot &vslot = lookupvslot(*tex, false);
- loopv(vslot.params)
- {
+ loopv(vslot.params) {
SlotShaderParam &p = vslot.params[i];
- if(!strcmp(p.name, name))
- {
+ if(!strcmp(p.name, name)) {
defformatstring(str, "%s %s %s %s", floatstr(p.val[0]), floatstr(p.val[1]), floatstr(p.val[2]), floatstr(p.val[3]));
result(str);
return;
}
}
});
-ICOMMAND(getvshaderparamnames, "i", (int *tex),
-{
+ICOMMAND(getvshaderparamnames, "i", (int *tex), {
VSlot &vslot = lookupvslot(*tex, false);
vector<char> str;
- loopv(vslot.params)
- {
+ loopv(vslot.params) {
SlotShaderParam &p = vslot.params[i];
if(i) str.put(' ');
str.put(p.name, strlen(p.name));
@@ -1980,10 +1676,8 @@ ICOMMAND(getvshaderparamnames, "i", (int *tex),
stringret(newstring(str.getbuf(), str.length()-1));
});
-void mpedittex(int tex, int allfaces, selinfo &sel, bool local)
-{
- if(local)
- {
+void mpedittex(int tex, int allfaces, selinfo &sel, bool local) {
+ if(local) {
game::edittrigger(sel, EDIT_TEX, tex, allfaces);
if(allfaces || !(repsel == sel)) reptex = -1;
repsel = sel;
@@ -1992,8 +1686,7 @@ void mpedittex(int tex, int allfaces, selinfo &sel, bool local)
loopselxyz(edittexcube(c, tex, allfaces ? -1 : sel.orient, findrep));
}
-static int unpacktex(int &tex, ucharbuf &buf, bool insert = true)
-{
+static int unpacktex(int &tex, ucharbuf &buf, bool insert = true) {
if(tex < 0x10000) return true;
VSlot ds;
if(!unpackvslot(buf, ds, false)) return false;
@@ -2005,10 +1698,8 @@ static int unpacktex(int &tex, ucharbuf &buf, bool insert = true)
return true;
}
-int shouldpacktex(int index)
-{
- if(vslots.inrange(index))
- {
+int shouldpacktex(int index) {
+ if(vslots.inrange(index)) {
VSlot &vs = *vslots[index];
if(vs.changed) return 0x10000 + vs.slot->index;
}
@@ -2016,19 +1707,15 @@ int shouldpacktex(int index)
}
-bool mpedittex(int tex, int allfaces, selinfo &sel, ucharbuf &buf)
-{
+bool mpedittex(int tex, int allfaces, selinfo &sel, ucharbuf &buf) {
if(!unpacktex(tex, buf)) return false;
mpedittex(tex, allfaces, sel, false);
return true;
}
-void filltexlist()
-{
- if(texmru.length()!=vslots.length())
- {
- loopvrev(texmru) if(texmru[i]>=vslots.length())
- {
+void filltexlist() {
+ if(texmru.length()!=vslots.length()) {
+ loopvrev(texmru) if(texmru[i]>=vslots.length()) {
if(curtexindex > i) curtexindex--;
else if(curtexindex == i) curtexindex = -1;
texmru.remove(i);
@@ -2037,16 +1724,12 @@ void filltexlist()
}
}
-void compactmruvslots()
-{
+void compactmruvslots() {
remappedvslots.setsize(0);
- loopvrev(texmru)
- {
- if(vslots.inrange(texmru[i]))
- {
+ loopvrev(texmru) {
+ if(vslots.inrange(texmru[i])) {
VSlot &vs = *vslots[texmru[i]];
- if(vs.index >= 0)
- {
+ if(vs.index >= 0) {
texmru[i] = vs.index;
continue;
}
@@ -2055,8 +1738,7 @@ void compactmruvslots()
else if(curtexindex == i) curtexindex = -1;
texmru.remove(i);
}
- if(vslots.inrange(lasttex))
- {
+ if(vslots.inrange(lasttex)) {
VSlot &vs = *vslots[lasttex];
lasttex = vs.index >= 0 ? vs.index : 0;
}
@@ -2064,19 +1746,16 @@ void compactmruvslots()
reptex = vslots.inrange(reptex) ? vslots[reptex]->index : -1;
}
-void edittex(int i, bool save = true)
-{
+void edittex(int i, bool save = true) {
lasttex = i;
lasttexmillis = totalmillis;
- if(save)
- {
+ if(save) {
loopvj(texmru) if(texmru[j]==lasttex) { curtexindex = j; break; }
}
mpedittex(i, allfaces, sel, true);
}
-void edittex_(int *dir)
-{
+void edittex_(int *dir) {
if(noedit()) return;
filltexlist();
if(texmru.empty()) return;
@@ -2086,22 +1765,19 @@ void edittex_(int *dir)
edittex(texmru[curtexindex], false);
}
-void gettex()
-{
+void gettex() {
if(noedit(true)) return;
filltexlist();
int tex = -1;
loopxyz(sel, sel.grid, tex = c.texture[sel.orient]);
- loopv(texmru) if(texmru[i]==tex)
- {
+ loopv(texmru) if(texmru[i]==tex) {
curtexindex = i;
tofronttex();
return;
}
}
-void getcurtex()
-{
+void getcurtex() {
if(noedit(true)) return;
filltexlist();
int index = curtexindex < 0 ? 0 : curtexindex;
@@ -2109,16 +1785,14 @@ void getcurtex()
intret(texmru[index]);
}
-void getseltex()
-{
+void getseltex() {
if(noedit(true)) return;
cube &c = lookupcube(sel.o, -sel.grid);
if(c.children || isempty(c)) return;
intret(c.texture[sel.orient]);
}
-void gettexname(int *tex, int *subslot)
-{
+void gettexname(int *tex, int *subslot) {
if(noedit(true) || *tex<0) return;
VSlot &vslot = lookupvslot(*tex, false);
Slot &slot = *vslot.slot;
@@ -2126,8 +1800,7 @@ void gettexname(int *tex, int *subslot)
result(slot.sts[*subslot].name);
}
-void getslottex(int *idx)
-{
+void getslottex(int *idx) {
if(*idx < 0 || !slots.inrange(*idx)) { intret(-1); return; }
Slot &slot = lookupslot(*idx, false);
intret(slot.variants->index);
@@ -2144,28 +1817,23 @@ ICOMMAND(numslots, "", (), intret(slots.length()));
COMMAND(getslottex, "i");
ICOMMAND(texloaded, "i", (int *tex), intret(slots.inrange(*tex) && slots[*tex]->loaded ? 1 : 0));
-void replacetexcube(cube &c, int oldtex, int newtex)
-{
+void replacetexcube(cube &c, int oldtex, int newtex) {
loopi(6) if(c.texture[i] == oldtex) c.texture[i] = newtex;
if(c.children) loopi(8) replacetexcube(c.children[i], oldtex, newtex);
}
-void mpreplacetex(int oldtex, int newtex, bool insel, selinfo &sel, bool local)
-{
+void mpreplacetex(int oldtex, int newtex, bool insel, selinfo &sel, bool local) {
if(local) game::edittrigger(sel, EDIT_REPLACE, oldtex, newtex, insel ? 1 : 0);
- if(insel)
- {
+ if(insel) {
loopselxyz(replacetexcube(c, oldtex, newtex));
}
- else
- {
+ else {
loopi(8) replacetexcube(worldroot[i], oldtex, newtex);
}
allchanged();
}
-bool mpreplacetex(int oldtex, int newtex, bool insel, selinfo &sel, ucharbuf &buf)
-{
+bool mpreplacetex(int oldtex, int newtex, bool insel, selinfo &sel, ucharbuf &buf) {
if(!unpacktex(oldtex, buf, false)) return false;
editingvslot(oldtex);
if(!unpacktex(newtex, buf)) return false;
@@ -2173,8 +1841,7 @@ bool mpreplacetex(int oldtex, int newtex, bool insel, selinfo &sel, ucharbuf &bu
return true;
}
-void replace(bool insel)
-{
+void replace(bool insel) {
if(noedit()) return;
if(reptex < 0) { conoutf(CON_ERROR, "can only replace after a texture edit"); return; }
mpreplacetex(reptex, lasttex, insel, sel, true);
@@ -2189,37 +1856,30 @@ uint cflip(uint face) { return ((face&0xFF00FF00)>>8) | ((face&0x00FF00FF)<<8);
uint rflip(uint face) { return ((face&0xFFFF0000)>>16)| ((face&0x0000FFFF)<<16); }
uint mflip(uint face) { return (face&0xFF0000FF) | ((face&0x00FF0000)>>8) | ((face&0x0000FF00)<<8); }
-void flipcube(cube &c, int d)
-{
+void flipcube(cube &c, int d) {
swap(c.texture[d*2], c.texture[d*2+1]);
c.faces[D[d]] = dflip(c.faces[D[d]]);
c.faces[C[d]] = cflip(c.faces[C[d]]);
c.faces[R[d]] = rflip(c.faces[R[d]]);
- if(c.children)
- {
+ if(c.children) {
loopi(8) if(i&octadim(d)) swap(c.children[i], c.children[i-octadim(d)]);
loopi(8) flipcube(c.children[i], d);
}
}
-void rotatequad(cube &a, cube &b, cube &c, cube &d)
-{
+void rotatequad(cube &a, cube &b, cube &c, cube &d) {
cube t = a; a = b; b = c; c = d; d = t;
}
-void rotatecube(cube &c, int d) // rotates cube clockwise. see pics in cvs for help.
-{
+void rotatecube(cube &c, int d) { // rotates cube clockwise. see pics in cvs for help. {
c.faces[D[d]] = cflip (mflip(c.faces[D[d]]));
c.faces[C[d]] = dflip (mflip(c.faces[C[d]]));
c.faces[R[d]] = rflip (mflip(c.faces[R[d]]));
swap(c.faces[R[d]], c.faces[C[d]]);
-
swap(c.texture[2*R[d]], c.texture[2*C[d]+1]);
swap(c.texture[2*C[d]], c.texture[2*R[d]+1]);
swap(c.texture[2*C[d]], c.texture[2*C[d]+1]);
-
- if(c.children)
- {
+ if(c.children) {
int row = octadim(R[d]);
int col = octadim(C[d]);
for(int i=0; i<=octadim(d); i+=octadim(d)) rotatequad
@@ -2233,19 +1893,15 @@ void rotatecube(cube &c, int d) // rotates cube clockwise. see pics in cvs for
}
}
-void mpflip(selinfo &sel, bool local)
-{
- if(local)
- {
+void mpflip(selinfo &sel, bool local) {
+ if(local) {
game::edittrigger(sel, EDIT_FLIP);
makeundo();
}
int zs = sel.s[dimension(sel.orient)];
- loopxy(sel)
- {
+ loopxy(sel) {
loop(z,zs) flipcube(selcube(x, y, z), dimension(sel.orient));
- loop(z,zs/2)
- {
+ loop(z,zs/2) {
cube &a = selcube(x, y, z);
cube &b = selcube(x, y, zs-z-1);
swap(a, b);
@@ -2254,22 +1910,19 @@ void mpflip(selinfo &sel, bool local)
changed(sel);
}
-void flip()
-{
+void flip() {
if(noedit()) return;
mpflip(sel, true);
}
-void mprotate(int cw, selinfo &sel, bool local)
-{
+void mprotate(int cw, selinfo &sel, bool local) {
if(local) game::edittrigger(sel, EDIT_ROTATE, cw);
int d = dimension(sel.orient);
if(!dimcoord(sel.orient)) cw = -cw;
int m = sel.s[C[d]] < sel.s[R[d]] ? C[d] : R[d];
int ss = sel.s[m] = max(sel.s[R[d]], sel.s[C[d]]);
if(local) makeundo();
- loop(z,sel.s[D[d]]) loopi(cw>0 ? 1 : 3)
- {
+ loop(z,sel.s[D[d]]) loopi(cw>0 ? 1 : 3) {
loopxy(sel) rotatecube(selcube(x,y,z), d);
loop(y,ss/2) loop(x,ss-1-y*2) rotatequad
(
@@ -2282,8 +1935,7 @@ void mprotate(int cw, selinfo &sel, bool local)
changed(sel);
}
-void rotate(int *cw)
-{
+void rotate(int *cw) {
if(noedit()) return;
mprotate(*cw, sel, true);
}
@@ -2292,29 +1944,25 @@ COMMAND(flip, "");
COMMAND(rotate, "i");
enum { EDITMATF_EMPTY = 0x10000, EDITMATF_NOTEMPTY = 0x20000, EDITMATF_SOLID = 0x30000, EDITMATF_NOTSOLID = 0x40000 };
-static const struct { const char *name; int filter; } editmatfilters[] =
-{
- { "empty", EDITMATF_EMPTY },
- { "notempty", EDITMATF_NOTEMPTY },
- { "solid", EDITMATF_SOLID },
- { "notsolid", EDITMATF_NOTSOLID }
+static const struct { const char *name; int filter; } editmatfilters[] = {
+ {
+ "empty", EDITMATF_EMPTY }, {
+ "notempty", EDITMATF_NOTEMPTY }, {
+ "solid", EDITMATF_SOLID }, {
+ "notsolid", EDITMATF_NOTSOLID }
};
-void setmat(cube &c, ushort mat, ushort matmask, ushort filtermat, ushort filtermask, int filtergeom)
-{
+void setmat(cube &c, ushort mat, ushort matmask, ushort filtermat, ushort filtermask, int filtergeom) {
if(c.children)
loopi(8) setmat(c.children[i], mat, matmask, filtermat, filtermask, filtergeom);
- else if((c.material&filtermask) == filtermat)
- {
- switch(filtergeom)
- {
+ else if((c.material&filtermask) == filtermat) {
+ switch(filtergeom) {
case EDITMATF_EMPTY: if(isempty(c)) break; return;
case EDITMATF_NOTEMPTY: if(!isempty(c)) break; return;
case EDITMATF_SOLID: if(isentirelysolid(c)) break; return;
case EDITMATF_NOTSOLID: if(!isentirelysolid(c)) break; return;
}
- if(mat!=MAT_AIR)
- {
+ if(mat!=MAT_AIR) {
c.material &= matmask;
c.material |= mat;
}
@@ -2322,47 +1970,38 @@ void setmat(cube &c, ushort mat, ushort matmask, ushort filtermat, ushort filter
}
}
-void mpeditmat(int matid, int filter, selinfo &sel, bool local)
-{
+void mpeditmat(int matid, int filter, selinfo &sel, bool local) {
if(local) game::edittrigger(sel, EDIT_MAT, matid, filter);
-
ushort filtermat = 0, filtermask = 0, matmask;
int filtergeom = 0;
- if(filter >= 0)
- {
+ if(filter >= 0) {
filtermat = filter&0xFFFF;
filtermask = filtermat&(MATF_INDEX) ? (int) MATF_INDEX : (filtermat&MATF_CLIP ? (int) MATF_CLIP : (int) filtermat);
filtergeom = filter&~0xFFFF;
}
- if(matid < 0)
- {
+ if(matid < 0) {
matid = 0;
matmask = filtermask;
}
- else
- {
+ else {
matmask = matid&MATF_INDEX ? 0 : (matid&MATF_CLIP ? ~MATF_CLIP : ~matid);
}
loopselxyz(setmat(c, matid, matmask, filtermat, filtermask, filtergeom));
}
-void editmat(char *name, char *filtername)
-{
+void editmat(char *name, char *filtername) {
if(noedit()) return;
int filter = -1;
- if(filtername[0])
- {
+ if(filtername[0]) {
loopi(sizeof(editmatfilters)/sizeof(editmatfilters[0])) if(!strcmp(editmatfilters[i].name, filtername)) { filter = editmatfilters[i].filter; break; }
if(filter < 0) filter = findmaterial(filtername);
- if(filter < 0)
- {
+ if(filter < 0) {
conoutf(CON_ERROR, "unknown material \"%s\"", filtername);
return;
}
}
int id = -1;
- if(name[0] || filter < 0)
- {
+ if(name[0] || filter < 0) {
id = findmaterial(name);
if(id<0) { conoutf(CON_ERROR, "unknown material \"%s\"", name); return; }
}
@@ -2384,39 +2023,30 @@ static int lastthumbnail = 0;
VARP(texgui2d, 0, 1, 1);
VAR(texguinum, 1, -1, 0);
-struct texturegui : g3d_callback
-{
+struct texturegui : g3d_callback {
bool menuon;
vec menupos;
int menustart, menutab;
-
texturegui() : menustart(-1) {}
-
- void gui(g3d_gui &g, bool firstpass)
- {
+ void gui(g3d_gui &g, bool firstpass) {
int origtab = menutab, numtabs = max((slots.length() + texguiwidth*texguiheight - 1)/(texguiwidth*texguiheight), 1);
if(!firstpass) texguinum = -1;
g.start(menustart, 0.04f, &menutab);
bool oldautotab = g.allowautotab(false);
- loopi(numtabs)
- {
+ loopi(numtabs) {
g.tab(!i ? "Textures" : NULL, 0xFFDD88);
if(i+1 != origtab) continue; //don't load textures on non-visible tabs!
Slot *rollover = NULL;
- loop(h, texguiheight)
- {
+ loop(h, texguiheight) {
g.pushlist();
- loop(w, texguiwidth)
- {
+ loop(w, texguiwidth) {
extern VSlot dummyvslot;
int ti = (i*texguiheight+h)*texguiwidth+w;
- if(ti<slots.length())
- {
+ if(ti<slots.length()) {
Slot &slot = lookupslot(ti, false);
VSlot &vslot = *slot.variants;
if(slot.sts.empty()) continue;
- else if(!slot.loaded && !slot.thumbnail)
- {
+ else if(!slot.loaded && !slot.thumbnail) {
if(totalmillis-lastthumbnail<texguitime)
{
g.texture(dummyvslot, texguiscale, false); //create an empty space
@@ -2427,23 +2057,19 @@ struct texturegui : g3d_callback
}
int ret = g.texture(vslot, texguiscale, true);
if(ret&G3D_ROLLOVER) { rollover = &slot; texguinum = ti; }
- if(ret&G3D_UP && (slot.loaded || slot.thumbnail!=notexture))
- {
+ if(ret&G3D_UP && (slot.loaded || slot.thumbnail!=notexture)) {
edittex(vslot.index);
hudshader->set();
}
}
- else
- {
+ else {
g.texture(dummyvslot, texguiscale, false); //create an empty space
}
}
g.poplist();
}
- if(texguiname)
- {
- if(rollover)
- {
+ if(texguiname) {
+ if(rollover) {
defformatstring(name, "%d \f7:\fc %s", texguinum, rollover->sts[0].name);
g.title(name, 0xFFDD88);
}
@@ -2453,12 +2079,9 @@ struct texturegui : g3d_callback
g.allowautotab(oldautotab);
g.end();
}
-
- void showtextures(bool on)
- {
+ void showtextures(bool on) {
if(on == menuon) return;
- if((menuon = on))
- {
+ if((menuon = on)) {
if(menustart <= lasttexmillis)
menutab = 1+clamp(lookupvslot(lasttex, false).slot->index, 0, slots.length()-1)/(texguiwidth*texguiheight);
menupos = menuinfrontofplayer();
@@ -2466,9 +2089,7 @@ struct texturegui : g3d_callback
}
else texguinum = -1;
}
-
- void show()
- {
+ void show() {
if(!menuon) return;
filltexlist();
extern int usegui2d;
@@ -2477,13 +2098,11 @@ struct texturegui : g3d_callback
}
} gui;
-void g3d_texturemenu()
-{
+void g3d_texturemenu() {
gui.show();
}
-void showtexgui(int *n)
-{
+void showtexgui(int *n) {
if(!editmode) { conoutf(CON_ERROR, "operation only allowed in edit mode"); return; }
gui.showtextures(*n==0 ? !gui.menuon : *n==1);
}
@@ -2491,47 +2110,36 @@ void showtexgui(int *n)
// 0/noargs = toggle, 1 = on, other = off - will autoclose if too far away or exit editmode
COMMAND(showtexgui, "i");
-bool cleartexgui()
-{
+bool cleartexgui() {
if(!gui.menuon) return false;
gui.showtextures(false);
return true;
}
ICOMMAND(cleartexgui, "", (), intret(cleartexgui() ? 1 : 0));
-void rendertexturepanel(int w, int h)
-{
- if((texpaneltimer -= curtime)>0 && editmode)
- {
+void rendertexturepanel(int w, int h) {
+ if((texpaneltimer -= curtime)>0 && editmode) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
pushhudmatrix();
hudmatrix.scale(h/1800.0f, h/1800.0f, 1);
flushhudmatrix(false);
SETSHADER(hudrgb);
-
int y = 50, gap = 10;
-
gle::defvertex(2);
gle::deftexcoord0();
-
- loopi(7)
- {
+ loopi(7) {
int s = (i == 3 ? 285 : 220), ti = curtexindex+i-3;
- if(texmru.inrange(ti))
- {
- VSlot &vslot = lookupvslot(texmru[ti]), *layer = NULL;
+ if(texmru.inrange(ti)) {
+ VSlot &vslot = lookupvslot(texmru[ti]), *layer = NULL; (void) layer;
Slot &slot = *vslot.slot;
Texture *tex = slot.sts.empty() ? notexture : slot.sts[0].t;
- if(vslot.layer)
- {
+ if(vslot.layer) {
layer = &lookupvslot(vslot.layer);
}
float sx = min(1.0f, tex->xs/(float)tex->ys), sy = min(1.0f, tex->ys/(float)tex->xs);
vec2 tc[4] = { vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1) };
float xoff = vslot.offset.x, yoff = vslot.offset.y;
- if(vslot.rotation)
- {
+ if(vslot.rotation) {
const texrotation &r = texrotations[vslot.rotation];
if(r.swapxy) { swap(xoff, yoff); loopk(4) swap(tc[k].x, tc[k].y); }
if(r.flipx) { xoff *= -1; loopk(4) tc[k].x *= -1; }
@@ -2542,7 +2150,6 @@ void rendertexturepanel(int w, int h)
}
y += s+gap;
}
-
pophudmatrix(true, false);
hudshader->set();
}
diff --git a/src/engine/octarender.cpp b/src/engine/octarender.cpp
index 6b8a5b5..afbc7b2 100644
--- a/src/engine/octarender.cpp
+++ b/src/engine/octarender.cpp
@@ -2,8 +2,7 @@
#include "engine.h"
-struct vboinfo
-{
+struct vboinfo {
int uses;
};
@@ -12,8 +11,7 @@ hashtable<GLuint, vboinfo> vbos;
VAR(printvbo, 0, 0, 1);
VARFN(vbosize, maxvbosize, 0, 1<<14, 1<<16, allchanged());
-enum
-{
+enum {
VBO_VBUF = 0,
VBO_EBUF,
NUMVBO
@@ -23,41 +21,32 @@ static vector<uchar> vbodata[NUMVBO];
static vector<vtxarray *> vbovas[NUMVBO];
static int vbosize[NUMVBO];
-void destroyvbo(GLuint vbo)
-{
+void destroyvbo(GLuint vbo) {
vboinfo *exists = vbos.access(vbo);
if(!exists) return;
vboinfo &vbi = *exists;
if(vbi.uses <= 0) return;
vbi.uses--;
- if(!vbi.uses)
- {
+ if(!vbi.uses) {
glDeleteBuffers_(1, &vbo);
vbos.remove(vbo);
}
}
-void genvbo(int type, void *buf, int len, vtxarray **vas, int numva)
-{
+void genvbo(int type, void *buf, int len, vtxarray **vas, int numva) {
gle::disable();
-
GLuint vbo;
glGenBuffers_(1, &vbo);
GLenum target = type==VBO_VBUF ? GL_ARRAY_BUFFER : GL_ELEMENT_ARRAY_BUFFER;
glBindBuffer_(target, vbo);
glBufferData_(target, len, buf, GL_STATIC_DRAW);
glBindBuffer_(target, 0);
-
vboinfo &vbi = vbos[vbo];
vbi.uses = numva;
-
if(printvbo) conoutf(CON_DEBUG, "vbo %d: type %d, size %d, %d uses", vbo, type, len, numva);
-
- loopi(numva)
- {
+ loopi(numva) {
vtxarray *va = vas[i];
- switch(type)
- {
+ switch(type) {
case VBO_VBUF:
va->vbuf = vbo;
break;
@@ -68,31 +57,24 @@ void genvbo(int type, void *buf, int len, vtxarray **vas, int numva)
}
}
-bool readva(vtxarray *va, ushort *&edata, vertex *&vdata)
-{
+bool readva(vtxarray *va, ushort *&edata, vertex *&vdata) {
if(!va->vbuf || !va->ebuf) return false;
-
edata = new ushort[3*va->tris];
vdata = new vertex[va->verts];
-
gle::bindebo(va->ebuf);
glGetBufferSubData_(GL_ELEMENT_ARRAY_BUFFER, (size_t)va->edata, 3*va->tris*sizeof(ushort), edata);
gle::clearebo();
-
gle::bindvbo(va->vbuf);
glGetBufferSubData_(GL_ARRAY_BUFFER, va->voffset*sizeof(vertex), va->verts*sizeof(vertex), vdata);
gle::clearvbo();
return true;
}
-void flushvbo(int type = -1)
-{
- if(type < 0)
- {
+void flushvbo(int type = -1) {
+ if(type < 0) {
loopi(NUMVBO) flushvbo(i);
return;
}
-
vector<uchar> &data = vbodata[type];
if(data.empty()) return;
vector<vtxarray *> &vas = vbovas[type];
@@ -102,42 +84,31 @@ void flushvbo(int type = -1)
vbosize[type] = 0;
}
-uchar *addvbo(vtxarray *va, int type, int numelems, int elemsize)
-{
+uchar *addvbo(vtxarray *va, int type, int numelems, int elemsize) {
vbosize[type] += numelems;
-
vector<uchar> &data = vbodata[type];
vector<vtxarray *> &vas = vbovas[type];
-
vas.add(va);
-
int len = numelems*elemsize;
uchar *buf = data.reserve(len).buf;
data.advance(len);
return buf;
}
-struct verthash
-{
+struct verthash {
static const int SIZE = 1<<13;
int table[SIZE];
vector<vertex> verts;
vector<int> chain;
-
verthash() { clearverts(); }
-
- void clearverts()
- {
+ void clearverts() {
memset(table, -1, sizeof(table));
chain.setsize(0);
verts.setsize(0);
}
-
- int addvert(const vertex &v)
- {
+ int addvert(const vertex &v) {
uint h = hthash(v.pos)&(SIZE-1);
- for(int i = table[h]; i>=0; i = chain[i])
- {
+ for(int i = table[h]; i>=0; i = chain[i]) {
const vertex &c = verts[i];
if(c.pos==v.pos && c.tc==v.tc && c.norm==v.norm && c.tangent==v.tangent && (v.lm.iszero() || c.lm==v.lm))
return i;
@@ -147,9 +118,7 @@ struct verthash
chain.add(table[h]);
return table[h] = verts.length()-1;
}
-
- int addvert(const vec &pos, const vec2 &tc = vec2(0, 0), const svec2 &lm = svec2(0, 0), const bvec &norm = bvec(128, 128, 128), const bvec4 &tangent = bvec4(128, 128, 128, 128))
- {
+ int addvert(const vec &pos, const vec2 &tc = vec2(0, 0), const svec2 &lm = svec2(0, 0), const bvec &norm = bvec(128, 128, 128), const bvec4 &tangent = bvec4(128, 128, 128, 128)) {
vertex vtx;
vtx.pos = pos;
vtx.tc = tc;
@@ -160,46 +129,37 @@ struct verthash
}
};
-enum
-{
+enum {
NO_ALPHA = 0,
ALPHA_BACK,
ALPHA_FRONT
};
-struct sortkey
-{
+struct sortkey {
ushort tex, lmid;
uchar dim, layer, alpha;
-
sortkey() {}
sortkey(ushort tex, ushort lmid, uchar dim, uchar layer = LAYER_TOP, uchar alpha = NO_ALPHA)
: tex(tex), lmid(lmid), dim(dim), layer(layer), alpha(alpha)
{}
-
bool operator==(const sortkey &o) const { return tex==o.tex && lmid==o.lmid && dim==o.dim && layer==o.layer && alpha==o.alpha; }
};
-struct sortval
-{
+struct sortval {
int unlit;
vector<ushort> tris[2];
-
sortval() : unlit(0) {}
};
-static inline bool htcmp(const sortkey &x, const sortkey &y)
-{
+static inline bool htcmp(const sortkey &x, const sortkey &y) {
return x == y;
}
-static inline uint hthash(const sortkey &k)
-{
+static inline uint hthash(const sortkey &k) {
return k.tex + k.lmid*9741;
}
-struct vacollect : verthash
-{
+struct vacollect : verthash {
ivec origin;
int size;
hashtable<sortkey, sortval> indices;
@@ -207,9 +167,7 @@ struct vacollect : verthash
vector<materialsurface> matsurfs;
vector<octaentities *> mapmodels;
int worldtris;
-
- void clear()
- {
+ void clear() {
clearverts();
worldtris = 0;
indices.clear();
@@ -217,47 +175,38 @@ struct vacollect : verthash
mapmodels.setsize(0);
texs.setsize(0);
}
-
- void remapunlit(vector<sortkey> &remap)
- {
+ void remapunlit(vector<sortkey> &remap) {
uint lastlmid[8] = { LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT },
firstlmid[8] = { LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT };
int firstlit[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
- loopv(texs)
- {
+ loopv(texs) {
sortkey &k = texs[i];
- if(k.lmid>=LMID_RESERVED)
- {
+ if(k.lmid>=LMID_RESERVED) {
LightMapTexture &lmtex = lightmaptexs[k.lmid];
int type = lmtex.type&LM_TYPE;
if(k.layer==LAYER_BLEND) type += 2;
else if(k.alpha) type += 4 + 2*(k.alpha-1);
lastlmid[type] = lmtex.unlitx>=0 ? (int) k.lmid : (int) LMID_AMBIENT;
- if(firstlmid[type]==LMID_AMBIENT && lastlmid[type]!=LMID_AMBIENT)
- {
+ if(firstlmid[type]==LMID_AMBIENT && lastlmid[type]!=LMID_AMBIENT) {
firstlit[type] = i;
firstlmid[type] = lastlmid[type];
}
}
- else if(k.lmid==LMID_AMBIENT)
- {
+ else if(k.lmid==LMID_AMBIENT) {
Shader *s = lookupvslot(k.tex, false).slot->shader;
int type = s->type&SHADER_NORMALSLMS ? LM_BUMPMAP0 : LM_DIFFUSE;
if(k.layer==LAYER_BLEND) type += 2;
else if(k.alpha) type += 4 + 2*(k.alpha-1);
- if(lastlmid[type]!=LMID_AMBIENT)
- {
+ if(lastlmid[type]!=LMID_AMBIENT) {
sortval &t = indices[k];
if(t.unlit<=0) t.unlit = lastlmid[type];
}
}
}
- loopj(2)
- {
+ loopj(2) {
int offset = 2*j;
if(firstlmid[offset]==LMID_AMBIENT && firstlmid[offset+1]==LMID_AMBIENT) continue;
- loopi(max(firstlit[offset], firstlit[offset+1]))
- {
+ loopi(max(firstlit[offset], firstlit[offset+1])) {
sortkey &k = texs[i];
if((j ? k.layer!=LAYER_BLEND : k.layer==LAYER_BLEND) || k.alpha) continue;
if(k.lmid!=LMID_AMBIENT) continue;
@@ -267,12 +216,10 @@ struct vacollect : verthash
indices[k].unlit = firstlmid[type];
}
}
- loopj(2)
- {
+ loopj(2) {
int offset = 4 + 2*j;
if(firstlmid[offset]==LMID_AMBIENT && firstlmid[offset+1]==LMID_AMBIENT) continue;
- loopi(max(firstlit[offset], firstlit[offset+1]))
- {
+ loopi(max(firstlit[offset], firstlit[offset+1])) {
sortkey &k = texs[i];
if(k.alpha != j+1) continue;
if(k.lmid!=LMID_AMBIENT) continue;
@@ -282,20 +229,17 @@ struct vacollect : verthash
indices[k].unlit = firstlmid[type];
}
}
- loopv(remap)
- {
+ loopv(remap) {
sortkey &k = remap[i];
sortval &t = indices[k];
if(t.unlit<=0) continue;
LightMapTexture &lm = lightmaptexs[t.unlit];
svec2 lmtc(short(ceil((lm.unlitx + 0.5f) * SHRT_MAX/lm.w)),
short(ceil((lm.unlity + 0.5f) * SHRT_MAX/lm.h)));
- loopl(2) loopvj(t.tris[l])
- {
+ loopl(2) loopvj(t.tris[l]) {
vertex &vtx = verts[t.tris[l][j]];
if(vtx.lm.iszero()) vtx.lm = lmtc;
- else if(vtx.lm != lmtc)
- {
+ else if(vtx.lm != lmtc) {
vertex vtx2 = vtx;
vtx2.lm = lmtc;
t.tris[l][j] = addvert(vtx2);
@@ -305,26 +249,20 @@ struct vacollect : verthash
if(dst) loopl(2) loopvj(t.tris[l]) dst->tris[l].add(t.tris[l][j]);
}
}
-
- void optimize()
- {
+ void optimize() {
vector<sortkey> remap;
enumeratekt(indices, sortkey, k, sortval, t,
- loopl(2) if(t.tris[l].length() && t.unlit<=0)
- {
- if(k.lmid>=LMID_RESERVED && lightmaptexs[k.lmid].unlitx>=0)
- {
+ loopl(2) if(t.tris[l].length() && t.unlit<=0) {
+ if(k.lmid>=LMID_RESERVED && lightmaptexs[k.lmid].unlitx>=0) {
sortkey ukey(k.tex, LMID_AMBIENT, k.dim, k.layer, k.alpha);
sortval *uval = indices.access(ukey);
- if(uval && uval->unlit<=0)
- {
+ if(uval && uval->unlit<=0) {
if(uval->unlit<0) texs.removeobj(ukey);
else remap.add(ukey);
uval->unlit = k.lmid;
}
}
- else if(k.lmid==LMID_AMBIENT)
- {
+ else if(k.lmid==LMID_AMBIENT) {
remap.add(k);
t.unlit = -1;
}
@@ -333,20 +271,15 @@ struct vacollect : verthash
}
);
texs.sort(texsort);
-
remapunlit(remap);
-
matsurfs.shrink(optimizematsurfs(matsurfs.getbuf(), matsurfs.length()));
}
-
- static inline bool texsort(const sortkey &x, const sortkey &y)
- {
+ static inline bool texsort(const sortkey &x, const sortkey &y) {
if(x.alpha < y.alpha) return true;
if(x.alpha > y.alpha) return false;
if(x.layer < y.layer) return true;
if(x.layer > y.layer) return false;
- if(x.tex == y.tex)
- {
+ if(x.tex == y.tex) {
if(x.lmid < y.lmid) return true;
if(x.lmid > y.lmid) return false;
if(x.dim < y.dim) return true;
@@ -362,24 +295,20 @@ struct vacollect : verthash
else return false;
}
-#define GENVERTS(type, ptr, body) do \
- { \
+#define GENVERTS(type, ptr, body) do { \
+ \
type *f = (type *)ptr; \
- loopv(verts) \
- { \
+ loopv(verts) { \
+ \
const vertex &v = verts[i]; \
body; \
f++; \
} \
} while(0)
-
- void genverts(void *buf)
- {
+ void genverts(void *buf) {
GENVERTS(vertex, buf, { *f = v; f->norm.flip(); f->tangent.flip(); });
}
-
- void setupdata(vtxarray *va)
- {
+ void setupdata(vtxarray *va) {
va->verts = verts.length();
va->tris = worldtris/3;
va->vbuf = 0;
@@ -387,27 +316,22 @@ struct vacollect : verthash
va->minvert = 0;
va->maxvert = va->verts-1;
va->voffset = 0;
- if(va->verts)
- {
+ if(va->verts) {
if(vbosize[VBO_VBUF] + verts.length() > maxvbosize ||
vbosize[VBO_EBUF] + worldtris > USHRT_MAX)
flushvbo();
-
va->voffset = vbosize[VBO_VBUF];
uchar *vdata = addvbo(va, VBO_VBUF, va->verts, sizeof(vertex));
genverts(vdata);
va->minvert += va->voffset;
va->maxvert += va->voffset;
}
-
va->matbuf = NULL;
va->matsurfs = matsurfs.length();
- if(va->matsurfs)
- {
+ if(va->matsurfs) {
va->matbuf = new materialsurface[matsurfs.length()];
memcpy(va->matbuf, matsurfs.getbuf(), matsurfs.length()*sizeof(materialsurface));
}
-
va->eslist = NULL;
va->texs = texs.length();
va->blendtris = 0;
@@ -419,13 +343,11 @@ struct vacollect : verthash
va->ebuf = 0;
va->edata = 0;
va->texmask = 0;
- if(va->texs)
- {
+ if(va->texs) {
va->eslist = new elementset[va->texs];
va->edata += vbosize[VBO_EBUF];
ushort *edata = (ushort *)addvbo(va, VBO_EBUF, worldtris, sizeof(ushort)), *curbuf = edata;
- loopv(texs)
- {
+ loopv(texs) {
const sortkey &k = texs[i];
const sortval &t = indices[k];
elementset &e = va->eslist[i];
@@ -434,22 +356,16 @@ struct vacollect : verthash
e.dim = k.dim;
e.layer = k.layer;
ushort *startbuf = curbuf;
- loopl(2)
- {
+ loopl(2) {
e.minvert[l] = USHRT_MAX;
e.maxvert[l] = 0;
-
- if(t.tris[l].length())
- {
+ if(t.tris[l].length()) {
memcpy(curbuf, t.tris[l].getbuf(), t.tris[l].length() * sizeof(ushort));
-
- loopvj(t.tris[l])
- {
+ loopvj(t.tris[l]) {
curbuf[j] += va->voffset;
e.minvert[l] = min(e.minvert[l], curbuf[j]);
e.maxvert[l] = max(e.maxvert[l], curbuf[j]);
}
-
curbuf += t.tris[l].length();
}
e.length[l] = curbuf-startbuf;
@@ -457,19 +373,14 @@ struct vacollect : verthash
if(k.layer==LAYER_BLEND) { va->texs--; va->tris -= e.length[1]/3; va->blends++; va->blendtris += e.length[1]/3; }
else if(k.alpha==ALPHA_BACK) { va->texs--; va->tris -= e.length[1]/3; va->alphaback++; va->alphabacktris += e.length[1]/3; }
else if(k.alpha==ALPHA_FRONT) { va->texs--; va->tris -= e.length[1]/3; va->alphafront++; va->alphafronttris += e.length[1]/3; }
-
Slot &slot = *lookupvslot(k.tex, false).slot;
loopvj(slot.sts) va->texmask |= 1<<slot.sts[j].type;
}
}
-
va->alphatris = va->alphabacktris + va->alphafronttris;
-
if(mapmodels.length()) va->mapmodels.put(mapmodels.getbuf(), mapmodels.length());
}
-
- bool emptyva()
- {
+ bool emptyva() {
return verts.empty() && matsurfs.empty() && mapmodels.empty();
}
} vc;
@@ -481,24 +392,20 @@ vector<tjoint> tjoints;
vec shadowmapmin, shadowmapmax;
-int calcshadowmask(vec *pos, int numpos)
-{
+int calcshadowmask(vec *pos, int numpos) {
extern vec shadowdir;
int mask = 0, used = 1;
vec pe = vec(pos[1]).sub(pos[0]);
- loopk(numpos-2)
- {
+ loopk(numpos-2) {
vec e = vec(pos[k+2]).sub(pos[0]);
- if(vec().cross(pe, e).dot(shadowdir)>0)
- {
+ if(vec().cross(pe, e).dot(shadowdir)>0) {
mask |= 1<<k;
used |= 6<<k;
}
pe = e;
}
if(!mask) return 0;
- loopk(numpos) if(used&(1<<k))
- {
+ loopk(numpos) if(used&(1<<k)) {
const vec &v = pos[k];
shadowmapmin.min(v);
shadowmapmax.max(v);
@@ -508,14 +415,11 @@ int calcshadowmask(vec *pos, int numpos)
VARFP(filltjoints, 0, 1, 1, allchanged());
-void reduceslope(ivec &n)
-{
+void reduceslope(ivec &n) {
int mindim = -1, minval = 64;
- loopi(3) if(n[i])
- {
+ loopi(3) if(n[i]) {
int val = abs(n[i]);
- if(mindim < 0 || val < minval)
- {
+ if(mindim < 0 || val < minval) {
mindim = i;
minval = val;
}
@@ -525,49 +429,44 @@ void reduceslope(ivec &n)
}
// [rotation][dimension]
-extern const vec orientation_tangent[8][3] =
-{
- { vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) },
- { vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) },
- { vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) },
- { vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) },
- { vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) },
- { vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) },
- { vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) },
- { vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) },
+extern const vec orientation_tangent[8][3] = {
+ {
+ vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) }, {
+ vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) }, {
+ vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) }, {
+ vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) }, {
+ vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) }, {
+ vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) }, {
+ vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) }, {
+ vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) },
};
-extern const vec orientation_bitangent[8][3] =
-{
- { vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) },
- { vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) },
- { vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) },
- { vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) },
- { vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) },
- { vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) },
- { vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) },
- { vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) },
+extern const vec orientation_bitangent[8][3] = {
+ {
+ vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) }, {
+ vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) }, {
+ vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) }, {
+ vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) }, {
+ vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) }, {
+ vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) }, {
+ vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) }, {
+ vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) },
};
-void addtris(const sortkey &key, int orient, vertex *verts, int *index, int numverts, int convex, int shadowmask, int tj)
-{
+void addtris(const sortkey &key, int orient, vertex *verts, int *index, int numverts, int convex, int shadowmask, int tj) {
int &total = vc.worldtris;
int edge = orient*(MAXFACEVERTS+1);
- loopi(numverts-2) if(index[0]!=index[i+1] && index[i+1]!=index[i+2] && index[i+2]!=index[0])
- {
+ loopi(numverts-2) if(index[0]!=index[i+1] && index[i+1]!=index[i+2] && index[i+2]!=index[0]) {
vector<ushort> &idxs = vc.indices[key].tris[(shadowmask>>i)&1];
int left = index[0], mid = index[i+1], right = index[i+2], start = left, i0 = left, i1 = -1;
- loopk(4)
- {
+ loopk(4) {
int i2 = -1, ctj = -1, cedge = -1;
- switch(k)
- {
+ switch(k) {
case 1: i1 = i2 = mid; cedge = edge+i+1; break;
case 2: if(i1 != mid || i0 == left) { i0 = i1; i1 = right; } i2 = right; if(i+1 == numverts-2) cedge = edge+i+2; break;
case 3: if(i0 == start) { i0 = i1; i1 = left; } i2 = left; // fall-through
default: if(!i) cedge = edge; break;
}
- if(i1 != i2)
- {
+ if(i1 != i2) {
if(total + 3 > USHRT_MAX) return;
total += 3;
idxs.add(i0);
@@ -575,18 +474,15 @@ void addtris(const sortkey &key, int orient, vertex *verts, int *index, int numv
idxs.add(i2);
i1 = i2;
}
- if(cedge >= 0)
- {
- for(ctj = tj;;)
- {
+ if(cedge >= 0) {
+ for(ctj = tj;;) {
if(ctj < 0) break;
if(tjoints[ctj].edge < cedge) { ctj = tjoints[ctj].next; continue; }
if(tjoints[ctj].edge != cedge) ctj = -1;
break;
}
}
- if(ctj >= 0)
- {
+ if(ctj >= 0) {
int e1 = cedge%(MAXFACEVERTS+1), e2 = (e1+1)%numverts;
vertex &v1 = verts[e1], &v2 = verts[e2];
ivec d(vec(v2.pos).sub(v1.pos).mul(8));
@@ -598,15 +494,12 @@ void addtris(const sortkey &key, int orient, vertex *verts, int *index, int numv
offset2 = (int(v2.pos[axis]*8) - origin) / d[axis];
vec o = vec(v1.pos).sub(vec(d).mul(offset1/8.0f));
float doffset = 1.0f / (offset2 - offset1);
-
- if(i1 < 0) for(;;)
- {
+ if(i1 < 0) for(;;) {
tjoint &t = tjoints[ctj];
if(t.next < 0 || tjoints[t.next].edge != cedge) break;
ctj = t.next;
}
- while(ctj >= 0)
- {
+ while(ctj >= 0) {
tjoint &t = tjoints[ctj];
if(t.edge != cedge) break;
float offset = (t.offset - offset1) * doffset;
@@ -619,8 +512,7 @@ void addtris(const sortkey &key, int orient, vertex *verts, int *index, int numv
vt.tangent.lerp(v1.tangent, v2.tangent, offset);
int i2 = vc.addvert(vt);
if(i2 < 0) return;
- if(i1 >= 0)
- {
+ if(i1 >= 0) {
if(total + 3 > USHRT_MAX) return;
total += 3;
idxs.add(i0);
@@ -636,8 +528,7 @@ void addtris(const sortkey &key, int orient, vertex *verts, int *index, int numv
}
}
-static inline void calctexgen(VSlot &vslot, int dim, vec4 &sgen, vec4 &tgen)
-{
+static inline void calctexgen(VSlot &vslot, int dim, vec4 &sgen, vec4 &tgen) {
Texture *tex = vslot.slot->sts.empty() ? notexture : vslot.slot->sts[0].t;
const texrotation &r = texrotations[vslot.rotation];
float k = TEX_SCALE/vslot.scale,
@@ -650,53 +541,45 @@ static inline void calctexgen(VSlot &vslot, int dim, vec4 &sgen, vec4 &tgen)
int sdim = si[dim], tdim = ti[dim];
sgen = vec4(0, 0, 0, soff);
tgen = vec4(0, 0, 0, toff);
- if(r.swapxy)
- {
+ if(r.swapxy) {
sgen[tdim] = (dim <= 1 ? -sk : sk);
tgen[sdim] = tk;
}
- else
- {
+ else {
sgen[sdim] = sk;
tgen[tdim] = (dim <= 1 ? -tk : tk);
}
}
-ushort encodenormal(const vec &n)
-{
+ushort encodenormal(const vec &n) {
if(n.iszero()) return 0;
int yaw = int(-atan2(n.x, n.y)/RAD), pitch = int(asin(n.z)/RAD);
return ushort(clamp(pitch + 90, 0, 180)*360 + (yaw < 0 ? yaw%360 + 360 : yaw%360) + 1);
}
-vec decodenormal(ushort norm)
-{
+vec decodenormal(ushort norm) {
if(!norm) return vec(0, 0, 1);
norm--;
const vec2 &yaw = sincos360[norm%360], &pitch = sincos360[norm/360+270];
return vec(-yaw.y*pitch.x, yaw.x*pitch.x, pitch.y);
}
-void guessnormals(const vec *pos, int numverts, vec *normals)
-{
+void guessnormals(const vec *pos, int numverts, vec *normals) {
vec n1, n2;
n1.cross(pos[0], pos[1], pos[2]);
- if(numverts != 4)
- {
+ if(numverts != 4) {
n1.normalize();
loopk(numverts) normals[k] = n1;
return;
}
n2.cross(pos[0], pos[2], pos[3]);
- if(n1.iszero())
- {
+ if(n1.iszero()) {
n2.normalize();
loopk(4) normals[k] = n2;
return;
}
else n1.normalize();
- if(n2.iszero())
- {
+ if(n2.iszero()) {
loopk(4) normals[k] = n1;
return;
}
@@ -708,16 +591,13 @@ void guessnormals(const vec *pos, int numverts, vec *normals)
normals[3] = n2;
}
-void addcubeverts(VSlot &vslot, int orient, int size, vec *pos, int convex, ushort texture, ushort lmid, vertinfo *vinfo, int numverts, int tj = -1, int grassy = 0, bool alpha = false, int layer = LAYER_TOP)
-{
+void addcubeverts(VSlot &vslot, int orient, int size, vec *pos, int convex, ushort texture, ushort lmid, vertinfo *vinfo, int numverts, int tj = -1, int grassy = 0, bool alpha = false, int layer = LAYER_TOP) {
(void) grassy;
int dim = dimension(orient);
int shadowmask = alpha ? 0 : calcshadowmask(pos, numverts);
-
LightMap *lm = NULL;
LightMapTexture *lmtex = NULL;
- if(lightmaps.inrange(lmid-LMID_RESERVED))
- {
+ if(lightmaps.inrange(lmid-LMID_RESERVED)) {
lm = &lightmaps[lmid-LMID_RESERVED];
if((lm->type&LM_TYPE)==LM_DIFFUSE ||
((lm->type&LM_TYPE)==LM_BUMPMAP0 &&
@@ -726,70 +606,58 @@ void addcubeverts(VSlot &vslot, int orient, int size, vec *pos, int convex, usho
lmtex = &lightmaptexs[lm->tex];
else lm = NULL;
}
-
vec4 sgen, tgen;
calctexgen(vslot, dim, sgen, tgen);
vertex verts[MAXFACEVERTS];
int index[MAXFACEVERTS];
- loopk(numverts)
- {
+ loopk(numverts) {
vertex &v = verts[k];
v.pos = pos[k];
v.tc = vec2(sgen.dot(v.pos), tgen.dot(v.pos));
- if(lmtex)
- {
+ if(lmtex) {
v.lm = svec2(short(ceil((lm->offsetx + vinfo[k].u*(float(LM_PACKW)/float(USHRT_MAX+1)) + 0.5f) * float(SHRT_MAX)/lmtex->w)),
short(ceil((lm->offsety + vinfo[k].v*(float(LM_PACKH)/float(USHRT_MAX+1)) + 0.5f) * float(SHRT_MAX)/lmtex->h)));
}
else v.lm = svec2(0, 0);
- if(vinfo && vinfo[k].norm)
- {
+ if(vinfo && vinfo[k].norm) {
vec n = decodenormal(vinfo[k].norm), t = orientation_tangent[vslot.rotation][dim];
t.project(n).normalize();
v.norm = bvec(n);
v.tangent = bvec4(bvec(t), orientation_bitangent[vslot.rotation][dim].scalartriple(n, t) < 0 ? 0 : 255);
}
- else
- {
+ else {
v.norm = bvec(128, 128, 255);
v.tangent = bvec4(255, 128, 128, 255);
}
index[k] = vc.addvert(v);
if(index[k] < 0) return;
}
-
if(lmid >= LMID_RESERVED) lmid = lm ? lm->tex : LMID_AMBIENT;
-
sortkey key(texture, lmid, !vslot.scroll.iszero() ? dim : 3, layer == LAYER_BLEND ? LAYER_BLEND : LAYER_TOP, alpha ? (vslot.alphaback ? ALPHA_BACK : (vslot.alphafront ? ALPHA_FRONT : NO_ALPHA)) : NO_ALPHA);
addtris(key, orient, verts, index, numverts, convex, shadowmask, tj);
}
-struct edgegroup
-{
+struct edgegroup {
ivec slope, origin;
int axis;
};
-static uint hthash(const edgegroup &g)
-{
+static uint hthash(const edgegroup &g) {
return g.slope.x^(g.slope.y<<2)^(g.slope.z<<4)^g.origin.x^g.origin.y^g.origin.z;
}
-static bool htcmp(const edgegroup &x, const edgegroup &y)
-{
+static bool htcmp(const edgegroup &x, const edgegroup &y) {
return x.slope==y.slope && x.origin==y.origin;
}
-enum
-{
+enum {
CE_START = 1<<0,
CE_END = 1<<1,
CE_FLIP = 1<<2,
CE_DUP = 1<<3
};
-struct cubeedge
-{
+struct cubeedge {
cube *c;
int next, offset;
ushort size;
@@ -799,26 +667,21 @@ struct cubeedge
vector<cubeedge> cubeedges;
hashtable<edgegroup, int> edgegroups(1<<13);
-void gencubeedges(cube &c, const ivec &co, int size)
-{
+void gencubeedges(cube &c, const ivec &co, int size) {
ivec pos[MAXFACEVERTS];
int vis;
- loopi(6) if((vis = visibletris(c, i, co, size)))
- {
+ loopi(6) if((vis = visibletris(c, i, co, size))) {
int numverts = c.ext ? c.ext->surfaces[i].numverts&MAXFACEVERTS : 0;
- if(numverts)
- {
+ if(numverts) {
vertinfo *verts = c.ext->verts() + c.ext->surfaces[i].verts;
ivec vo = ivec(co).mask(~0xFFF).shl(3);
- loopj(numverts)
- {
+ loopj(numverts) {
vertinfo &v = verts[j];
pos[j] = ivec(v.x, v.y, v.z).add(vo);
}
}
else if(c.merged&(1<<i)) continue;
- else
- {
+ else {
ivec v[4];
genfaceverts(c, i, v);
int order = vis&4 || (!flataxisface(c, i) && faceconvexity(v) < 0) ? 1 : 0;
@@ -828,20 +691,17 @@ void gencubeedges(cube &c, const ivec &co, int size)
pos[numverts++] = v[order+2].mul(size).add(vo);
if(vis&2) pos[numverts++] = v[(order+3)&3].mul(size).add(vo);
}
- loopj(numverts)
- {
+ loopj(numverts) {
int e1 = j, e2 = j+1 < numverts ? j+1 : 0;
ivec d = pos[e2];
d.sub(pos[e1]);
if(d.iszero()) continue;
int axis = abs(d.x) > abs(d.y) ? (abs(d.x) > abs(d.z) ? 0 : 2) : (abs(d.y) > abs(d.z) ? 1 : 2);
- if(d[axis] < 0)
- {
+ if(d[axis] < 0) {
d.neg();
swap(e1, e2);
}
reduceslope(d);
-
int t1 = pos[e1][axis]/d[axis],
t2 = pos[e2][axis]/d[axis];
edgegroup g;
@@ -855,22 +715,17 @@ void gencubeedges(cube &c, const ivec &co, int size)
ce.index = i*(MAXFACEVERTS+1)+j;
ce.flags = CE_START | CE_END | (e1!=j ? CE_FLIP : 0);
ce.next = -1;
-
bool insert = true;
int *exists = edgegroups.access(g);
- if(exists)
- {
+ if(exists) {
int prev = -1, cur = *exists;
- while(cur >= 0)
- {
+ while(cur >= 0) {
cubeedge &p = cubeedges[cur];
- if(ce.offset <= p.offset+p.size)
- {
+ if(ce.offset <= p.offset+p.size) {
if(ce.offset < p.offset) break;
if(p.flags&CE_DUP ?
ce.offset+ce.size <= p.offset+p.size :
- ce.offset==p.offset && ce.size==p.size)
- {
+ ce.offset==p.offset && ce.size==p.size) {
p.flags |= CE_DUP;
insert = false;
break;
@@ -880,11 +735,9 @@ void gencubeedges(cube &c, const ivec &co, int size)
prev = cur;
cur = p.next;
}
- if(insert)
- {
+ if(insert) {
ce.next = cur;
- while(cur >= 0)
- {
+ while(cur >= 0) {
cubeedge &p = cubeedges[cur];
if(ce.offset+ce.size==p.offset) { ce.flags &= ~CE_END; break; }
cur = p.next;
@@ -894,18 +747,15 @@ void gencubeedges(cube &c, const ivec &co, int size)
}
}
else edgegroups[g] = cubeedges.length();
-
if(insert) cubeedges.add(ce);
}
}
}
-void gencubeedges(cube *c = worldroot, const ivec &co = ivec(0, 0, 0), int size = worldsize>>1)
-{
+void gencubeedges(cube *c = worldroot, const ivec &co = ivec(0, 0, 0), int size = worldsize>>1) {
progress("fixing t-joints...");
neighbourstack[++neighbourdepth] = c;
- loopi(8)
- {
+ loopi(8) {
ivec o(i, co, size);
if(c[i].ext) c[i].ext->tjoints = -1;
if(c[i].children) gencubeedges(c[i].children, o, size>>1);
@@ -914,29 +764,23 @@ void gencubeedges(cube *c = worldroot, const ivec &co = ivec(0, 0, 0), int size
--neighbourdepth;
}
-void gencubeverts(cube &c, const ivec &co, int size, int csi)
-{
+void gencubeverts(cube &c, const ivec &co, int size, int csi) {
if(!(c.visible&0xC0)) return;
-
int vismask = ~c.merged & 0x3F;
if(!(c.visible&0x80)) vismask &= c.visible;
if(!vismask) return;
-
int tj = filltjoints && c.ext ? c.ext->tjoints : -1, vis;
- loopi(6) if(vismask&(1<<i) && (vis = visibletris(c, i, co, size)))
- {
+ loopi(6) if(vismask&(1<<i) && (vis = visibletris(c, i, co, size))) {
vec pos[MAXFACEVERTS];
vertinfo *verts = NULL;
int numverts = c.ext ? c.ext->surfaces[i].numverts&MAXFACEVERTS : 0, convex = 0;
- if(numverts)
- {
+ if(numverts) {
verts = c.ext->verts() + c.ext->surfaces[i].verts;
vec vo(ivec(co).mask(~0xFFF));
loopj(numverts) pos[j] = vec(verts[j].getxyz()).mul(1.0f/8).add(vo);
if(!flataxisface(c, i)) convex = faceconvexity(verts, numverts, size);
}
- else
- {
+ else {
ivec v[4];
genfaceverts(c, i, v);
if(!flataxisface(c, i)) convex = faceconvexity(v);
@@ -947,15 +791,13 @@ void gencubeverts(cube &c, const ivec &co, int size, int csi)
pos[numverts++] = vec(v[order+2]).mul(size/8.0f).add(vo);
if(vis&2) pos[numverts++] = vec(v[(order+3)&3]).mul(size/8.0f).add(vo);
}
-
VSlot &vslot = lookupvslot(c.texture[i], true),
*layer = vslot.layer && !(c.material&MAT_ALPHA) ? &lookupvslot(vslot.layer, true) : NULL;
while(tj >= 0 && tjoints[tj].edge < i*(MAXFACEVERTS+1)) tj = tjoints[tj].next;
int hastj = tj >= 0 && tjoints[tj].edge < (i+1)*(MAXFACEVERTS+1) ? tj : -1;
if(!c.ext)
addcubeverts(vslot, i, size, pos, convex, c.texture[i], LMID_AMBIENT, NULL, numverts, hastj, 0, (c.material&MAT_ALPHA)!=0);
- else
- {
+ else {
const surfaceinfo &surf = c.ext->surfaces[i];
if(!surf.numverts || surf.numverts&LAYER_TOP)
addcubeverts(vslot, i, size, pos, convex, c.texture[i], surf.lmid[0], verts, numverts, hastj, 0, (c.material&MAT_ALPHA)!=0, LAYER_TOP|(surf.numverts&LAYER_BLEND));
@@ -971,10 +813,8 @@ int allocva = 0;
int wtris = 0, wverts = 0, vtris = 0, vverts = 0, glde = 0, gbatches = 0;
vector<vtxarray *> valist, varoot;
-vtxarray *newva(const ivec &co, int size)
-{
+vtxarray *newva(const ivec &co, int size) {
vc.optimize();
-
vtxarray *va = new vtxarray;
va->parent = NULL;
va->o = co;
@@ -986,29 +826,23 @@ vtxarray *newva(const ivec &co, int size)
va->bbmax = ivec(-1, -1, -1);
va->hasmerges = 0;
va->mergelevel = -1;
-
vc.setupdata(va);
-
wverts += va->verts;
wtris += va->tris + va->blends + va->alphatris;
allocva++;
valist.add(va);
-
return va;
}
-void destroyva(vtxarray *va, bool reparent)
-{
+void destroyva(vtxarray *va, bool reparent) {
wverts -= va->verts;
wtris -= va->tris + va->blends + va->alphatris;
allocva--;
valist.removeobj(va);
if(!va->parent) varoot.removeobj(va);
- if(reparent)
- {
+ if(reparent) {
if(va->parent) va->parent->children.removeobj(va);
- loopv(va->children)
- {
+ loopv(va->children) {
vtxarray *child = va->children[i];
child->parent = va->parent;
if(child->parent) child->parent->children.add(child);
@@ -1021,12 +855,9 @@ void destroyva(vtxarray *va, bool reparent)
delete va;
}
-void clearvas(cube *c)
-{
- loopi(8)
- {
- if(c[i].ext)
- {
+void clearvas(cube *c) {
+ loopi(8) {
+ if(c[i].ext) {
if(c[i].ext->va) destroyva(c[i].ext->va, false);
c[i].ext->va = NULL;
c[i].ext->tjoints = -1;
@@ -1035,23 +866,19 @@ void clearvas(cube *c)
}
}
-void updatevabb(vtxarray *va, bool force)
-{
+void updatevabb(vtxarray *va, bool force) {
if(!force && va->bbmin.x >= 0) return;
-
va->bbmin = va->geommin;
va->bbmax = va->geommax;
va->bbmin.min(va->matmin);
va->bbmax.max(va->matmax);
- loopv(va->children)
- {
+ loopv(va->children) {
vtxarray *child = va->children[i];
updatevabb(child, force);
va->bbmin.min(child->bbmin);
va->bbmax.max(child->bbmax);
}
- loopv(va->mapmodels)
- {
+ loopv(va->mapmodels) {
octaentities *oe = va->mapmodels[i];
va->bbmin.min(oe->bbmin);
va->bbmax.max(oe->bbmax);
@@ -1060,13 +887,11 @@ void updatevabb(vtxarray *va, bool force)
va->bbmax.min(ivec(va->o).add(va->size));
}
-void updatevabbs(bool force)
-{
+void updatevabbs(bool force) {
loopv(varoot) updatevabb(varoot[i], force);
}
-struct mergedface
-{
+struct mergedface {
uchar orient, lmid, numverts;
ushort mat, tex;
vertinfo *verts;
@@ -1077,16 +902,13 @@ struct mergedface
static int vahasmerges = 0, vamergemax = 0;
static vector<mergedface> vamerges[MAXMERGELEVEL+1];
-int genmergedfaces(cube &c, const ivec &co, int size, int minlevel = -1)
-{
+int genmergedfaces(cube &c, const ivec &co, int size, int minlevel = -1) {
if(!c.ext || isempty(c)) return -1;
int tj = c.ext->tjoints, maxlevel = -1;
- loopi(6) if(c.merged&(1<<i))
- {
+ loopi(6) if(c.merged&(1<<i)) {
surfaceinfo &surf = c.ext->surfaces[i];
int numverts = surf.numverts&MAXFACEVERTS;
- if(!numverts)
- {
+ if(!numverts) {
if(minlevel < 0) vahasmerges |= MERGE_PART;
continue;
}
@@ -1099,18 +921,13 @@ int genmergedfaces(cube &c, const ivec &co, int size, int minlevel = -1)
mf.verts = c.ext->verts() + surf.verts;
mf.tjoints = -1;
int level = calcmergedsize(i, co, size, mf.verts, mf.numverts&MAXFACEVERTS);
- if(level > minlevel)
- {
+ if(level > minlevel) {
maxlevel = max(maxlevel, level);
-
while(tj >= 0 && tjoints[tj].edge < i*(MAXFACEVERTS+1)) tj = tjoints[tj].next;
if(tj >= 0 && tjoints[tj].edge < (i+1)*(MAXFACEVERTS+1)) mf.tjoints = tj;
-
VSlot &vslot = lookupvslot(mf.tex, true);
-
if(surf.numverts&LAYER_TOP) vamerges[level].add(mf);
- if(surf.numverts&LAYER_BOTTOM)
- {
+ if(surf.numverts&LAYER_BOTTOM) {
mf.tex = vslot.layer;
mf.lmid = surf.lmid[1];
mf.numverts &= ~LAYER_TOP;
@@ -1119,22 +936,18 @@ int genmergedfaces(cube &c, const ivec &co, int size, int minlevel = -1)
}
}
}
- if(maxlevel >= 0)
- {
+ if(maxlevel >= 0) {
vamergemax = max(vamergemax, maxlevel);
vahasmerges |= MERGE_ORIGIN;
}
return maxlevel;
}
-int findmergedfaces(cube &c, const ivec &co, int size, int csi, int minlevel)
-{
+int findmergedfaces(cube &c, const ivec &co, int size, int csi, int minlevel) {
if(c.ext && c.ext->va && !(c.ext->va->hasmerges&MERGE_ORIGIN)) return c.ext->va->mergelevel;
- else if(c.children)
- {
+ else if(c.children) {
int maxlevel = -1;
- loopi(8)
- {
+ loopi(8) {
ivec o(i, co, size/2);
int level = findmergedfaces(c.children[i], o, size/2, csi-1, minlevel);
maxlevel = max(maxlevel, level);
@@ -1145,18 +958,15 @@ int findmergedfaces(cube &c, const ivec &co, int size, int csi, int minlevel)
else return -1;
}
-void addmergedverts(int level, const ivec &o)
-{
+void addmergedverts(int level, const ivec &o) {
vector<mergedface> &mfl = vamerges[level];
if(mfl.empty()) return;
vec vo(ivec(o).mask(~0xFFF));
vec pos[MAXFACEVERTS];
- loopv(mfl)
- {
+ loopv(mfl) {
mergedface &mf = mfl[i];
int numverts = mf.numverts&MAXFACEVERTS;
- loopi(numverts)
- {
+ loopi(numverts) {
vertinfo &v = mf.verts[i];
pos[i] = vec(v.x, v.y, v.z).mul(1.0f/8).add(vo);
}
@@ -1167,21 +977,16 @@ void addmergedverts(int level, const ivec &o)
mfl.setsize(0);
}
-void rendercube(cube &c, const ivec &co, int size, int csi, int &maxlevel) // creates vertices and indices ready to be put into a va
-{
+void rendercube(cube &c, const ivec &co, int size, int csi, int &maxlevel) { // creates vertices and indices ready to be put into a va {
//if(size<=16) return;
- if(c.ext && c.ext->va)
- {
+ if(c.ext && c.ext->va) {
maxlevel = max(maxlevel, c.ext->va->mergelevel);
return; // don't re-render
}
-
- if(c.children)
- {
+ if(c.children) {
neighbourstack[++neighbourdepth] = c.children;
c.escaped = 0;
- loopi(8)
- {
+ loopi(8) {
ivec o(i, co, size/2);
int level = -1;
rendercube(c.children[i], o, size/2, csi-1, level);
@@ -1190,91 +995,65 @@ void rendercube(cube &c, const ivec &co, int size, int csi, int &maxlevel) // c
maxlevel = max(maxlevel, level);
}
--neighbourdepth;
-
if(csi <= MAXMERGELEVEL && vamerges[csi].length()) addmergedverts(csi, co);
-
- if(c.ext)
- {
+ if(c.ext) {
if(c.ext->ents && c.ext->ents->mapmodels.length()) vc.mapmodels.add(c.ext->ents);
}
return;
}
-
- if(!isempty(c))
- {
+ if(!isempty(c)) {
gencubeverts(c, co, size, csi);
if(c.merged) maxlevel = max(maxlevel, genmergedfaces(c, co, size));
}
if(c.material != MAT_AIR) genmatsurfs(c, co, size, vc.matsurfs);
-
- if(c.ext)
- {
+ if(c.ext) {
if(c.ext->ents && c.ext->ents->mapmodels.length()) vc.mapmodels.add(c.ext->ents);
}
-
if(csi <= MAXMERGELEVEL && vamerges[csi].length()) addmergedverts(csi, co);
}
-void calcgeombb(const ivec &co, int size, ivec &bbmin, ivec &bbmax)
-{
+void calcgeombb(const ivec &co, int size, ivec &bbmin, ivec &bbmax) {
vec vmin(co), vmax = vmin;
vmin.add(size);
-
- loopv(vc.verts)
- {
+ loopv(vc.verts) {
const vec &v = vc.verts[i].pos;
vmin.min(v);
vmax.max(v);
}
-
bbmin = ivec(vmin.mul(8)).shr(3);
bbmax = ivec(vmax.mul(8)).add(7).shr(3);
}
-void calcmatbb(const ivec &co, int size, ivec &bbmin, ivec &bbmax)
-{
+void calcmatbb(const ivec &co, int size, ivec &bbmin, ivec &bbmax) {
bbmax = co;
(bbmin = bbmax).add(size);
- loopv(vc.matsurfs)
- {
+ loopv(vc.matsurfs) {
materialsurface &m = vc.matsurfs[i];
-
int dim = dimension(m.orient),
r = R[dim],
c = C[dim];
bbmin[dim] = min(bbmin[dim], m.o[dim]);
bbmax[dim] = max(bbmax[dim], m.o[dim]);
-
bbmin[r] = min(bbmin[r], m.o[r]);
bbmax[r] = max(bbmax[r], m.o[r] + m.rsize);
-
bbmin[c] = min(bbmin[c], m.o[c]);
bbmax[c] = max(bbmax[c], m.o[c] + m.csize);
}
}
-void setva(cube &c, const ivec &co, int size, int csi)
-{
+void setva(cube &c, const ivec &co, int size, int csi) {
ASSERT(size <= 0x1000);
-
int vamergeoffset[MAXMERGELEVEL+1];
loopi(MAXMERGELEVEL+1) vamergeoffset[i] = vamerges[i].length();
-
vc.origin = co;
vc.size = size;
-
shadowmapmin = vec(co).add(size);
shadowmapmax = vec(co);
-
int maxlevel = -1;
rendercube(c, co, size, csi, maxlevel);
-
ivec bbmin, bbmax;
-
calcgeombb(co, size, bbmin, bbmax);
-
- if(size == min(0x1000, worldsize/2) || !vc.emptyva())
- {
+ if(size == min(0x1000, worldsize/2) || !vc.emptyva()) {
vtxarray *va = newva(co, size);
ext(c).va = va;
va->geommin = bbmin;
@@ -1285,29 +1064,22 @@ void setva(cube &c, const ivec &co, int size, int csi)
va->hasmerges = vahasmerges;
va->mergelevel = vamergemax;
}
- else
- {
+ else {
loopi(MAXMERGELEVEL+1) vamerges[i].setsize(vamergeoffset[i]);
}
-
vc.clear();
}
-static inline int setcubevisibility(cube &c, const ivec &co, int size)
-{
+static inline int setcubevisibility(cube &c, const ivec &co, int size) {
int numvis = 0, vismask = 0, collidemask = 0, checkmask = 0;
- loopi(6)
- {
+ loopi(6) {
int facemask = classifyface(c, i, co, size);
- if(facemask&1)
- {
+ if(facemask&1) {
vismask |= 1<<i;
- if(c.merged&(1<<i))
- {
+ if(c.merged&(1<<i)) {
if(c.ext && c.ext->surfaces[i].numverts&MAXFACEVERTS) numvis++;
}
- else
- {
+ else {
numvis++;
if(!(c.ext && c.ext->surfaces[i].numverts&MAXFACEVERTS)) checkmask |= 1<<i;
}
@@ -1322,45 +1094,36 @@ VARF(vafacemax, 64, 384, 256*256, allchanged());
VARF(vafacemin, 0, 96, 256*256, allchanged());
VARF(vacubesize, 32, 128, 0x1000, allchanged());
-int updateva(cube *c, const ivec &co, int size, int csi)
-{
+int updateva(cube *c, const ivec &co, int size, int csi) {
progress("recalculating geometry...");
int ccount = 0, cmergemax = vamergemax, chasmerges = vahasmerges;
neighbourstack[++neighbourdepth] = c;
- loopi(8) // counting number of semi-solid/solid children cubes
- {
+ loopi(8) { // counting number of semi-solid/solid children cubes {
int count = 0, childpos = varoot.length();
ivec o(i, co, size);
vamergemax = 0;
vahasmerges = 0;
- if(c[i].ext && c[i].ext->va)
- {
+ if(c[i].ext && c[i].ext->va) {
varoot.add(c[i].ext->va);
if(c[i].ext->va->hasmerges&MERGE_ORIGIN) findmergedfaces(c[i], o, size, csi, csi);
}
- else
- {
+ else {
if(c[i].children) count += updateva(c[i].children, o, size/2, csi-1);
- else
- {
+ else {
if(!isempty(c[i])) count += setcubevisibility(c[i], o, size);
}
int tcount = count + (csi <= MAXMERGELEVEL ? vamerges[csi].length() : 0);
- if(tcount > vafacemax || (tcount >= vafacemin && size >= vacubesize) || size == min(0x1000, worldsize/2))
- {
+ if(tcount > vafacemax || (tcount >= vafacemin && size >= vacubesize) || size == min(0x1000, worldsize/2)) {
loadprogress = clamp(recalcprogress/float(allocnodes), 0.0f, 1.0f);
setva(c[i], o, size, csi);
- if(c[i].ext && c[i].ext->va)
- {
- while(varoot.length() > childpos)
- {
+ if(c[i].ext && c[i].ext->va) {
+ while(varoot.length() > childpos) {
vtxarray *child = varoot.pop();
c[i].ext->va->children.add(child);
child->parent = c[i].ext->va;
}
varoot.add(c[i].ext->va);
- if(vamergemax > size)
- {
+ if(vamergemax > size) {
cmergemax = max(cmergemax, vamergemax);
chasmerges |= vahasmerges&~MERGE_USE;
}
@@ -1377,58 +1140,46 @@ int updateva(cube *c, const ivec &co, int size, int csi)
--neighbourdepth;
vamergemax = cmergemax;
vahasmerges = chasmerges;
-
return ccount;
}
-void addtjoint(const edgegroup &g, const cubeedge &e, int offset)
-{
+void addtjoint(const edgegroup &g, const cubeedge &e, int offset) {
int vcoord = (g.slope[g.axis]*offset + g.origin[g.axis]) & 0x7FFF;
tjoint &tj = tjoints.add();
tj.offset = vcoord / g.slope[g.axis];
tj.edge = e.index;
-
int prev = -1, cur = ext(*e.c).tjoints;
- while(cur >= 0)
- {
+ while(cur >= 0) {
tjoint &o = tjoints[cur];
if(tj.edge < o.edge || (tj.edge==o.edge && (e.flags&CE_FLIP ? tj.offset > o.offset : tj.offset < o.offset))) break;
prev = cur;
cur = o.next;
}
-
tj.next = cur;
if(prev < 0) e.c->ext->tjoints = tjoints.length()-1;
else tjoints[prev].next = tjoints.length()-1;
}
-void findtjoints(int cur, const edgegroup &g)
-{
+void findtjoints(int cur, const edgegroup &g) {
int active = -1;
- while(cur >= 0)
- {
+ while(cur >= 0) {
cubeedge &e = cubeedges[cur];
int prevactive = -1, curactive = active;
- while(curactive >= 0)
- {
+ while(curactive >= 0) {
cubeedge &a = cubeedges[curactive];
- if(a.offset+a.size <= e.offset)
- {
+ if(a.offset+a.size <= e.offset) {
if(prevactive >= 0) cubeedges[prevactive].next = a.next;
else active = a.next;
}
- else
- {
+ else {
prevactive = curactive;
- if(!(a.flags&CE_DUP))
- {
+ if(!(a.flags&CE_DUP)) {
if(e.flags&CE_START && e.offset > a.offset && e.offset < a.offset+a.size)
addtjoint(g, a, e.offset);
if(e.flags&CE_END && e.offset+e.size > a.offset && e.offset+e.size < a.offset+a.size)
addtjoint(g, a, e.offset+e.size);
}
- if(!(e.flags&CE_DUP))
- {
+ if(!(e.flags&CE_DUP)) {
if(a.flags&CE_START && a.offset > e.offset && a.offset < e.offset+e.size)
addtjoint(g, e, a.offset);
if(a.flags&CE_END && a.offset+a.size > e.offset && a.offset+a.size < e.offset+e.size)
@@ -1444,8 +1195,7 @@ void findtjoints(int cur, const edgegroup &g)
}
}
-void findtjoints()
-{
+void findtjoints() {
recalcprogress = 0;
gencubeedges();
tjoints.setsize(0);
@@ -1454,38 +1204,31 @@ void findtjoints()
edgegroups.clear();
}
-void octarender() // creates va s for all leaf cubes that don't already have them
-{
+void octarender() { // creates va s for all leaf cubes that don't already have them {
int csi = 0;
while(1<<csi < worldsize) csi++;
-
recalcprogress = 0;
varoot.setsize(0);
updateva(worldroot, ivec(0, 0, 0), worldsize/2, csi-1);
loadprogress = 0;
flushvbo();
-
visibleva = NULL;
}
-void precachetextures()
-{
+void precachetextures() {
vector<int> texs;
- loopv(valist)
- {
+ loopv(valist) {
vtxarray *va = valist[i];
loopj(va->texs + va->blends) if(texs.find(va->eslist[j].texture) < 0) texs.add(va->eslist[j].texture);
}
- loopv(texs)
- {
+ loopv(texs) {
loadprogress = float(i+1)/texs.length();
lookupvslot(texs[i]);
}
loadprogress = 0;
}
-void allchanged(bool load)
-{
+void allchanged(bool load) {
renderprogress(0, "clearing vertex arrays...");
clearvas(worldroot);
resetqueries();
@@ -1499,15 +1242,13 @@ void allchanged(bool load)
setupmaterials();
updatevabbs(true);
lightents();
- if(load)
- {
+ if(load) {
seedparticles();
drawtextures();
}
}
-void recalc()
-{
+void recalc() {
allchanged(true);
}
diff --git a/src/engine/physics.cpp b/src/engine/physics.cpp
index b1b800a..a43e8b4 100644
--- a/src/engine/physics.cpp
+++ b/src/engine/physics.cpp
@@ -10,11 +10,9 @@ const int MAXCLIPPLANES = 1024;
static clipplanes clipcache[MAXCLIPPLANES];
static int clipcacheversion = -2;
-static inline clipplanes &getclipplanes(const cube &c, const ivec &o, int size, bool collide = true, int offset = 0)
-{
+static inline clipplanes &getclipplanes(const cube &c, const ivec &o, int size, bool collide = true, int offset = 0) {
clipplanes &p = clipcache[int(&c - worldroot)&(MAXCLIPPLANES-1)];
- if(p.owner != &c || p.version != clipcacheversion+offset)
- {
+ if(p.owner != &c || p.version != clipcacheversion+offset) {
p.owner = &c;
p.version = clipcacheversion+offset;
genclipplanes(c, o, size, p, collide);
@@ -22,11 +20,9 @@ static inline clipplanes &getclipplanes(const cube &c, const ivec &o, int size,
return p;
}
-void resetclipplanes()
-{
+void resetclipplanes() {
clipcacheversion += 2;
- if(!clipcacheversion)
- {
+ if(!clipcacheversion) {
memclear(clipcache);
clipcacheversion = 2;
}
@@ -36,24 +32,24 @@ void resetclipplanes()
#define INTERSECTPLANES(setentry, exit) \
float enterdist = -1e16f, exitdist = 1e16f; \
- loopi(p.size) \
- { \
+ loopi(p.size) { \
+ \
float pdist = p.p[i].dist(v), facing = ray.dot(p.p[i]); \
- if(facing < 0) \
- { \
+ if(facing < 0) { \
+ \
pdist /= -facing; \
- if(pdist > enterdist) \
- { \
+ if(pdist > enterdist) { \
+ \
if(pdist > exitdist) exit; \
enterdist = pdist; \
setentry; \
} \
} \
- else if(facing > 0) \
- { \
+ else if(facing > 0) { \
+ \
pdist /= -facing; \
- if(pdist < exitdist) \
- { \
+ if(pdist < exitdist) { \
+ \
if(pdist < enterdist) exit; \
exitdist = pdist; \
} \
@@ -62,19 +58,19 @@ void resetclipplanes()
}
#define INTERSECTBOX(setentry, exit) \
- loop(i, 3) \
- { \
- if(ray[i]) \
- { \
+ loop(i, 3) { \
+ \
+ if(ray[i]) { \
+ \
float prad = fabs(p.r[i] * invray[i]), pdist = (p.o[i] - v[i]) * invray[i], pmin = pdist - prad, pmax = pdist + prad; \
- if(pmin > enterdist) \
- { \
+ if(pmin > enterdist) { \
+ \
if(pmin > exitdist) exit; \
enterdist = pmin; \
setentry; \
} \
- if(pmax < exitdist) \
- { \
+ if(pmax < exitdist) { \
+ \
if(pmax < enterdist) exit; \
exitdist = pmax; \
} \
@@ -84,8 +80,7 @@ void resetclipplanes()
vec hitsurface;
-static inline bool raycubeintersect(const clipplanes &p, const cube &c, const vec &v, const vec &ray, const vec &invray, float &dist)
-{
+static inline bool raycubeintersect(const clipplanes &p, const cube &c, const vec &v, const vec &ray, const vec &invray, float &dist) {
int entry = -1, bbentry = -1;
INTERSECTPLANES(entry = i, return false);
INTERSECTBOX(bbentry = i, return false);
@@ -100,59 +95,50 @@ extern void entselectionbox(const entity &e, vec &eo, vec &es);
float hitentdist;
int hitent, hitorient;
-static float disttoent(octaentities *oc, const vec &o, const vec &ray, float radius, int mode, extentity *t)
-{
+static float disttoent(octaentities *oc, const vec &o, const vec &ray, float radius, int mode, extentity *t) {
vec eo, es;
int orient = -1;
float dist = radius, f = 0.0f;
const vector<extentity *> &ents = entities::getents();
-
#define entintersect(mask, type, func) {\
- if((mode&(mask))==(mask)) loopv(oc->type) \
- { \
+ if((mode&(mask))==(mask)) loopv(oc->type) { \
+ \
extentity &e = *ents[oc->type[i]]; \
if(!(e.flags&EF_OCTA) || &e==t) continue; \
func; \
- if(f<dist && f>0 && vec(ray).mul(f).add(o).insidebb(oc->o, oc->size)) \
- { \
+ if(f<dist && f>0 && vec(ray).mul(f).add(o).insidebb(oc->o, oc->size)) { \
+ \
hitentdist = dist = f; \
hitent = oc->type[i]; \
hitorient = orient; \
} \
} \
}
-
entintersect(RAY_POLY, mapmodels,
if(!mmintersect(e, o, ray, radius, mode, f)) continue;
);
-
entintersect(RAY_ENTS, other,
entselectionbox(e, eo, es);
if(!rayboxintersect(eo, es, o, ray, f, orient)) continue;
);
-
entintersect(RAY_ENTS, mapmodels,
entselectionbox(e, eo, es);
if(!rayboxintersect(eo, es, o, ray, f, orient)) continue;
);
-
return dist;
}
-static float disttooutsideent(const vec &o, const vec &ray, float radius, int mode, extentity *t)
-{
+static float disttooutsideent(const vec &o, const vec &ray, float radius, int mode, extentity *t) {
vec eo, es;
int orient;
float dist = radius, f = 0.0f;
const vector<extentity *> &ents = entities::getents();
- loopv(outsideents)
- {
+ loopv(outsideents) {
extentity &e = *ents[outsideents[i]];
if(!(e.flags&EF_OCTA) || &e==t) continue;
entselectionbox(e, eo, es);
if(!rayboxintersect(eo, es, o, ray, f, orient)) continue;
- if(f<dist && f>0)
- {
+ if(f<dist && f>0) {
hitentdist = dist = f;
hitent = outsideents[i];
hitorient = orient;
@@ -162,12 +148,10 @@ static float disttooutsideent(const vec &o, const vec &ray, float radius, int mo
}
// optimized shadow version
-static float shadowent(octaentities *oc, const vec &o, const vec &ray, float radius, int mode, extentity *t)
-{
+static float shadowent(octaentities *oc, const vec &o, const vec &ray, float radius, int mode, extentity *t) {
float dist = radius, f = 0.0f;
const vector<extentity *> &ents = entities::getents();
- loopv(oc->mapmodels)
- {
+ loopv(oc->mapmodels) {
extentity &e = *ents[oc->mapmodels[i]];
if(!(e.flags&EF_OCTA) || &e==t) continue;
if(!mmintersect(e, o, ray, radius, mode, f)) continue;
@@ -185,14 +169,14 @@ static float shadowent(octaentities *oc, const vec &o, const vec &ray, float rad
ivec lsizemask(invray.x>0 ? 1 : 0, invray.y>0 ? 1 : 0, invray.z>0 ? 1 : 0); \
#define CHECKINSIDEWORLD \
- if(!insideworld(o)) \
- { \
+ if(!insideworld(o)) { \
+ \
float disttoworld = 0, exitworld = 1e16f; \
- loopi(3) \
- { \
+ loopi(3) { \
+ \
float c = v[i]; \
- if(c<0 || c>=worldsize) \
- { \
+ if(c<0 || c>=worldsize) { \
+ \
float d = ((invray[i]>0?0:worldsize)-c)*invray[i]; \
if(d<0) return (radius>0?radius:-1); \
disttoworld = max(disttoworld, 0.1f + d); \
@@ -207,15 +191,15 @@ static float shadowent(octaentities *oc, const vec &o, const vec &ray, float rad
#define DOWNOCTREE(disttoent, earlyexit) \
cube *lc = levels[lshift]; \
- for(;;) \
- { \
+ for(;;) { \
+ \
lshift--; \
lc += octastep(x, y, z, lshift); \
- if(lc->ext && lc->ext->ents && lshift < elvl) \
- { \
+ if(lc->ext && lc->ext->ents && lshift < elvl) { \
+ \
float edist = disttoent(lc->ext->ents, o, ray, dent, mode, t); \
- if(edist < dent) \
- { \
+ if(edist < dent) { \
+ \
earlyexit return min(edist, dist); \
elvl = lshift; \
dent = min(dent, edist); \
@@ -246,103 +230,76 @@ static float shadowent(octaentities *oc, const vec &o, const vec &ray, float rad
if(diff >= uint(worldsize)) exitworld; \
diff >>= lshift; \
if(!diff) exitworld; \
- do \
- { \
+ do { \
+ \
lshift++; \
diff >>= 1; \
} while(diff);
-float raycube(const vec &o, const vec &ray, float radius, int mode, int size, extentity *t)
-{
+float raycube(const vec &o, const vec &ray, float radius, int mode, int size, extentity *t) {
if(ray.iszero()) return 0;
-
INITRAYCUBE;
CHECKINSIDEWORLD;
-
int closest = -1, x = int(v.x), y = int(v.y), z = int(v.z);
- for(;;)
- {
+ for(;;) {
DOWNOCTREE(disttoent, if(mode&RAY_SHADOW));
-
int lsize = 1<<lshift;
-
cube &c = *lc;
if((dist>0 || !(mode&RAY_SKIPFIRST)) &&
(((mode&RAY_EDITMAT) && c.material != MAT_AIR) ||
(!(mode&RAY_PASS) && lsize==size && !isempty(c)) ||
isentirelysolid(c) ||
- dent < dist))
- {
+ dent < dist)) {
if(closest >= 0) { hitsurface = vec(0, 0, 0); hitsurface[closest] = ray[closest]>0 ? -1 : 1; }
return min(dent, dist);
}
-
ivec lo(x&(~0U<<lshift), y&(~0U<<lshift), z&(~0U<<lshift));
-
- if(!isempty(c))
- {
+ if(!isempty(c)) {
const clipplanes &p = getclipplanes(c, lo, lsize, false, 1);
float f = 0;
if(raycubeintersect(p, c, v, ray, invray, f) && (dist+f>0 || !(mode&RAY_SKIPFIRST)))
return min(dent, dist+f);
}
-
FINDCLOSEST(closest = 0, closest = 1, closest = 2);
-
if(radius>0 && dist>=radius) return min(dent, dist);
-
UPOCTREE(return min(dent, radius>0 ? radius : dist));
}
}
// optimized version for lightmap shadowing... every cycle here counts!!!
-float shadowray(const vec &o, const vec &ray, float radius, int mode, extentity *t)
-{
+float shadowray(const vec &o, const vec &ray, float radius, int mode, extentity *t) {
INITRAYCUBE;
CHECKINSIDEWORLD;
-
- int side = O_BOTTOM, x = int(v.x), y = int(v.y), z = int(v.z);
- for(;;)
- {
+ int side = O_BOTTOM, x = int(v.x), y = int(v.y), z = int(v.z); (void) side;
+ for(;;) {
DOWNOCTREE(shadowent, );
-
cube &c = *lc;
ivec lo(x&(~0U<<lshift), y&(~0U<<lshift), z&(~0U<<lshift));
-
- if(!isempty(c) && !(c.material&MAT_ALPHA))
- {
- if(isentirelysolid(c))
- {
+ if(!isempty(c) && !(c.material&MAT_ALPHA)) {
+ if(isentirelysolid(c)) {
return dist;
}
- else
- {
+ else {
const clipplanes &p = getclipplanes(c, lo, 1<<lshift, false, 1);
INTERSECTPLANES(side = p.side[i], goto nextcube);
INTERSECTBOX(side = (i<<1) + 1 - lsizemask[i], goto nextcube);
- if(exitdist >= 0)
- {
+ if(exitdist >= 0) {
return dist+max(enterdist+0.1f, 0.0f);
}
}
}
-
nextcube:
FINDCLOSEST(side = O_RIGHT - lsizemask.x, side = O_FRONT - lsizemask.y, side = O_TOP - lsizemask.z);
-
if(dist>=radius) return dist;
-
UPOCTREE(return radius);
}
}
// thread safe version
-struct ShadowRayCache
-{
+struct ShadowRayCache {
clipplanes clipcache[MAXCLIPPLANES];
int version;
-
ShadowRayCache() : version(-1) {}
};
@@ -350,65 +307,49 @@ ShadowRayCache *newshadowraycache() { return new ShadowRayCache; }
void freeshadowraycache(ShadowRayCache *&cache) { delete cache; cache = NULL; }
-void resetshadowraycache(ShadowRayCache *cache)
-{
+void resetshadowraycache(ShadowRayCache *cache) {
cache->version++;
- if(!cache->version)
- {
+ if(!cache->version) {
memclear(cache->clipcache);
cache->version = 1;
}
}
-float shadowray(ShadowRayCache *cache, const vec &o, const vec &ray, float radius, int mode, extentity *t)
-{
+float shadowray(ShadowRayCache *cache, const vec &o, const vec &ray, float radius, int mode, extentity *t) {
INITRAYCUBE;
CHECKINSIDEWORLD;
-
- int side = O_BOTTOM, x = int(v.x), y = int(v.y), z = int(v.z);
- for(;;)
- {
+ int side = O_BOTTOM, x = int(v.x), y = int(v.y), z = int(v.z); (void) side;
+ for(;;) {
DOWNOCTREE(shadowent, );
-
cube &c = *lc;
ivec lo(x&(~0U<<lshift), y&(~0U<<lshift), z&(~0U<<lshift));
-
- if(!isempty(c) && !(c.material&MAT_ALPHA))
- {
- if(isentirelysolid(c))
- {
+ if(!isempty(c) && !(c.material&MAT_ALPHA)) {
+ if(isentirelysolid(c)) {
return dist;
}
- else
- {
+ else {
clipplanes &p = cache->clipcache[int(&c - worldroot)&(MAXCLIPPLANES-1)];
if(p.owner != &c || p.version != cache->version) { p.owner = &c; p.version = cache->version; genclipplanes(c, lo, 1<<lshift, p, false); }
INTERSECTPLANES(side = p.side[i], goto nextcube);
INTERSECTBOX(side = (i<<1) + 1 - lsizemask[i], goto nextcube);
- if(exitdist >= 0)
- {
+ if(exitdist >= 0) {
return dist+max(enterdist+0.1f, 0.0f);
}
}
}
-
nextcube:
FINDCLOSEST(side = O_RIGHT - lsizemask.x, side = O_FRONT - lsizemask.y, side = O_TOP - lsizemask.z);
-
if(dist>=radius) return dist;
-
UPOCTREE(return radius);
}
}
-float rayent(const vec &o, const vec &ray, float radius, int mode, int size, int &orient, int &ent)
-{
+float rayent(const vec &o, const vec &ray, float radius, int mode, int size, int &orient, int &ent) {
hitent = -1;
hitentdist = radius;
hitorient = -1;
float dist = raycube(o, ray, radius, mode, size);
- if((mode&RAY_ENTS) == RAY_ENTS)
- {
+ if((mode&RAY_ENTS) == RAY_ENTS) {
float dent = disttooutsideent(o, ray, dist < 0 ? 1e16f : dist, mode, NULL);
if(dent < 1e15f && (dist < 0 || dent < dist)) dist = dent;
}
@@ -417,8 +358,7 @@ float rayent(const vec &o, const vec &ray, float radius, int mode, int size, int
return dist;
}
-float raycubepos(const vec &o, const vec &ray, vec &hitpos, float radius, int mode, int size)
-{
+float raycubepos(const vec &o, const vec &ray, vec &hitpos, float radius, int mode, int size) {
hitpos = ray;
float dist = raycube(o, ray, radius, mode, size);
if(radius>0 && dist>=radius) dist = radius;
@@ -426,8 +366,7 @@ float raycubepos(const vec &o, const vec &ray, vec &hitpos, float radius, int mo
return dist;
}
-bool raycubelos(const vec &o, const vec &dest, vec &hitpos)
-{
+bool raycubelos(const vec &o, const vec &dest, vec &hitpos) {
vec ray(dest);
ray.sub(o);
float mag = ray.magnitude();
@@ -436,8 +375,7 @@ bool raycubelos(const vec &o, const vec &dest, vec &hitpos)
return distance >= mag;
}
-float rayfloor(const vec &o, vec &floor, int mode, float radius)
-{
+float rayfloor(const vec &o, vec &floor, int mode, float radius) {
if(o.z<=0) return -1;
hitsurface = vec(0, 0, 1);
float dist = raycube(o, vec(0, 0, -1), radius, mode);
@@ -460,53 +398,42 @@ const float WALLZ = 0.2f;
extern const float JUMPVEL = 125.0f;
extern const float GRAVITY = 200.0f;
-bool ellipseboxcollide(physent *d, const vec &dir, const vec &o, const vec &center, float yaw, float xr, float yr, float hi, float lo)
-{
+bool ellipseboxcollide(physent *d, const vec &dir, const vec &o, const vec &center, float yaw, float xr, float yr, float hi, float lo) {
float below = (o.z+center.z-lo) - (d->o.z+d->aboveeye),
above = (d->o.z-d->eyeheight) - (o.z+center.z+hi);
if(below>=0 || above>=0) return false;
-
vec yo(d->o);
yo.sub(o);
yo.rotate_around_z(-yaw*RAD);
yo.sub(center);
-
float dx = clamp(yo.x, -xr, xr) - yo.x, dy = clamp(yo.y, -yr, yr) - yo.y,
dist = sqrtf(dx*dx + dy*dy) - d->radius;
- if(dist < 0)
- {
+ if(dist < 0) {
int sx = yo.x <= -xr ? -1 : (yo.x >= xr ? 1 : 0),
sy = yo.y <= -yr ? -1 : (yo.y >= yr ? 1 : 0);
- if(dist > (yo.z < 0 ? below : above) && (sx || sy))
- {
+ if(dist > (yo.z < 0 ? below : above) && (sx || sy)) {
vec ydir(dir);
ydir.rotate_around_z(-yaw*RAD);
- if(sx*yo.x - xr > sy*yo.y - yr)
- {
- if(dir.iszero() || sx*ydir.x < -1e-6f)
- {
+ if(sx*yo.x - xr > sy*yo.y - yr) {
+ if(dir.iszero() || sx*ydir.x < -1e-6f) {
collidewall = vec(sx, 0, 0);
collidewall.rotate_around_z(yaw*RAD);
return true;
}
}
- else if(dir.iszero() || sy*ydir.y < -1e-6f)
- {
+ else if(dir.iszero() || sy*ydir.y < -1e-6f) {
collidewall = vec(0, sy, 0);
collidewall.rotate_around_z(yaw*RAD);
return true;
}
}
- if(yo.z < 0)
- {
- if(dir.iszero() || (dir.z > 0 && (d->type>=ENT_INANIMATE || below >= d->zmargin-(d->eyeheight+d->aboveeye)/4.0f)))
- {
+ if(yo.z < 0) {
+ if(dir.iszero() || (dir.z > 0 && (d->type>=ENT_INANIMATE || below >= d->zmargin-(d->eyeheight+d->aboveeye)/4.0f))) {
collidewall = vec(0, 0, -1);
return true;
}
}
- else if(dir.iszero() || (dir.z < 0 && (d->type>=ENT_INANIMATE || above >= d->zmargin-(d->eyeheight+d->aboveeye)/3.0f)))
- {
+ else if(dir.iszero() || (dir.z < 0 && (d->type>=ENT_INANIMATE || above >= d->zmargin-(d->eyeheight+d->aboveeye)/3.0f))) {
collidewall = vec(0, 0, 1);
return true;
}
@@ -515,8 +442,7 @@ bool ellipseboxcollide(physent *d, const vec &dir, const vec &o, const vec &cent
return false;
}
-bool ellipsecollide(physent *d, const vec &dir, const vec &o, const vec &center, float yaw, float xr, float yr, float hi, float lo)
-{
+bool ellipsecollide(physent *d, const vec &dir, const vec &o, const vec &center, float yaw, float xr, float yr, float hi, float lo) {
float below = (o.z+center.z-lo) - (d->o.z+d->aboveeye),
above = (d->o.z-d->eyeheight) - (o.z+center.z+hi);
if(below>=0 || above>=0) return false;
@@ -528,24 +454,19 @@ bool ellipsecollide(physent *d, const vec &dir, const vec &o, const vec &center,
float dx = d->xradius*cosf(dangle), dy = d->yradius*sinf(dangle);
float ex = xr*cosf(eangle), ey = yr*sinf(eangle);
float dist = sqrtf(x*x + y*y) - sqrtf(dx*dx + dy*dy) - sqrtf(ex*ex + ey*ey);
- if(dist < 0)
- {
- if(dist > (d->o.z < yo.z ? below : above) && (dir.iszero() || x*dir.x + y*dir.y > 0))
- {
+ if(dist < 0) {
+ if(dist > (d->o.z < yo.z ? below : above) && (dir.iszero() || x*dir.x + y*dir.y > 0)) {
collidewall = vec(-x, -y, 0);
if(!collidewall.iszero()) collidewall.normalize();
return true;
}
- if(d->o.z < yo.z)
- {
- if(dir.iszero() || (dir.z > 0 && (d->type>=ENT_INANIMATE || below >= d->zmargin-(d->eyeheight+d->aboveeye)/4.0f)))
- {
+ if(d->o.z < yo.z) {
+ if(dir.iszero() || (dir.z > 0 && (d->type>=ENT_INANIMATE || below >= d->zmargin-(d->eyeheight+d->aboveeye)/4.0f))) {
collidewall = vec(0, 0, -1);
return true;
}
}
- else if(dir.iszero() || (dir.z < 0 && (d->type>=ENT_INANIMATE || above >= d->zmargin-(d->eyeheight+d->aboveeye)/3.0f)))
- {
+ else if(dir.iszero() || (dir.z < 0 && (d->type>=ENT_INANIMATE || above >= d->zmargin-(d->eyeheight+d->aboveeye)/3.0f))) {
collidewall = vec(0, 0, 1);
return true;
}
@@ -558,15 +479,13 @@ bool ellipsecollide(physent *d, const vec &dir, const vec &o, const vec &center,
static uint dynentframe = 0;
-static struct dynentcacheentry
-{
+static struct dynentcacheentry {
int x, y;
uint frame;
vector<physent *> dynents;
} dynentcache[DYNENTCACHESIZE];
-void cleardynentcache()
-{
+void cleardynentcache() {
dynentframe++;
if(!dynentframe || dynentframe == 1) loopi(DYNENTCACHESIZE) dynentcache[i].frame = 0;
if(!dynentframe) dynentframe = 1;
@@ -576,8 +495,7 @@ VARF(dynentsize, 4, 7, 12, cleardynentcache());
#define DYNENTHASH(x, y) (((((x)^(y))<<5) + (((x)^(y))>>5)) & (DYNENTCACHESIZE - 1))
-const vector<physent *> &checkdynentcache(int x, int y)
-{
+const vector<physent *> &checkdynentcache(int x, int y) {
dynentcacheentry &dec = dynentcache[DYNENTHASH(x, y)];
if(dec.x == x && dec.y == y && dec.frame == dynentframe) return dec.dynents;
dec.x = x;
@@ -585,8 +503,7 @@ const vector<physent *> &checkdynentcache(int x, int y)
dec.frame = dynentframe;
dec.dynents.shrink(0);
int numdyns = game::numdynents(), dsize = 1<<dynentsize, dx = x<<dynentsize, dy = y<<dynentsize;
- loopi(numdyns)
- {
+ loopi(numdyns) {
dynent *d = game::iterdynents(i);
if(d->state != CS_ALIVE ||
d->o.x+d->radius <= dx || d->o.x-d->radius >= dx+dsize ||
@@ -601,23 +518,18 @@ const vector<physent *> &checkdynentcache(int x, int y)
for(int curx = max(int(o.x-radius), 0)>>dynentsize, endx = min(int(o.x+radius), worldsize-1)>>dynentsize; curx <= endx; curx++) \
for(int cury = max(int(o.y-radius), 0)>>dynentsize, endy = min(int(o.y+radius), worldsize-1)>>dynentsize; cury <= endy; cury++)
-void updatedynentcache(physent *d)
-{
- loopdynentcache(x, y, d->o, d->radius)
- {
+void updatedynentcache(physent *d) {
+ loopdynentcache(x, y, d->o, d->radius) {
dynentcacheentry &dec = dynentcache[DYNENTHASH(x, y)];
if(dec.x != x || dec.y != y || dec.frame != dynentframe || dec.dynents.find(d) >= 0) continue;
dec.dynents.add(d);
}
}
-bool overlapsdynent(const vec &o, float radius)
-{
- loopdynentcache(x, y, o, radius)
- {
+bool overlapsdynent(const vec &o, float radius) {
+ loopdynentcache(x, y, o, radius) {
const vector<physent *> &dynents = checkdynentcache(x, y);
- loopv(dynents)
- {
+ loopv(dynents) {
physent *d = dynents[i];
if(o.dist(d->o)-d->radius < radius) return true;
}
@@ -626,13 +538,11 @@ bool overlapsdynent(const vec &o, float radius)
}
template<class E, class O>
-static inline bool plcollide(physent *d, const vec &dir, physent *o)
-{
+static inline bool plcollide(physent *d, const vec &dir, physent *o) {
E entvol(d);
O obvol(o);
vec cp;
- if(mpr::collide(entvol, obvol, NULL, NULL, &cp))
- {
+ if(mpr::collide(entvol, obvol, NULL, NULL, &cp)) {
vec wn = vec(cp).sub(obvol.center());
collidewall = obvol.contactface(wn, dir.iszero() ? vec(wn).neg() : dir);
if(!collidewall.iszero()) return true;
@@ -641,10 +551,8 @@ static inline bool plcollide(physent *d, const vec &dir, physent *o)
return false;
}
-static inline bool plcollide(physent *d, const vec &dir, physent *o)
-{
- switch(d->collidetype)
- {
+static inline bool plcollide(physent *d, const vec &dir, physent *o) {
+ switch(d->collidetype) {
case COLLIDE_ELLIPSE:
case COLLIDE_ELLIPSE_PRECISE:
if(o->collidetype == COLLIDE_OBB) return ellipseboxcollide(d, dir, o->o, vec(0, 0, 0), o->yaw, o->xradius, o->yradius, o->aboveeye, o->eyeheight);
@@ -656,33 +564,27 @@ static inline bool plcollide(physent *d, const vec &dir, physent *o)
}
}
-bool plcollide(physent *d, const vec &dir, bool insideplayercol) // collide with player or monster
-{
+bool plcollide(physent *d, const vec &dir, bool insideplayercol) { // collide with player or monster {
if(d->type==ENT_CAMERA || d->state!=CS_ALIVE) return false;
int lastinside = collideinside;
physent *insideplayer = NULL;
- loopdynentcache(x, y, d->o, d->radius)
- {
+ loopdynentcache(x, y, d->o, d->radius) {
const vector<physent *> &dynents = checkdynentcache(x, y);
- loopv(dynents)
- {
+ loopv(dynents) {
physent *o = dynents[i];
if(o==d || d->o.reject(o->o, d->radius+o->radius)) continue;
- if(plcollide(d, dir, o))
- {
+ if(plcollide(d, dir, o)) {
collideplayer = o;
game::dynentcollide(d, o, collidewall);
return true;
}
- if(collideinside > lastinside)
- {
+ if(collideinside > lastinside) {
lastinside = collideinside;
insideplayer = o;
}
}
}
- if(insideplayer && insideplayercol)
- {
+ if(insideplayer && insideplayercol) {
collideplayer = insideplayer;
game::dynentcollide(d, insideplayer, vec(0, 0, 0));
return true;
@@ -690,8 +592,7 @@ bool plcollide(physent *d, const vec &dir, bool insideplayercol) // collide with
return false;
}
-void rotatebb(vec &center, vec &radius, int yaw)
-{
+void rotatebb(vec &center, vec &radius, int yaw) {
if(yaw < 0) yaw = 360 + yaw%360;
else if(yaw >= 360) yaw %= 360;
const vec2 &rot = sincos360[yaw];
@@ -703,13 +604,11 @@ void rotatebb(vec &center, vec &radius, int yaw)
}
template<class E, class M>
-static inline bool mmcollide(physent *d, const vec &dir, const extentity &e, const vec &center, const vec &radius, float yaw)
-{
+static inline bool mmcollide(physent *d, const vec &dir, const extentity &e, const vec &center, const vec &radius, float yaw) {
E entvol(d);
M mdlvol(e.o, center, radius, yaw);
vec cp;
- if(mpr::collide(entvol, mdlvol, NULL, NULL, &cp))
- {
+ if(mpr::collide(entvol, mdlvol, NULL, NULL, &cp)) {
vec wn = vec(cp).sub(mdlvol.center());
collidewall = mdlvol.contactface(wn, dir.iszero() ? vec(wn).neg() : dir);
if(!collidewall.iszero()) return true;
@@ -718,34 +617,27 @@ static inline bool mmcollide(physent *d, const vec &dir, const extentity &e, con
return false;
}
-bool mmcollide(physent *d, const vec &dir, octaentities &oc) // collide with a mapmodel
-{
+bool mmcollide(physent *d, const vec &dir, octaentities &oc) { // collide with a mapmodel {
const vector<extentity *> &ents = entities::getents();
- loopv(oc.mapmodels)
- {
+ loopv(oc.mapmodels) {
extentity &e = *ents[oc.mapmodels[i]];
if(e.flags&EF_NOCOLLIDE) continue;
model *m = loadmapmodel(e.attr2);
if(!m || !m->collide) continue;
-
vec center, radius;
float rejectradius = m->collisionbox(center, radius);
if(d->o.reject(e.o, d->radius + rejectradius)) continue;
-
float yaw = e.attr1;
- switch(d->collidetype)
- {
+ switch(d->collidetype) {
case COLLIDE_ELLIPSE:
case COLLIDE_ELLIPSE_PRECISE:
- if(m->ellipsecollide)
- {
+ if(m->ellipsecollide) {
if(ellipsecollide(d, dir, e.o, center, yaw, radius.x, radius.y, radius.z, radius.z)) return true;
}
else if(ellipseboxcollide(d, dir, e.o, center, yaw, radius.x, radius.y, radius.z, radius.z)) return true;
break;
case COLLIDE_OBB:
- if(m->ellipsecollide)
- {
+ if(m->ellipsecollide) {
if(mmcollide<mpr::EntOBB, mpr::ModelEllipse>(d, dir, e, center, radius, yaw)) return true;
}
else if(mmcollide<mpr::EntOBB, mpr::ModelOBB>(d, dir, e, center, radius, yaw)) return true;
@@ -757,24 +649,22 @@ bool mmcollide(physent *d, const vec &dir, octaentities &oc) // collide wit
}
template<class E>
-static bool fuzzycollidesolid(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) // collide with solid cube geometry
-{
+static bool fuzzycollidesolid(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) { // collide with solid cube geometry {
int crad = size/2;
if(fabs(d->o.x - co.x - crad) > d->radius + crad || fabs(d->o.y - co.y - crad) > d->radius + crad ||
d->o.z + d->aboveeye < co.z || d->o.z - d->eyeheight > co.z + size)
return false;
-
E entvol(d);
collidewall = vec(0, 0, 0);
float bestdist = -1e10f;
int visible = isentirelysolid(c) ? c.visible : 0xFF;
- #define CHECKSIDE(side, distval, dotval, margin, normal) if(visible&(1<<side)) do \
- { \
+ #define CHECKSIDE(side, distval, dotval, margin, normal) if(visible&(1<<side)) do { \
+ \
float dist = distval; \
if(dist > 0) return false; \
if(dist <= bestdist) continue; \
- if(!dir.iszero()) \
- { \
+ if(!dir.iszero()) { \
+ \
if(dotval >= -cutoff*dir.magnitude()) continue; \
if(d->type<ENT_CAMERA && dotval < 0 && dist < margin) continue; \
} \
@@ -787,9 +677,7 @@ static bool fuzzycollidesolid(physent *d, const vec &dir, float cutoff, const cu
CHECKSIDE(O_FRONT, d->o.y - d->radius - (co.y + size), dir.y, -d->radius, vec(0, 1, 0));
CHECKSIDE(O_BOTTOM, co.z - (d->o.z + d->aboveeye), -dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/4.0f, vec(0, 0, -1));
CHECKSIDE(O_TOP, d->o.z - d->eyeheight - (co.z + size), dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/3.0f, vec(0, 0, 1));
-
- if(collidewall.iszero())
- {
+ if(collidewall.iszero()) {
collideinside++;
return false;
}
@@ -797,24 +685,20 @@ static bool fuzzycollidesolid(physent *d, const vec &dir, float cutoff, const cu
}
template<class E>
-static inline bool clampcollide(const clipplanes &p, const E &entvol, const plane &w, const vec &pw)
-{
- if(w.x && (w.y || w.z) && fabs(pw.x - p.o.x) > p.r.x)
- {
+static inline bool clampcollide(const clipplanes &p, const E &entvol, const plane &w, const vec &pw) {
+ if(w.x && (w.y || w.z) && fabs(pw.x - p.o.x) > p.r.x) {
vec c = entvol.center();
float fv = pw.x < p.o.x ? p.o.x-p.r.x : p.o.x+p.r.x, fdist = (w.x*fv + w.y*c.y + w.z*c.z + w.offset) / (w.y*w.y + w.z*w.z);
vec fdir(fv - c.x, -w.y*fdist, -w.z*fdist);
if((pw.y-c.y-fdir.y)*w.y + (pw.z-c.z-fdir.z)*w.z >= 0 && entvol.supportpoint(fdir).squaredist(c) < fdir.squaredlen()) return true;
}
- if(w.y && (w.x || w.z) && fabs(pw.y - p.o.y) > p.r.y)
- {
+ if(w.y && (w.x || w.z) && fabs(pw.y - p.o.y) > p.r.y) {
vec c = entvol.center();
float fv = pw.y < p.o.y ? p.o.y-p.r.y : p.o.y+p.r.y, fdist = (w.x*c.x + w.y*fv + w.z*c.z + w.offset) / (w.x*w.x + w.z*w.z);
vec fdir(-w.x*fdist, fv - c.y, -w.z*fdist);
if((pw.x-c.x-fdir.x)*w.x + (pw.z-c.z-fdir.z)*w.z >= 0 && entvol.supportpoint(fdir).squaredist(c) < fdir.squaredlen()) return true;
}
- if(w.z && (w.x || w.y) && fabs(pw.z - p.o.z) > p.r.z)
- {
+ if(w.z && (w.x || w.y) && fabs(pw.z - p.o.z) > p.r.z) {
vec c = entvol.center();
float fv = pw.z < p.o.z ? p.o.z-p.r.z : p.o.z+p.r.z, fdist = (w.x*c.x + w.y*c.y + w.z*fv + w.offset) / (w.x*w.x + w.y*w.y);
vec fdir(-w.x*fdist, -w.y*fdist, fv - c.z);
@@ -824,14 +708,11 @@ static inline bool clampcollide(const clipplanes &p, const E &entvol, const plan
}
template<class E>
-static bool fuzzycollideplanes(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) // collide with deformed cube geometry
-{
+static bool fuzzycollideplanes(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) { // collide with deformed cube geometry {
const clipplanes &p = getclipplanes(c, co, size);
-
if(fabs(d->o.x - p.o.x) > p.r.x + d->radius || fabs(d->o.y - p.o.y) > p.r.y + d->radius ||
d->o.z + d->aboveeye < p.o.z - p.r.z || d->o.z - d->eyeheight > p.o.z + p.r.z)
return false;
-
collidewall = vec(0, 0, 0);
float bestdist = -1e10f;
int visible = p.visible;
@@ -841,11 +722,9 @@ static bool fuzzycollideplanes(physent *d, const vec &dir, float cutoff, const c
CHECKSIDE(O_FRONT, d->o.y - d->radius - (p.o.y + p.r.y), dir.y, -d->radius, vec(0, 1, 0));
CHECKSIDE(O_BOTTOM, p.o.z - p.r.z - (d->o.z + d->aboveeye), -dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/4.0f, vec(0, 0, -1));
CHECKSIDE(O_TOP, d->o.z - d->eyeheight - (p.o.z + p.r.z), dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/3.0f, vec(0, 0, 1));
-
E entvol(d);
int bestplane = -1;
- loopi(p.size)
- {
+ loopi(p.size) {
const plane &w = p.p[i];
vec pw = entvol.supportpoint(vec(w).neg());
float dist = w.dist(pw);
@@ -853,8 +732,7 @@ static bool fuzzycollideplanes(physent *d, const vec &dir, float cutoff, const c
if(dist <= bestdist) continue;
bestplane = -1;
bestdist = dist;
- if(!dir.iszero())
- {
+ if(!dir.iszero()) {
if(w.dot(dir) >= -cutoff*dir.magnitude()) continue;
if(d->type<ENT_CAMERA &&
dist < (dir.z*w.z < 0 ?
@@ -866,8 +744,7 @@ static bool fuzzycollideplanes(physent *d, const vec &dir, float cutoff, const c
bestplane = i;
}
if(bestplane >= 0) collidewall = p.p[bestplane];
- else if(collidewall.iszero())
- {
+ else if(collidewall.iszero()) {
collideinside++;
return false;
}
@@ -875,17 +752,14 @@ static bool fuzzycollideplanes(physent *d, const vec &dir, float cutoff, const c
}
template<class E>
-static bool cubecollidesolid(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) // collide with solid cube geometry
-{
+static bool cubecollidesolid(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) { // collide with solid cube geometry {
int crad = size/2;
if(fabs(d->o.x - co.x - crad) > d->radius + crad || fabs(d->o.y - co.y - crad) > d->radius + crad ||
d->o.z + d->aboveeye < co.z || d->o.z - d->eyeheight > co.z + size)
return false;
-
E entvol(d);
bool collided = mpr::collide(mpr::SolidCube(co, size), entvol);
if(!collided) return false;
-
collidewall = vec(0, 0, 0);
float bestdist = -1e10f;
int visible = isentirelysolid(c) ? c.visible : 0xFF;
@@ -895,9 +769,7 @@ static bool cubecollidesolid(physent *d, const vec &dir, float cutoff, const cub
CHECKSIDE(O_FRONT, entvol.back() - (co.y + size), dir.y, -d->radius, vec(0, 1, 0));
CHECKSIDE(O_BOTTOM, co.z - entvol.top(), -dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/4.0f, vec(0, 0, -1));
CHECKSIDE(O_TOP, entvol.bottom() - (co.z + size), dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/3.0f, vec(0, 0, 1));
-
- if(collidewall.iszero())
- {
+ if(collidewall.iszero()) {
collideinside++;
return false;
}
@@ -905,18 +777,14 @@ static bool cubecollidesolid(physent *d, const vec &dir, float cutoff, const cub
}
template<class E>
-static bool cubecollideplanes(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) // collide with deformed cube geometry
-{
+static bool cubecollideplanes(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) { // collide with deformed cube geometry {
const clipplanes &p = getclipplanes(c, co, size);
-
if(fabs(d->o.x - p.o.x) > p.r.x + d->radius || fabs(d->o.y - p.o.y) > p.r.y + d->radius ||
d->o.z + d->aboveeye < p.o.z - p.r.z || d->o.z - d->eyeheight > p.o.z + p.r.z)
return false;
-
E entvol(d);
bool collided = mpr::collide(mpr::CubePlanes(p), entvol);
if(!collided) return false;
-
collidewall = vec(0, 0, 0);
float bestdist = -1e10f;
int visible = p.visible;
@@ -926,18 +794,15 @@ static bool cubecollideplanes(physent *d, const vec &dir, float cutoff, const cu
CHECKSIDE(O_FRONT, entvol.back() - (p.o.y + p.r.y), dir.y, -d->radius, vec(0, 1, 0));
CHECKSIDE(O_BOTTOM, p.o.z - p.r.z - entvol.top(), -dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/4.0f, vec(0, 0, -1));
CHECKSIDE(O_TOP, entvol.bottom() - (p.o.z + p.r.z), dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/3.0f, vec(0, 0, 1));
-
int bestplane = -1;
- loopi(p.size)
- {
+ loopi(p.size) {
const plane &w = p.p[i];
vec pw = entvol.supportpoint(vec(w).neg());
float dist = w.dist(pw);
if(dist <= bestdist) continue;
bestplane = -1;
bestdist = dist;
- if(!dir.iszero())
- {
+ if(!dir.iszero()) {
if(w.dot(dir) >= -cutoff*dir.magnitude()) continue;
if(d->type<ENT_CAMERA &&
dist < (dir.z*w.z < 0 ?
@@ -949,18 +814,15 @@ static bool cubecollideplanes(physent *d, const vec &dir, float cutoff, const cu
bestplane = i;
}
if(bestplane >= 0) collidewall = p.p[bestplane];
- else if(collidewall.iszero())
- {
+ else if(collidewall.iszero()) {
collideinside++;
return false;
}
return true;
}
-static inline bool cubecollide(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size, bool solid)
-{
- switch(d->collidetype)
- {
+static inline bool cubecollide(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size, bool solid) {
+ switch(d->collidetype) {
case COLLIDE_OBB:
if(isentirelysolid(c) || solid) return cubecollidesolid<mpr::EntOBB>(d, dir, cutoff, c, co, size);
else return cubecollideplanes<mpr::EntOBB>(d, dir, cutoff, c, co, size);
@@ -974,21 +836,16 @@ static inline bool cubecollide(physent *d, const vec &dir, float cutoff, const c
}
}
-static inline bool octacollide(physent *d, const vec &dir, float cutoff, const ivec &bo, const ivec &bs, const cube *c, const ivec &cor, int size) // collide with octants
-{
- loopoctabox(cor, size, bo, bs)
- {
+static inline bool octacollide(physent *d, const vec &dir, float cutoff, const ivec &bo, const ivec &bs, const cube *c, const ivec &cor, int size) { // collide with octants {
+ loopoctabox(cor, size, bo, bs) {
if(c[i].ext && c[i].ext->ents) if(mmcollide(d, dir, *c[i].ext->ents)) return true;
ivec o(i, cor, size);
- if(c[i].children)
- {
+ if(c[i].children) {
if(octacollide(d, dir, cutoff, bo, bs, c[i].children, o, size>>1)) return true;
}
- else
- {
+ else {
bool solid = false;
- switch(c[i].material&MATF_CLIP)
- {
+ switch(c[i].material&MATF_CLIP) {
case MAT_NOCLIP: continue;
case MAT_GAMECLIP: if(d->type==ENT_AI) solid = true; break;
case MAT_CLIP: if(d->type<ENT_CAMERA) solid = true; break;
@@ -1000,8 +857,7 @@ static inline bool octacollide(physent *d, const vec &dir, float cutoff, const i
return false;
}
-static inline bool octacollide(physent *d, const vec &dir, float cutoff, const ivec &bo, const ivec &bs)
-{
+static inline bool octacollide(physent *d, const vec &dir, float cutoff, const ivec &bo, const ivec &bs) {
int diff = (bo.x^bs.x) | (bo.y^bs.y) | (bo.z^bs.z),
scale = worldscale-1;
if(diff&~((1<<scale)-1) || uint(bo.x|bo.y|bo.z|bs.x|bs.y|bs.z) >= uint(worldsize))
@@ -1009,16 +865,14 @@ static inline bool octacollide(physent *d, const vec &dir, float cutoff, const i
const cube *c = &worldroot[octastep(bo.x, bo.y, bo.z, scale)];
if(c->ext && c->ext->ents && mmcollide(d, dir, *c->ext->ents)) return true;
scale--;
- while(c->children && !(diff&(1<<scale)))
- {
+ while(c->children && !(diff&(1<<scale))) {
c = &c->children[octastep(bo.x, bo.y, bo.z, scale)];
if(c->ext && c->ext->ents && mmcollide(d, dir, *c->ext->ents)) return true;
scale--;
}
if(c->children) return octacollide(d, dir, cutoff, bo, bs, c->children, ivec(bo).mask(~((2<<scale)-1)), 1<<scale);
bool solid = false;
- switch(c->material&MATF_CLIP)
- {
+ switch(c->material&MATF_CLIP) {
case MAT_NOCLIP: return false;
case MAT_GAMECLIP: if(d->type==ENT_AI) solid = true; break;
case MAT_CLIP: if(d->type<ENT_CAMERA) solid = true; break;
@@ -1029,8 +883,7 @@ static inline bool octacollide(physent *d, const vec &dir, float cutoff, const i
}
// all collision happens here
-bool collide(physent *d, const vec &dir, float cutoff, bool playercol, bool insideplayercol)
-{
+bool collide(physent *d, const vec &dir, float cutoff, bool playercol, bool insideplayercol) {
collideinside = 0;
collideplayer = NULL;
collidewall = vec(0, 0, 0);
@@ -1040,11 +893,9 @@ bool collide(physent *d, const vec &dir, float cutoff, bool playercol, bool insi
return octacollide(d, dir, cutoff, bo, bs) || (playercol && plcollide(d, dir, insideplayercol));
}
-void recalcdir(physent *d, const vec &oldvel, vec &dir)
-{
+void recalcdir(physent *d, const vec &oldvel, vec &dir) {
float speed = oldvel.magnitude();
- if(speed > 1e-6f)
- {
+ if(speed > 1e-6f) {
float step = dir.magnitude();
dir = d->vel;
dir.add(d->falling);
@@ -1052,11 +903,9 @@ void recalcdir(physent *d, const vec &oldvel, vec &dir)
}
}
-void slideagainst(physent *d, vec &dir, const vec &obstacle, bool foundfloor, bool slidecollide)
-{
+void slideagainst(physent *d, vec &dir, const vec &obstacle, bool foundfloor, bool slidecollide) {
vec wall(obstacle);
- if(foundfloor ? wall.z > 0 : slidecollide)
- {
+ if(foundfloor ? wall.z > 0 : slidecollide) {
wall.z = 0;
if(!wall.iszero()) wall.normalize();
}
@@ -1067,14 +916,11 @@ void slideagainst(physent *d, vec &dir, const vec &obstacle, bool foundfloor, bo
recalcdir(d, oldvel, dir);
}
-void switchfloor(physent *d, vec &dir, const vec &floor)
-{
+void switchfloor(physent *d, vec &dir, const vec &floor) {
if(floor.z >= FLOORZ) d->falling = vec(0, 0, 0);
-
vec oldvel(d->vel);
oldvel.add(d->falling);
- if(dir.dot(floor) >= 0)
- {
+ if(dir.dot(floor) >= 0) {
if(d->physstate < PHYS_SLIDE || fabs(dir.dot(d->floor)) > 0.01f*dir.magnitude()) return;
d->vel.projectxy(floor, 0.0f);
}
@@ -1083,57 +929,46 @@ void switchfloor(physent *d, vec &dir, const vec &floor)
recalcdir(d, oldvel, dir);
}
-bool trystepup(physent *d, vec &dir, const vec &obstacle, float maxstep, const vec &floor)
-{
+bool trystepup(physent *d, vec &dir, const vec &obstacle, float maxstep, const vec &floor) {
vec old(d->o), stairdir = (obstacle.z >= 0 && obstacle.z < SLOPEZ ? vec(-obstacle.x, -obstacle.y, 0) : vec(dir.x, dir.y, 0)).rescale(1);
bool cansmooth = true;
/* check if there is space atop the stair to move to */
- if(d->physstate != PHYS_STEP_UP)
- {
+ if(d->physstate != PHYS_STEP_UP) {
vec checkdir = stairdir;
checkdir.mul(0.1f);
checkdir.z += maxstep + 0.1f;
d->o.add(checkdir);
- if(collide(d))
- {
+ if(collide(d)) {
d->o = old;
if(!collide(d, vec(0, 0, -1), SLOPEZ)) return false;
cansmooth = false;
}
}
-
- if(cansmooth)
- {
+ if(cansmooth) {
vec checkdir = stairdir;
checkdir.z += 1;
checkdir.mul(maxstep);
d->o = old;
d->o.add(checkdir);
int scale = 2;
- if(collide(d, checkdir))
- {
- if(!collide(d, vec(0, 0, -1), SLOPEZ))
- {
+ if(collide(d, checkdir)) {
+ if(!collide(d, vec(0, 0, -1), SLOPEZ)) {
d->o = old;
return false;
}
d->o.add(checkdir);
if(collide(d, vec(0, 0, -1), SLOPEZ)) scale = 1;
}
- if(scale != 1)
- {
+ if(scale != 1) {
d->o = old;
d->o.sub(checkdir.mul(vec(2, 2, 1)));
if(!collide(d, vec(0, 0, -1), SLOPEZ)) scale = 1;
}
-
d->o = old;
vec smoothdir(dir.x, dir.y, 0);
float magxy = smoothdir.magnitude();
- if(magxy > 1e-9f)
- {
- if(magxy > scale*dir.z)
- {
+ if(magxy > 1e-9f) {
+ if(magxy > scale*dir.z) {
smoothdir.mul(1/magxy);
smoothdir.z = 1.0f/scale;
smoothdir.mul(dir.magnitude()/smoothdir.magnitude());
@@ -1141,11 +976,9 @@ bool trystepup(physent *d, vec &dir, const vec &obstacle, float maxstep, const v
else smoothdir.z = dir.z;
d->o.add(smoothdir);
d->o.z += maxstep + 0.1f;
- if(!collide(d, smoothdir))
- {
+ if(!collide(d, smoothdir)) {
d->o.z -= maxstep + 0.1f;
- if(d->physstate == PHYS_FALL || d->floor != floor)
- {
+ if(d->physstate == PHYS_FALL || d->floor != floor) {
d->timeinair = 0;
d->floor = floor;
switchfloor(d, dir, d->floor);
@@ -1155,14 +988,11 @@ bool trystepup(physent *d, vec &dir, const vec &obstacle, float maxstep, const v
}
}
}
-
/* try stepping up */
d->o = old;
d->o.z += dir.magnitude();
- if(!collide(d, vec(0, 0, 1)))
- {
- if(d->physstate == PHYS_FALL || d->floor != floor)
- {
+ if(!collide(d, vec(0, 0, 1))) {
+ if(d->physstate == PHYS_FALL || d->floor != floor) {
d->timeinair = 0;
d->floor = floor;
switchfloor(d, dir, d->floor);
@@ -1174,34 +1004,28 @@ bool trystepup(physent *d, vec &dir, const vec &obstacle, float maxstep, const v
return false;
}
-bool trystepdown(physent *d, vec &dir, float step, float xy, float z, bool init = false)
-{
+bool trystepdown(physent *d, vec &dir, float step, float xy, float z, bool init = false) {
vec stepdir(dir.x, dir.y, 0);
stepdir.z = -stepdir.magnitude2()*z/xy;
if(!stepdir.z) return false;
stepdir.normalize();
-
vec old(d->o);
d->o.add(vec(stepdir).mul(STAIRHEIGHT/fabs(stepdir.z))).z -= STAIRHEIGHT;
d->zmargin = -STAIRHEIGHT;
- if(collide(d, vec(0, 0, -1), SLOPEZ))
- {
+ if(collide(d, vec(0, 0, -1), SLOPEZ)) {
d->o = old;
d->o.add(vec(stepdir).mul(step));
d->zmargin = 0;
- if(!collide(d, vec(0, 0, -1)))
- {
+ if(!collide(d, vec(0, 0, -1))) {
vec stepfloor(stepdir);
stepfloor.mul(-stepfloor.z).z += 1;
stepfloor.normalize();
- if(d->physstate >= PHYS_SLOPE && d->floor != stepfloor)
- {
+ if(d->physstate >= PHYS_SLOPE && d->floor != stepfloor) {
// prevent alternating step-down/step-up states if player would keep bumping into the same floor
vec stepped(d->o);
d->o.z -= 0.5f;
d->zmargin = -0.5f;
- if(collide(d, stepdir) && collidewall == d->floor)
- {
+ if(collide(d, stepdir) && collidewall == d->floor) {
d->o = old;
if(!init) { d->o.x += dir.x; d->o.y += dir.y; if(dir.z <= 0 || collide(d, dir)) d->o.z += dir.z; }
d->zmargin = 0;
@@ -1225,14 +1049,12 @@ bool trystepdown(physent *d, vec &dir, float step, float xy, float z, bool init
return false;
}
-bool trystepdown(physent *d, vec &dir, bool init = false)
-{
+bool trystepdown(physent *d, vec &dir, bool init = false) {
if((!d->move && !d->strafe) || !game::allowmove(d)) return false;
vec old(d->o);
d->o.z -= STAIRHEIGHT;
d->zmargin = -STAIRHEIGHT;
- if(!collide(d, vec(0, 0, -1), SLOPEZ))
- {
+ if(!collide(d, vec(0, 0, -1), SLOPEZ)) {
d->o = old;
d->zmargin = 0;
return false;
@@ -1251,10 +1073,8 @@ bool trystepdown(physent *d, vec &dir, bool init = false)
return false;
}
-void falling(physent *d, vec &dir, const vec &floor)
-{
- if(floor.z > 0.0f && floor.z < SLOPEZ)
- {
+void falling(physent *d, vec &dir, const vec &floor) {
+ if(floor.z > 0.0f && floor.z < SLOPEZ) {
if(floor.z >= WALLZ) switchfloor(d, dir, floor);
d->timeinair = 0;
d->physstate = PHYS_SLIDE;
@@ -1264,11 +1084,9 @@ void falling(physent *d, vec &dir, const vec &floor)
d->physstate = PHYS_FALL;
}
-void landing(physent *d, vec &dir, const vec &floor, bool collided)
-{
+void landing(physent *d, vec &dir, const vec &floor, bool collided) {
#if 0
- if(d->physstate == PHYS_FALL)
- {
+ if(d->physstate == PHYS_FALL) {
d->timeinair = 0;
if(dir.z < 0.0f) dir.z = d->vel.z = 0.0f;
}
@@ -1280,40 +1098,32 @@ void landing(physent *d, vec &dir, const vec &floor, bool collided)
d->floor = floor;
}
-bool findfloor(physent *d, bool collided, const vec &obstacle, bool &slide, vec &floor)
-{
+bool findfloor(physent *d, bool collided, const vec &obstacle, bool &slide, vec &floor) {
bool found = false;
vec moved(d->o);
d->o.z -= 0.1f;
- if(collide(d, vec(0, 0, -1), d->physstate == PHYS_SLOPE || d->physstate == PHYS_STEP_DOWN ? SLOPEZ : FLOORZ))
- {
+ if(collide(d, vec(0, 0, -1), d->physstate == PHYS_SLOPE || d->physstate == PHYS_STEP_DOWN ? SLOPEZ : FLOORZ)) {
floor = collidewall;
found = true;
}
- else if(collided && obstacle.z >= SLOPEZ)
- {
+ else if(collided && obstacle.z >= SLOPEZ) {
floor = obstacle;
found = true;
slide = false;
}
- else if(d->physstate == PHYS_STEP_UP || d->physstate == PHYS_SLIDE)
- {
- if(collide(d, vec(0, 0, -1)) && collidewall.z > 0.0f)
- {
+ else if(d->physstate == PHYS_STEP_UP || d->physstate == PHYS_SLIDE) {
+ if(collide(d, vec(0, 0, -1)) && collidewall.z > 0.0f) {
floor = collidewall;
if(floor.z >= SLOPEZ) found = true;
}
}
- else if(d->physstate >= PHYS_SLOPE && d->floor.z < 1.0f)
- {
- if(collide(d, vec(d->floor).neg(), 0.95f) || collide(d, vec(0, 0, -1)))
- {
+ else if(d->physstate >= PHYS_SLOPE && d->floor.z < 1.0f) {
+ if(collide(d, vec(d->floor).neg(), 0.95f) || collide(d, vec(0, 0, -1))) {
floor = collidewall;
if(floor.z >= SLOPEZ && floor.z < 1.0f) found = true;
}
}
- if(collided && (!found || obstacle.z > floor.z))
- {
+ if(collided && (!found || obstacle.z > floor.z)) {
floor = obstacle;
slide = !found && (floor.z < WALLZ || floor.z >= SLOPEZ);
}
@@ -1321,49 +1131,41 @@ bool findfloor(physent *d, bool collided, const vec &obstacle, bool &slide, vec
return found;
}
-bool move(physent *d, vec &dir)
-{
+bool move(physent *d, vec &dir) {
vec old(d->o);
bool collided = false, slidecollide = false;
vec obstacle = vec(0, 0, 0);
d->o.add(dir);
- if(collide(d, dir) || ((d->type==ENT_AI || d->type==ENT_INANIMATE) && collide(d, vec(0, 0, 0), 0, false)))
- {
+ if(collide(d, dir) || ((d->type==ENT_AI || d->type==ENT_INANIMATE) && collide(d, vec(0, 0, 0), 0, false))) {
obstacle = collidewall;
/* check to see if there is an obstacle that would prevent this one from being used as a floor (or ceiling bump) */
- if(d->type==ENT_PLAYER && ((collidewall.z>=SLOPEZ && dir.z<0) || (collidewall.z<=-SLOPEZ && dir.z>0)) && (dir.x || dir.y) && collide(d, vec(dir.x, dir.y, 0)))
- {
+ if(d->type==ENT_PLAYER && ((collidewall.z>=SLOPEZ && dir.z<0) || (collidewall.z<=-SLOPEZ && dir.z>0)) && (dir.x || dir.y) && collide(d, vec(dir.x, dir.y, 0))) {
if(collidewall.dot(dir) >= 0) slidecollide = true;
obstacle = collidewall;
}
d->o = old;
d->o.z -= STAIRHEIGHT;
d->zmargin = -STAIRHEIGHT;
- if(d->physstate == PHYS_SLOPE || d->physstate == PHYS_FLOOR || (collide(d, vec(0, 0, -1), SLOPEZ) && (d->physstate==PHYS_STEP_UP || d->physstate==PHYS_STEP_DOWN || collidewall.z>=FLOORZ)))
- {
+ if(d->physstate == PHYS_SLOPE || d->physstate == PHYS_FLOOR || (collide(d, vec(0, 0, -1), SLOPEZ) && (d->physstate==PHYS_STEP_UP || d->physstate==PHYS_STEP_DOWN || collidewall.z>=FLOORZ))) {
d->o = old;
d->zmargin = 0;
if(trystepup(d, dir, obstacle, STAIRHEIGHT, d->physstate == PHYS_SLOPE || d->physstate == PHYS_FLOOR ? d->floor : vec(collidewall))) return true;
}
- else
- {
+ else {
d->o = old;
d->zmargin = 0;
}
/* can't step over the obstacle, so just slide against it */
collided = true;
}
- else if(d->physstate == PHYS_STEP_UP)
- {
- if(collide(d, vec(0, 0, -1), SLOPEZ))
- {
+ else if(d->physstate == PHYS_STEP_UP) {
+ if(collide(d, vec(0, 0, -1), SLOPEZ)) {
d->o = old;
if(trystepup(d, dir, vec(0, 0, 1), STAIRHEIGHT, vec(collidewall))) return true;
d->o.add(dir);
}
}
- else if(d->physstate == PHYS_STEP_DOWN && dir.dot(d->floor) <= 1e-6f)
- {
+ else if(d->physstate == PHYS_STEP_DOWN && dir.dot(d->floor) <= 1e-6f) {
vec moved(d->o);
d->o = old;
if(trystepdown(d, dir)) return true;
@@ -1372,8 +1174,7 @@ bool move(physent *d, vec &dir)
vec floor(0, 0, 0);
bool slide = collided,
found = findfloor(d, collided, obstacle, slide, floor);
- if(slide || (!collided && floor.z > 0 && floor.z < WALLZ))
- {
+ if(slide || (!collided && floor.z > 0 && floor.z < WALLZ)) {
slideagainst(d, dir, slide ? obstacle : floor, found, slidecollide);
//if(d->type == ENT_AI || d->type == ENT_INANIMATE)
d->blocked = true;
@@ -1383,21 +1184,17 @@ bool move(physent *d, vec &dir)
return !collided;
}
-bool bounce(physent *d, float secs, float elasticity, float grav)
-{
+bool bounce(physent *d, float secs, float elasticity, float grav) {
// make sure bouncers don't start inside geometry
if(d->physstate!=PHYS_BOUNCE && collide(d, vec(0, 0, 0), 0, false)) return true;
d->vel.z -= grav*GRAVITY*secs;
vec old(d->o);
- loopi(2)
- {
+ loopi(2) {
vec dir(d->vel);
dir.mul(secs);
d->o.add(dir);
- if(!collide(d, dir, 0, true, true))
- {
- if(collideinside)
- {
+ if(!collide(d, dir, 0, true, true)) {
+ if(collideinside) {
d->o = old;
d->vel.mul(-elasticity);
}
@@ -1411,8 +1208,7 @@ bool bounce(physent *d, float secs, float elasticity, float grav)
d->vel.mul(k);
d->vel.sub(vec(collidewall).mul(elasticity*2.0f*c));
}
- if(d->physstate!=PHYS_BOUNCE)
- {
+ if(d->physstate!=PHYS_BOUNCE) {
// make sure bouncers don't start inside geometry
if(d->o == old) return !collideplayer;
d->physstate = PHYS_BOUNCE;
@@ -1420,8 +1216,7 @@ bool bounce(physent *d, float secs, float elasticity, float grav)
return collideplayer!=NULL;
}
-void avoidcollision(physent *d, const vec &dir, physent *obstacle, float space)
-{
+void avoidcollision(physent *d, const vec &dir, physent *obstacle, float space) {
float rad = obstacle->radius+d->radius;
vec bbmin(obstacle->o);
bbmin.x -= rad;
@@ -1433,31 +1228,24 @@ void avoidcollision(physent *d, const vec &dir, physent *obstacle, float space)
bbmax.y += rad;
bbmax.z += obstacle->aboveeye+d->eyeheight;
bbmax.add(space);
-
loopi(3) if(d->o[i] <= bbmin[i] || d->o[i] >= bbmax[i]) return;
-
float mindist = 1e16f;
- loopi(3) if(dir[i] != 0)
- {
+ loopi(3) if(dir[i] != 0) {
float dist = ((dir[i] > 0 ? bbmax[i] : bbmin[i]) - d->o[i]) / dir[i];
mindist = min(mindist, dist);
}
if(mindist >= 0.0f && mindist < 1e15f) d->o.add(vec(dir).mul(mindist));
}
-bool movecamera(physent *pl, const vec &dir, float dist, float stepdist)
-{
+bool movecamera(physent *pl, const vec &dir, float dist, float stepdist) {
int steps = (int)ceil(dist/stepdist);
if(steps <= 0) return true;
-
vec d(dir);
d.mul(dist/steps);
- loopi(steps)
- {
+ loopi(steps) {
vec oldpos(pl->o);
pl->o.add(d);
- if(collide(pl, vec(0, 0, 0), 0, false))
- {
+ if(collide(pl, vec(0, 0, 0), 0, false)) {
pl->o = oldpos;
return false;
}
@@ -1465,22 +1253,18 @@ bool movecamera(physent *pl, const vec &dir, float dist, float stepdist)
return true;
}
-void dropenttofloor(entity *e)
-{
+void dropenttofloor(entity *e) {
float radius = 1.0f;
float height = 4.0f;
vec o = e->o;
- static struct dropent : physent
- {
- dropent()
- {
+ static struct dropent : physent {
+ dropent() {
type = ENT_BOUNCE;
vel = vec(0, 0, -1);
}
} d;
d.o = o;
- if(!insideworld(d.o))
- {
+ if(!insideworld(d.o)) {
if(d.o.z < worldsize) return;
d.o.z = worldsize - 1e-3f;
if(!insideworld(d.o)) return;
@@ -1495,35 +1279,27 @@ void dropenttofloor(entity *e)
o = d.o;
}
-void vecfromyawpitch(float yaw, float pitch, int move, int strafe, vec &m)
-{
- if(move)
- {
+void vecfromyawpitch(float yaw, float pitch, int move, int strafe, vec &m) {
+ if(move) {
m.x = move*-sinf(RAD*yaw);
m.y = move*cosf(RAD*yaw);
}
else m.x = m.y = 0;
-
- if(pitch)
- {
+ if(pitch) {
m.x *= cosf(RAD*pitch);
m.y *= cosf(RAD*pitch);
m.z = move*sinf(RAD*pitch);
}
else m.z = 0;
-
- if(strafe)
- {
+ if(strafe) {
m.x += strafe*cosf(RAD*yaw);
m.y += strafe*sinf(RAD*yaw);
}
}
-void vectoyawpitch(const vec &v, float &yaw, float &pitch)
-{
+void vectoyawpitch(const vec &v, float &yaw, float &pitch) {
if(v.iszero()) yaw = pitch = 0;
- else
- {
+ else {
yaw = -atan2(v.x, v.y)/RAD;
pitch = asin(v.z/v.magnitude())/RAD;
}
@@ -1536,51 +1312,36 @@ FVAR(straferoll, 0, 0.033f, 90);
FVAR(faderoll, 0, 0.95f, 1);
VAR(floatspeed, 1, 100, 10000);
-void modifyvelocity(physent *pl, bool local, bool floating, int curtime)
-{
+void modifyvelocity(physent *pl, bool local, bool floating, int curtime) {
bool allowmove = game::allowmove(pl);
- if(floating)
- {
- if(pl->jumping && allowmove)
- {
+ if(floating) {
+ if(pl->jumping && allowmove) {
pl->jumping = false;
pl->vel.z = max(pl->vel.z, JUMPVEL);
}
}
- else if(pl->physstate >= PHYS_SLOPE)
- {
+ else if(pl->physstate >= PHYS_SLOPE) {
if(!pl->inwater) pl->vel.div(8);
- if(pl->jumping && allowmove)
- {
+ if(pl->jumping && allowmove) {
pl->jumping = false;
-
pl->vel.z = max(pl->vel.z, JUMPVEL); // physics impulse upwards
-
game::physicstrigger(pl, local, 1);
}
}
if(!floating && pl->physstate == PHYS_FALL) pl->timeinair = min(pl->timeinair + curtime, 1000);
-
vec m(0.0f, 0.0f, 0.0f);
- if((pl->move || pl->strafe) && allowmove)
- {
+ if((pl->move || pl->strafe) && allowmove) {
vecfromyawpitch(pl->yaw, floating || pl->type==ENT_CAMERA ? pl->pitch : 0, pl->move, pl->strafe, m);
-
if(!floating && pl->physstate >= PHYS_SLOPE)
m.z = -(m.x*pl->floor.x + m.y*pl->floor.y)/pl->floor.z; // move up or down slopes in air
-
m.normalize();
}
-
vec d(m);
speedmodifier*=(pl->physstate!=PHYS_FLOOR)*(speedmodifier>0);
speedmodifier=(speedmodifier>100.0f)?100.0f:speedmodifier;
d.mul(pl->maxspeed + speedmodifier);
-
- if(pl->type==ENT_PLAYER)
- {
- if(floating)
- {
+ if(pl->type==ENT_PLAYER) {
+ if(floating) {
if(pl==player) d.mul(floatspeed/100.0f);
}
else if(allowmove) d.mul((pl->move && !pl->strafe ? 1.3f : 1.0f) * (pl->physstate < PHYS_SLOPE ? 1.3f : 1.0f));
@@ -1589,22 +1350,18 @@ void modifyvelocity(physent *pl, bool local, bool floating, int curtime)
pl->vel.lerp(d, pl->vel, pow(1 - 1/fric, curtime/20.0f));
}
-void modifygravity(physent *pl, int curtime)
-{
+void modifygravity(physent *pl, int curtime) {
float secs = curtime/1000.0f;
vec g(0, 0, 0);
if(pl->physstate == PHYS_FALL) g.z -= GRAVITY*secs;
- else if(pl->floor.z > 0 && pl->floor.z < FLOORZ)
- {
+ else if(pl->floor.z > 0 && pl->floor.z < FLOORZ) {
g.z = -1;
g.project(pl->floor);
g.normalize();
g.mul(GRAVITY*secs);
}
if(!game::allowmove(pl) || (!pl->move && !pl->strafe)) pl->falling.add(g);
-
- if(pl->physstate >= PHYS_SLOPE)
- {
+ if(pl->physstate >= PHYS_SLOPE) {
float fric = 6.0f,
c = clamp((pl->floor.z - SLOPEZ)/(FLOORZ-SLOPEZ), 0.0f, 1.0f);
pl->falling.mul(pow(1 - c/fric, curtime/20.0f));
@@ -1615,71 +1372,53 @@ void modifygravity(physent *pl, int curtime)
// moveres indicated the physics precision (which is lower for monsters and multiplayer prediction)
// local is false for multiplayer prediction
-bool moveplayer(physent *pl, int moveres, bool local, int curtime)
-{
+bool moveplayer(physent *pl, int moveres, bool local, int curtime) {
int material = lookupmaterial(vec(pl->o.x, pl->o.y, pl->o.z + (3*pl->aboveeye - pl->eyeheight)/4));
bool floating = pl->type==ENT_PLAYER && (pl->state==CS_EDITING || pl->state==CS_SPECTATOR);
float secs = curtime/1000.f;
-
// apply gravity
if(!floating) modifygravity(pl, curtime);
// apply any player generated changes in velocity
modifyvelocity(pl, local, floating, curtime);
-
vec d(pl->vel);
if(!floating) d.mul(0.5f);
d.add(pl->falling);
d.mul(secs);
-
pl->blocked = false;
-
- if(floating) // just apply velocity
- {
- if(pl->physstate != PHYS_FLOAT)
- {
+ if(floating) { // just apply velocity {
+ if(pl->physstate != PHYS_FLOAT) {
pl->physstate = PHYS_FLOAT;
pl->timeinair = 0;
pl->falling = vec(0, 0, 0);
}
pl->o.add(d);
}
- else // apply velocity with collision
- {
+ else { // apply velocity with collision {
const float f = 1.0f/moveres;
const int timeinair = pl->timeinair;
int collisions = 0;
-
d.mul(f);
loopi(moveres) if(!move(pl, d) && ++collisions<5) i--; // discrete steps collision detection & sliding
- if(timeinair > 800 && !pl->timeinair) // if we land after long time must have been a high jump, make thud sound
- {
+ if(timeinair > 800 && !pl->timeinair) { // if we land after long time must have been a high jump, make thud sound {
game::physicstrigger(pl, local, -1);
}
}
-
if(pl->state==CS_ALIVE) updatedynentcache(pl);
-
// automatically apply smooth roll when strafing
-
if(pl->strafe && maxroll) pl->roll = clamp(pl->roll - pow(clamp(1.0f + pl->strafe*pl->roll/maxroll, 0.0f, 1.0f), 0.33f)*pl->strafe*curtime*straferoll, -maxroll, maxroll);
else pl->roll *= curtime == PHYSFRAMETIME ? faderoll : pow(faderoll, curtime/float(PHYSFRAMETIME));
-
if(pl->inwater) game::physicstrigger(pl, local, 0, pl->inwater);
pl->inwater = MAT_AIR;
-
if(pl->state==CS_ALIVE && (pl->o.z < 0 || material&MAT_DEATH)) game::suicide(pl);
-
return true;
}
int physsteps = 0, physframetime = PHYSFRAMETIME, lastphysframe = 0;
-void physicsframe() // optimally schedule physics frames inside the graphics frames
-{
+void physicsframe() { // optimally schedule physics frames inside the graphics frames {
int diff = lastmillis - lastphysframe;
if(diff <= 0) physsteps = 0;
- else
- {
+ else {
physframetime = clamp(game::scaletime(PHYSFRAMETIME)/100, 1, PHYSFRAMETIME);
physsteps = (diff + physframetime - 1)/physframetime;
lastphysframe += physsteps * physframetime;
@@ -1689,50 +1428,39 @@ void physicsframe() // optimally schedule physics frames inside the graphics
VAR(physinterp, 0, 1, 1);
-void interppos(physent *pl)
-{
+void interppos(physent *pl) {
pl->o = pl->newpos;
-
int diff = lastphysframe - lastmillis;
if(diff <= 0 || !physinterp) return;
-
vec deltapos(pl->deltapos);
deltapos.mul(min(diff, physframetime)/float(physframetime));
pl->o.add(deltapos);
}
-void moveplayer(physent *pl, int moveres, bool local)
-{
- if(physsteps <= 0)
- {
+void moveplayer(physent *pl, int moveres, bool local) {
+ if(physsteps <= 0) {
if(local) interppos(pl);
return;
}
-
if(local) pl->o = pl->newpos;
loopi(physsteps-1) moveplayer(pl, moveres, local, physframetime);
if(local) pl->deltapos = pl->o;
moveplayer(pl, moveres, local, physframetime);
- if(local)
- {
+ if(local) {
pl->newpos = pl->o;
pl->deltapos.sub(pl->newpos);
interppos(pl);
}
}
-bool bounce(physent *d, float elasticity, float grav)
-{
- if(physsteps <= 0)
- {
+bool bounce(physent *d, float elasticity, float grav) {
+ if(physsteps <= 0) {
interppos(d);
return false;
}
-
d->o = d->newpos;
bool hitplayer = false;
- loopi(physsteps-1)
- {
+ loopi(physsteps-1) {
if(bounce(d, physframetime/1000.0f, elasticity, grav)) hitplayer = true;
}
d->deltapos = d->o;
@@ -1743,8 +1471,7 @@ bool bounce(physent *d, float elasticity, float grav)
return hitplayer;
}
-void updatephysstate(physent *d)
-{
+void updatephysstate(physent *d) {
if(d->physstate == PHYS_FALL) return;
d->timeinair = 0;
vec old(d->o);
@@ -1752,8 +1479,7 @@ void updatephysstate(physent *d)
* May be inaccurate since movement collisions are not considered.
* If good floor is not found, just keep the old floor and hope it's correct enough.
*/
- switch(d->physstate)
- {
+ switch(d->physstate) {
case PHYS_SLOPE:
case PHYS_FLOOR:
case PHYS_STEP_DOWN:
@@ -1761,13 +1487,11 @@ void updatephysstate(physent *d)
if(collide(d, vec(0, 0, -1), d->physstate == PHYS_SLOPE || d->physstate == PHYS_STEP_DOWN ? SLOPEZ : FLOORZ))
d->floor = collidewall;
break;
-
case PHYS_STEP_UP:
d->o.z -= STAIRHEIGHT+0.15f;
if(collide(d, vec(0, 0, -1), SLOPEZ))
d->floor = collidewall;
break;
-
case PHYS_SLIDE:
d->o.z -= 0.15f;
if(collide(d, vec(0, 0, -1)) && collidewall.z < SLOPEZ)
@@ -1788,30 +1512,23 @@ dir(right, strafe, -1, k_right, k_left);
ICOMMAND(jump, "D", (int *down), { if(!*down || game::canjump()) player->jumping = *down!=0; });
ICOMMAND(attack, "D", (int *down), { game::doattack(*down!=0); });
-bool entinmap(dynent *d, bool avoidplayers) // brute force but effective way to find a free spawn spot in the map
-{
+bool entinmap(dynent *d, bool avoidplayers) { // brute force but effective way to find a free spawn spot in the map {
d->o.z += d->eyeheight; // pos specified is at feet
vec orig = d->o;
- loopi(100) // try max 100 times
- {
- if(i)
- {
+ loopi(100) { // try max 100 times {
+ if(i) {
d->o = orig;
d->o.x += (rnd(21)-10)*i/5; // increasing distance
d->o.y += (rnd(21)-10)*i/5;
d->o.z += (rnd(21)-10)*i/5;
}
-
- if(!collide(d) && !collideinside)
- {
- if(collideplayer)
- {
+ if(!collide(d) && !collideinside) {
+ if(collideplayer) {
if(!avoidplayers) continue;
d->o = orig;
d->resetinterp();
return false;
}
-
d->resetinterp();
return true;
}
diff --git a/src/engine/ragdoll.h b/src/engine/ragdoll.h
index 4dac48c..915076e 100644
--- a/src/engine/ragdoll.h
+++ b/src/engine/ragdoll.h
@@ -1,53 +1,36 @@
-struct ragdollskel
-{
- struct vert
- {
+struct ragdollskel {
+ struct vert {
vec pos;
float radius, weight;
};
-
- struct tri
- {
+ struct tri {
int vert[3];
-
- bool shareverts(const tri &t) const
- {
+ bool shareverts(const tri &t) const {
loopi(3) loopj(3) if(vert[i] == t.vert[j]) return true;
return false;
}
};
-
- struct distlimit
- {
+ struct distlimit {
int vert[2];
float mindist, maxdist;
};
-
- struct rotlimit
- {
+ struct rotlimit {
int tri[2];
float maxangle;
matrix3 middle;
};
-
- struct rotfriction
- {
+ struct rotfriction {
int tri[2];
matrix3 middle;
};
-
- struct joint
- {
+ struct joint {
int bone, tri, vert[3];
float weight;
matrix4x3 orient;
};
-
- struct reljoint
- {
+ struct reljoint {
int bone, parent;
};
-
bool loaded, animjoints;
int eye;
vector<vert> verts;
@@ -57,26 +40,20 @@ struct ragdollskel
vector<rotfriction> rotfrictions;
vector<joint> joints;
vector<reljoint> reljoints;
-
ragdollskel() : loaded(false), animjoints(false), eye(-1) {}
-
- void setupjoints()
- {
+ void setupjoints() {
loopv(verts) verts[i].weight = 0;
- loopv(joints)
- {
+ loopv(joints) {
joint &j = joints[i];
j.weight = 0;
vec pos(0, 0, 0);
- loopk(3) if(j.vert[k]>=0)
- {
+ loopk(3) if(j.vert[k]>=0) {
pos.add(verts[j.vert[k]].pos);
j.weight++;
verts[j.vert[k]].weight++;
}
if(j.weight) j.weight = 1/j.weight;
pos.mul(j.weight);
-
tri &t = tris[j.tri];
matrix4x3 &m = j.orient;
const vec &v1 = verts[t.vert[0]].pos,
@@ -91,45 +68,33 @@ struct ragdollskel
loopv(verts) if(verts[i].weight) verts[i].weight = 1/verts[i].weight;
reljoints.shrink(0);
}
-
- void setuprotfrictions()
- {
+ void setuprotfrictions() {
rotfrictions.shrink(0);
- loopv(tris) for(int j = i+1; j < tris.length(); j++) if(tris[i].shareverts(tris[j]))
- {
+ loopv(tris) for(int j = i+1; j < tris.length(); j++) if(tris[i].shareverts(tris[j])) {
rotfriction &r = rotfrictions.add();
r.tri[0] = i;
r.tri[1] = j;
}
}
-
- void setup()
- {
+ void setup() {
setupjoints();
setuprotfrictions();
-
loaded = true;
}
-
- void addreljoint(int bone, int parent)
- {
+ void addreljoint(int bone, int parent) {
reljoint &r = reljoints.add();
r.bone = bone;
r.parent = parent;
}
};
-struct ragdolldata
-{
- struct vert
- {
+struct ragdolldata {
+ struct vert {
vec oldpos, pos, newpos;
float weight;
bool collided, stuck;
-
vert() : pos(0, 0, 0), newpos(0, 0, 0), weight(0), collided(false), stuck(true) {}
};
-
ragdollskel *skel;
int millis, collidemillis, collisions, floating, lastmove, unsticks;
vec offset, center;
@@ -138,7 +103,6 @@ struct ragdolldata
matrix3 *tris;
matrix4x3 *animjoints;
dualquat *reljoints;
-
ragdolldata(ragdollskel *skel, float scale = 1)
: skel(skel),
millis(lastmillis),
@@ -153,26 +117,20 @@ struct ragdolldata
verts(new vert[skel->verts.length()]),
tris(new matrix3[skel->tris.length()]),
animjoints(!skel->animjoints || skel->joints.empty() ? NULL : new matrix4x3[skel->joints.length()]),
- reljoints(skel->reljoints.empty() ? NULL : new dualquat[skel->reljoints.length()])
- {
+ reljoints(skel->reljoints.empty() ? NULL : new dualquat[skel->reljoints.length()]) {
}
-
- ~ragdolldata()
- {
+ ~ragdolldata() {
delete[] verts;
delete[] tris;
if(animjoints) delete[] animjoints;
if(reljoints) delete[] reljoints;
}
-
- void calcanimjoint(int i, const matrix4x3 &anim)
- {
+ void calcanimjoint(int i, const matrix4x3 &anim) {
if(!animjoints) return;
ragdollskel::joint &j = skel->joints[i];
vec pos(0, 0, 0);
loopk(3) if(j.vert[k]>=0) pos.add(verts[j.vert[k]].pos);
pos.mul(j.weight);
-
ragdollskel::tri &t = skel->tris[j.tri];
matrix4x3 m;
const vec &v1 = verts[t.vert[0]].pos,
@@ -184,11 +142,8 @@ struct ragdolldata
m.d = pos;
animjoints[i].transposemul(m, anim);
}
-
- void calctris()
- {
- loopv(skel->tris)
- {
+ void calctris() {
+ loopv(skel->tris) {
ragdollskel::tri &t = skel->tris[i];
matrix3 &m = tris[i];
const vec &v1 = verts[t.vert[0]].pos,
@@ -199,30 +154,24 @@ struct ragdolldata
m.b.cross(m.c, m.a);
}
}
-
- void calcboundsphere()
- {
+ void calcboundsphere() {
center = vec(0, 0, 0);
loopv(skel->verts) center.add(verts[i].pos);
center.div(skel->verts.length());
radius = 0;
loopv(skel->verts) radius = max(radius, verts[i].pos.dist(center));
}
-
- void init(dynent *d)
- {
+ void init(dynent *d) {
extern int ragdolltimestepmin;
float ts = ragdolltimestepmin/1000.0f;
loopv(skel->verts) (verts[i].oldpos = verts[i].pos).sub(vec(d->vel).add(d->falling).mul(ts));
timestep = ts;
-
calctris();
calcboundsphere();
offset = d->o;
offset.sub(skel->eye >= 0 ? verts[skel->eye].pos : center);
offset.z += (d->eyeheight + d->aboveeye)/2;
}
-
void move(dynent *pl, float ts);
void updatepos();
void constrain();
@@ -232,13 +181,9 @@ struct ragdolldata
void calcrotfriction();
void applyrotfriction(float ts);
void tryunstick(float speed);
-
- static inline bool collidevert(const vec &pos, const vec &dir, float radius)
- {
- static struct vertent : physent
- {
- vertent()
- {
+ static inline bool collidevert(const vec &pos, const vec &dir, float radius) {
+ static struct vertent : physent {
+ vertent() {
type = ENT_BOUNCE;
radius = xradius = yradius = eyeheight = aboveeye = 1;
}
@@ -255,11 +200,9 @@ struct ragdolldata
parented transform = parent{invert(curtri) * origtrig} * (invert(parent{base2anim}) * base2anim)
*/
-void ragdolldata::constraindist()
-{
+void ragdolldata::constraindist() {
float invscale = 1.0f/scale;
- loopv(skel->distlimits)
- {
+ loopv(skel->distlimits) {
ragdollskel::distlimit &d = skel->distlimits[i];
vert &v1 = verts[d.vert[0]], &v2 = verts[d.vert[1]];
vec dir = vec(v2.pos).sub(v1.pos);
@@ -277,8 +220,7 @@ void ragdolldata::constraindist()
}
}
-inline void ragdolldata::applyrotlimit(ragdollskel::tri &t1, ragdollskel::tri &t2, float angle, const vec &axis)
-{
+inline void ragdolldata::applyrotlimit(ragdollskel::tri &t1, ragdollskel::tri &t2, float angle, const vec &axis) {
vert &v1a = verts[t1.vert[0]], &v1b = verts[t1.vert[1]], &v1c = verts[t1.vert[2]],
&v2a = verts[t2.vert[0]], &v2b = verts[t2.vert[1]], &v2c = verts[t2.vert[2]];
vec m1 = vec(v1a.pos).add(v1b.pos).add(v1c.pos).div(3),
@@ -308,22 +250,18 @@ inline void ragdolldata::applyrotlimit(ragdollskel::tri &t1, ragdollskel::tri &t
v2c.weight++;
}
-void ragdolldata::constrainrot()
-{
- loopv(skel->rotlimits)
- {
+void ragdolldata::constrainrot() {
+ loopv(skel->rotlimits) {
ragdollskel::rotlimit &r = skel->rotlimits[i];
matrix3 rot;
rot.mul(tris[r.tri[0]], r.middle);
rot.multranspose(tris[r.tri[1]]);
-
vec axis;
float angle;
if(!rot.calcangleaxis(angle, axis)) continue;
angle = r.maxangle - fabs(angle);
if(angle >= 0) continue;
angle += 1e-3f;
-
applyrotlimit(skel->tris[r.tri[0]], skel->tris[r.tri[1]], angle, axis);
}
}
@@ -333,36 +271,29 @@ VAR(ragdolltimestepmax, 1, 10, 50);
FVAR(ragdollrotfric, 0, 0.85f, 1);
FVAR(ragdollrotfricstop, 0, 0.1f, 1);
-void ragdolldata::calcrotfriction()
-{
- loopv(skel->rotfrictions)
- {
+void ragdolldata::calcrotfriction() {
+ loopv(skel->rotfrictions) {
ragdollskel::rotfriction &r = skel->rotfrictions[i];
r.middle.transposemul(tris[r.tri[0]], tris[r.tri[1]]);
}
}
-void ragdolldata::applyrotfriction(float ts)
-{
+void ragdolldata::applyrotfriction(float ts) {
calctris();
float stopangle = 2*M_PI*ts*ragdollrotfricstop, rotfric = 1.0f - pow(ragdollrotfric, ts*1000.0f/ragdolltimestepmin);
- loopv(skel->rotfrictions)
- {
+ loopv(skel->rotfrictions) {
ragdollskel::rotfriction &r = skel->rotfrictions[i];
matrix3 rot;
rot.mul(tris[r.tri[0]], r.middle);
rot.multranspose(tris[r.tri[1]]);
-
vec axis;
float angle;
- if(rot.calcangleaxis(angle, axis))
- {
+ if(rot.calcangleaxis(angle, axis)) {
angle *= -(fabs(angle) >= stopangle ? rotfric : 1.0f);
applyrotlimit(skel->tris[r.tri[0]], skel->tris[r.tri[1]], angle, axis);
}
}
- loopv(skel->verts)
- {
+ loopv(skel->verts) {
vert &v = verts[i];
if(v.weight) v.pos = v.newpos.div(v.weight);
v.newpos = vec(0, 0, 0);
@@ -370,15 +301,12 @@ void ragdolldata::applyrotfriction(float ts)
}
}
-void ragdolldata::tryunstick(float speed)
-{
+void ragdolldata::tryunstick(float speed) {
vec unstuck(0, 0, 0);
int stuck = 0;
- loopv(skel->verts)
- {
+ loopv(skel->verts) {
vert &v = verts[i];
- if(v.stuck)
- {
+ if(v.stuck) {
if(collidevert(v.pos, vec(0, 0, 0), skel->verts[i].radius)) { stuck++; continue; }
v.stuck = false;
}
@@ -387,28 +315,22 @@ void ragdolldata::tryunstick(float speed)
unsticks = 0;
if(!stuck || stuck >= skel->verts.length()) return;
unstuck.div(skel->verts.length() - stuck);
- loopv(skel->verts)
- {
+ loopv(skel->verts) {
vert &v = verts[i];
- if(v.stuck)
- {
+ if(v.stuck) {
v.pos.add(vec(unstuck).sub(v.pos).rescale(speed));
unsticks++;
}
}
}
-void ragdolldata::updatepos()
-{
- loopv(skel->verts)
- {
+void ragdolldata::updatepos() {
+ loopv(skel->verts) {
vert &v = verts[i];
- if(v.weight)
- {
+ if(v.weight) {
v.newpos.div(v.weight);
if(!collidevert(v.newpos, vec(v.newpos).sub(v.pos), skel->verts[i].radius)) v.pos = v.newpos;
- else
- {
+ else {
vec dir = vec(v.newpos).sub(v.oldpos);
if(dir.dot(collidewall) < 0) v.oldpos = vec(v.pos).sub(dir.reflect(collidewall));
v.collided = true;
@@ -421,13 +343,10 @@ void ragdolldata::updatepos()
VAR(ragdollconstrain, 1, 5, 100);
-void ragdolldata::constrain()
-{
- loopi(ragdollconstrain)
- {
+void ragdolldata::constrain() {
+ loopi(ragdollconstrain) {
constraindist();
updatepos();
-
calctris();
constrainrot();
updatepos();
@@ -441,19 +360,15 @@ FVAR(ragdollairfric, 0, 0.996f, 1);
FVAR(ragdollunstick, 0, 10, 1e3f);
VAR(ragdollexpireoffset, 0, 1500, 30000);
-void ragdolldata::move(dynent *pl, float ts)
-{
+void ragdolldata::move(dynent *pl, float ts) {
extern const float GRAVITY;
if(collidemillis && lastmillis > collidemillis) return;
-
pl->inwater = MAT_AIR;
-
calcrotfriction();
float tsfric = timestep ? ts/timestep : 1,
airfric = ragdollairfric + min((ragdollbodyfricscale*collisions)/skel->verts.length(), 1.0f)*(ragdollbodyfric - ragdollairfric);
collisions = 0;
- loopv(skel->verts)
- {
+ loopv(skel->verts) {
vert &v = verts[i];
vec dpos = vec(v.pos).sub(v.oldpos);
dpos.z -= GRAVITY*ts*ts;
@@ -462,30 +377,24 @@ void ragdolldata::move(dynent *pl, float ts)
v.pos.add(dpos);
}
applyrotfriction(ts);
- loopv(skel->verts)
- {
+ loopv(skel->verts) {
vert &v = verts[i];
if(v.pos.z < 0) { v.pos.z = 0; v.oldpos = v.pos; collisions++; }
vec dir = vec(v.pos).sub(v.oldpos);
v.collided = collidevert(v.pos, dir, skel->verts[i].radius);
- if(v.collided)
- {
+ if(v.collided) {
v.pos = v.oldpos;
v.oldpos.sub(dir.reflect(collidewall));
collisions++;
}
}
-
if(unsticks && ragdollunstick) tryunstick(ts*ragdollunstick);
-
timestep = ts;
- if(collisions)
- {
+ if(collisions) {
floating = 0;
if(!collidemillis) collidemillis = lastmillis + ragdollexpireoffset;
}
else if(++floating > 1 && lastmillis < collidemillis) collidemillis = 0;
-
constrain();
calctris();
calcboundsphere();
@@ -494,28 +403,22 @@ void ragdolldata::move(dynent *pl, float ts)
FVAR(ragdolleyesmooth, 0, 0.5f, 1);
VAR(ragdolleyesmoothmillis, 1, 250, 10000);
-void moveragdoll(dynent *d)
-{
+void moveragdoll(dynent *d) {
if(!curtime || !d->ragdoll) return;
-
- if(!d->ragdoll->collidemillis || lastmillis < d->ragdoll->collidemillis)
- {
+ if(!d->ragdoll->collidemillis || lastmillis < d->ragdoll->collidemillis) {
int lastmove = d->ragdoll->lastmove;
- while(d->ragdoll->lastmove + (lastmove == d->ragdoll->lastmove ? ragdolltimestepmin : ragdolltimestepmax) <= lastmillis)
- {
+ while(d->ragdoll->lastmove + (lastmove == d->ragdoll->lastmove ? ragdolltimestepmin : ragdolltimestepmax) <= lastmillis) {
int timestep = min(ragdolltimestepmax, lastmillis - d->ragdoll->lastmove);
d->ragdoll->move(d, timestep/1000.0f);
d->ragdoll->lastmove += timestep;
}
}
-
vec eye = d->ragdoll->skel->eye >= 0 ? d->ragdoll->verts[d->ragdoll->skel->eye].pos : d->ragdoll->center;
eye.add(d->ragdoll->offset);
float k = pow(ragdolleyesmooth, float(curtime)/ragdolleyesmoothmillis);
d->o.mul(k).add(eye.mul(1-k));
}
-void cleanragdoll(dynent *d)
-{
+void cleanragdoll(dynent *d) {
DELETEP(d->ragdoll);
}
diff --git a/src/engine/rendergl.cpp b/src/engine/rendergl.cpp
index 7489ff5..b8b28c5 100644
--- a/src/engine/rendergl.cpp
+++ b/src/engine/rendergl.cpp
@@ -143,8 +143,7 @@ PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays_ = NULL;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays_ = NULL;
PFNGLISVERTEXARRAYPROC glIsVertexArray_ = NULL;
-void *getprocaddress(const char *name)
-{
+void *getprocaddress(const char *name) {
return SDL_GL_GetProcAddress(name);
}
@@ -162,23 +161,18 @@ VAR(rtsharefb, 0, 1, 1);
hashset<const char *> glexts;
-void parseglexts()
-{
- if(glversion >= 300)
- {
+void parseglexts() {
+ if(glversion >= 300) {
GLint numexts = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &numexts);
- loopi(numexts)
- {
+ loopi(numexts) {
const char *ext = (const char *)glGetStringi_(GL_EXTENSIONS, i);
glexts.add(newstring(ext));
}
}
- else
- {
+ else {
const char *exts = (const char *)glGetString(GL_EXTENSIONS);
- for(;;)
- {
+ for(;;) {
while(*exts == ' ') exts++;
if(!*exts) break;
const char *ext = exts;
@@ -188,47 +182,35 @@ void parseglexts()
}
}
-bool hasext(const char *ext)
-{
+bool hasext(const char *ext) {
return glexts.access(ext)!=NULL;
}
-void gl_checkextensions()
-{
+void gl_checkextensions() {
const char *vendor = (const char *)glGetString(GL_VENDOR);
const char *renderer = (const char *)glGetString(GL_RENDERER);
const char *version = (const char *)glGetString(GL_VERSION);
conoutf(CON_INIT, "Renderer: %s (%s)", renderer, vendor);
conoutf(CON_INIT, "Driver: %s", version);
-
- bool mesa = false, intel = false, ati = false, nvidia = false;
- if(strstr(renderer, "Mesa") || strstr(version, "Mesa"))
- {
+ bool mesa = false, ati = false, nvidia = false;
+ if(strstr(renderer, "Mesa") || strstr(version, "Mesa")) {
mesa = true;
- if(strstr(renderer, "Intel")) intel = true;
}
else if(strstr(vendor, "NVIDIA"))
nvidia = true;
else if(strstr(vendor, "ATI") || strstr(vendor, "Advanced Micro Devices"))
ati = true;
- else if(strstr(vendor, "Intel"))
- intel = true;
-
uint glmajorversion, glminorversion;
if(sscanf(version, " %u.%u", &glmajorversion, &glminorversion) != 2) glversion = 100;
else glversion = glmajorversion*100 + glminorversion*10;
-
if(glversion < 200) fatal("OpenGL 2.0 or greater is required!");
-
glMultiDrawArrays_ = (PFNGLMULTIDRAWARRAYSPROC) getprocaddress("glMultiDrawArrays");
glMultiDrawElements_ = (PFNGLMULTIDRAWELEMENTSPROC) getprocaddress("glMultiDrawElements");
-
glBlendFuncSeparate_ = (PFNGLBLENDFUNCSEPARATEPROC) getprocaddress("glBlendFuncSeparate");
glBlendEquationSeparate_ = (PFNGLBLENDEQUATIONSEPARATEPROC) getprocaddress("glBlendEquationSeparate");
glStencilOpSeparate_ = (PFNGLSTENCILOPSEPARATEPROC) getprocaddress("glStencilOpSeparate");
glStencilFuncSeparate_ = (PFNGLSTENCILFUNCSEPARATEPROC) getprocaddress("glStencilFuncSeparate");
glStencilMaskSeparate_ = (PFNGLSTENCILMASKSEPARATEPROC) getprocaddress("glStencilMaskSeparate");
-
glGenBuffers_ = (PFNGLGENBUFFERSPROC) getprocaddress("glGenBuffers");
glBindBuffer_ = (PFNGLBINDBUFFERPROC) getprocaddress("glBindBuffer");
glMapBuffer_ = (PFNGLMAPBUFFERPROC) getprocaddress("glMapBuffer");
@@ -237,7 +219,6 @@ void gl_checkextensions()
glBufferSubData_ = (PFNGLBUFFERSUBDATAPROC) getprocaddress("glBufferSubData");
glDeleteBuffers_ = (PFNGLDELETEBUFFERSPROC) getprocaddress("glDeleteBuffers");
glGetBufferSubData_ = (PFNGLGETBUFFERSUBDATAPROC) getprocaddress("glGetBufferSubData");
-
glGetQueryiv_ = (PFNGLGETQUERYIVPROC) getprocaddress("glGetQueryiv");
glGenQueries_ = (PFNGLGENQUERIESPROC) getprocaddress("glGenQueries");
glDeleteQueries_ = (PFNGLDELETEQUERIESPROC) getprocaddress("glDeleteQueries");
@@ -245,7 +226,6 @@ void gl_checkextensions()
glEndQuery_ = (PFNGLENDQUERYPROC) getprocaddress("glEndQuery");
glGetQueryObjectiv_ = (PFNGLGETQUERYOBJECTIVPROC) getprocaddress("glGetQueryObjectiv");
glGetQueryObjectuiv_ = (PFNGLGETQUERYOBJECTUIVPROC) getprocaddress("glGetQueryObjectuiv");
-
glCreateProgram_ = (PFNGLCREATEPROGRAMPROC) getprocaddress("glCreateProgram");
glDeleteProgram_ = (PFNGLDELETEPROGRAMPROC) getprocaddress("glDeleteProgram");
glUseProgram_ = (PFNGLUSEPROGRAMPROC) getprocaddress("glUseProgram");
@@ -283,7 +263,6 @@ void gl_checkextensions()
glGetActiveUniform_ = (PFNGLGETACTIVEUNIFORMPROC) getprocaddress("glGetActiveUniform");
glEnableVertexAttribArray_ = (PFNGLENABLEVERTEXATTRIBARRAYPROC) getprocaddress("glEnableVertexAttribArray");
glDisableVertexAttribArray_ = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) getprocaddress("glDisableVertexAttribArray");
-
glVertexAttrib1f_ = (PFNGLVERTEXATTRIB1FPROC) getprocaddress("glVertexAttrib1f");
glVertexAttrib1fv_ = (PFNGLVERTEXATTRIB1FVPROC) getprocaddress("glVertexAttrib1fv");
glVertexAttrib1s_ = (PFNGLVERTEXATTRIB1SPROC) getprocaddress("glVertexAttrib1s");
@@ -312,44 +291,31 @@ void gl_checkextensions()
glVertexAttrib4Nuiv_ = (PFNGLVERTEXATTRIB4NUIVPROC) getprocaddress("glVertexAttrib4Nuiv");
glVertexAttrib4Nusv_ = (PFNGLVERTEXATTRIB4NUSVPROC) getprocaddress("glVertexAttrib4Nusv");
glVertexAttribPointer_ = (PFNGLVERTEXATTRIBPOINTERPROC) getprocaddress("glVertexAttribPointer");
-
glDrawBuffers_ = (PFNGLDRAWBUFFERSPROC) getprocaddress("glDrawBuffers");
-
- if(glversion >= 300)
- {
+ if(glversion >= 300) {
glGetStringi_ = (PFNGLGETSTRINGIPROC) getprocaddress("glGetStringi");
glBindFragDataLocation_ = (PFNGLBINDFRAGDATALOCATIONPROC)getprocaddress("glBindFragDataLocation");
}
-
const char *glslstr = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
uint glslmajorversion, glslminorversion;
if(glslstr && sscanf(glslstr, " %u.%u", &glslmajorversion, &glslminorversion) == 2) glslversion = glslmajorversion*100 + glslminorversion;
-
if(glslversion < 120) fatal("GLSL 1.20 or greater is required!");
-
parseglexts();
-
GLint val;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &val);
hwtexsize = val;
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &val);
hwcubetexsize = val;
-
- if(glversion >= 300 || hasext("GL_ARB_texture_float") || hasext("GL_ATI_texture_float"))
- {
+ if(glversion >= 300 || hasext("GL_ARB_texture_float") || hasext("GL_ATI_texture_float")) {
hasTF = true;
shadowmap = 1;
extern int smoothshadowmappeel;
smoothshadowmappeel = 1;
}
-
- if(glversion >= 300 || hasext("GL_ARB_texture_rg"))
- {
+ if(glversion >= 300 || hasext("GL_ARB_texture_rg")) {
hasTRG = true;
}
-
- if(glversion >= 300 || hasext("GL_ARB_framebuffer_object"))
- {
+ if(glversion >= 300 || hasext("GL_ARB_framebuffer_object")) {
glBindRenderbuffer_ = (PFNGLBINDRENDERBUFFERPROC) getprocaddress("glBindRenderbuffer");
glDeleteRenderbuffers_ = (PFNGLDELETERENDERBUFFERSPROC) getprocaddress("glDeleteRenderbuffers");
glGenRenderbuffers_ = (PFNGLGENFRAMEBUFFERSPROC) getprocaddress("glGenRenderbuffers");
@@ -364,8 +330,7 @@ void gl_checkextensions()
glBlitFramebuffer_ = (PFNGLBLITFRAMEBUFFERPROC) getprocaddress("glBlitFramebuffer");
hasAFBO = hasFBO = hasFBB = hasDS = true;
}
- else if(hasext("GL_EXT_framebuffer_object"))
- {
+ else if(hasext("GL_EXT_framebuffer_object")) {
glBindRenderbuffer_ = (PFNGLBINDRENDERBUFFERPROC) getprocaddress("glBindRenderbufferEXT");
glDeleteRenderbuffers_ = (PFNGLDELETERENDERBUFFERSPROC) getprocaddress("glDeleteRenderbuffersEXT");
glGenRenderbuffers_ = (PFNGLGENFRAMEBUFFERSPROC) getprocaddress("glGenRenderbuffersEXT");
@@ -378,49 +343,36 @@ void gl_checkextensions()
glFramebufferRenderbuffer_ = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)getprocaddress("glFramebufferRenderbufferEXT");
glGenerateMipmap_ = (PFNGLGENERATEMIPMAPPROC) getprocaddress("glGenerateMipmapEXT");
hasFBO = true;
-
- if(hasext("GL_EXT_framebuffer_blit"))
- {
+ if(hasext("GL_EXT_framebuffer_blit")) {
glBlitFramebuffer_ = (PFNGLBLITFRAMEBUFFERPROC) getprocaddress("glBlitFramebufferEXT");
hasFBB = true;
}
-
- if(hasext("GL_EXT_packed_depth_stencil") || hasext("GL_NV_packed_depth_stencil"))
- {
+ if(hasext("GL_EXT_packed_depth_stencil") || hasext("GL_NV_packed_depth_stencil")) {
hasDS = true;
}
}
else fatal("Framebuffer object support is required!");
-
- if(ati)
- {
+ if(ati) {
minimizetcusage = 1;
// On Catalyst 10.2, issuing an occlusion query on the first draw using a given cubemap texture causes a nasty crash
ati_cubemap_bug = 1;
}
- else if(nvidia)
- {
+ else if(nvidia) {
reservevpparams = 10;
rtsharefb = 0; // work-around for strange driver stalls involving when using many FBOs
extern int filltjoints;
if(glversion < 300 && !hasext("GL_EXT_gpu_shader4")) filltjoints = 0; // DX9 or less NV cards seem to not cause many sparklies
}
- else
- {
+ else {
reservevpparams = 20;
-
if(mesa) mesa_swap_bug = 1;
}
-
- if(glversion >= 300 || hasext("GL_ARB_map_buffer_range"))
- {
+ if(glversion >= 300 || hasext("GL_ARB_map_buffer_range")) {
glMapBufferRange_ = (PFNGLMAPBUFFERRANGEPROC) getprocaddress("glMapBufferRange");
glFlushMappedBufferRange_ = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)getprocaddress("glFlushMappedBufferRange");
hasMBR = true;
}
-
- if(glversion >= 310 || hasext("GL_ARB_uniform_buffer_object"))
- {
+ if(glversion >= 310 || hasext("GL_ARB_uniform_buffer_object")) {
glGetUniformIndices_ = (PFNGLGETUNIFORMINDICESPROC) getprocaddress("glGetUniformIndices");
glGetActiveUniformsiv_ = (PFNGLGETACTIVEUNIFORMSIVPROC) getprocaddress("glGetActiveUniformsiv");
glGetUniformBlockIndex_ = (PFNGLGETUNIFORMBLOCKINDEXPROC) getprocaddress("glGetUniformBlockIndex");
@@ -428,66 +380,50 @@ void gl_checkextensions()
glUniformBlockBinding_ = (PFNGLUNIFORMBLOCKBINDINGPROC) getprocaddress("glUniformBlockBinding");
glBindBufferBase_ = (PFNGLBINDBUFFERBASEPROC) getprocaddress("glBindBufferBase");
glBindBufferRange_ = (PFNGLBINDBUFFERRANGEPROC) getprocaddress("glBindBufferRange");
-
useubo = 1;
hasUBO = true;
}
-
- if(glversion >= 300 || hasext("GL_ARB_vertex_array_object"))
- {
+ if(glversion >= 300 || hasext("GL_ARB_vertex_array_object")) {
glBindVertexArray_ = (PFNGLBINDVERTEXARRAYPROC) getprocaddress("glBindVertexArray");
glDeleteVertexArrays_ = (PFNGLDELETEVERTEXARRAYSPROC)getprocaddress("glDeleteVertexArrays");
glGenVertexArrays_ = (PFNGLGENVERTEXARRAYSPROC) getprocaddress("glGenVertexArrays");
glIsVertexArray_ = (PFNGLISVERTEXARRAYPROC) getprocaddress("glIsVertexArray");
hasVAO = true;
}
- else if(hasext("GL_APPLE_vertex_array_object"))
- {
+ else if(hasext("GL_APPLE_vertex_array_object")) {
glBindVertexArray_ = (PFNGLBINDVERTEXARRAYPROC) getprocaddress("glBindVertexArrayAPPLE");
glDeleteVertexArrays_ = (PFNGLDELETEVERTEXARRAYSPROC)getprocaddress("glDeleteVertexArraysAPPLE");
glGenVertexArrays_ = (PFNGLGENVERTEXARRAYSPROC) getprocaddress("glGenVertexArraysAPPLE");
glIsVertexArray_ = (PFNGLISVERTEXARRAYPROC) getprocaddress("glIsVertexArrayAPPLE");
hasVAO = true;
}
-
- if(glversion >= 330 || hasext("GL_ARB_texture_swizzle") || hasext("GL_EXT_texture_swizzle"))
- {
+ if(glversion >= 330 || hasext("GL_ARB_texture_swizzle") || hasext("GL_EXT_texture_swizzle")) {
hasTSW = true;
}
-
- if(hasext("GL_EXT_texture_compression_s3tc"))
- {
+ if(hasext("GL_EXT_texture_compression_s3tc")) {
hasS3TC = true;
if(!mesa) usetexcompress = 2;
}
- else if(hasext("GL_EXT_texture_compression_dxt1") && hasext("GL_ANGLE_texture_compression_dxt3") && hasext("GL_ANGLE_texture_compression_dxt5"))
- {
+ else if(hasext("GL_EXT_texture_compression_dxt1") && hasext("GL_ANGLE_texture_compression_dxt3") && hasext("GL_ANGLE_texture_compression_dxt5")) {
hasS3TC = true;
}
- if(hasext("GL_3DFX_texture_compression_FXT1"))
- {
+ if(hasext("GL_3DFX_texture_compression_FXT1")) {
hasFXT1 = true;
if(mesa) usetexcompress = max(usetexcompress, 1);
}
- if(hasext("GL_EXT_texture_compression_latc"))
- {
+ if(hasext("GL_EXT_texture_compression_latc")) {
hasLATC = true;
}
- if(glversion >= 300 || hasext("GL_ARB_texture_compression_rgtc") || hasext("GL_EXT_texture_compression_rgtc"))
- {
+ if(glversion >= 300 || hasext("GL_ARB_texture_compression_rgtc") || hasext("GL_EXT_texture_compression_rgtc")) {
hasRGTC = true;
}
-
- if(hasext("GL_EXT_texture_filter_anisotropic"))
- {
+ if(hasext("GL_EXT_texture_filter_anisotropic")) {
GLint val;
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &val);
hwmaxaniso = val;
hasAF = true;
}
-
- if(glversion >= 300 || hasext("GL_EXT_gpu_shader4"))
- {
+ if(glversion >= 300 || hasext("GL_EXT_gpu_shader4")) {
// on DX10 or above class cards (i.e. GF8 or RadeonHD) enable expensive features
extern int maxdynlights, texcompress;
maxdynlights = MAXDYNLIGHTS;
@@ -495,37 +431,28 @@ void gl_checkextensions()
}
}
-void glext(char *ext)
-{
+void glext(char *ext) {
intret(hasext(ext) ? 1 : 0);
}
COMMAND(glext, "s");
-void gl_resize()
-{
+void gl_resize() {
glViewport(0, 0, screenw, screenh);
}
-void gl_init()
-{
+void gl_init() {
glClearColor(0, 0, 0, 0);
glClearDepth(1);
glDepthFunc(GL_LESS);
glDisable(GL_DEPTH_TEST);
-
glEnable(GL_LINE_SMOOTH);
//glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
-
glFrontFace(GL_CW);
glCullFace(GL_BACK);
glDisable(GL_CULL_FACE);
-
gle::setup();
-
setupshaders();
-
setuptexcompress();
-
gl_resize();
}
@@ -534,95 +461,76 @@ VAR(wireframe, 0, 0, 1);
ICOMMAND(getcamyaw, "", (), floatret(camera1->yaw));
ICOMMAND(getcampitch, "", (), floatret(camera1->pitch));
ICOMMAND(getcamroll, "", (), floatret(camera1->roll));
-ICOMMAND(getcampos, "", (),
-{
+ICOMMAND(getcampos, "", (), {
defformatstring(pos, "%s %s %s", floatstr(camera1->o.x), floatstr(camera1->o.y), floatstr(camera1->o.z));
result(pos);
});
vec worldpos, camdir, camright, camup;
-void setcammatrix()
-{
+void setcammatrix() {
// move from RH to Z-up LH quake style worldspace
cammatrix = viewmatrix;
cammatrix.rotate_around_y(camera1->roll*RAD);
cammatrix.rotate_around_x(camera1->pitch*-RAD);
cammatrix.rotate_around_z(camera1->yaw*-RAD);
cammatrix.translate(vec(camera1->o).neg());
-
cammatrix.transposedtransformnormal(vec(viewmatrix.b), camdir);
cammatrix.transposedtransformnormal(vec(viewmatrix.a).neg(), camright);
cammatrix.transposedtransformnormal(vec(viewmatrix.c), camup);
-
- if(!drawtex)
- {
+ if(!drawtex) {
if(raycubepos(camera1->o, camdir, worldpos, 0, RAY_CLIPMAT|RAY_SKIPFIRST) == -1)
worldpos = vec(camdir).mul(2*worldsize).add(camera1->o); // if nothing is hit, just far away in the view direction
}
}
-void setcamprojmatrix(bool init = true, bool flush = false)
-{
- if(init)
- {
+void setcamprojmatrix(bool init = true, bool flush = false) {
+ if(init) {
setcammatrix();
}
-
camprojmatrix.muld(projmatrix, cammatrix);
-
- if(init)
- {
+ if(init) {
invcammatrix.invert(cammatrix);
invcamprojmatrix.invert(camprojmatrix);
}
-
GLOBALPARAM(camprojmatrix, camprojmatrix);
-
if(flush && Shader::lastshader) Shader::lastshader->flushparams();
}
matrix4 hudmatrix, hudmatrixstack[64];
int hudmatrixpos = 0;
-void resethudmatrix()
-{
+void resethudmatrix() {
hudmatrixpos = 0;
GLOBALPARAM(hudmatrix, hudmatrix);
}
-void pushhudmatrix()
-{
+void pushhudmatrix() {
if(hudmatrixpos >= 0 && hudmatrixpos < int(sizeof(hudmatrixstack)/sizeof(hudmatrixstack[0]))) hudmatrixstack[hudmatrixpos] = hudmatrix;
++hudmatrixpos;
}
-void flushhudmatrix(bool flushparams)
-{
+void flushhudmatrix(bool flushparams) {
GLOBALPARAM(hudmatrix, hudmatrix);
if(flushparams && Shader::lastshader) Shader::lastshader->flushparams();
}
-void pophudmatrix(bool flush, bool flushparams)
-{
+void pophudmatrix(bool flush, bool flushparams) {
--hudmatrixpos;
- if(hudmatrixpos >= 0 && hudmatrixpos < int(sizeof(hudmatrixstack)/sizeof(hudmatrixstack[0])))
- {
+ if(hudmatrixpos >= 0 && hudmatrixpos < int(sizeof(hudmatrixstack)/sizeof(hudmatrixstack[0]))) {
hudmatrix = hudmatrixstack[hudmatrixpos];
if(flush) flushhudmatrix(flushparams);
}
}
-void pushhudscale(float sx, float sy)
-{
+void pushhudscale(float sx, float sy) {
if(!sy) sy = sx;
pushhudmatrix();
hudmatrix.scale(sx, sy, 1);
flushhudmatrix();
}
-void pushhudtranslate(float tx, float ty, float sx, float sy)
-{
+void pushhudtranslate(float tx, float ty, float sx, float sy) {
if(!sy) sy = sx;
pushhudmatrix();
hudmatrix.translate(tx, ty, 0);
@@ -644,18 +552,15 @@ FVARNP(aspect, forceaspect, 0, 0, 1e3f);
static float zoomprogress = 0;
VAR(zoom, -1, 0, 1);
-void disablezoom()
-{
+void disablezoom() {
zoom = 0;
zoomprogress = 0;
}
-void computezoom()
-{
+void computezoom() {
if(!zoom) { zoomprogress = 0; curfov = fov; curavatarfov = avatarfov; return; }
if(zoom > 0) zoomprogress = zoominvel ? min(zoomprogress + float(elapsedtime) / zoominvel, 1.0f) : 1;
- else
- {
+ else {
zoomprogress = zoomoutvel ? max(zoomprogress - float(elapsedtime) / zoomoutvel, 0.0f) : 0;
if(zoomprogress <= 0) zoom = 0;
}
@@ -679,8 +584,7 @@ physent *camera1 = NULL;
bool detachedcamera = false;
bool isthirdperson() { return player!=camera1 || detachedcamera; }
-void fixcamerarange()
-{
+void fixcamerarange() {
const float MAXPITCH = 90.0f;
if(camera1->pitch>MAXPITCH) camera1->pitch = MAXPITCH;
if(camera1->pitch<-MAXPITCH) camera1->pitch = -MAXPITCH;
@@ -688,19 +592,15 @@ void fixcamerarange()
while(camera1->yaw>=360.0f) camera1->yaw -= 360.0f;
}
-void mousemove(int dx, int dy)
-{
+void mousemove(int dx, int dy) {
if(!game::allowmouselook()) return;
float cursens = sensitivity, curaccel = mouseaccel;
- if(zoom)
- {
- if(zoomautosens)
- {
+ if(zoom) {
+ if(zoomautosens) {
cursens = float(sensitivity*zoomfov)/fov;
curaccel = float(mouseaccel*zoomfov)/fov;
}
- else
- {
+ else {
cursens = zoomsens;
curaccel = zoomaccel;
}
@@ -710,33 +610,27 @@ void mousemove(int dx, int dy)
camera1->yaw += dx*cursens;
camera1->pitch -= dy*cursens*(invmouse ? -1 : 1);
fixcamerarange();
- if(camera1!=player && !detachedcamera)
- {
+ if(camera1!=player && !detachedcamera) {
player->yaw = camera1->yaw;
player->pitch = camera1->pitch;
}
speedmodifier += abs(dx)-abs(dy);
}
-void recomputecamera()
-{
+void recomputecamera() {
game::setupcamera();
computezoom();
-
bool allowthirdperson = game::allowthirdperson();
bool shoulddetach = (allowthirdperson && thirdperson > 1) || game::detachcamera();
- if((!allowthirdperson || !thirdperson) && !shoulddetach)
- {
+ if((!allowthirdperson || !thirdperson) && !shoulddetach) {
camera1 = player;
detachedcamera = false;
}
- else
- {
+ else {
static physent tempcamera;
camera1 = &tempcamera;
if(detachedcamera && shoulddetach) camera1->o = player->o;
- else
- {
+ else {
*camera1 = *player;
detachedcamera = shoulddetach;
}
@@ -744,28 +638,23 @@ void recomputecamera()
camera1->type = ENT_CAMERA;
camera1->move = -1;
camera1->eyeheight = camera1->aboveeye = camera1->radius = camera1->xradius = camera1->yradius = 2;
-
matrix3 orient;
orient.identity();
orient.rotate_around_z(camera1->yaw*RAD);
orient.rotate_around_x(camera1->pitch*RAD);
orient.rotate_around_y(camera1->roll*-RAD);
vec dir = vec(orient.b).neg(), side = vec(orient.a).neg(), up = orient.c;
-
- if(game::collidecamera())
- {
+ if(game::collidecamera()) {
movecamera(camera1, dir, thirdpersondistance, 1);
movecamera(camera1, dir, clamp(thirdpersondistance - camera1->o.dist(player->o), 0.0f, 1.0f), 0.1f);
- if(thirdpersonup)
- {
+ if(thirdpersonup) {
vec pos = camera1->o;
float dist = fabs(thirdpersonup);
if(thirdpersonup < 0) up.neg();
movecamera(camera1, up, dist, 1);
movecamera(camera1, up, clamp(dist - camera1->o.dist(pos), 0.0f, 1.0f), 0.1f);
}
- if(thirdpersonside)
- {
+ if(thirdpersonside) {
vec pos = camera1->o;
float dist = fabs(thirdpersonside);
if(thirdpersonside < 0) side.neg();
@@ -773,8 +662,7 @@ void recomputecamera()
movecamera(camera1, side, clamp(dist - camera1->o.dist(pos), 0.0f, 1.0f), 0.1f);
}
}
- else
- {
+ else {
camera1->o.add(vec(dir).mul(thirdpersondistance));
if(thirdpersonup) camera1->o.add(vec(up).mul(thirdpersonup));
if(thirdpersonside) camera1->o.add(vec(side).mul(thirdpersonside));
@@ -787,8 +675,7 @@ matrix4 cammatrix, projmatrix, camprojmatrix, invcammatrix, invcamprojmatrix;
FVAR(nearplane, 0.01f, 0.54f, 2.0f);
-vec calcavatarpos(const vec &pos, float dist)
-{
+vec calcavatarpos(const vec &pos, float dist) {
vec eyepos;
cammatrix.transform(pos, eyepos);
GLdouble ydist = nearplane * tan(curavatarfov/2*RAD), xdist = ydist * aspect;
@@ -797,7 +684,6 @@ vec calcavatarpos(const vec &pos, float dist)
scrpos.y = eyepos.y*nearplane/ydist;
scrpos.z = (eyepos.z*(farplane + nearplane) - 2*nearplane*farplane) / (farplane - nearplane);
scrpos.w = -eyepos.z;
-
vec worldpos = invcamprojmatrix.perspectivetransform(scrpos);
vec dir = vec(worldpos).sub(camera1->o).rescale(dist);
return dir.add(camera1->o);
@@ -805,17 +691,13 @@ vec calcavatarpos(const vec &pos, float dist)
matrix4 clipmatrix, noclipmatrix;
-void renderavatar()
-{
+void renderavatar() {
if(isthirdperson()) return;
-
matrix4 oldprojmatrix = projmatrix;
projmatrix.perspective(curavatarfov, aspect, nearplane, farplane);
projmatrix.scalez(avatardepth);
setcamprojmatrix(false);
-
game::renderavatar();
-
projmatrix = oldprojmatrix;
setcamprojmatrix(false);
}
@@ -826,36 +708,28 @@ FVAR(depthoffset, -1e4f, 0.01f, 1e4f);
matrix4 nooffsetmatrix;
-void enablepolygonoffset(GLenum type)
-{
- if(!depthoffset)
- {
+void enablepolygonoffset(GLenum type) {
+ if(!depthoffset) {
glPolygonOffset(polygonoffsetfactor, polygonoffsetunits);
glEnable(type);
return;
}
-
bool clipped = false;
-
nooffsetmatrix = projmatrix;
projmatrix.d.z += depthoffset * (clipped ? noclipmatrix.c.z : projmatrix.c.z);
setcamprojmatrix(false, true);
}
-void disablepolygonoffset(GLenum type)
-{
- if(!depthoffset)
- {
+void disablepolygonoffset(GLenum type) {
+ if(!depthoffset) {
glDisable(type);
return;
}
-
projmatrix = nooffsetmatrix;
setcamprojmatrix(false, true);
}
-void calcspherescissor(const vec &center, float size, float &sx1, float &sy1, float &sx2, float &sy2)
-{
+void calcspherescissor(const vec &center, float size, float &sx1, float &sy1, float &sx2, float &sy2) {
vec worldpos(center), e;
cammatrix.transform(worldpos, e);
if(e.z > 2*size) { sx1 = sy1 = 1; sx2 = sy2 = -1; return; }
@@ -868,22 +742,20 @@ void calcspherescissor(const vec &center, float size, float &sx1, float &sy1, fl
do { \
float nzc = (cz*cz + 1) / (cz dir drt) - cz, \
pz = (d##c)/(nzc*e.c - e.z); \
- if(pz > 0) \
- { \
+ if(pz > 0) { \
+ \
float c = (focaldist)*nzc, \
pc = pz*nzc; \
if(pc < e.c) low = c; \
else if(pc > e.c) high = c; \
} \
} while(0)
- if(dx > 0)
- {
+ if(dx > 0) {
float cz = e.x/e.z, drt = sqrtf(dx)/size;
CHECKPLANE(x, -, focaldist/aspect, sx1, sx2);
CHECKPLANE(x, +, focaldist/aspect, sx1, sx2);
}
- if(dy > 0)
- {
+ if(dy > 0) {
float cz = e.y/e.z, drt = sqrtf(dy)/size;
CHECKPLANE(y, -, focaldist, sy1, sy2);
CHECKPLANE(y, +, focaldist, sy1, sy2);
@@ -893,17 +765,13 @@ void calcspherescissor(const vec &center, float size, float &sx1, float &sy1, fl
static int scissoring = 0;
static GLint oldscissor[4];
-int pushscissor(float sx1, float sy1, float sx2, float sy2)
-{
+int pushscissor(float sx1, float sy1, float sx2, float sy2) {
scissoring = 0;
-
if(sx1 <= -1 && sy1 <= -1 && sx2 >= 1 && sy2 >= 1) return 0;
-
sx1 = max(sx1, -1.0f);
sy1 = max(sy1, -1.0f);
sx2 = min(sx2, 1.0f);
sy2 = min(sy2, 1.0f);
-
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
int sx = viewport[0] + int(floor((sx1+1)*0.5f*viewport[2])),
@@ -911,9 +779,7 @@ int pushscissor(float sx1, float sy1, float sx2, float sy2)
sw = viewport[0] + int(ceil((sx2+1)*0.5f*viewport[2])) - sx,
sh = viewport[1] + int(ceil((sy2+1)*0.5f*viewport[3])) - sy;
if(sw <= 0 || sh <= 0) return 0;
-
- if(glIsEnabled(GL_SCISSOR_TEST))
- {
+ if(glIsEnabled(GL_SCISSOR_TEST)) {
glGetIntegerv(GL_SCISSOR_BOX, oldscissor);
sw += sx;
sh += sy;
@@ -925,15 +791,12 @@ int pushscissor(float sx1, float sy1, float sx2, float sy2)
scissoring = 2;
}
else scissoring = 1;
-
glScissor(sx, sy, sw, sh);
if(scissoring<=1) glEnable(GL_SCISSOR_TEST);
-
return scissoring;
}
-void popscissor()
-{
+void popscissor() {
if(scissoring>1) glScissor(oldscissor[0], oldscissor[1], oldscissor[2], oldscissor[3]);
else if(scissoring) glDisable(GL_SCISSOR_TEST);
scissoring = 0;
@@ -941,10 +804,8 @@ void popscissor()
static GLuint screenquadvbo = 0;
-static void setupscreenquad()
-{
- if(!screenquadvbo)
- {
+static void setupscreenquad() {
+ if(!screenquadvbo) {
glGenBuffers_(1, &screenquadvbo);
gle::bindvbo(screenquadvbo);
vec2 verts[4] = { vec2(1, -1), vec2(-1, -1), vec2(1, 1), vec2(-1, 1) };
@@ -953,13 +814,11 @@ static void setupscreenquad()
}
}
-static void cleanupscreenquad()
-{
+static void cleanupscreenquad() {
if(screenquadvbo) { glDeleteBuffers_(1, &screenquadvbo); screenquadvbo = 0; }
}
-void screenquad()
-{
+void screenquad() {
setupscreenquad();
gle::bindvbo(screenquadvbo);
gle::enablevertex();
@@ -971,38 +830,32 @@ void screenquad()
static LocalShaderParam screentexcoord[2] = { LocalShaderParam("screentexcoord0"), LocalShaderParam("screentexcoord1") };
-static inline void setscreentexcoord(int i, float w, float h, float x = 0, float y = 0)
-{
+static inline void setscreentexcoord(int i, float w, float h, float x = 0, float y = 0) {
screentexcoord[i].setf(w*0.5f, h*0.5f, x + w*0.5f, y + fabs(h)*0.5f);
}
-void screenquad(float sw, float sh)
-{
+void screenquad(float sw, float sh) {
setscreentexcoord(0, sw, sh);
screenquad();
}
-void screenquadflipped(float sw, float sh)
-{
+void screenquadflipped(float sw, float sh) {
setscreentexcoord(0, sw, -sh);
screenquad();
}
-void screenquad(float sw, float sh, float sw2, float sh2)
-{
+void screenquad(float sw, float sh, float sw2, float sh2) {
setscreentexcoord(0, sw, sh);
setscreentexcoord(1, sw2, sh2);
screenquad();
}
-void screenquadoffset(float x, float y, float w, float h)
-{
+void screenquadoffset(float x, float y, float w, float h) {
setscreentexcoord(0, w, h, x, y);
screenquad();
}
-void screenquadoffset(float x, float y, float w, float h, float x2, float y2, float w2, float h2)
-{
+void screenquadoffset(float x, float y, float w, float h, float x2, float y2, float w2, float h2) {
setscreentexcoord(0, w, h, x, y);
setscreentexcoord(1, w2, h2, x2, y2);
screenquad();
@@ -1019,15 +872,13 @@ void screenquadoffset(float x, float y, float w, float h, float x2, float y2, fl
gle::end(); \
}
-void hudquad(float x, float y, float w, float h, float tx, float ty, float tw, float th)
-{
+void hudquad(float x, float y, float w, float h, float tx, float ty, float tw, float th) {
HUDQUAD(x, y, x+w, y+h, tx, ty, tx+tw, ty+th);
}
bool renderedgame = false;
-void rendergame(bool mainpass)
-{
+void rendergame(bool mainpass) {
game::rendergame(mainpass);
if(!shadowmapping) renderedgame = true;
}
@@ -1037,23 +888,17 @@ int drawtex = 0;
VAR(modelpreviewfov, 10, 20, 100);
VAR(modelpreviewpitch, -90, -15, 90);
-namespace modelpreview
-{
+namespace modelpreview {
physent *oldcamera;
physent camera;
-
float oldaspect, oldfovy, oldfov;
int oldfarplane;
matrix4 oldprojmatrix;
-
- void start(int x, int y, int w, int h, bool background)
- {
+ void start(int x, int y, int w, int h, bool background) {
drawtex = DRAWTEX_MODELPREVIEW;
-
glViewport(x, y, w, h);
glScissor(x, y, w, h);
glEnable(GL_SCISSOR_TEST);
-
oldcamera = camera1;
camera = *camera1;
camera.reset();
@@ -1063,52 +908,39 @@ namespace modelpreview
camera.pitch = modelpreviewpitch;
camera.roll = 0;
camera1 = &camera;
-
oldaspect = aspect;
oldfovy = fovy;
oldfov = curfov;
oldfarplane = farplane;
oldprojmatrix = projmatrix;
-
aspect = w/float(h);
fovy = modelpreviewfov;
curfov = 2*atan2(tan(fovy/2*RAD), 1/aspect)/RAD;
farplane = 1024;
-
glClearColor(0, 0, 0, 1);
-
glClear((background ? GL_COLOR_BUFFER_BIT : 0) | GL_DEPTH_BUFFER_BIT);
-
projmatrix.perspective(fovy, aspect, nearplane, farplane);
setcamprojmatrix();
-
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
}
-
- void end()
- {
+ void end() {
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
-
aspect = oldaspect;
fovy = oldfovy;
curfov = oldfov;
farplane = oldfarplane;
-
camera1 = oldcamera;
drawtex = 0;
-
glDisable(GL_SCISSOR_TEST);
glViewport(0, 0, screenw, screenh);
-
projmatrix = oldprojmatrix;
setcamprojmatrix();
}
}
-vec calcmodelpreviewpos(const vec &radius, float &yaw)
-{
+vec calcmodelpreviewpos(const vec &radius, float &yaw) {
yaw = fmod(lastmillis/10000.0f*360.0f, 360.0f);
float dist = 1.15f*max(radius.magnitude2()/aspect, radius.magnitude())/sinf(fovy/2*RAD);
return vec(0, dist, 0).rotate_around_x(camera1->pitch*RAD);
@@ -1116,70 +948,47 @@ vec calcmodelpreviewpos(const vec &radius, float &yaw)
bool deferdrawtextures = false;
-void drawtextures()
-{
+void drawtextures() {
if(minimized) { deferdrawtextures = true; return; }
deferdrawtextures = false;
}
int xtraverts, xtravertsva;
-void gl_drawframe()
-{
+void gl_drawframe() {
if(deferdrawtextures) drawtextures();
-
updatedynlights();
-
int w = screenw, h = screenh;
aspect = forceaspect ? forceaspect : w/float(h);
fovy = 2*atan2(tan(curfov/2*RAD), aspect)/RAD;
-
farplane = worldsize*2;
-
projmatrix.perspective(fovy, aspect, nearplane, farplane);
setcamprojmatrix();
-
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
-
xtravertsva = xtraverts = glde = gbatches = 0;
-
visiblecubes();
-
glClear(GL_DEPTH_BUFFER_BIT|(wireframe && editmode ? GL_COLOR_BUFFER_BIT : 0));
-
if(wireframe && editmode) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
rendergeom();
-
extern int outline;
if(!wireframe && editmode && outline) renderoutline();
-
renderdecals(true);
-
rendermapmodels();
rendergame(true);
renderavatar();
-
if(wireframe && editmode) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
rendermaterials();
renderalphageom();
-
if(wireframe && editmode) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
renderparticles(true);
-
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
-
gl_drawhud();
-
renderedgame = false;
}
-void gl_drawmainmenu()
-{
+void gl_drawmainmenu() {
xtravertsva = xtraverts = glde = gbatches = 0;
renderbackground(NULL, NULL, NULL, NULL, true, true);
gl_drawhud();
@@ -1194,14 +1003,12 @@ VARP(damagecompassmax, 1, 200, 1000);
float damagedirs[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-void damagecompass(int n, const vec &loc)
-{
+void damagecompass(int n, const vec &loc) {
if(!usedamagecompass || minimized) return;
vec delta(loc);
delta.sub(camera1->o);
float yaw = 0, pitch;
- if(delta.magnitude() > 4)
- {
+ if(delta.magnitude() > 4) {
vectoyawpitch(delta, yaw, pitch);
yaw -= camera1->yaw;
}
@@ -1212,23 +1019,18 @@ void damagecompass(int n, const vec &loc)
if(damagedirs[dir]>1) damagedirs[dir] = 1;
}
-void drawdamagecompass(int w, int h)
-{
+void drawdamagecompass(int w, int h) {
hudnotextureshader->set();
-
int dirs = 0;
float size = damagecompasssize/100.0f*min(h, w)/2.0f;
- loopi(8) if(damagedirs[i]>0)
- {
- if(!dirs)
- {
+ loopi(8) if(damagedirs[i]>0) {
+ if(!dirs) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gle::colorf(1, 0, 0, damagecompassalpha/100.0f);
gle::defvertex();
gle::begin(GL_TRIANGLES);
}
dirs++;
-
float logscale = 32,
scale = log(1 + (logscale - 1)*damagedirs[i]) / log(logscale),
offset = -size/2.0f-min(h, w)/4.0f;
@@ -1238,11 +1040,9 @@ void drawdamagecompass(int w, int h)
m.rotate_around_z(i*45*RAD);
m.translate(0, offset, 0);
m.scale(size*scale);
-
gle::attrib(m.transform(vec2(1, 1)));
gle::attrib(m.transform(vec2(-1, 1)));
gle::attrib(m.transform(vec2(0, 0)));
-
// fade in log space so short blips don't disappear too quickly
scale -= float(curtime)/damagecompassfade;
damagedirs[i] = scale > 0 ? (pow(logscale, scale) - 1) / (logscale - 1) : 0;
@@ -1261,68 +1061,57 @@ VARP(crosshaircolors, 0, 1, 1);
#define MAXCROSSHAIRS 4
static Texture *crosshairs[MAXCROSSHAIRS] = { NULL, NULL, NULL, NULL };
-void loadcrosshair(const char *name, int i)
-{
+void loadcrosshair(const char *name, int i) {
if(i < 0 || i >= MAXCROSSHAIRS) return;
crosshairs[i] = name ? textureload(name, 3, true) : notexture;
- if(crosshairs[i] == notexture)
- {
+ if(crosshairs[i] == notexture) {
name = game::defaultcrosshair(i);
if(!name) name = "data/crosshair.png";
crosshairs[i] = textureload(name, 3, true);
}
}
-void loadcrosshair_(const char *name, int *i)
-{
+void loadcrosshair_(const char *name, int *i) {
loadcrosshair(name, *i);
}
COMMANDN(loadcrosshair, loadcrosshair_, "si");
-ICOMMAND(getcrosshair, "i", (int *i),
-{
+ICOMMAND(getcrosshair, "i", (int *i), {
const char *name = "";
- if(*i >= 0 && *i < MAXCROSSHAIRS)
- {
+ if(*i >= 0 && *i < MAXCROSSHAIRS) {
name = crosshairs[*i] ? crosshairs[*i]->name : game::defaultcrosshair(*i);
if(!name) name = "data/crosshair.png";
}
result(name);
});
-void writecrosshairs(stream *f)
-{
+void writecrosshairs(stream *f) {
loopi(MAXCROSSHAIRS) if(crosshairs[i] && crosshairs[i]!=notexture)
f->printf("loadcrosshair %s %d\n", escapestring(crosshairs[i]->name), i);
f->printf("\n");
}
-void drawcrosshair(int w, int h)
-{
+void drawcrosshair(int w, int h) {
bool windowhit = g3d_windowhit(true, false);
if(!windowhit && (hidehud || mainmenu)) return; //(hidehud || player->state==CS_SPECTATOR || player->state==CS_DEAD)) return;
-
vec color(1, 1, 1);
float cx = 0.5f, cy = 0.5f, chsize;
Texture *crosshair;
- if(windowhit)
- {
+ if(windowhit) {
static Texture *cursor = NULL;
if(!cursor) cursor = textureload("data/guicursor.png", 3, true);
crosshair = cursor;
chsize = cursorsize*w/900.0f;
g3d_cursorpos(cx, cy);
}
- else
- {
+ else {
int index = game::selectcrosshair(color);
if(index < 0) return;
if(!crosshairfx) index = 0;
if(!crosshairfx || !crosshaircolors) color = vec(1, 1, 1);
crosshair = crosshairs[index];
- if(!crosshair)
- {
+ if(!crosshair) {
loadcrosshair(NULL, index);
crosshair = crosshairs[index];
}
@@ -1333,7 +1122,6 @@ void drawcrosshair(int w, int h)
float x = cx*w - (windowhit ? 0 : chsize/2.0f);
float y = cy*h - (windowhit ? 0 : chsize/2.0f);
glBindTexture(GL_TEXTURE_2D, crosshair->id);
-
hudshader->set();
gle::color(color);
hudquad(x, y, chsize, chsize);
@@ -1346,55 +1134,36 @@ VAR(statrate, 1, 200, 1000);
FVARP(conscale, 1e-3f, 0.33f, 1e3f);
-void gl_drawhud()
-{
+void gl_drawhud() {
g3d_render();
-
int w = screenw, h = screenh;
if(forceaspect) w = int(ceil(h*forceaspect));
-
- if(editmode && !hidehud && !mainmenu)
- {
+ if(editmode && !hidehud && !mainmenu) {
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
-
rendereditcursor();
-
glDepthMask(GL_TRUE);
glDisable(GL_DEPTH_TEST);
}
-
gettextres(w, h);
-
hudmatrix.ortho(0, w, h, 0, -1, 1);
resethudmatrix();
-
gle::colorf(1, 1, 1);
-
glEnable(GL_BLEND);
-
- if(!mainmenu)
- {
+ if(!mainmenu) {
drawdamagecompass(w, h);
}
-
hudshader->set();
-
int conw = int(w/conscale), conh = int(h/conscale), abovehud = conh - FONTH, limitgui = abovehud;
- if(!hidehud && !mainmenu)
- {
- if(!hidestats)
- {
+ if(!hidehud && !mainmenu) {
+ if(!hidestats) {
pushhudmatrix();
hudmatrix.scale(conscale, conscale, 1);
flushhudmatrix();
-
int roffset = 0;
- if(showfps)
- {
+ if(showfps) {
static int lastfps = 0, prevfps[3] = { 0, 0, 0 }, curfps[3] = { 0, 0, 0 };
- if(totalmillis - lastfps >= statrate)
- {
+ if(totalmillis - lastfps >= statrate) {
memcpy(prevfps, curfps, sizeof(prevfps));
lastfps = totalmillis - (totalmillis%statrate);
}
@@ -1405,17 +1174,13 @@ void gl_drawhud()
else draw_textf("fps %d", conw-5*FONTH, conh-FONTH*3/2, curfps[0]);
roffset += FONTH;
}
-
- if(editmode || showeditstats)
- {
+ if(editmode || showeditstats) {
static int laststats = 0, prevstats[8] = { 0, 0, 0, 0, 0, 0, 0 }, curstats[8] = { 0, 0, 0, 0, 0, 0, 0 };
- if(totalmillis - laststats >= statrate)
- {
+ if(totalmillis - laststats >= statrate) {
memcpy(prevstats, curstats, sizeof(prevstats));
laststats = totalmillis - (totalmillis%statrate);
}
- int nextstats[8] =
- {
+ int nextstats[8] = {
vtris*100/max(wtris, 1),
vverts*100/max(wverts, 1),
xtraverts/1024,
@@ -1425,22 +1190,16 @@ void gl_drawhud()
getnumqueries()
};
loopi(8) if(prevstats[i]==curstats[i]) curstats[i] = nextstats[i];
-
abovehud -= 2*FONTH;
draw_textf("wtr:%dk(%d%%) wvt:%dk(%d%%) evt:%dk eva:%dk", FONTH/2, abovehud, wtris/1024, curstats[0], wverts/1024, curstats[1], curstats[2], curstats[3]);
draw_textf("ond:%d va:%d gl:%d(%d) oq:%d lm:%d rp:%d", FONTH/2, abovehud+FONTH, allocnodes*8, allocva, curstats[4], curstats[5], curstats[6], lightmaps.length(), curstats[7]);
limitgui = abovehud;
}
-
- if(editmode)
- {
+ if(editmode) {
abovehud -= FONTH;
draw_textf("cube %s%d%s", FONTH/2, abovehud, selchildcount<0 ? "1/" : "", abs(selchildcount), showmat && selchildmat > 0 ? getmaterialdesc(selchildmat, ": ") : "");
-
- if(char *editinfo = execidentstr("edithud"))
- {
- if(editinfo[0])
- {
+ if(char *editinfo = execidentstr("edithud")) {
+ if(editinfo[0]) {
int tw, th;
text_bounds(editinfo, tw, th);
th += FONTH-1; th -= th%FONTH;
@@ -1450,10 +1209,8 @@ void gl_drawhud()
DELETEA(editinfo);
}
}
- else if(char *gameinfo = execidentstr("gamehud"))
- {
- if(gameinfo[0])
- {
+ else if(char *gameinfo = execidentstr("gamehud")) {
+ if(gameinfo[0]) {
int tw, th;
text_bounds(gameinfo, tw, th);
th += FONTH-1; th -= th%FONTH;
@@ -1462,30 +1219,21 @@ void gl_drawhud()
}
DELETEA(gameinfo);
}
-
pophudmatrix();
}
-
- if(hidestats || (!editmode && !showeditstats))
- {
+ if(hidestats || (!editmode && !showeditstats)) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
game::gameplayhud(w, h);
limitgui = abovehud = min(abovehud, int(conh*game::abovegameplayhud(w, h)));
}
-
rendertexturepanel(w, h);
}
-
glDisable(GL_BLEND);
-
g3d_limitscale((2*limitgui - conh) / float(conh));
g3d_render2d();
-
glEnable(GL_BLEND);
-
hudmatrix.ortho(0, w, h, 0, -1, 1);
resethudmatrix();
-
pushhudmatrix();
hudmatrix.scale(conscale, conscale, 1);
flushhudmatrix();
@@ -1493,16 +1241,12 @@ void gl_drawhud()
extern int fullconsole;
if(!hidehud || fullconsole) renderconsole(conw, conh, abovehud - FONTH/2);
pophudmatrix();
-
drawcrosshair(w, h);
-
glDisable(GL_BLEND);
}
-void cleanupgl()
-{
+void cleanupgl() {
cleanupscreenquad();
-
gle::cleanup();
}
diff --git a/src/engine/rendermodel.cpp b/src/engine/rendermodel.cpp
index 9f2aba9..bc93caa 100644
--- a/src/engine/rendermodel.cpp
+++ b/src/engine/rendermodel.cpp
@@ -7,60 +7,52 @@ model *loadingmodel = NULL;
#include "ragdoll.h"
#include "animmodel.h"
-#include "vertmodel.h"
#include "skelmodel.h"
static model *(__cdecl *modeltypes[NUMMODELTYPES])(const char *);
-static int addmodeltype(int type, model *(__cdecl *loader)(const char *))
-{
+static int addmodeltype(int type, model *(__cdecl *loader)(const char *)) {
modeltypes[type] = loader;
return type;
}
#define MODELTYPE(modeltype, modelclass) \
-static model *__loadmodel__##modelclass(const char *filename) \
-{ \
+static model *__loadmodel__##modelclass(const char *filename) { \
+ \
return new modelclass(filename); \
} \
UNUSED static int __dummy__##modelclass = addmodeltype((modeltype), __loadmodel__##modelclass);
-#include "md3.h"
#include "md5.h"
#include "iqm.h"
-MODELTYPE(MDL_MD3, md3);
MODELTYPE(MDL_MD5, md5);
MODELTYPE(MDL_IQM, iqm);
#define checkmdl if(!loadingmodel) { conoutf(CON_ERROR, "not loading a model"); return; }
-void mdlcullface(int *cullface)
-{
+void mdlcullface(int *cullface) {
checkmdl;
loadingmodel->setcullface(*cullface!=0);
}
COMMAND(mdlcullface, "i");
-void mdlcollide(int *collide)
-{
+void mdlcollide(int *collide) {
checkmdl;
loadingmodel->collide = *collide!=0;
}
COMMAND(mdlcollide, "i");
-void mdlellipsecollide(int *collide)
-{
+void mdlellipsecollide(int *collide) {
checkmdl;
loadingmodel->ellipsecollide = *collide!=0;
}
COMMAND(mdlellipsecollide, "i");
-void mdlspec(int *percent)
-{
+void mdlspec(int *percent) {
checkmdl;
float spec = 1.0f;
if(*percent>0) spec = *percent/100.0f;
@@ -70,8 +62,7 @@ void mdlspec(int *percent)
COMMAND(mdlspec, "i");
-void mdlambient(int *percent)
-{
+void mdlambient(int *percent) {
checkmdl;
float ambient = 0.3f;
if(*percent>0) ambient = *percent/100.0f;
@@ -81,56 +72,49 @@ void mdlambient(int *percent)
COMMAND(mdlambient, "i");
-void mdlalphatest(float *cutoff)
-{
+void mdlalphatest(float *cutoff) {
checkmdl;
loadingmodel->setalphatest(max(0.0f, min(1.0f, *cutoff)));
}
COMMAND(mdlalphatest, "f");
-void mdlalphablend(int *blend)
-{
+void mdlalphablend(int *blend) {
checkmdl;
loadingmodel->setalphablend(*blend!=0);
}
COMMAND(mdlalphablend, "i");
-void mdlalphadepth(int *depth)
-{
+void mdlalphadepth(int *depth) {
checkmdl;
loadingmodel->alphadepth = *depth!=0;
}
COMMAND(mdlalphadepth, "i");
-void mdldepthoffset(int *offset)
-{
+void mdldepthoffset(int *offset) {
checkmdl;
loadingmodel->depthoffset = *offset!=0;
}
COMMAND(mdldepthoffset, "i");
-void mdlfullbright(float *fullbright)
-{
+void mdlfullbright(float *fullbright) {
checkmdl;
loadingmodel->setfullbright(*fullbright);
}
COMMAND(mdlfullbright, "f");
-void mdlshader(char *shader)
-{
+void mdlshader(char *shader) {
checkmdl;
loadingmodel->setshader(lookupshaderbyname(shader));
}
COMMAND(mdlshader, "s");
-void mdlspin(float *yaw, float *pitch)
-{
+void mdlspin(float *yaw, float *pitch) {
checkmdl;
loadingmodel->spinyaw = *yaw;
loadingmodel->spinpitch = *pitch;
@@ -138,8 +122,7 @@ void mdlspin(float *yaw, float *pitch)
COMMAND(mdlspin, "ff");
-void mdlscale(int *percent)
-{
+void mdlscale(int *percent) {
checkmdl;
float scale = 1.0f;
if(*percent>0) scale = *percent/100.0f;
@@ -148,40 +131,35 @@ void mdlscale(int *percent)
COMMAND(mdlscale, "i");
-void mdltrans(float *x, float *y, float *z)
-{
+void mdltrans(float *x, float *y, float *z) {
checkmdl;
loadingmodel->translate = vec(*x, *y, *z);
}
COMMAND(mdltrans, "fff");
-void mdlyaw(float *angle)
-{
+void mdlyaw(float *angle) {
checkmdl;
loadingmodel->offsetyaw = *angle;
}
COMMAND(mdlyaw, "f");
-void mdlpitch(float *angle)
-{
+void mdlpitch(float *angle) {
checkmdl;
loadingmodel->offsetpitch = *angle;
}
COMMAND(mdlpitch, "f");
-void mdlshadow(int *shadow)
-{
+void mdlshadow(int *shadow) {
checkmdl;
loadingmodel->shadow = *shadow!=0;
}
COMMAND(mdlshadow, "i");
-void mdlbb(float *rad, float *h, float *eyeheight)
-{
+void mdlbb(float *rad, float *h, float *eyeheight) {
checkmdl;
loadingmodel->collidexyradius = *rad;
loadingmodel->collideheight = *h;
@@ -190,16 +168,14 @@ void mdlbb(float *rad, float *h, float *eyeheight)
COMMAND(mdlbb, "fff");
-void mdlextendbb(float *x, float *y, float *z)
-{
+void mdlextendbb(float *x, float *y, float *z) {
checkmdl;
loadingmodel->bbextend = vec(*x, *y, *z);
}
COMMAND(mdlextendbb, "fff");
-void mdlname()
-{
+void mdlname() {
checkmdl;
result(loadingmodel->name);
}
@@ -219,8 +195,7 @@ COMMAND(mdlname, "");
if(ragdoll->loaded) return;
-void rdvert(float *x, float *y, float *z, float *radius)
-{
+void rdvert(float *x, float *y, float *z, float *radius) {
checkragdoll;
ragdollskel::vert &v = ragdoll->verts.add();
v.pos = vec(*x, *y, *z);
@@ -228,15 +203,13 @@ void rdvert(float *x, float *y, float *z, float *radius)
}
COMMAND(rdvert, "ffff");
-void rdeye(int *v)
-{
+void rdeye(int *v) {
checkragdoll;
ragdoll->eye = *v;
}
COMMAND(rdeye, "i");
-void rdtri(int *v1, int *v2, int *v3)
-{
+void rdtri(int *v1, int *v2, int *v3) {
checkragdoll;
ragdollskel::tri &t = ragdoll->tris.add();
t.vert[0] = *v1;
@@ -245,8 +218,7 @@ void rdtri(int *v1, int *v2, int *v3)
}
COMMAND(rdtri, "iii");
-void rdjoint(int *n, int *t, int *v1, int *v2, int *v3)
-{
+void rdjoint(int *n, int *t, int *v1, int *v2, int *v3) {
checkragdoll;
if(*n < 0 || *n >= skel->numbones) return;
ragdollskel::joint &j = ragdoll->joints.add();
@@ -258,8 +230,7 @@ void rdjoint(int *n, int *t, int *v1, int *v2, int *v3)
}
COMMAND(rdjoint, "iibbb");
-void rdlimitdist(int *v1, int *v2, float *mindist, float *maxdist)
-{
+void rdlimitdist(int *v1, int *v2, float *mindist, float *maxdist) {
checkragdoll;
ragdollskel::distlimit &d = ragdoll->distlimits.add();
d.vert[0] = *v1;
@@ -269,8 +240,7 @@ void rdlimitdist(int *v1, int *v2, float *mindist, float *maxdist)
}
COMMAND(rdlimitdist, "iiff");
-void rdlimitrot(int *t1, int *t2, float *maxangle, float *qx, float *qy, float *qz, float *qw)
-{
+void rdlimitrot(int *t1, int *t2, float *maxangle, float *qx, float *qy, float *qz, float *qw) {
checkragdoll;
ragdollskel::rotlimit &r = ragdoll->rotlimits.add();
r.tri[0] = *t1;
@@ -280,8 +250,7 @@ void rdlimitrot(int *t1, int *t2, float *maxangle, float *qx, float *qy, float *
}
COMMAND(rdlimitrot, "iifffff");
-void rdanimjoints(int *on)
-{
+void rdanimjoints(int *on) {
checkragdoll;
ragdoll->animjoints = *on!=0;
}
@@ -291,20 +260,17 @@ COMMAND(rdanimjoints, "i");
vector<mapmodelinfo> mapmodels;
-void mmodel(char *name)
-{
+void mmodel(char *name) {
mapmodelinfo &mmi = mapmodels.add();
copystring(mmi.name, name);
mmi.m = NULL;
}
-void mapmodelcompat(int *rad, int *h, int *tex, char *name, char *shadow)
-{
+void mapmodelcompat(int *rad, int *h, int *tex, char *name, char *shadow) {
mmodel(name);
}
-void mapmodelreset(int *n)
-{
+void mapmodelreset(int *n) {
if(!(identflags&IDF_OVERRIDDEN) && !game::allowedittoggle()) return;
mapmodels.shrink(clamp(*n, 0, mapmodels.length()));
}
@@ -325,21 +291,17 @@ ICOMMAND(mapmodelfind, "s", (char *name), { int found = -1; loopv(mapmodels) if(
hashnameset<model *> models;
vector<const char *> preloadmodels;
-void preloadmodel(const char *name)
-{
+void preloadmodel(const char *name) {
if(!name || !name[0] || models.access(name)) return;
preloadmodels.add(newstring(name));
}
-void flushpreloadedmodels(bool msg)
-{
- loopv(preloadmodels)
- {
+void flushpreloadedmodels(bool msg) {
+ loopv(preloadmodels) {
loadprogress = float(i+1)/preloadmodels.length();
model *m = loadmodel(preloadmodels[i], -1, msg);
if(!m) { if(msg) conoutf(CON_WARN, "could not load model: %s", preloadmodels[i]); }
- else
- {
+ else {
m->preloadmeshes();
}
}
@@ -347,25 +309,20 @@ void flushpreloadedmodels(bool msg)
loadprogress = 0;
}
-void preloadusedmapmodels(bool msg, bool bih)
-{
+void preloadusedmapmodels(bool msg, bool bih) {
vector<extentity *> &ents = entities::getents();
vector<int> mapmodels;
- loopv(ents)
- {
+ loopv(ents) {
extentity &e = *ents[i];
if(e.type==ET_MAPMODEL && e.attr2 >= 0 && mapmodels.find(e.attr2) < 0) mapmodels.add(e.attr2);
}
-
- loopv(mapmodels)
- {
+ loopv(mapmodels) {
loadprogress = float(i+1)/mapmodels.length();
int mmindex = mapmodels[i];
mapmodelinfo *mmi = getmminfo(mmindex);
if(!mmi) { if(msg) conoutf(CON_WARN, "could not find map model: %d", mmindex); }
else if(mmi->name[0] && !loadmodel(NULL, mmindex, msg)) { if(msg) conoutf(CON_WARN, "could not load model: %s", mmi->name); }
- else if(mmi->m)
- {
+ else if(mmi->m) {
if(bih) mmi->m->preloadBIH();
mmi->m->preloadmeshes();
}
@@ -373,15 +330,12 @@ void preloadusedmapmodels(bool msg, bool bih)
loadprogress = 0;
}
-bool modelloaded(const char *name)
-{
+bool modelloaded(const char *name) {
return models.find(name, NULL) != NULL;
}
-model *loadmodel(const char *name, int i, bool msg)
-{
- if(!name)
- {
+model *loadmodel(const char *name, int i, bool msg) {
+ if(!name) {
if(!mapmodels.inrange(i)) return NULL;
mapmodelinfo &mmi = mapmodels[i];
if(mmi.m) return mmi.m;
@@ -390,16 +344,13 @@ model *loadmodel(const char *name, int i, bool msg)
model **mm = models.access(name);
model *m;
if(mm) m = *mm;
- else
- {
+ else {
if(!name[0] || loadingmodel || lightmapping > 1) return NULL;
- if(msg)
- {
+ if(msg) {
defformatstring(filename, "packages/models/%s", name);
renderprogress(loadprogress, filename);
}
- loopi(NUMMODELTYPES)
- {
+ loopi(NUMMODELTYPES) {
m = modeltypes[i](name);
if(!m) continue;
loadingmodel = m;
@@ -415,24 +366,20 @@ model *loadmodel(const char *name, int i, bool msg)
return m;
}
-void preloadmodelshaders(bool force)
-{
+void preloadmodelshaders() {
if(initing) return;
- enumerate(models, model *, m, m->preloadshaders(force));
+ enumerate(models, model *, m, m->preloadshaders());
}
-void clear_mdls()
-{
+void clear_mdls() {
enumerate(models, model *, m, delete m);
}
-void cleanupmodels()
-{
+void cleanupmodels() {
enumerate(models, model *, m, m->cleanup());
}
-void clearmodel(char *name)
-{
+void clearmodel(char *name) {
model **m = models.access(name);
if(!m) { conoutf(CON_WARN, "model %s is not loaded", name); return; }
loopv(mapmodels) if(mapmodels[i].m==*m) mapmodels[i].m = NULL;
@@ -444,16 +391,14 @@ void clearmodel(char *name)
COMMAND(clearmodel, "s");
-bool modeloccluded(const vec &center, float radius)
-{
+bool modeloccluded(const vec &center, float radius) {
ivec bbmin(vec(center).sub(radius)), bbmax(ivec(center).add(radius+1));
return bboccluded(bbmin, bbmax);
}
VAR(showboundingbox, 0, 0, 2);
-void render2dbox(vec &o, float x, float y, float z)
-{
+void render2dbox(vec &o, float x, float y, float z) {
gle::begin(GL_LINE_LOOP);
gle::attribf(o.x, o.y, o.z);
gle::attribf(o.x, o.y, o.z+z);
@@ -462,8 +407,7 @@ void render2dbox(vec &o, float x, float y, float z)
xtraverts += gle::end();
}
-void render3dbox(vec &o, float tofloor, float toceil, float xradius, float yradius)
-{
+void render3dbox(vec &o, float tofloor, float toceil, float xradius, float yradius) {
if(yradius<=0) yradius = xradius;
vec c = o;
c.sub(vec(xradius, yradius, tofloor));
@@ -478,21 +422,18 @@ void render3dbox(vec &o, float tofloor, float toceil, float xradius, float yradi
render2dbox(c, 0, -ysz, h);
}
-void renderellipse(vec &o, float xradius, float yradius, float yaw)
-{
+void renderellipse(vec &o, float xradius, float yradius, float yaw) {
gle::colorf(0.5f, 0.5f, 0.5f);
gle::defvertex();
gle::begin(GL_LINE_LOOP);
- loopi(15)
- {
+ loopi(15) {
const vec2 &sc = sincos360[i*(360/15)];
gle::attrib(vec(xradius*sc.x, yradius*sc.y, 0).rotate_around_z((yaw+90)*RAD).add(o));
}
xtraverts += gle::end();
}
-struct batchedmodel
-{
+struct batchedmodel {
vec pos, color, dir;
int anim;
float yaw, pitch, transparent;
@@ -501,8 +442,7 @@ struct batchedmodel
int attached;
occludequery *query;
};
-struct modelbatch
-{
+struct modelbatch {
model *m;
int flags;
vector<batchedmodel> batched;
@@ -512,20 +452,16 @@ static vector<modelattach> modelattached;
static int numbatches = -1;
static occludequery *modelquery = NULL;
-void startmodelbatches()
-{
+void startmodelbatches() {
numbatches = 0;
modelattached.setsize(0);
}
-modelbatch &addbatchedmodel(model *m)
-{
+modelbatch &addbatchedmodel(model *m) {
modelbatch *b = NULL;
if(m->batch>=0 && m->batch<numbatches && batches[m->batch]->m==m) b = batches[m->batch];
- else
- {
- if(numbatches<batches.length())
- {
+ else {
+ if(numbatches<batches.length()) {
b = batches[numbatches];
b->batched.setsize(0);
}
@@ -537,75 +473,59 @@ modelbatch &addbatchedmodel(model *m)
return *b;
}
-void renderbatchedmodel(model *m, batchedmodel &b)
-{
+void renderbatchedmodel(model *m, batchedmodel &b) {
modelattach *a = NULL;
if(b.attached>=0) a = &modelattached[b.attached];
-
int anim = b.anim;
- if(shadowmapping)
- {
+ if(shadowmapping) {
anim |= ANIM_NOSKIN;
GLOBALPARAMF(shadowintensity, b.transparent);
}
- else
- {
+ else {
if(b.flags&MDL_FULLBRIGHT) anim |= ANIM_FULLBRIGHT;
if(b.flags&MDL_GHOST) anim |= ANIM_GHOST;
}
-
m->render(anim, b.basetime, b.basetime2, b.pos, b.yaw, b.pitch, b.d, a, b.color, b.dir, b.transparent);
}
-struct transparentmodel
-{
+struct transparentmodel {
model *m;
batchedmodel *batched;
float dist;
};
-static inline bool sorttransparentmodels(const transparentmodel &x, const transparentmodel &y)
-{
+static inline bool sorttransparentmodels(const transparentmodel &x, const transparentmodel &y) {
return x.dist < y.dist;
}
-void endmodelbatches()
-{
+void endmodelbatches() {
vector<transparentmodel> transparent;
- loopi(numbatches)
- {
+ loopi(numbatches) {
modelbatch &b = *batches[i];
if(b.batched.empty()) continue;
-
bool rendered = false;
occludequery *query = NULL;
- if(b.flags&MDL_GHOST)
- {
- loopvj(b.batched)
- {
+ if(b.flags&MDL_GHOST) {
+ loopvj(b.batched) {
batchedmodel &bm = b.batched[j];
if((bm.flags&(MDL_CULL_VFC|MDL_GHOST))!=MDL_GHOST || bm.query) continue;
if(!rendered) { b.m->startrender(); rendered = true; }
renderbatchedmodel(b.m, bm);
}
- if(rendered)
- {
+ if(rendered) {
b.m->endrender();
rendered = false;
}
}
- loopvj(b.batched)
- {
+ loopvj(b.batched) {
batchedmodel &bm = b.batched[j];
if(bm.flags&(MDL_CULL_VFC|MDL_GHOST)) continue;
- if(bm.query!=query)
- {
+ if(bm.query!=query) {
if(query) endquery(query);
query = bm.query;
if(query) startquery(query);
}
- if(bm.transparent < 1 && (!query || query->owner==bm.d) && !shadowmapping)
- {
+ if(bm.transparent < 1 && (!query || query->owner==bm.d) && !shadowmapping) {
transparentmodel &tm = transparent.add();
tm.m = b.m;
tm.batched = &bm;
@@ -618,21 +538,17 @@ void endmodelbatches()
if(query) endquery(query);
if(rendered) b.m->endrender();
}
- if(transparent.length())
- {
+ if(transparent.length()) {
transparent.sort(sorttransparentmodels);
model *lastmodel = NULL;
occludequery *query = NULL;
- loopv(transparent)
- {
+ loopv(transparent) {
transparentmodel &tm = transparent[i];
- if(lastmodel!=tm.m)
- {
+ if(lastmodel!=tm.m) {
if(lastmodel) lastmodel->endrender();
(lastmodel = tm.m)->startrender();
}
- if(query!=tm.batched->query)
- {
+ if(query!=tm.batched->query) {
if(query) endquery(query);
query = tm.batched->query;
if(query) startquery(query);
@@ -645,35 +561,29 @@ void endmodelbatches()
numbatches = -1;
}
-void startmodelquery(occludequery *query)
-{
+void startmodelquery(occludequery *query) {
modelquery = query;
}
-void endmodelquery()
-{
+void endmodelquery() {
int querybatches = 0;
- loopi(numbatches)
- {
+ loopi(numbatches) {
modelbatch &b = *batches[i];
if(b.batched.empty() || b.batched.last().query!=modelquery) continue;
querybatches++;
}
- if(querybatches<=1)
- {
+ if(querybatches<=1) {
if(!querybatches) modelquery->fragments = 0;
modelquery = NULL;
return;
}
int minattached = modelattached.length();
startquery(modelquery);
- loopi(numbatches)
- {
+ loopi(numbatches) {
modelbatch &b = *batches[i];
if(b.batched.empty() || b.batched.last().query!=modelquery) continue;
b.m->startrender();
- do
- {
+ do {
batchedmodel &bm = b.batched.pop();
if(bm.attached>=0) minattached = min(minattached, bm.attached);
renderbatchedmodel(b.m, bm);
@@ -688,17 +598,14 @@ void endmodelquery()
VAR(maxmodelradiusdistance, 10, 200, 1000);
-static inline void enablecullmodelquery()
-{
+static inline void enablecullmodelquery() {
startbb();
}
-static inline void rendercullmodelquery(model *m, dynent *d, const vec &center, float radius)
-{
+static inline void rendercullmodelquery(model *m, dynent *d, const vec &center, float radius) {
if(fabs(camera1->o.x-center.x) < radius+1 &&
fabs(camera1->o.y-center.y) < radius+1 &&
- fabs(camera1->o.z-center.z) < radius+1)
- {
+ fabs(camera1->o.z-center.z) < radius+1) {
d->query = NULL;
return;
}
@@ -710,95 +617,73 @@ static inline void rendercullmodelquery(model *m, dynent *d, const vec &center,
endquery(d->query);
}
-static inline void disablecullmodelquery()
-{
+static inline void disablecullmodelquery() {
endbb();
}
-static inline int cullmodel(model *m, const vec &center, float radius, int flags, dynent *d = NULL, bool shadow = false)
-{
+static inline int cullmodel(model *m, const vec &center, float radius, int flags, dynent *d = NULL, bool shadow = false) {
if(flags&MDL_CULL_DIST && center.dist(camera1->o)/radius>maxmodelradiusdistance) return MDL_CULL_DIST;
- if(flags&MDL_CULL_VFC)
- {
+ if(flags&MDL_CULL_VFC) {
if(shadowmapping && !isshadowmapcaster(center, radius)) return MDL_CULL_VFC;
}
- if(shadowmapping)
- {
- if(d)
- {
+ if(shadowmapping) {
+ if(d) {
if(flags&MDL_CULL_OCCLUDED && d->occluded>=OCCLUDE_PARENT) return MDL_CULL_OCCLUDED;
if(flags&MDL_CULL_QUERY && d->occluded+1>=OCCLUDE_BB && d->query && d->query->owner==d && checkquery(d->query)) return MDL_CULL_QUERY;
}
if(!addshadowmapcaster(center, radius, radius)) return MDL_CULL_VFC;
}
- else if(flags&MDL_CULL_OCCLUDED && modeloccluded(center, radius))
- {
+ else if(flags&MDL_CULL_OCCLUDED && modeloccluded(center, radius)) {
if(d) d->occluded = OCCLUDE_PARENT;
return MDL_CULL_OCCLUDED;
}
- else if(flags&MDL_CULL_QUERY && d->query && d->query->owner==d && checkquery(d->query))
- {
+ else if(flags&MDL_CULL_QUERY && d->query && d->query->owner==d && checkquery(d->query)) {
if(d->occluded<OCCLUDE_BB) d->occluded++;
return MDL_CULL_QUERY;
}
return 0;
}
-void rendermodel(entitylight *light, const char *mdl, int anim, const vec &o, float yaw, float pitch, int flags, dynent *d, modelattach *a, int basetime, int basetime2, float trans)
-{
+void rendermodel(entitylight *light, const char *mdl, int anim, const vec &o, float yaw, float pitch, int flags, dynent *d, modelattach *a, int basetime, int basetime2, float trans) {
if(shadowmapping && !(flags&(MDL_SHADOW|MDL_DYNSHADOW))) return;
model *m = loadmodel(mdl);
if(!m) return;
vec center(0, 0, 0), bbradius(0, 0, 0);
float radius = 0;
bool shadow = !shadowmap && (flags&(MDL_SHADOW|MDL_DYNSHADOW));
-
- if(flags&(MDL_CULL_VFC|MDL_CULL_DIST|MDL_CULL_OCCLUDED|MDL_CULL_QUERY|MDL_SHADOW|MDL_DYNSHADOW))
- {
- if(flags&MDL_CULL_QUERY)
- {
+ if(flags&(MDL_CULL_VFC|MDL_CULL_DIST|MDL_CULL_OCCLUDED|MDL_CULL_QUERY|MDL_SHADOW|MDL_DYNSHADOW)) {
+ if(flags&MDL_CULL_QUERY) {
if(!oqfrags || !oqdynent || !d) flags &= ~MDL_CULL_QUERY;
}
-
m->boundbox(center, bbradius);
radius = bbradius.magnitude();
- if(d && d->ragdoll)
- {
+ if(d && d->ragdoll) {
radius = max(radius, d->ragdoll->radius);
center = d->ragdoll->center;
}
- else
- {
+ else {
center.rotate_around_z(yaw*RAD);
center.add(o);
}
-
int culled = cullmodel(m, center, radius, flags, d, shadow);
- if(culled)
- {
- if(culled&(MDL_CULL_OCCLUDED|MDL_CULL_QUERY) && flags&MDL_CULL_QUERY)
- {
+ if(culled) {
+ if(culled&(MDL_CULL_OCCLUDED|MDL_CULL_QUERY) && flags&MDL_CULL_QUERY) {
enablecullmodelquery();
rendercullmodelquery(m, d, center, radius);
disablecullmodelquery();
}
return;
}
-
if(shadowmapping) flags &= ~MDL_CULL_QUERY;
}
-
if(flags&MDL_NORENDER) anim |= ANIM_NORENDER;
- else if(showboundingbox && !shadowmapping && editmode)
- {
+ else if(showboundingbox && !shadowmapping && editmode) {
notextureshader->set();
- if(d && showboundingbox==1)
- {
+ if(d && showboundingbox==1) {
render3dbox(d->o, d->eyeheight, d->aboveeye, d->radius);
renderellipse(d->o, d->xradius, d->yradius, d->yaw);
}
- else
- {
+ else {
vec center, radius;
if(showboundingbox==1) m->collisionbox(center, radius);
else m->boundbox(center, radius);
@@ -807,19 +692,14 @@ void rendermodel(entitylight *light, const char *mdl, int anim, const vec &o, fl
render3dbox(center, radius.z, radius.z, radius.x, radius.y);
}
}
-
vec lightcolor(1, 1, 1), lightdir(0, 0, 1);
- if(!shadowmapping)
- {
+ if(!shadowmapping) {
vec pos = o;
- if(d)
- {
+ if(d) {
d->occluded = OCCLUDE_NOTHING;
if(!light) light = &d->light;
- if(flags&MDL_LIGHT && light->millis!=lastmillis)
- {
- if(d->ragdoll)
- {
+ if(flags&MDL_LIGHT && light->millis!=lastmillis) {
+ if(d->ragdoll) {
pos = d->ragdoll->center;
pos.z += radius/2;
}
@@ -830,15 +710,12 @@ void rendermodel(entitylight *light, const char *mdl, int anim, const vec &o, fl
light->millis = lastmillis;
}
}
- else if(flags&MDL_LIGHT)
- {
- if(!light)
- {
+ else if(flags&MDL_LIGHT) {
+ if(!light) {
lightreaching(pos, lightcolor, lightdir, (flags&MDL_LIGHT_FAST)!=0);
dynlightreaching(pos, lightcolor, lightdir, (flags&MDL_HUD)!=0);
}
- else if(light->millis!=lastmillis)
- {
+ else if(light->millis!=lastmillis) {
lightreaching(pos, light->color, light->dir, (flags&MDL_LIGHT_FAST)!=0);
dynlightreaching(pos, light->color, light->dir, (flags&MDL_HUD)!=0);
light->millis = lastmillis;
@@ -847,15 +724,11 @@ void rendermodel(entitylight *light, const char *mdl, int anim, const vec &o, fl
if(light) { lightcolor = light->color; lightdir = light->dir; }
if(flags&MDL_DYNLIGHT) dynlightreaching(pos, lightcolor, lightdir, (flags&MDL_HUD)!=0);
}
-
- if(a) for(int i = 0; a[i].tag; i++)
- {
+ if(a) for(int i = 0; a[i].tag; i++) {
if(a[i].name) a[i].m = loadmodel(a[i].name);
//if(a[i].m && a[i].m->type()!=m->type()) a[i].m = NULL;
}
-
- if(numbatches>=0)
- {
+ if(numbatches>=0) {
modelbatch &mb = addbatchedmodel(m);
batchedmodel &b = mb.batched.add();
b.query = modelquery;
@@ -869,8 +742,7 @@ void rendermodel(entitylight *light, const char *mdl, int anim, const vec &o, fl
b.basetime2 = basetime2;
b.transparent = trans;
b.flags = flags & ~(MDL_CULL_VFC | MDL_CULL_DIST | MDL_CULL_OCCLUDED);
- if(!shadow)
- {
+ if(!shadow) {
b.flags &= ~(MDL_SHADOW|MDL_DYNSHADOW);
if(flags&MDL_CULL_VFC) b.flags |= MDL_CULL_VFC;
}
@@ -881,52 +753,38 @@ void rendermodel(entitylight *light, const char *mdl, int anim, const vec &o, fl
if(flags&MDL_CULL_QUERY) d->query = b.query = newquery(d);
return;
}
-
m->startrender();
-
- if(shadowmapping)
- {
+ if(shadowmapping) {
anim |= ANIM_NOSKIN;
GLOBALPARAMF(shadowintensity, trans);
}
- else
- {
+ else {
if(flags&MDL_FULLBRIGHT) anim |= ANIM_FULLBRIGHT;
if(flags&MDL_GHOST) anim |= ANIM_GHOST;
}
-
- if(flags&MDL_CULL_QUERY)
- {
+ if(flags&MDL_CULL_QUERY) {
d->query = newquery(d);
if(d->query) startquery(d->query);
}
-
m->render(anim, basetime, basetime2, o, yaw, pitch, d, a, lightcolor, lightdir, trans);
-
if(flags&MDL_CULL_QUERY && d->query) endquery(d->query);
-
m->endrender();
}
-void abovemodel(vec &o, const char *mdl)
-{
+void abovemodel(vec &o, const char *mdl) {
model *m = loadmodel(mdl);
if(!m) return;
o.z += m->above();
}
-bool matchanim(const char *name, const char *pattern)
-{
- for(;; pattern++)
- {
+bool matchanim(const char *name, const char *pattern) {
+ for(;; pattern++) {
const char *s = name;
char c;
- for(;; pattern++)
- {
+ for(;; pattern++) {
c = *pattern;
if(!c || c=='|') break;
- else if(c=='*')
- {
+ else if(c=='*') {
if(!*s || iscubespace(*s)) break;
do s++; while(*s && !iscubespace(*s));
}
@@ -940,19 +798,16 @@ bool matchanim(const char *name, const char *pattern)
return false;
}
-void findanims(const char *pattern, vector<int> &anims)
-{
+void findanims(const char *pattern, vector<int> &anims) {
loopi(sizeof(animnames)/sizeof(animnames[0])) if(matchanim(animnames[i], pattern)) anims.add(i);
}
-ICOMMAND(findanims, "s", (char *name),
-{
+ICOMMAND(findanims, "s", (char *name), {
vector<int> anims;
findanims(name, anims);
vector<char> buf;
string num;
- loopv(anims)
- {
+ loopv(anims) {
formatstring(num, "%d", anims[i]);
if(i > 0) buf.add(' ');
buf.put(num, strlen(num));
@@ -961,21 +816,19 @@ ICOMMAND(findanims, "s", (char *name),
result(buf.getbuf());
});
-void loadskin(const char *dir, const char *altdir, Texture *&skin, Texture *&masks) // model skin sharing
-{
+void loadskin(const char *dir, const char *altdir, Texture *&skin, Texture *&masks) { // model skin sharing {
#define ifnoload(tex, path) if((tex = textureload(path, 0, true, false))==notexture)
#define tryload(tex, prefix, cmd, name) \
- ifnoload(tex, makerelpath(mdir, name ".jpg", prefix, cmd)) \
- { \
- ifnoload(tex, makerelpath(mdir, name ".png", prefix, cmd)) \
- { \
- ifnoload(tex, makerelpath(maltdir, name ".jpg", prefix, cmd)) \
- { \
+ ifnoload(tex, makerelpath(mdir, name ".jpg", prefix, cmd)) { \
+ \
+ ifnoload(tex, makerelpath(mdir, name ".png", prefix, cmd)) { \
+ \
+ ifnoload(tex, makerelpath(maltdir, name ".jpg", prefix, cmd)) { \
+ \
ifnoload(tex, makerelpath(maltdir, name ".png", prefix, cmd)) return; \
} \
} \
}
-
defformatstring(mdir, "packages/models/%s", dir);
defformatstring(maltdir, "packages/models/%s", altdir);
masks = notexture;
@@ -989,22 +842,18 @@ VAR(animoverride, -1, 0, NUMANIMS-1);
VAR(testanims, 0, 0, 1);
VAR(testpitch, -90, 0, 90);
-void renderclient(dynent *d, const char *mdlname, modelattach *attachments, int hold, int attack, int attackdelay, int lastaction, int lastpain, float fade, bool ragdoll)
-{
+void renderclient(dynent *d, const char *mdlname, modelattach *attachments, int hold, int attack, int attackdelay, int lastaction, int lastpain, float fade, bool ragdoll) {
int anim = hold ? hold : ANIM_IDLE|ANIM_LOOP;
float yaw = testanims && d==player ? 0 : d->yaw+90,
pitch = testpitch && d==player ? testpitch : d->pitch;
vec o = d->feetpos();
int basetime = 0;
if(animoverride) anim = (animoverride<0 ? ANIM_ALL : animoverride)|ANIM_LOOP;
- else if(d->state==CS_DEAD)
- {
+ else if(d->state==CS_DEAD) {
anim = ANIM_DYING|ANIM_NOPITCH;
basetime = lastpain;
- if(ragdoll)
- {
- if(!d->ragdoll || d->ragdoll->millis < basetime)
- {
+ if(ragdoll) {
+ if(!d->ragdoll || d->ragdoll->millis < basetime) {
DELETEP(d->ragdoll);
anim |= ANIM_RAGDOLL;
}
@@ -1013,32 +862,25 @@ void renderclient(dynent *d, const char *mdlname, modelattach *attachments, int
}
else if(d->state==CS_EDITING || d->state==CS_SPECTATOR) anim = ANIM_EDIT|ANIM_LOOP;
else if(d->state==CS_LAGGED) anim = ANIM_LAG|ANIM_LOOP;
- else
- {
- if(lastmillis-lastpain < 300)
- {
+ else {
+ if(lastmillis-lastpain < 300) {
anim = ANIM_PAIN;
basetime = lastpain;
}
- else if(lastpain < lastaction && (attack < 0 || (d->type != ENT_AI && lastmillis-lastaction < attackdelay)))
- {
+ else if(lastpain < lastaction && (attack < 0 || (d->type != ENT_AI && lastmillis-lastaction < attackdelay))) {
anim = attack < 0 ? -attack : attack;
basetime = lastaction;
}
-
if(d->inwater && d->physstate<=PHYS_FALL) anim |= (((game::allowmove(d) && (d->move || d->strafe)) || d->vel.z+d->falling.z>0 ? ANIM_SWIM : ANIM_SINK)|ANIM_LOOP)<<ANIM_SECONDARY;
else if(d->timeinair>100) anim |= (ANIM_JUMP|ANIM_END)<<ANIM_SECONDARY;
- else if(game::allowmove(d) && (d->move || d->strafe))
- {
+ else if(game::allowmove(d) && (d->move || d->strafe)) {
if(d->move>0) anim |= (ANIM_FORWARD|ANIM_LOOP)<<ANIM_SECONDARY;
- else if(d->strafe)
- {
+ else if(d->strafe) {
if(d->move<0) anim |= ((d->strafe>0 ? ANIM_RIGHT : ANIM_LEFT)|ANIM_REVERSE|ANIM_LOOP)<<ANIM_SECONDARY;
else anim |= ((d->strafe>0 ? ANIM_LEFT : ANIM_RIGHT)|ANIM_LOOP)<<ANIM_SECONDARY;
}
else if(d->move<0) anim |= (ANIM_BACKWARD|ANIM_LOOP)<<ANIM_SECONDARY;
}
-
if((anim&ANIM_INDEX)==ANIM_IDLE && (anim>>ANIM_SECONDARY)&ANIM_INDEX) anim >>= ANIM_SECONDARY;
}
if(d->ragdoll && (!ragdoll || (anim&ANIM_INDEX)!=ANIM_DYING)) DELETEP(d->ragdoll);
@@ -1053,8 +895,7 @@ void renderclient(dynent *d, const char *mdlname, modelattach *attachments, int
rendermodel(NULL, mdlname, anim, o, yaw, pitch, flags, d, attachments, basetime, 0, fade);
}
-void setbbfrommodel(dynent *d, const char *mdl)
-{
+void setbbfrommodel(dynent *d, const char *mdl) {
model *m = loadmodel(mdl);
if(!m) return;
vec center, radius;
@@ -1066,8 +907,7 @@ void setbbfrommodel(dynent *d, const char *mdl)
d->radius = d->collidetype==COLLIDE_OBB ? sqrtf(d->xradius*d->xradius + d->yradius*d->yradius) : max(d->xradius, d->yradius);
d->eyeheight = (center.z-radius.z) + radius.z*2*m->eyeheight;
d->aboveeye = radius.z*2*(1.0f-m->eyeheight);
- if (d->aboveeye + d->eyeheight <= 0.5f)
- {
+ if (d->aboveeye + d->eyeheight <= 0.5f) {
float zrad = (0.5f - (d->aboveeye + d->eyeheight)) / 2;
d->aboveeye += zrad;
d->eyeheight += zrad;
diff --git a/src/engine/renderparticles.cpp b/src/engine/renderparticles.cpp
index 392e943..dbdf855 100644
--- a/src/engine/renderparticles.cpp
+++ b/src/engine/renderparticles.cpp
@@ -11,8 +11,7 @@ VARP(emitmillis, 1, 17, 1000);
static int lastemitframe = 0, emitoffset = 0;
static bool canemit = false, regenemitters = false, canstep = false;
-static bool canemitparticles()
-{
+static bool canemitparticles() {
return canemit || emitoffset;
}
@@ -21,29 +20,23 @@ VAR(cullparticles, 0, 1, 1);
VAR(replayparticles, 0, 1, 1);
VARN(seedparticles, seedmillis, 0, 3000, 10000);
-struct particleemitter
-{
+struct particleemitter {
extentity *ent;
vec bbmin, bbmax;
vec center;
float radius;
ivec cullmin, cullmax;
int maxfade, lastemit, lastcull;
-
particleemitter(extentity *ent)
- : ent(ent), bbmin(ent->o), bbmax(ent->o), maxfade(-1), lastemit(0), lastcull(0)
- {}
-
- void finalize()
- {
+ : ent(ent), bbmin(ent->o), bbmax(ent->o), maxfade(-1), lastemit(0), lastcull(0) {
+ }
+ void finalize() {
center = vec(bbmin).add(bbmax).mul(0.5f);
radius = bbmin.dist(bbmax)/2;
cullmin = ivec(int(floor(bbmin.x)), int(floor(bbmin.y)), int(floor(bbmin.z)));
cullmax = ivec(int(ceil(bbmax.x)), int(ceil(bbmax.y)), int(ceil(bbmax.z)));
}
-
- void extendbb(const vec &o, float size = 0)
- {
+ void extendbb(const vec &o, float size = 0) {
bbmin.x = min(bbmin.x, o.x - size);
bbmin.y = min(bbmin.y, o.y - size);
bbmin.z = min(bbmin.z, o.z - size);
@@ -51,9 +44,7 @@ struct particleemitter
bbmax.y = max(bbmax.y, o.y + size);
bbmax.z = max(bbmax.z, o.z + size);
}
-
- void extendbb(float z, float size = 0)
- {
+ void extendbb(float z, float size = 0) {
bbmin.z = min(bbmin.z, z - size);
bbmax.z = max(bbmax.z, z + size);
}
@@ -62,18 +53,15 @@ struct particleemitter
static vector<particleemitter> emitters;
static particleemitter *seedemitter = NULL;
-void clearparticleemitters()
-{
+void clearparticleemitters() {
emitters.setsize(0);
regenemitters = true;
}
-void addparticleemitters()
-{
+void addparticleemitters() {
emitters.setsize(0);
const vector<extentity *> &ents = entities::getents();
- loopv(ents)
- {
+ loopv(ents) {
extentity &e = *ents[i];
if(e.type != ET_PARTICLES) continue;
emitters.add(particleemitter(&e));
@@ -81,8 +69,7 @@ void addparticleemitters()
regenemitters = false;
}
-enum
-{
+enum {
PT_PART = 0,
PT_TAPE,
PT_TRAIL,
@@ -90,10 +77,7 @@ enum
PT_TEXTICON,
PT_METER,
PT_METERVS,
- PT_FIREBALL,
- PT_LIGHTNING,
PT_FLARE,
-
PT_MOD = 1<<8,
PT_RND4 = 1<<9,
PT_LERP = 1<<10, // use very sparingly - order of blending issues
@@ -111,30 +95,26 @@ enum
PT_FLIP = PT_HFLIP | PT_VFLIP | PT_ROT
};
-const char *partnames[] = { "part", "tape", "trail", "text", "texticon", "meter", "metervs", "fireball", "lightning", "flare" };
+const char *partnames[] = { "part", "tape", "trail", "text", "texticon", "meter", "metervs", "flare" };
-struct particle
-{
+struct particle {
vec o, d;
int gravity, fade, millis;
bvec color;
uchar flags;
float size;
- union
- {
+ union {
const char *text;
float val;
physent *owner;
- struct
- {
+ struct {
uchar color2[3];
uchar progress;
};
};
};
-struct partvert
-{
+struct partvert {
vec pos;
bvec4 color;
vec2 tc;
@@ -143,27 +123,21 @@ struct partvert
#define COLLIDERADIUS 8.0f
#define COLLIDEERROR 1.0f
-struct partrenderer
-{
+struct partrenderer {
Texture *tex;
const char *texname;
int texclamp;
uint type;
int collide;
string info;
-
partrenderer(const char *texname, int texclamp, int type, int collide = 0)
- : tex(NULL), texname(texname), texclamp(texclamp), type(type), collide(collide)
- {
+ : tex(NULL), texname(texname), texclamp(texclamp), type(type), collide(collide) {
}
partrenderer(int type, int collide = 0)
- : tex(NULL), texname(NULL), texclamp(0), type(type), collide(collide)
- {
+ : tex(NULL), texname(NULL), texclamp(0), type(type), collide(collide) {
}
- virtual ~partrenderer()
- {
+ virtual ~partrenderer() {
}
-
virtual void init(int n) { }
virtual void reset() = 0;
virtual void resettracked(physent *owner) { }
@@ -172,44 +146,34 @@ struct partrenderer
virtual void render() = 0;
virtual bool haswork() = 0;
virtual void cleanup() {}
-
- virtual void seedemitter(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int gravity)
- {
+ virtual void seedemitter(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int gravity) {
}
-
//blend = 0 => remove it
- void calc(particle *p, int &blend, int &ts, vec &o, vec &d, bool step = true)
- {
+ void calc(particle *p, int &blend, int &ts, vec &o, vec &d, bool step = true) {
o = p->o;
d = p->d;
if(type&PT_TRACK && p->owner) game::particletrack(p->owner, o, d);
- if(p->fade <= 5)
- {
+ if(p->fade <= 5) {
ts = 1;
blend = 255;
}
- else
- {
+ else {
ts = lastmillis-p->millis;
blend = max(255 - (ts<<8)/p->fade, 0);
- if(p->gravity)
- {
+ if(p->gravity) {
if(ts > p->fade) ts = p->fade;
float t = ts;
o.add(vec(d).mul(t/5000.0f));
o.z -= t*t/(2.0f * 5000.0f * p->gravity);
}
- if(collide && o.z < p->val && step)
- {
- if(collide >= 0)
- {
+ if(collide && o.z < p->val && step) {
+ if(collide >= 0) {
vec surface;
float floorz = rayfloor(vec(o.x, o.y, p->val), surface, RAY_CLIPMAT, COLLIDERADIUS);
float collidez = floorz<0 ? o.z-COLLIDERADIUS : p->val - floorz;
if(o.z >= collidez+COLLIDEERROR)
p->val = collidez+COLLIDEERROR;
- else
- {
+ else {
adddecal(collide, vec(o.x, o.y, collidez), vec(p->o).sub(o).normalize(), 2*p->size, p->color, type&PT_RND4 ? (p->flags>>5)&3 : 0);
blend = 0;
}
@@ -220,41 +184,29 @@ struct partrenderer
}
};
-struct listparticle : particle
-{
+struct listparticle : particle {
listparticle *next;
};
VARP(outlinemeters, 0, 0, 1);
-struct listrenderer : partrenderer
-{
+struct listrenderer : partrenderer {
static listparticle *parempty;
listparticle *list;
-
listrenderer(const char *texname, int texclamp, int type, int collide = 0)
- : partrenderer(texname, texclamp, type, collide), list(NULL)
- {
+ : partrenderer(texname, texclamp, type, collide), list(NULL) {
}
listrenderer(int type, int collide = 0)
- : partrenderer(type, collide), list(NULL)
- {
+ : partrenderer(type, collide), list(NULL) {
}
-
- virtual ~listrenderer()
- {
+ virtual ~listrenderer() {
}
-
- virtual void killpart(listparticle *p)
- {
+ virtual void killpart(listparticle *p) {
}
-
- void reset()
- {
+ void reset() {
if(!list) return;
listparticle *p = list;
- for(;;)
- {
+ for(;;) {
killpart(p);
if(p->next) p = p->next;
else break;
@@ -263,14 +215,10 @@ struct listrenderer : partrenderer
parempty = list;
list = NULL;
}
-
- void resettracked(physent *owner)
- {
+ void resettracked(physent *owner) {
if(!(type&PT_TRACK)) return;
- for(listparticle **prev = &list, *cur = list; cur; cur = *prev)
- {
- if(!owner || cur->owner==owner)
- {
+ for(listparticle **prev = &list, *cur = list; cur; cur = *prev) {
+ if(!owner || cur->owner==owner) {
*prev = cur->next;
cur->next = parempty;
parempty = cur;
@@ -278,11 +226,8 @@ struct listrenderer : partrenderer
else prev = &cur->next;
}
}
-
- particle *addpart(const vec &o, const vec &d, int fade, int color, float size, int gravity)
- {
- if(!parempty)
- {
+ particle *addpart(const vec &o, const vec &d, int fade, int color, float size, int gravity) {
+ if(!parempty) {
listparticle *ps = new listparticle[256];
loopi(255) ps[i].next = &ps[i+1];
ps[255].next = parempty;
@@ -303,44 +248,31 @@ struct listrenderer : partrenderer
p->flags = 0;
return p;
}
-
- int count()
- {
+ int count() {
int num = 0;
listparticle *lp;
for(lp = list; lp; lp = lp->next) num++;
return num;
}
-
- bool haswork()
- {
+ bool haswork() {
return (list != NULL);
}
-
virtual void startrender() = 0;
virtual void endrender() = 0;
virtual void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts) = 0;
-
- void render()
- {
+ void render() {
startrender();
- if(texname)
- {
+ if(texname) {
if(!tex) tex = textureload(texname, texclamp);
glBindTexture(GL_TEXTURE_2D, tex->id);
}
-
- for(listparticle **prev = &list, *p = list; p; p = *prev)
- {
+ for(listparticle **prev = &list, *p = list; p; p = *prev) {
vec o, d;
int blend, ts;
calc(p, blend, ts, o, d, canstep);
- if(blend > 0)
- {
+ if(blend > 0) {
renderpart(p, o, d, blend, ts);
-
- if(p->fade > 5 || !canstep)
- {
+ if(p->fade > 5 || !canstep) {
prev = &p->next;
continue;
}
@@ -351,44 +283,33 @@ struct listrenderer : partrenderer
killpart(p);
parempty = p;
}
-
endrender();
}
};
listparticle *listrenderer::parempty = NULL;
-struct meterrenderer : listrenderer
-{
+struct meterrenderer : listrenderer {
meterrenderer(int type)
- : listrenderer(type|PT_NOTEX|PT_LERP)
- {}
-
- void startrender()
- {
+ : listrenderer(type|PT_NOTEX|PT_LERP) {
+ }
+ void startrender() {
glDisable(GL_BLEND);
gle::defvertex();
}
-
- void endrender()
- {
+ void endrender() {
glEnable(GL_BLEND);
}
-
- void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts)
- {
+ void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts) {
int basetype = type&0xFF;
float scale = FONTH*p->size/80.0f, right = 8, left = p->progress/100.0f*right;
matrix4x3 m(camright, vec(camup).neg(), vec(camdir).neg(), o);
m.scale(scale);
m.translate(-right/2.0f, 0, 0);
-
- if(outlinemeters)
- {
+ if(outlinemeters) {
gle::colorf(0, 0.8f, 0);
gle::begin(GL_TRIANGLE_STRIP);
- loopk(10)
- {
+ loopk(10) {
const vec2 &sc = sincos360[k*(180/(10-1))];
float c = (0.5f + 0.1f)*sc.y, s = 0.5f - (0.5f + 0.1f)*sc.x;
gle::attrib(m.transform(vec2(-c, s)));
@@ -396,36 +317,29 @@ struct meterrenderer : listrenderer
}
gle::end();
}
-
if(basetype==PT_METERVS) gle::colorub(p->color2[0], p->color2[1], p->color2[2]);
else gle::colorf(0, 0, 0);
gle::begin(GL_TRIANGLE_STRIP);
- loopk(10)
- {
+ loopk(10) {
const vec2 &sc = sincos360[k*(180/(10-1))];
float c = 0.5f*sc.y, s = 0.5f - 0.5f*sc.x;
gle::attrib(m.transform(vec2(left + c, s)));
gle::attrib(m.transform(vec2(right + c, s)));
}
gle::end();
-
- if(outlinemeters)
- {
+ if(outlinemeters) {
gle::colorf(0, 0.8f, 0);
gle::begin(GL_TRIANGLE_FAN);
- loopk(10)
- {
+ loopk(10) {
const vec2 &sc = sincos360[k*(180/(10-1))];
float c = (0.5f + 0.1f)*sc.y, s = 0.5f - (0.5f + 0.1f)*sc.x;
gle::attrib(m.transform(vec2(left + c, s)));
}
gle::end();
}
-
gle::color(p->color);
gle::begin(GL_TRIANGLE_STRIP);
- loopk(10)
- {
+ loopk(10) {
const vec2 &sc = sincos360[k*(180/(10-1))];
float c = 0.5f*sc.y, s = 0.5f - 0.5f*sc.x;
gle::attrib(m.transform(vec2(-c, s)));
@@ -436,33 +350,22 @@ struct meterrenderer : listrenderer
};
static meterrenderer meters(PT_METER), metervs(PT_METERVS);
-struct textrenderer : listrenderer
-{
+struct textrenderer : listrenderer {
textrenderer(int type)
- : listrenderer(type)
- {}
-
- void startrender()
- {
+ : listrenderer(type) {
}
-
- void endrender()
- {
+ void startrender() {
}
-
- void killpart(listparticle *p)
- {
+ void endrender() {
+ }
+ void killpart(listparticle *p) {
if(p->text && p->flags&1) delete[] p->text;
}
-
- void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts)
- {
+ void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts) {
float scale = p->size/80.0f, xoff = -(text_width(p->text) + ((p->flags>>1)&7)*FONTH)/2, yoff = 0;
-
matrix4x3 m(camright, vec(camup).neg(), vec(camdir).neg(), o);
m.scale(scale);
m.translate(xoff, yoff, 50);
-
textmatrix = &m;
draw_text(p->text, 0, 0, p->color.r, p->color.g, p->color.b, blend);
textmatrix = NULL;
@@ -470,35 +373,25 @@ struct textrenderer : listrenderer
};
static textrenderer texts(PT_TEXT|PT_LERP);
-struct texticonrenderer : listrenderer
-{
+struct texticonrenderer : listrenderer {
texticonrenderer(const char *texname, int type)
- : listrenderer(texname, 3, type)
- {}
-
- void startrender()
- {
+ : listrenderer(texname, 3, type) {
+ }
+ void startrender() {
gle::defvertex();
gle::deftexcoord0();
gle::defcolor(4, GL_UNSIGNED_BYTE);
gle::begin(GL_QUADS);
}
-
- void endrender()
- {
+ void endrender() {
gle::end();
}
-
- void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts)
- {
+ void renderpart(listparticle *p, const vec &o, const vec &d, int blend, int ts) {
float scale = p->size/80.0f, xoff = p->val, yoff = 0;
-
matrix4x3 m(camright, vec(camup).neg(), vec(camdir).neg(), o);
m.scale(scale);
m.translate(xoff, yoff, 50);
-
float tx = 0.25f*(p->flags&3), ty = 0.25f*((p->flags>>2)&3);
-
gle::attrib(m.transform(vec2(0, 0)));
gle::attrib(tx, ty);
gle::attrib(p->color, blend);
@@ -516,19 +409,16 @@ struct texticonrenderer : listrenderer
static texticonrenderer texticons("packages/hud/items.png", PT_TEXTICON|PT_LERP);
template<int T>
-static inline void modifyblend(const vec &o, int &blend)
-{
+static inline void modifyblend(const vec &o, int &blend) {
blend = min(blend<<2, 255);
}
template<>
-inline void modifyblend<PT_TAPE>(const vec &o, int &blend)
-{
+inline void modifyblend<PT_TAPE>(const vec &o, int &blend) {
}
template<int T>
-static inline void genpos(const vec &o, const vec &d, float size, int grav, int ts, partvert *vs)
-{
+static inline void genpos(const vec &o, const vec &d, float size, int grav, int ts, partvert *vs) {
vec udir = vec(camup).sub(camright).mul(size);
vec vdir = vec(camup).add(camright).mul(size);
vs[0].pos = vec(o.x + udir.x, o.y + udir.y, o.z + udir.z);
@@ -538,8 +428,7 @@ static inline void genpos(const vec &o, const vec &d, float size, int grav, int
}
template<>
-inline void genpos<PT_TAPE>(const vec &o, const vec &d, float size, int ts, int grav, partvert *vs)
-{
+inline void genpos<PT_TAPE>(const vec &o, const vec &d, float size, int ts, int grav, partvert *vs) {
vec dir1 = d, dir2 = d, c;
dir1.sub(o);
dir2.sub(camera1->o);
@@ -551,8 +440,7 @@ inline void genpos<PT_TAPE>(const vec &o, const vec &d, float size, int ts, int
}
template<>
-inline void genpos<PT_TRAIL>(const vec &o, const vec &d, float size, int ts, int grav, partvert *vs)
-{
+inline void genpos<PT_TRAIL>(const vec &o, const vec &d, float size, int ts, int grav, partvert *vs) {
vec e = d;
if(grav) e.z -= float(ts)/grav;
e.div(-75.0f).add(o);
@@ -560,8 +448,7 @@ inline void genpos<PT_TRAIL>(const vec &o, const vec &d, float size, int ts, int
}
template<int T>
-static inline void genrotpos(const vec &o, const vec &d, float size, int grav, int ts, partvert *vs, int rot)
-{
+static inline void genrotpos(const vec &o, const vec &d, float size, int grav, int ts, partvert *vs, int rot) {
genpos<T>(o, d, size, grav, ts, vs);
}
@@ -571,8 +458,7 @@ static inline void genrotpos(const vec &o, const vec &d, float size, int grav, i
vec( 1, -1, 0).rotate_around_z(n*2*M_PI/32.0f), \
vec(-1, -1, 0).rotate_around_z(n*2*M_PI/32.0f) \
}
-static const vec rotcoeffs[32][4] =
-{
+static const vec rotcoeffs[32][4] = {
ROTCOEFFS(0), ROTCOEFFS(1), ROTCOEFFS(2), ROTCOEFFS(3), ROTCOEFFS(4), ROTCOEFFS(5), ROTCOEFFS(6), ROTCOEFFS(7),
ROTCOEFFS(8), ROTCOEFFS(9), ROTCOEFFS(10), ROTCOEFFS(11), ROTCOEFFS(12), ROTCOEFFS(13), ROTCOEFFS(14), ROTCOEFFS(15),
ROTCOEFFS(16), ROTCOEFFS(17), ROTCOEFFS(18), ROTCOEFFS(19), ROTCOEFFS(20), ROTCOEFFS(21), ROTCOEFFS(22), ROTCOEFFS(7),
@@ -580,8 +466,7 @@ static const vec rotcoeffs[32][4] =
};
template<>
-inline void genrotpos<PT_PART>(const vec &o, const vec &d, float size, int grav, int ts, partvert *vs, int rot)
-{
+inline void genrotpos<PT_PART>(const vec &o, const vec &d, float size, int grav, int ts, partvert *vs, int rot) {
const vec *coeffs = rotcoeffs[rot];
(vs[0].pos = o).add(vec(camright).mul(coeffs[0].x*size)).add(vec(camup).mul(coeffs[0].y*size));
(vs[1].pos = o).add(vec(camright).mul(coeffs[1].x*size)).add(vec(camup).mul(coeffs[1].y*size));
@@ -590,30 +475,25 @@ inline void genrotpos<PT_PART>(const vec &o, const vec &d, float size, int grav,
}
template<int T>
-static inline void seedpos(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int grav)
-{
- if(grav)
- {
+static inline void seedpos(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int grav) {
+ if(grav) {
vec end(o);
float t = fade;
end.add(vec(d).mul(t/5000.0f));
end.z -= t*t/(2.0f * 5000.0f * grav);
pe.extendbb(end, size);
-
float tpeak = d.z*grav;
if(tpeak > 0 && tpeak < fade) pe.extendbb(o.z + 1.5f*d.z*tpeak/5000.0f, size);
}
}
template<>
-inline void seedpos<PT_TAPE>(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int grav)
-{
+inline void seedpos<PT_TAPE>(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int grav) {
pe.extendbb(d, size);
}
template<>
-inline void seedpos<PT_TRAIL>(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int grav)
-{
+inline void seedpos<PT_TRAIL>(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int grav) {
vec e = d;
if(grav) e.z -= float(fade)/grav;
e.div(-75.0f).add(o);
@@ -621,30 +501,23 @@ inline void seedpos<PT_TRAIL>(particleemitter &pe, const vec &o, const vec &d, i
}
template<int T>
-struct varenderer : partrenderer
-{
+struct varenderer : partrenderer {
partvert *verts;
particle *parts;
int maxparts, numparts, lastupdate, rndmask;
GLuint vbo;
-
varenderer(const char *texname, int type, int collide = 0)
: partrenderer(texname, 3, type, collide),
- verts(NULL), parts(NULL), maxparts(0), numparts(0), lastupdate(-1), rndmask(0), vbo(0)
- {
+ verts(NULL), parts(NULL), maxparts(0), numparts(0), lastupdate(-1), rndmask(0), vbo(0) {
if(type & PT_HFLIP) rndmask |= 0x01;
if(type & PT_VFLIP) rndmask |= 0x02;
if(type & PT_ROT) rndmask |= 0x1F<<2;
if(type & PT_RND4) rndmask |= 0x03<<5;
}
-
- void cleanup()
- {
+ void cleanup() {
if(vbo) { glDeleteBuffers_(1, &vbo); vbo = 0; }
}
-
- void init(int n)
- {
+ void init(int n) {
DELETEA(parts);
DELETEA(verts);
parts = new particle[n];
@@ -653,36 +526,25 @@ struct varenderer : partrenderer
numparts = 0;
lastupdate = -1;
}
-
- void reset()
- {
+ void reset() {
numparts = 0;
lastupdate = -1;
}
-
- void resettracked(physent *owner)
- {
+ void resettracked(physent *owner) {
if(!(type&PT_TRACK)) return;
- loopi(numparts)
- {
+ loopi(numparts) {
particle *p = parts+i;
if(!owner || (p->owner == owner)) p->fade = -1;
}
lastupdate = -1;
}
-
- int count()
- {
+ int count() {
return numparts;
}
-
- bool haswork()
- {
+ bool haswork() {
return (numparts > 0);
}
-
- particle *addpart(const vec &o, const vec &d, int fade, int color, float size, int gravity)
- {
+ particle *addpart(const vec &o, const vec &d, int fade, int color, float size, int gravity) {
particle *p = parts + (numparts < maxparts ? numparts++ : rnd(maxparts)); //next free slot, or kill a random kitten
p->o = o;
p->d = d;
@@ -696,42 +558,30 @@ struct varenderer : partrenderer
lastupdate = -1;
return p;
}
-
- void seedemitter(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int gravity)
- {
+ void seedemitter(particleemitter &pe, const vec &o, const vec &d, int fade, float size, int gravity) {
pe.maxfade = max(pe.maxfade, fade);
size *= SQRT2;
pe.extendbb(o, size);
-
seedpos<T>(pe, o, d, fade, size, gravity);
if(!gravity) return;
-
vec end(o);
float t = fade;
end.add(vec(d).mul(t/5000.0f));
end.z -= t*t/(2.0f * 5000.0f * gravity);
pe.extendbb(end, size);
-
float tpeak = d.z*gravity;
if(tpeak > 0 && tpeak < fade) pe.extendbb(o.z + 1.5f*d.z*tpeak/5000.0f, size);
}
-
- void genverts(particle *p, partvert *vs, bool regen)
- {
+ void genverts(particle *p, partvert *vs, bool regen) {
vec o, d;
int blend, ts;
-
calc(p, blend, ts, o, d);
if(blend <= 1 || p->fade <= 5) p->fade = -1; //mark to remove on next pass (i.e. after render)
-
modifyblend<T>(o, blend);
-
- if(regen)
- {
+ if(regen) {
p->flags &= ~0x80;
-
- #define SETTEXCOORDS(u1c, u2c, v1c, v2c, body) \
- { \
+ #define SETTEXCOORDS(u1c, u2c, v1c, v2c, body) { \
+ \
float u1 = u1c, u2 = u2c, v1 = v1c, v2 = v2c; \
body; \
vs[0].tc = vec2(u1, v1); \
@@ -739,22 +589,18 @@ struct varenderer : partrenderer
vs[2].tc = vec2(u2, v2); \
vs[3].tc = vec2(u1, v2); \
}
- if(type&PT_RND4)
- {
+ if(type&PT_RND4) {
float tx = 0.5f*((p->flags>>5)&1), ty = 0.5f*((p->flags>>6)&1);
- SETTEXCOORDS(tx, tx + 0.5f, ty, ty + 0.5f,
- {
+ SETTEXCOORDS(tx, tx + 0.5f, ty, ty + 0.5f, {
if(p->flags&0x01) swap(u1, u2);
if(p->flags&0x02) swap(v1, v2);
});
}
- else if(type&PT_ICON)
- {
+ else if(type&PT_ICON) {
float tx = 0.25f*(p->flags&3), ty = 0.25f*((p->flags>>2)&3);
SETTEXCOORDS(tx, tx + 0.25f, ty, ty + 0.25f, {});
}
else SETTEXCOORDS(0, 1, 0, 1, {});
-
#define SETCOLOR(r, g, b, a) \
do { \
bvec4 col(r, g, b, a); \
@@ -766,21 +612,15 @@ struct varenderer : partrenderer
}
else if(type&PT_MOD) SETMODCOLOR;
else loopi(4) vs[i].color.a = blend;
-
if(type&PT_ROT) genrotpos<T>(o, d, p->size, ts, p->gravity, vs, (p->flags>>2)&0x1F);
else genpos<T>(o, d, p->size, ts, p->gravity, vs);
}
-
- void genverts()
- {
- loopi(numparts)
- {
+ void genverts() {
+ loopi(numparts) {
particle *p = &parts[i];
partvert *vs = &verts[i*4];
- if(p->fade < 0)
- {
- do
- {
+ if(p->fade < 0) {
+ do {
--numparts;
if(numparts <= i) return;
}
@@ -791,26 +631,19 @@ struct varenderer : partrenderer
else genverts(p, vs, (p->flags&0x80)!=0);
}
}
-
- void update()
- {
+ void update() {
if(lastmillis == lastupdate && vbo) return;
lastupdate = lastmillis;
-
genverts();
-
if(!vbo) glGenBuffers_(1, &vbo);
gle::bindvbo(vbo);
glBufferData_(GL_ARRAY_BUFFER, maxparts*4*sizeof(partvert), NULL, GL_STREAM_DRAW);
glBufferSubData_(GL_ARRAY_BUFFER, 0, numparts*4*sizeof(partvert), verts);
gle::clearvbo();
}
-
- void render()
- {
+ void render() {
if(!tex) tex = textureload(texname, texclamp);
glBindTexture(GL_TEXTURE_2D, tex->id);
-
gle::bindvbo(vbo);
const partvert *ptr = 0;
gle::vertexpointer(sizeof(partvert), ptr->pos.v);
@@ -820,9 +653,7 @@ struct varenderer : partrenderer
gle::enabletexcoord0();
gle::enablecolor();
gle::enablequads();
-
gle::drawquads(0, numparts);
-
gle::disablequads();
gle::disablevertex();
gle::disabletexcoord0();
@@ -830,35 +661,24 @@ struct varenderer : partrenderer
gle::clearvbo();
}
};
+
typedef varenderer<PT_PART> quadrenderer;
typedef varenderer<PT_TAPE> taperenderer;
typedef varenderer<PT_TRAIL> trailrenderer;
-#include "explosion.h"
-#include "lightning.h"
-
-struct softquadrenderer : quadrenderer
-{
+struct softquadrenderer : quadrenderer {
softquadrenderer(const char *texname, int type, int collide = 0)
- : quadrenderer(texname, type|PT_SOFT, collide)
- {
+ : quadrenderer(texname, type|PT_SOFT, collide) {
}
};
-static partrenderer *parts[] =
-{
+static partrenderer *parts[] = {
new quadrenderer("<grey>packages/particles/blood.png", PT_PART|PT_FLIP|PT_MOD|PT_RND4, DECAL_BLOOD), // blood spats (note: rgb is inverted)
new trailrenderer("packages/particles/base.png", PT_TRAIL|PT_LERP), // water, entity
new quadrenderer("<grey>packages/particles/smoke.png", PT_PART|PT_FLIP|PT_LERP), // smoke
new quadrenderer("<grey>packages/particles/steam.png", PT_PART|PT_FLIP), // steam
new quadrenderer("<grey>packages/particles/flames.png", PT_PART|PT_HFLIP|PT_RND4|PT_GLARE), // flame on - no flipping please, they have orientation
- new quadrenderer("packages/particles/ball1.png", PT_PART|PT_FEW|PT_GLARE), // fireball1
- new quadrenderer("packages/particles/ball2.png", PT_PART|PT_FEW|PT_GLARE), // fireball2
- new quadrenderer("packages/particles/ball3.png", PT_PART|PT_FEW|PT_GLARE), // fireball3
new taperenderer("packages/particles/flare.png", PT_TAPE|PT_GLARE), // streak
- &lightnings, // lightning
- &fireballs, // explosion fireball
- &bluefireballs, // bluish explosion fireball
new quadrenderer("packages/particles/spark.png", PT_PART|PT_FLIP|PT_GLARE), // sparks
new quadrenderer("packages/particles/base.png", PT_PART|PT_FLIP|PT_GLARE), // edit mode entities
new quadrenderer("<grey>packages/particles/snow.png", PT_PART|PT_FLIP|PT_RND4, -1), // colliding snow
@@ -876,73 +696,54 @@ static partrenderer *parts[] =
VARFP(maxparticles, 10, 4000, 40000, initparticles());
VARFP(fewparticles, 10, 100, 40000, initparticles());
-void initparticles()
-{
+void initparticles() {
if(!particleshader) particleshader = lookupshaderbyname("particle");
if(!particlenotextureshader) particlenotextureshader = lookupshaderbyname("particlenotexture");
loopi(sizeof(parts)/sizeof(parts[0])) parts[i]->init(parts[i]->type&PT_FEW ? min(fewparticles, maxparticles) : maxparticles);
}
-void clearparticles()
-{
+void clearparticles() {
loopi(sizeof(parts)/sizeof(parts[0])) parts[i]->reset();
clearparticleemitters();
}
-void cleanupparticles()
-{
+void cleanupparticles() {
loopi(sizeof(parts)/sizeof(parts[0])) parts[i]->cleanup();
}
-void removetrackedparticles(physent *owner)
-{
+void removetrackedparticles(physent *owner) {
loopi(sizeof(parts)/sizeof(parts[0])) parts[i]->resettracked(owner);
}
-void renderparticles(bool mainpass)
-{
+void renderparticles(bool mainpass) {
canstep = mainpass;
-
- loopi(sizeof(parts)/sizeof(parts[0]))
- {
+ loopi(sizeof(parts)/sizeof(parts[0])) {
parts[i]->update();
}
-
bool rendered = false;
uint lastflags = PT_LERP|PT_SHADER,
flagmask = PT_LERP|PT_MOD|PT_SHADER|PT_NOTEX;
-
- loopi(sizeof(parts)/sizeof(parts[0]))
- {
+ loopi(sizeof(parts)/sizeof(parts[0])) {
partrenderer *p = parts[i];
if(!(p->type&PT_GLARE)) continue;
if(!p->haswork()) continue;
-
- if(!rendered)
- {
+ if(!rendered) {
rendered = true;
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
GLOBALPARAMF(colorscale, 1, 1, 1, 1);
}
-
uint flags = p->type & flagmask, changedbits = (flags ^ lastflags);
- if(changedbits)
- {
- if(changedbits&(PT_LERP|PT_MOD))
- {
+ if(changedbits) {
+ if(changedbits&(PT_LERP|PT_MOD)) {
if(flags&PT_LERP) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
else if(flags&PT_MOD) glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
else glBlendFunc(GL_SRC_ALPHA, GL_ONE);
}
- if(!(flags&PT_SHADER))
- {
- if(changedbits&(PT_SOFT|PT_SHADER|PT_NOTEX|PT_LERP))
- {
- if(flags&PT_SOFT)
- {
+ if(!(flags&PT_SHADER)) {
+ if(changedbits&(PT_SOFT|PT_SHADER|PT_NOTEX|PT_LERP)) {
+ if(flags&PT_SOFT) {
SETSHADER(particlesoft);
}
else if(flags&PT_NOTEX) particlenotextureshader->set();
@@ -953,9 +754,7 @@ void renderparticles(bool mainpass)
}
p->render();
}
-
- if(rendered)
- {
+ if(rendered) {
if(lastflags&(PT_LERP|PT_MOD)) glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
@@ -964,11 +763,9 @@ void renderparticles(bool mainpass)
static int addedparticles = 0;
-static inline particle *newparticle(const vec &o, const vec &d, int fade, int type, int color, float size, int gravity = 0)
-{
+static inline particle *newparticle(const vec &o, const vec &d, int fade, int type, int color, float size, int gravity = 0) {
static particle dummy;
- if(seedemitter)
- {
+ if(seedemitter) {
parts[type]->seedemitter(*seedemitter, o, d, fade, size, gravity);
return &dummy;
}
@@ -979,17 +776,14 @@ static inline particle *newparticle(const vec &o, const vec &d, int fade, int ty
VARP(maxparticledistance, 256, 1024, 4096);
-static void splash(int type, int color, int radius, int num, int fade, const vec &p, float size, int gravity)
-{
+static void splash(int type, int color, int radius, int num, int fade, const vec &p, float size, int gravity) {
if(camera1->o.dist(p) > maxparticledistance && !seedemitter) return;
float collidez = parts[type]->collide ? p.z - raycube(p, vec(0, 0, -1), COLLIDERADIUS, RAY_CLIPMAT) + (parts[type]->collide >= 0 ? COLLIDEERROR : 0) : -1;
int fmin = 1;
int fmax = fade*3;
- loopi(num)
- {
+ loopi(num) {
int x, y, z;
- do
- {
+ do {
x = rnd(radius*2)-radius;
y = rnd(radius*2)-radius;
z = rnd(radius*2)-radius;
@@ -1001,41 +795,35 @@ static void splash(int type, int color, int radius, int num, int fade, const vec
}
}
-static void regularsplash(int type, int color, int radius, int num, int fade, const vec &p, float size, int gravity, int delay = 0)
-{
+static void regularsplash(int type, int color, int radius, int num, int fade, const vec &p, float size, int gravity, int delay = 0) {
if(!canemitparticles() || (delay > 0 && rnd(delay) != 0)) return;
splash(type, color, radius, num, fade, p, size, gravity);
}
-bool canaddparticles()
-{
+bool canaddparticles() {
return !renderedgame && !shadowmapping && !minimized;
}
-void regular_particle_splash(int type, int num, int fade, const vec &p, int color, float size, int radius, int gravity, int delay)
-{
+void regular_particle_splash(int type, int num, int fade, const vec &p, int color, float size, int radius, int gravity, int delay) {
if(!canaddparticles()) return;
regularsplash(type, color, radius, num, fade, p, size, gravity, delay);
}
-void particle_splash(int type, int num, int fade, const vec &p, int color, float size, int radius, int gravity)
-{
+void particle_splash(int type, int num, int fade, const vec &p, int color, float size, int radius, int gravity) {
if(!canaddparticles()) return;
splash(type, color, radius, num, fade, p, size, gravity);
}
VARP(maxtrail, 1, 500, 10000);
-void particle_trail(int type, int fade, const vec &s, const vec &e, int color, float size, int gravity)
-{
+void particle_trail(int type, int fade, const vec &s, const vec &e, int color, float size, int gravity) {
if(!canaddparticles()) return;
vec v;
float d = e.dist(s, v);
int steps = clamp(int(d*2), 1, maxtrail);
v.div(steps);
vec p = s;
- loopi(steps)
- {
+ loopi(steps) {
p.add(v);
vec tmp = vec(float(rnd(11)-5), float(rnd(11)-5), float(rnd(11)-5));
newparticle(p, tmp, rnd(fade)+fade, type, color, size, gravity);
@@ -1045,8 +833,7 @@ void particle_trail(int type, int fade, const vec &s, const vec &e, int color, f
VARP(particletext, 0, 1, 1);
VARP(maxparticletextdistance, 0, 128, 10000);
-void particle_text(const vec &s, const char *t, int type, int fade, int color, float size, int gravity, int icons)
-{
+void particle_text(const vec &s, const char *t, int type, int fade, int color, float size, int gravity, int icons) {
if(!canaddparticles()) return;
if(!particletext || camera1->o.dist(s) > maxparticletextdistance) return;
particle *p = newparticle(s, vec(0, 0, 1), fade, type, color, size, gravity);
@@ -1054,8 +841,7 @@ void particle_text(const vec &s, const char *t, int type, int fade, int color, f
p->flags = icons<<1;
}
-void particle_textcopy(const vec &s, const char *t, int type, int fade, int color, float size, int gravity)
-{
+void particle_textcopy(const vec &s, const char *t, int type, int fade, int color, float size, int gravity) {
if(!canaddparticles()) return;
if(!particletext || camera1->o.dist(s) > maxparticletextdistance) return;
particle *p = newparticle(s, vec(0, 0, 1), fade, type, color, size, gravity);
@@ -1063,8 +849,7 @@ void particle_textcopy(const vec &s, const char *t, int type, int fade, int colo
p->flags = 1;
}
-void particle_texticon(const vec &s, int ix, int iy, float offset, int type, int fade, int color, float size, int gravity)
-{
+void particle_texticon(const vec &s, int ix, int iy, float offset, int type, int fade, int color, float size, int gravity) {
if(!canaddparticles()) return;
if(!particletext || camera1->o.dist(s) > maxparticletextdistance) return;
particle *p = newparticle(s, vec(0, 0, 1), fade, type, color, size, gravity);
@@ -1072,15 +857,13 @@ void particle_texticon(const vec &s, int ix, int iy, float offset, int type, int
p->val = offset;
}
-void particle_icon(const vec &s, int ix, int iy, int type, int fade, int color, float size, int gravity)
-{
+void particle_icon(const vec &s, int ix, int iy, int type, int fade, int color, float size, int gravity) {
if(!canaddparticles()) return;
particle *p = newparticle(s, vec(0, 0, 1), fade, type, color, size, gravity);
p->flags |= ix | (iy<<2);
}
-void particle_meter(const vec &s, float val, int type, int fade, int color, int color2, float size)
-{
+void particle_meter(const vec &s, float val, int type, int fade, int color, int color2, float size) {
if(!canaddparticles()) return;
particle *p = newparticle(s, vec(0, 0, 1), fade, type, color, size);
p->color2[0] = color2>>16;
@@ -1089,31 +872,20 @@ void particle_meter(const vec &s, float val, int type, int fade, int color, int
p->progress = clamp(int(val*100), 0, 100);
}
-void particle_flare(const vec &p, const vec &dest, int fade, int type, int color, float size, physent *owner)
-{
+void particle_flare(const vec &p, const vec &dest, int fade, int type, int color, float size, physent *owner) {
if(!canaddparticles()) return;
newparticle(p, dest, fade, type, color, size)->owner = owner;
}
-void particle_fireball(const vec &dest, float maxsize, int type, int fade, int color, float size)
-{
- if(!canaddparticles()) return;
- float growth = maxsize - size;
- if(fade < 0) fade = int(growth*20);
- newparticle(dest, vec(0, 0, 1), fade, type, color, size)->val = growth;
-}
-
//dir = 0..6 where 0=up
-static inline vec offsetvec(vec o, int dir, int dist)
-{
+static inline vec offsetvec(vec o, int dir, int dist) {
vec v = vec(o);
v[(2+dir)%3] += (dir>2)?(-dist):dist;
return v;
}
//converts a 16bit color to 24bit
-static inline int colorfromattr(int attr)
-{
+static inline int colour_from_attribute(int attr) {
return (((attr&0xF)<<4) | ((attr&0xF0)<<8) | ((attr&0xF00)<<12)) + 0x0F0F0F;
}
@@ -1128,19 +900,15 @@ static inline int colorfromattr(int attr)
* 24..26 flat plane
* +32 to inverse direction
*/
-void regularshape(int type, int radius, int color, int dir, int num, int fade, const vec &p, float size, int gravity, int vel = 200)
-{
+void regularshape(int type, int radius, int color, int dir, int num, int fade, const vec &p, float size, int gravity, int vel = 200) {
if(!canemitparticles()) return;
-
int basetype = parts[type]->type&0xFF;
- bool flare = (basetype == PT_TAPE) || (basetype == PT_LIGHTNING),
+ bool flare = (basetype == PT_TAPE),
inv = (dir&0x20)!=0, taper = (dir&0x40)!=0 && !seedemitter;
dir &= 0x1F;
- loopi(num)
- {
+ loopi(num) {
vec to, from;
- if(dir < 12)
- {
+ if(dir < 12) {
const vec2 &sc = sincos360[rnd(360)];
to[dir%3] = sc.y*radius;
to[(dir+1)%3] = sc.x*radius;
@@ -1148,20 +916,17 @@ void regularshape(int type, int radius, int color, int dir, int num, int fade, c
to.add(p);
if(dir < 3) //circle
from = p;
- else if(dir < 6) //cylinder
- {
+ else if(dir < 6) { //cylinder {
from = to;
to[(dir+2)%3] += radius;
from[(dir+2)%3] -= radius;
}
- else //cone
- {
+ else { //cone {
from = p;
to[(dir+2)%3] += (dir < 9)?radius:(-radius);
}
}
- else if(dir < 15) //plane
- {
+ else if(dir < 15) { //plane {
to[dir%3] = float(rnd(radius<<4)-(radius<<3))/8.0;
to[(dir+1)%3] = float(rnd(radius<<4)-(radius<<3))/8.0;
to[(dir+2)%3] = radius;
@@ -1169,15 +934,12 @@ void regularshape(int type, int radius, int color, int dir, int num, int fade, c
from = to;
from[(dir+2)%3] -= 2*radius;
}
- else if(dir < 21) //line
- {
- if(dir < 18)
- {
+ else if(dir < 21) { //line {
+ if(dir < 18) {
to[dir%3] = float(rnd(radius<<4)-(radius<<3))/8.0;
to[(dir+1)%3] = 0.0;
}
- else
- {
+ else {
to[dir%3] = 0.0;
to[(dir+1)%3] = float(rnd(radius<<4)-(radius<<3))/8.0;
}
@@ -1186,14 +948,12 @@ void regularshape(int type, int radius, int color, int dir, int num, int fade, c
from = to;
to[(dir+2)%3] += radius;
}
- else if(dir < 24) //sphere
- {
+ else if(dir < 24) { //sphere {
to = vec(2*M_PI*float(rnd(1000))/1000.0, M_PI*float(rnd(1000)-500)/1000.0).mul(radius);
to.add(p);
from = p;
}
- else if(dir < 27) // flat plane
- {
+ else if(dir < 27) { // flat plane {
to[dir%3] = float(rndscale(2*radius)-radius);
to[(dir+1)%3] = float(rndscale(2*radius)-radius);
to[(dir+2)%3] = 0.0;
@@ -1201,23 +961,17 @@ void regularshape(int type, int radius, int color, int dir, int num, int fade, c
from = to;
}
else from = to = p;
-
if(inv) swap(from, to);
-
- if(taper)
- {
+ if(taper) {
float dist = clamp(from.dist2(camera1->o)/maxparticledistance, 0.0f, 1.0f);
- if(dist > 0.2f)
- {
+ if(dist > 0.2f) {
dist = 1 - (dist - 0.2f)/0.8f;
if(rnd(0x10000) > dist*dist*0xFFFF) continue;
}
}
-
if(flare)
newparticle(from, to, rnd(fade*3)+1, type, color, size, gravity);
- else
- {
+ else {
vec d = vec(to).sub(from).rescale(vel); //velocity
particle *n = newparticle(from, d, rnd(fade*3)+1, type, color, size, gravity);
if(parts[type]->collide)
@@ -1226,14 +980,11 @@ void regularshape(int type, int radius, int color, int dir, int num, int fade, c
}
}
-static void regularflame(int type, const vec &p, float radius, float height, int color, int density = 3, float scale = 2.0f, float speed = 200.0f, float fade = 600.0f, int gravity = -15)
-{
+static void regularflame(int type, const vec &p, float radius, float height, int color, int density = 3, float scale = 2.0f, float speed = 200.0f, float fade = 600.0f, int gravity = -15) {
if(!canemitparticles()) return;
-
float size = scale * min(radius, height);
vec v(0, 0, min(1.0f, height)*speed);
- loopi(density)
- {
+ loopi(density) {
vec s = p;
s.x += rndscale(radius*2.0f)-radius;
s.y += rndscale(radius*2.0f)-radius;
@@ -1241,65 +992,48 @@ static void regularflame(int type, const vec &p, float radius, float height, int
}
}
-void regular_particle_flame(int type, const vec &p, float radius, float height, int color, int density, float scale, float speed, float fade, int gravity)
-{
+void regular_particle_flame(int type, const vec &p, float radius, float height, int color, int density, float scale, float speed, float fade, int gravity) {
if(!canaddparticles()) return;
regularflame(type, p, radius, height, color, density, scale, speed, fade, gravity);
}
-static void makeparticles(entity &e)
-{
- switch(e.attr1)
- {
- case 0: //fire and smoke - <radius> <height> <rgb> - 0 values default to compat for old maps
- {
- //regularsplash(PART_FIREBALL1, 0xFFC8C8, 150, 1, 40, e.o, 4.8f);
- //regularsplash(PART_SMOKE, 0x897661, 50, 1, 200, vec(e.o.x, e.o.y, e.o.z+3.0f), 2.4f, -20, 3);
+static void makeparticles(entity &e) {
+ switch(e.attr1) {
+ case 0: { //fire and smoke - <radius> <height> <rgb> - 0 values default to compat for old maps {
float radius = e.attr2 ? float(e.attr2)/100.0f : 1.5f,
height = e.attr3 ? float(e.attr3)/100.0f : radius/3;
- regularflame(PART_FLAME, e.o, radius, height, e.attr4 ? colorfromattr(e.attr4) : 0x903020, 3, 2.0f);
+ regularflame(PART_FLAME, e.o, radius, height, e.attr4 ? colour_from_attribute(e.attr4) : 0x903020, 3, 2.0f);
regularflame(PART_SMOKE, vec(e.o.x, e.o.y, e.o.z + 4.0f*min(radius, height)), radius, height, 0x303020, 1, 4.0f, 100.0f, 2000.0f, -20);
break;
}
case 1: //steam vent - <dir>
regularsplash(PART_STEAM, 0x897661, 50, 1, 200, offsetvec(e.o, e.attr2, rnd(10)), 2.4f, -20);
break;
- case 2: //water fountain - <dir>
- {
+ case 2: { //water fountain - <dir> {
int color;
- if(e.attr3 > 0) color = colorfromattr(e.attr3);
- else
- {
- int mat = clamp(-e.attr3, 0, 3);
- color = 0xff7700;
- }
+ if(e.attr3 > 0) color = colour_from_attribute(e.attr3);
+ else color = 0xff7700;
regularsplash(PART_WATER, color, 150, 4, 200, offsetvec(e.o, e.attr2, rnd(10)), 0.6f, 2);
break;
}
- case 3: //fire ball - <size> <rgb>
- newparticle(e.o, vec(0, 0, 1), 1, PART_EXPLOSION, colorfromattr(e.attr3), 4.0f)->val = 1+e.attr2;
- break;
- case 4: //tape - <dir> <length> <rgb>
- case 7: //lightning
case 9: //steam
+ case 4: //tape - <dir> <length> <rgb>
case 10: //water
- case 13: //snow
- {
- static const int typemap[] = { PART_STREAK, -1, -1, PART_LIGHTNING, -1, PART_STEAM, PART_WATER, -1, -1, PART_SNOW };
- static const float sizemap[] = { 0.28f, 0.0f, 0.0f, 1.0f, 0.0f, 2.4f, 0.60f, 0.0f, 0.0f, 0.5f };
+ case 13: { //snow {
+ static const int typemap[] = { PART_STREAK, -1, -1, -1, -1, PART_STEAM, PART_WATER, -1, -1, PART_SNOW };
+ static const float sizemap[] = { 0.28f, 0.0f, 0.0f, 0.0f, 0.0f, 2.4f, 0.60f, 0.0f, 0.0f, 0.5f };
static const int gravmap[] = { 0, 0, 0, 0, 0, -20, 2, 0, 0, 20 };
int type = typemap[e.attr1-4];
float size = sizemap[e.attr1-4];
int gravity = gravmap[e.attr1-4];
- if(e.attr2 >= 256) regularshape(type, max(1+e.attr3, 1), colorfromattr(e.attr4), e.attr2-256, 5, e.attr5 > 0 ? min(int(e.attr5), 10000) : 200, e.o, size, gravity);
- else newparticle(e.o, offsetvec(e.o, e.attr2, max(1+e.attr3, 0)), 1, type, colorfromattr(e.attr4), size, gravity);
+ if(e.attr2 >= 256) regularshape(type, max(1+e.attr3, 1), colour_from_attribute(e.attr4), e.attr2-256, 5, e.attr5 > 0 ? min(int(e.attr5), 10000) : 200, e.o, size, gravity);
+ else newparticle(e.o, offsetvec(e.o, e.attr2, max(1+e.attr3, 0)), 1, type, colour_from_attribute(e.attr4), size, gravity);
break;
}
case 5: //meter, metervs - <percent> <rgb> <rgb2>
- case 6:
- {
- particle *p = newparticle(e.o, vec(0, 0, 1), 1, e.attr1==5 ? PART_METER : PART_METER_VS, colorfromattr(e.attr3), 2.0f);
- int color2 = colorfromattr(e.attr4);
+ case 6: {
+ particle *p = newparticle(e.o, vec(0, 0, 1), 1, e.attr1==5 ? PART_METER : PART_METER_VS, colour_from_attribute(e.attr3), 2.0f);
+ int color2 = colour_from_attribute(e.attr4);
p->color2[0] = color2>>16;
p->color2[1] = (color2>>8)&0xFF;
p->color2[2] = color2&0xFF;
@@ -1307,10 +1041,10 @@ static void makeparticles(entity &e)
break;
}
case 11: // flame <radius> <height> <rgb> - radius=100, height=100 is the classic size
- regularflame(PART_FLAME, e.o, float(e.attr2)/100.0f, float(e.attr3)/100.0f, colorfromattr(e.attr4), 3, 2.0f);
+ regularflame(PART_FLAME, e.o, float(e.attr2)/100.0f, float(e.attr3)/100.0f, colour_from_attribute(e.attr4), 3, 2.0f);
break;
case 12: // smoke plume <radius> <height> <rgb>
- regularflame(PART_SMOKE, e.o, float(e.attr2)/100.0f, float(e.attr3)/100.0f, colorfromattr(e.attr4), 1, 4.0f, 100.0f, 2000.0f, -20);
+ regularflame(PART_SMOKE, e.o, float(e.attr2)/100.0f, float(e.attr3)/100.0f, colour_from_attribute(e.attr4), 1, 4.0f, 100.0f, 2000.0f, -20);
break;
case 32: //lens flares - plain/sparkle/sun/sparklesun <red> <green> <blue>
case 33:
@@ -1318,8 +1052,7 @@ static void makeparticles(entity &e)
case 35:
break;
default:
- if(!editmode)
- {
+ if(!editmode) {
defformatstring(ds, "particles %d?", e.attr1);
particle_textcopy(e.o, ds, PART_TEXT, 1, 0x6496FF, 2.0f);
}
@@ -1327,10 +1060,8 @@ static void makeparticles(entity &e)
}
}
-bool printparticles(extentity &e, char *buf, int len)
-{
- switch(e.attr1)
- {
+bool printparticles(extentity &e, char *buf, int len) {
+ switch(e.attr1) {
case 0: case 4: case 7: case 8: case 9: case 10: case 11: case 12: case 13:
nformatstring(buf, len, "%s %d %d %d 0x%.3hX %d", entities::entname(e.type), e.attr1, e.attr2, e.attr3, e.attr4, e.attr5);
return true;
@@ -1344,13 +1075,11 @@ bool printparticles(extentity &e, char *buf, int len)
return false;
}
-void seedparticles()
-{
+void seedparticles() {
renderprogress(0, "seeding particles");
addparticleemitters();
canemit = true;
- loopv(emitters)
- {
+ loopv(emitters) {
particleemitter &pe = emitters[i];
extentity &e = *pe.ent;
seedemitter = &pe;
@@ -1362,34 +1091,25 @@ void seedparticles()
}
}
-void updateparticles()
-{
+void updateparticles() {
if(regenemitters) addparticleemitters();
-
if(minimized) { canemit = false; return; }
-
- if(lastmillis - lastemitframe >= emitmillis)
- {
+ if(lastmillis - lastemitframe >= emitmillis) {
canemit = true;
lastemitframe = lastmillis - (lastmillis%emitmillis);
}
else canemit = false;
-
- if(!editmode || showparticles)
- {
+ if(!editmode || showparticles) {
int emitted = 0, replayed = 0;
addedparticles = 0;
- loopv(emitters)
- {
+ loopv(emitters) {
particleemitter &pe = emitters[i];
extentity &e = *pe.ent;
if(e.o.dist(camera1->o) > maxparticledistance) { pe.lastemit = lastmillis; continue; }
makeparticles(e);
emitted++;
- if(replayparticles && pe.maxfade > 5 && pe.lastcull > pe.lastemit)
- {
- for(emitoffset = max(pe.lastemit + emitmillis - lastmillis, -pe.maxfade); emitoffset < 0; emitoffset += emitmillis)
- {
+ if(replayparticles && pe.maxfade > 5 && pe.lastcull > pe.lastemit) {
+ for(emitoffset = max(pe.lastemit + emitmillis - lastmillis, -pe.maxfade); emitoffset < 0; emitoffset += emitmillis) {
makeparticles(e);
replayed++;
}
@@ -1398,17 +1118,14 @@ void updateparticles()
pe.lastemit = lastmillis;
}
}
- if(editmode) // show sparkly thingies for map entities in edit mode
- {
+ if(editmode) { // show sparkly thingies for map entities in edit mode {
const vector<extentity *> &ents = entities::getents();
// note: order matters in this case as particles of the same type are drawn in the reverse order that they are added
- loopv(entgroup)
- {
+ loopv(entgroup) {
entity &e = *ents[entgroup[i]];
particle_textcopy(e.o, entname(e), PART_TEXT, 1, 0xFF4B19, 2.0f);
}
- loopv(ents)
- {
+ loopv(ents) {
entity &e = *ents[i];
if(e.type==ET_EMPTY) continue;
particle_textcopy(e.o, entname(e), PART_TEXT, 1, 0x1EC850, 2.0f);
diff --git a/src/engine/rendertarget.h b/src/engine/rendertarget.h
index a22298b..e89393a 100644
--- a/src/engine/rendertarget.h
+++ b/src/engine/rendertarget.h
@@ -1,7 +1,6 @@
extern int rtsharefb, rtscissor, blurtile;
-struct rendertarget
-{
+struct rendertarget {
int texw, texh, vieww, viewh;
GLenum colorfmt, depthfmt;
GLuint rendertex, renderfb, renderdb, blurtex, blurfb, blurdb;
@@ -9,70 +8,49 @@ struct rendertarget
float blursigma;
float blurweights[MAXBLURRADIUS+1], bluroffsets[MAXBLURRADIUS+1];
float bluryweights[MAXBLURRADIUS+1], bluryoffsets[MAXBLURRADIUS+1];
-
float scissorx1, scissory1, scissorx2, scissory2;
#define BLURTILES 32
#define BLURTILEMASK (0xFFFFFFFFU>>(32-BLURTILES))
uint blurtiles[BLURTILES+1];
-
bool initialized;
-
- rendertarget() : texw(0), texh(0), vieww(0), viewh(0), colorfmt(GL_FALSE), depthfmt(GL_FALSE), rendertex(0), renderfb(0), renderdb(0), blurtex(0), blurfb(0), blurdb(0), blursize(0), blurysize(0), blursigma(0), initialized(false)
- {
+ rendertarget() : texw(0), texh(0), vieww(0), viewh(0), colorfmt(GL_FALSE), depthfmt(GL_FALSE), rendertex(0), renderfb(0), renderdb(0), blurtex(0), blurfb(0), blurdb(0), blursize(0), blurysize(0), blursigma(0), initialized(false) {
}
-
virtual ~rendertarget() {}
-
- virtual GLenum attachment() const
- {
+ virtual GLenum attachment() const {
return GL_COLOR_ATTACHMENT0;
}
-
- virtual const GLenum *colorformats() const
- {
+ virtual const GLenum *colorformats() const {
static const GLenum colorfmts[] = { GL_RGB, GL_RGB8, GL_FALSE };
return colorfmts;
}
-
- virtual const GLenum *depthformats() const
- {
+ virtual const GLenum *depthformats() const {
static const GLenum depthfmts[] = { GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32, GL_FALSE };
return depthfmts;
}
-
virtual bool depthtest() const { return true; }
-
- void cleanup(bool fullclean = false)
- {
+ void cleanup(bool fullclean = false) {
if(renderfb) { glDeleteFramebuffers_(1, &renderfb); renderfb = 0; }
if(renderdb) { glDeleteRenderbuffers_(1, &renderdb); renderdb = 0; }
if(rendertex) { glDeleteTextures(1, &rendertex); rendertex = 0; }
texw = texh = 0;
cleanupblur();
-
if(fullclean) colorfmt = depthfmt = GL_FALSE;
}
-
- void cleanupblur()
- {
+ void cleanupblur() {
if(blurfb) { glDeleteFramebuffers_(1, &blurfb); blurfb = 0; }
if(blurtex) { glDeleteTextures(1, &blurtex); blurtex = 0; }
if(blurdb) { glDeleteRenderbuffers_(1, &blurdb); blurdb = 0; }
blursize = blurysize = 0;
blursigma = 0.0f;
}
-
- void setupblur()
- {
+ void setupblur() {
if(!blurtex) glGenTextures(1, &blurtex);
createtexture(blurtex, texw, texh, NULL, 3, 1, colorfmt);
-
if(!swaptexs() || rtsharefb) return;
if(!blurfb) glGenFramebuffers_(1, &blurfb);
glBindFramebuffer_(GL_FRAMEBUFFER, blurfb);
glFramebufferTexture2D_(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blurtex, 0);
- if(depthtest())
- {
+ if(depthtest()) {
if(!blurdb) glGenRenderbuffers_(1, &blurdb);
glGenRenderbuffers_(1, &blurdb);
glBindRenderbuffer_(GL_RENDERBUFFER, blurdb);
@@ -81,39 +59,30 @@ struct rendertarget
}
glBindFramebuffer_(GL_FRAMEBUFFER, 0);
}
-
- void setup(int w, int h)
- {
+ void setup(int w, int h) {
if(!renderfb) glGenFramebuffers_(1, &renderfb);
glBindFramebuffer_(GL_FRAMEBUFFER, renderfb);
if(!rendertex) glGenTextures(1, &rendertex);
-
GLenum attach = attachment();
- if(attach == GL_DEPTH_ATTACHMENT)
- {
+ if(attach == GL_DEPTH_ATTACHMENT) {
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
}
-
const GLenum *colorfmts = colorformats();
int find = 0;
- do
- {
+ do {
createtexture(rendertex, w, h, NULL, 3, filter() ? 1 : 0, colorfmt ? colorfmt : colorfmts[find]);
glFramebufferTexture2D_(GL_FRAMEBUFFER, attach, GL_TEXTURE_2D, rendertex, 0);
if(glCheckFramebufferStatus_(GL_FRAMEBUFFER)==GL_FRAMEBUFFER_COMPLETE) break;
}
while(!colorfmt && colorfmts[++find]);
if(!colorfmt) colorfmt = colorfmts[find];
-
- if(attach != GL_DEPTH_ATTACHMENT && depthtest())
- {
+ if(attach != GL_DEPTH_ATTACHMENT && depthtest()) {
if(!renderdb) { glGenRenderbuffers_(1, &renderdb); depthfmt = GL_FALSE; }
if(!depthfmt) glBindRenderbuffer_(GL_RENDERBUFFER, renderdb);
const GLenum *depthfmts = depthformats();
find = 0;
- do
- {
+ do {
if(!depthfmt) glRenderbufferStorage_(GL_RENDERBUFFER, depthfmts[find], w, h);
glFramebufferRenderbuffer_(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderdb);
if(glCheckFramebufferStatus_(GL_FRAMEBUFFER)==GL_FRAMEBUFFER_COMPLETE) break;
@@ -121,72 +90,53 @@ struct rendertarget
while(!depthfmt && depthfmts[++find]);
if(!depthfmt) depthfmt = depthfmts[find];
}
-
glBindFramebuffer_(GL_FRAMEBUFFER, 0);
-
texw = w;
texh = h;
initialized = false;
}
-
- bool addblurtiles(float x1, float y1, float x2, float y2, float blurmargin = 0)
- {
+ bool addblurtiles(float x1, float y1, float x2, float y2, float blurmargin = 0) {
if(x1 >= 1 || y1 >= 1 || x2 <= -1 || y2 <= -1) return false;
-
scissorx1 = min(scissorx1, max(x1, -1.0f));
scissory1 = min(scissory1, max(y1, -1.0f));
scissorx2 = max(scissorx2, min(x2, 1.0f));
scissory2 = max(scissory2, min(y2, 1.0f));
-
float blurerror = 2.0f*float(2*blursize + blurmargin);
int tx1 = max(0, min(BLURTILES - 1, int((x1-blurerror/vieww + 1)/2 * BLURTILES))),
ty1 = max(0, min(BLURTILES - 1, int((y1-blurerror/viewh + 1)/2 * BLURTILES))),
tx2 = max(0, min(BLURTILES - 1, int((x2+blurerror/vieww + 1)/2 * BLURTILES))),
ty2 = max(0, min(BLURTILES - 1, int((y2+blurerror/viewh + 1)/2 * BLURTILES)));
-
uint mask = (BLURTILEMASK>>(BLURTILES - (tx2+1))) & (BLURTILEMASK<<tx1);
for(int y = ty1; y <= ty2; y++) blurtiles[y] |= mask;
return true;
}
-
- bool checkblurtiles(float x1, float y1, float x2, float y2, float blurmargin = 0)
- {
+ bool checkblurtiles(float x1, float y1, float x2, float y2, float blurmargin = 0) {
float blurerror = 2.0f*float(2*blursize + blurmargin);
if(x2+blurerror/vieww < scissorx1 || y2+blurerror/viewh < scissory1 ||
x1-blurerror/vieww > scissorx2 || y1-blurerror/viewh > scissory2)
return false;
-
if(!blurtile) return true;
-
int tx1 = max(0, min(BLURTILES - 1, int((x1 + 1)/2 * BLURTILES))),
ty1 = max(0, min(BLURTILES - 1, int((y1 + 1)/2 * BLURTILES))),
tx2 = max(0, min(BLURTILES - 1, int((x2 + 1)/2 * BLURTILES))),
ty2 = max(0, min(BLURTILES - 1, int((y2 + 1)/2 * BLURTILES)));
-
uint mask = (BLURTILEMASK>>(BLURTILES - (tx2+1))) & (BLURTILEMASK<<tx1);
for(int y = ty1; y <= ty2; y++) if(blurtiles[y] & mask) return true;
-
return false;
}
-
- void rendertiles()
- {
+ void rendertiles() {
float wscale = vieww/float(texw), hscale = viewh/float(texh);
- if(blurtile && scissorx1 < scissorx2 && scissory1 < scissory2)
- {
+ if(blurtile && scissorx1 < scissorx2 && scissory1 < scissory2) {
uint tiles[sizeof(blurtiles)/sizeof(uint)];
memcpy(tiles, blurtiles, sizeof(blurtiles));
-
LOCALPARAMF(screentexcoord0, wscale*0.5f, hscale*0.5f, wscale*0.5f, hscale*0.5f);
gle::defvertex(2);
gle::begin(GL_QUADS);
float tsz = 1.0f/BLURTILES;
- loop(y, BLURTILES+1)
- {
+ loop(y, BLURTILES+1) {
uint mask = tiles[y];
int x = 0;
- while(mask)
- {
+ while(mask) {
while(!(mask&0xFF)) { mask >>= 8; x += 8; }
while(!(mask&1)) { mask >>= 1; x++; }
int xstart = x;
@@ -207,71 +157,49 @@ struct rendertarget
}
gle::end();
}
- else
- {
+ else {
screenquad(wscale, hscale);
}
}
-
- void blur(int wantsblursize, float wantsblursigma, int wantsblurysize, int x, int y, int w, int h, bool scissor)
- {
+ void blur(int wantsblursize, float wantsblursigma, int wantsblurysize, int x, int y, int w, int h, bool scissor) {
if(!blurtex) setupblur();
- if(blursize!=wantsblursize || blurysize != wantsblurysize || (wantsblursize && blursigma!=wantsblursigma))
- {
+ if(blursize!=wantsblursize || blurysize != wantsblurysize || (wantsblursize && blursigma!=wantsblursigma)) {
setupblurkernel(wantsblursize, wantsblursigma, blurweights, bluroffsets);
if(wantsblurysize != wantsblursize) setupblurkernel(wantsblurysize, wantsblursigma, bluryweights, bluryoffsets);
blursize = wantsblursize;
blursigma = wantsblursigma;
blurysize = wantsblurysize;
}
-
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
-
- if(scissor)
- {
+ if(scissor) {
glScissor(x, y, w, h);
glEnable(GL_SCISSOR_TEST);
}
-
- loopi(2)
- {
+ loopi(2) {
if(i && blurysize != blursize) setblurshader(i, texh, blurysize, bluryweights, bluryoffsets);
else setblurshader(i, i ? texh : texw, blursize, blurweights, bluroffsets);
-
if(!swaptexs() || rtsharefb) glFramebufferTexture2D_(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, i ? rendertex : blurtex, 0);
else glBindFramebuffer_(GL_FRAMEBUFFER, i ? renderfb : blurfb);
glBindTexture(GL_TEXTURE_2D, i ? blurtex : rendertex);
-
rendertiles();
}
-
if(scissor) glDisable(GL_SCISSOR_TEST);
-
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
}
-
virtual bool swaptexs() const { return false; }
-
virtual bool dorender() { return true; }
-
virtual bool shouldrender() { return true; }
-
- virtual void doblur(int blursize, float blursigma, int blurysize)
- {
+ virtual void doblur(int blursize, float blursigma, int blurysize) {
int sx, sy, sw, sh;
bool scissoring = rtscissor && scissorblur(sx, sy, sw, sh) && sw > 0 && sh > 0;
if(!scissoring) { sx = sy = 0; sw = vieww; sh = viewh; }
blur(blursize, blursigma, blurysize, sx, sy, sw, sh, scissoring);
}
-
- virtual bool scissorrender(int &x, int &y, int &w, int &h)
- {
- if(scissorx1 >= scissorx2 || scissory1 >= scissory2)
- {
- if(vieww < texw || viewh < texh)
- {
+ virtual bool scissorrender(int &x, int &y, int &w, int &h) {
+ if(scissorx1 >= scissorx2 || scissory1 >= scissory2) {
+ if(vieww < texw || viewh < texh) {
x = y = 0;
w = vieww;
h = viewh;
@@ -285,13 +213,9 @@ struct rendertarget
h = min(int(ceil((scissory2+1)/2*viewh)) + 2*blursize, viewh) - y;
return true;
}
-
- virtual bool scissorblur(int &x, int &y, int &w, int &h)
- {
- if(scissorx1 >= scissorx2 || scissory1 >= scissory2)
- {
- if(vieww < texw || viewh < texh)
- {
+ virtual bool scissorblur(int &x, int &y, int &w, int &h) {
+ if(scissorx1 >= scissorx2 || scissory1 >= scissory2) {
+ if(vieww < texw || viewh < texh) {
x = y = 0;
w = vieww;
h = viewh;
@@ -305,45 +229,32 @@ struct rendertarget
h = min(int(ceil((scissory2+1)/2*viewh)), viewh) - y;
return true;
}
-
virtual void doclear() {}
-
virtual bool screenrect() const { return false; }
virtual bool filter() const { return true; }
-
- void render(int w, int h, int blursize = 0, float blursigma = 0, int blurysize = 0)
- {
+ void render(int w, int h, int blursize = 0, float blursigma = 0, int blurysize = 0) {
w = min(w, hwtexsize);
h = min(h, hwtexsize);
- if(screenrect())
- {
+ if(screenrect()) {
if(w > screenw) w = screenw;
if(h > screenh) h = screenh;
}
vieww = w;
viewh = h;
if(w!=texw || h!=texh || (swaptexs() && !rtsharefb ? !blurfb : blurfb)) cleanup();
-
- if(!filter())
- {
+ if(!filter()) {
if(blurtex) cleanupblur();
blursize = blurysize = 0;
}
-
if(!rendertex) setup(w, h);
-
scissorx2 = scissory2 = -1;
scissorx1 = scissory1 = 1;
memset(blurtiles, 0, sizeof(blurtiles));
-
if(!shouldrender()) return;
-
if(blursize && !blurtex) setupblur();
- if(swaptexs() && blursize)
- {
+ if(swaptexs() && blursize) {
swap(rendertex, blurtex);
- if(!rtsharefb)
- {
+ if(!rtsharefb) {
swap(renderfb, blurfb);
swap(renderdb, blurdb);
}
@@ -352,38 +263,26 @@ struct rendertarget
if(swaptexs() && blursize && rtsharefb)
glFramebufferTexture2D_(GL_FRAMEBUFFER, attachment(), GL_TEXTURE_2D, rendertex, 0);
glViewport(0, 0, vieww, viewh);
-
doclear();
-
int sx, sy, sw, sh;
bool scissoring = rtscissor && scissorrender(sx, sy, sw, sh) && sw > 0 && sh > 0;
- if(scissoring)
- {
+ if(scissoring) {
glScissor(sx, sy, sw, sh);
glEnable(GL_SCISSOR_TEST);
}
- else
- {
+ else {
sx = sy = 0;
sw = vieww;
sh = viewh;
}
-
if(!depthtest()) glDisable(GL_DEPTH_TEST);
-
bool succeeded = dorender();
-
if(!depthtest()) glEnable(GL_DEPTH_TEST);
-
if(scissoring) glDisable(GL_SCISSOR_TEST);
-
- if(succeeded)
- {
+ if(succeeded) {
initialized = true;
-
if(blursize) doblur(blursize, blursigma, blurysize ? blurysize : blursize);
}
-
glBindFramebuffer_(GL_FRAMEBUFFER, 0);
glViewport(0, 0, screenw, screenh);
}
diff --git a/src/engine/rendertext.cpp b/src/engine/rendertext.cpp
index 925e1a8..3fd4dc8 100644
--- a/src/engine/rendertext.cpp
+++ b/src/engine/rendertext.cpp
@@ -7,8 +7,7 @@ static int fontdeftex = 0;
font *curfont = NULL;
int curfonttex = 0;
-void newfont(char *name, char *tex, int *defaultw, int *defaulth)
-{
+void newfont(char *name, char *tex, int *defaultw, int *defaulth) {
font *f = &fonts[name];
if(!f->name) f->name = newstring(name);
f->texs.shrink(0);
@@ -18,39 +17,30 @@ void newfont(char *name, char *tex, int *defaultw, int *defaulth)
f->defaultw = *defaultw;
f->defaulth = *defaulth;
f->scale = f->defaulth;
-
fontdef = f;
fontdeftex = 0;
}
-void fontoffset(char *c)
-{
+void fontoffset(char *c) {
if(!fontdef) return;
-
fontdef->charoffset = c[0];
}
-void fontscale(int *scale)
-{
+void fontscale(int *scale) {
if(!fontdef) return;
-
fontdef->scale = *scale > 0 ? *scale : fontdef->defaulth;
}
-void fonttex(char *s)
-{
+void fonttex(char *s) {
if(!fontdef) return;
-
Texture *t = textureload(s);
loopv(fontdef->texs) if(fontdef->texs[i] == t) { fontdeftex = i; return; }
fontdeftex = fontdef->texs.length();
fontdef->texs.add(t);
}
-void fontchar(int *x, int *y, int *w, int *h, int *offsetx, int *offsety, int *advance)
-{
+void fontchar(int *x, int *y, int *w, int *h, int *offsetx, int *offsety, int *advance) {
if(!fontdef) return;
-
font::charinfo &c = fontdef->chars.add();
c.x = *x;
c.y = *y;
@@ -62,11 +52,9 @@ void fontchar(int *x, int *y, int *w, int *h, int *offsetx, int *offsety, int *a
c.tex = fontdeftex;
}
-void fontskip(int *n)
-{
+void fontskip(int *n) {
if(!fontdef) return;
- loopi(max(*n, 1))
- {
+ loopi(max(*n, 1)) {
font::charinfo &c = fontdef->chars.add();
c.x = c.y = c.w = c.h = c.offsetx = c.offsety = c.advance = c.tex = 0;
}
@@ -79,8 +67,7 @@ COMMAND(fonttex, "s");
COMMAND(fontchar, "iiiiiii");
COMMAND(fontskip, "i");
-void fontalias(const char *dst, const char *src)
-{
+void fontalias(const char *dst, const char *src) {
font *s = fonts.access(src);
if(!s) return;
font *d = &fonts[dst];
@@ -91,15 +78,13 @@ void fontalias(const char *dst, const char *src)
d->defaultw = s->defaultw;
d->defaulth = s->defaulth;
d->scale = s->scale;
-
fontdef = d;
fontdeftex = d->texs.length()-1;
}
COMMAND(fontalias, "ss");
-bool setfont(const char *name)
-{
+bool setfont(const char *name) {
font *f = fonts.access(name);
if(!f) return false;
curfont = f;
@@ -108,37 +93,30 @@ bool setfont(const char *name)
static vector<font *> fontstack;
-void pushfont()
-{
+void pushfont() {
fontstack.add(curfont);
}
-bool popfont()
-{
+bool popfont() {
if(fontstack.empty()) return false;
curfont = fontstack.pop();
return true;
}
-void gettextres(int &w, int &h)
-{
- if(w < MINRESW || h < MINRESH)
- {
- if(MINRESW > w*MINRESH/h)
- {
+void gettextres(int &w, int &h) {
+ if(w < MINRESW || h < MINRESH) {
+ if(MINRESW > w*MINRESH/h) {
h = h*MINRESW/w;
w = MINRESW;
}
- else
- {
+ else {
w = w*MINRESH/h;
h = MINRESH;
}
}
}
-float text_widthf(const char *str)
-{
+float text_widthf(const char *str) {
float width, height;
text_boundsf(str, width, height);
return width;
@@ -147,8 +125,7 @@ float text_widthf(const char *str)
#define FONTTAB (4*FONTW)
#define TEXTTAB(x) ((int((x)/FONTTAB)+1.0f)*FONTTAB)
-void tabify(const char *str, int *numtabs)
-{
+void tabify(const char *str, int *numtabs) {
int tw = max(*numtabs, 0)*FONTTAB-1, tabs = 0;
for(float w = text_widthf(str); w <= tw; w = TEXTTAB(w)) ++tabs;
int len = strlen(str);
@@ -161,24 +138,20 @@ void tabify(const char *str, int *numtabs)
COMMAND(tabify, "si");
-void draw_textf(const char *fstr, int left, int top, ...)
-{
+void draw_textf(const char *fstr, int left, int top, ...) {
defvformatstring(str, top, fstr);
draw_text(str, left, top);
}
const matrix4x3 *textmatrix = NULL;
-static float draw_char(Texture *&tex, int c, float x, float y, float scale)
-{
+static float draw_char(Texture *&tex, int c, float x, float y, float scale) {
font::charinfo &info = curfont->chars[c-curfont->charoffset];
- if(tex != curfont->texs[info.tex])
- {
+ if(tex != curfont->texs[info.tex]) {
xtraverts += gle::end();
tex = curfont->texs[info.tex];
glBindTexture(GL_TEXTURE_2D, tex->id);
}
-
float x1 = x + scale*info.offsetx,
y1 = y + scale*info.offsety,
x2 = x + scale*(info.offsetx + info.w),
@@ -187,40 +160,31 @@ static float draw_char(Texture *&tex, int c, float x, float y, float scale)
ty1 = info.y / float(tex->ys),
tx2 = (info.x + info.w) / float(tex->xs),
ty2 = (info.y + info.h) / float(tex->ys);
-
- if(textmatrix)
- {
+ if(textmatrix) {
gle::attrib(textmatrix->transform(vec2(x1, y1))); gle::attribf(tx1, ty1);
gle::attrib(textmatrix->transform(vec2(x2, y1))); gle::attribf(tx2, ty1);
gle::attrib(textmatrix->transform(vec2(x2, y2))); gle::attribf(tx2, ty2);
gle::attrib(textmatrix->transform(vec2(x1, y2))); gle::attribf(tx1, ty2);
}
- else
- {
+ else {
gle::attribf(x1, y1); gle::attribf(tx1, ty1);
gle::attribf(x2, y1); gle::attribf(tx2, ty1);
gle::attribf(x2, y2); gle::attribf(tx2, ty2);
gle::attribf(x1, y2); gle::attribf(tx1, ty2);
}
-
return scale*info.advance;
}
//stack[sp] is current color index
-static void text_color(char c, char *stack, int size, int &sp, bvec color, int a)
-{
- if(c=='s') // save color
- {
+static void text_color(char c, char *stack, int size, int &sp, bvec color, int a) {
+ if(c=='s') { // save color {
c = stack[sp];
if(sp<size-1) stack[++sp] = c;
- }
- else
- {
+ } else {
xtraverts += gle::end();
if(c=='r') { if(sp > 0) --sp; c = stack[sp]; } // restore color
else stack[sp] = c;
- switch(c)
- {
+ switch(c) {
case '0': color = bvec( 64, 255, 128); break; // green: player talk
case '1': color = bvec( 96, 160, 255); break; // blue: "echo" command
case '2': color = bvec(255, 192, 64); break; // yellow: gameplay messages
@@ -239,24 +203,21 @@ static void text_color(char c, char *stack, int size, int &sp, bvec color, int a
#define TEXTSKELETON \
float y = 0, x = 0, scale = curfont->scale/float(curfont->defaulth);\
int i;\
- for(i = 0; str[i]; i++)\
- {\
+ for(i = 0; str[i]; i++) { \
TEXTINDEX(i)\
int c = uchar(str[i]);\
- if(c=='\t') { x = TEXTTAB(x); TEXTWHITE(i) }\
- else if(c==' ') { x += scale*curfont->defaultw; TEXTWHITE(i) }\
+ if(c=='\t') { x = TEXTTAB(x); TEXTWHITE(i) }\
+ else if(c==' ') { x += scale*curfont->defaultw; TEXTWHITE(i) }\
else if(c=='\n') { TEXTLINE(i) x = 0; y += FONTH; }\
else if(c=='\f') { if(str[i+1]) { i++; TEXTCOLOR(i) }}\
- else if(curfont->chars.inrange(c-curfont->charoffset))\
- {\
+ else if(curfont->chars.inrange(c-curfont->charoffset)) {\
float cw = scale*curfont->chars[c-curfont->charoffset].advance;\
if(cw <= 0) continue;\
- if(maxwidth != -1)\
- {\
+ if(maxwidth != -1) {\
int j = i;\
float w = cw;\
- for(; str[i+1]; i++)\
- {\
+ for(; str[i+1]; i++) {\
+ \
int c = uchar(str[i+1]);\
if(c=='\f') { if(str[i+2]) i++; continue; }\
if(i-j > 16) break;\
@@ -268,15 +229,15 @@ static void text_color(char c, char *stack, int size, int &sp, bvec color, int a
if(x + w > maxwidth && j!=0) { TEXTLINE(j-1) x = 0; y += FONTH; }\
TEXTWORD\
}\
- else\
- { TEXTCHAR(i) }\
+ else{ \
+ TEXTCHAR(i) }\
}\
}
//all the chars are guaranteed to be either drawable or color commands
#define TEXTWORDSKELETON \
- for(; j <= i; j++)\
- {\
+ for(; j <= i; j++){ \
+ \
TEXTINDEX(j)\
int c = uchar(str[j]);\
if(c=='\f') { if(str[j+1]) { j++; TEXTCOLOR(j) }}\
@@ -285,8 +246,7 @@ static void text_color(char c, char *stack, int size, int &sp, bvec color, int a
#define TEXTEND(cursor) if(cursor >= i) { do { TEXTINDEX(cursor); } while(0); }
-int text_visible(const char *str, float hitx, float hity, int maxwidth)
-{
+int text_visible(const char *str, float hitx, float hity, int maxwidth) {
#define TEXTINDEX(idx)
#define TEXTWHITE(idx) if(y+FONTH > hity && x >= hitx) return idx;
#define TEXTLINE(idx) if(y+FONTH > hity) return idx;
@@ -304,8 +264,7 @@ int text_visible(const char *str, float hitx, float hity, int maxwidth)
}
//inverse of text_visible
-void text_posf(const char *str, int cursor, float &cx, float &cy, int maxwidth)
-{
+void text_posf(const char *str, int cursor, float &cx, float &cy, int maxwidth) {
#define TEXTINDEX(idx) if(idx == cursor) { cx = x; cy = y; break; }
#define TEXTWHITE(idx)
#define TEXTLINE(idx)
@@ -323,8 +282,7 @@ void text_posf(const char *str, int cursor, float &cx, float &cy, int maxwidth)
#undef TEXTWORD
}
-void text_boundsf(const char *str, float &width, float &height, int maxwidth)
-{
+void text_boundsf(const char *str, float &width, float &height, int maxwidth) {
#define TEXTINDEX(idx)
#define TEXTWHITE(idx)
#define TEXTLINE(idx) if(x > width) width = x;
@@ -343,8 +301,7 @@ void text_boundsf(const char *str, float &width, float &height, int maxwidth)
#undef TEXTWORD
}
-void draw_text(const char *str, int left, int top, int r, int g, int b, int a, int cursor, int maxwidth)
-{
+void draw_text(const char *str, int left, int top, int r, int g, int b, int a, int cursor, int maxwidth) {
#define TEXTINDEX(idx) if(idx == cursor) { cx = x; cy = y; }
#define TEXTWHITE(idx)
#define TEXTLINE(idx)
@@ -368,8 +325,7 @@ void draw_text(const char *str, int left, int top, int r, int g, int b, int a, i
TEXTSKELETON
TEXTEND(cursor)
xtraverts += gle::end();
- if(cursor >= 0 && (totalmillis/250)&1)
- {
+ if(cursor >= 0 && (totalmillis/250)&1) {
gle::color(color, a);
if(maxwidth != -1 && cx >= maxwidth) { cx = 0; cy += FONTH; }
draw_char(tex, '_', left+cx, top+cy, scale);
@@ -383,8 +339,7 @@ void draw_text(const char *str, int left, int top, int r, int g, int b, int a, i
#undef TEXTWORD
}
-void reloadfonts()
-{
+void reloadfonts() {
enumerate(fonts, font, f,
loopv(f.texs) if(!reloadtexture(*f.texs[i])) fatal("failed to reload font texture");
);
diff --git a/src/engine/renderva.cpp b/src/engine/renderva.cpp
index 1e33702..cc0b65d 100644
--- a/src/engine/renderva.cpp
+++ b/src/engine/renderva.cpp
@@ -2,14 +2,12 @@
#include "engine.h"
-static inline void drawtris(GLsizei numindices, const GLvoid *indices, ushort minvert, ushort maxvert)
-{
+static inline void drawtris(GLsizei numindices, const GLvoid *indices, ushort minvert, ushort maxvert) {
glDrawRangeElements_(GL_TRIANGLES, minvert, maxvert, numindices, GL_UNSIGNED_SHORT, indices);
glde++;
}
-static inline void drawvatris(vtxarray *va, GLsizei numindices, const GLvoid *indices)
-{
+static inline void drawvatris(vtxarray *va, GLsizei numindices, const GLvoid *indices) {
drawtris(numindices, indices, va->minvert, va->maxvert);
}
@@ -20,48 +18,36 @@ float vfcDnear[5], vfcDfar[5];
vtxarray *visibleva;
-int isvisiblesphere(float rad, const vec &cv)
-{
+int isvisiblesphere(float rad, const vec &cv) {
int v = VFC_FULL_VISIBLE;
float dist;
-
- loopi(5)
- {
+ loopi(5) {
dist = vfcP[i].dist(cv);
if(dist < -rad) return VFC_NOT_VISIBLE;
if(dist < rad) v = VFC_PART_VISIBLE;
}
-
if(dist > -rad) v = VFC_PART_VISIBLE;
-
return v;
}
-static inline int ishiddencube(const ivec &o, int size)
-{
+static inline int ishiddencube(const ivec &o, int size) {
loopi(5) if(o.dist(vfcP[i]) < -vfcDfar[i]*size) return true;
return false;
}
-int isvisiblecube(const ivec &o, int size)
-{
+int isvisiblecube(const ivec &o, int size) {
int v = VFC_FULL_VISIBLE;
float dist;
-
- loopi(5)
- {
+ loopi(5) {
dist = o.dist(vfcP[i]);
if(dist < -vfcDfar[i]*size) return VFC_NOT_VISIBLE;
if(dist < -vfcDnear[i]*size) v = VFC_PART_VISIBLE;
}
-
if(dist > -vfcDfar[4]*size) v = VFC_PART_VISIBLE;
-
return v;
}
-float vadist(vtxarray *va, const vec &p)
-{
+float vadist(vtxarray *va, const vec &p) {
return p.dist_to_bb(va->bbmin, va->bbmax);
}
@@ -69,30 +55,23 @@ float vadist(vtxarray *va, const vec &p)
static vtxarray *vasort[VASORTSIZE];
-void addvisibleva(vtxarray *va)
-{
+void addvisibleva(vtxarray *va) {
float dist = vadist(va, camera1->o);
va->distance = int(dist); /*cv.dist(camera1->o) - va->size*SQRT3/2*/
-
int hash = clamp(int(dist*VASORTSIZE/worldsize), 0, VASORTSIZE-1);
vtxarray **prev = &vasort[hash], *cur = vasort[hash];
-
- while(cur && va->distance >= cur->distance)
- {
+ while(cur && va->distance >= cur->distance) {
prev = &cur->next;
cur = cur->next;
}
-
va->next = *prev;
*prev = va;
}
-void sortvisiblevas()
-{
+void sortvisiblevas() {
visibleva = NULL;
vtxarray **last = &visibleva;
- loopi(VASORTSIZE) if(vasort[i])
- {
+ loopi(VASORTSIZE) if(vasort[i]) {
vtxarray *va = vasort[i];
*last = va;
while(va->next) va = va->next;
@@ -100,19 +79,15 @@ void sortvisiblevas()
}
}
-void findvisiblevas(vector<vtxarray *> &vas, bool resetocclude = false)
-{
- loopv(vas)
- {
+void findvisiblevas(vector<vtxarray *> &vas, bool resetocclude = false) {
+ loopv(vas) {
vtxarray &v = *vas[i];
int prevvfc = resetocclude ? (int) VFC_NOT_VISIBLE : (int) v.curvfc;
v.curvfc = isvisiblecube(v.o, v.size);
- if(v.curvfc!=VFC_NOT_VISIBLE)
- {
+ if(v.curvfc!=VFC_NOT_VISIBLE) {
addvisibleva(&v);
if(v.children.length()) findvisiblevas(v.children, prevvfc>=VFC_NOT_VISIBLE);
- if(prevvfc>=VFC_NOT_VISIBLE)
- {
+ if(prevvfc>=VFC_NOT_VISIBLE) {
v.occluded = !v.texs ? OCCLUDE_GEOM : OCCLUDE_NOTHING;
v.query = NULL;
}
@@ -120,10 +95,8 @@ void findvisiblevas(vector<vtxarray *> &vas, bool resetocclude = false)
}
}
-void calcvfcD()
-{
- loopi(5)
- {
+void calcvfcD() {
+ loopi(5) {
plane &p = vfcP[i];
vfcDnear[i] = vfcDfar[i] = 0;
loopk(3) if(p[k] > 0) vfcDfar[i] += p[k];
@@ -131,8 +104,7 @@ void calcvfcD()
}
}
-void setvfcP(float z, const vec &bbmin, const vec &bbmax)
-{
+void setvfcP(float z, const vec &bbmin, const vec &bbmax) {
vec4 px = camprojmatrix.rowx(), py = camprojmatrix.rowy(), pz = camprojmatrix.rowz(), pw = camprojmatrix.roww();
vfcP[0] = plane(vec4(pw).mul(-bbmin.x).add(px)).normalize(); // left plane
vfcP[1] = plane(vec4(pw).mul(bbmax.x).sub(px)).normalize(); // right plane
@@ -140,41 +112,33 @@ void setvfcP(float z, const vec &bbmin, const vec &bbmax)
vfcP[3] = plane(vec4(pw).mul(bbmax.y).sub(py)).normalize(); // top plane
vfcP[4] = plane(vec4(pw).add(pz)).normalize(); // near/far planes
if(z >= 0) loopi(5) vfcP[i].reflectz(z);
-
calcvfcD();
}
plane oldvfcP[5];
-void savevfcP()
-{
+void savevfcP() {
memcpy(oldvfcP, vfcP, sizeof(vfcP));
}
-void restorevfcP()
-{
+void restorevfcP() {
memcpy(vfcP, oldvfcP, sizeof(vfcP));
calcvfcD();
}
-void visiblecubes(bool cull)
-{
+void visiblecubes(bool cull) {
memclear(vasort);
-
- if(cull)
- {
+ if(cull) {
setvfcP();
findvisiblevas(varoot);
sortvisiblevas();
}
- else
- {
+ else {
memclear(vfcP);
memclear(vfcDnear);
memclear(vfcDfar);
visibleva = NULL;
- loopv(valist)
- {
+ loopv(valist) {
vtxarray *va = valist[i];
va->distance = 0;
va->curvfc = VFC_FULL_VISIBLE;
@@ -186,8 +150,7 @@ void visiblecubes(bool cull)
}
}
-static inline bool insideva(const vtxarray *va, const vec &v, int margin = 2)
-{
+static inline bool insideva(const vtxarray *va, const vec &v, int margin = 2) {
int size = va->size + margin;
return v.x>=va->o.x-margin && v.y>=va->o.y-margin && v.z>=va->o.z-margin &&
v.x<=va->o.x+size && v.y<=va->o.y+size && v.z<=va->o.z+size;
@@ -198,19 +161,13 @@ static inline bool insideva(const vtxarray *va, const vec &v, int margin = 2)
#define MAXQUERY 2048
#define MAXQUERYFRAMES 2
-struct queryframe
-{
+struct queryframe {
int cur, max;
occludequery queries[MAXQUERY];
-
queryframe() : cur(0), max(0) {}
-
void flip() { loopi(cur) queries[i].owner = NULL; cur = 0; }
-
- occludequery *newquery(void *owner)
- {
- if(cur >= max)
- {
+ occludequery *newquery(void *owner) {
+ if(cur >= max) {
if(max >= MAXQUERY) return NULL;
glGenQueries_(1, &queries[max++].id);
}
@@ -219,13 +176,9 @@ struct queryframe
query->fragments = -1;
return query;
}
-
void reset() { loopi(max) queries[i].owner = NULL; }
-
- void cleanup()
- {
- loopi(max)
- {
+ void cleanup() {
+ loopi(max) {
glDeleteQueries_(1, &queries[i].id);
queries[i].owner = NULL;
}
@@ -236,53 +189,43 @@ struct queryframe
static queryframe queryframes[MAXQUERYFRAMES];
static uint flipquery = 0;
-int getnumqueries()
-{
+int getnumqueries() {
return queryframes[flipquery].cur;
}
-void flipqueries()
-{
+void flipqueries() {
flipquery = (flipquery + 1) % MAXQUERYFRAMES;
queryframes[flipquery].flip();
}
-occludequery *newquery(void *owner)
-{
+occludequery *newquery(void *owner) {
return queryframes[flipquery].newquery(owner);
}
-void resetqueries()
-{
+void resetqueries() {
loopi(MAXQUERYFRAMES) queryframes[i].reset();
}
-void clearqueries()
-{
+void clearqueries() {
loopi(MAXQUERYFRAMES) queryframes[i].cleanup();
}
VAR(oqfrags, 0, 8, 64);
VAR(oqwait, 0, 1, 1);
-void startquery(occludequery *query)
-{
+void startquery(occludequery *query) {
glBeginQuery_(GL_SAMPLES_PASSED, query->id);
}
-void endquery(occludequery *query)
-{
+void endquery(occludequery *query) {
glEndQuery_(GL_SAMPLES_PASSED);
}
-bool checkquery(occludequery *query, bool nowait)
-{
+bool checkquery(occludequery *query, bool nowait) {
GLuint fragments;
if(query->fragments >= 0) fragments = query->fragments;
- else
- {
- if(nowait || !oqwait)
- {
+ else {
+ if(nowait || !oqwait) {
GLint avail;
glGetQueryObjectiv_(query->id, GL_QUERY_RESULT_AVAILABLE, &avail);
if(!avail) return false;
@@ -295,10 +238,8 @@ bool checkquery(occludequery *query, bool nowait)
static GLuint bbvbo = 0, bbebo = 0;
-static void setupbb()
-{
- if(!bbvbo)
- {
+static void setupbb() {
+ if(!bbvbo) {
glGenBuffers_(1, &bbvbo);
gle::bindvbo(bbvbo);
vec verts[8];
@@ -306,8 +247,7 @@ static void setupbb()
glBufferData_(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
gle::clearvbo();
}
- if(!bbebo)
- {
+ if(!bbebo) {
glGenBuffers_(1, &bbebo);
gle::bindebo(bbebo);
GLushort tris[3*2*6];
@@ -329,41 +269,35 @@ static void setupbb()
}
}
-static void cleanupbb()
-{
+static void cleanupbb() {
if(bbvbo) { glDeleteBuffers_(1, &bbvbo); bbvbo = 0; }
if(bbebo) { glDeleteBuffers_(1, &bbebo); bbebo = 0; }
}
-void startbb(bool mask)
-{
+void startbb(bool mask) {
setupbb();
gle::bindvbo(bbvbo);
gle::bindebo(bbebo);
gle::vertexpointer(sizeof(vec), (const vec *)0);
gle::enablevertex();
SETSHADER(bbquery);
- if(mask)
- {
+ if(mask) {
glDepthMask(GL_FALSE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
}
}
-void endbb(bool mask)
-{
+void endbb(bool mask) {
gle::disablevertex();
gle::clearvbo();
gle::clearebo();
- if(mask)
- {
+ if(mask) {
glDepthMask(GL_TRUE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
}
-void drawbb(const ivec &bo, const ivec &br)
-{
+void drawbb(const ivec &bo, const ivec &br) {
LOCALPARAMF(bborigin, bo.x, bo.y, bo.z);
LOCALPARAMF(bbsize, br.x, br.y, br.z);
glDrawRangeElements_(GL_TRIANGLES, 0, 8-1, 3*2*6, GL_UNSIGNED_SHORT, (ushort *)0);
@@ -374,53 +308,40 @@ extern int octaentsize;
static octaentities *visiblemms, **lastvisiblemms;
-static inline bool insideoe(const octaentities *oe, const vec &v, int margin = 1)
-{
+static inline bool insideoe(const octaentities *oe, const vec &v, int margin = 1) {
return v.x>=oe->bbmin.x-margin && v.y>=oe->bbmin.y-margin && v.z>=oe->bbmin.z-margin &&
v.x<=oe->bbmax.x+margin && v.y<=oe->bbmax.y+margin && v.z<=oe->bbmax.z+margin;
}
-void findvisiblemms(const vector<extentity *> &ents, bool doquery)
-{
+void findvisiblemms(const vector<extentity *> &ents, bool doquery) {
visiblemms = NULL;
lastvisiblemms = &visiblemms;
- for(vtxarray *va = visibleva; va; va = va->next)
- {
+ for(vtxarray *va = visibleva; va; va = va->next) {
if(va->mapmodels.empty() || va->occluded >= OCCLUDE_BB) continue;
- loopv(va->mapmodels)
- {
+ loopv(va->mapmodels) {
octaentities *oe = va->mapmodels[i];
-
bool occluded = doquery && oe->query && oe->query->owner == oe && checkquery(oe->query);
- if(occluded)
- {
+ if(occluded) {
oe->distance = -1;
-
oe->next = NULL;
*lastvisiblemms = oe;
lastvisiblemms = &oe->next;
}
- else
- {
+ else {
int visible = 0;
- loopv(oe->mapmodels)
- {
+ loopv(oe->mapmodels) {
extentity &e = *ents[oe->mapmodels[i]];
if(e.flags&EF_NOVIS) continue;
e.flags |= EF_RENDER;
++visible;
}
if(!visible) continue;
-
oe->distance = int(camera1->o.dist_to_bb(oe->o, oe->size));
-
octaentities **prev = &visiblemms, *cur = visiblemms;
- while(cur && cur->distance >= 0 && oe->distance > cur->distance)
- {
+ while(cur && cur->distance >= 0 && oe->distance > cur->distance) {
prev = &cur->next;
cur = cur->next;
}
-
if(*prev == NULL) lastvisiblemms = &oe->next;
oe->next = *prev;
*prev = oe;
@@ -431,30 +352,24 @@ void findvisiblemms(const vector<extentity *> &ents, bool doquery)
VAR(oqmm, 0, 4, 8);
-void rendermapmodel(extentity &e)
-{
+void rendermapmodel(extentity &e) {
int anim = ANIM_MAPMODEL|ANIM_LOOP, basetime = 0;
mapmodelinfo *mmi = getmminfo(e.attr2);
if(mmi) rendermodel(&e.light, mmi->name, anim, e.o, e.attr1, 0, MDL_CULL_VFC | MDL_CULL_DIST | MDL_DYNLIGHT, NULL, NULL, basetime);
}
-void rendermapmodels()
-{
+void rendermapmodels() {
static int skipoq = 0;
bool doquery = !drawtex && oqfrags && oqmm;
const vector<extentity *> &ents = entities::getents();
findvisiblemms(ents, doquery);
-
startmodelbatches();
- for(octaentities *oe = visiblemms; oe; oe = oe->next) if(oe->distance>=0)
- {
+ for(octaentities *oe = visiblemms; oe; oe = oe->next) if(oe->distance>=0) {
bool rendered = false;
- loopv(oe->mapmodels)
- {
+ loopv(oe->mapmodels) {
extentity &e = *ents[oe->mapmodels[i]];
if(!(e.flags&EF_RENDER)) continue;
- if(!rendered)
- {
+ if(!rendered) {
rendered = true;
oe->query = doquery && oe->distance>0 && !(++skipoq%oqmm) ? newquery(oe) : NULL;
if(oe->query) startmodelquery(oe->query);
@@ -465,14 +380,11 @@ void rendermapmodels()
if(rendered && oe->query) endmodelquery();
}
endmodelbatches();
-
bool queried = true;
- for(octaentities *oe = visiblemms; oe; oe = oe->next) if(oe->distance<0)
- {
+ for(octaentities *oe = visiblemms; oe; oe = oe->next) if(oe->distance<0) {
oe->query = doquery && !insideoe(oe, camera1->o) ? newquery(oe) : NULL;
if(!oe->query) continue;
- if(queried)
- {
+ if(queried) {
startbb();
queried = false;
}
@@ -480,25 +392,20 @@ void rendermapmodels()
drawbb(oe->bbmin, ivec(oe->bbmax).sub(oe->bbmin));
endquery(oe->query);
}
- if(!queried)
- {
+ if(!queried) {
endbb();
}
}
-static inline bool bbinsideva(const ivec &bo, const ivec &br, vtxarray *va)
-{
+static inline bool bbinsideva(const ivec &bo, const ivec &br, vtxarray *va) {
return bo.x >= va->bbmin.x && bo.y >= va->bbmin.y && bo.z >= va->bbmin.z &&
br.x <= va->bbmax.x && br.y <= va->bbmax.y && br.z <= va->bbmax.z;
}
-static inline bool bboccluded(const ivec &bo, const ivec &br, cube *c, const ivec &o, int size)
-{
- loopoctabox(o, size, bo, br)
- {
+static inline bool bboccluded(const ivec &bo, const ivec &br, cube *c, const ivec &o, int size) {
+ loopoctabox(o, size, bo, br) {
ivec co(i, o, size);
- if(c[i].ext && c[i].ext->va)
- {
+ if(c[i].ext && c[i].ext->va) {
vtxarray *va = c[i].ext->va;
if(va->occluded >= OCCLUDE_BB && bbinsideva(bo, br, va)) continue;
}
@@ -508,24 +415,20 @@ static inline bool bboccluded(const ivec &bo, const ivec &br, cube *c, const ive
return true;
}
-bool bboccluded(const ivec &bo, const ivec &br)
-{
+bool bboccluded(const ivec &bo, const ivec &br) {
int diff = (bo.x^br.x) | (bo.y^br.y) | (bo.z^br.z);
if(diff&~((1<<worldscale)-1)) return false;
int scale = worldscale-1;
if(diff&(1<<scale)) return bboccluded(bo, br, worldroot, ivec(0, 0, 0), 1<<scale);
cube *c = &worldroot[octastep(bo.x, bo.y, bo.z, scale)];
- if(c->ext && c->ext->va)
- {
+ if(c->ext && c->ext->va) {
vtxarray *va = c->ext->va;
if(va->occluded >= OCCLUDE_BB && bbinsideva(bo, br, va)) return true;
}
scale--;
- while(c->children && !(diff&(1<<scale)))
- {
+ while(c->children && !(diff&(1<<scale))) {
c = &c->children[octastep(bo.x, bo.y, bo.z, scale)];
- if(c->ext && c->ext->va)
- {
+ if(c->ext && c->ext->va) {
vtxarray *va = c->ext->va;
if(va->occluded >= OCCLUDE_BB && bbinsideva(bo, br, va)) return true;
}
@@ -539,103 +442,71 @@ VAR(outline, 0, 0, 1);
HVARP(outlinecolour, 0, 0, 0xFFFFFF);
VAR(dtoutline, 0, 1, 1);
-void renderoutline()
-{
+void renderoutline() {
notextureshader->set();
-
gle::enablevertex();
-
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
gle::color(vec::hexcolor(outlinecolour));
-
enablepolygonoffset(GL_POLYGON_OFFSET_LINE);
-
if(!dtoutline) glDisable(GL_DEPTH_TEST);
-
vtxarray *prev = NULL;
- for(vtxarray *va = visibleva; va; va = va->next)
- {
+ for(vtxarray *va = visibleva; va; va = va->next) {
if(va->occluded >= OCCLUDE_BB) continue;
if(!va->alphaback && !va->alphafront && (!va->texs || va->occluded >= OCCLUDE_GEOM)) continue;
-
- if(!prev || va->vbuf != prev->vbuf)
- {
+ if(!prev || va->vbuf != prev->vbuf) {
gle::bindvbo(va->vbuf);
gle::bindebo(va->ebuf);
const vertex *ptr = 0;
gle::vertexpointer(sizeof(vertex), ptr->pos.v);
}
-
- if(va->texs && va->occluded < OCCLUDE_GEOM)
- {
+ if(va->texs && va->occluded < OCCLUDE_GEOM) {
drawvatris(va, 3*va->tris, va->edata);
xtravertsva += va->verts;
}
- if(va->alphatris)
- {
+ if(va->alphatris) {
drawvatris(va, 3*va->alphatris, &va->edata[3*(va->tris + va->blendtris)]);
xtravertsva += 3*va->alphatris;
}
-
prev = va;
}
-
if(!dtoutline) glEnable(GL_DEPTH_TEST);
-
disablepolygonoffset(GL_POLYGON_OFFSET_LINE);
-
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
gle::clearvbo();
gle::clearebo();
gle::disablevertex();
}
-void rendershadowmapreceivers()
-{
+void rendershadowmapreceivers() {
SETSHADER(shadowmapreceiver);
-
gle::enablevertex();
-
glCullFace(GL_FRONT);
glDepthMask(GL_FALSE);
glDepthFunc(GL_GREATER);
-
extern int ati_minmax_bug;
if(!ati_minmax_bug) glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
-
glEnable(GL_BLEND);
glBlendEquation_(GL_MAX);
glBlendFunc(GL_ONE, GL_ONE);
-
vtxarray *prev = NULL;
- for(vtxarray *va = visibleva; va; va = va->next)
- {
+ for(vtxarray *va = visibleva; va; va = va->next) {
if(!va->texs || !isshadowmapreceiver(va)) continue;
-
- if(!prev || va->vbuf != prev->vbuf)
- {
+ if(!prev || va->vbuf != prev->vbuf) {
gle::bindvbo(va->vbuf);
gle::bindebo(va->ebuf);
const vertex *ptr = 0;
gle::vertexpointer(sizeof(vertex), ptr->pos.v);
}
-
drawvatris(va, 3*va->tris, va->edata);
xtravertsva += va->verts;
-
prev = va;
}
-
glDisable(GL_BLEND);
glBlendEquation_(GL_FUNC_ADD);
-
glCullFace(GL_BACK);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LESS);
-
if(!ati_minmax_bug) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
gle::clearvbo();
gle::clearebo();
gle::disablevertex();
@@ -645,8 +516,7 @@ VAR(oqdist, 0, 256, 1024);
VAR(zpass, 0, 1, 1);
VAR(envpass, 0, 1, 1);
-struct renderstate
-{
+struct renderstate {
bool colormask, depthmask, blending;
int alphaing;
GLuint vbuf;
@@ -660,68 +530,54 @@ struct renderstate
int texgendim;
int visibledynlights;
uint dynlightmask;
-
- renderstate() : colormask(true), depthmask(true), blending(false), alphaing(0), vbuf(0), vattribs(false), vquery(false), colorscale(1, 1, 1), alphascale(0), slot(NULL), texgenslot(NULL), vslot(NULL), texgenvslot(NULL), texgenscroll(0, 0), texgendim(-1), visibledynlights(0), dynlightmask(0)
- {
+ renderstate() : colormask(true), depthmask(true), blending(false), alphaing(0), vbuf(0), vattribs(false), vquery(false), colorscale(1, 1, 1), alphascale(0), slot(NULL), texgenslot(NULL), vslot(NULL), texgenvslot(NULL), texgenscroll(0, 0), texgendim(-1), visibledynlights(0), dynlightmask(0) {
loopk(8) textures[k] = 0;
}
};
-static inline void disablevbuf(renderstate &cur)
-{
+static inline void disablevbuf(renderstate &cur) {
gle::clearvbo();
gle::clearebo();
cur.vbuf = 0;
}
-static inline void enablevquery(renderstate &cur)
-{
+static inline void enablevquery(renderstate &cur) {
if(cur.colormask) { cur.colormask = false; glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); }
if(cur.depthmask) { cur.depthmask = false; glDepthMask(GL_FALSE); }
startbb(false);
cur.vquery = true;
}
-static inline void disablevquery(renderstate &cur)
-{
+static inline void disablevquery(renderstate &cur) {
endbb(false);
cur.vquery = false;
}
-static void renderquery(renderstate &cur, occludequery *query, vtxarray *va, bool full = true)
-{
+static void renderquery(renderstate &cur, occludequery *query, vtxarray *va, bool full = true) {
if(!cur.vquery) enablevquery(cur);
-
startquery(query);
-
if(full) drawbb(ivec(va->bbmin).sub(1), ivec(va->bbmax).sub(va->bbmin).add(2));
else drawbb(va->geommin, ivec(va->geommax).sub(va->geommin));
-
endquery(query);
}
-enum
-{
+enum {
RENDERPASS_LIGHTMAP = 0,
RENDERPASS_Z,
RENDERPASS_LIGHTMAP_BLEND
};
-struct geombatch
-{
+struct geombatch {
const elementset &es;
VSlot &vslot;
ushort *edata;
vtxarray *va;
int next, batch;
-
geombatch(const elementset &es, ushort *edata, vtxarray *va)
: es(es), vslot(lookupvslot(es.texture)), edata(edata), va(va),
- next(-1), batch(-1)
- {}
-
- int compare(const geombatch &b) const
- {
+ next(-1), batch(-1) {
+ }
+ int compare(const geombatch &b) const {
if(va->vbuf < b.va->vbuf) return -1;
if(va->vbuf > b.va->vbuf) return 1;
if(va->dynlightmask < b.va->dynlightmask) return -1;
@@ -743,73 +599,59 @@ struct geombatch
static vector<geombatch> geombatches;
static int firstbatch = -1, numbatches = 0;
-static void mergetexs(renderstate &cur, vtxarray *va, elementset *texs = NULL, int numtexs = 0, ushort *edata = NULL)
-{
- if(!texs)
- {
+static void mergetexs(renderstate &cur, vtxarray *va, elementset *texs = NULL, int numtexs = 0, ushort *edata = NULL) {
+ if(!texs) {
texs = va->eslist;
numtexs = va->texs;
edata = va->edata;
- if(cur.alphaing)
- {
+ if(cur.alphaing) {
texs += va->texs + va->blends;
edata += 3*(va->tris + va->blendtris);
numtexs = va->alphaback;
if(cur.alphaing > 1) numtexs += va->alphafront;
}
}
-
- if(firstbatch < 0)
- {
+ if(firstbatch < 0) {
firstbatch = geombatches.length();
numbatches = numtexs;
- loopi(numtexs-1)
- {
+ loopi(numtexs-1) {
geombatches.add(geombatch(texs[i], edata, va)).next = i+1;
edata += texs[i].length[1];
}
geombatches.add(geombatch(texs[numtexs-1], edata, va));
return;
}
-
int prevbatch = -1, curbatch = firstbatch, curtex = 0;
- do
- {
+ do {
geombatch &b = geombatches.add(geombatch(texs[curtex], edata, va));
edata += texs[curtex].length[1];
int dir = -1;
- while(curbatch >= 0)
- {
+ while(curbatch >= 0) {
dir = b.compare(geombatches[curbatch]);
if(dir <= 0) break;
prevbatch = curbatch;
curbatch = geombatches[curbatch].next;
}
- if(!dir)
- {
+ if(!dir) {
int last = curbatch, next;
- for(;;)
- {
+ for(;;) {
next = geombatches[last].batch;
if(next < 0) break;
last = next;
}
- if(last==curbatch)
- {
+ if(last==curbatch) {
b.batch = curbatch;
b.next = geombatches[curbatch].next;
if(prevbatch < 0) firstbatch = geombatches.length()-1;
else geombatches[prevbatch].next = geombatches.length()-1;
curbatch = geombatches.length()-1;
}
- else
- {
+ else {
b.batch = next;
geombatches[last].batch = geombatches.length()-1;
}
}
- else
- {
+ else {
numbatches++;
b.next = curbatch;
if(prevbatch < 0) firstbatch = geombatches.length()-1;
@@ -820,11 +662,9 @@ static void mergetexs(renderstate &cur, vtxarray *va, elementset *texs = NULL, i
while(++curtex < numtexs);
}
-static inline void enablevattribs(renderstate &cur, bool all = true)
-{
+static inline void enablevattribs(renderstate &cur, bool all = true) {
gle::enablevertex();
- if(all)
- {
+ if(all) {
gle::enabletexcoord0();
gle::enabletexcoord1();
gle::enablenormal();
@@ -833,11 +673,9 @@ static inline void enablevattribs(renderstate &cur, bool all = true)
cur.vattribs = true;
}
-static inline void disablevattribs(renderstate &cur, bool all = true)
-{
+static inline void disablevattribs(renderstate &cur, bool all = true) {
gle::disablevertex();
- if(all)
- {
+ if(all) {
gle::disabletexcoord0();
gle::disabletexcoord1();
gle::disablenormal();
@@ -846,17 +684,13 @@ static inline void disablevattribs(renderstate &cur, bool all = true)
cur.vattribs = false;
}
-static void changevbuf(renderstate &cur, int pass, vtxarray *va)
-{
+static void changevbuf(renderstate &cur, int pass, vtxarray *va) {
gle::bindvbo(va->vbuf);
gle::bindebo(va->ebuf);
cur.vbuf = va->vbuf;
-
vertex *vdata = (vertex *)0;
gle::vertexpointer(sizeof(vertex), vdata->pos.v);
-
- if(pass==RENDERPASS_LIGHTMAP)
- {
+ if(pass==RENDERPASS_LIGHTMAP) {
gle::normalpointer(sizeof(vertex), vdata->norm.v, GL_BYTE);
gle::texcoord0pointer(sizeof(vertex), vdata->tc.v);
gle::texcoord1pointer(sizeof(vertex), vdata->lm.v, GL_SHORT);
@@ -864,86 +698,68 @@ static void changevbuf(renderstate &cur, int pass, vtxarray *va)
}
}
-static void changebatchtmus(renderstate &cur, int pass, geombatch &b)
-{
+static void changebatchtmus(renderstate &cur, int pass, geombatch &b) {
bool changed = false;
extern bool brightengeom;
extern int fullbright;
int lmid = brightengeom && (b.es.lmid < LMID_RESERVED || (fullbright && editmode)) ? (int) LMID_BRIGHT : (int) b.es.lmid;
- if(cur.textures[1]!=lightmaptexs[lmid].id)
- {
+ if(cur.textures[1]!=lightmaptexs[lmid].id) {
glActiveTexture_(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, cur.textures[1] = lightmaptexs[lmid].id);
changed = true;
}
int tmu = 2;
- if(b.vslot.slot->shader->type&SHADER_NORMALSLMS)
- {
- if(cur.textures[tmu]!=lightmaptexs[lmid+1].id)
- {
+ if(b.vslot.slot->shader->type&SHADER_NORMALSLMS) {
+ if(cur.textures[tmu]!=lightmaptexs[lmid+1].id) {
glActiveTexture_(GL_TEXTURE0+tmu);
glBindTexture(GL_TEXTURE_2D, cur.textures[tmu] = lightmaptexs[lmid+1].id);
changed = true;
}
tmu++;
}
-
if(changed) glActiveTexture_(GL_TEXTURE0);
-
- if(cur.dynlightmask != b.va->dynlightmask)
- {
+ if(cur.dynlightmask != b.va->dynlightmask) {
cur.visibledynlights = setdynlights(b.va);
cur.dynlightmask = b.va->dynlightmask;
}
}
-static void changeslottmus(renderstate &cur, int pass, Slot &slot, VSlot &vslot)
-{
- if(pass==RENDERPASS_LIGHTMAP)
- {
+static void changeslottmus(renderstate &cur, int pass, Slot &slot, VSlot &vslot) {
+ if(pass==RENDERPASS_LIGHTMAP) {
GLuint diffusetex = slot.sts.empty() ? notexture->id : slot.sts[0].t->id;
if(cur.textures[0]!=diffusetex)
glBindTexture(GL_TEXTURE_2D, cur.textures[0] = diffusetex);
}
-
- if(cur.alphaing)
- {
+ if(cur.alphaing) {
float alpha = cur.alphaing > 1 ? vslot.alphafront : vslot.alphaback;
- if(cur.colorscale != vslot.colorscale || cur.alphascale != alpha)
- {
+ if(cur.colorscale != vslot.colorscale || cur.alphascale != alpha) {
cur.colorscale = vslot.colorscale;
cur.alphascale = alpha;
GLOBALPARAMF(colorparams, 2*alpha*vslot.colorscale.x, 2*alpha*vslot.colorscale.y, 2*alpha*vslot.colorscale.z, alpha);
}
}
- else if(cur.colorscale != vslot.colorscale)
- {
+ else if(cur.colorscale != vslot.colorscale) {
cur.colorscale = vslot.colorscale;
GLOBALPARAMF(colorparams, 2*vslot.colorscale.x, 2*vslot.colorscale.y, 2*vslot.colorscale.z, 1);
}
int tmu = 2;
if(slot.shader->type&SHADER_NORMALSLMS) tmu++;
- loopvj(slot.sts)
- {
+ loopvj(slot.sts) {
Slot::Tex &t = slot.sts[j];
if(t.type==TEX_DIFFUSE || t.combined>=0) continue;
- if(cur.textures[tmu]!=t.t->id)
- {
+ if(cur.textures[tmu]!=t.t->id) {
glActiveTexture_(GL_TEXTURE0+tmu);
glBindTexture(GL_TEXTURE_2D, cur.textures[tmu] = t.t->id);
}
if(++tmu >= 8) break;
}
glActiveTexture_(GL_TEXTURE0);
-
cur.slot = &slot;
cur.vslot = &vslot;
}
-static void changeshader(renderstate &cur, Shader *s, Slot &slot, VSlot &vslot, bool shadowed)
-{
- if(!cur.blending && !cur.alphaing)
- {
+static void changeshader(renderstate &cur, Shader *s, Slot &slot, VSlot &vslot, bool shadowed) {
+ if(!cur.blending && !cur.alphaing) {
if(shadowed) s->setvariant(cur.visibledynlights, 3, slot, vslot);
else s->setvariant(cur.visibledynlights, 2, slot, vslot);
}
@@ -952,17 +768,14 @@ static void changeshader(renderstate &cur, Shader *s, Slot &slot, VSlot &vslot,
else s->setvariant(cur.visibledynlights-1, 0, slot, vslot);
}
-static void changetexgen(renderstate &cur, int dim, Slot &slot, VSlot &vslot)
-{
- if(cur.texgenslot != &slot || cur.texgenvslot != &vslot)
- {
+static void changetexgen(renderstate &cur, int dim, Slot &slot, VSlot &vslot) {
+ if(cur.texgenslot != &slot || cur.texgenvslot != &vslot) {
Texture *curtex = !cur.texgenslot || cur.texgenslot->sts.empty() ? notexture : cur.texgenslot->sts[0].t,
*tex = slot.sts.empty() ? notexture : slot.sts[0].t;
if(!cur.texgenvslot || slot.sts.empty() ||
(curtex->xs != tex->xs || curtex->ys != tex->ys ||
cur.texgenvslot->rotation != vslot.rotation || cur.texgenvslot->scale != vslot.scale ||
- cur.texgenvslot->offset != vslot.offset || cur.texgenvslot->scroll != vslot.scroll))
- {
+ cur.texgenvslot->offset != vslot.offset || cur.texgenvslot->scroll != vslot.scroll)) {
const texrotation &r = texrotations[vslot.rotation];
float xs = r.flipx ? -tex->xs : tex->xs,
ys = r.flipy ? -tex->ys : tex->ys;
@@ -970,8 +783,7 @@ static void changetexgen(renderstate &cur, int dim, Slot &slot, VSlot &vslot)
if(r.swapxy) swap(scroll.x, scroll.y);
scroll.x *= lastmillis*tex->xs/xs;
scroll.y *= lastmillis*tex->ys/ys;
- if(cur.texgenscroll != scroll)
- {
+ if(cur.texgenscroll != scroll) {
cur.texgenscroll = scroll;
cur.texgendim = -1;
}
@@ -979,23 +791,18 @@ static void changetexgen(renderstate &cur, int dim, Slot &slot, VSlot &vslot)
cur.texgenslot = &slot;
cur.texgenvslot = &vslot;
}
-
if(cur.texgendim == dim) return;
GLOBALPARAM(texgenscroll, cur.texgenscroll);
cur.texgendim = dim;
}
-static void renderbatch(renderstate &cur, int pass, geombatch &b)
-{
+static void renderbatch(renderstate &cur, int pass, geombatch &b) {
geombatch *shadowed = NULL;
int rendered = -1;
- for(geombatch *curbatch = &b;; curbatch = &geombatches[curbatch->batch])
- {
+ for(geombatch *curbatch = &b;; curbatch = &geombatches[curbatch->batch]) {
ushort len = curbatch->es.length[curbatch->va->shadowed ? 0 : 1];
- if(len)
- {
- if(rendered < 0)
- {
+ if(len) {
+ if(rendered < 0) {
changeshader(cur, b.vslot.slot->shader, *b.vslot.slot, b.vslot, false);
rendered = 0;
gbatches++;
@@ -1008,12 +815,9 @@ static void renderbatch(renderstate &cur, int pass, geombatch &b)
if(curbatch->es.length[1] > len && !shadowed) shadowed = curbatch;
if(curbatch->batch < 0) break;
}
- if(shadowed) for(geombatch *curbatch = shadowed;; curbatch = &geombatches[curbatch->batch])
- {
- if(curbatch->va->shadowed && curbatch->es.length[1] > curbatch->es.length[0])
- {
- if(rendered < 1)
- {
+ if(shadowed) for(geombatch *curbatch = shadowed;; curbatch = &geombatches[curbatch->batch]) {
+ if(curbatch->va->shadowed && curbatch->es.length[1] > curbatch->es.length[0]) {
+ if(rendered < 1) {
changeshader(cur, b.vslot.slot->shader, *b.vslot.slot, b.vslot, true);
rendered = 1;
gbatches++;
@@ -1026,56 +830,44 @@ static void renderbatch(renderstate &cur, int pass, geombatch &b)
}
}
-static void resetbatches()
-{
+static void resetbatches() {
geombatches.setsize(0);
firstbatch = -1;
numbatches = 0;
}
-static void renderbatches(renderstate &cur, int pass)
-{
+static void renderbatches(renderstate &cur, int pass) {
cur.slot = NULL;
cur.vslot = NULL;
int curbatch = firstbatch;
- if(curbatch >= 0)
- {
- if(cur.alphaing)
- {
+ if(curbatch >= 0) {
+ if(cur.alphaing) {
if(cur.depthmask) { cur.depthmask = false; glDepthMask(GL_FALSE); }
}
else if(!cur.depthmask) { cur.depthmask = true; glDepthMask(GL_TRUE); }
if(!cur.colormask) { cur.colormask = true; glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, cur.alphaing ? GL_FALSE : GL_TRUE); }
- if(!cur.vattribs)
- {
+ if(!cur.vattribs) {
if(cur.vquery) disablevquery(cur);
enablevattribs(cur);
}
}
- while(curbatch >= 0)
- {
+ while(curbatch >= 0) {
geombatch &b = geombatches[curbatch];
curbatch = b.next;
-
if(cur.vbuf != b.va->vbuf) changevbuf(cur, pass, b.va);
- if(cur.vslot != &b.vslot)
- {
+ if(cur.vslot != &b.vslot) {
changeslottmus(cur, pass, *b.vslot.slot, b.vslot);
if(cur.texgendim != b.es.dim || (cur.texgendim <= 2 && cur.texgenvslot != &b.vslot)) changetexgen(cur, b.es.dim, *b.vslot.slot, b.vslot);
}
else if(cur.texgendim != b.es.dim) changetexgen(cur, b.es.dim, *b.vslot.slot, b.vslot);
if(pass == RENDERPASS_LIGHTMAP) changebatchtmus(cur, pass, b);
-
renderbatch(cur, pass, b);
}
-
resetbatches();
}
-void renderzpass(renderstate &cur, vtxarray *va)
-{
- if(!cur.vattribs)
- {
+void renderzpass(renderstate &cur, vtxarray *va) {
+ if(!cur.vattribs) {
if(cur.vquery) disablevquery(cur);
enablevattribs(cur, false);
}
@@ -1084,8 +876,7 @@ void renderzpass(renderstate &cur, vtxarray *va)
if(cur.colormask) { cur.colormask = false; glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); }
int firsttex = 0, numtris = va->tris;
ushort *edata = va->edata;
- if(cur.alphaing)
- {
+ if(cur.alphaing) {
firsttex += va->texs + va->blends;
edata += 3*(va->tris + va->blendtris);
numtris = va->alphatris;
@@ -1098,8 +889,8 @@ void renderzpass(renderstate &cur, vtxarray *va)
#define startvaquery(va, flush) \
do { \
- if(va->query) \
- { \
+ if(va->query) { \
+ \
flush; \
startquery(va->query); \
} \
@@ -1108,8 +899,8 @@ void renderzpass(renderstate &cur, vtxarray *va)
#define endvaquery(va, flush) \
do { \
- if(va->query) \
- { \
+ if(va->query) { \
+ \
flush; \
endquery(va->query); \
} \
@@ -1117,16 +908,13 @@ void renderzpass(renderstate &cur, vtxarray *va)
VAR(batchgeom, 0, 1, 1);
-void renderva(renderstate &cur, vtxarray *va, int pass = RENDERPASS_LIGHTMAP, bool doquery = false)
-{
- switch(pass)
- {
+void renderva(renderstate &cur, vtxarray *va, int pass = RENDERPASS_LIGHTMAP, bool doquery = false) {
+ switch(pass) {
case RENDERPASS_LIGHTMAP:
if(!cur.alphaing) vverts += va->verts;
va->shadowed = false;
va->dynlightmask = 0;
- if(!drawtex && !cur.alphaing)
- {
+ if(!drawtex && !cur.alphaing) {
va->shadowed = isshadowmapreceiver(va);
calcdynlightmask(va);
}
@@ -1135,16 +923,13 @@ void renderva(renderstate &cur, vtxarray *va, int pass = RENDERPASS_LIGHTMAP, bo
if(doquery) endvaquery(va, { if(geombatches.length()) renderbatches(cur, pass); });
else if(!batchgeom && geombatches.length()) renderbatches(cur, pass);
break;
-
- case RENDERPASS_LIGHTMAP_BLEND:
- {
+ case RENDERPASS_LIGHTMAP_BLEND: {
if(doquery) startvaquery(va, { if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP); });
mergetexs(cur, va, &va->eslist[va->texs], va->blends, va->edata + 3*va->tris);
if(doquery) endvaquery(va, { if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP); });
else if(!batchgeom && geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP);
break;
}
-
case RENDERPASS_Z:
if(doquery) startvaquery(va, );
renderzpass(cur, va);
@@ -1153,62 +938,49 @@ void renderva(renderstate &cur, vtxarray *va, int pass = RENDERPASS_LIGHTMAP, bo
}
}
-void cleanupva()
-{
+void cleanupva() {
clearvas(worldroot);
clearqueries();
cleanupbb();
}
-void setupgeom(renderstate &cur)
-{
+void setupgeom(renderstate &cur) {
GLOBALPARAMF(colorparams, 2, 2, 2, 1);
GLOBALPARAM(camera, camera1->o);
GLOBALPARAMF(ambient, ambientcolor.x/255.0f, ambientcolor.y/255.0f, ambientcolor.z/255.0f);
GLOBALPARAMF(millis, lastmillis/1000.0f);
-
glActiveTexture_(GL_TEXTURE0);
}
-void cleanupgeom(renderstate &cur)
-{
+void cleanupgeom(renderstate &cur) {
if(cur.vattribs) disablevattribs(cur);
if(cur.vbuf) disablevbuf(cur);
}
VAR(oqgeom, 0, 1, 1);
-void rendergeom(void)
-{
+void rendergeom(void) {
bool mainpass = !drawtex,
doOQ = oqfrags && oqgeom && mainpass,
doZP = doOQ && zpass,
doSM = shadowmap && !drawtex;
renderstate cur;
- if(mainpass)
- {
+ if(mainpass) {
flipqueries();
vtris = vverts = 0;
}
- if(!doZP)
- {
+ if(!doZP) {
if(shadowmap && mainpass) rendershadowmap();
setupgeom(cur);
if(doSM) pushshadowmap();
}
-
finddynlights();
-
resetbatches();
-
int blends = 0;
- for(vtxarray *va = visibleva; va; va = va->next)
- {
+ for(vtxarray *va = visibleva; va; va = va->next) {
if(!va->texs) continue;
- if(doOQ && (zpass || va->distance > oqdist) && !insideva(va, camera1->o))
- {
- if(va->parent && va->parent->occluded >= OCCLUDE_BB)
- {
+ if(doOQ && (zpass || va->distance > oqdist) && !insideva(va, camera1->o)) {
+ if(va->parent && va->parent->occluded >= OCCLUDE_BB) {
va->query = NULL;
va->occluded = OCCLUDE_PARENT;
continue;
@@ -1217,10 +989,8 @@ void rendergeom(void)
va->query = newquery(va);
if((!va->query && zpass) || !va->occluded)
va->occluded = OCCLUDE_NOTHING;
- if(va->occluded >= OCCLUDE_GEOM)
- {
- if(va->query)
- {
+ if(va->occluded >= OCCLUDE_GEOM) {
+ if(va->query) {
if(!zpass && geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP);
if(cur.vattribs) disablevattribs(cur, !doZP);
if(cur.vbuf) disablevbuf(cur);
@@ -1229,117 +999,85 @@ void rendergeom(void)
continue;
}
}
- else
- {
+ else {
va->query = NULL;
va->occluded = OCCLUDE_NOTHING;
}
-
if(!doZP) blends += va->blends;
renderva(cur, va, doZP ? RENDERPASS_Z : RENDERPASS_LIGHTMAP, doOQ);
}
-
if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP);
-
if(cur.vquery) disablevquery(cur);
if(cur.vattribs) disablevattribs(cur, !doZP);
if(cur.vbuf) disablevbuf(cur);
-
if(!cur.colormask) { cur.colormask = true; glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); }
if(!cur.depthmask) { cur.depthmask = true; glDepthMask(GL_TRUE); }
-
bool multipassing = false;
-
- if(doZP)
- {
+ if(doZP) {
glFlush();
-
if(shadowmap && mainpass) rendershadowmap();
setupgeom(cur);
if(doSM) pushshadowmap();
-
if(!multipassing) { multipassing = true; glDepthFunc(GL_LEQUAL); }
cur.texgendim = -1;
-
- for(vtxarray *va = visibleva; va; va = va->next)
- {
+ for(vtxarray *va = visibleva; va; va = va->next) {
if(!va->texs || va->occluded >= OCCLUDE_GEOM) continue;
blends += va->blends;
renderva(cur, va, RENDERPASS_LIGHTMAP);
}
if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP);
- for(vtxarray *va = visibleva; va; va = va->next)
- {
+ for(vtxarray *va = visibleva; va; va = va->next) {
if(!va->texs || va->occluded < OCCLUDE_GEOM) continue;
else if((va->parent && va->parent->occluded >= OCCLUDE_BB) ||
- (va->query && checkquery(va->query)))
- {
+ (va->query && checkquery(va->query))) {
va->occluded = OCCLUDE_BB;
continue;
}
-
blends += va->blends;
renderva(cur, va, RENDERPASS_LIGHTMAP);
}
if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP);
}
-
- if(blends)
- {
+ if(blends) {
if(cur.vbuf) disablevbuf(cur);
-
if(!multipassing) { multipassing = true; glDepthFunc(GL_LEQUAL); }
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
-
cur.texgendim = -1;
cur.blending = true;
- for(vtxarray *va = visibleva; va; va = va->next)
- {
+ for(vtxarray *va = visibleva; va; va = va->next) {
if(!va->blends) continue;
if(va->occluded >= OCCLUDE_GEOM) continue;
renderva(cur, va, RENDERPASS_LIGHTMAP_BLEND);
}
if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP);
cur.blending = false;
-
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
}
-
- if(doSM) popshadowmap();
-
if(cur.vattribs) disablevattribs(cur);
-
if(multipassing) glDepthFunc(GL_LESS);
-
cleanupgeom(cur);
}
-void renderalphageom(void)
-{
+void renderalphageom(void) {
static vector<vtxarray *> alphavas;
alphavas.setsize(0);
bool hasback = false;
- for(vtxarray *va = visibleva; va; va = va->next)
- {
+ for(vtxarray *va = visibleva; va; va = va->next) {
if(!va->alphatris) continue;
if(va->occluded >= OCCLUDE_BB) continue;
alphavas.add(va);
if(va->alphabacktris) hasback = true;
}
if(alphavas.empty()) return;
-
resetbatches();
-
renderstate cur;
cur.alphaing = 1;
-
- loop(front, 2) if(front || hasback)
- {
+ loop(front, 2) if(front || hasback) {
cur.alphaing = front+1;
if(!front) glCullFace(GL_FRONT);
cur.vbuf = 0;
@@ -1348,12 +1086,9 @@ void renderalphageom(void)
if(cur.depthmask) { cur.depthmask = false; glDepthMask(GL_FALSE); }
cur.colormask = true;
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
-
if(cur.vattribs) disablevattribs(cur, false);
if(cur.vbuf) disablevbuf(cur);
-
setupgeom(cur);
-
glDepthFunc(GL_LEQUAL);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@@ -1363,14 +1098,11 @@ void renderalphageom(void)
cur.alphascale = -1;
loopv(alphavas) if(front || alphavas[i]->alphabacktris) renderva(cur, alphavas[i], RENDERPASS_LIGHTMAP);
if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP);
-
cleanupgeom(cur);
-
if(!cur.depthmask) { cur.depthmask = true; glDepthMask(GL_TRUE); }
glDisable(GL_BLEND);
glDepthFunc(GL_LESS);
if(!front) glCullFace(GL_BACK);
}
-
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
diff --git a/src/engine/server.cpp b/src/engine/server.cpp
index 7e338b3..29761e1 100644
--- a/src/engine/server.cpp
+++ b/src/engine/server.cpp
@@ -7,25 +7,20 @@
static FILE *logfile = NULL;
-void closelogfile()
-{
- if(logfile)
- {
+void closelogfile() {
+ if(logfile) {
fclose(logfile);
logfile = NULL;
}
}
-FILE *getlogfile()
-{
+FILE *getlogfile() {
return logfile ? logfile : stdout;
}
-void setlogfile(const char *fname)
-{
+void setlogfile(const char *fname) {
closelogfile();
- if(fname && fname[0])
- {
+ if(fname && fname[0]) {
fname = findfile(fname, "w");
if(fname) logfile = fopen(fname, "w");
}
@@ -33,8 +28,7 @@ void setlogfile(const char *fname)
if(f) setvbuf(f, NULL, _IOLBF, BUFSIZ);
}
-void logoutf(const char *fmt, ...)
-{
+void logoutf(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
logoutfv(fmt, args);
@@ -42,28 +36,24 @@ void logoutf(const char *fmt, ...)
}
-static void writelog(FILE *file, const char *buf)
-{
+static void writelog(FILE *file, const char *buf) {
static uchar ubuf[512];
size_t len = strlen(buf), carry = 0;
- while(carry < len)
- {
+ while(carry < len) {
size_t numu = encodeutf8(ubuf, sizeof(ubuf)-1, &((const uchar *)buf)[carry], len - carry, &carry);
if(carry >= len) ubuf[numu++] = '\n';
fwrite(ubuf, 1, numu, file);
}
}
-static void writelogv(FILE *file, const char *fmt, va_list args)
-{
+static void writelogv(FILE *file, const char *fmt, va_list args) {
static char buf[LOGSTRLEN];
vformatstring(buf, fmt, args, sizeof(buf));
writelog(file, buf);
}
#ifdef STANDALONE
-void fatal(const char *fmt, ...)
-{
+void fatal(const char *fmt, ...) {
void cleanupserver();
cleanupserver();
defvformatstring(msg,fmt,fmt);
@@ -73,8 +63,7 @@ void fatal(const char *fmt, ...)
exit(EXIT_FAILURE);
}
-void conoutfv(int type, const char *fmt, va_list args)
-{
+void conoutfv(int type, const char *fmt, va_list args) {
logoutfv(fmt, args);
}
#endif
@@ -83,8 +72,7 @@ void conoutfv(int type, const char *fmt, va_list args)
enum { ST_EMPTY, ST_LOCAL, ST_TCPIP };
-struct client // server side version of "dynent" type
-{
+struct client { // server side version of "dynent" type {
int type;
int num;
ENetPeer *peer;
@@ -103,53 +91,44 @@ int localclients = 0, nonlocalclients = 0;
bool hasnonlocalclients() { return nonlocalclients!=0; }
bool haslocalclients() { return localclients!=0; }
-client &addclient(int type)
-{
+client &addclient(int type) {
client *c = NULL;
- loopv(clients) if(clients[i]->type==ST_EMPTY)
- {
+ loopv(clients) if(clients[i]->type==ST_EMPTY) {
c = clients[i];
break;
}
- if(!c)
- {
+ if(!c) {
c = new client;
c->num = clients.length();
clients.add(c);
}
c->info = server::newclientinfo();
c->type = type;
- switch(type)
- {
+ switch(type) {
case ST_TCPIP: nonlocalclients++; break;
case ST_LOCAL: localclients++; break;
}
return *c;
}
-void delclient(client *c)
-{
+void delclient(client *c) {
if(!c) return;
- switch(c->type)
- {
+ switch(c->type) {
case ST_TCPIP: nonlocalclients--; if(c->peer) c->peer->data = NULL; break;
case ST_LOCAL: localclients--; break;
case ST_EMPTY: return;
}
c->type = ST_EMPTY;
c->peer = NULL;
- if(c->info)
- {
+ if(c->info) {
server::deleteclientinfo(c->info);
c->info = NULL;
}
}
-void cleanupserver()
-{
+void cleanupserver() {
if(serverhost) enet_host_destroy(serverhost);
serverhost = NULL;
-
if(pongsock != ENET_SOCKET_NULL) enet_socket_destroy(pongsock);
if(lansock != ENET_SOCKET_NULL) enet_socket_destroy(lansock);
pongsock = lansock = ENET_SOCKET_NULL;
@@ -167,18 +146,14 @@ ENetPeer *getclientpeer(int i) { return clients.inrange(i) && clients[i]->type==
int getnumclients() { return clients.length(); }
uint getclientip(int n) { return clients.inrange(n) && clients[n]->type==ST_TCPIP ? clients[n]->peer->address.host : 0; }
-void sendpacket(int n, int chan, ENetPacket *packet, int exclude)
-{
- if(n<0)
- {
+void sendpacket(int n, int chan, ENetPacket *packet, int exclude) {
+ if(n<0) {
server::recordpacket(chan, packet->data, packet->dataLength);
loopv(clients) if(i!=exclude && server::allowbroadcast(i)) sendpacket(i, chan, packet);
return;
}
- switch(clients[n]->type)
- {
- case ST_TCPIP:
- {
+ switch(clients[n]->type) {
+ case ST_TCPIP: {
enet_peer_send(clients[n]->peer, chan, packet);
break;
}
@@ -191,43 +166,35 @@ void sendpacket(int n, int chan, ENetPacket *packet, int exclude)
}
}
-ENetPacket *sendf(int cn, int chan, const char *format, ...)
-{
+ENetPacket *sendf(int cn, int chan, const char *format, ...) {
int exclude = -1;
bool reliable = false;
if(*format=='r') { reliable = true; ++format; }
packetbuf p(MAXTRANS, reliable ? ENET_PACKET_FLAG_RELIABLE : 0);
va_list args;
va_start(args, format);
- while(*format) switch(*format++)
- {
+ while(*format) switch(*format++) {
case 'x':
exclude = va_arg(args, int);
break;
-
- case 'v':
- {
+ case 'v': {
int n = va_arg(args, int);
int *v = va_arg(args, int *);
loopi(n) putint(p, v[i]);
break;
}
-
- case 'i':
- {
+ case 'i': {
int n = isdigit(*format) ? *format++-'0' : 1;
loopi(n) putint(p, va_arg(args, int));
break;
}
- case 'f':
- {
+ case 'f': {
int n = isdigit(*format) ? *format++-'0' : 1;
loopi(n) putfloat(p, (float)va_arg(args, double));
break;
}
case 's': sendstring(va_arg(args, const char *), p); break;
- case 'm':
- {
+ case 'm': {
int n = va_arg(args, int);
p.put(va_arg(args, uchar *), n);
break;
@@ -239,26 +206,20 @@ ENetPacket *sendf(int cn, int chan, const char *format, ...)
return packet->referenceCount > 0 ? packet : NULL;
}
-ENetPacket *sendfile(int cn, int chan, stream *file, const char *format, ...)
-{
- if(cn < 0)
- {
+ENetPacket *sendfile(int cn, int chan, stream *file, const char *format, ...) {
+ if(cn < 0) {
#ifdef STANDALONE
return NULL;
#endif
}
else if(!clients.inrange(cn)) return NULL;
-
int len = (int)min(file->size(), stream::offset(INT_MAX));
if(len <= 0 || len > 16<<20) return NULL;
-
packetbuf p(MAXTRANS+len, ENET_PACKET_FLAG_RELIABLE);
va_list args;
va_start(args, format);
- while(*format) switch(*format++)
- {
- case 'i':
- {
+ while(*format) switch(*format++) {
+ case 'i': {
int n = isdigit(*format) ? *format++-'0' : 1;
loopi(n) putint(p, va_arg(args, int));
break;
@@ -267,10 +228,8 @@ ENetPacket *sendfile(int cn, int chan, stream *file, const char *format, ...)
case 'l': putint(p, len); break;
}
va_end(args);
-
file->seek(0, SEEK_SET);
file->read(p.subbuf(len).buf, len);
-
ENetPacket *packet = p.finalize();
if(cn >= 0) sendpacket(cn, chan, packet, -1);
#ifndef STANDALONE
@@ -279,10 +238,8 @@ ENetPacket *sendfile(int cn, int chan, stream *file, const char *format, ...)
return packet->referenceCount > 0 ? packet : NULL;
}
-const char *disconnectreason(int reason)
-{
- switch(reason)
- {
+const char *disconnectreason(int reason) {
+ switch(reason) {
case DISC_EOP: return "end of packet";
case DISC_LOCAL: return "server is in local mode";
case DISC_KICK: return "kicked/banned";
@@ -297,8 +254,7 @@ const char *disconnectreason(int reason)
}
}
-void disconnect_client(int n, int reason)
-{
+void disconnect_client(int n, int reason) {
if(!clients.inrange(n) || clients[n]->type!=ST_TCPIP) return;
enet_peer_disconnect(clients[n]->peer, reason);
server::clientdisconnect(n);
@@ -311,33 +267,28 @@ void disconnect_client(int n, int reason)
server::sendservmsg(s);
}
-void kicknonlocalclients(int reason)
-{
+void kicknonlocalclients(int reason) {
loopv(clients) if(clients[i]->type==ST_TCPIP) disconnect_client(i, reason);
}
-void process(ENetPacket *packet, int sender, int chan) // sender may be -1
-{
+void process(ENetPacket *packet, int sender, int chan) { // sender may be -1 {
packetbuf p(packet);
server::parsepacket(sender, chan, p);
if(p.overread()) { disconnect_client(sender, DISC_EOP); return; }
}
-void localclienttoserver(int chan, ENetPacket *packet)
-{
+void localclienttoserver(int chan, ENetPacket *packet) {
client *c = NULL;
loopv(clients) if(clients[i]->type==ST_LOCAL) { c = clients[i]; break; }
if(c) process(packet, c->num, chan);
}
#ifdef STANDALONE
-bool resolverwait(const char *name, ENetAddress *address)
-{
+bool resolverwait(const char *name, ENetAddress *address) {
return enet_address_set_host(address, name) >= 0;
}
-int connectwithtimeout(ENetSocket sock, const char *hostname, const ENetAddress &remoteaddress)
-{
+int connectwithtimeout(ENetSocket sock, const char *hostname, const ENetAddress &remoteaddress) {
return enet_socket_connect(sock, &remoteaddress);
}
#endif
@@ -349,48 +300,38 @@ vector<char> masterout, masterin;
int masteroutpos = 0, masterinpos = 0;
VARN(updatemaster, allowupdatemaster, 0, 1, 1);
-void disconnectmaster()
-{
- if(mastersock != ENET_SOCKET_NULL)
- {
+void disconnectmaster() {
+ if(mastersock != ENET_SOCKET_NULL) {
server::masterdisconnected();
enet_socket_destroy(mastersock);
mastersock = ENET_SOCKET_NULL;
}
-
masterout.setsize(0);
masterin.setsize(0);
masteroutpos = masterinpos = 0;
-
masteraddress.host = ENET_HOST_ANY;
masteraddress.port = ENET_PORT_ANY;
-
lastupdatemaster = masterconnecting = masterconnected = 0;
}
SVARF(mastername, server::defaultmaster(), disconnectmaster());
VARF(masterport, 1, server::masterport(), 0xFFFF, disconnectmaster());
-ENetSocket connectmaster(bool wait)
-{
+ENetSocket connectmaster(bool wait) {
if(!mastername[0]) return ENET_SOCKET_NULL;
- if(masteraddress.host == ENET_HOST_ANY)
- {
+ if(masteraddress.host == ENET_HOST_ANY) {
if(isdedicatedserver()) logoutf("looking up %s...", mastername);
masteraddress.port = masterport;
if(!resolverwait(mastername, &masteraddress)) return ENET_SOCKET_NULL;
}
ENetSocket sock = enet_socket_create(ENET_SOCKET_TYPE_STREAM);
- if(sock == ENET_SOCKET_NULL)
- {
+ if(sock == ENET_SOCKET_NULL) {
if(isdedicatedserver()) logoutf("could not open master server socket");
return ENET_SOCKET_NULL;
}
- if(wait || serveraddress.host == ENET_HOST_ANY || !enet_socket_bind(sock, &serveraddress))
- {
+ if(wait || serveraddress.host == ENET_HOST_ANY || !enet_socket_bind(sock, &serveraddress)) {
enet_socket_set_option(sock, ENET_SOCKOPT_NONBLOCK, 1);
- if(wait)
- {
+ if(wait) {
if(!connectwithtimeout(sock, mastername, masteraddress)) return sock;
}
else if(!enet_socket_connect(sock, &masteraddress)) return sock;
@@ -400,78 +341,60 @@ ENetSocket connectmaster(bool wait)
return ENET_SOCKET_NULL;
}
-bool requestmaster(const char *req)
-{
- if(mastersock == ENET_SOCKET_NULL)
- {
+bool requestmaster(const char *req) {
+ if(mastersock == ENET_SOCKET_NULL) {
mastersock = connectmaster(false);
if(mastersock == ENET_SOCKET_NULL) return false;
lastconnectmaster = masterconnecting = totalmillis ? totalmillis : 1;
}
-
if(masterout.length() >= 4096) return false;
-
masterout.put(req, strlen(req));
return true;
}
-bool requestmasterf(const char *fmt, ...)
-{
+bool requestmasterf(const char *fmt, ...) {
defvformatstring(req, fmt, fmt);
return requestmaster(req);
}
-void processmasterinput()
-{
+void processmasterinput() {
if(masterinpos >= masterin.length()) return;
-
char *input = &masterin[masterinpos], *end = (char *)memchr(input, '\n', masterin.length() - masterinpos);
- while(end)
- {
+ while(end) {
*end = '\0';
-
const char *args = input;
while(args < end && !iscubespace(*args)) args++;
int cmdlen = args - input;
while(args < end && iscubespace(*args)) args++;
-
if(matchstring(input, cmdlen, "failreg"))
conoutf(CON_ERROR, "master server registration failed: %s", args);
else if(matchstring(input, cmdlen, "succreg"))
conoutf("master server registration succeeded");
- else server::processmasterinput(input, cmdlen, args);
-
+ else server::processmasterinput(input, cmdlen);
end++;
masterinpos = end - masterin.getbuf();
input = end;
end = (char *)memchr(input, '\n', masterin.length() - masterinpos);
}
-
- if(masterinpos >= masterin.length())
- {
+ if(masterinpos >= masterin.length()) {
masterin.setsize(0);
masterinpos = 0;
}
}
-void flushmasteroutput()
-{
- if(masterconnecting && totalmillis - masterconnecting >= 60000)
- {
+void flushmasteroutput() {
+ if(masterconnecting && totalmillis - masterconnecting >= 60000) {
logoutf("could not connect to master server");
disconnectmaster();
}
if(masterout.empty() || !masterconnected) return;
-
ENetBuffer buf;
buf.data = &masterout[masteroutpos];
buf.dataLength = masterout.length() - masteroutpos;
int sent = enet_socket_send(mastersock, NULL, &buf, 1);
- if(sent >= 0)
- {
+ if(sent >= 0) {
masteroutpos += sent;
- if(masteroutpos >= masterout.length())
- {
+ if(masteroutpos >= masterout.length()) {
masterout.setsize(0);
masteroutpos = 0;
}
@@ -479,17 +402,14 @@ void flushmasteroutput()
else disconnectmaster();
}
-void flushmasterinput()
-{
+void flushmasterinput() {
if(masterin.length() >= masterin.capacity())
masterin.reserve(4096);
-
ENetBuffer buf;
buf.data = masterin.getbuf() + masterin.length();
buf.dataLength = masterin.capacity() - masterin.length();
int recv = enet_socket_receive(mastersock, NULL, &buf, 1);
- if(recv > 0)
- {
+ if(recv > 0) {
masterin.advance(recv);
processmasterinput();
}
@@ -498,8 +418,7 @@ void flushmasterinput()
static ENetAddress pongaddr;
-void sendserverinforeply(ucharbuf &p)
-{
+void sendserverinforeply(ucharbuf &p) {
ENetBuffer buf;
buf.data = p.buf;
buf.dataLength = p.length();
@@ -508,33 +427,27 @@ void sendserverinforeply(ucharbuf &p)
#define MAXPINGDATA 32
-void checkserversockets() // reply all server info requests
-{
+void checkserversockets() { // reply all server info requests {
static ENetSocketSet readset, writeset;
ENET_SOCKETSET_EMPTY(readset);
ENET_SOCKETSET_EMPTY(writeset);
ENetSocket maxsock = pongsock;
ENET_SOCKETSET_ADD(readset, pongsock);
- if(mastersock != ENET_SOCKET_NULL)
- {
+ if(mastersock != ENET_SOCKET_NULL) {
maxsock = max(maxsock, mastersock);
ENET_SOCKETSET_ADD(readset, mastersock);
if(!masterconnected) ENET_SOCKETSET_ADD(writeset, mastersock);
}
- if(lansock != ENET_SOCKET_NULL)
- {
+ if(lansock != ENET_SOCKET_NULL) {
maxsock = max(maxsock, lansock);
ENET_SOCKETSET_ADD(readset, lansock);
}
if(enet_socketset_select(maxsock, &readset, &writeset, 0) <= 0) return;
-
ENetBuffer buf;
uchar pong[MAXTRANS];
- loopi(2)
- {
+ loopi(2) {
ENetSocket sock = i ? lansock : pongsock;
if(sock == ENET_SOCKET_NULL || !ENET_SOCKETSET_CHECK(readset, sock)) continue;
-
buf.data = pong;
buf.dataLength = sizeof(pong);
int len = enet_socket_receive(sock, &pongaddr, &buf, 1);
@@ -543,21 +456,15 @@ void checkserversockets() // reply all server info requests
p.len += len;
server::serverinforeply(req, p);
}
-
- if(mastersock != ENET_SOCKET_NULL)
- {
- if(!masterconnected)
- {
- if(ENET_SOCKETSET_CHECK(readset, mastersock) || ENET_SOCKETSET_CHECK(writeset, mastersock))
- {
+ if(mastersock != ENET_SOCKET_NULL) {
+ if(!masterconnected) {
+ if(ENET_SOCKETSET_CHECK(readset, mastersock) || ENET_SOCKETSET_CHECK(writeset, mastersock)) {
int error = 0;
- if(enet_socket_get_option(mastersock, ENET_SOCKOPT_ERROR, &error) < 0 || error)
- {
+ if(enet_socket_get_option(mastersock, ENET_SOCKOPT_ERROR, &error) < 0 || error) {
logoutf("could not connect to master server");
disconnectmaster();
}
- else
- {
+ else {
masterconnecting = 0;
masterconnected = totalmillis ? totalmillis : 1;
server::masterconnected();
@@ -576,8 +483,7 @@ VARF(serverport, 0, server::serverport(), 0xFFFF-1, { if(!serverport) serverport
int curtime = 0, lastmillis = 0, elapsedtime = 0, totalmillis = 0;
#endif
-void updatemasterserver()
-{
+void updatemasterserver() {
if(!masterconnected && lastconnectmaster && totalmillis-lastconnectmaster <= 5*60*1000) return;
if(mastername[0] && allowupdatemaster) requestmasterf("regserv %d\n", serverport);
lastupdatemaster = totalmillis ? totalmillis : 1;
@@ -585,30 +491,23 @@ void updatemasterserver()
uint totalsecs = 0;
-void updatetime()
-{
+void updatetime() {
static int lastsec = 0;
- if(totalmillis - lastsec >= 1000)
- {
+ if(totalmillis - lastsec >= 1000) {
int cursecs = (totalmillis - lastsec) / 1000;
totalsecs += cursecs;
lastsec += cursecs * 1000;
}
}
-void serverslice(bool dedicated, uint timeout) // main server update, called from main loop in sp, or from below in dedicated server
-{
- if(!serverhost)
- {
+void serverslice(bool dedicated, uint timeout) { // main server update, called from main loop in sp, or from below in dedicated server {
+ if(!serverhost) {
server::serverupdate();
server::sendpackets();
return;
}
-
// below is network only
-
- if(dedicated)
- {
+ if(dedicated) {
int millis = (int)enet_time_get();
elapsedtime = millis - totalmillis;
static int timeerr = 0;
@@ -621,33 +520,24 @@ void serverslice(bool dedicated, uint timeout) // main server update, called f
updatetime();
}
server::serverupdate();
-
flushmasteroutput();
checkserversockets();
-
if(!lastupdatemaster || totalmillis-lastupdatemaster>60*60*1000) // send alive signal to masterserver every hour of uptime
updatemasterserver();
-
- if(totalmillis-laststatus>60*1000) // display bandwidth stats, useful for server ops
- {
+ if(totalmillis-laststatus>60*1000) { // display bandwidth stats, useful for server ops {
laststatus = totalmillis;
if(nonlocalclients || serverhost->totalSentData || serverhost->totalReceivedData) logoutf("status: %d remote clients, %.1f send, %.1f rec (K/sec)", nonlocalclients, serverhost->totalSentData/60.0f/1024, serverhost->totalReceivedData/60.0f/1024);
serverhost->totalSentData = serverhost->totalReceivedData = 0;
}
-
ENetEvent event;
bool serviced = false;
- while(!serviced)
- {
- if(enet_host_check_events(serverhost, &event) <= 0)
- {
+ while(!serviced) {
+ if(enet_host_check_events(serverhost, &event) <= 0) {
if(enet_host_service(serverhost, &event, timeout) <= 0) break;
serviced = true;
}
- switch(event.type)
- {
- case ENET_EVENT_TYPE_CONNECT:
- {
+ switch(event.type) {
+ case ENET_EVENT_TYPE_CONNECT: {
client &c = addclient(ST_TCPIP);
c.peer = event.peer;
c.peer->data = &c;
@@ -658,15 +548,13 @@ void serverslice(bool dedicated, uint timeout) // main server update, called f
if(reason) disconnect_client(c.num, reason);
break;
}
- case ENET_EVENT_TYPE_RECEIVE:
- {
+ case ENET_EVENT_TYPE_RECEIVE: {
client *c = (client *)event.peer->data;
if(c) process(event.packet, c->num, event.channelID);
if(event.packet->referenceCount==0) enet_packet_destroy(event.packet);
break;
}
- case ENET_EVENT_TYPE_DISCONNECT:
- {
+ case ENET_EVENT_TYPE_DISCONNECT: {
client *c = (client *)event.peer->data;
if(!c) break;
logoutf("disconnected client (%s)", c->hostname);
@@ -681,17 +569,14 @@ void serverslice(bool dedicated, uint timeout) // main server update, called f
if(server::sendpackets()) enet_host_flush(serverhost);
}
-void flushserver(bool force)
-{
+void flushserver(bool force) {
if(server::sendpackets(force) && serverhost) enet_host_flush(serverhost);
}
#ifndef STANDALONE
-void localdisconnect(bool cleanup)
-{
+void localdisconnect(bool cleanup) {
bool disconnected = false;
- loopv(clients) if(clients[i]->type==ST_LOCAL)
- {
+ loopv(clients) if(clients[i]->type==ST_LOCAL) {
server::localdisconnect(i);
delclient(clients[i]);
disconnected = true;
@@ -701,8 +586,7 @@ void localdisconnect(bool cleanup)
mainmenu = 1;
}
-void localconnect()
-{
+void localconnect() {
if(initing) return;
client &c = addclient(ST_LOCAL);
copystring(c.hostname, "local");
@@ -711,8 +595,7 @@ void localconnect()
}
#endif
-void logoutfv(const char *fmt, va_list args)
-{
+void logoutfv(const char *fmt, va_list args) {
FILE *f = getlogfile();
if(f) writelogv(f, fmt, args);
}
@@ -721,19 +604,17 @@ static bool dedicatedserver = false;
bool isdedicatedserver() { return dedicatedserver; }
-void rundedicatedserver()
-{
+void rundedicatedserver() {
dedicatedserver = true;
logoutf("dedicated server started, waiting for clients...");
for(;;) serverslice(true, 5);
dedicatedserver = false;
}
-bool servererror(bool dedicated, const char *desc)
-{
+bool servererror(bool dedicated, const char *desc) {
+ (void) dedicated;
#ifndef STANDALONE
- if(!dedicated)
- {
+ if(!dedicated) {
conoutf(CON_ERROR, "%s", desc);
cleanupserver();
}
@@ -743,11 +624,9 @@ bool servererror(bool dedicated, const char *desc)
return false;
}
-bool setuplistenserver(bool dedicated)
-{
+bool setuplistenserver(bool dedicated) {
ENetAddress address = { ENET_HOST_ANY, enet_uint16(serverport <= 0 ? server::serverport() : serverport) };
- if(*serverip)
- {
+ if(*serverip) {
if(enet_address_set_host(&address, serverip)<0) conoutf(CON_WARN, "WARNING: server ip not resolved");
else serveraddress.host = address.host;
}
@@ -756,8 +635,7 @@ bool setuplistenserver(bool dedicated)
serverhost->duplicatePeers = maxdupclients ? maxdupclients : MAXCLIENTS;
address.port = server::serverinfoport(serverport > 0 ? serverport : -1);
pongsock = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
- if(pongsock != ENET_SOCKET_NULL && enet_socket_bind(pongsock, &address) < 0)
- {
+ if(pongsock != ENET_SOCKET_NULL && enet_socket_bind(pongsock, &address) < 0) {
enet_socket_destroy(pongsock);
pongsock = ENET_SOCKET_NULL;
}
@@ -765,8 +643,7 @@ bool setuplistenserver(bool dedicated)
else enet_socket_set_option(pongsock, ENET_SOCKOPT_NONBLOCK, 1);
address.port = server::laninfoport();
lansock = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
- if(lansock != ENET_SOCKET_NULL && (enet_socket_set_option(lansock, ENET_SOCKOPT_REUSEADDR, 1) < 0 || enet_socket_bind(lansock, &address) < 0))
- {
+ if(lansock != ENET_SOCKET_NULL && (enet_socket_set_option(lansock, ENET_SOCKOPT_REUSEADDR, 1) < 0 || enet_socket_bind(lansock, &address) < 0)) {
enet_socket_destroy(lansock);
lansock = ENET_SOCKET_NULL;
}
@@ -775,16 +652,11 @@ bool setuplistenserver(bool dedicated)
return true;
}
-void initserver(bool listen, bool dedicated)
-{
+void initserver(bool listen, bool dedicated) {
execfile("server-init.cfg", false);
-
if(listen) setuplistenserver(dedicated);
-
server::serverinit();
-
- if(listen)
- {
+ if(listen) {
dedicatedserver = dedicated;
updatemasterserver();
if(dedicated) rundedicatedserver(); // never returns
@@ -795,37 +667,27 @@ void initserver(bool listen, bool dedicated)
}
#ifndef STANDALONE
-void startlistenserver(int *usemaster)
-{
+void startlistenserver(int *usemaster) {
if(serverhost) { conoutf(CON_ERROR, "listen server is already running"); return; }
-
allowupdatemaster = *usemaster>0 ? 1 : 0;
-
if(!setuplistenserver(false)) return;
-
updatemasterserver();
-
conoutf("listen server started for %d clients%s", maxclients, allowupdatemaster ? " and listed with master server" : "");
}
COMMAND(startlistenserver, "i");
-void stoplistenserver()
-{
+void stoplistenserver() {
if(!serverhost) { conoutf(CON_ERROR, "listen server is not running"); return; }
-
kicknonlocalclients();
enet_host_flush(serverhost);
cleanupserver();
-
conoutf("listen server stopped");
}
COMMAND(stoplistenserver, "");
#endif
-bool serveroption(char *opt)
-{
- switch(opt[1])
- {
+bool serveroption(char *opt) {
+ switch(opt[1]) {
case 'u': setvar("serveruprate", atoi(opt+2)); return true;
case 'c': setvar("maxclients", atoi(opt+2)); return true;
case 'i': setsvar("serverip", opt+2); return true;
@@ -843,8 +705,7 @@ bool serveroption(char *opt)
vector<const char *> gameargs;
#ifdef STANDALONE
-int main(int argc, char **argv)
-{
+int main(int argc, char **argv) {
setlogfile(NULL);
if(enet_initialize()<0) fatal("Unable to initialise network module");
atexit(enet_deinitialize);
diff --git a/src/engine/serverbrowser.cpp b/src/engine/serverbrowser.cpp
index 85109bf..a839c35 100644
--- a/src/engine/serverbrowser.cpp
+++ b/src/engine/serverbrowser.cpp
@@ -4,15 +4,13 @@
#define PROTOCOL_VERSION 260 // bump when protocol changes, dpulicate
-struct resolverthread
-{
+struct resolverthread {
SDL_Thread *thread;
const char *query;
int starttime;
};
-struct resolverresult
-{
+struct resolverresult {
const char *query;
ENetAddress address;
};
@@ -26,28 +24,23 @@ SDL_cond *querycond, *resultcond;
#define RESOLVERTHREADS 2
#define RESOLVERLIMIT 3000
-int resolverloop(void * data)
-{
+int resolverloop(void * data) {
resolverthread *rt = (resolverthread *)data;
SDL_LockMutex(resolvermutex);
SDL_Thread *thread = rt->thread;
SDL_UnlockMutex(resolvermutex);
if(!thread || SDL_GetThreadID(thread) != SDL_ThreadID())
return 0;
- while(thread == rt->thread)
- {
+ while(thread == rt->thread) {
SDL_LockMutex(resolvermutex);
while(resolverqueries.empty()) SDL_CondWait(querycond, resolvermutex);
rt->query = resolverqueries.pop();
rt->starttime = totalmillis;
SDL_UnlockMutex(resolvermutex);
-
ENetAddress address = { ENET_HOST_ANY, ENET_PORT_ANY };
enet_address_set_host(&address, rt->query);
-
SDL_LockMutex(resolvermutex);
- if(rt->query && thread == rt->thread)
- {
+ if(rt->query && thread == rt->thread) {
resolverresult &rr = resolverresults.add();
rr.query = rt->query;
rr.address = address;
@@ -60,15 +53,12 @@ int resolverloop(void * data)
return 0;
}
-void resolverinit()
-{
+void resolverinit() {
resolvermutex = SDL_CreateMutex();
querycond = SDL_CreateCond();
resultcond = SDL_CreateCond();
-
SDL_LockMutex(resolvermutex);
- loopi(RESOLVERTHREADS)
- {
+ loopi(RESOLVERTHREADS) {
resolverthread &rt = resolverthreads.add();
rt.query = NULL;
rt.starttime = 0;
@@ -77,11 +67,9 @@ void resolverinit()
SDL_UnlockMutex(resolvermutex);
}
-void resolverstop(resolverthread &rt)
-{
+void resolverstop(resolverthread &rt) {
SDL_LockMutex(resolvermutex);
- if(rt.query)
- {
+ if(rt.query) {
#if SDL_VERSION_ATLEAST(2, 0, 2)
SDL_DetachThread(rt.thread);
#endif
@@ -92,47 +80,38 @@ void resolverstop(resolverthread &rt)
SDL_UnlockMutex(resolvermutex);
}
-void resolverclear()
-{
+void resolverclear() {
if(resolverthreads.empty()) return;
-
SDL_LockMutex(resolvermutex);
resolverqueries.shrink(0);
resolverresults.shrink(0);
- loopv(resolverthreads)
- {
+ loopv(resolverthreads) {
resolverthread &rt = resolverthreads[i];
resolverstop(rt);
}
SDL_UnlockMutex(resolvermutex);
}
-void resolverquery(const char *name)
-{
+void resolverquery(const char *name) {
if(resolverthreads.empty()) resolverinit();
-
SDL_LockMutex(resolvermutex);
resolverqueries.add(name);
SDL_CondSignal(querycond);
SDL_UnlockMutex(resolvermutex);
}
-bool resolvercheck(const char **name, ENetAddress *address)
-{
+bool resolvercheck(const char **name, ENetAddress *address) {
bool resolved = false;
SDL_LockMutex(resolvermutex);
- if(!resolverresults.empty())
- {
+ if(!resolverresults.empty()) {
resolverresult &rr = resolverresults.pop();
*name = rr.query;
address->host = rr.address.host;
resolved = true;
}
- else loopv(resolverthreads)
- {
+ else loopv(resolverthreads) {
resolverthread &rt = resolverthreads[i];
- if(rt.query && totalmillis - rt.starttime > RESOLVERLIMIT)
- {
+ if(rt.query && totalmillis - rt.starttime > RESOLVERLIMIT) {
resolverstop(rt);
*name = rt.query;
resolved = true;
@@ -142,39 +121,31 @@ bool resolvercheck(const char **name, ENetAddress *address)
return resolved;
}
-bool resolverwait(const char *name, ENetAddress *address)
-{
+bool resolverwait(const char *name, ENetAddress *address) {
if(resolverthreads.empty()) resolverinit();
-
defformatstring(text, "resolving %s... (esc to abort)", name);
renderprogress(0, text);
-
SDL_LockMutex(resolvermutex);
resolverqueries.add(name);
SDL_CondSignal(querycond);
int starttime = SDL_GetTicks(), timeout = 0;
bool resolved = false;
- for(;;)
- {
+ for(;;) {
SDL_CondWaitTimeout(resultcond, resolvermutex, 250);
- loopv(resolverresults) if(resolverresults[i].query == name)
- {
+ loopv(resolverresults) if(resolverresults[i].query == name) {
address->host = resolverresults[i].address.host;
resolverresults.remove(i);
resolved = true;
break;
}
if(resolved) break;
-
timeout = SDL_GetTicks() - starttime;
renderprogress(min(float(timeout)/RESOLVERLIMIT, 1.0f), text);
if(interceptkey(SDLK_ESCAPE)) timeout = RESOLVERLIMIT + 1;
if(timeout > RESOLVERLIMIT) break;
}
- if(!resolved && timeout > RESOLVERLIMIT)
- {
- loopv(resolverthreads)
- {
+ if(!resolved && timeout > RESOLVERLIMIT) {
+ loopv(resolverthreads) {
resolverthread &rt = resolverthreads[i];
if(rt.query == name) { resolverstop(rt); break; }
}
@@ -185,24 +156,19 @@ bool resolverwait(const char *name, ENetAddress *address)
#define CONNLIMIT 20000
-int connectwithtimeout(ENetSocket sock, const char *hostname, const ENetAddress &address)
-{
+int connectwithtimeout(ENetSocket sock, const char *hostname, const ENetAddress &address) {
defformatstring(text, "connecting to %s... (esc to abort)", hostname);
renderprogress(0, text);
-
ENetSocketSet readset, writeset;
- if(!enet_socket_connect(sock, &address)) for(int starttime = SDL_GetTicks(), timeout = 0; timeout <= CONNLIMIT;)
- {
+ if(!enet_socket_connect(sock, &address)) for(int starttime = SDL_GetTicks(), timeout = 0; timeout <= CONNLIMIT;) {
ENET_SOCKETSET_EMPTY(readset);
ENET_SOCKETSET_EMPTY(writeset);
ENET_SOCKETSET_ADD(readset, sock);
ENET_SOCKETSET_ADD(writeset, sock);
int result = enet_socketset_select(sock, &readset, &writeset, 250);
if(result < 0) break;
- else if(result > 0)
- {
- if(ENET_SOCKETSET_CHECK(readset, sock) || ENET_SOCKETSET_CHECK(writeset, sock))
- {
+ else if(result > 0) {
+ if(ENET_SOCKETSET_CHECK(readset, sock) || ENET_SOCKETSET_CHECK(writeset, sock)) {
int error = 0;
if(enet_socket_get_option(sock, ENET_SOCKOPT_ERROR, &error) < 0 || error) break;
return 0;
@@ -212,45 +178,30 @@ int connectwithtimeout(ENetSocket sock, const char *hostname, const ENetAddress
renderprogress(min(float(timeout)/CONNLIMIT, 1.0f), text);
if(interceptkey(SDLK_ESCAPE)) break;
}
-
return -1;
}
-struct pingattempts
-{
+struct pingattempts {
enum { MAXATTEMPTS = 2 };
-
int offset, attempts[MAXATTEMPTS];
-
pingattempts() : offset(0) { clearattempts(); }
-
void clearattempts() { memset(attempts, 0, sizeof(attempts)); }
-
void setoffset() { offset = 1 + rnd(0xFFFFFF); }
-
- int encodeping(int millis)
- {
+ int encodeping(int millis) {
millis += offset;
return millis ? millis : 1;
}
-
- int decodeping(int val)
- {
+ int decodeping(int val) {
return val - offset;
}
-
- int addattempt(int millis)
- {
+ int addattempt(int millis) {
int val = encodeping(millis);
loopk(MAXATTEMPTS-1) attempts[k+1] = attempts[k];
attempts[0] = val;
return val;
}
-
- bool checkattempt(int val, bool del = true)
- {
- if(val) loopk(MAXATTEMPTS) if(attempts[k] == val)
- {
+ bool checkattempt(int val, bool del = true) {
+ if(val) loopk(MAXATTEMPTS) if(attempts[k] == val) {
if(del) attempts[k] = 0;
return true;
}
@@ -261,15 +212,11 @@ struct pingattempts
enum { UNRESOLVED = 0, RESOLVING, RESOLVED };
-struct serverinfo : pingattempts
-{
- enum
- {
+struct serverinfo : pingattempts {
+ enum {
WAITING = INT_MAX,
-
MAXPINGS = 3
};
-
string name, map, sdesc;
int port, numplayers, resolved, ping, lastping, nextping;
int pings[MAXPINGS];
@@ -277,65 +224,47 @@ struct serverinfo : pingattempts
ENetAddress address;
bool keep;
const char *password;
-
serverinfo()
- : port(-1), numplayers(0), resolved(UNRESOLVED), keep(false), password(NULL)
- {
+ : port(-1), numplayers(0), resolved(UNRESOLVED), keep(false), password(NULL) {
name[0] = map[0] = sdesc[0] = '\0';
clearpings();
setoffset();
}
-
- ~serverinfo()
- {
+ ~serverinfo() {
DELETEA(password);
}
-
- void clearpings()
- {
+ void clearpings() {
ping = WAITING;
loopk(MAXPINGS) pings[k] = WAITING;
nextping = 0;
lastping = -1;
clearattempts();
}
-
- void cleanup()
- {
+ void cleanup() {
clearpings();
attr.setsize(0);
numplayers = 0;
}
-
- void reset()
- {
+ void reset() {
lastping = -1;
}
-
- void checkdecay(int decay)
- {
+ void checkdecay(int decay) {
if(lastping >= 0 && totalmillis - lastping >= decay)
cleanup();
if(lastping < 0) lastping = totalmillis;
}
-
- void calcping()
- {
+ void calcping() {
int numpings = 0, totalpings = 0;
loopk(MAXPINGS) if(pings[k] != WAITING) { totalpings += pings[k]; numpings++; }
ping = numpings ? totalpings/numpings : WAITING;
}
-
- void addping(int rtt, int millis)
- {
+ void addping(int rtt, int millis) {
if(millis >= lastping) lastping = -1;
pings[nextping] = rtt;
nextping = (nextping+1)%MAXPINGS;
calcping();
}
-
- static bool compare(serverinfo *a, serverinfo *b)
- {
+ static bool compare(serverinfo *a, serverinfo *b) {
bool ac = (a->attr.length() != 0) && (a->attr[0]==PROTOCOL_VERSION);
bool bc = (b->attr.length() != 0) && (b->attr[0]==PROTOCOL_VERSION);
if(ac > bc) return true;
@@ -358,36 +287,27 @@ vector<serverinfo *> servers;
ENetSocket pingsock = ENET_SOCKET_NULL;
int lastinfo = 0;
-static serverinfo *newserver(const char *name, int port, uint ip = ENET_HOST_ANY)
-{
+static serverinfo *newserver(const char *name, int port, uint ip = ENET_HOST_ANY) {
serverinfo *si = new serverinfo;
si->address.host = ip;
si->address.port = server::serverinfoport(port);
if(ip!=ENET_HOST_ANY) si->resolved = RESOLVED;
-
si->port = port;
if(name) copystring(si->name, name);
- else if(ip==ENET_HOST_ANY || enet_address_get_host_ip(&si->address, si->name, sizeof(si->name)) < 0)
- {
+ else if(ip==ENET_HOST_ANY || enet_address_get_host_ip(&si->address, si->name, sizeof(si->name)) < 0) {
delete si;
return NULL;
-
}
-
servers.add(si);
-
return si;
}
-void addserver(const char *name, int port, const char *password, bool keep)
-{
+void addserver(const char *name, int port, const char *password, bool keep) {
if(port <= 0) port = server::serverport();
- loopv(servers)
- {
+ loopv(servers) {
serverinfo *s = servers[i];
if(strcmp(s->name, name) || s->port != port) continue;
- if(password && (!s->password || strcmp(s->password, password)))
- {
+ if(password && (!s->password || strcmp(s->password, password))) {
DELETEA(s->password);
s->password = newstring(password);
}
@@ -407,47 +327,37 @@ VARP(maxservpings, 0, 10, 1000);
pingattempts lanpings;
-template<size_t N> static inline void buildping(ENetBuffer &buf, uchar (&ping)[N], pingattempts &a)
-{
+template<size_t N> static inline void buildping(ENetBuffer &buf, uchar (&ping)[N], pingattempts &a) {
ucharbuf p(ping, N);
putint(p, a.addattempt(totalmillis));
buf.data = ping;
buf.dataLength = p.length();
}
-void pingservers()
-{
- if(pingsock == ENET_SOCKET_NULL)
- {
+void pingservers() {
+ if(pingsock == ENET_SOCKET_NULL) {
pingsock = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
- if(pingsock == ENET_SOCKET_NULL)
- {
+ if(pingsock == ENET_SOCKET_NULL) {
lastinfo = totalmillis;
return;
}
enet_socket_set_option(pingsock, ENET_SOCKOPT_NONBLOCK, 1);
enet_socket_set_option(pingsock, ENET_SOCKOPT_BROADCAST, 1);
-
lanpings.setoffset();
}
-
ENetBuffer buf;
uchar ping[MAXTRANS];
-
static int lastping = 0;
if(lastping >= servers.length()) lastping = 0;
- loopi(maxservpings ? min(servers.length(), maxservpings) : servers.length())
- {
+ loopi(maxservpings ? min(servers.length(), maxservpings) : servers.length()) {
serverinfo &si = *servers[lastping];
if(++lastping >= servers.length()) lastping = 0;
if(si.address.host == ENET_HOST_ANY) continue;
buildping(buf, ping, si);
enet_socket_send(pingsock, &si.address, &buf, 1);
-
si.checkdecay(servpingdecay);
}
- if(searchlan)
- {
+ if(searchlan) {
ENetAddress address;
address.host = ENET_HOST_BROADCAST;
address.port = server::laninfoport();
@@ -457,31 +367,24 @@ void pingservers()
lastinfo = totalmillis;
}
-void checkresolver()
-{
+void checkresolver() {
int resolving = 0;
- loopv(servers)
- {
+ loopv(servers) {
serverinfo &si = *servers[i];
if(si.resolved == RESOLVED) continue;
- if(si.address.host == ENET_HOST_ANY)
- {
+ if(si.address.host == ENET_HOST_ANY) {
if(si.resolved == UNRESOLVED) { si.resolved = RESOLVING; resolverquery(si.name); }
resolving++;
}
}
if(!resolving) return;
-
const char *name = NULL;
- for(;;)
- {
+ for(;;) {
ENetAddress addr = { ENET_HOST_ANY, ENET_PORT_ANY };
if(!resolvercheck(&name, &addr)) break;
- loopv(servers)
- {
+ loopv(servers) {
serverinfo &si = *servers[i];
- if(name == si.name)
- {
+ if(name == si.name) {
si.resolved = RESOLVED;
si.address.host = addr.host;
break;
@@ -492,8 +395,7 @@ void checkresolver()
static int lastreset = 0;
-void checkpings()
-{
+void checkpings() {
if(pingsock==ENET_SOCKET_NULL) return;
enet_uint32 events = ENET_SOCKET_WAIT_RECEIVE;
ENetBuffer buf;
@@ -502,22 +404,19 @@ void checkpings()
char text[MAXTRANS];
buf.data = ping;
buf.dataLength = sizeof(ping);
- while(enet_socket_wait(pingsock, &events, 0) >= 0 && events)
- {
+ while(enet_socket_wait(pingsock, &events, 0) >= 0 && events) {
int len = enet_socket_receive(pingsock, &addr, &buf, 1);
if(len <= 0) return;
ucharbuf p(ping, len);
int millis = getint(p);
serverinfo *si = NULL;
loopv(servers) if(addr.host == servers[i]->address.host && addr.port == servers[i]->address.port) { si = servers[i]; break; }
- if(si)
- {
+ if(si) {
if(!si->checkattempt(millis)) continue;
millis = si->decodeping(millis);
}
else if(!searchlan || !lanpings.checkattempt(millis, false)) continue;
- else
- {
+ else {
si = newserver(NULL, server::serverport(addr.port), addr.host);
millis = lanpings.decodeping(millis);
}
@@ -534,8 +433,7 @@ void checkpings()
}
}
-void sortservers()
-{
+void sortservers() {
servers.sort(serverinfo::compare);
}
COMMAND(sortservers, "");
@@ -543,17 +441,14 @@ COMMAND(sortservers, "");
VARP(autosortservers, 0, 1, 1);
VARP(autoupdateservers, 0, 1, 1);
-void refreshservers()
-{
+void refreshservers() {
static int lastrefresh = 0;
if(lastrefresh==totalmillis) return;
- if(totalmillis - lastrefresh > 1000)
- {
+ if(totalmillis - lastrefresh > 1000) {
loopv(servers) servers[i]->reset();
lastreset = totalmillis;
}
lastrefresh = totalmillis;
-
checkresolver();
checkpings();
if(totalmillis - lastinfo >= servpingrate/(maxservpings ? max(1, (servers.length() + maxservpings - 1) / maxservpings) : 1)) pingservers();
@@ -562,26 +457,21 @@ void refreshservers()
serverinfo *selectedserver = NULL;
-const char *showservers(g3d_gui *cgui, uint *header, int pagemin, int pagemax)
-{
+const char *showservers(g3d_gui *cgui, uint *header, int pagemin, int pagemax) {
refreshservers();
- if(servers.empty())
- {
+ if(servers.empty()) {
if(header) execute(header);
return NULL;
}
serverinfo *sc = NULL;
- for(int start = 0; start < servers.length();)
- {
+ for(int start = 0; start < servers.length();) {
if(start > 0) cgui->tab();
if(header) execute(header);
int end = servers.length();
cgui->pushlist();
- loopi(10)
- {
+ loopi(10) {
if(!game::serverinfostartcolumn(cgui, i)) break;
- for(int j = start; j < end; j++)
- {
+ for(int j = start; j < end; j++) {
if(!i && j+1 - start >= pagemin && (j+1 - start >= pagemax || cgui->shouldtab())) { end = j; break; }
serverinfo &si = *servers[j];
const char *sdesc = si.sdesc;
@@ -600,8 +490,7 @@ const char *showservers(g3d_gui *cgui, uint *header, int pagemin, int pagemax)
return "connectselected";
}
-void connectselected()
-{
+void connectselected() {
if(!selectedserver) return;
connectserv(selectedserver->name, selectedserver->port, selectedserver->password);
selectedserver = NULL;
@@ -609,8 +498,7 @@ void connectselected()
COMMAND(connectselected, "");
-void clearservers(bool full = false)
-{
+void clearservers(bool full = false) {
resolverclear();
if(full) servers.deletecontents();
else loopvrev(servers) if(!servers[i]->keep) delete servers.remove(i);
@@ -619,24 +507,19 @@ void clearservers(bool full = false)
#define RETRIEVELIMIT 20000
-void retrieveservers(vector<char> &data)
-{
+void retrieveservers(vector<char> &data) {
ENetSocket sock = connectmaster(true);
if(sock == ENET_SOCKET_NULL) return;
-
extern char *mastername;
defformatstring(text, "retrieving servers from %s... (esc to abort)", mastername);
renderprogress(0, text);
-
int starttime = SDL_GetTicks(), timeout = 0;
const char *req = "list\n";
int reqlen = strlen(req);
ENetBuffer buf;
- while(reqlen > 0)
- {
+ while(reqlen > 0) {
enet_uint32 events = ENET_SOCKET_WAIT_SEND;
- if(enet_socket_wait(sock, &events, 250) >= 0 && events)
- {
+ if(enet_socket_wait(sock, &events, 250) >= 0 && events) {
buf.data = (void *)req;
buf.dataLength = reqlen;
int sent = enet_socket_send(sock, NULL, &buf, 1);
@@ -650,12 +533,9 @@ void retrieveservers(vector<char> &data)
if(interceptkey(SDLK_ESCAPE)) timeout = RETRIEVELIMIT + 1;
if(timeout > RETRIEVELIMIT) break;
}
-
- if(reqlen <= 0) for(;;)
- {
+ if(reqlen <= 0) for(;;) {
enet_uint32 events = ENET_SOCKET_WAIT_RECEIVE;
- if(enet_socket_wait(sock, &events, 250) >= 0 && events)
- {
+ if(enet_socket_wait(sock, &events, 250) >= 0 && events) {
if(data.length() >= data.capacity()) data.reserve(4096);
buf.data = data.getbuf() + data.length();
buf.dataLength = data.capacity() - data.length();
@@ -668,39 +548,31 @@ void retrieveservers(vector<char> &data)
if(interceptkey(SDLK_ESCAPE)) timeout = RETRIEVELIMIT + 1;
if(timeout > RETRIEVELIMIT) break;
}
-
if(data.length()) data.add('\0');
enet_socket_destroy(sock);
}
bool updatedservers = false;
-void updatefrommaster()
-{
+void updatefrommaster() {
vector<char> data;
retrieveservers(data);
if(data.empty()) conoutf(CON_ERROR, "master server not replying");
- else
- {
+ else {
clearservers();
char *line = data.getbuf();
- while(char *end = (char *)memchr(line, '\n', data.length() - (line - data.getbuf())))
- {
+ while(char *end = (char *)memchr(line, '\n', data.length() - (line - data.getbuf()))) {
*end = '\0';
-
const char *args = line;
while(args < end && !iscubespace(*args)) args++;
int cmdlen = args - line;
while(args < end && iscubespace(*args)) args++;
-
- if(matchstring(line, cmdlen, "addserver"))
- {
+ if(matchstring(line, cmdlen, "addserver")) {
string ip;
int port;
if(sscanf(args, "%100s %d", ip, &port) == 2) addserver(ip, port);
}
else if(matchstring(line, cmdlen, "echo")) conoutf("\f1%s", args);
-
line = end + 1;
}
}
@@ -708,8 +580,7 @@ void updatefrommaster()
updatedservers = true;
}
-void initservers()
-{
+void initservers() {
selectedserver = NULL;
if(autoupdateservers && !updatedservers) updatefrommaster();
}
@@ -720,17 +591,14 @@ ICOMMAND(clearservers, "i", (int *full), clearservers(*full!=0));
COMMAND(updatefrommaster, "");
COMMAND(initservers, "");
-void writeservercfg()
-{
+void writeservercfg() {
if(!game::savedservers()) return;
stream *f = openutf8file(path(game::savedservers(), true), "w");
if(!f) return;
int kept = 0;
- loopv(servers)
- {
+ loopv(servers) {
serverinfo *s = servers[i];
- if(s->keep)
- {
+ if(s->keep) {
if(!kept) f->printf("// servers that should never be cleared from the server list\n\n");
if(s->password) f->printf("keepserver %s %d %s\n", escapeid(s->name), s->port, escapestring(s->password));
else f->printf("keepserver %s %d\n", escapeid(s->name), s->port);
@@ -739,11 +607,9 @@ void writeservercfg()
}
if(kept) f->printf("\n");
f->printf("// servers connected to are added here automatically\n\n");
- loopv(servers)
- {
+ loopv(servers) {
serverinfo *s = servers[i];
- if(!s->keep)
- {
+ if(!s->keep) {
if(s->password) f->printf("addserver %s %d %s\n", escapeid(s->name), s->port, escapestring(s->password));
else f->printf("addserver %s %d\n", escapeid(s->name), s->port);
}
diff --git a/src/engine/shader.cpp b/src/engine/shader.cpp
index 67b9e42..8f5e9b7 100644
--- a/src/engine/shader.cpp
+++ b/src/engine/shader.cpp
@@ -18,41 +18,32 @@ VAR(maxvsuniforms, 1, 0, 0);
VAR(maxfsuniforms, 1, 0, 0);
VAR(maxvaryings, 1, 0, 0);
-void loadshaders()
-{
+void loadshaders() {
standardshaders = true;
execfile("data/glsl.cfg");
standardshaders = false;
-
nullshader = lookupshaderbyname("null");
hudshader = lookupshaderbyname("hud");
hudnotextureshader = lookupshaderbyname("hudnotexture");
stdworldshader = lookupshaderbyname("stdworld");
if(!nullshader || !hudshader || !hudnotextureshader || !stdworldshader) fatal("cannot find shader definitions");
-
dummyslot.shader = stdworldshader;
-
textureshader = lookupshaderbyname("texture");
notextureshader = lookupshaderbyname("notexture");
nocolorshader = lookupshaderbyname("nocolor");
-
nullshader->set();
-
loadedshaders = true;
}
-Shader *lookupshaderbyname(const char *name)
-{
+Shader *lookupshaderbyname(const char *name) {
Shader *s = shaders.access(name);
return s && s->loaded() ? s : NULL;
}
-Shader *generateshader(const char *name, const char *fmt, ...)
-{
+Shader *generateshader(const char *name, const char *fmt, ...) {
if(!loadedshaders) return NULL;
Shader *s = name ? lookupshaderbyname(name) : NULL;
- if(!s)
- {
+ if(!s) {
defvformatstring(cmd, fmt, fmt);
bool wasstandard = standardshaders;
standardshaders = true;
@@ -64,29 +55,24 @@ Shader *generateshader(const char *name, const char *fmt, ...)
return s;
}
-static void showglslinfo(GLenum type, GLuint obj, const char *name, const char **parts = NULL, int numparts = 0)
-{
+static void showglslinfo(GLenum type, GLuint obj, const char *name, const char **parts = NULL, int numparts = 0) {
GLint length = 0;
if(type) glGetShaderiv_(obj, GL_INFO_LOG_LENGTH, &length);
else glGetProgramiv_(obj, GL_INFO_LOG_LENGTH, &length);
- if(length > 1)
- {
+ if(length > 1) {
conoutf(CON_ERROR, "GLSL ERROR (%s:%s)", type == GL_VERTEX_SHADER ? "VS" : (type == GL_FRAGMENT_SHADER ? "FS" : "PROG"), name);
FILE *l = getlogfile();
- if(l)
- {
+ if(l) {
GLchar *log = new GLchar[length];
if(type) glGetShaderInfoLog_(obj, length, &length, log);
else glGetProgramInfoLog_(obj, length, &length, log);
fprintf(l, "%s\n", log);
bool partlines = log[0] != '0';
int line = 0;
- loopi(numparts)
- {
+ loopi(numparts) {
const char *part = parts[i];
int startline = line;
- while(*part)
- {
+ while(*part) {
const char *next = strchr(part, '\n');
if(++line > 1000) goto done;
if(partlines) fprintf(l, "%d(%d): ", i, line - startline); else fprintf(l, "%d: ", line);
@@ -101,30 +87,26 @@ static void showglslinfo(GLenum type, GLuint obj, const char *name, const char *
}
}
-static void compileglslshader(GLenum type, GLuint &obj, const char *def, const char *name, bool msg = true)
-{
+static void compileglslshader(GLenum type, GLuint &obj, const char *def, const char *name, bool msg = true) {
const char *source = def + strspn(def, " \t\r\n");
const char *parts[16];
int numparts = 0;
- static const struct { int version; const char * const header; } glslversions[] =
- {
- { 330, "#version 330\n" },
- { 150, "#version 150\n" },
- { 130, "#version 130\n" },
- { 120, "#version 120\n" }
+ static const struct { int version; const char * const header; } glslversions[] = {
+ {
+ 330, "#version 330\n" }, {
+ 150, "#version 150\n" }, {
+ 130, "#version 130\n" }, {
+ 120, "#version 120\n" }
};
- loopi(sizeof(glslversions)/sizeof(glslversions[0])) if(glslversion >= glslversions[i].version)
- {
+ loopi(sizeof(glslversions)/sizeof(glslversions[0])) if(glslversion >= glslversions[i].version) {
parts[numparts++] = glslversions[i].header;
break;
}
- if(glslversion >= 130)
- {
+ if(glslversion >= 130) {
if(type == GL_VERTEX_SHADER) parts[numparts++] =
"#define attribute in\n"
"#define varying out\n";
- else if(type == GL_FRAGMENT_SHADER)
- {
+ else if(type == GL_FRAGMENT_SHADER) {
parts[numparts++] = "#define varying in\n";
if(glslversion < 150) parts[numparts++] = "precision highp float;\n";
if(glversion >= 300) parts[numparts++] =
@@ -137,35 +119,30 @@ static void compileglslshader(GLenum type, GLuint &obj, const char *def, const c
"#define textureCube(sampler, coords) texture(sampler, coords)\n";
}
parts[numparts++] = source;
-
obj = glCreateShader_(type);
glShaderSource_(obj, numparts, (const GLchar **)parts, NULL);
glCompileShader_(obj);
GLint success;
glGetShaderiv_(obj, GL_COMPILE_STATUS, &success);
- if(!success)
- {
+ if(!success) {
if(msg) showglslinfo(type, obj, name, parts, numparts);
glDeleteShader_(obj);
obj = 0;
}
}
-static void bindglsluniform(Shader &s, UniformLoc &u)
-{
+static void bindglsluniform(Shader &s, UniformLoc &u) {
u.loc = glGetUniformLocation_(s.program, u.name);
if(!u.blockname || !hasUBO) return;
GLuint bidx = glGetUniformBlockIndex_(s.program, u.blockname);
GLuint uidx = GL_INVALID_INDEX;
glGetUniformIndices_(s.program, 1, &u.name, &uidx);
- if(bidx != GL_INVALID_INDEX && uidx != GL_INVALID_INDEX)
- {
+ if(bidx != GL_INVALID_INDEX && uidx != GL_INVALID_INDEX) {
GLint sizeval = 0, offsetval = 0, strideval = 0;
glGetActiveUniformBlockiv_(s.program, bidx, GL_UNIFORM_BLOCK_DATA_SIZE, &sizeval);
if(sizeval <= 0) return;
glGetActiveUniformsiv_(s.program, 1, &uidx, GL_UNIFORM_OFFSET, &offsetval);
- if(u.stride > 0)
- {
+ if(u.stride > 0) {
glGetActiveUniformsiv_(s.program, 1, &uidx, GL_UNIFORM_ARRAY_STRIDE, &strideval);
if(strideval > u.stride) return;
}
@@ -175,69 +152,57 @@ static void bindglsluniform(Shader &s, UniformLoc &u)
}
}
-static void linkglslprogram(Shader &s, bool msg = true)
-{
+static void linkglslprogram(Shader &s, bool msg = true) {
s.program = s.vsobj && s.psobj ? glCreateProgram_() : 0;
GLint success = 0;
- if(s.program)
- {
+ if(s.program) {
glAttachShader_(s.program, s.vsobj);
glAttachShader_(s.program, s.psobj);
uint attribs = 0;
- loopv(s.attriblocs)
- {
+ loopv(s.attriblocs) {
AttribLoc &a = s.attriblocs[i];
glBindAttribLocation_(s.program, a.loc, a.name);
attribs |= 1<<a.loc;
}
loopi(gle::MAXATTRIBS) if(!(attribs&(1<<i))) glBindAttribLocation_(s.program, i, gle::attribnames[i]);
- if(glversion >= 300)
- {
+ if(glversion >= 300) {
glBindFragDataLocation_(s.program, 0, "cube2_FragColor");
}
glLinkProgram_(s.program);
glGetProgramiv_(s.program, GL_LINK_STATUS, &success);
}
- if(success)
- {
+ if(success) {
glUseProgram_(s.program);
- loopi(8)
- {
+ loopi(8) {
static const char * const texnames[8] = { "tex0", "tex1", "tex2", "tex3", "tex4", "tex5", "tex6", "tex7" };
GLint loc = glGetUniformLocation_(s.program, texnames[i]);
if(loc != -1) glUniform1i_(loc, i);
}
- loopv(s.defaultparams)
- {
+ loopv(s.defaultparams) {
SlotShaderParamState &param = s.defaultparams[i];
param.loc = glGetUniformLocation_(s.program, param.name);
}
loopv(s.uniformlocs) bindglsluniform(s, s.uniformlocs[i]);
glUseProgram_(0);
}
- else if(s.program)
- {
+ else if(s.program) {
if(msg) showglslinfo(GL_FALSE, s.program, s.name);
glDeleteProgram_(s.program);
s.program = 0;
}
}
-int getlocalparam(const char *name)
-{
+int getlocalparam(const char *name) {
return localparams.access(name, int(localparams.numelems));
}
-static int addlocalparam(Shader &s, const char *name, int loc, int size, GLenum format)
-{
+static int addlocalparam(Shader &s, const char *name, int loc, int size, GLenum format) {
int idx = getlocalparam(name);
- if(idx >= s.localparamremap.length())
- {
+ if(idx >= s.localparamremap.length()) {
int n = idx + 1 - s.localparamremap.length();
memset(s.localparamremap.pad(n), 0xFF, n);
}
s.localparamremap[idx] = s.localparams.length();
-
LocalShaderParamState &l = s.localparams.add();
l.name = name;
l.loc = loc;
@@ -246,11 +211,9 @@ static int addlocalparam(Shader &s, const char *name, int loc, int size, GLenum
return idx;
}
-GlobalShaderParamState *getglobalparam(const char *name)
-{
+GlobalShaderParamState *getglobalparam(const char *name) {
GlobalShaderParamState *param = globalparams.access(name);
- if(!param)
- {
+ if(!param) {
param = &globalparams[name];
param->name = name;
memset(param->buf, -1, sizeof(param->buf));
@@ -259,8 +222,7 @@ GlobalShaderParamState *getglobalparam(const char *name)
return param;
}
-static GlobalShaderParamUse *addglobalparam(Shader &s, GlobalShaderParamState *param, int loc, int size, GLenum format)
-{
+static GlobalShaderParamUse *addglobalparam(Shader &s, GlobalShaderParamState *param, int loc, int size, GLenum format) {
GlobalShaderParamUse &g = s.globalparams.add();
g.param = param;
g.version = -2;
@@ -270,10 +232,8 @@ static GlobalShaderParamUse *addglobalparam(Shader &s, GlobalShaderParamState *p
return &g;
}
-static void setglsluniformformat(Shader &s, const char *name, GLenum format, int size)
-{
- switch(format)
- {
+static void setglsluniformformat(Shader &s, const char *name, GLenum format, int size) {
+ switch(format) {
case GL_FLOAT:
case GL_FLOAT_VEC2:
case GL_FLOAT_VEC3:
@@ -294,31 +254,26 @@ static void setglsluniformformat(Shader &s, const char *name, GLenum format, int
return;
}
if(!strncmp(name, "gl_", 3)) return;
-
int loc = glGetUniformLocation_(s.program, name);
if(loc < 0) return;
- loopvj(s.defaultparams) if(s.defaultparams[j].loc == loc)
- {
+ loopvj(s.defaultparams) if(s.defaultparams[j].loc == loc) {
s.defaultparams[j].format = format;
return;
}
loopvj(s.uniformlocs) if(s.uniformlocs[j].loc == loc) return;
loopvj(s.globalparams) if(s.globalparams[j].loc == loc) return;
loopvj(s.localparams) if(s.localparams[j].loc == loc) return;
-
name = getshaderparamname(name);
GlobalShaderParamState *param = globalparams.access(name);
if(param) addglobalparam(s, param, loc, size, format);
else addlocalparam(s, name, loc, size, format);
}
-static void allocglslactiveuniforms(Shader &s)
-{
+static void allocglslactiveuniforms(Shader &s) {
GLint numactive = 0;
glGetProgramiv_(s.program, GL_ACTIVE_UNIFORMS, &numactive);
string name;
- loopi(numactive)
- {
+ loopi(numactive) {
GLsizei namelen = 0;
GLint size = 0;
GLenum format = GL_FLOAT_VEC4;
@@ -332,19 +287,16 @@ static void allocglslactiveuniforms(Shader &s)
}
}
-void Shader::allocparams(Slot *slot)
-{
- if(slot)
- {
-#define UNIFORMTEX(name, tmu) \
- { \
+void Shader::allocparams(Slot *slot) {
+ if(slot) {
+#define UNIFORMTEX(name, tmu) { \
+ \
loc = glGetUniformLocation_(program, name); \
int val = tmu; \
if(loc != -1) glUniform1i_(loc, val); \
}
int loc, tmu = 2;
- if(type & SHADER_NORMALSLMS)
- {
+ if(type & SHADER_NORMALSLMS) {
UNIFORMTEX("lmcolor", 1);
UNIFORMTEX("lmdir", 2);
tmu++;
@@ -352,19 +304,16 @@ void Shader::allocparams(Slot *slot)
else UNIFORMTEX("lightmap", 1);
UNIFORMTEX("shadowmap", 7);
int stex = 0;
- loopv(slot->sts)
- {
+ loopv(slot->sts) {
Slot::Tex &t = slot->sts[i];
- switch(t.type)
- {
+ switch(t.type) {
case TEX_DIFFUSE: UNIFORMTEX("diffusemap", 0); break;
case TEX_NORMAL: UNIFORMTEX("normalmap", tmu++); break;
case TEX_DECAL: UNIFORMTEX("decal", tmu++); break;
case TEX_SPEC: if(t.combined<0) UNIFORMTEX("specmap", tmu++); break;
case TEX_DEPTH: if(t.combined<0) UNIFORMTEX("depthmap", tmu++); break;
case TEX_ALPHA: if(t.combined<0) UNIFORMTEX("alphamap", tmu++); break;
- case TEX_UNKNOWN:
- {
+ case TEX_UNKNOWN: {
defformatstring(sname, "stex%d", stex++);
UNIFORMTEX(sname, tmu++);
break;
@@ -377,32 +326,25 @@ void Shader::allocparams(Slot *slot)
int GlobalShaderParamState::nextversion = 0;
-void GlobalShaderParamState::resetversions()
-{
- enumerate(shaders, Shader, s,
- {
- loopv(s.globalparams)
- {
+void GlobalShaderParamState::resetversions() {
+ enumerate(shaders, Shader, s, {
+ loopv(s.globalparams) {
GlobalShaderParamUse &u = s.globalparams[i];
if(u.version != u.param->version) u.version = -2;
}
});
nextversion = 0;
enumerate(globalparams, GlobalShaderParamState, g, { g.version = ++nextversion; });
- enumerate(shaders, Shader, s,
- {
- loopv(s.globalparams)
- {
+ enumerate(shaders, Shader, s, {
+ loopv(s.globalparams) {
GlobalShaderParamUse &u = s.globalparams[i];
if(u.version >= 0) u.version = u.param->version;
}
});
}
-static inline void setslotparam(SlotShaderParamState &l, const float *val)
-{
- switch(l.format)
- {
+static inline void setslotparam(SlotShaderParamState &l, const float *val) {
+ switch(l.format) {
case GL_BOOL:
case GL_FLOAT: glUniform1fv_(l.loc, 1, val); break;
case GL_BOOL_VEC2:
@@ -426,52 +368,46 @@ static inline void setslotparam(SlotShaderParamState &l, const float *val)
} while(0)
#define SETSLOTPARAMS(slotparams) \
- loopv(slotparams) \
- { \
+ loopv(slotparams) { \
+ \
SlotShaderParam &p = slotparams[i]; \
if(!defaultparams.inrange(p.loc)) continue; \
SlotShaderParamState &l = defaultparams[p.loc]; \
SETSLOTPARAM(l, unimask, p.loc, p.val); \
}
#define SETDEFAULTPARAMS \
- loopv(defaultparams) \
- { \
+ loopv(defaultparams) { \
+ \
SlotShaderParamState &l = defaultparams[i]; \
SETSLOTPARAM(l, unimask, i, l.val); \
}
-void Shader::setslotparams(Slot &slot)
-{
+void Shader::setslotparams(Slot &slot) {
uint unimask = 0;
SETSLOTPARAMS(slot.params)
SETDEFAULTPARAMS
}
-void Shader::setslotparams(Slot &slot, VSlot &vslot)
-{
+void Shader::setslotparams(Slot &slot, VSlot &vslot) {
uint unimask = 0;
- if(vslot.slot == &slot)
- {
+ if(vslot.slot == &slot) {
SETSLOTPARAMS(vslot.params)
SETSLOTPARAMS(slot.params)
SETDEFAULTPARAMS
}
- else
- {
+ else {
SETSLOTPARAMS(slot.params)
SETDEFAULTPARAMS
}
}
-void Shader::bindprograms()
-{
+void Shader::bindprograms() {
if(this == lastshader || type&(SHADER_DEFERRED|SHADER_INVALID)) return;
glUseProgram_(program);
lastshader = this;
}
-bool Shader::compile()
-{
+bool Shader::compile() {
if(!vsstr) vsobj = !reusevs || reusevs->invalid() ? 0 : reusevs->vsobj;
else compileglslshader(GL_VERTEX_SHADER, vsobj, vsstr, name, !variantshader);
if(!psstr) psobj = !reuseps || reuseps->invalid() ? 0 : reuseps->psobj;
@@ -480,8 +416,7 @@ bool Shader::compile()
return program!=0;
}
-void Shader::cleanup(bool invalid)
-{
+void Shader::cleanup(bool invalid) {
detailshader = NULL;
used = false;
if(vsobj) { if(!reusevs) glDeleteShader_(vsobj); vsobj = 0; }
@@ -490,8 +425,7 @@ void Shader::cleanup(bool invalid)
localparams.setsize(0);
localparamremap.setsize(0);
globalparams.setsize(0);
- if(standard || invalid)
- {
+ if(standard || invalid) {
type = SHADER_INVALID;
DELETEA(vsstr);
DELETEA(psstr);
@@ -511,28 +445,24 @@ void Shader::cleanup(bool invalid)
bool Shader::isnull(const Shader *s) { return !s; }
-static void genattriblocs(Shader &s, const char *vs, const char *ps, Shader *reusevs, Shader *reuseps)
-{
+static void genattriblocs(Shader &s, const char *vs, const char *ps, Shader *reusevs, Shader *reuseps) {
static int len = strlen("//:attrib");
string name;
int loc;
if(reusevs) s.attriblocs = reusevs->attriblocs;
- else while((vs = strstr(vs, "//:attrib")))
- {
+ else while((vs = strstr(vs, "//:attrib"))) {
if(sscanf(vs, "//:attrib %100s %d", name, &loc) == 2)
s.attriblocs.add(AttribLoc(getshaderparamname(name), loc));
vs += len;
}
}
-static void genuniformlocs(Shader &s, const char *vs, const char *ps, Shader *reusevs, Shader *reuseps)
-{
+static void genuniformlocs(Shader &s, const char *vs, const char *ps, Shader *reusevs, Shader *reuseps) {
static int len = strlen("//:uniform");
string name, blockname;
int binding, stride;
if(reusevs) s.uniformlocs = reusevs->uniformlocs;
- else while((vs = strstr(vs, "//:uniform")))
- {
+ else while((vs = strstr(vs, "//:uniform"))) {
int numargs = sscanf(vs, "//:uniform %100s %100s %d %d", name, blockname, &binding, &stride);
if(numargs >= 3) s.uniformlocs.add(UniformLoc(getshaderparamname(name), getshaderparamname(blockname), binding, numargs >= 4 ? stride : 0));
else if(numargs >= 1) s.uniformlocs.add(UniformLoc(getshaderparamname(name)));
@@ -540,14 +470,11 @@ static void genuniformlocs(Shader &s, const char *vs, const char *ps, Shader *re
}
}
-Shader *newshader(int type, const char *name, const char *vs, const char *ps, Shader *variant = NULL, int row = 0)
-{
- if(Shader::lastshader)
- {
+Shader *newshader(int type, const char *name, const char *vs, const char *ps, Shader *variant = NULL, int row = 0) {
+ if(Shader::lastshader) {
glUseProgram_(0);
Shader::lastshader = NULL;
}
-
Shader *exists = shaders.access(name);
char *rname = exists ? exists->name : newstring(name);
Shader &s = shaders[rname];
@@ -560,17 +487,14 @@ Shader *newshader(int type, const char *name, const char *vs, const char *ps, Sh
s.standard = standardshaders;
if(forceshaders) s.forced = true;
s.reusevs = s.reuseps = NULL;
- if(variant)
- {
+ if(variant) {
int row = 0, col = 0;
- if(!vs[0] || sscanf(vs, "%d , %d", &row, &col) >= 1)
- {
+ if(!vs[0] || sscanf(vs, "%d , %d", &row, &col) >= 1) {
DELETEA(s.vsstr);
s.reusevs = !vs[0] ? variant : variant->getvariant(col, row);
}
row = col = 0;
- if(!ps[0] || sscanf(ps, "%d , %d", &row, &col) >= 1)
- {
+ if(!ps[0] || sscanf(ps, "%d , %d", &row, &col) >= 1) {
DELETEA(s.psstr);
s.reuseps = !ps[0] ? variant : variant->getvariant(col, row);
}
@@ -581,8 +505,7 @@ Shader *newshader(int type, const char *name, const char *vs, const char *ps, Sh
s.uniformlocs.setsize(0);
genattriblocs(s, vs, ps, s.reusevs, s.reuseps);
genuniformlocs(s, vs, ps, s.reusevs, s.reuseps);
- if(!s.compile())
- {
+ if(!s.compile()) {
s.cleanup(true);
if(variant) shaders.remove(rname);
return NULL;
@@ -592,19 +515,16 @@ Shader *newshader(int type, const char *name, const char *vs, const char *ps, Sh
return &s;
}
-void setupshaders()
-{
+void setupshaders() {
GLint val;
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &val);
maxvsuniforms = val/4;
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &val);
maxfsuniforms = val/4;
- if(glversion < 300)
- {
+ if(glversion < 300) {
glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &val);
maxvaryings = val;
}
-
standardshaders = true;
nullshader = newshader(0, "<init>null",
"attribute vec4 vvertex;\n"
@@ -644,38 +564,31 @@ void setupshaders()
" gl_FragColor = color;\n"
"}\n");
standardshaders = false;
-
if(!nullshader || !hudshader || !hudnotextureshader) fatal("failed to setup shaders");
-
dummyslot.shader = nullshader;
}
-static const char *findglslmain(const char *s)
-{
+static const char *findglslmain(const char *s) {
const char *main = strstr(s, "main");
if(!main) return NULL;
for(; main >= s; main--) switch(*main) { case '\r': case '\n': case ';': return main + 1; }
return s;
}
-static void gengenericvariant(Shader &s, const char *sname, const char *vs, const char *ps, int row = 0)
-{
+static void gengenericvariant(Shader &s, const char *sname, const char *vs, const char *ps, int row = 0) {
int rowoffset = 0;
bool vschanged = false, pschanged = false;
vector<char> vsv, psv;
vsv.put(vs, strlen(vs)+1);
psv.put(ps, strlen(ps)+1);
-
static const int len = strlen("//:variant"), olen = strlen("override");
- for(char *vspragma = vsv.getbuf();; vschanged = true)
- {
+ for(char *vspragma = vsv.getbuf();; vschanged = true) {
vspragma = strstr(vspragma, "//:variant");
if(!vspragma) break;
if(sscanf(vspragma + len, "row %d", &rowoffset) == 1) continue;
memset(vspragma, ' ', len);
vspragma += len;
- if(!strncmp(vspragma, "override", olen))
- {
+ if(!strncmp(vspragma, "override", olen)) {
memset(vspragma, ' ', olen);
vspragma += olen;
char *end = vspragma + strcspn(vspragma, "\n\r");
@@ -684,15 +597,13 @@ static void gengenericvariant(Shader &s, const char *sname, const char *vs, cons
memset(end, ' ', endlen);
}
}
- for(char *pspragma = psv.getbuf();; pschanged = true)
- {
+ for(char *pspragma = psv.getbuf();; pschanged = true) {
pspragma = strstr(pspragma, "//:variant");
if(!pspragma) break;
if(sscanf(pspragma + len, "row %d", &rowoffset) == 1) continue;
memset(pspragma, ' ', len);
pspragma += len;
- if(!strncmp(pspragma, "override", olen))
- {
+ if(!strncmp(pspragma, "override", olen)) {
memset(pspragma, ' ', olen);
pspragma += olen;
char *end = pspragma + strcspn(pspragma, "\n\r");
@@ -713,52 +624,38 @@ static void gengenericvariant(Shader &s, const char *sname, const char *vs, cons
bool minimizedynlighttcusage() { return glversion < 300 && maxvaryings < 48; }
-static void gendynlightvariant(Shader &s, const char *sname, const char *vs, const char *ps, int row = 0)
-{
+static void gendynlightvariant(Shader &s, const char *sname, const char *vs, const char *ps, int row = 0) {
int numlights = minimizedynlighttcusage() ? 1 : MAXDYNLIGHTS;
-
const char *vspragma = strstr(vs, "//:dynlight"), *pspragma = strstr(ps, "//:dynlight");
if(!vspragma || !pspragma) return;
-
string pslight;
vspragma += strcspn(vspragma, "\n");
if(*vspragma) vspragma++;
-
if(sscanf(pspragma, "//:dynlight %100s", pslight)!=1) return;
-
pspragma += strcspn(pspragma, "\n");
if(*pspragma) pspragma++;
-
const char *vsmain = findglslmain(vs), *psmain = findglslmain(ps);
if(vsmain > vspragma) vsmain = vs;
if(psmain > pspragma) psmain = ps;
-
vector<char> vsdl, psdl;
- loopi(MAXDYNLIGHTS)
- {
+ loopi(MAXDYNLIGHTS) {
vsdl.setsize(0);
psdl.setsize(0);
if(vsmain >= vs) vsdl.put(vs, vsmain - vs);
if(psmain >= ps) psdl.put(ps, psmain - ps);
-
defformatstring(pos, "uniform vec4 dynlightpos[%d];\n", i+1);
vsdl.put(pos, strlen(pos));
psdl.put(pos, strlen(pos));
defformatstring(color, "uniform vec3 dynlightcolor[%d];\n", i+1);
psdl.put(color, strlen(color));
-
- loopk(min(i+1, numlights))
- {
+ loopk(min(i+1, numlights)) {
defformatstring(dir, "%sdynlight%ddir%s", !k ? "varying vec3 " : " ", k, k==i || k+1==numlights ? ";\n" : ",");
vsdl.put(dir, strlen(dir));
psdl.put(dir, strlen(dir));
}
-
vsdl.put(vsmain, vspragma-vsmain);
psdl.put(psmain, pspragma-psmain);
-
- loopk(i+1)
- {
+ loopk(i+1) {
defformatstring(tc,
k<numlights ?
"dynlight%ddir = vvertex.xyz*dynlightpos[%d].w + dynlightpos[%d].xyz;\n" :
@@ -766,58 +663,45 @@ static void gendynlightvariant(Shader &s, const char *sname, const char *vs, con
k, k, k);
if(k < numlights) vsdl.put(tc, strlen(tc));
else psdl.put(tc, strlen(tc));
-
defformatstring(dl,
"%s.rgb += dynlightcolor[%d] * (1.0 - clamp(dot(dynlight%ddir, dynlight%ddir), 0.0, 1.0));\n",
pslight, k, k, k);
psdl.put(dl, strlen(dl));
}
-
vsdl.put(vspragma, strlen(vspragma)+1);
psdl.put(pspragma, strlen(pspragma)+1);
-
defformatstring(name, "<dynlight %d>%s", i+1, sname);
Shader *variant = newshader(s.type, name, vsdl.getbuf(), psdl.getbuf(), &s, row);
if(!variant) return;
}
}
-static void genshadowmapvariant(Shader &s, const char *sname, const char *vs, const char *ps, int row = 1)
-{
+static void genshadowmapvariant(Shader &s, const char *sname, const char *vs, const char *ps, int row = 1) {
const char *vspragma = strstr(vs, "//:shadowmap"), *pspragma = strstr(ps, "//:shadowmap");
if(!vspragma || !pspragma) return;
-
string pslight;
vspragma += strcspn(vspragma, "\n");
if(*vspragma) vspragma++;
-
if(sscanf(pspragma, "//:shadowmap %100s", pslight)!=1) return;
-
pspragma += strcspn(pspragma, "\n");
if(*pspragma) pspragma++;
-
const char *vsmain = findglslmain(vs), *psmain = findglslmain(ps);
if(vsmain > vspragma) vsmain = vs;
if(psmain > pspragma) psmain = ps;
-
vector<char> vssm, pssm;
if(vsmain >= vs) vssm.put(vs, vsmain - vs);
if(psmain >= ps) pssm.put(ps, psmain - ps);
-
const char *vsdecl =
"uniform mat4 shadowmapproject;\n"
"varying vec3 shadowmaptc;\n";
vssm.put(vsdecl, strlen(vsdecl));
-
const char *psdecl =
"uniform sampler2D shadowmap;\n"
"uniform vec4 shadowmapambient;\n"
"varying vec3 shadowmaptc;\n";
pssm.put(psdecl, strlen(psdecl));
-
vssm.put(vsmain, vspragma-vsmain);
pssm.put(psmain, pspragma-psmain);
-
extern int smoothshadowmappeel;
const char *tcgen =
"shadowmaptc = vec3(shadowmapproject * vvertex);\n";
@@ -827,7 +711,6 @@ static void genshadowmapvariant(Shader &s, const char *sname, const char *vs, co
"vec4 smvals = texture2D(shadowmap, shadowmaptc.xy);\n"
"vec2 smdiff = clamp(smvals.xz - shadowmaptc.zz*smvals.y, 0.0, 1.0);\n"
"float shadowed = clamp((smdiff.x > 0.0 ? smvals.w : 0.0) - 8.0*smdiff.y, 0.0, 1.0);\n" :
-
"vec4 smvals = texture2D(shadowmap, shadowmaptc.xy);\n"
"float smtest = shadowmaptc.z*smvals.y;\n"
"float shadowed = smtest < smvals.x && smtest > smvals.z ? smvals.w : 0.0;\n";
@@ -836,32 +719,26 @@ static void genshadowmapvariant(Shader &s, const char *sname, const char *vs, co
"%s.rgb -= shadowed*clamp(%s.rgb - shadowmapambient.rgb, 0.0, 1.0);\n",
pslight, pslight);
pssm.put(smlight, strlen(smlight));
-
vssm.put(vspragma, strlen(vspragma)+1);
pssm.put(pspragma, strlen(pspragma)+1);
-
defformatstring(name, "<shadowmap>%s", sname);
Shader *variant = newshader(s.type, name, vssm.getbuf(), pssm.getbuf(), &s, row);
if(!variant) return;
-
if(strstr(vs, "//:dynlight")) gendynlightvariant(s, name, vssm.getbuf(), pssm.getbuf(), row);
}
-static void genuniformdefs(vector<char> &vsbuf, vector<char> &psbuf, const char *vs, const char *ps, Shader *variant = NULL)
-{
+static void genuniformdefs(vector<char> &vsbuf, vector<char> &psbuf, const char *vs, const char *ps, Shader *variant = NULL) {
if(variant ? variant->defaultparams.empty() : slotparams.empty()) return;
const char *vsmain = findglslmain(vs), *psmain = findglslmain(ps);
if(!vsmain || !psmain) return;
vsbuf.put(vs, vsmain - vs);
psbuf.put(ps, psmain - ps);
- if(variant) loopv(variant->defaultparams)
- {
+ if(variant) loopv(variant->defaultparams) {
defformatstring(uni, "\nuniform vec4 %s;\n", variant->defaultparams[i].name);
vsbuf.put(uni, strlen(uni));
psbuf.put(uni, strlen(uni));
}
- else loopv(slotparams)
- {
+ else loopv(slotparams) {
defformatstring(uni, "\nuniform vec4 %s;\n", slotparams[i].name);
vsbuf.put(uni, strlen(uni));
psbuf.put(uni, strlen(uni));
@@ -872,8 +749,7 @@ static void genuniformdefs(vector<char> &vsbuf, vector<char> &psbuf, const char
VAR(defershaders, 0, 1, 1);
-void defershader(int *type, const char *name, const char *contents)
-{
+void defershader(int *type, const char *name, const char *contents) {
Shader *exists = shaders.access(name);
if(exists && !exists->invalid()) return;
if(!defershaders) { execute(contents); return; }
@@ -886,10 +762,8 @@ void defershader(int *type, const char *name, const char *contents)
s.standard = standardshaders;
}
-void Shader::force()
-{
+void Shader::force() {
if(!deferred() || !defer) return;
-
char *cmd = defer;
defer = NULL;
bool wasstandard = standardshaders, wasforcing = forceshaders;
@@ -903,24 +777,20 @@ void Shader::force()
forceshaders = wasforcing;
standardshaders = wasstandard;
delete[] cmd;
-
- if(deferred())
- {
+ if(deferred()) {
DELETEA(defer);
type = SHADER_INVALID;
}
}
-void fixshaderdetail()
-{
+void fixshaderdetail() {
// must null out separately because fixdetailshader can recursively set it
enumerate(shaders, Shader, s, { if(!s.forced) s.detailshader = NULL; });
enumerate(shaders, Shader, s, { if(s.forced) s.fixdetailshader(); });
linkslotshaders();
}
-int Shader::uniformlocversion()
-{
+int Shader::uniformlocversion() {
static int version = 0;
if(++version >= 0) return version;
version = 0;
@@ -930,28 +800,23 @@ int Shader::uniformlocversion()
VARFP(shaderdetail, 0, MAXSHADERDETAIL, MAXSHADERDETAIL, fixshaderdetail());
-void Shader::fixdetailshader(bool shouldforce, bool recurse)
-{
+void Shader::fixdetailshader(bool shouldforce, bool recurse) {
Shader *alt = this;
detailshader = NULL;
- do
- {
+ do {
Shader *cur = shaderdetail < MAXSHADERDETAIL ? alt->fastshader[shaderdetail] : alt;
if(cur->deferred() && shouldforce) cur->force();
- if(!cur->invalid())
- {
+ if(!cur->invalid()) {
if(cur->deferred()) break;
detailshader = cur;
break;
}
alt = alt->altshader;
} while(alt && alt!=this);
-
if(recurse && detailshader) loopv(detailshader->variants) detailshader->variants[i]->fixdetailshader(shouldforce, false);
}
-Shader *useshaderbyname(const char *name)
-{
+Shader *useshaderbyname(const char *name) {
Shader *s = shaders.access(name);
if(!s) return NULL;
if(!s->detailshader) s->fixdetailshader();
@@ -959,17 +824,14 @@ Shader *useshaderbyname(const char *name)
return s;
}
-void shader(int *type, char *name, char *vs, char *ps)
-{
+void shader(int *type, char *name, char *vs, char *ps) {
if(lookupshaderbyname(name)) return;
-
defformatstring(info, "shader %s", name);
renderprogress(loadprogress, info);
-
vector<char> vsbuf, psbuf, vsbak, psbak;
#define GENSHADER(cond, body) \
- if(cond) \
- { \
+ if(cond) { \
+ \
if(vsbuf.length()) { vsbak.setsize(0); vsbak.put(vs, strlen(vs)+1); vs = vsbak.getbuf(); vsbuf.setsize(0); } \
if(psbuf.length()) { psbak.setsize(0); psbak.put(ps, strlen(ps)+1); ps = psbak.getbuf(); psbuf.setsize(0); } \
body; \
@@ -978,78 +840,63 @@ void shader(int *type, char *name, char *vs, char *ps)
}
GENSHADER(slotparams.length(), genuniformdefs(vsbuf, psbuf, vs, ps));
Shader *s = newshader(*type, name, vs, ps);
- if(s)
- {
+ if(s) {
if(strstr(vs, "//:shadowmap")) genshadowmapvariant(*s, s->name, vs, ps);
if(strstr(vs, "//:dynlight")) gendynlightvariant(*s, s->name, vs, ps);
}
slotparams.shrink(0);
}
-void variantshader(int *type, char *name, int *row, char *vs, char *ps)
-{
- if(*row < 0)
- {
+void variantshader(int *type, char *name, int *row, char *vs, char *ps) {
+ if(*row < 0) {
shader(type, name, vs, ps);
return;
}
else if(*row >= MAXVARIANTROWS) return;
-
Shader *s = lookupshaderbyname(name);
if(!s) return;
-
defformatstring(varname, "<variant:%d,%d>%s", s->numvariants(*row), *row, name);
//defformatstring(info, "shader %s", varname);
//renderprogress(loadprogress, info);
vector<char> vsbuf, psbuf, vsbak, psbak;
GENSHADER(s->defaultparams.length(), genuniformdefs(vsbuf, psbuf, vs, ps, s));
Shader *v = newshader(*type, varname, vs, ps, s, *row);
- if(v)
- {
+ if(v) {
if(strstr(vs, "//:dynlight")) gendynlightvariant(*s, varname, vs, ps, *row);
if(strstr(ps, "//:variant") || strstr(vs, "//:variant")) gengenericvariant(*s, varname, vs, ps, *row);
}
}
-void setshader(char *name)
-{
+void setshader(char *name) {
slotparams.shrink(0);
Shader *s = shaders.access(name);
- if(!s)
- {
+ if(!s) {
conoutf(CON_ERROR, "no such shader: %s", name);
}
else slotshader = s;
}
-void resetslotshader()
-{
+void resetslotshader() {
slotshader = NULL;
slotparams.shrink(0);
}
-void setslotshader(Slot &s)
-{
+void setslotshader(Slot &s) {
s.shader = slotshader;
- if(!s.shader)
- {
+ if(!s.shader) {
s.shader = stdworldshader;
return;
}
loopv(slotparams) s.params.add(slotparams[i]);
}
-static void linkslotshaderparams(vector<SlotShaderParam> &params, Shader *sh, bool load)
-{
- if(sh) loopv(params)
- {
+static void linkslotshaderparams(vector<SlotShaderParam> &params, Shader *sh, bool load) {
+ if(sh) loopv(params) {
int loc = -1;
SlotShaderParam &param = params[i];
- loopv(sh->defaultparams)
- {
+ loopv(sh->defaultparams) {
SlotShaderParamState &dparam = sh->defaultparams[i];
- if(dparam.name==param.name)
- {
+ if(dparam.name==param.name) {
if(memcmp(param.val, dparam.val, sizeof(param.val))) loc = i;
break;
}
@@ -1059,35 +906,27 @@ static void linkslotshaderparams(vector<SlotShaderParam> &params, Shader *sh, bo
else if(load) loopv(params) params[i].loc = -1;
}
-void linkslotshader(Slot &s, bool load)
-{
+void linkslotshader(Slot &s, bool load) {
if(!s.shader) return;
-
if(load && !s.shader->detailshader) s.shader->fixdetailshader();
-
linkslotshaderparams(s.params, s.shader->detailshader, load);
}
-void linkvslotshader(VSlot &s, bool load)
-{
+void linkvslotshader(VSlot &s, bool load) {
if(!s.slot->shader) return;
-
Shader *sh = s.slot->shader->detailshader;
linkslotshaderparams(s.params, sh, load);
-
if(!sh) return;
}
-void altshader(char *origname, char *altname)
-{
+void altshader(char *origname, char *altname) {
Shader *orig = shaders.access(origname), *alt = shaders.access(altname);
if(!orig || !alt) return;
orig->altshader = alt;
orig->fixdetailshader(false);
}
-void fastshader(char *nice, char *fast, int *detail)
-{
+void fastshader(char *nice, char *fast, int *detail) {
Shader *ns = shaders.access(nice), *fs = shaders.access(fast);
if(!ns || !fs) return;
loopi(min(*detail+1, MAXSHADERDETAIL)) ns->fastshader[i] = fs;
@@ -1106,21 +945,17 @@ ICOMMAND(isshaderdefined, "s", (char *name), intret(lookupshaderbyname(name) ? 1
static hashset<const char *> shaderparamnames(256);
-const char *getshaderparamname(const char *name, bool insert)
-{
+const char *getshaderparamname(const char *name, bool insert) {
const char *exists = shaderparamnames.find(name, NULL);
if(exists || !insert) return exists;
return shaderparamnames.add(newstring(name));
}
-void addslotparam(const char *name, float x, float y, float z, float w)
-{
+void addslotparam(const char *name, float x, float y, float z, float w) {
if(name) name = getshaderparamname(name);
- loopv(slotparams)
- {
+ loopv(slotparams) {
SlotShaderParam &param = slotparams[i];
- if(param.name==name)
- {
+ if(param.name==name) {
param.val[0] = x;
param.val[1] = y;
param.val[2] = z;
@@ -1136,8 +971,7 @@ ICOMMAND(setuniformparam, "sffff", (char *name, float *x, float *y, float *z, fl
ICOMMAND(setshaderparam, "sffff", (char *name, float *x, float *y, float *z, float *w), addslotparam(name, *x, *y, *z, *w));
ICOMMAND(defuniformparam, "sffff", (char *name, float *x, float *y, float *z, float *w), addslotparam(name, *x, *y, *z, *w));
-void cleanupshaders()
-{
+void cleanupshaders() {
loadedshaders = false;
nullshader = hudshader = hudnotextureshader = textureshader = notextureshader = nocolorshader = stdworldshader = NULL;
enumerate(shaders, Shader, s, s.cleanup());
@@ -1145,21 +979,17 @@ void cleanupshaders()
glUseProgram_(0);
}
-void reloadshaders()
-{
+void reloadshaders() {
identflags &= ~IDF_PERSIST;
loadshaders();
identflags |= IDF_PERSIST;
linkslotshaders();
- enumerate(shaders, Shader, s,
- {
- if(!s.standard && !(s.type&(SHADER_DEFERRED|SHADER_INVALID)) && !s.variantshader)
- {
+ enumerate(shaders, Shader, s, {
+ if(!s.standard && !(s.type&(SHADER_DEFERRED|SHADER_INVALID)) && !s.variantshader) {
defformatstring(info, "shader %s", s.name);
renderprogress(0.0, info);
if(!s.compile()) s.cleanup(true);
- loopv(s.variants)
- {
+ loopv(s.variants) {
Shader *v = s.variants[i];
if((v->reusevs && v->reusevs->invalid()) ||
(v->reuseps && v->reuseps->invalid()) ||
@@ -1171,8 +1001,7 @@ void reloadshaders()
});
}
-void setupblurkernel(int radius, float sigma, float *weights, float *offsets)
-{
+void setupblurkernel(int radius, float sigma, float *weights, float *offsets) {
if(radius<1 || radius>MAXBLURRADIUS) return;
sigma *= 2*radius;
float total = 1.0f/sigma;
@@ -1180,8 +1009,7 @@ void setupblurkernel(int radius, float sigma, float *weights, float *offsets)
offsets[0] = 0;
// rely on bilinear filtering to sample 2 pixels at once
// transforms a*X + b*Y into (u+v)*[X*u/(u+v) + Y*(1 - u/(u+v))]
- loopi(radius)
- {
+ loopi(radius) {
float weight1 = exp(-((2*i)*(2*i)) / (2*sigma*sigma)) / sigma,
weight2 = exp(-((2*i+1)*(2*i+1)) / (2*sigma*sigma)) / sigma,
scale = weight1 + weight2,
@@ -1194,13 +1022,11 @@ void setupblurkernel(int radius, float sigma, float *weights, float *offsets)
for(int i = radius+1; i <= MAXBLURRADIUS; i++) weights[i] = offsets[i] = 0;
}
-void setblurshader(int pass, int size, int radius, float *weights, float *offsets)
-{
+void setblurshader(int pass, int size, int radius, float *weights, float *offsets) {
if(radius<1 || radius>MAXBLURRADIUS) return;
static Shader *blurshader[7][2] = { { NULL, NULL }, { NULL, NULL }, { NULL, NULL }, { NULL, NULL }, { NULL, NULL }, { NULL, NULL }, { NULL, NULL } };
Shader *&s = blurshader[radius-1][pass];
- if(!s)
- {
+ if(!s) {
defformatstring(name, "blur%c%d", 'x'+pass, radius);
s = lookupshaderbyname(name);
}
diff --git a/src/engine/shadowmap.cpp b/src/engine/shadowmap.cpp
index 24a6fe5..1eefe4b 100644
--- a/src/engine/shadowmap.cpp
+++ b/src/engine/shadowmap.cpp
@@ -11,8 +11,7 @@ VARP(shadowmapdist, 128, 256, 512);
VARFP(fpshadowmap, 0, 0, 1, cleanshadowmap());
VARFP(shadowmapprecision, 0, 0, 1, cleanshadowmap());
bvec shadowmapambientcolor(0, 0, 0);
-HVARFR(shadowmapambient, 0, 0, 0xFFFFFF,
-{
+HVARFR(shadowmapambient, 0, 0, 0xFFFFFF, {
if(shadowmapambient <= 255) shadowmapambient |= (shadowmapambient<<8) | (shadowmapambient<<16);
shadowmapambientcolor = bvec((shadowmapambient>>16)&0xFF, (shadowmapambient>>8)&0xFF, shadowmapambient&0xFF);
});
@@ -27,36 +26,29 @@ vec shadowoffset(0, 0, 0), shadowfocus(0, 0, 0), shadowdir(0, SHADOWSKEW, 1);
VAR(shadowmapcasters, 1, 0, 0);
float shadowmapmaxz = 0;
-void setshadowdir(int angle)
-{
+void setshadowdir(int angle) {
shadowdir = vec(0, SHADOWSKEW, 1);
shadowdir.rotate_around_z(angle*RAD);
}
VARFR(shadowmapangle, 0, 0, 360, setshadowdir(shadowmapangle));
-void guessshadowdir()
-{
+void guessshadowdir() {
if(shadowmapangle) return;
- vec dir;
- {
+ vec dir; {
vec lightpos(0, 0, 0), casterpos(0, 0, 0);
int numlights = 0, numcasters = 0;
const vector<extentity *> &ents = entities::getents();
- loopv(ents)
- {
+ loopv(ents) {
extentity &e = *ents[i];
- switch(e.type)
- {
+ switch(e.type) {
case ET_LIGHT:
if(!e.attr1) { lightpos.add(e.o); numlights++; }
break;
-
case ET_MAPMODEL:
casterpos.add(e.o);
numcasters++;
break;
-
default:
if(e.type<ET_GAMESPECIFIC) break;
casterpos.add(e.o);
@@ -86,148 +78,112 @@ VARP(shadowmappeelbias, 0, 20, 1024);
VAR(smdepthpeel, 0, 1, 1);
VAR(smoothshadowmappeel, 1, 0, 0);
-static struct shadowmaptexture : rendertarget
-{
- const GLenum *colorformats() const
- {
+static struct shadowmaptexture : rendertarget {
+ const GLenum *colorformats() const {
static const GLenum rgbafmts[] = { GL_RGBA16F, GL_RGBA16, GL_RGBA, GL_RGBA8, GL_FALSE };
return &rgbafmts[fpshadowmap && hasTF ? 0 : (shadowmapprecision ? 1 : 2)];
}
-
bool swaptexs() const { return true; }
-
- bool scissorblur(int &x, int &y, int &w, int &h)
- {
+ bool scissorblur(int &x, int &y, int &w, int &h) {
x = max(int(floor((scissorx1+1)/2*vieww)) - 2*blursize, 2);
y = max(int(floor((scissory1+1)/2*viewh)) - 2*blursize, 2);
w = min(int(ceil((scissorx2+1)/2*vieww)) + 2*blursize, vieww-2) - x;
h = min(int(ceil((scissory2+1)/2*viewh)) + 2*blursize, viewh-2) - y;
return true;
}
-
- bool scissorrender(int &x, int &y, int &w, int &h)
- {
+ bool scissorrender(int &x, int &y, int &w, int &h) {
x = y = 2;
w = vieww - 2*2;
h = viewh - 2*2;
return true;
}
-
- void doclear()
- {
+ void doclear() {
glClearColor(0, 0, 0, 0);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
}
-
- bool dorender()
- {
+ bool dorender() {
vec skewdir(shadowdir);
skewdir.rotate_around_z(-camera1->yaw*RAD);
-
vec dir;
vecfromyawpitch(camera1->yaw, camera1->pitch, 1, 0, dir);
dir.z = 0;
dir.mul(shadowmapradius);
-
vec dirx, diry;
vecfromyawpitch(camera1->yaw, 0, 0, 1, dirx);
vecfromyawpitch(camera1->yaw, 0, 1, 0, diry);
shadowoffset.x = -fmod(dirx.dot(camera1->o) - skewdir.x*camera1->o.z, 2.0f*shadowmapradius/vieww);
shadowoffset.y = -fmod(diry.dot(camera1->o) - skewdir.y*camera1->o.z, 2.0f*shadowmapradius/viewh);
-
shadowmatrix.ortho(-shadowmapradius, shadowmapradius, -shadowmapradius, shadowmapradius, -shadowmapdist, shadowmapdist);
shadowmatrix.mul(matrix3(vec(1, 0, 0), vec(0, 1, 0), vec(skewdir.x, skewdir.y, 1)));
shadowmatrix.translate(skewdir.x*shadowmapheight + shadowoffset.x, skewdir.y*shadowmapheight + shadowoffset.y + dir.magnitude(), -shadowmapheight);
shadowmatrix.rotate_around_z((camera1->yaw+180)*-RAD);
shadowmatrix.translate(vec(camera1->o).neg());
GLOBALPARAM(shadowmatrix, shadowmatrix);
-
shadowfocus = camera1->o;
shadowfocus.add(dir);
shadowfocus.add(vec(shadowdir).mul(shadowmapheight));
shadowfocus.add(dirx.mul(shadowoffset.x));
shadowfocus.add(diry.mul(shadowoffset.y));
-
gle::colorf(0, 0, 0);
-
GLOBALPARAMF(shadowmapbias, -shadowmapbias/float(shadowmapdist), 1 - (shadowmapbias + (smoothshadowmappeel ? 0 : shadowmappeelbias))/float(shadowmapdist));
-
shadowmapcasters = 0;
shadowmapmaxz = shadowfocus.z - shadowmapdist;
shadowmapping = true;
rendergame();
shadowmapping = false;
shadowmapmaxz = min(shadowmapmaxz, shadowfocus.z);
-
- if(shadowmapcasters && smdepthpeel)
- {
+ if(shadowmapcasters && smdepthpeel) {
int sx, sy, sw, sh;
bool scissoring = rtscissor && scissorblur(sx, sy, sw, sh) && sw > 0 && sh > 0;
if(scissoring) glScissor(sx, sy, sw, sh);
if(!rtscissor || scissoring) rendershadowmapreceivers();
}
-
return shadowmapcasters>0;
}
} shadowmaptex;
-void cleanshadowmap()
-{
+void cleanshadowmap() {
shadowmaptex.cleanup(true);
}
-void calcshadowmapbb(const vec &o, float xyrad, float zrad, float &x1, float &y1, float &x2, float &y2)
-{
+void calcshadowmapbb(const vec &o, float xyrad, float zrad, float &x1, float &y1, float &x2, float &y2) {
vec skewdir(shadowdir);
skewdir.rotate_around_z(-camera1->yaw*RAD);
-
vec ro(o);
ro.sub(camera1->o);
ro.rotate_around_z(-(camera1->yaw+180)*RAD);
ro.x += ro.z * skewdir.x + shadowoffset.x;
ro.y += ro.z * skewdir.y + shadowmapradius * cosf(camera1->pitch*RAD) + shadowoffset.y;
-
vec high(ro), low(ro);
high.x += zrad * skewdir.x;
high.y += zrad * skewdir.y;
low.x -= zrad * skewdir.x;
low.y -= zrad * skewdir.y;
-
x1 = (min(high.x, low.x) - xyrad) / shadowmapradius;
y1 = (min(high.y, low.y) - xyrad) / shadowmapradius;
x2 = (max(high.x, low.x) + xyrad) / shadowmapradius;
y2 = (max(high.y, low.y) + xyrad) / shadowmapradius;
}
-bool addshadowmapcaster(const vec &o, float xyrad, float zrad)
-{
+bool addshadowmapcaster(const vec &o, float xyrad, float zrad) {
if(o.z + zrad <= shadowfocus.z - shadowmapdist || o.z - zrad >= shadowfocus.z) return false;
-
shadowmapmaxz = max(shadowmapmaxz, o.z + zrad);
-
float x1, y1, x2, y2;
calcshadowmapbb(o, xyrad, zrad, x1, y1, x2, y2);
-
if(!shadowmaptex.addblurtiles(x1, y1, x2, y2, 2)) return false;
-
shadowmapcasters++;
return true;
}
-bool isshadowmapreceiver(vtxarray *va)
-{
+bool isshadowmapreceiver(vtxarray *va) {
if(!shadowmap || !shadowmapcasters) return false;
-
if(va->shadowmapmax.z <= shadowfocus.z - shadowmapdist || va->shadowmapmin.z >= shadowmapmaxz) return false;
-
float xyrad = SQRT2*0.5f*max(va->shadowmapmax.x-va->shadowmapmin.x, va->shadowmapmax.y-va->shadowmapmin.y),
zrad = 0.5f*(va->shadowmapmax.z-va->shadowmapmin.z),
x1, y1, x2, y2;
if(xyrad<0 || zrad<0) return false;
-
vec center = vec(va->shadowmapmin).add(vec(va->shadowmapmax)).mul(0.5f);
calcshadowmapbb(center, xyrad, zrad, x1, y1, x2, y2);
-
return shadowmaptex.checkblurtiles(x1, y1, x2, y2, 2);
#if 0
@@ -244,8 +200,7 @@ bool isshadowmapreceiver(vtxarray *va)
#endif
}
-bool isshadowmapcaster(const vec &o, float rad)
-{
+bool isshadowmapcaster(const vec &o, float rad) {
// cheaper inexact test
float dz = o.z - shadowfocus.z;
float cx = shadowfocus.x + dz*shadowdir.x, cy = shadowfocus.y + dz*shadowdir.y;
@@ -258,22 +213,16 @@ bool isshadowmapcaster(const vec &o, float rad)
return true;
}
-void pushshadowmap()
-{
+void pushshadowmap() {
if(!shadowmap || !shadowmaptex.rendertex) return;
-
glActiveTexture_(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_2D, shadowmaptex.rendertex);
-
matrix4 m = shadowmatrix;
m.projective(-1, 1-shadowmapbias/float(shadowmapdist));
GLOBALPARAM(shadowmapproject, m);
-
glActiveTexture_(GL_TEXTURE0);
-
float r, g, b;
- if(!shadowmapambient)
- {
+ if(!shadowmapambient) {
r = max(25.0f, 2.0f*ambientcolor[0]);
g = max(25.0f, 2.0f*ambientcolor[1]);
b = max(25.0f, 2.0f*ambientcolor[2]);
@@ -282,14 +231,7 @@ void pushshadowmap()
GLOBALPARAMF(shadowmapambient, r/255.0f, g/255.0f, b/255.0f);
}
-void popshadowmap()
-{
- if(!shadowmap || !shadowmaptex.rendertex) return;
-}
-
-void rendershadowmap()
-{
+void rendershadowmap() {
if(!shadowmap) return;
-
shadowmaptex.render(1<<shadowmapsize, 1<<shadowmapsize, blurshadowmap, blursmsigma/100.0f);
}
diff --git a/src/engine/skelmodel.h b/src/engine/skelmodel.h
index c8d14d0..e823337 100644
--- a/src/engine/skelmodel.h
+++ b/src/engine/skelmodel.h
@@ -7,8 +7,7 @@ VAR(testtags, 0, 0, 1);
#define BONEMASK_END 0xFFFF
#define BONEMASK_BONE 0x7FFF
-struct skelmodel : animmodel
-{
+struct skelmodel : animmodel {
struct vert { vec pos, norm; vec2 tc; int blend, interpindex; };
struct vvert { vec pos; vec2 tc; };
struct vvertn : vvert { vec norm; };
@@ -18,37 +17,25 @@ struct skelmodel : animmodel
struct vvertbumpw : vvertbump, vvertw {};
struct bumpvert { quat tangent; };
struct tri { ushort vert[3]; };
-
- struct blendcombo
- {
+ struct blendcombo {
int uses, interpindex;
float weights[4];
uchar bones[4], interpbones[4];
-
- blendcombo() : uses(1)
- {
+ blendcombo() : uses(1) {
}
-
- bool operator==(const blendcombo &c) const
- {
+ bool operator==(const blendcombo &c) const {
loopk(4) if(bones[k] != c.bones[k]) return false;
loopk(4) if(weights[k] != c.weights[k]) return false;
return true;
}
-
- int size() const
- {
+ int size() const {
int i = 1;
while(i < 4 && weights[i]) i++;
return i;
}
-
- static bool sortcmp(const blendcombo &x, const blendcombo &y)
- {
- loopi(4)
- {
- if(x.weights[i])
- {
+ static bool sortcmp(const blendcombo &x, const blendcombo &y) {
+ loopi(4) {
+ if(x.weights[i]) {
if(!y.weights[i]) return true;
}
else if(y.weights[i]) return false;
@@ -56,14 +43,10 @@ struct skelmodel : animmodel
}
return false;
}
-
- int addweight(int sorted, float weight, int bone)
- {
+ int addweight(int sorted, float weight, int bone) {
if(weight <= 1e-3f) return sorted;
- loopk(sorted) if(weight > weights[k])
- {
- for(int l = min(sorted-1, 2); l >= k; l--)
- {
+ loopk(sorted) if(weight > weights[k]) {
+ for(int l = min(sorted-1, 2); l >= k; l--) {
weights[l+1] = weights[l];
bones[l+1] = bones[l];
}
@@ -76,9 +59,7 @@ struct skelmodel : animmodel
bones[sorted] = bone;
return sorted+1;
}
-
- void finalize(int sorted)
- {
+ void finalize(int sorted) {
loopj(4-sorted) { weights[sorted+j] = 0; bones[sorted+j] = 0; }
if(sorted <= 0) return;
float total = 0;
@@ -86,26 +67,20 @@ struct skelmodel : animmodel
total = 1.0f/total;
loopj(sorted) weights[j] *= total;
}
-
- void serialize(vvertw &v)
- {
- if(interpindex >= 0)
- {
+ void serialize(vvertw &v) {
+ if(interpindex >= 0) {
v.weights[0] = 255;
loopk(3) v.weights[k+1] = 0;
v.bones[0] = 2*interpindex;
loopk(3) v.bones[k+1] = v.bones[0];
}
- else
- {
+ else {
int total = 0;
loopk(4) total += (v.weights[k] = uchar(0.5f + weights[k]*255));
- while(total > 255)
- {
+ while(total > 255) {
loopk(4) if(v.weights[k] > 0 && total > 255) { v.weights[k]--; total--; }
}
- while(total < 255)
- {
+ while(total < 255) {
loopk(4) if(v.weights[k] < 255 && total < 255) { v.weights[k]++; total++; }
}
loopk(4) v.bones[k] = 2*interpbones[k];
@@ -113,118 +88,79 @@ struct skelmodel : animmodel
}
};
-
- struct animcacheentry
- {
+ struct animcacheentry {
animstate as[MAXANIMPARTS];
float pitch;
int millis;
uchar *partmask;
ragdolldata *ragdoll;
-
- animcacheentry() : ragdoll(NULL)
- {
+ animcacheentry() : ragdoll(NULL) {
loopk(MAXANIMPARTS) as[k].cur.fr1 = as[k].prev.fr1 = -1;
}
-
- bool operator==(const animcacheentry &c) const
- {
+ bool operator==(const animcacheentry &c) const {
loopi(MAXANIMPARTS) if(as[i]!=c.as[i]) return false;
return pitch==c.pitch && partmask==c.partmask && ragdoll==c.ragdoll && (!ragdoll || min(millis, c.millis) >= ragdoll->lastmove);
}
};
-
- struct vbocacheentry : animcacheentry
- {
+ struct vbocacheentry : animcacheentry {
GLuint vbuf;
int owner;
-
vbocacheentry() : vbuf(0), owner(-1) {}
};
-
- struct skelcacheentry : animcacheentry
- {
+ struct skelcacheentry : animcacheentry {
dualquat *bdata;
int version;
bool dirty;
-
skelcacheentry() : bdata(NULL), version(-1), dirty(false) {}
-
- void nextversion()
- {
+ void nextversion() {
version = Shader::uniformlocversion();
dirty = true;
}
};
-
- struct blendcacheentry : skelcacheentry
- {
+ struct blendcacheentry : skelcacheentry {
int owner;
-
blendcacheentry() : owner(-1) {}
};
-
struct skelmeshgroup;
-
- struct skelmesh : mesh
- {
+ struct skelmesh : mesh {
vert *verts;
bumpvert *bumpverts;
tri *tris;
int numverts, numtris, maxweights;
-
int voffset, eoffset, elen;
ushort minvert, maxvert;
-
- skelmesh() : verts(NULL), bumpverts(NULL), tris(NULL), numverts(0), numtris(0), maxweights(0)
- {
+ skelmesh() : verts(NULL), bumpverts(NULL), tris(NULL), numverts(0), numtris(0), maxweights(0) {
}
-
- virtual ~skelmesh()
- {
+ virtual ~skelmesh() {
DELETEA(verts);
DELETEA(bumpverts);
DELETEA(tris);
}
-
- int addblendcombo(const blendcombo &c)
- {
+ int addblendcombo(const blendcombo &c) {
maxweights = max(maxweights, c.size());
return ((skelmeshgroup *)group)->addblendcombo(c);
}
-
- void smoothnorms(float limit = 0, bool areaweight = true)
- {
+ void smoothnorms(float limit = 0, bool areaweight = true) {
mesh::smoothnorms(verts, numverts, tris, numtris, limit, areaweight);
}
-
- void buildnorms(bool areaweight = true)
- {
+ void buildnorms(bool areaweight = true) {
mesh::buildnorms(verts, numverts, tris, numtris, areaweight);
}
-
- void calctangents(bool areaweight = true)
- {
+ void calctangents(bool areaweight = true) {
if(bumpverts) return;
bumpverts = new bumpvert[numverts];
mesh::calctangents(bumpverts, verts, verts, numverts, tris, numtris, areaweight);
}
-
- void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m)
- {
- loopj(numverts)
- {
+ void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m) {
+ loopj(numverts) {
vec v = m.transform(verts[j].pos);
- loopi(3)
- {
+ loopi(3) {
bbmin[i] = min(bbmin[i], v[i]);
bbmax[i] = max(bbmax[i], v[i]);
}
}
}
-
- void genBIH(BIH::mesh &m)
- {
+ void genBIH(BIH::mesh &m) {
m.tris = (const BIH::tri *)tris;
m.numtris = numtris;
m.pos = (const uchar *)&verts->pos;
@@ -232,44 +168,33 @@ struct skelmodel : animmodel
m.tc = (const uchar *)&verts->tc;
m.tcstride = sizeof(vert);
}
-
- static inline void assignvert(vvertn &vv, int j, vert &v, blendcombo &c)
- {
+ static inline void assignvert(vvertn &vv, int j, vert &v, blendcombo &c) {
vv.pos = v.pos;
vv.norm = v.norm;
vv.tc = v.tc;
}
-
- inline void assignvert(vvertbump &vv, int j, vert &v, blendcombo &c)
- {
+ inline void assignvert(vvertbump &vv, int j, vert &v, blendcombo &c) {
vv.pos = v.pos;
vv.tc = v.tc;
vv.tangent = bumpverts[j].tangent;
}
-
- static inline void assignvert(vvertnw &vv, int j, vert &v, blendcombo &c)
- {
+ static inline void assignvert(vvertnw &vv, int j, vert &v, blendcombo &c) {
vv.pos = v.pos;
vv.norm = v.norm;
vv.tc = v.tc;
c.serialize(vv);
}
-
- inline void assignvert(vvertbumpw &vv, int j, vert &v, blendcombo &c)
- {
+ inline void assignvert(vvertbumpw &vv, int j, vert &v, blendcombo &c) {
vv.pos = v.pos;
vv.tc = v.tc;
vv.tangent = bumpverts[j].tangent;
c.serialize(vv);
}
-
template<class T>
- int genvbo(vector<ushort> &idxs, int offset, vector<T> &vverts)
- {
+ int genvbo(vector<ushort> &idxs, int offset, vector<T> &vverts) {
voffset = offset;
eoffset = idxs.length();
- loopi(numverts)
- {
+ loopi(numverts) {
vert &v = verts[i];
assignvert(vverts.add(), i, v, ((skelmeshgroup *)group)->blendcombos[v.blend]);
}
@@ -279,25 +204,20 @@ struct skelmodel : animmodel
maxvert = voffset + numverts-1;
return numverts;
}
-
template<class T>
- int genvbo(vector<ushort> &idxs, int offset, vector<T> &vverts, int *htdata, int htlen)
- {
+ int genvbo(vector<ushort> &idxs, int offset, vector<T> &vverts, int *htdata, int htlen) {
voffset = offset;
eoffset = idxs.length();
minvert = 0xFFFF;
- loopi(numtris)
- {
+ loopi(numtris) {
tri &t = tris[i];
- loopj(3)
- {
+ loopj(3) {
int index = t.vert[j];
vert &v = verts[index];
T vv;
assignvert(vv, index, v, ((skelmeshgroup *)group)->blendcombos[v.blend]);
int htidx = hthash(v.pos)&(htlen-1);
- loopk(htlen)
- {
+ loopk(htlen) {
int &vidx = htdata[(htidx+k)&(htlen-1)];
if(vidx < 0) { vidx = idxs.add(ushort(vverts.length())); vverts.add(vv); break; }
else if(!memcmp(&vverts[vidx], &vv, sizeof(vv))) { minvert = min(minvert, idxs.add(ushort(vidx))); break; }
@@ -309,15 +229,11 @@ struct skelmodel : animmodel
maxvert = max(minvert, ushort(vverts.length()-1));
return vverts.length()-voffset;
}
-
- int genvbo(vector<ushort> &idxs, int offset)
- {
+ int genvbo(vector<ushort> &idxs, int offset) {
loopi(numverts) verts[i].interpindex = ((skelmeshgroup *)group)->remapblend(verts[i].blend);
-
voffset = offset;
eoffset = idxs.length();
- loopi(numtris)
- {
+ loopi(numtris) {
tri &t = tris[i];
loopj(3) idxs.add(voffset+t.vert[j]);
}
@@ -326,28 +242,21 @@ struct skelmodel : animmodel
elen = idxs.length()-eoffset;
return numverts;
}
-
template<class T>
- static inline void fillvert(T &vv, int j, vert &v)
- {
+ static inline void fillvert(T &vv, int j, vert &v) {
vv.tc = v.tc;
}
-
template<class T>
- void fillverts(T *vdata)
- {
+ void fillverts(T *vdata) {
vdata += voffset;
loopi(numverts) fillvert(vdata[i], i, verts[i]);
}
-
- void interpverts(const dualquat * RESTRICT bdata1, const dualquat * RESTRICT bdata2, bool tangents, void * RESTRICT vdata, skin &s)
- {
+ void interpverts(const dualquat * RESTRICT bdata1, const dualquat * RESTRICT bdata2, bool tangents, void * RESTRICT vdata, skin &s) {
const int blendoffset = ((skelmeshgroup *)group)->skel->numgpubones;
bdata2 -= blendoffset;
-
#define IPLOOP(type, dosetup, dotransform) \
- loopi(numverts) \
- { \
+ loopi(numverts) { \
+ \
const vert &src = verts[i]; \
type &dst = ((type * RESTRICT)vdata)[i]; \
dosetup; \
@@ -355,36 +264,26 @@ struct skelmodel : animmodel
dst.pos = b.transform(src.pos); \
dotransform; \
}
-
- if(tangents)
- {
- IPLOOP(vvertbump, bumpvert &bsrc = bumpverts[i],
- {
+ if(tangents) {
+ IPLOOP(vvertbump, bumpvert &bsrc = bumpverts[i], {
quat q = b.transform(bsrc.tangent);
fixqtangent(q, bsrc.tangent.w);
dst.tangent = q;
});
}
- else
- {
- IPLOOP(vvertn, ,
- {
+ else {
+ IPLOOP(vvertn, , {
dst.norm = b.transformnormal(src.norm);
});
}
-
#undef IPLOOP
}
-
- void setshader(Shader *s)
- {
+ void setshader(Shader *s) {
skelmeshgroup *g = (skelmeshgroup *)group;
if(!g->skel->usegpuskel) s->set();
else s->setvariant(min(maxweights, g->vweights)-1, 0);
}
-
- void render(const animstate *as, skin &s, vbocacheentry &vc)
- {
+ void render(const animstate *as, skin &s, vbocacheentry &vc) {
if(!Shader::lastshader) return;
glDrawRangeElements_(GL_TRIANGLES, minvert, maxvert, elen, GL_UNSIGNED_SHORT, &((skelmeshgroup *)group)->edata[eoffset]);
glde++;
@@ -392,73 +291,50 @@ struct skelmodel : animmodel
}
};
-
- struct tag
- {
+ struct tag {
char *name;
int bone;
matrix4x3 matrix;
-
tag() : name(NULL) {}
~tag() { DELETEA(name); }
};
-
- struct skelanimspec
- {
+ struct skelanimspec {
char *name;
int frame, range;
-
skelanimspec() : name(NULL), frame(0), range(0) {}
- ~skelanimspec()
- {
+ ~skelanimspec() {
DELETEA(name);
}
};
-
- struct boneinfo
- {
+ struct boneinfo {
const char *name;
int parent, children, next, group, scheduled, interpindex, interpparent, ragdollindex, correctindex;
float pitchscale, pitchoffset, pitchmin, pitchmax;
dualquat base, invbase;
-
boneinfo() : name(NULL), parent(-1), children(-1), next(-1), group(INT_MAX), scheduled(-1), interpindex(-1), interpparent(-1), ragdollindex(-1), correctindex(-1), pitchscale(0), pitchoffset(0), pitchmin(0), pitchmax(0) {}
- ~boneinfo()
- {
+ ~boneinfo() {
DELETEA(name);
}
};
-
- struct antipode
- {
+ struct antipode {
int parent, child;
-
antipode(int parent, int child) : parent(parent), child(child) {}
};
-
- struct pitchdep
- {
+ struct pitchdep {
int bone, parent;
dualquat pose;
};
-
- struct pitchtarget
- {
+ struct pitchtarget {
int bone, frame, corrects, deps;
float pitchmin, pitchmax, deviated;
dualquat pose;
};
-
- struct pitchcorrect
- {
+ struct pitchcorrect {
int bone, target, parent;
float pitchmin, pitchmax, pitchscale, pitchangle, pitchtotal;
-
pitchcorrect() : parent(-1), pitchangle(0), pitchtotal(0) {}
};
-
- struct skeleton
- {
+ struct skeleton {
char *name;
int shared;
vector<skelmeshgroup *> users;
@@ -472,36 +348,25 @@ struct skelmodel : animmodel
vector<pitchdep> pitchdeps;
vector<pitchtarget> pitchtargets;
vector<pitchcorrect> pitchcorrects;
-
bool usegpuskel;
vector<skelcacheentry> skelcache;
hashtable<GLuint, int> blendoffsets;
-
- skeleton() : name(NULL), shared(0), bones(NULL), numbones(0), numinterpbones(0), numgpubones(0), numframes(0), framebones(NULL), ragdoll(NULL), usegpuskel(false), blendoffsets(32)
- {
+ skeleton() : name(NULL), shared(0), bones(NULL), numbones(0), numinterpbones(0), numgpubones(0), numframes(0), framebones(NULL), ragdoll(NULL), usegpuskel(false), blendoffsets(32) {
}
-
- ~skeleton()
- {
+ ~skeleton() {
DELETEA(name);
DELETEA(bones);
DELETEA(framebones);
DELETEP(ragdoll);
- loopv(skelcache)
- {
+ loopv(skelcache) {
DELETEA(skelcache[i].bdata);
}
}
-
- skelanimspec *findskelanim(const char *name, char sep = '\0')
- {
+ skelanimspec *findskelanim(const char *name, char sep = '\0') {
int len = sep ? strlen(name) : 0;
- loopv(skelanims)
- {
- if(skelanims[i].name)
- {
- if(sep)
- {
+ loopv(skelanims) {
+ if(skelanims[i].name) {
+ if(sep) {
const char *end = strchr(skelanims[i].name, ':');
if(end && end - skelanims[i].name == len && !memcmp(name, skelanims[i].name, len)) return &skelanims[i];
}
@@ -510,38 +375,28 @@ struct skelmodel : animmodel
}
return NULL;
}
-
- skelanimspec &addskelanim(const char *name)
- {
+ skelanimspec &addskelanim(const char *name) {
skelanimspec &sa = skelanims.add();
sa.name = name ? newstring(name) : NULL;
return sa;
}
-
- int findbone(const char *name)
- {
+ int findbone(const char *name) {
loopi(numbones) if(bones[i].name && !strcmp(bones[i].name, name)) return i;
return -1;
}
-
- int findtag(const char *name)
- {
+ int findtag(const char *name) {
loopv(tags) if(!strcmp(tags[i].name, name)) return i;
return -1;
}
-
- bool addtag(const char *name, int bone, const matrix4x3 &matrix)
- {
+ bool addtag(const char *name, int bone, const matrix4x3 &matrix) {
int idx = findtag(name);
- if(idx >= 0)
- {
+ if(idx >= 0) {
if(!testtags) return false;
tag &t = tags[idx];
t.bone = bone;
t.matrix = matrix;
}
- else
- {
+ else {
tag &t = tags.add();
t.name = newstring(name);
t.bone = bone;
@@ -549,67 +404,52 @@ struct skelmodel : animmodel
}
return true;
}
-
- void calcantipodes()
- {
+ void calcantipodes() {
antipodes.shrink(0);
vector<int> schedule;
- loopi(numbones)
- {
- if(bones[i].group >= numbones)
- {
+ loopi(numbones) {
+ if(bones[i].group >= numbones) {
bones[i].scheduled = schedule.length();
schedule.add(i);
}
else bones[i].scheduled = -1;
}
- loopv(schedule)
- {
+ loopv(schedule) {
int bone = schedule[i];
const boneinfo &info = bones[bone];
- loopj(numbones) if(abs(bones[j].group) == bone && bones[j].scheduled < 0)
- {
+ loopj(numbones) if(abs(bones[j].group) == bone && bones[j].scheduled < 0) {
antipodes.add(antipode(info.interpindex, bones[j].interpindex));
bones[j].scheduled = schedule.length();
schedule.add(j);
}
- if(i + 1 == schedule.length())
- {
+ if(i + 1 == schedule.length()) {
int conflict = INT_MAX;
loopj(numbones) if(bones[j].group < numbones && bones[j].scheduled < 0) conflict = min(conflict, abs(bones[j].group));
- if(conflict < numbones)
- {
+ if(conflict < numbones) {
bones[conflict].scheduled = schedule.length();
schedule.add(conflict);
}
}
}
}
-
- void remapbones()
- {
- loopi(numbones)
- {
+ void remapbones() {
+ loopi(numbones) {
boneinfo &info = bones[i];
info.interpindex = -1;
info.ragdollindex = -1;
}
numgpubones = 0;
- loopv(users)
- {
+ loopv(users) {
skelmeshgroup *group = users[i];
- loopvj(group->blendcombos)
- {
+ loopvj(group->blendcombos) {
blendcombo &c = group->blendcombos[j];
- loopk(4)
- {
+ loopk(4) {
if(!c.weights[k]) { c.interpbones[k] = k > 0 ? c.interpbones[k-1] : 0; continue; }
boneinfo &info = bones[c.bones[k]];
if(info.interpindex < 0) info.interpindex = numgpubones++;
c.interpbones[k] = info.interpindex;
if(info.group < 0) continue;
- loopl(4)
- {
+ loopl(4) {
if(!c.weights[l]) break;
if(l == k) continue;
int parent = c.bones[l];
@@ -623,41 +463,33 @@ struct skelmodel : animmodel
}
}
numinterpbones = numgpubones;
- loopv(tags)
- {
+ loopv(tags) {
boneinfo &info = bones[tags[i].bone];
if(info.interpindex < 0) info.interpindex = numinterpbones++;
}
- if(ragdoll)
- {
- loopv(ragdoll->joints)
- {
+ if(ragdoll) {
+ loopv(ragdoll->joints) {
boneinfo &info = bones[ragdoll->joints[i].bone];
if(info.interpindex < 0) info.interpindex = numinterpbones++;
info.ragdollindex = i;
}
}
- loopi(numbones)
- {
+ loopi(numbones) {
boneinfo &info = bones[i];
if(info.interpindex < 0) continue;
for(int parent = info.parent; parent >= 0 && bones[parent].interpindex < 0; parent = bones[parent].parent)
bones[parent].interpindex = numinterpbones++;
}
- loopi(numbones)
- {
+ loopi(numbones) {
boneinfo &info = bones[i];
if(info.interpindex < 0) continue;
info.interpparent = info.parent >= 0 ? bones[info.parent].interpindex : -1;
}
- if(ragdoll)
- {
- loopi(numbones)
- {
+ if(ragdoll) {
+ loopi(numbones) {
boneinfo &info = bones[i];
if(info.interpindex < 0 || info.ragdollindex >= 0) continue;
- for(int parent = info.parent; parent >= 0; parent = bones[parent].parent)
- {
+ for(int parent = info.parent; parent >= 0; parent = bones[parent].parent) {
if(bones[parent].ragdollindex >= 0) { ragdoll->addreljoint(i, bones[parent].ragdollindex); break; }
}
}
@@ -665,19 +497,14 @@ struct skelmodel : animmodel
calcantipodes();
}
-
- void addpitchdep(int bone, int frame)
- {
- for(; bone >= 0; bone = bones[bone].parent)
- {
+ void addpitchdep(int bone, int frame) {
+ for(; bone >= 0; bone = bones[bone].parent) {
int pos = pitchdeps.length();
- loopvj(pitchdeps) if(bone <= pitchdeps[j].bone)
- {
+ loopvj(pitchdeps) if(bone <= pitchdeps[j].bone) {
if(bone == pitchdeps[j].bone) goto nextbone;
pos = j;
break;
- }
- {
+ } {
pitchdep d;
d.bone = bone;
d.parent = -1;
@@ -687,66 +514,51 @@ struct skelmodel : animmodel
nextbone:;
}
}
-
- int findpitchdep(int bone)
- {
+ int findpitchdep(int bone) {
loopv(pitchdeps) if(bone <= pitchdeps[i].bone) return bone == pitchdeps[i].bone ? i : -1;
return -1;
}
-
- int findpitchcorrect(int bone)
- {
+ int findpitchcorrect(int bone) {
loopv(pitchcorrects) if(bone <= pitchcorrects[i].bone) return bone == pitchcorrects[i].bone ? i : -1;
return -1;
}
-
- void initpitchdeps()
- {
+ void initpitchdeps() {
pitchdeps.setsize(0);
if(pitchtargets.empty()) return;
- loopv(pitchtargets)
- {
+ loopv(pitchtargets) {
pitchtarget &t = pitchtargets[i];
t.deps = -1;
addpitchdep(t.bone, t.frame);
}
- loopv(pitchdeps)
- {
+ loopv(pitchdeps) {
pitchdep &d = pitchdeps[i];
int parent = bones[d.bone].parent;
- if(parent >= 0)
- {
+ if(parent >= 0) {
int j = findpitchdep(parent);
- if(j >= 0)
- {
+ if(j >= 0) {
d.parent = j;
d.pose.mul(pitchdeps[j].pose, dualquat(d.pose));
}
}
}
- loopv(pitchtargets)
- {
+ loopv(pitchtargets) {
pitchtarget &t = pitchtargets[i];
int j = findpitchdep(t.bone);
- if(j >= 0)
- {
+ if(j >= 0) {
t.deps = j;
t.pose = pitchdeps[j].pose;
}
t.corrects = -1;
- for(int parent = t.bone; parent >= 0; parent = bones[parent].parent)
- {
+ for(int parent = t.bone; parent >= 0; parent = bones[parent].parent) {
t.corrects = findpitchcorrect(parent);
if(t.corrects >= 0) break;
}
}
- loopv(pitchcorrects)
- {
+ loopv(pitchcorrects) {
pitchcorrect &c = pitchcorrects[i];
bones[c.bone].correctindex = i;
c.parent = -1;
- for(int parent = c.bone;;)
- {
+ for(int parent = c.bone;;) {
parent = bones[parent].parent;
if(parent < 0) break;
c.parent = findpitchcorrect(parent);
@@ -754,56 +566,42 @@ struct skelmodel : animmodel
}
}
}
-
- void optimize()
- {
+ void optimize() {
cleanup();
if(ragdoll) ragdoll->setup();
remapbones();
initpitchdeps();
}
-
- void expandbonemask(uchar *expansion, int bone, int val)
- {
+ void expandbonemask(uchar *expansion, int bone, int val) {
expansion[bone] = val;
bone = bones[bone].children;
while(bone>=0) { expandbonemask(expansion, bone, val); bone = bones[bone].next; }
}
-
- void applybonemask(ushort *mask, uchar *partmask, int partindex)
- {
+ void applybonemask(ushort *mask, uchar *partmask, int partindex) {
if(!mask || *mask==BONEMASK_END) return;
uchar *expansion = new uchar[numbones];
memset(expansion, *mask&BONEMASK_NOT ? 1 : 0, numbones);
- while(*mask!=BONEMASK_END)
- {
+ while(*mask!=BONEMASK_END) {
expandbonemask(expansion, *mask&BONEMASK_BONE, *mask&BONEMASK_NOT ? 0 : 1);
mask++;
}
loopi(numbones) if(expansion[i]) partmask[i] = partindex;
delete[] expansion;
}
-
- void linkchildren()
- {
- loopi(numbones)
- {
+ void linkchildren() {
+ loopi(numbones) {
boneinfo &b = bones[i];
b.children = -1;
if(b.parent<0) b.next = -1;
- else
- {
+ else {
b.next = bones[b.parent].children;
bones[b.parent].children = i;
}
}
}
-
int availgpubones() const { return min(maxvsuniforms - reservevpparams - 10, maxskelanimdata) / 2; }
bool gpuaccelerate() const { return numframes && gpuskel && numgpubones<=availgpubones(); }
-
- float calcdeviation(const vec &axis, const vec &forward, const dualquat &pose1, const dualquat &pose2)
- {
+ float calcdeviation(const vec &axis, const vec &forward, const dualquat &pose1, const dualquat &pose2) {
vec forward1 = pose1.transformnormal(forward).project(axis).normalize(),
forward2 = pose2.transformnormal(forward).project(axis).normalize(),
daxis = vec().cross(forward1, forward2);
@@ -811,35 +609,28 @@ struct skelmodel : animmodel
if(daxis.dot(axis) < 0) dy = -dy;
return atan2f(dy, dx)/RAD;
}
-
- void calcpitchcorrects(float pitch, const vec &axis, const vec &forward)
- {
- loopv(pitchtargets)
- {
+ void calcpitchcorrects(float pitch, const vec &axis, const vec &forward) {
+ loopv(pitchtargets) {
pitchtarget &t = pitchtargets[i];
t.deviated = calcdeviation(axis, forward, t.pose, pitchdeps[t.deps].pose);
}
- loopv(pitchcorrects)
- {
+ loopv(pitchcorrects) {
pitchcorrect &c = pitchcorrects[i];
c.pitchangle = c.pitchtotal = 0;
}
- loopvj(pitchtargets)
- {
+ loopvj(pitchtargets) {
pitchtarget &t = pitchtargets[j];
float tpitch = pitch - t.deviated;
for(int parent = t.corrects; parent >= 0; parent = pitchcorrects[parent].parent)
tpitch -= pitchcorrects[parent].pitchangle;
if(t.pitchmin || t.pitchmax) tpitch = clamp(tpitch, t.pitchmin, t.pitchmax);
- loopv(pitchcorrects)
- {
+ loopv(pitchcorrects) {
pitchcorrect &c = pitchcorrects[i];
if(c.target != j) continue;
float total = c.parent >= 0 ? pitchcorrects[c.parent].pitchtotal : 0,
avail = tpitch - total,
used = tpitch*c.pitchscale;
- if(c.pitchmin || c.pitchmax)
- {
+ if(c.pitchmin || c.pitchmax) {
if(used < 0) used = clamp(c.pitchmin, used, 0.0f);
else used = clamp(c.pitchmax, 0.0f, used);
}
@@ -850,39 +641,32 @@ struct skelmodel : animmodel
}
}
}
-
#define INTERPBONE(bone) \
const animstate &s = as[partmask[bone]]; \
const framedata &f = partframes[partmask[bone]]; \
dualquat d; \
(d = f.fr1[bone]).mul((1-s.cur.t)*s.interp); \
d.accumulate(f.fr2[bone], s.cur.t*s.interp); \
- if(s.interp<1) \
- { \
+ if(s.interp<1) { \
+ \
d.accumulate(f.pfr1[bone], (1-s.prev.t)*(1-s.interp)); \
d.accumulate(f.pfr2[bone], s.prev.t*(1-s.interp)); \
}
-
- void interpbones(const animstate *as, float pitch, const vec &axis, const vec &forward, int numanimparts, const uchar *partmask, skelcacheentry &sc)
- {
+ void interpbones(const animstate *as, float pitch, const vec &axis, const vec &forward, int numanimparts, const uchar *partmask, skelcacheentry &sc) {
if(!sc.bdata) sc.bdata = new dualquat[numinterpbones];
sc.nextversion();
- struct framedata
- {
+ struct framedata {
const dualquat *fr1, *fr2, *pfr1, *pfr2;
} partframes[MAXANIMPARTS];
- loopi(numanimparts)
- {
+ loopi(numanimparts) {
partframes[i].fr1 = &framebones[as[i].cur.fr1*numbones];
partframes[i].fr2 = &framebones[as[i].cur.fr2*numbones];
- if(as[i].interp<1)
- {
+ if(as[i].interp<1) {
partframes[i].pfr1 = &framebones[as[i].prev.fr1*numbones];
partframes[i].pfr2 = &framebones[as[i].prev.fr2*numbones];
}
}
- loopv(pitchdeps)
- {
+ loopv(pitchdeps) {
pitchdep &p = pitchdeps[i];
INTERPBONE(p.bone);
d.normalize();
@@ -890,8 +674,7 @@ struct skelmodel : animmodel
else p.pose = d;
}
calcpitchcorrects(pitch, axis, forward);
- loopi(numbones) if(bones[i].interpindex>=0)
- {
+ loopi(numbones) if(bones[i].interpindex>=0) {
INTERPBONE(i);
const boneinfo &b = bones[i];
d.normalize();
@@ -907,49 +690,39 @@ struct skelmodel : animmodel
}
loopv(antipodes) sc.bdata[antipodes[i].child].fixantipodal(sc.bdata[antipodes[i].parent]);
}
-
- void initragdoll(ragdolldata &d, skelcacheentry &sc, part *p)
- {
+ void initragdoll(ragdolldata &d, skelcacheentry &sc, part *p) {
const dualquat *bdata = sc.bdata;
- loopv(ragdoll->joints)
- {
+ loopv(ragdoll->joints) {
const ragdollskel::joint &j = ragdoll->joints[i];
const boneinfo &b = bones[j.bone];
const dualquat &q = bdata[b.interpindex];
- loopk(3) if(j.vert[k] >= 0)
- {
+ loopk(3) if(j.vert[k] >= 0) {
ragdollskel::vert &v = ragdoll->verts[j.vert[k]];
ragdolldata::vert &dv = d.verts[j.vert[k]];
dv.pos.add(q.transform(v.pos).mul(v.weight));
}
}
- if(ragdoll->animjoints) loopv(ragdoll->joints)
- {
+ if(ragdoll->animjoints) loopv(ragdoll->joints) {
const ragdollskel::joint &j = ragdoll->joints[i];
const boneinfo &b = bones[j.bone];
const dualquat &q = bdata[b.interpindex];
d.calcanimjoint(i, matrix4x3(q));
}
- loopv(ragdoll->verts)
- {
+ loopv(ragdoll->verts) {
ragdolldata::vert &dv = d.verts[i];
matrixstack[matrixpos].transform(vec(dv.pos).add(p->translate).mul(p->model->scale), dv.pos);
}
- loopv(ragdoll->reljoints)
- {
+ loopv(ragdoll->reljoints) {
const ragdollskel::reljoint &r = ragdoll->reljoints[i];
const ragdollskel::joint &j = ragdoll->joints[r.parent];
const boneinfo &br = bones[r.bone], &bj = bones[j.bone];
d.reljoints[i].mul(dualquat(bdata[bj.interpindex]).invert(), bdata[br.interpindex]);
}
}
-
- void genragdollbones(ragdolldata &d, skelcacheentry &sc, part *p)
- {
+ void genragdollbones(ragdolldata &d, skelcacheentry &sc, part *p) {
if(!sc.bdata) sc.bdata = new dualquat[numinterpbones];
sc.nextversion();
- loopv(ragdoll->joints)
- {
+ loopv(ragdoll->joints) {
const ragdollskel::joint &j = ragdoll->joints[i];
const boneinfo &b = bones[j.bone];
vec pos(0, 0, 0);
@@ -959,8 +732,7 @@ struct skelmodel : animmodel
m.mul(d.tris[j.tri], pos, d.animjoints ? d.animjoints[i] : j.orient);
sc.bdata[b.interpindex] = dualquat(m);
}
- loopv(ragdoll->reljoints)
- {
+ loopv(ragdoll->reljoints) {
const ragdollskel::reljoint &r = ragdoll->reljoints[i];
const ragdollskel::joint &j = ragdoll->joints[r.parent];
const boneinfo &br = bones[r.bone], &bj = bones[j.bone];
@@ -968,19 +740,14 @@ struct skelmodel : animmodel
}
loopv(antipodes) sc.bdata[antipodes[i].child].fixantipodal(sc.bdata[antipodes[i].parent]);
}
-
- void concattagtransform(part *p, int i, const matrix4x3 &m, matrix4x3 &n)
- {
+ void concattagtransform(part *p, int i, const matrix4x3 &m, matrix4x3 &n) {
matrix4x3 t;
t.mul(bones[tags[i].bone].base, tags[i].matrix);
t.posttranslate(p->translate, p->model->scale);
n.mul(m, t);
}
-
- void calctags(part *p, skelcacheentry *sc = NULL)
- {
- loopv(p->links)
- {
+ void calctags(part *p, skelcacheentry *sc = NULL) {
+ loopv(p->links) {
linkedpart &l = p->links[i];
tag &t = tags[l.tag];
dualquat q;
@@ -992,11 +759,8 @@ struct skelmodel : animmodel
l.matrix = m;
}
}
-
- void cleanup(bool full = true)
- {
- loopv(skelcache)
- {
+ void cleanup(bool full = true) {
+ loopv(skelcache) {
skelcacheentry &sc = skelcache[i];
loopj(MAXANIMPARTS) sc.as[j].cur.fr1 = -1;
DELETEA(sc.bdata);
@@ -1005,31 +769,22 @@ struct skelmodel : animmodel
blendoffsets.clear();
if(full) loopv(users) users[i]->cleanup();
}
-
bool canpreload() { return !numframes || gpuaccelerate(); }
-
- void preload()
- {
+ void preload() {
if(!numframes) return;
- if(skelcache.empty())
- {
+ if(skelcache.empty()) {
usegpuskel = gpuaccelerate();
}
}
-
- skelcacheentry &checkskelcache(part *p, const animstate *as, float pitch, const vec &axis, const vec &forward, ragdolldata *rdata)
- {
- if(skelcache.empty())
- {
+ skelcacheentry &checkskelcache(part *p, const animstate *as, float pitch, const vec &axis, const vec &forward, ragdolldata *rdata) {
+ if(skelcache.empty()) {
usegpuskel = gpuaccelerate();
}
-
int numanimparts = ((skelpart *)as->owner)->numanimparts;
uchar *partmask = ((skelpart *)as->owner)->partmask;
skelcacheentry *sc = NULL;
bool match = false;
- loopv(skelcache)
- {
+ loopv(skelcache) {
skelcacheentry &c = skelcache[i];
loopj(numanimparts) if(c.as[j]!=as[j]) goto mismatch;
if(c.pitch != pitch || c.partmask != partmask || c.ragdoll != rdata || (rdata && c.millis < rdata->lastmove)) goto mismatch;
@@ -1040,8 +795,7 @@ struct skelmodel : animmodel
if(c.millis < lastmillis) { sc = &c; break; }
}
if(!sc) sc = &skelcache.add();
- if(!match)
- {
+ if(!match) {
loopi(numanimparts) sc->as[i] = as[i];
sc->pitch = pitch;
sc->partmask = partmask;
@@ -1052,101 +806,73 @@ struct skelmodel : animmodel
sc->millis = lastmillis;
return *sc;
}
-
- int getblendoffset(UniformLoc &u)
- {
+ int getblendoffset(UniformLoc &u) {
int &offset = blendoffsets.access(Shader::lastshader->program, -1);
- if(offset < 0)
- {
+ if(offset < 0) {
defformatstring(offsetname, "%s[%d]", u.name, 2*numgpubones);
offset = glGetUniformLocation_(Shader::lastshader->program, offsetname);
}
return offset;
}
-
- void setglslbones(UniformLoc &u, skelcacheentry &sc, skelcacheentry &bc, int count)
- {
+ void setglslbones(UniformLoc &u, skelcacheentry &sc, skelcacheentry &bc, int count) {
if(u.version == bc.version && u.data == bc.bdata) return;
glUniform4fv_(u.loc, 2*numgpubones, sc.bdata[0].real.v);
- if(count > 0)
- {
+ if(count > 0) {
int offset = getblendoffset(u);
if(offset >= 0) glUniform4fv_(offset, 2*count, bc.bdata[0].real.v);
}
u.version = bc.version;
u.data = bc.bdata;
}
-
- void setgpubones(skelcacheentry &sc, blendcacheentry *bc, int count)
- {
+ void setgpubones(skelcacheentry &sc, blendcacheentry *bc, int count) {
if(!Shader::lastshader) return;
if(Shader::lastshader->uniformlocs.length() < 1) return;
UniformLoc &u = Shader::lastshader->uniformlocs[0];
setglslbones(u, sc, bc ? *bc : sc, count);
}
-
- bool shouldcleanup() const
- {
+ bool shouldcleanup() const {
return numframes && (skelcache.empty() || gpuaccelerate()!=usegpuskel);
}
};
-
- struct skelmeshgroup : meshgroup
- {
+ struct skelmeshgroup : meshgroup {
skeleton *skel;
-
vector<blendcombo> blendcombos;
int numblends[4];
-
static const int MAXBLENDCACHE = 16;
blendcacheentry blendcache[MAXBLENDCACHE];
-
static const int MAXVBOCACHE = 16;
vbocacheentry vbocache[MAXVBOCACHE];
-
ushort *edata;
GLuint ebuf;
bool vtangents;
int vlen, vertsize, vblends, vweights;
uchar *vdata;
-
- skelmeshgroup() : skel(NULL), edata(NULL), ebuf(0), vtangents(false), vlen(0), vertsize(0), vblends(0), vweights(0), vdata(NULL)
- {
+ skelmeshgroup() : skel(NULL), edata(NULL), ebuf(0), vtangents(false), vlen(0), vertsize(0), vblends(0), vweights(0), vdata(NULL) {
memset(numblends, 0, sizeof(numblends));
}
-
- virtual ~skelmeshgroup()
- {
- if(skel)
- {
+ virtual ~skelmeshgroup() {
+ if(skel) {
if(skel->shared) skel->users.removeobj(this);
else DELETEP(skel);
}
if(ebuf) glDeleteBuffers_(1, &ebuf);
- loopi(MAXBLENDCACHE)
- {
+ loopi(MAXBLENDCACHE) {
DELETEA(blendcache[i].bdata);
}
- loopi(MAXVBOCACHE)
- {
+ loopi(MAXVBOCACHE) {
if(vbocache[i].vbuf) glDeleteBuffers_(1, &vbocache[i].vbuf);
}
DELETEA(vdata);
}
-
- void shareskeleton(char *name)
- {
- if(!name)
- {
+ void shareskeleton(char *name) {
+ if(!name) {
skel = new skeleton;
skel->users.add(this);
return;
}
-
static hashnameset<skeleton *> skeletons;
if(skeletons.access(name)) skel = skeletons[name];
- else
- {
+ else {
skel = new skeleton;
skel->name = newstring(name);
skeletons.add(skel);
@@ -1154,38 +880,26 @@ struct skelmodel : animmodel
skel->users.add(this);
skel->shared++;
}
-
- int findtag(const char *name)
- {
+ int findtag(const char *name) {
return skel->findtag(name);
}
-
void *animkey() { return skel; }
int totalframes() const { return max(skel->numframes, 1); }
-
virtual skelanimspec *loadanim(const char *filename) { (void) filename; return NULL; }
-
- void genvbo(bool tangents, vbocacheentry &vc)
- {
+ void genvbo(bool tangents, vbocacheentry &vc) {
if(!vc.vbuf) glGenBuffers_(1, &vc.vbuf);
if(ebuf) return;
-
vector<ushort> idxs;
-
if(tangents) loopv(meshes) ((skelmesh *)meshes[i])->calctangents();
-
vtangents = tangents;
vlen = 0;
vblends = 0;
- if(skel->numframes && !skel->usegpuskel)
- {
+ if(skel->numframes && !skel->usegpuskel) {
vweights = 1;
- loopv(blendcombos)
- {
+ loopv(blendcombos) {
blendcombo &c = blendcombos[i];
c.interpindex = c.weights[1] ? skel->numgpubones + vblends++ : -1;
}
-
vertsize = tangents ? sizeof(vvertbump) : sizeof(vvertn);
loopv(meshes) vlen += ((skelmesh *)meshes[i])->genvbo(idxs, vlen);
DELETEA(vdata);
@@ -1197,25 +911,20 @@ struct skelmodel : animmodel
else FILLVDATA(vvertn);
#undef FILLVDATA
}
- else
- {
- if(skel->numframes)
- {
+ else {
+ if(skel->numframes) {
vweights = 4;
int availbones = skel->availgpubones() - skel->numgpubones;
while(vweights > 1 && availbones >= numblends[vweights-1]) availbones -= numblends[--vweights];
- loopv(blendcombos)
- {
+ loopv(blendcombos) {
blendcombo &c = blendcombos[i];
c.interpindex = c.size() > vweights ? skel->numgpubones + vblends++ : -1;
}
}
- else
- {
+ else {
vweights = 0;
loopv(blendcombos) blendcombos[i].interpindex = -1;
}
-
gle::bindvbo(vc.vbuf);
#define GENVBO(type, args) do { \
vertsize = sizeof(type); \
@@ -1225,13 +934,11 @@ struct skelmodel : animmodel
} while(0)
#define GENVBOANIM(type) GENVBO(type, (idxs, vlen, vverts))
#define GENVBOSTAT(type) GENVBO(type, (idxs, vlen, vverts, htdata, htlen))
- if(skel->numframes)
- {
+ if(skel->numframes) {
if(tangents) GENVBOANIM(vvertbumpw);
else GENVBOANIM(vvertnw);
}
- else
- {
+ else {
int numverts = 0, htlen = 128;
loopv(meshes) numverts += ((skelmesh *)meshes[i])->numverts;
while(htlen < numverts) htlen *= 2;
@@ -1247,68 +954,51 @@ struct skelmodel : animmodel
#undef GENVBOSTAT
gle::clearvbo();
}
-
glGenBuffers_(1, &ebuf);
gle::bindebo(ebuf);
glBufferData_(GL_ELEMENT_ARRAY_BUFFER, idxs.length()*sizeof(ushort), idxs.getbuf(), GL_STATIC_DRAW);
gle::clearebo();
}
-
- void bindvbo(const animstate *as, vbocacheentry &vc, skelcacheentry *sc = NULL, blendcacheentry *bc = NULL)
- {
+ void bindvbo(const animstate *as, vbocacheentry &vc, skelcacheentry *sc = NULL, blendcacheentry *bc = NULL) {
vvert *vverts = 0;
bindpos(ebuf, vc.vbuf, &vverts->pos, vertsize);
- if(as->cur.anim&ANIM_NOSKIN)
- {
+ if(as->cur.anim&ANIM_NOSKIN) {
if(enabletc) disabletc();
if(enablenormals) disablenormals();
if(enabletangents) disabletangents();
}
- else
- {
- if(vtangents)
- {
+ else {
+ if(vtangents) {
if(enablenormals) disablenormals();
vvertbump *vvertbumps = 0;
bindtangents(&vvertbumps->tangent, vertsize);
}
- else
- {
+ else {
if(enabletangents) disabletangents();
vvertn *vvertns = 0;
bindnormals(&vvertns->norm, vertsize);
}
-
bindtc(&vverts->tc, vertsize);
}
- if(!sc || !skel->usegpuskel)
- {
+ if(!sc || !skel->usegpuskel) {
if(enablebones) disablebones();
}
- else
- {
- if(vtangents)
- {
+ else {
+ if(vtangents) {
vvertbumpw *vvertbumpws = 0;
bindbones(vvertbumpws->weights, vvertbumpws->bones, vertsize);
}
- else
- {
+ else {
vvertnw *vvertnws = 0;
bindbones(vvertnws->weights, vvertnws->bones, vertsize);
}
}
}
-
- void concattagtransform(part *p, int i, const matrix4x3 &m, matrix4x3 &n)
- {
+ void concattagtransform(part *p, int i, const matrix4x3 &m, matrix4x3 &n) {
skel->concattagtransform(p, i, m, n);
}
-
- int addblendcombo(const blendcombo &c)
- {
- loopv(blendcombos) if(blendcombos[i]==c)
- {
+ int addblendcombo(const blendcombo &c) {
+ loopv(blendcombos) if(blendcombos[i]==c) {
blendcombos[i].uses += c.uses;
return i;
}
@@ -1316,50 +1006,38 @@ struct skelmodel : animmodel
blendcombo &a = blendcombos.add(c);
return a.interpindex = blendcombos.length()-1;
}
-
- void sortblendcombos()
- {
+ void sortblendcombos() {
blendcombos.sort(blendcombo::sortcmp);
int *remap = new int[blendcombos.length()];
loopv(blendcombos) remap[blendcombos[i].interpindex] = i;
- loopv(meshes)
- {
+ loopv(meshes) {
skelmesh *m = (skelmesh *)meshes[i];
- loopj(m->numverts)
- {
+ loopj(m->numverts) {
vert &v = m->verts[j];
v.blend = remap[v.blend];
}
}
delete[] remap;
}
-
- int remapblend(int blend)
- {
+ int remapblend(int blend) {
const blendcombo &c = blendcombos[blend];
return c.weights[1] ? c.interpindex : c.interpbones[0];
}
-
- static inline void blendbones(dualquat &d, const dualquat *bdata, const blendcombo &c)
- {
+ static inline void blendbones(dualquat &d, const dualquat *bdata, const blendcombo &c) {
d = bdata[c.interpbones[0]];
d.mul(c.weights[0]);
d.accumulate(bdata[c.interpbones[1]], c.weights[1]);
- if(c.weights[2])
- {
+ if(c.weights[2]) {
d.accumulate(bdata[c.interpbones[2]], c.weights[2]);
if(c.weights[3]) d.accumulate(bdata[c.interpbones[3]], c.weights[3]);
}
}
-
- void blendbones(const skelcacheentry &sc, blendcacheentry &bc)
- {
+ void blendbones(const skelcacheentry &sc, blendcacheentry &bc) {
bc.nextversion();
if(!bc.bdata) bc.bdata = new dualquat[vblends];
dualquat *dst = bc.bdata - skel->numgpubones;
bool normalize = !skel->usegpuskel || vweights<=1;
- loopv(blendcombos)
- {
+ loopv(blendcombos) {
const blendcombo &c = blendcombos[i];
if(c.interpindex<0) break;
dualquat &d = dst[c.interpindex];
@@ -1367,17 +1045,13 @@ struct skelmodel : animmodel
if(normalize) d.normalize();
}
}
-
- void cleanup()
- {
- loopi(MAXBLENDCACHE)
- {
+ void cleanup() {
+ loopi(MAXBLENDCACHE) {
blendcacheentry &c = blendcache[i];
DELETEA(c.bdata);
c.owner = -1;
}
- loopi(MAXVBOCACHE)
- {
+ loopi(MAXVBOCACHE) {
vbocacheentry &c = vbocache[i];
if(c.vbuf) { glDeleteBuffers_(1, &c.vbuf); c.vbuf = 0; }
c.owner = -1;
@@ -1385,38 +1059,31 @@ struct skelmodel : animmodel
if(ebuf) { glDeleteBuffers_(1, &ebuf); ebuf = 0; }
if(skel) skel->cleanup(false);
}
-
#define SEARCHCACHE(cachesize, cacheentry, cache, reusecheck) \
- loopi(cachesize) \
- { \
+ loopi(cachesize) { \
+ \
cacheentry &c = cache[i]; \
- if(c.owner==owner) \
- { \
+ if(c.owner==owner) { \
+ \
if(c==sc) return c; \
else c.owner = -1; \
break; \
} \
} \
- loopi(cachesize-1) \
- { \
+ loopi(cachesize-1) { \
+ \
cacheentry &c = cache[i]; \
if(reusecheck c.owner < 0 || c.millis < lastmillis) \
return c; \
} \
return cache[cachesize-1];
-
- vbocacheentry &checkvbocache(skelcacheentry &sc, int owner)
- {
+ vbocacheentry &checkvbocache(skelcacheentry &sc, int owner) {
SEARCHCACHE(MAXVBOCACHE, vbocacheentry, vbocache, !c.vbuf || );
}
-
- blendcacheentry &checkblendcache(skelcacheentry &sc, int owner)
- {
+ blendcacheentry &checkblendcache(skelcacheentry &sc, int owner) {
SEARCHCACHE(MAXBLENDCACHE, blendcacheentry, blendcache, )
}
-
- void preload(part *p)
- {
+ void preload(part *p) {
if(!skel->canpreload()) return;
bool tangents = false;
loopv(p->skins) if(p->skins[i].tangents()) tangents = true;
@@ -1425,22 +1092,16 @@ struct skelmodel : animmodel
skel->preload();
if(!vbocache->vbuf) genvbo(tangents, *vbocache);
}
-
- void render(const animstate *as, float pitch, const vec &axis, const vec &forward, dynent *d, part *p)
- {
+ void render(const animstate *as, float pitch, const vec &axis, const vec &forward, dynent *d, part *p) {
bool tangents = false;
loopv(p->skins) if(p->skins[i].tangents()) tangents = true;
if(skel->shouldcleanup()) { skel->cleanup(); disablevbo(); }
else if(tangents!=vtangents) { cleanup(); disablevbo(); }
-
- if(!skel->numframes)
- {
- if(!(as->cur.anim&ANIM_NORENDER))
- {
+ if(!skel->numframes) {
+ if(!(as->cur.anim&ANIM_NORENDER)) {
if(!vbocache->vbuf) genvbo(tangents, *vbocache);
bindvbo(as, *vbocache);
- loopv(meshes)
- {
+ loopv(meshes) {
skelmesh *m = (skelmesh *)meshes[i];
p->skins[i].bind(m, as);
m->render(as, p->skins[i], *vbocache);
@@ -1449,153 +1110,110 @@ struct skelmodel : animmodel
skel->calctags(p);
return;
}
-
skelcacheentry &sc = skel->checkskelcache(p, as, pitch, axis, forward, as->cur.anim&ANIM_RAGDOLL || !d || !d->ragdoll || d->ragdoll->skel != skel->ragdoll ? NULL : d->ragdoll);
- if(!(as->cur.anim&ANIM_NORENDER))
- {
+ if(!(as->cur.anim&ANIM_NORENDER)) {
int owner = &sc-&skel->skelcache[0];
vbocacheentry &vc = skel->usegpuskel ? *vbocache : checkvbocache(sc, owner);
vc.millis = lastmillis;
if(!vc.vbuf) genvbo(tangents, vc);
blendcacheentry *bc = NULL;
- if(vblends)
- {
+ if(vblends) {
bc = &checkblendcache(sc, owner);
bc->millis = lastmillis;
- if(bc->owner!=owner)
- {
+ if(bc->owner!=owner) {
bc->owner = owner;
*(animcacheentry *)bc = sc;
blendbones(sc, *bc);
}
}
- if(!skel->usegpuskel && vc.owner!=owner)
- {
+ if(!skel->usegpuskel && vc.owner!=owner) {
vc.owner = owner;
(animcacheentry &)vc = sc;
- loopv(meshes)
- {
+ loopv(meshes) {
skelmesh &m = *(skelmesh *)meshes[i];
m.interpverts(sc.bdata, bc ? bc->bdata : NULL, tangents, vdata + m.voffset*vertsize, p->skins[i]);
}
gle::bindvbo(vc.vbuf);
glBufferData_(GL_ARRAY_BUFFER, vlen*vertsize, vdata, GL_STREAM_DRAW);
}
-
bindvbo(as, vc, &sc, bc);
- loopv(meshes)
- {
+ loopv(meshes) {
skelmesh *m = (skelmesh *)meshes[i];
p->skins[i].bind(m, as);
if(skel->usegpuskel) skel->setgpubones(sc, bc, vblends);
m->render(as, p->skins[i], vc);
}
}
-
skel->calctags(p, &sc);
-
- if(as->cur.anim&ANIM_RAGDOLL && skel->ragdoll && !d->ragdoll)
- {
+ if(as->cur.anim&ANIM_RAGDOLL && skel->ragdoll && !d->ragdoll) {
d->ragdoll = new ragdolldata(skel->ragdoll, p->model->scale);
skel->initragdoll(*d->ragdoll, sc, p);
d->ragdoll->init(d);
}
}
};
-
- struct animpartmask
- {
+ struct animpartmask {
animpartmask *next;
int numbones;
uchar bones[1];
};
-
- struct skelpart : part
- {
+ struct skelpart : part {
animpartmask *buildingpartmask;
-
uchar *partmask;
-
- skelpart(animmodel *model, int index = 0) : part(model, index), buildingpartmask(NULL), partmask(NULL)
- {
+ skelpart(animmodel *model, int index = 0) : part(model, index), buildingpartmask(NULL), partmask(NULL) {
}
-
- virtual ~skelpart()
- {
+ virtual ~skelpart() {
DELETEA(buildingpartmask);
}
-
- uchar *sharepartmask(animpartmask *o)
- {
+ uchar *sharepartmask(animpartmask *o) {
static animpartmask *partmasks = NULL;
animpartmask *p = partmasks;
- for(; p; p = p->next) if(p->numbones==o->numbones && !memcmp(p->bones, o->bones, p->numbones))
- {
+ for(; p; p = p->next) if(p->numbones==o->numbones && !memcmp(p->bones, o->bones, p->numbones)) {
delete[] (uchar *)o;
return p->bones;
}
-
o->next = p;
partmasks = o;
return o->bones;
}
-
- animpartmask *newpartmask()
- {
+ animpartmask *newpartmask() {
animpartmask *p = (animpartmask *)new uchar[sizeof(animpartmask) + ((skelmeshgroup *)meshes)->skel->numbones-1];
p->numbones = ((skelmeshgroup *)meshes)->skel->numbones;
memset(p->bones, 0, p->numbones);
return p;
}
-
- void initanimparts()
- {
+ void initanimparts() {
DELETEA(buildingpartmask);
buildingpartmask = newpartmask();
}
-
- bool addanimpart(ushort *bonemask)
- {
+ bool addanimpart(ushort *bonemask) {
if(!buildingpartmask || numanimparts>=MAXANIMPARTS) return false;
((skelmeshgroup *)meshes)->skel->applybonemask(bonemask, buildingpartmask->bones, numanimparts);
numanimparts++;
return true;
}
-
- void endanimparts()
- {
- if(buildingpartmask)
- {
+ void endanimparts() {
+ if(buildingpartmask) {
partmask = sharepartmask(buildingpartmask);
buildingpartmask = NULL;
}
-
((skelmeshgroup *)meshes)->skel->optimize();
}
-
- void loaded()
- {
+ void loaded() {
endanimparts();
part::loaded();
}
};
-
- skelmodel(const char *name) : animmodel(name)
- {
+ skelmodel(const char *name) : animmodel(name) {
}
-
- int linktype(animmodel *m) const
- {
+ int linktype(animmodel *m) const {
return type()==m->type() &&
((skelmeshgroup *)parts[0]->meshes)->skel == ((skelmeshgroup *)m->parts[0]->meshes)->skel ?
LINK_REUSE :
LINK_TAG;
}
-
bool skeletal() const { return true; }
-
- skelpart &addpart()
- {
+ skelpart &addpart() {
flushpart();
skelpart *p = new skelpart(this, parts.length());
parts.add(p);
@@ -1603,15 +1221,11 @@ struct skelmodel : animmodel
}
};
-struct skeladjustment
-{
+struct skeladjustment {
float yaw, pitch, roll;
vec translate;
-
skeladjustment(float yaw, float pitch, float roll, const vec &translate) : yaw(yaw), pitch(pitch), roll(roll), translate(translate) {}
-
- void adjust(dualquat &dq)
- {
+ void adjust(dualquat &dq) {
if(yaw) dq.mulorient(quat(vec(0, 0, 1), yaw*RAD));
if(pitch) dq.mulorient(quat(vec(0, -1, 0), pitch*RAD));
if(roll) dq.mulorient(quat(vec(-1, 0, 0), roll*RAD));
@@ -1619,22 +1233,17 @@ struct skeladjustment
}
};
-template<class MDL> struct skelloader : modelloader<MDL, skelmodel>
-{
+template<class MDL> struct skelloader : modelloader<MDL, skelmodel> {
static vector<skeladjustment> adjustments;
-
skelloader(const char *name) : modelloader<MDL, skelmodel>(name) {}
-
- void flushpart()
- {
+ void flushpart() {
adjustments.setsize(0);
}
};
template<class MDL> vector<skeladjustment> skelloader<MDL>::adjustments;
-template<class MDL> struct skelcommands : modelcommands<MDL, struct MDL::skelmesh>
-{
+template<class MDL> struct skelcommands : modelcommands<MDL, struct MDL::skelmesh> {
typedef modelcommands<MDL, struct MDL::skelmesh> commands;
typedef struct MDL::skeleton skeleton;
typedef struct MDL::skelmeshgroup meshgroup;
@@ -1645,29 +1254,23 @@ template<class MDL> struct skelcommands : modelcommands<MDL, struct MDL::skelmes
typedef struct MDL::pitchdep pitchdep;
typedef struct MDL::pitchtarget pitchtarget;
typedef struct MDL::pitchcorrect pitchcorrect;
-
- static void loadpart(char *meshfile, char *skelname, float *smooth)
- {
+ static void loadpart(char *meshfile, char *skelname, float *smooth) {
if(!MDL::loading) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
defformatstring(filename, "%s/%s", MDL::dir, meshfile);
part &mdl = MDL::loading->addpart();
mdl.pitchscale = mdl.pitchoffset = mdl.pitchmin = mdl.pitchmax = 0;
mdl.meshes = MDL::loading->sharemeshes(path(filename), skelname[0] ? skelname : NULL, double(*smooth > 0 ? cos(clamp(*smooth, 0.0f, 180.0f)*RAD) : 2));
if(!mdl.meshes) conoutf(CON_ERROR, "could not load %s", filename);
- else
- {
+ else {
mdl.initanimparts();
mdl.initskins();
}
}
-
- static void settag(char *name, char *tagname, float *tx, float *ty, float *tz, float *rx, float *ry, float *rz)
- {
+ static void settag(char *name, char *tagname, float *tx, float *ty, float *tz, float *rx, float *ry, float *rz) {
if(!MDL::loading || MDL::loading->parts.empty()) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
part &mdl = *(part *)MDL::loading->parts.last();
int i = mdl.meshes ? ((meshgroup *)mdl.meshes)->skel->findbone(name) : -1;
- if(i >= 0)
- {
+ if(i >= 0) {
float cx = *rx ? cosf(*rx/2*RAD) : 1, sx = *rx ? sinf(*rx/2*RAD) : 0,
cy = *ry ? cosf(*ry/2*RAD) : 1, sy = *ry ? sinf(*ry/2*RAD) : 0,
cz = *rz ? cosf(*rz/2*RAD) : 1, sz = *rz ? sinf(*rz/2*RAD) : 0;
@@ -1678,27 +1281,20 @@ template<class MDL> struct skelcommands : modelcommands<MDL, struct MDL::skelmes
}
conoutf(CON_ERROR, "could not find bone %s for tag %s", name, tagname);
}
-
- static void setpitch(char *name, float *pitchscale, float *pitchoffset, float *pitchmin, float *pitchmax)
- {
+ static void setpitch(char *name, float *pitchscale, float *pitchoffset, float *pitchmin, float *pitchmax) {
if(!MDL::loading || MDL::loading->parts.empty()) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
part &mdl = *(part *)MDL::loading->parts.last();
-
- if(name[0])
- {
+ if(name[0]) {
int i = mdl.meshes ? ((meshgroup *)mdl.meshes)->skel->findbone(name) : -1;
- if(i>=0)
- {
+ if(i>=0) {
boneinfo &b = ((meshgroup *)mdl.meshes)->skel->bones[i];
b.pitchscale = *pitchscale;
b.pitchoffset = *pitchoffset;
- if(*pitchmin || *pitchmax)
- {
+ if(*pitchmin || *pitchmax) {
b.pitchmin = *pitchmin;
b.pitchmax = *pitchmax;
}
- else
- {
+ else {
b.pitchmin = -360*fabs(b.pitchscale) + b.pitchoffset;
b.pitchmax = 360*fabs(b.pitchscale) + b.pitchoffset;
}
@@ -1707,23 +1303,18 @@ template<class MDL> struct skelcommands : modelcommands<MDL, struct MDL::skelmes
conoutf(CON_ERROR, "could not find bone %s to pitch", name);
return;
}
-
mdl.pitchscale = *pitchscale;
mdl.pitchoffset = *pitchoffset;
- if(*pitchmin || *pitchmax)
- {
+ if(*pitchmin || *pitchmax) {
mdl.pitchmin = *pitchmin;
mdl.pitchmax = *pitchmax;
}
- else
- {
+ else {
mdl.pitchmin = -360*fabs(mdl.pitchscale) + mdl.pitchoffset;
mdl.pitchmax = 360*fabs(mdl.pitchscale) + mdl.pitchoffset;
}
}
-
- static void setpitchtarget(char *name, char *animfile, int *frameoffset, float *pitchmin, float *pitchmax)
- {
+ static void setpitchtarget(char *name, char *animfile, int *frameoffset, float *pitchmin, float *pitchmax) {
if(!MDL::loading || MDL::loading->parts.empty()) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
part &mdl = *(part *)MDL::loading->parts.last();
if(!mdl.meshes) return;
@@ -1732,8 +1323,7 @@ template<class MDL> struct skelcommands : modelcommands<MDL, struct MDL::skelmes
if(!sa) { conoutf(CON_ERROR, "could not load %s anim file %s", MDL::formatname(), filename); return; }
skeleton *skel = ((meshgroup *)mdl.meshes)->skel;
int bone = skel ? skel->findbone(name) : -1;
- if(bone < 0)
- {
+ if(bone < 0) {
conoutf(CON_ERROR, "could not find bone %s to pitch target", name);
return;
}
@@ -1744,24 +1334,20 @@ template<class MDL> struct skelcommands : modelcommands<MDL, struct MDL::skelmes
t.pitchmin = *pitchmin;
t.pitchmax = *pitchmax;
}
-
- static void setpitchcorrect(char *name, char *targetname, float *scale, float *pitchmin, float *pitchmax)
- {
+ static void setpitchcorrect(char *name, char *targetname, float *scale, float *pitchmin, float *pitchmax) {
if(!MDL::loading || MDL::loading->parts.empty()) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
part &mdl = *(part *)MDL::loading->parts.last();
if(!mdl.meshes) return;
skeleton *skel = ((meshgroup *)mdl.meshes)->skel;
int bone = skel ? skel->findbone(name) : -1;
- if(bone < 0)
- {
+ if(bone < 0) {
conoutf(CON_ERROR, "could not find bone %s to pitch correct", name);
return;
}
if(skel->findpitchcorrect(bone) >= 0) return;
int targetbone = skel->findbone(targetname), target = -1;
if(targetbone >= 0) loopv(skel->pitchtargets) if(skel->pitchtargets[i].bone == targetbone) { target = i; break; }
- if(target < 0)
- {
+ if(target < 0) {
conoutf(CON_ERROR, "could not find pitch target %s to pitch correct %s", targetname, name);
return;
}
@@ -1775,23 +1361,18 @@ template<class MDL> struct skelcommands : modelcommands<MDL, struct MDL::skelmes
loopv(skel->pitchcorrects) if(bone <= skel->pitchcorrects[i].bone) { pos = i; break; }
skel->pitchcorrects.insert(pos, c);
}
-
- static void setanim(char *anim, char *animfile, float *speed, int *priority, int *startoffset, int *endoffset)
- {
+ static void setanim(char *anim, char *animfile, float *speed, int *priority, int *startoffset, int *endoffset) {
if(!MDL::loading || MDL::loading->parts.empty()) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
-
vector<int> anims;
findanims(anim, anims);
if(anims.empty()) conoutf(CON_ERROR, "could not find animation %s", anim);
- else
- {
+ else {
part *p = (part *)MDL::loading->parts.last();
if(!p->meshes) return;
defformatstring(filename, "%s/%s", MDL::dir, animfile);
animspec *sa = ((meshgroup *)p->meshes)->loadanim(path(filename));
if(!sa) conoutf(CON_ERROR, "could not load %s anim file %s", MDL::formatname(), filename);
- else loopv(anims)
- {
+ else loopv(anims) {
int start = sa->frame, end = sa->range;
if(*startoffset > 0) start += min(*startoffset, end-1);
else if(*startoffset < 0) start += max(end + *startoffset, 0);
@@ -1802,18 +1383,13 @@ template<class MDL> struct skelcommands : modelcommands<MDL, struct MDL::skelmes
}
}
}
-
- static void setanimpart(char *maskstr)
- {
+ static void setanimpart(char *maskstr) {
if(!MDL::loading || MDL::loading->parts.empty()) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
-
part *p = (part *)MDL::loading->parts.last();
-
vector<char *> bonestrs;
explodelist(maskstr, bonestrs);
vector<ushort> bonemask;
- loopv(bonestrs)
- {
+ loopv(bonestrs) {
char *bonestr = bonestrs[i];
int bone = p->meshes ? ((meshgroup *)p->meshes)->skel->findbone(bonestr[0]=='!' ? bonestr+1 : bonestr) : -1;
if(bone<0) { conoutf(CON_ERROR, "could not find bone %s for anim part mask [%s]", bonestr, maskstr); bonestrs.deletearrays(); return; }
@@ -1822,31 +1398,24 @@ template<class MDL> struct skelcommands : modelcommands<MDL, struct MDL::skelmes
bonestrs.deletearrays();
bonemask.sort();
if(bonemask.length()) bonemask.add(BONEMASK_END);
-
if(!p->addanimpart(bonemask.getbuf())) conoutf(CON_ERROR, "too many animation parts");
}
-
- static void setadjust(char *name, float *yaw, float *pitch, float *roll, float *tx, float *ty, float *tz)
- {
+ static void setadjust(char *name, float *yaw, float *pitch, float *roll, float *tx, float *ty, float *tz) {
if(!MDL::loading || MDL::loading->parts.empty()) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
part &mdl = *(part *)MDL::loading->parts.last();
-
if(!name[0]) return;
int i = mdl.meshes ? ((meshgroup *)mdl.meshes)->skel->findbone(name) : -1;
if(i < 0) { conoutf(CON_ERROR, "could not find bone %s to adjust", name); return; }
while(!MDL::adjustments.inrange(i)) MDL::adjustments.add(skeladjustment(0, 0, 0, vec(0, 0, 0)));
MDL::adjustments[i] = skeladjustment(*yaw, *pitch, *roll, vec(*tx/4, *ty/4, *tz/4));
}
-
- skelcommands()
- {
+ skelcommands() {
if(MDL::multiparted()) this->modelcommand(loadpart, "load", "ssf");
this->modelcommand(settag, "tag", "ssffffff");
this->modelcommand(setpitch, "pitch", "sffff");
this->modelcommand(setpitchtarget, "pitchtarget", "ssiff");
this->modelcommand(setpitchcorrect, "pitchcorrect", "ssfff");
- if(MDL::animated())
- {
+ if(MDL::animated()) {
this->modelcommand(setanim, "anim", "ssfiii");
this->modelcommand(setanimpart, "animpart", "s");
this->modelcommand(setadjust, "adjust", "sffffff");
diff --git a/src/engine/sound.cpp b/src/engine/sound.cpp
index d10386d..62cab3e 100644
--- a/src/engine/sound.cpp
+++ b/src/engine/sound.cpp
@@ -5,44 +5,34 @@
bool nosound = true;
-struct soundsample
-{
+struct soundsample {
char *name;
Mix_Chunk *chunk;
-
soundsample() : name(NULL), chunk(NULL) {}
~soundsample() { DELETEA(name); }
-
void cleanup() { if(chunk) { Mix_FreeChunk(chunk); chunk = NULL; } }
bool load(bool msg = false);
};
-struct soundslot
-{
+struct soundslot {
soundsample *sample;
int volume;
};
-struct soundconfig
-{
+struct soundconfig {
int slots, numslots;
int maxuses;
-
- bool hasslot(const soundslot *p, const vector<soundslot> &v) const
- {
+ bool hasslot(const soundslot *p, const vector<soundslot> &v) const {
return p >= v.getbuf() + slots && p < v.getbuf() + slots+numslots && slots+numslots < v.length();
}
-
- int chooseslot(int flags) const
- {
+ int chooseslot(int flags) const {
if(flags&SND_NO_ALT || numslots <= 1) return slots;
if(flags&SND_USE_ALT) return slots + 1 + rnd(numslots - 1);
return slots + rnd(numslots);
}
};
-struct soundchannel
-{
+struct soundchannel {
int id;
bool inuse;
vec loc;
@@ -50,14 +40,10 @@ struct soundchannel
extentity *ent;
int radius, volume, pan, flags;
bool dirty;
-
soundchannel(int id) : id(id) { reset(); }
-
bool hasloc() const { return loc.x >= -1e15f; }
void clearloc() { loc = vec(-1e16f, -1e16f, -1e16f); }
-
- void reset()
- {
+ void reset() {
inuse = false;
clearloc();
slot = NULL;
@@ -72,10 +58,8 @@ struct soundchannel
vector<soundchannel> channels;
int maxchannels = 0;
-soundchannel &newchannel(int n, soundslot *slot, const vec *loc = NULL, extentity *ent = NULL, int flags = 0, int radius = 0)
-{
- if(ent)
- {
+soundchannel &newchannel(int n, soundslot *slot, const vec *loc = NULL, extentity *ent = NULL, int flags = 0, int radius = 0) {
+ if(ent) {
loc = &ent->o;
ent->flags |= EF_SOUND;
}
@@ -91,26 +75,22 @@ soundchannel &newchannel(int n, soundslot *slot, const vec *loc = NULL, extentit
return chan;
}
-void freechannel(int n)
-{
+void freechannel(int n) {
if(!channels.inrange(n) || !channels[n].inuse) return;
soundchannel &chan = channels[n];
chan.inuse = false;
if(chan.ent) chan.ent->flags &= ~EF_SOUND;
}
-void syncchannel(soundchannel &chan)
-{
+void syncchannel(soundchannel &chan) {
if(!chan.dirty) return;
if(!Mix_FadingChannel(chan.id)) Mix_Volume(chan.id, chan.volume);
Mix_SetPanning(chan.id, 255-chan.pan, chan.pan);
chan.dirty = false;
}
-void stopchannels()
-{
- loopv(channels)
- {
+void stopchannels() {
+ loopv(channels) {
soundchannel &chan = channels[i];
if(!chan.inuse) continue;
Mix_HaltChannel(i);
@@ -121,8 +101,7 @@ void stopchannels()
void setmusicvol(int musicvol);
extern int musicvol;
static int curvol = 0;
-VARFP(soundvol, 0, 255, 255,
-{
+VARFP(soundvol, 0, 255, 255, {
if(!soundvol) { stopchannels(); setmusicvol(0); }
else if(!curvol) setmusicvol(musicvol);
curvol = soundvol;
@@ -135,19 +114,16 @@ Mix_Music *music = NULL;
SDL_RWops *musicrw = NULL;
stream *musicstream = NULL;
-void setmusicvol(int musicvol)
-{
+void setmusicvol(int musicvol) {
if(nosound) return;
if(music) Mix_VolumeMusic((musicvol*MIX_MAX_VOLUME)/255);
}
-void stopmusic()
-{
+void stopmusic() {
if(nosound) return;
DELETEA(musicfile);
DELETEA(musicdonecmd);
- if(music)
- {
+ if(music) {
Mix_HaltMusic();
Mix_FreeMusic(music);
music = NULL;
@@ -163,34 +139,28 @@ VARF(soundchans, 1, 32, 128, initwarning("sound configuration", INIT_RESET, CHAN
VARF(soundfreq, 0, MIX_DEFAULT_FREQUENCY, 48000, initwarning("sound configuration", INIT_RESET, CHANGE_SOUND));
VARF(soundbufferlen, 128, 1024, 4096, initwarning("sound configuration", INIT_RESET, CHANGE_SOUND));
-bool initaudio()
-{
+bool initaudio() {
static string fallback = "";
static bool initfallback = true;
static bool restorefallback = false;
- if(initfallback)
- {
+ if(initfallback) {
initfallback = false;
if(char *env = SDL_getenv("SDL_AUDIODRIVER")) copystring(fallback, env);
}
- if(!fallback[0] && audiodriver[0])
- {
+ if(!fallback[0] && audiodriver[0]) {
vector<char*> drivers;
explodelist(audiodriver, drivers);
- loopv(drivers)
- {
+ loopv(drivers) {
restorefallback = true;
SDL_setenv("SDL_AUDIODRIVER", drivers[i], 1);
- if(SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0)
- {
+ if(SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0) {
drivers.deletearrays();
return true;
}
}
drivers.deletearrays();
}
- if(restorefallback)
- {
+ if(restorefallback) {
restorefallback = false;
unsetenv("SDL_AUDIODRIVER");
}
@@ -199,30 +169,23 @@ bool initaudio()
return false;
}
-void initsound()
-{
+void initsound() {
SDL_version version;
SDL_GetVersion(&version);
- if(version.major == 2 && version.minor == 0 && version.patch == 6)
- {
+ if(version.major == 2 && version.minor == 0 && version.patch == 6) {
nosound = true;
if(usesound) conoutf(CON_ERROR, "audio is broken in SDL 2.0.6");
return;
}
-
- if(shouldinitaudio)
- {
+ if(shouldinitaudio) {
shouldinitaudio = false;
if(SDL_WasInit(SDL_INIT_AUDIO)) SDL_QuitSubSystem(SDL_INIT_AUDIO);
- if(!usesound || !initaudio())
- {
+ if(!usesound || !initaudio()) {
nosound = true;
return;
}
}
-
- if(Mix_OpenAudio(soundfreq, MIX_DEFAULT_FORMAT, 2, soundbufferlen)<0)
- {
+ if(Mix_OpenAudio(soundfreq, MIX_DEFAULT_FORMAT, 2, soundbufferlen)<0) {
nosound = true;
conoutf(CON_ERROR, "sound init failed (SDL_mixer): %s", Mix_GetError());
return;
@@ -232,8 +195,7 @@ void initsound()
nosound = false;
}
-void musicdone()
-{
+void musicdone() {
if(music) { Mix_HaltMusic(); Mix_FreeMusic(music); music = NULL; }
if(musicrw) { SDL_FreeRW(musicrw); musicrw = NULL; }
DELETEP(musicstream);
@@ -245,34 +207,28 @@ void musicdone()
delete[] cmd;
}
-Mix_Music *loadmusic(const char *name)
-{
+Mix_Music *loadmusic(const char *name) {
if(!musicstream) musicstream = openzipfile(name, "rb");
- if(musicstream)
- {
+ if(musicstream) {
if(!musicrw) musicrw = musicstream->rwops();
if(!musicrw) DELETEP(musicstream);
}
if(musicrw) music = Mix_LoadMUSType_RW(musicrw, MUS_NONE, 0);
else music = Mix_LoadMUS(findfile(name, "rb"));
- if(!music)
- {
+ if(!music) {
if(musicrw) { SDL_FreeRW(musicrw); musicrw = NULL; }
DELETEP(musicstream);
}
return music;
}
-void startmusic(char *name, char *cmd)
-{
+void startmusic(char *name, char *cmd) {
if(nosound) return;
stopmusic();
- if(soundvol && musicvol && *name)
- {
+ if(soundvol && musicvol && *name) {
defformatstring(file, "packages/%s", name);
path(file);
- if(loadmusic(file))
- {
+ if(loadmusic(file)) {
DELETEA(musicfile);
DELETEA(musicdonecmd);
musicfile = newstring(file);
@@ -281,8 +237,7 @@ void startmusic(char *name, char *cmd)
Mix_VolumeMusic((musicvol*MIX_MAX_VOLUME)/255);
intret(1);
}
- else
- {
+ else {
conoutf(CON_ERROR, "could not play music: %s", file);
intret(0);
}
@@ -291,15 +246,12 @@ void startmusic(char *name, char *cmd)
COMMANDN(music, startmusic, "ss");
-static Mix_Chunk *loadwav(const char *name)
-{
+static Mix_Chunk *loadwav(const char *name) {
Mix_Chunk *c = NULL;
stream *z = openzipfile(name, "rb");
- if(z)
- {
+ if(z) {
SDL_RWops *rw = z->rwops();
- if(rw)
- {
+ if(rw) {
c = Mix_LoadWAV_RW(rw, 0);
SDL_FreeRW(rw);
}
@@ -309,47 +261,39 @@ static Mix_Chunk *loadwav(const char *name)
return c;
}
-template<class T> static void scalewav(T* dst, T* src, size_t len, int scale)
-{
+template<class T> static void scalewav(T* dst, T* src, size_t len, int scale) {
len /= sizeof(T);
const T* end = src + len;
- if(scale==2) for(; src < end; src++, dst += scale)
- {
+ if(scale==2) for(; src < end; src++, dst += scale) {
T s = src[0];
dst[0] = s;
dst[1] = s;
}
- else if(scale==4) for(; src < end; src++, dst += scale)
- {
+ else if(scale==4) for(; src < end; src++, dst += scale) {
T s = src[0];
dst[0] = s;
dst[1] = s;
dst[2] = s;
dst[3] = s;
}
- else for(; src < end; src++)
- {
+ else for(; src < end; src++) {
T s = src[0];
loopi(scale) *dst++ = s;
}
}
-static Mix_Chunk *loadwavscaled(const char *name)
-{
+static Mix_Chunk *loadwavscaled(const char *name) {
int mixerfreq = 0;
Uint16 mixerformat = 0;
int mixerchannels = 0;
if(!Mix_QuerySpec(&mixerfreq, &mixerformat, &mixerchannels)) return NULL;
-
SDL_AudioSpec spec;
Uint8 *audiobuf = NULL;
Uint32 audiolen = 0;
stream *z = openzipfile(name, "rb");
- if(z)
- {
+ if(z) {
SDL_RWops *rw = z->rwops();
- if(rw)
- {
+ if(rw) {
SDL_LoadWAV_RW(rw, 0, &spec, &audiobuf, &audiolen);
SDL_FreeRW(rw);
}
@@ -359,21 +303,17 @@ static Mix_Chunk *loadwavscaled(const char *name)
if(!audiobuf) return NULL;
int samplesize = ((spec.format&0xFF)/8) * spec.channels;
int scale = mixerfreq / spec.freq;
- if(scale >= 2)
- {
+ if(scale >= 2) {
Uint8 *scalebuf = (Uint8*)SDL_malloc(audiolen * scale);
- if(scalebuf)
- {
- switch(samplesize)
- {
+ if(scalebuf) {
+ switch(samplesize) {
case 1: scalewav((uchar*)scalebuf, (uchar*)audiobuf, audiolen, scale); break;
case 2: scalewav((ushort*)scalebuf, (ushort*)audiobuf, audiolen, scale); break;
case 4: scalewav((uint*)scalebuf, (uint*)audiobuf, audiolen, scale); break;
case 8: scalewav((ullong*)scalebuf, (ullong*)audiobuf, audiolen, scale); break;
default: SDL_free(scalebuf); scalebuf = NULL; break;
}
- if(scalebuf)
- {
+ if(scalebuf) {
SDL_free(audiobuf);
audiobuf = scalebuf;
audiolen *= scale;
@@ -381,16 +321,13 @@ static Mix_Chunk *loadwavscaled(const char *name)
}
}
}
- if(spec.freq != mixerfreq || spec.format != mixerformat || spec.channels != mixerchannels)
- {
+ if(spec.freq != mixerfreq || spec.format != mixerformat || spec.channels != mixerchannels) {
SDL_AudioCVT cvt;
- if(SDL_BuildAudioCVT(&cvt, spec.format, spec.channels, spec.freq, mixerformat, mixerchannels, mixerfreq) < 0)
- {
+ if(SDL_BuildAudioCVT(&cvt, spec.format, spec.channels, spec.freq, mixerformat, mixerchannels, mixerfreq) < 0) {
SDL_free(audiobuf);
return NULL;
}
- if(cvt.filters[0])
- {
+ if(cvt.filters[0]) {
cvt.len = audiolen & ~(samplesize-1);
cvt.buf = (Uint8*)SDL_malloc(cvt.len * cvt.len_mult);
if(!cvt.buf) { SDL_free(audiobuf); return NULL; }
@@ -409,23 +346,18 @@ static Mix_Chunk *loadwavscaled(const char *name)
VARFP(fixwav, 0, 1, 1, initwarning("sound configuration", INIT_LOAD, CHANGE_SOUND));
-bool soundsample::load(bool msg)
-{
+bool soundsample::load(bool msg) {
if(chunk) return true;
if(!name[0]) return false;
-
static const char * const exts[] = { "", ".wav", ".ogg" };
string filename;
- loopi(sizeof(exts)/sizeof(exts[0]))
- {
+ loopi(sizeof(exts)/sizeof(exts[0])) {
formatstring(filename, "packages/sounds/%s%s", name, exts[i]);
if(msg && !i) renderprogress(0, filename);
path(filename);
- if(fixwav)
- {
+ if(fixwav) {
size_t len = strlen(filename);
- if(len >= 4 && !strcasecmp(filename + len - 4, ".wav"))
- {
+ if(len >= 4 && !strcasecmp(filename + len - 4, ".wav")) {
chunk = loadwavscaled(filename);
if(chunk) return true;
}
@@ -433,42 +365,32 @@ bool soundsample::load(bool msg)
chunk = loadwav(filename);
if(chunk) return true;
}
-
conoutf(CON_ERROR, "failed to load sample: packages/sounds/%s", name);
return false;
}
static hashnameset<soundsample> samples;
-static void cleanupsamples()
-{
+static void cleanupsamples() {
enumerate(samples, soundsample, s, s.cleanup());
}
-static struct soundtype
-{
+static struct soundtype {
vector<soundslot> slots;
vector<soundconfig> configs;
-
- int findsound(const char *name, int vol)
- {
- loopv(configs)
- {
+ int findsound(const char *name, int vol) {
+ loopv(configs) {
soundconfig &s = configs[i];
- loopj(s.numslots)
- {
+ loopj(s.numslots) {
soundslot &c = slots[s.slots+j];
if(!strcmp(c.sample->name, name) && (!vol || c.volume==vol)) return i;
}
}
return -1;
}
-
- int addslot(const char *name, int vol)
- {
+ int addslot(const char *name, int vol) {
soundsample *s = samples.access(name);
- if(!s)
- {
+ if(!s) {
char *n = newstring(name);
s = &samples[n];
s->name = n;
@@ -478,8 +400,7 @@ static struct soundtype
int oldlen = slots.length();
soundslot &slot = slots.add();
// soundslots.add() may relocate slot pointers
- if(slots.getbuf() != oldslots) loopv(channels)
- {
+ if(slots.getbuf() != oldslots) loopv(channels) {
soundchannel &chan = channels[i];
if(chan.inuse && chan.slot >= oldslots && chan.slot < &oldslots[oldlen])
chan.slot = &slots[chan.slot - oldslots];
@@ -488,52 +409,38 @@ static struct soundtype
slot.volume = vol ? vol : 100;
return oldlen;
}
-
- int addsound(const char *name, int vol, int maxuses = 0)
- {
+ int addsound(const char *name, int vol, int maxuses = 0) {
soundconfig &s = configs.add();
s.slots = addslot(name, vol);
s.numslots = 1;
s.maxuses = maxuses;
return configs.length()-1;
}
-
- void addalt(const char *name, int vol)
- {
+ void addalt(const char *name, int vol) {
if(configs.empty()) return;
addslot(name, vol);
configs.last().numslots++;
}
-
- void clear()
- {
+ void clear() {
slots.setsize(0);
configs.setsize(0);
}
-
- void reset()
- {
- loopv(channels)
- {
+ void reset() {
+ loopv(channels) {
soundchannel &chan = channels[i];
- if(chan.inuse && slots.inbuf(chan.slot))
- {
+ if(chan.inuse && slots.inbuf(chan.slot)) {
Mix_HaltChannel(i);
freechannel(i);
}
}
clear();
}
-
- void preloadsound(int n)
- {
+ void preloadsound(int n) {
if(nosound || !configs.inrange(n)) return;
soundconfig &config = configs[n];
loopk(config.numslots) slots[config.slots+k].sample->load(true);
}
-
- bool playing(const soundchannel &chan, const soundconfig &config) const
- {
+ bool playing(const soundchannel &chan, const soundconfig &config) const {
return chan.inuse && config.hasslot(chan.slot, slots);
}
} gamesounds, mapsounds;
@@ -553,29 +460,24 @@ COMMAND(altmapsound, "si");
ICOMMAND(numsounds, "", (), intret(gamesounds.configs.length()));
ICOMMAND(nummapsounds, "", (), intret(mapsounds.configs.length()));
-void soundreset()
-{
+void soundreset() {
gamesounds.reset();
}
COMMAND(soundreset, "");
-void mapsoundreset()
-{
+void mapsoundreset() {
mapsounds.reset();
}
COMMAND(mapsoundreset, "");
-void resetchannels()
-{
+void resetchannels() {
loopv(channels) if(channels[i].inuse) freechannel(i);
channels.shrink(0);
}
-void clear_sound()
-{
+void clear_sound() {
if(nosound) return;
stopmusic();
-
cleanupsamples();
gamesounds.clear();
mapsounds.clear();
@@ -584,43 +486,34 @@ void clear_sound()
resetchannels();
}
-void stopmapsounds()
-{
- loopv(channels) if(channels[i].inuse && channels[i].ent)
- {
+void stopmapsounds() {
+ loopv(channels) if(channels[i].inuse && channels[i].ent) {
Mix_HaltChannel(i);
freechannel(i);
}
}
-void clearmapsounds()
-{
+void clearmapsounds() {
stopmapsounds();
mapsounds.clear();
}
-void stopmapsound(extentity *e)
-{
- loopv(channels)
- {
+void stopmapsound(extentity *e) {
+ loopv(channels) {
soundchannel &chan = channels[i];
- if(chan.inuse && chan.ent == e)
- {
+ if(chan.inuse && chan.ent == e) {
Mix_HaltChannel(i);
freechannel(i);
}
}
}
-void checkmapsounds()
-{
+void checkmapsounds() {
const vector<extentity *> &ents = entities::getents();
- loopv(ents)
- {
+ loopv(ents) {
extentity &e = *ents[i];
if(e.type!=ET_SOUND) continue;
- if(camera1->o.dist(e.o) < e.attr2)
- {
+ if(camera1->o.dist(e.o) < e.attr2) {
if(!(e.flags&EF_SOUND)) playsound(e.attr1, NULL, &e, SND_MAP, -1);
}
else if(e.flags&EF_SOUND) stopmapsound(&e);
@@ -629,28 +522,23 @@ void checkmapsounds()
VAR(stereo, 0, 1, 1);
-bool updatechannel(soundchannel &chan)
-{
+bool updatechannel(soundchannel &chan) {
if(!chan.slot) return false;
int vol = soundvol, pan = 255/2;
- if(chan.hasloc())
- {
+ if(chan.hasloc()) {
vec v;
float dist = chan.loc.dist(camera1->o, v);
int rad = 0;
- if(chan.ent)
- {
+ if(chan.ent) {
rad = chan.ent->attr2;
- if(chan.ent->attr3)
- {
+ if(chan.ent->attr3) {
rad -= chan.ent->attr3;
dist -= chan.ent->attr3;
}
}
else if(chan.radius > 0) rad = chan.radius;
if(rad > 0) vol -= int(clamp(dist/rad, 0.0f, 1.0f)*soundvol); // simple mono distance attenuation
- if(stereo && (v.x != 0 || v.y != 0) && dist>0)
- {
+ if(stereo && (v.x != 0 || v.y != 0) && dist>0) {
v.rotate_around_z(-camera1->yaw*RAD);
pan = int(255.9f*(0.5f - 0.5f*v.x/v.magnitude2())); // range is from 0 (left) to 255 (right)
}
@@ -664,19 +552,15 @@ bool updatechannel(soundchannel &chan)
return true;
}
-void reclaimchannels()
-{
- loopv(channels)
- {
+void reclaimchannels() {
+ loopv(channels) {
soundchannel &chan = channels[i];
if(chan.inuse && !Mix_Playing(i)) freechannel(i);
}
}
-void syncchannels()
-{
- loopv(channels)
- {
+void syncchannels() {
+ loopv(channels) {
soundchannel &chan = channels[i];
if(chan.inuse && chan.hasloc() && updatechannel(chan)) syncchannel(chan);
}
@@ -684,19 +568,16 @@ void syncchannels()
VARP(minimizedsounds, 0, 0, 1);
-void updatesounds()
-{
+void updatesounds() {
if(nosound) return;
if(minimized && !minimizedsounds) stopsounds();
- else
- {
+ else {
reclaimchannels();
if(mainmenu) stopmapsounds();
else checkmapsounds();
syncchannels();
}
- if(music)
- {
+ if(music) {
if(!Mix_PlayingMusic()) musicdone();
else if(Mix_PausedMusic()) Mix_ResumeMusic();
}
@@ -704,91 +585,70 @@ void updatesounds()
VARP(maxsoundsatonce, 0, 7, 100);
-void preloadsound(int n)
-{
+void preloadsound(int n) {
gamesounds.preloadsound(n);
}
-void preloadmapsound(int n)
-{
+void preloadmapsound(int n) {
mapsounds.preloadsound(n);
}
-void preloadmapsounds()
-{
+void preloadmapsounds() {
const vector<extentity *> &ents = entities::getents();
- loopv(ents)
- {
+ loopv(ents) {
extentity &e = *ents[i];
if(e.type==ET_SOUND) mapsounds.preloadsound(e.attr1);
}
}
-int playsound(int n, const vec *loc, extentity *ent, int flags, int loops, int fade, int chanid, int radius, int expire)
-{
+int playsound(int n, const vec *loc, extentity *ent, int flags, int loops, int fade, int chanid, int radius, int expire) {
if(nosound || !soundvol || (minimized && !minimizedsounds)) return -1;
-
soundtype &sounds = ent || flags&SND_MAP ? mapsounds : gamesounds;
if(!sounds.configs.inrange(n)) { conoutf(CON_WARN, "unregistered sound: %d", n); return -1; }
soundconfig &config = sounds.configs[n];
-
- if(loc)
- {
+ if(loc) {
// cull sounds that are unlikely to be heard
int maxrad = game::maxsoundradius(n);
if(radius <= 0 || maxrad < radius) radius = maxrad;
- if(camera1->o.dist(*loc) > 1.5f*radius)
- {
- if(channels.inrange(chanid) && sounds.playing(channels[chanid], config))
- {
+ if(camera1->o.dist(*loc) > 1.5f*radius) {
+ if(channels.inrange(chanid) && sounds.playing(channels[chanid], config)) {
Mix_HaltChannel(chanid);
freechannel(chanid);
}
return -1;
}
}
-
- if(chanid < 0)
- {
- if(config.maxuses)
- {
+ if(chanid < 0) {
+ if(config.maxuses) {
int uses = 0;
loopv(channels) if(sounds.playing(channels[i], config) && ++uses >= config.maxuses) return -1;
}
-
// avoid bursts of sounds with heavy packetloss and in sp
static int soundsatonce = 0, lastsoundmillis = 0;
if(totalmillis == lastsoundmillis) soundsatonce++; else soundsatonce = 1;
lastsoundmillis = totalmillis;
if(maxsoundsatonce && soundsatonce > maxsoundsatonce) return -1;
}
-
- if(channels.inrange(chanid))
- {
+ if(channels.inrange(chanid)) {
soundchannel &chan = channels[chanid];
- if(sounds.playing(chan, config))
- {
+ if(sounds.playing(chan, config)) {
if(loc) chan.loc = *loc;
else if(chan.hasloc()) chan.clearloc();
return chanid;
}
}
if(fade < 0) return -1;
-
soundslot &slot = sounds.slots[config.chooseslot(flags)];
if(!slot.sample->chunk && !slot.sample->load()) return -1;
-
chanid = -1;
loopv(channels) if(!channels[i].inuse) { chanid = i; break; }
if(chanid < 0 && channels.length() < maxchannels) chanid = channels.length();
if(chanid < 0) loopv(channels) if(!channels[i].volume) { chanid = i; break; }
if(chanid < 0) return -1;
-
soundchannel &chan = newchannel(chanid, &slot, loc, ent, flags, radius);
updatechannel(chan);
int playing = -1;
- if(fade)
- {
+ if(fade) {
Mix_Volume(chanid, chan.volume);
playing = expire >= 0 ? Mix_FadeInChannelTimed(chanid, slot.sample->chunk, loops, fade, expire) : Mix_FadeInChannel(chanid, slot.sample->chunk, loops, fade);
}
@@ -798,28 +658,23 @@ int playsound(int n, const vec *loc, extentity *ent, int flags, int loops, int f
return playing;
}
-void stopsounds()
-{
- loopv(channels) if(channels[i].inuse)
- {
+void stopsounds() {
+ loopv(channels) if(channels[i].inuse) {
Mix_HaltChannel(i);
freechannel(i);
}
}
-bool stopsound(int n, int chanid, int fade)
-{
+bool stopsound(int n, int chanid, int fade) {
if(!gamesounds.configs.inrange(n) || !channels.inrange(chanid) || !channels[chanid].inuse || !gamesounds.playing(channels[chanid], gamesounds.configs[n])) return false;
- if(!fade || !Mix_FadeOutChannel(chanid, fade))
- {
+ if(!fade || !Mix_FadeOutChannel(chanid, fade)) {
Mix_HaltChannel(chanid);
freechannel(chanid);
}
return true;
}
-int playsoundname(const char *s, const vec *loc, int vol, int flags, int loops, int fade, int chanid, int radius, int expire)
-{
+int playsoundname(const char *s, const vec *loc, int vol, int flags, int loops, int fade, int chanid, int radius, int expire) {
if(!vol) vol = 100;
int id = gamesounds.findsound(s, vol);
if(id < 0) id = gamesounds.addsound(s, vol);
@@ -828,14 +683,11 @@ int playsoundname(const char *s, const vec *loc, int vol, int flags, int loops,
ICOMMAND(sound, "i", (int *n), playsound(*n));
-void resetsound()
-{
+void resetsound() {
clearchanges(CHANGE_SOUND);
- if(!nosound)
- {
+ if(!nosound) {
cleanupsamples();
- if(music)
- {
+ if(music) {
Mix_HaltMusic();
Mix_FreeMusic(music);
}
@@ -844,21 +696,18 @@ void resetsound()
}
initsound();
resetchannels();
- if(nosound)
- {
+ if(nosound) {
DELETEA(musicfile);
DELETEA(musicdonecmd);
music = NULL;
cleanupsamples();
return;
}
- if(music && loadmusic(musicfile))
- {
+ if(music && loadmusic(musicfile)) {
Mix_PlayMusic(music, musicdonecmd ? 0 : -1);
Mix_VolumeMusic((musicvol*MIX_MAX_VOLUME)/255);
}
- else
- {
+ else {
DELETEA(musicfile);
DELETEA(musicdonecmd);
}
diff --git a/src/engine/textedit.h b/src/engine/textedit.h
index 0dcda1d..742fd33 100644
--- a/src/engine/textedit.h
+++ b/src/engine/textedit.h
@@ -1,31 +1,21 @@
-struct editline
-{
+struct editline {
enum { CHUNKSIZE = 256 };
-
char *text;
int len, maxlen;
-
editline() : text(NULL), len(0), maxlen(0) {}
- editline(const char *init) : text(NULL), len(0), maxlen(0)
- {
+ editline(const char *init) : text(NULL), len(0), maxlen(0) {
set(init);
}
-
bool empty() { return len <= 0; }
-
- void clear()
- {
+ void clear() {
DELETEA(text);
len = maxlen = 0;
}
-
- bool grow(int total, const char *fmt = "", ...)
- {
+ bool grow(int total, const char *fmt = "", ...) {
if(total + 1 <= maxlen) return false;
maxlen = (total + CHUNKSIZE) - total%CHUNKSIZE;
char *newtext = new char[maxlen];
- if(fmt)
- {
+ if(fmt) {
va_list args;
va_start(args, fmt);
vformatstring(newtext, fmt, args, maxlen);
@@ -36,69 +26,52 @@ struct editline
text = newtext;
return true;
}
-
- void set(const char *str, int slen = -1)
- {
- if(slen < 0)
- {
+ void set(const char *str, int slen = -1) {
+ if(slen < 0) {
slen = strlen(str);
if(!grow(slen, "%s", str)) memcpy(text, str, slen + 1);
}
- else
- {
+ else {
grow(slen);
memcpy(text, str, slen);
text[slen] = '\0';
}
len = slen;
}
-
- void prepend(const char *str)
- {
+ void prepend(const char *str) {
int slen = strlen(str);
- if(!grow(slen + len, "%s%s", str, text ? text : ""))
- {
+ if(!grow(slen + len, "%s%s", str, text ? text : "")) {
memmove(&text[slen], text, len + 1);
memcpy(text, str, slen + 1);
}
len += slen;
}
-
- void append(const char *str)
- {
+ void append(const char *str) {
int slen = strlen(str);
if(!grow(len + slen, "%s%s", text ? text : "", str)) memcpy(&text[len], str, slen + 1);
len += slen;
}
-
- bool read(stream *f, int chop = -1)
- {
+ bool read(stream *f, int chop = -1) {
if(chop < 0) chop = INT_MAX; else chop++;
set("");
- while(len + 1 < chop && f->getline(&text[len], min(maxlen, chop) - len))
- {
+ while(len + 1 < chop && f->getline(&text[len], min(maxlen, chop) - len)) {
len += strlen(&text[len]);
- if(len > 0 && text[len-1] == '\n')
- {
+ if(len > 0 && text[len-1] == '\n') {
text[--len] = '\0';
return true;
}
if(len + 1 >= maxlen && len + 1 < chop) grow(len + CHUNKSIZE, "%s", text);
}
- if(len + 1 >= chop)
- {
+ if(len + 1 >= chop) {
char buf[CHUNKSIZE];
- while(f->getline(buf, sizeof(buf)))
- {
+ while(f->getline(buf, sizeof(buf))) {
int blen = strlen(buf);
if(blen > 0 && buf[blen-1] == '\n') return true;
}
}
return len > 0;
}
-
- void del(int start, int count)
- {
+ void del(int start, int count) {
if(!text) return;
if(start < 0) { count += start; start = 0; }
if(count <= 0 || start >= len) return;
@@ -106,16 +79,12 @@ struct editline
memmove(&text[start], &text[start+count], len + 1 - (start + count));
len -= count;
}
-
- void chop(int newlen)
- {
+ void chop(int newlen) {
if(!text) return;
len = clamp(newlen, 0, len);
text[len] = '\0';
}
-
- void insert(char *str, int start, int count = 0)
- {
+ void insert(char *str, int start, int count = 0) {
if(count <= 0) count = strlen(str);
start = clamp(start, 0, len);
grow(len + count, "%s", text ? text : "");
@@ -123,12 +92,9 @@ struct editline
memcpy(&text[start], str, count);
len += count;
}
-
- void combinelines(vector<editline> &src)
- {
+ void combinelines(vector<editline> &src) {
if(src.empty()) set("");
- else loopv(src)
- {
+ else loopv(src) {
if(i) append("\n");
if(!i) set(src[i].text, src[i].len);
else insert(src[i].text, len, src[i].len);
@@ -136,102 +102,77 @@ struct editline
}
};
-struct editor
-{
+struct editor {
int mode; //editor mode - 1= keep while focused, 2= keep while used in gui, 3= keep forever (i.e. until mode changes)
bool active, rendered;
const char *name;
const char *filename;
-
int cx, cy; // cursor position - ensured to be valid after a region() or currentline()
int mx, my; // selection mark, mx=-1 if following cursor - avoid direct access, instead use region()
int maxx, maxy; // maxy=-1 if unlimited lines, 1 if single line editor
-
int scrolly; // vertical scroll offset
-
bool linewrap;
int pixelwidth; // required for up/down/hit/draw/bounds
int pixelheight; // -1 for variable sized, i.e. from bounds()
-
vector<editline> lines; // MUST always contain at least one line!
-
editor(const char *name, int mode, const char *initval) :
mode(mode), active(true), rendered(false), name(newstring(name)), filename(NULL),
- cx(0), cy(0), mx(-1), maxx(-1), maxy(-1), scrolly(0), linewrap(false), pixelwidth(-1), pixelheight(-1)
- {
+ cx(0), cy(0), mx(-1), maxx(-1), maxy(-1), scrolly(0), linewrap(false), pixelwidth(-1), pixelheight(-1) {
//printf("editor %08x '%s'\n", this, name);
lines.add().set(initval ? initval : "");
}
-
- ~editor()
- {
+ ~editor() {
//printf("~editor %08x '%s'\n", this, name);
DELETEA(name);
DELETEA(filename);
clear(NULL);
}
-
- void clear(const char *init = "")
- {
+ void clear(const char *init = "") {
cx = cy = 0;
mark(false);
loopv(lines) lines[i].clear();
lines.shrink(0);
if(init) lines.add().set(init);
}
-
- void setfile(const char *fname)
- {
+ void setfile(const char *fname) {
DELETEA(filename);
if(fname) filename = newstring(fname);
}
-
- void load()
- {
+ void load() {
if(!filename) return;
clear(NULL);
stream *file = openutf8file(filename, "r");
- if(file)
- {
+ if(file) {
while(lines.add().read(file, maxx) && (maxy < 0 || lines.length() <= maxy));
lines.pop().clear();
delete file;
}
if(lines.empty()) lines.add().set("");
}
-
- void save()
- {
+ void save() {
if(!filename) return;
stream *file = openutf8file(filename, "w");
if(!file) return;
loopv(lines) file->putline(lines[i].text);
delete file;
}
-
- void mark(bool enable)
- {
+ void mark(bool enable) {
mx = (enable) ? cx : -1;
my = cy;
}
-
- void selectall()
- {
+ void selectall() {
mx = my = INT_MAX;
cx = cy = 0;
}
-
// constrain results to within buffer - s=start, e=end, return true if a selection range
// also ensures that cy is always within lines[] and cx is valid
- bool region(int &sx, int &sy, int &ex, int &ey)
- {
+ bool region(int &sx, int &sy, int &ex, int &ey) {
int n = lines.length();
ASSERT(n != 0);
if(cy < 0) cy = 0; else if(cy >= n) cy = n-1;
int len = lines[cy].len;
if(cx < 0) cx = 0; else if(cx > len) cx = len;
- if(mx >= 0)
- {
+ if(mx >= 0) {
if(my < 0) my = 0; else if(my >= n) my = n-1;
len = lines[my].len;
if(mx > len) mx = len;
@@ -244,34 +185,26 @@ struct editor
else if(sy==ey && sx > ex) swap(sx, ex);
return (sx != ex) || (sy != ey);
}
-
bool region() { int sx, sy, ex, ey; return region(sx, sy, ex, ey); }
-
// also ensures that cy is always within lines[] and cx is valid
- editline &currentline()
- {
+ editline &currentline() {
int n = lines.length();
ASSERT(n != 0);
if(cy < 0) cy = 0; else if(cy >= n) cy = n-1;
if(cx < 0) cx = 0; else if(cx > lines[cy].len) cx = lines[cy].len;
return lines[cy];
}
-
- void copyselectionto(editor *b)
- {
+ void copyselectionto(editor *b) {
if(b==this) return;
-
b->clear(NULL);
int sx, sy, ex, ey;
region(sx, sy, ex, ey);
- loopi(1+ey-sy)
- {
+ loopi(1+ey-sy) {
if(b->maxy != -1 && b->lines.length() >= b->maxy) break;
int y = sy+i;
char *line = lines[y].text;
int len = lines[y].len;
- if(y == sy && y == ey)
- {
+ if(y == sy && y == ey) {
line += sx;
len = ex - sx;
}
@@ -281,15 +214,12 @@ struct editor
}
if(b->lines.empty()) b->lines.add().set("");
}
-
- char *tostring()
- {
+ char *tostring() {
int len = 0;
loopv(lines) len += lines[i].len + 1;
char *str = newstring(len);
int offset = 0;
- loopv(lines)
- {
+ loopv(lines) {
editline &l = lines[i];
memcpy(&str[offset], l.text, l.len);
offset += l.len;
@@ -298,19 +228,15 @@ struct editor
str[offset] = '\0';
return str;
}
-
- char *selectiontostring()
- {
+ char *selectiontostring() {
vector<char> buf;
int sx, sy, ex, ey;
region(sx, sy, ex, ey);
- loopi(1+ey-sy)
- {
+ loopi(1+ey-sy) {
int y = sy+i;
char *line = lines[y].text;
int len = lines[y].len;
- if(y == sy && y == ey)
- {
+ if(y == sy && y == ey) {
line += sx;
len = ex - sx;
}
@@ -322,28 +248,21 @@ struct editor
buf.add('\0');
return newstring(buf.getbuf(), buf.length()-1);
}
-
- void removelines(int start, int count)
- {
+ void removelines(int start, int count) {
loopi(count) lines[start+i].clear();
lines.remove(start, count);
}
-
- bool del() // removes the current selection (if any)
- {
+ bool del() { // removes the current selection (if any) {
int sx, sy, ex, ey;
- if(!region(sx, sy, ex, ey))
- {
+ if(!region(sx, sy, ex, ey)) {
mark(false);
return false;
}
- if(sy == ey)
- {
+ if(sy == ey) {
if(sx == 0 && ex == lines[ey].len) removelines(sy, 1);
else lines[sy].del(sx, ex - sx);
}
- else
- {
+ else {
if(ey > sy+1) { removelines(sy+1, ey-(sy+1)); ey = sy+1; }
if(ex == lines[ey].len) removelines(ey, 1); else lines[ey].del(0, ex);
if(sx == 0) removelines(sy, 1); else lines[sy].del(sx, lines[sy].len - sx);
@@ -353,22 +272,17 @@ struct editor
cx = sx;
cy = sy;
editline &current = currentline();
- if(cx >= current.len && cy < lines.length() - 1)
- {
+ if(cx >= current.len && cy < lines.length() - 1) {
current.append(lines[cy+1].text);
removelines(cy + 1, 1);
}
return true;
}
-
- void insert(char ch)
- {
+ void insert(char ch) {
del();
editline &current = currentline();
- if(ch == '\n')
- {
- if(maxy == -1 || cy < maxy-1)
- {
+ if(ch == '\n') {
+ if(maxy == -1 || cy < maxy-1) {
editline newline(&current.text[cx]);
current.chop(cx);
cy = min(lines.length(), cy+1);
@@ -377,49 +291,36 @@ struct editor
else current.chop(cx);
cx = 0;
}
- else
- {
+ else {
int len = current.len;
if(maxx >= 0 && len > maxx-1) len = maxx-1;
if(cx <= len) current.insert(&ch, cx++, 1);
}
}
-
- void insert(const char *s)
- {
+ void insert(const char *s) {
while(*s) insert(*s++);
}
-
- void insertallfrom(editor *b)
- {
+ void insertallfrom(editor *b) {
if(b==this) return;
-
del();
-
- if(b->lines.length() == 1 || maxy == 1)
- {
+ if(b->lines.length() == 1 || maxy == 1) {
editline &current = currentline();
char *str = b->lines[0].text;
int slen = b->lines[0].len;
if(maxx >= 0 && b->lines[0].len + cx > maxx) slen = maxx-cx;
- if(slen > 0)
- {
+ if(slen > 0) {
int len = current.len;
if(maxx >= 0 && slen + cx + len > maxx) len = max(0, maxx-(cx+slen));
current.insert(str, cx, slen);
cx += slen;
}
}
- else
- {
- loopv(b->lines)
- {
- if(!i)
- {
+ else {
+ loopv(b->lines) {
+ if(!i) {
lines[cy++].append(b->lines[i].text);
}
- else if(i >= b->lines.length())
- {
+ else if(i >= b->lines.length()) {
cx = b->lines[i].len;
lines[cy].prepend(b->lines[i].text);
}
@@ -427,14 +328,10 @@ struct editor
}
}
}
-
- void key(int code)
- {
- switch(code)
- {
+ void key(int code) {
+ switch(code) {
case SDLK_UP:
- if(linewrap)
- {
+ if(linewrap) {
int x, y;
char *str = currentline().text;
text_pos(str, cx+1, x, y, pixelwidth);
@@ -443,8 +340,7 @@ struct editor
cy--;
break;
case SDLK_DOWN:
- if(linewrap)
- {
+ if(linewrap) {
int x, y, width, height;
char *str = currentline().text;
text_pos(str, cx, x, y, pixelwidth);
@@ -479,24 +375,22 @@ struct editor
cx++;
break;
case SDLK_DELETE:
- if(!del())
- {
+ if(!del()) {
editline &current = currentline();
if(cx < current.len) current.del(cx, 1);
- else if(cy < lines.length()-1)
- { //combine with next line
+ else if(cy < lines.length()-1) {
+ //combine with next line
current.append(lines[cy+1].text);
removelines(cy+1, 1);
}
}
break;
case SDLK_BACKSPACE:
- if(!del())
- {
+ if(!del()) {
editline &current = currentline();
if(cx > 0) current.del(--cx, 1);
- else if(cy > 0)
- { //combine with previous line
+ else if(cy > 0) {
+ //combine with previous line
cx = lines[cy-1].len;
lines[cy-1].append(current.text);
removelines(cy--, 1);
@@ -514,24 +408,17 @@ struct editor
break;
}
}
-
- void input(const char *str, int len)
- {
+ void input(const char *str, int len) {
loopi(len) insert(str[i]);
}
-
- void hit(int hitx, int hity, bool dragged)
- {
+ void hit(int hitx, int hity, bool dragged) {
int maxwidth = linewrap?pixelwidth:-1;
int h = 0;
- for(int i = scrolly; i < lines.length(); i++)
- {
+ for(int i = scrolly; i < lines.length(); i++) {
int width, height;
text_bounds(lines[i].text, width, height, maxwidth);
if(h + height > pixelheight) break;
-
- if(hity >= h && hity <= h+height)
- {
+ if(hity >= h && hity <= h+height) {
int x = text_visible(lines[i].text, hitx, hity-h, maxwidth);
if(dragged) { mx = x; my = i; } else { cx = x; cy = i; };
break;
@@ -539,13 +426,10 @@ struct editor
h+=height;
}
}
-
- int limitscrolly()
- {
+ int limitscrolly() {
int maxwidth = linewrap?pixelwidth:-1;
int slines = lines.length();
- for(int ph = pixelheight; slines > 0 && ph > 0;)
- {
+ for(int ph = pixelheight; slines > 0 && ph > 0;) {
int width, height;
text_bounds(lines[slines-1].text, width, height, maxwidth);
if(height > ph) break;
@@ -554,39 +438,30 @@ struct editor
}
return slines;
}
-
- void draw(int x, int y, int color, bool hit)
- {
+ void draw(int x, int y, int color, bool hit) {
int maxwidth = linewrap?pixelwidth:-1;
-
int sx, sy, ex, ey;
bool selection = region(sx, sy, ex, ey);
-
// fix scrolly so that <cx, cy> is always on screen
if(cy < scrolly) scrolly = cy;
- else
- {
+ else {
if(scrolly < 0) scrolly = 0;
int h = 0;
- for(int i = cy; i >= scrolly; i--)
- {
+ for(int i = cy; i >= scrolly; i--) {
int width, height;
text_bounds(lines[i].text, width, height, maxwidth);
if(h + height > pixelheight) { scrolly = i+1; break; }
h += height;
}
}
-
- if(selection)
- {
+ if(selection) {
// convert from cursor coords into pixel coords
int psx, psy, pex, pey;
text_pos(lines[sy].text, sx, psx, psy, maxwidth);
text_pos(lines[ey].text, ex, pex, pey, maxwidth);
int maxy = lines.length();
int h = 0;
- for(int i = scrolly; i < maxy; i++)
- {
+ for(int i = scrolly; i < maxy; i++) {
int width, height;
text_bounds(lines[i].text, width, height, maxwidth);
if(h + height > pixelheight) { maxy = i; break; }
@@ -595,31 +470,26 @@ struct editor
h += height;
}
maxy--;
-
- if(ey >= scrolly && sy <= maxy)
- {
+ if(ey >= scrolly && sy <= maxy) {
// crop top/bottom within window
if(sy < scrolly) { sy = scrolly; psy = 0; psx = 0; }
if(ey > maxy) { ey = maxy; pey = pixelheight - FONTH; pex = pixelwidth; }
-
hudnotextureshader->set();
gle::colorub(0xA0, 0x80, 0x80);
gle::defvertex(2);
gle::begin(GL_QUADS);
- if(psy == pey)
- {
+ if(psy == pey) {
gle::attribf(x+psx, y+psy);
gle::attribf(x+pex, y+psy);
gle::attribf(x+pex, y+pey+FONTH);
gle::attribf(x+psx, y+pey+FONTH);
}
- else
- { gle::attribf(x+psx, y+psy);
+ else {
+ gle::attribf(x+psx, y+psy);
gle::attribf(x+psx, y+psy+FONTH);
gle::attribf(x+pixelwidth, y+psy+FONTH);
gle::attribf(x+pixelwidth, y+psy);
- if(pey-psy > FONTH)
- {
+ if(pey-psy > FONTH) {
gle::attribf(x, y+psy+FONTH);
gle::attribf(x+pixelwidth, y+psy+FONTH);
gle::attribf(x+pixelwidth, y+pey);
@@ -634,17 +504,13 @@ struct editor
hudshader->set();
}
}
-
int h = 0;
- for(int i = scrolly; i < lines.length(); i++)
- {
+ for(int i = scrolly; i < lines.length(); i++) {
int width, height;
text_bounds(lines[i].text, width, height, maxwidth);
if(h + height > pixelheight) break;
-
draw_text(lines[i].text, x, y+h, color>>16, (color>>8)&0xFF, color&0xFF, 0xFF, hit&&(cy==i)?cx:-1, maxwidth);
- if(linewrap && height > FONTH) // line wrap indicator
- {
+ if(linewrap && height > FONTH) { // line wrap indicator {
hudnotextureshader->set();
gle::colorub(0x80, 0xA0, 0x80);
gle::defvertex(2);
@@ -666,24 +532,19 @@ static vector <editor*> editors;
static editor *currentfocus() { return editors.length() ? editors.last() : NULL; }
-static void readyeditors()
-{
+static void readyeditors() {
loopv(editors) editors[i]->active = (editors[i]->mode==EDITORFOREVER);
}
-static void flusheditors()
-{
- loopvrev(editors) if(!editors[i]->active)
- {
+static void flusheditors() {
+ loopvrev(editors) if(!editors[i]->active) {
editor *e = editors.remove(i);
DELETEP(e);
}
}
-static editor *useeditor(const char *name, int mode, bool focus, const char *initval = NULL)
-{
- loopv(editors) if(strcmp(editors[i]->name, name) == 0)
- {
+static editor *useeditor(const char *name, int mode, bool focus, const char *initval = NULL) {
+ loopv(editors) if(strcmp(editors[i]->name, name) == 0) {
editor *e = editors[i];
if(focus) { editors.add(e); editors.remove(i); } // re-position as last
e->active = true;
@@ -703,8 +564,7 @@ static editor *useeditor(const char *name, int mode, bool focus, const char *ini
ICOMMAND(textlist, "", (), // @DEBUG return list of all the editors
vector<char> s;
- loopv(editors)
- {
+ loopv(editors) {
if(i > 0) s.put(", ", 2);
s.put(editors[i]->name, strlen(editors[i]->name));
}
@@ -731,19 +591,16 @@ TEXTCOMMAND(textsave, "s", (char *file), // saves the topmost (filename is opti
top->save();
);
TEXTCOMMAND(textload, "s", (char *file), // loads into the topmost editor, returns filename if no args
- if(*file)
- {
+ if(*file) {
top->setfile(path(file, true));
top->load();
}
else if(top->filename) result(top->filename);
);
-TEXTCOMMAND(textinit, "sss", (char *name, char *file, char *initval), // loads into named editor if no file assigned and editor has been rendered
-{
+TEXTCOMMAND(textinit, "sss", (char *name, char *file, char *initval), { // loads into named editor if no file assigned and editor has been rendered {
editor *e = NULL;
loopv(editors) if(!strcmp(editors[i]->name, name)) { e = editors[i]; break; }
- if(e && e->rendered && !e->filename && *file && (e->lines.empty() || (e->lines.length() == 1 && !strcmp(e->lines[0].text, initval))))
- {
+ if(e && e->rendered && !e->filename && *file && (e->lines.empty() || (e->lines.length() == 1 && !strcmp(e->lines[0].text, initval)))) {
e->setfile(path(file, true));
e->load();
}
diff --git a/src/engine/texture.cpp b/src/engine/texture.cpp
index 7f391a9..0f7a5df 100644
--- a/src/engine/texture.cpp
+++ b/src/engine/texture.cpp
@@ -8,33 +8,26 @@
(SDL_VERSIONNUM(SDL_IMAGE_MAJOR_VERSION, SDL_IMAGE_MINOR_VERSION, SDL_IMAGE_PATCHLEVEL) >= SDL_VERSIONNUM(X, Y, Z))
#endif
-template<int BPP> static void halvetexture(uchar * RESTRICT src, uint sw, uint sh, uint stride, uchar * RESTRICT dst)
-{
- for(uchar *yend = &src[sh*stride]; src < yend;)
- {
- for(uchar *xend = &src[sw*BPP], *xsrc = src; xsrc < xend; xsrc += 2*BPP, dst += BPP)
- {
+template<int BPP> static void halvetexture(uchar * RESTRICT src, uint sw, uint sh, uint stride, uchar * RESTRICT dst) {
+ for(uchar *yend = &src[sh*stride]; src < yend;) {
+ for(uchar *xend = &src[sw*BPP], *xsrc = src; xsrc < xend; xsrc += 2*BPP, dst += BPP) {
loopi(BPP) dst[i] = (uint(xsrc[i]) + uint(xsrc[i+BPP]) + uint(xsrc[stride+i]) + uint(xsrc[stride+i+BPP]))>>2;
}
src += 2*stride;
}
}
-template<int BPP> static void shifttexture(uchar * RESTRICT src, uint sw, uint sh, uint stride, uchar * RESTRICT dst, uint dw, uint dh)
-{
+template<int BPP> static void shifttexture(uchar * RESTRICT src, uint sw, uint sh, uint stride, uchar * RESTRICT dst, uint dw, uint dh) {
uint wfrac = sw/dw, hfrac = sh/dh, wshift = 0, hshift = 0;
while(dw<<wshift < sw) wshift++;
while(dh<<hshift < sh) hshift++;
uint tshift = wshift + hshift;
- for(uchar *yend = &src[sh*stride]; src < yend;)
- {
- for(uchar *xend = &src[sw*BPP], *xsrc = src; xsrc < xend; xsrc += wfrac*BPP, dst += BPP)
- {
+ for(uchar *yend = &src[sh*stride]; src < yend;) {
+ for(uchar *xend = &src[sw*BPP], *xsrc = src; xsrc < xend; xsrc += wfrac*BPP, dst += BPP) {
uint t[BPP] = {0};
for(uchar *ycur = xsrc, *xend = &ycur[wfrac*BPP], *yend = &src[hfrac*stride];
ycur < yend;
- ycur += stride, xend += stride)
- {
+ ycur += stride, xend += stride) {
for(uchar *xcur = ycur; xcur < xend; xcur += BPP)
loopi(BPP) t[i] += xcur[i];
}
@@ -44,8 +37,7 @@ template<int BPP> static void shifttexture(uchar * RESTRICT src, uint sw, uint s
}
}
-template<int BPP> static void scaletexture(uchar * RESTRICT src, uint sw, uint sh, uint stride, uchar * RESTRICT dst, uint dw, uint dh)
-{
+template<int BPP> static void scaletexture(uchar * RESTRICT src, uint sw, uint sh, uint stride, uchar * RESTRICT dst, uint dw, uint dh) {
uint wfrac = (sw<<12)/dw, hfrac = (sh<<12)/dh, darea = dw*dh, sarea = sw*sh;
int over, under;
for(over = 0; (darea>>over) > sarea; over++);
@@ -56,24 +48,20 @@ template<int BPP> static void scaletexture(uchar * RESTRICT src, uint sw, uint s
area = ((ullong)darea<<ascale)/sarea;
dw *= wfrac;
dh *= hfrac;
- for(uint y = 0; y < dh; y += hfrac)
- {
+ for(uint y = 0; y < dh; y += hfrac) {
const uint yn = y + hfrac - 1, yi = y>>12, h = (yn>>12) - yi, ylow = ((yn|(-int(h)>>24))&0xFFFU) + 1 - (y&0xFFFU), yhigh = (yn&0xFFFU) + 1;
const uchar *ysrc = &src[yi*stride];
- for(uint x = 0; x < dw; x += wfrac, dst += BPP)
- {
+ for(uint x = 0; x < dw; x += wfrac, dst += BPP) {
const uint xn = x + wfrac - 1, xi = x>>12, w = (xn>>12) - xi, xlow = ((w+0xFFFU)&0x1000U) - (x&0xFFFU), xhigh = (xn&0xFFFU) + 1;
const uchar *xsrc = &ysrc[xi*BPP], *xend = &xsrc[w*BPP];
uint t[BPP] = {0};
for(const uchar *xcur = &xsrc[BPP]; xcur < xend; xcur += BPP)
loopi(BPP) t[i] += xcur[i];
loopi(BPP) t[i] = (ylow*(t[i] + ((xsrc[i]*xlow + xend[i]*xhigh)>>12)))>>cscale;
- if(h)
- {
+ if(h) {
xsrc += stride;
xend += stride;
- for(uint hcur = h; --hcur; xsrc += stride, xend += stride)
- {
+ for(uint hcur = h; --hcur; xsrc += stride, xend += stride) {
uint c[BPP] = {0};
for(const uchar *xcur = &xsrc[BPP]; xcur < xend; xcur += BPP)
loopi(BPP) c[i] += xcur[i];
@@ -89,32 +77,25 @@ template<int BPP> static void scaletexture(uchar * RESTRICT src, uint sw, uint s
}
}
-static void scaletexture(uchar * RESTRICT src, uint sw, uint sh, uint bpp, uint pitch, uchar * RESTRICT dst, uint dw, uint dh)
-{
- if(sw == dw*2 && sh == dh*2)
- {
- switch(bpp)
- {
+static void scaletexture(uchar * RESTRICT src, uint sw, uint sh, uint bpp, uint pitch, uchar * RESTRICT dst, uint dw, uint dh) {
+ if(sw == dw*2 && sh == dh*2) {
+ switch(bpp) {
case 1: return halvetexture<1>(src, sw, sh, pitch, dst);
case 2: return halvetexture<2>(src, sw, sh, pitch, dst);
case 3: return halvetexture<3>(src, sw, sh, pitch, dst);
case 4: return halvetexture<4>(src, sw, sh, pitch, dst);
}
}
- else if(sw < dw || sh < dh || sw&(sw-1) || sh&(sh-1) || dw&(dw-1) || dh&(dh-1))
- {
- switch(bpp)
- {
+ else if(sw < dw || sh < dh || sw&(sw-1) || sh&(sh-1) || dw&(dw-1) || dh&(dh-1)) {
+ switch(bpp) {
case 1: return scaletexture<1>(src, sw, sh, pitch, dst, dw, dh);
case 2: return scaletexture<2>(src, sw, sh, pitch, dst, dw, dh);
case 3: return scaletexture<3>(src, sw, sh, pitch, dst, dw, dh);
case 4: return scaletexture<4>(src, sw, sh, pitch, dst, dw, dh);
}
}
- else
- {
- switch(bpp)
- {
+ else {
+ switch(bpp) {
case 1: return shifttexture<1>(src, sw, sh, pitch, dst, dw, dh);
case 2: return shifttexture<2>(src, sw, sh, pitch, dst, dw, dh);
case 3: return shifttexture<3>(src, sw, sh, pitch, dst, dw, dh);
@@ -123,17 +104,14 @@ static void scaletexture(uchar * RESTRICT src, uint sw, uint sh, uint bpp, uint
}
}
-static void reorientnormals(uchar * RESTRICT src, int sw, int sh, int bpp, int stride, uchar * RESTRICT dst, bool flipx, bool flipy, bool swapxy)
-{
+static void reorientnormals(uchar * RESTRICT src, int sw, int sh, int bpp, int stride, uchar * RESTRICT dst, bool flipx, bool flipy, bool swapxy) {
int stridex = bpp, stridey = bpp;
if(swapxy) stridex *= sh; else stridey *= sw;
if(flipx) { dst += (sw-1)*stridex; stridex = -stridex; }
if(flipy) { dst += (sh-1)*stridey; stridey = -stridey; }
uchar *srcrow = src;
- loopi(sh)
- {
- for(uchar *curdst = dst, *src = srcrow, *end = &srcrow[sw*bpp]; src < end;)
- {
+ loopi(sh) {
+ for(uchar *curdst = dst, *src = srcrow, *end = &srcrow[sw*bpp]; src < end;) {
uchar nx = *src++, ny = *src++;
if(flipx) nx = 255-nx;
if(flipy) ny = 255-ny;
@@ -150,17 +128,14 @@ static void reorientnormals(uchar * RESTRICT src, int sw, int sh, int bpp, int s
}
template<int BPP>
-static inline void reorienttexture(uchar * RESTRICT src, int sw, int sh, int stride, uchar * RESTRICT dst, bool flipx, bool flipy, bool swapxy)
-{
+static inline void reorienttexture(uchar * RESTRICT src, int sw, int sh, int stride, uchar * RESTRICT dst, bool flipx, bool flipy, bool swapxy) {
int stridex = BPP, stridey = BPP;
if(swapxy) stridex *= sh; else stridey *= sw;
if(flipx) { dst += (sw-1)*stridex; stridex = -stridex; }
if(flipy) { dst += (sh-1)*stridey; stridey = -stridey; }
uchar *srcrow = src;
- loopi(sh)
- {
- for(uchar *curdst = dst, *src = srcrow, *end = &srcrow[sw*BPP]; src < end;)
- {
+ loopi(sh) {
+ for(uchar *curdst = dst, *src = srcrow, *end = &srcrow[sw*BPP]; src < end;) {
loopk(BPP) curdst[k] = *src++;
curdst += stridex;
}
@@ -169,10 +144,8 @@ static inline void reorienttexture(uchar * RESTRICT src, int sw, int sh, int str
}
}
-static void reorienttexture(uchar * RESTRICT src, int sw, int sh, int bpp, int stride, uchar * RESTRICT dst, bool flipx, bool flipy, bool swapxy)
-{
- switch(bpp)
- {
+static void reorienttexture(uchar * RESTRICT src, int sw, int sh, int bpp, int stride, uchar * RESTRICT dst, bool flipx, bool flipy, bool swapxy) {
+ switch(bpp) {
case 1: return reorienttexture<1>(src, sw, sh, stride, dst, flipx, flipy, swapxy);
case 2: return reorienttexture<2>(src, sw, sh, stride, dst, flipx, flipy, swapxy);
case 3: return reorienttexture<3>(src, sw, sh, stride, dst, flipx, flipy, swapxy);
@@ -180,23 +153,18 @@ static void reorienttexture(uchar * RESTRICT src, int sw, int sh, int bpp, int s
}
}
-static void reorients3tc(GLenum format, int blocksize, int w, int h, uchar *src, uchar *dst, bool flipx, bool flipy, bool swapxy, bool normals = false)
-{
+static void reorients3tc(GLenum format, int blocksize, int w, int h, uchar *src, uchar *dst, bool flipx, bool flipy, bool swapxy, bool normals = false) {
int bx1 = 0, by1 = 0, bx2 = min(w, 4), by2 = min(h, 4), bw = (w+3)/4, bh = (h+3)/4, stridex = blocksize, stridey = blocksize;
if(swapxy) stridex *= bw; else stridey *= bh;
if(flipx) { dst += (bw-1)*stridex; stridex = -stridex; bx1 += 4-bx2; bx2 = 4; }
if(flipy) { dst += (bh-1)*stridey; stridey = -stridey; by1 += 4-by2; by2 = 4; }
- loopi(bh)
- {
- for(uchar *curdst = dst, *end = &src[bw*blocksize]; src < end; src += blocksize, curdst += stridex)
- {
- if(format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
- {
+ loopi(bh) {
+ for(uchar *curdst = dst, *end = &src[bw*blocksize]; src < end; src += blocksize, curdst += stridex) {
+ if(format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) {
ullong salpha = lilswap(*(const ullong *)src), dalpha = 0;
uint xmask = flipx ? 15 : 0, ymask = flipy ? 15 : 0, xshift = 2, yshift = 4;
if(swapxy) swap(xshift, yshift);
- for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++)
- {
+ for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++) {
dalpha |= ((salpha&15) << (((xmask^x)<<xshift) + ((ymask^y)<<yshift)));
salpha >>= 4;
}
@@ -204,14 +172,12 @@ static void reorients3tc(GLenum format, int blocksize, int w, int h, uchar *src,
src += 8;
curdst += 8;
}
- else if(format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
- {
+ else if(format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) {
uchar alpha1 = src[0], alpha2 = src[1];
ullong salpha = lilswap(*(const ushort *)&src[2]) + ((ullong)lilswap(*(const uint *)&src[4]) << 16), dalpha = 0;
uint xmask = flipx ? 7 : 0, ymask = flipy ? 7 : 0, xshift = 0, yshift = 2;
if(swapxy) swap(xshift, yshift);
- for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++)
- {
+ for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++) {
dalpha |= ((salpha&7) << (3*((xmask^x)<<xshift) + ((ymask^y)<<yshift)));
salpha >>= 3;
}
@@ -223,24 +189,19 @@ static void reorients3tc(GLenum format, int blocksize, int w, int h, uchar *src,
src += 8;
curdst += 8;
}
-
ushort color1 = lilswap(*(const ushort *)src), color2 = lilswap(*(const ushort *)&src[2]);
uint sbits = lilswap(*(const uint *)&src[4]);
- if(normals)
- {
+ if(normals) {
ushort ncolor1 = color1, ncolor2 = color2;
- if(flipx)
- {
+ if(flipx) {
ncolor1 = (ncolor1 & ~0xF800) | (0xF800 - (ncolor1 & 0xF800));
ncolor2 = (ncolor2 & ~0xF800) | (0xF800 - (ncolor2 & 0xF800));
}
- if(flipy)
- {
+ if(flipy) {
ncolor1 = (ncolor1 & ~0x7E0) | (0x7E0 - (ncolor1 & 0x7E0));
ncolor2 = (ncolor2 & ~0x7E0) | (0x7E0 - (ncolor2 & 0x7E0));
}
- if(swapxy)
- {
+ if(swapxy) {
ncolor1 = (ncolor1 & 0x1F) | (((((ncolor1 >> 11) & 0x1F) * 0x3F) / 0x1F) << 5) | (((((ncolor1 >> 5) & 0x3F) * 0x1F) / 0x3F) << 11);
ncolor2 = (ncolor2 & 0x1F) | (((((ncolor2 >> 11) & 0x1F) * 0x3F) / 0x1F) << 5) | (((((ncolor2 >> 5) & 0x3F) * 0x1F) / 0x3F) << 11);
}
@@ -249,40 +210,33 @@ static void reorients3tc(GLenum format, int blocksize, int w, int h, uchar *src,
}
uint dbits = 0, xmask = flipx ? 3 : 0, ymask = flipy ? 3 : 0, xshift = 1, yshift = 3;
if(swapxy) swap(xshift, yshift);
- for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++)
- {
+ for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++) {
dbits |= ((sbits&3) << (((xmask^x)<<xshift) + ((ymask^y)<<yshift)));
sbits >>= 2;
}
*(ushort *)curdst = lilswap(color1);
*(ushort *)&curdst[2] = lilswap(color2);
*(uint *)&curdst[4] = lilswap(dbits);
-
if(blocksize > 8) { src -= 8; curdst -= 8; }
}
dst += stridey;
}
}
-static void reorientrgtc(GLenum format, int blocksize, int w, int h, uchar *src, uchar *dst, bool flipx, bool flipy, bool swapxy)
-{
+static void reorientrgtc(GLenum format, int blocksize, int w, int h, uchar *src, uchar *dst, bool flipx, bool flipy, bool swapxy) {
int bx1 = 0, by1 = 0, bx2 = min(w, 4), by2 = min(h, 4), bw = (w+3)/4, bh = (h+3)/4, stridex = blocksize, stridey = blocksize;
if(swapxy) stridex *= bw; else stridey *= bh;
if(flipx) { dst += (bw-1)*stridex; stridex = -stridex; bx1 += 4-bx2; bx2 = 4; }
if(flipy) { dst += (bh-1)*stridey; stridey = -stridey; by1 += 4-by2; by2 = 4; }
stridex -= blocksize;
- loopi(bh)
- {
- for(uchar *curdst = dst, *end = &src[bw*blocksize]; src < end; curdst += stridex)
- {
- loopj(blocksize/8)
- {
+ loopi(bh) {
+ for(uchar *curdst = dst, *end = &src[bw*blocksize]; src < end; curdst += stridex) {
+ loopj(blocksize/8) {
uchar val1 = src[0], val2 = src[1];
ullong sval = lilswap(*(const ushort *)&src[2]) + ((ullong)lilswap(*(const uint *)&src[4] )<< 16), dval = 0;
uint xmask = flipx ? 7 : 0, ymask = flipy ? 7 : 0, xshift = 0, yshift = 2;
if(swapxy) swap(xshift, yshift);
- for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++)
- {
+ for(int y = by1; y < by2; y++) for(int x = bx1; x < bx2; x++) {
dval |= ((sval&7) << (3*((xmask^x)<<xshift) + ((ymask^y)<<yshift)));
sval >>= 3;
}
@@ -299,26 +253,26 @@ static void reorientrgtc(GLenum format, int blocksize, int w, int h, uchar *src,
}
}
-#define writetex(t, body) do \
- { \
+#define writetex(t, body) do { \
+ \
uchar *dstrow = t.data; \
- loop(y, t.h) \
- { \
- for(uchar *dst = dstrow, *end = &dstrow[t.w*t.bpp]; dst < end; dst += t.bpp) \
- { \
+ loop(y, t.h) { \
+ \
+ for(uchar *dst = dstrow, *end = &dstrow[t.w*t.bpp]; dst < end; dst += t.bpp) { \
+ \
body; \
} \
dstrow += t.pitch; \
} \
} while(0)
-#define readwritetex(t, s, body) do \
- { \
+#define readwritetex(t, s, body) do { \
+ \
uchar *dstrow = t.data, *srcrow = s.data; \
- loop(y, t.h) \
- { \
- for(uchar *dst = dstrow, *src = srcrow, *end = &srcrow[s.w*s.bpp]; src < end; dst += t.bpp, src += s.bpp) \
- { \
+ loop(y, t.h) { \
+ \
+ for(uchar *dst = dstrow, *src = srcrow, *end = &srcrow[s.w*s.bpp]; src < end; dst += t.bpp, src += s.bpp) { \
+ \
body; \
} \
dstrow += t.pitch; \
@@ -326,13 +280,13 @@ static void reorientrgtc(GLenum format, int blocksize, int w, int h, uchar *src,
} \
} while(0)
-#define read2writetex(t, s1, src1, s2, src2, body) do \
- { \
+#define read2writetex(t, s1, src1, s2, src2, body) do { \
+ \
uchar *dstrow = t.data, *src1row = s1.data, *src2row = s2.data; \
- loop(y, t.h) \
- { \
- for(uchar *dst = dstrow, *end = &dstrow[t.w*t.bpp], *src1 = src1row, *src2 = src2row; dst < end; dst += t.bpp, src1 += s1.bpp, src2 += s2.bpp) \
- { \
+ loop(y, t.h) { \
+ \
+ for(uchar *dst = dstrow, *end = &dstrow[t.w*t.bpp], *src1 = src1row, *src2 = src2row; dst < end; dst += t.bpp, src1 += s1.bpp, src2 += s2.bpp) { \
+ \
body; \
} \
dstrow += t.pitch; \
@@ -341,30 +295,29 @@ static void reorientrgtc(GLenum format, int blocksize, int w, int h, uchar *src,
} \
} while(0)
-#define readwritergbtex(t, s, body) \
- { \
+#define readwritergbtex(t, s, body) { \
+ \
if(t.bpp >= 3) readwritetex(t, s, body); \
- else \
- { \
+ else { \
+ \
ImageData rgb(t.w, t.h, 3); \
read2writetex(rgb, t, orig, s, src, { dst[0] = dst[1] = dst[2] = orig[0]; body; }); \
t.replace(rgb); \
} \
}
-void forcergbimage(ImageData &s)
-{
+void forcergbimage(ImageData &s) {
if(s.bpp >= 3) return;
ImageData d(s.w, s.h, 3);
readwritetex(d, s, { dst[0] = dst[1] = dst[2] = src[0]; });
s.replace(d);
}
-#define readwritergbatex(t, s, body) \
- { \
+#define readwritergbatex(t, s, body) { \
+ \
if(t.bpp >= 4) { readwritetex(t, s, body); } \
- else \
- { \
+ else { \
+ \
ImageData rgba(t.w, t.h, 4); \
if(t.bpp==3) read2writetex(rgba, t, orig, s, src, { dst[0] = orig[0]; dst[1] = orig[1]; dst[2] = orig[2]; body; }); \
else read2writetex(rgba, t, orig, s, src, { dst[0] = dst[1] = dst[2] = orig[0]; body; }); \
@@ -372,8 +325,7 @@ void forcergbimage(ImageData &s)
} \
}
-void forcergbaimage(ImageData &s)
-{
+void forcergbaimage(ImageData &s) {
if(s.bpp >= 4) return;
ImageData d(s.w, s.h, 4);
if(s.bpp==3) readwritetex(d, s, { dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; });
@@ -381,38 +333,31 @@ void forcergbaimage(ImageData &s)
s.replace(d);
}
-void swizzleimage(ImageData &s)
-{
- if(s.bpp==2)
- {
+void swizzleimage(ImageData &s) {
+ if(s.bpp==2) {
ImageData d(s.w, s.h, 4);
readwritetex(d, s, { dst[0] = dst[1] = dst[2] = src[0]; dst[3] = src[1]; });
s.replace(d);
}
- else if(s.bpp==1)
- {
+ else if(s.bpp==1) {
ImageData d(s.w, s.h, 3);
readwritetex(d, s, { dst[0] = dst[1] = dst[2] = src[0]; });
s.replace(d);
}
}
-void texreorient(ImageData &s, bool flipx, bool flipy, bool swapxy, int type = TEX_DIFFUSE)
-{
+void texreorient(ImageData &s, bool flipx, bool flipy, bool swapxy, int type = TEX_DIFFUSE) {
ImageData d(swapxy ? s.h : s.w, swapxy ? s.w : s.h, s.bpp, s.levels, s.align, s.compressed);
- switch(s.compressed)
- {
+ switch(s.compressed) {
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[[fallthrough]];
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
[[fallthrough]];
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
[[fallthrough]];
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- {
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
uchar *dst = d.data, *src = s.data;
- loopi(s.levels)
- {
+ loopi(s.levels) {
reorients3tc(s.compressed, s.bpp, max(s.w>>i, 1), max(s.h>>i, 1), src, dst, flipx, flipy, swapxy, type==TEX_NORMAL);
src += s.calclevelsize(i);
dst += d.calclevelsize(i);
@@ -425,11 +370,9 @@ void texreorient(ImageData &s, bool flipx, bool flipy, bool swapxy, int type = T
[[fallthrough]];
case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
[[fallthrough]];
- case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
- {
+ case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT: {
uchar *dst = d.data, *src = s.data;
- loopi(s.levels)
- {
+ loopi(s.levels) {
reorientrgtc(s.compressed, s.bpp, max(s.w>>i, 1), max(s.h>>i, 1), src, dst, flipx, flipy, swapxy);
src += s.calclevelsize(i);
dst += d.calclevelsize(i);
@@ -444,29 +387,25 @@ void texreorient(ImageData &s, bool flipx, bool flipy, bool swapxy, int type = T
s.replace(d);
}
-extern const texrotation texrotations[8] =
-{
- { false, false, false }, // 0: default
- { false, true, true }, // 1: 90 degrees
- { true, true, false }, // 2: 180 degrees
- { true, false, true }, // 3: 270 degrees
- { true, false, false }, // 4: flip X
- { false, true, false }, // 5: flip Y
- { false, false, true }, // 6: transpose
+extern const texrotation texrotations[8] = {
+ { false, false, false }, // 0: default {
+ { false, true, true }, // 1: 90 degrees {
+ { true, true, false }, // 2: 180 degrees {
+ { true, false, true }, // 3: 270 degrees {
+ { true, false, false }, // 4: flip X {
+ { false, true, false }, // 5: flip Y {
+ { false, false, true }, // 6: transpose {
{ true, true, true }, // 7: flipped transpose
};
-void texrotate(ImageData &s, int numrots, int type = TEX_DIFFUSE)
-{
- if(numrots>=1 && numrots<=7)
- {
+void texrotate(ImageData &s, int numrots, int type = TEX_DIFFUSE) {
+ if(numrots>=1 && numrots<=7) {
const texrotation &r = texrotations[numrots];
texreorient(s, r.flipx, r.flipy, r.swapxy, type);
}
}
-void texoffset(ImageData &s, int xoffset, int yoffset)
-{
+void texoffset(ImageData &s, int xoffset, int yoffset) {
xoffset = max(xoffset, 0);
xoffset %= s.w;
yoffset = max(yoffset, 0);
@@ -474,8 +413,7 @@ void texoffset(ImageData &s, int xoffset, int yoffset)
if(!xoffset && !yoffset) return;
ImageData d(s.w, s.h, s.bpp);
uchar *src = s.data;
- loop(y, s.h)
- {
+ loop(y, s.h) {
uchar *dst = (uchar *)d.data+((y+yoffset)%d.h)*d.pitch;
memcpy(dst+xoffset*s.bpp, src, (s.w-xoffset)*s.bpp);
memcpy(dst, src+(s.w-xoffset)*s.bpp, xoffset*s.bpp);
@@ -484,8 +422,7 @@ void texoffset(ImageData &s, int xoffset, int yoffset)
s.replace(d);
}
-void texmad(ImageData &s, const vec &mul, const vec &add)
-{
+void texmad(ImageData &s, const vec &mul, const vec &add) {
if(s.bpp < 3 && (mul.x != mul.y || mul.y != mul.z || add.x != add.y || add.y != add.z))
swizzleimage(s);
int maxk = min(int(s.bpp), 3);
@@ -494,8 +431,7 @@ void texmad(ImageData &s, const vec &mul, const vec &add)
);
}
-void texcolorify(ImageData &s, const vec &color, vec weights)
-{
+void texcolorify(ImageData &s, const vec &color, vec weights) {
if(s.bpp < 3) return;
if(weights.iszero()) weights = vec(0.21f, 0.72f, 0.07f);
writetex(s,
@@ -504,8 +440,7 @@ void texcolorify(ImageData &s, const vec &color, vec weights)
);
}
-void texcolormask(ImageData &s, const vec &color1, const vec &color2)
-{
+void texcolormask(ImageData &s, const vec &color1, const vec &color2) {
if(s.bpp < 4) return;
ImageData d(s.w, s.h, 3);
readwritetex(d, s,
@@ -516,20 +451,17 @@ void texcolormask(ImageData &s, const vec &color1, const vec &color2)
s.replace(d);
}
-void texdup(ImageData &s, int srcchan, int dstchan)
-{
+void texdup(ImageData &s, int srcchan, int dstchan) {
if(srcchan==dstchan || max(srcchan, dstchan) >= s.bpp) return;
writetex(s, dst[dstchan] = dst[srcchan]);
}
-void texmix(ImageData &s, int c1, int c2, int c3, int c4)
-{
+void texmix(ImageData &s, int c1, int c2, int c3, int c4) {
int numchans = c1 < 0 ? 0 : (c2 < 0 ? 1 : (c3 < 0 ? 2 : (c4 < 0 ? 3 : 4)));
if(numchans <= 0) return;
ImageData d(s.w, s.h, numchans);
readwritetex(d, s,
- switch(numchans)
- {
+ switch(numchans) {
case 4: dst[3] = src[c4];
[[fallthrough]];
case 3: dst[2] = src[c3];
@@ -543,28 +475,23 @@ void texmix(ImageData &s, int c1, int c2, int c3, int c4)
s.replace(d);
}
-void texgrey(ImageData &s)
-{
+void texgrey(ImageData &s) {
if(s.bpp <= 2) return;
ImageData d(s.w, s.h, s.bpp >= 4 ? 2 : 1);
- if(s.bpp >= 4)
- {
+ if(s.bpp >= 4) {
readwritetex(d, s,
dst[0] = src[0];
dst[1] = src[3];
);
}
- else
- {
+ else {
readwritetex(d, s, dst[0] = src[0]);
}
s.replace(d);
}
-void texpremul(ImageData &s)
-{
- switch(s.bpp)
- {
+void texpremul(ImageData &s) {
+ switch(s.bpp) {
case 2:
writetex(s,
dst[0] = uchar((uint(dst[0])*uint(dst[1]))/255);
@@ -581,30 +508,25 @@ void texpremul(ImageData &s)
}
}
-void texagrad(ImageData &s, float x2, float y2, float x1, float y1)
-{
+void texagrad(ImageData &s, float x2, float y2, float x1, float y1) {
if(s.bpp != 2 && s.bpp != 4) return;
y1 = 1 - y1;
y2 = 1 - y2;
float minx = 1, miny = 1, maxx = 1, maxy = 1;
- if(x1 != x2)
- {
+ if(x1 != x2) {
minx = (0 - x1) / (x2 - x1);
maxx = (1 - x1) / (x2 - x1);
}
- if(y1 != y2)
- {
+ if(y1 != y2) {
miny = (0 - y1) / (y2 - y1);
maxy = (1 - y1) / (y2 - y1);
}
float dx = (maxx - minx)/max(s.w-1, 1),
dy = (maxy - miny)/max(s.h-1, 1),
cury = miny;
- for(uchar *dstrow = s.data + s.bpp - 1, *endrow = dstrow + s.h*s.pitch; dstrow < endrow; dstrow += s.pitch)
- {
+ for(uchar *dstrow = s.data + s.bpp - 1, *endrow = dstrow + s.h*s.pitch; dstrow < endrow; dstrow += s.pitch) {
float curx = minx;
- for(uchar *dst = dstrow, *end = &dstrow[s.w*s.bpp]; dst < end; dst += s.bpp)
- {
+ for(uchar *dst = dstrow, *end = &dstrow[s.w*s.bpp]; dst < end; dst += s.bpp) {
dst[0] = uchar(dst[0]*clamp(curx, 0.0f, 1.0f)*clamp(cury, 0.0f, 1.0f));
curx += dx;
}
@@ -626,23 +548,18 @@ VARFP(aniso, 0, 0, 16, initwarning("texture filtering", INIT_LOAD));
extern int usetexcompress;
-void setuptexcompress()
-{
+void setuptexcompress() {
if(!usetexcompress) return;
-
GLenum hint = GL_DONT_CARE;
- switch(texcompressquality)
- {
+ switch(texcompressquality) {
case 1: hint = GL_NICEST; break;
case 0: hint = GL_FASTEST; break;
}
glHint(GL_TEXTURE_COMPRESSION_HINT, hint);
}
-GLenum compressedformat(GLenum format, int w, int h, int force = 0)
-{
- if(usetexcompress && texcompress && force >= 0 && (force || max(w, h) >= texcompress)) switch(format)
- {
+GLenum compressedformat(GLenum format, int w, int h, int force = 0) {
+ if(usetexcompress && texcompress && force >= 0 && (force || max(w, h) >= texcompress)) switch(format) {
case GL_RGB5:
case GL_RGB8:
case GL_RGB: return usetexcompress > 1 ? GL_COMPRESSED_RGB_S3TC_DXT1_EXT : GL_COMPRESSED_RGB;
@@ -660,10 +577,8 @@ GLenum compressedformat(GLenum format, int w, int h, int force = 0)
return format;
}
-GLenum uncompressedformat(GLenum format)
-{
- switch(format)
- {
+GLenum uncompressedformat(GLenum format) {
+ switch(format) {
case GL_COMPRESSED_ALPHA:
return GL_ALPHA;
case GL_COMPRESSED_LUMINANCE:
@@ -690,10 +605,8 @@ GLenum uncompressedformat(GLenum format)
return GL_FALSE;
}
-int formatsize(GLenum format)
-{
- switch(format)
- {
+int formatsize(GLenum format) {
+ switch(format) {
case GL_RED:
case GL_LUMINANCE:
case GL_ALPHA: return 1;
@@ -707,61 +620,51 @@ int formatsize(GLenum format)
VARFP(usenp2, 0, 0, 1, initwarning("texture quality", INIT_LOAD));
-void resizetexture(int w, int h, bool mipmap, bool canreduce, GLenum target, int compress, int &tw, int &th)
-{
+void resizetexture(int w, int h, bool mipmap, bool canreduce, GLenum target, int compress, int &tw, int &th) {
int hwlimit = target==GL_TEXTURE_CUBE_MAP ? hwcubetexsize : hwtexsize,
sizelimit = mipmap && maxtexsize ? min(maxtexsize, hwlimit) : hwlimit;
- if(compress > 0 && !usetexcompress)
- {
+ if(compress > 0 && !usetexcompress) {
w = max(w/compress, 1);
h = max(h/compress, 1);
}
- if(canreduce && texreduce)
- {
+ if(canreduce && texreduce) {
w = max(w>>texreduce, 1);
h = max(h>>texreduce, 1);
}
w = min(w, sizelimit);
h = min(h, sizelimit);
- if(!usenp2 && (w&(w-1) || h&(h-1)))
- {
+ if(!usenp2 && (w&(w-1) || h&(h-1))) {
tw = th = 1;
while(tw < w) tw *= 2;
while(th < h) th *= 2;
if(w < tw - tw/4) tw /= 2;
if(h < th - th/4) th /= 2;
}
- else
- {
+ else {
tw = w;
th = h;
}
}
-void uploadtexture(int tnum, GLenum target, GLenum internal, int tw, int th, GLenum format, GLenum type, void *pixels, int pw, int ph, int pitch, bool mipmap)
-{
+void uploadtexture(int tnum, GLenum target, GLenum internal, int tw, int th, GLenum format, GLenum type, void *pixels, int pw, int ph, int pitch, bool mipmap) {
int bpp = formatsize(format), row = 0, rowalign = 0;
if(!pitch) pitch = pw*bpp;
uchar *buf = NULL;
- if(pw!=tw || ph!=th)
- {
+ if(pw!=tw || ph!=th) {
buf = new uchar[tw*th*bpp];
scaletexture((uchar *)pixels, pw, ph, bpp, pitch, buf, tw, th);
}
- else if(tw*bpp != pitch)
- {
+ else if(tw*bpp != pitch) {
row = pitch/bpp;
rowalign = texalign(pixels, pitch, 1);
while(rowalign > 0 && ((row*bpp + rowalign - 1)/rowalign)*rowalign != pitch) rowalign >>= 1;
- if(!rowalign)
- {
+ if(!rowalign) {
row = 0;
buf = new uchar[tw*th*bpp];
loopi(th) memcpy(&buf[i*tw*bpp], &((uchar *)pixels)[i*pitch], tw*bpp);
}
}
- for(int level = 0, align = 0, mw = tw, mh = th;; level++)
- {
+ for(int level = 0, align = 0, mw = tw, mh = th;; level++) {
uchar *src = buf ? buf : (uchar *)pixels;
if(buf) pitch = mw*bpp;
int srcalign = row > 0 ? rowalign : texalign(src, pitch, 1);
@@ -773,8 +676,7 @@ void uploadtexture(int tnum, GLenum target, GLenum internal, int tw, int th, GLe
int srcw = mw, srch = mh;
if(mw > 1) mw /= 2;
if(mh > 1) mh /= 2;
- if(src)
- {
+ if(src) {
if(!buf) buf = new uchar[mw*mh*bpp];
scaletexture(src, srcw, srch, bpp, pitch, buf, mw, mh);
}
@@ -782,16 +684,13 @@ void uploadtexture(int tnum, GLenum target, GLenum internal, int tw, int th, GLe
if(buf) delete[] buf;
}
-void uploadcompressedtexture(GLenum target, GLenum subtarget, GLenum format, int w, int h, uchar *data, int align, int blocksize, int levels, bool mipmap)
-{
+void uploadcompressedtexture(GLenum target, GLenum subtarget, GLenum format, int w, int h, uchar *data, int align, int blocksize, int levels, bool mipmap) {
int hwlimit = target==GL_TEXTURE_CUBE_MAP ? hwcubetexsize : hwtexsize,
sizelimit = levels > 1 && maxtexsize ? min(maxtexsize, hwlimit) : hwlimit;
int level = 0;
- loopi(levels)
- {
+ loopi(levels) {
int size = ((w + align-1)/align) * ((h + align-1)/align) * blocksize;
- if(w <= sizelimit && h <= sizelimit)
- {
+ if(w <= sizelimit && h <= sizelimit) {
glCompressedTexImage2D_(subtarget, level, format, w, h, 0, size, data);
level++;
if(!mipmap) break;
@@ -803,10 +702,8 @@ void uploadcompressedtexture(GLenum target, GLenum subtarget, GLenum format, int
}
}
-GLenum textarget(GLenum subtarget)
-{
- switch(subtarget)
- {
+GLenum textarget(GLenum subtarget) {
+ switch(subtarget) {
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
@@ -818,20 +715,17 @@ GLenum textarget(GLenum subtarget)
return subtarget;
}
-const GLint *swizzlemask(GLenum format)
-{
+const GLint *swizzlemask(GLenum format) {
static const GLint luminance[4] = { GL_RED, GL_RED, GL_RED, GL_ONE };
static const GLint luminancealpha[4] = { GL_RED, GL_RED, GL_RED, GL_GREEN };
- switch(format)
- {
+ switch(format) {
case GL_RED: return luminance;
case GL_RG: return luminancealpha;
}
return NULL;
}
-void setuptexparameters(int tnum, void *pixels, int clamp, int filter, GLenum format, GLenum target, bool swizzle)
-{
+void setuptexparameters(int tnum, void *pixels, int clamp, int filter, GLenum format, GLenum target, bool swizzle) {
glBindTexture(target, tnum);
glTexParameteri(target, GL_TEXTURE_WRAP_S, clamp&1 ? GL_CLAMP_TO_EDGE : (clamp&0x100 ? GL_MIRRORED_REPEAT : GL_REPEAT));
glTexParameteri(target, GL_TEXTURE_WRAP_T, clamp&2 ? GL_CLAMP_TO_EDGE : (clamp&0x200 ? GL_MIRRORED_REPEAT : GL_REPEAT));
@@ -843,48 +737,40 @@ void setuptexparameters(int tnum, void *pixels, int clamp, int filter, GLenum fo
(bilinear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_LINEAR) :
(bilinear ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_NEAREST)) :
(filter && bilinear ? GL_LINEAR : GL_NEAREST));
- if(swizzle && hasTRG && hasTSW)
- {
+ if(swizzle && hasTRG && hasTSW) {
const GLint *mask = swizzlemask(format);
if(mask) glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, mask);
}
}
-static GLenum textype(GLenum &component, GLenum &format)
-{
+static GLenum textype(GLenum &component, GLenum &format) {
GLenum type = GL_UNSIGNED_BYTE;
- switch(component)
- {
+ switch(component) {
case GL_R16F:
case GL_R32F:
if(!format) format = GL_RED;
type = GL_FLOAT;
break;
-
case GL_RG16F:
case GL_RG32F:
if(!format) format = GL_RG;
type = GL_FLOAT;
break;
-
case GL_RGB16F:
case GL_RGB32F:
if(!format) format = GL_RGB;
type = GL_FLOAT;
break;
-
case GL_RGBA16F:
case GL_RGBA32F:
if(!format) format = GL_RGBA;
type = GL_FLOAT;
break;
-
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32:
if(!format) format = GL_DEPTH_COMPONENT;
break;
-
case GL_RGB5:
case GL_RGB8:
case GL_RGB10:
@@ -893,7 +779,6 @@ static GLenum textype(GLenum &component, GLenum &format)
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
if(!format) format = GL_RGB;
break;
-
case GL_RGB5_A1:
case GL_RGBA8:
case GL_RGB10_A2:
@@ -904,41 +789,35 @@ static GLenum textype(GLenum &component, GLenum &format)
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
if(!format) format = GL_RGBA;
break;
-
case GL_DEPTH_STENCIL:
case GL_DEPTH24_STENCIL8:
if(!format) format = GL_DEPTH_STENCIL;
type = GL_UNSIGNED_INT_24_8;
break;
-
case GL_R8:
case GL_R16:
case GL_COMPRESSED_RED:
case GL_COMPRESSED_RED_RGTC1:
if(!format) format = GL_RED;
break;
-
case GL_RG8:
case GL_RG16:
case GL_COMPRESSED_RG:
case GL_COMPRESSED_RG_RGTC2:
if(!format) format = GL_RG;
break;
-
case GL_LUMINANCE8:
case GL_LUMINANCE16:
case GL_COMPRESSED_LUMINANCE:
case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
if(!format) format = GL_LUMINANCE;
break;
-
case GL_LUMINANCE8_ALPHA8:
case GL_LUMINANCE16_ALPHA16:
case GL_COMPRESSED_LUMINANCE_ALPHA:
case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
if(!format) format = GL_LUMINANCE_ALPHA;
break;
-
case GL_ALPHA8:
case GL_ALPHA16:
case GL_COMPRESSED_ALPHA:
@@ -949,24 +828,21 @@ static GLenum textype(GLenum &component, GLenum &format)
return type;
}
-void createtexture(int tnum, int w, int h, void *pixels, int clamp, int filter, GLenum component, GLenum subtarget, int pw, int ph, int pitch, bool resize, GLenum format, bool swizzle)
-{
+void createtexture(int tnum, int w, int h, void *pixels, int clamp, int filter, GLenum component, GLenum subtarget, int pw, int ph, int pitch, bool resize, GLenum format, bool swizzle) {
GLenum target = textarget(subtarget), type = textype(component, format);
if(filter >= 0 && clamp >= 0) setuptexparameters(tnum, pixels, clamp, filter, format, target, swizzle);
if(!pw) pw = w;
if(!ph) ph = h;
int tw = w, th = h;
bool mipmap = filter > 1 && pixels;
- if(resize && pixels)
- {
+ if(resize && pixels) {
resizetexture(w, h, mipmap, false, target, 0, tw, th);
if(mipmap) component = compressedformat(component, tw, th);
}
uploadtexture(tnum, subtarget, component, tw, th, format, type, pixels, pw, ph, pitch, mipmap);
}
-void createcompressedtexture(int tnum, int w, int h, uchar *data, int align, int blocksize, int levels, int clamp, int filter, GLenum format, GLenum subtarget, bool swizzle = false)
-{
+void createcompressedtexture(int tnum, int w, int h, uchar *data, int align, int blocksize, int levels, int clamp, int filter, GLenum format, GLenum subtarget, bool swizzle = false) {
GLenum target = textarget(subtarget);
if(filter >= 0 && clamp >= 0) setuptexparameters(tnum, data, clamp, filter, format, target);
uploadcompressedtexture(target, subtarget, format, w, h, data, align, blocksize, levels, filter > 1);
@@ -976,10 +852,8 @@ hashnameset<Texture> textures;
Texture *notexture = NULL; // used as default, ensured to be loaded
-static GLenum texformat(int bpp, bool swizzle = false)
-{
- switch(bpp)
- {
+static GLenum texformat(int bpp, bool swizzle = false) {
+ switch(bpp) {
case 1: return hasTRG && (hasTSW || !glcompat || !swizzle) ? GL_RED : GL_LUMINANCE;
case 2: return hasTRG && (hasTSW || !glcompat || !swizzle) ? GL_RG : GL_LUMINANCE_ALPHA;
case 3: return GL_RGB;
@@ -988,10 +862,8 @@ static GLenum texformat(int bpp, bool swizzle = false)
}
}
-static bool alphaformat(GLenum format)
-{
- switch(format)
- {
+static bool alphaformat(GLenum format) {
+ switch(format) {
case GL_ALPHA:
case GL_LUMINANCE_ALPHA:
case GL_RG:
@@ -1002,49 +874,40 @@ static bool alphaformat(GLenum format)
}
}
-int texalign(const void *data, int w, int bpp)
-{
+int texalign(const void *data, int w, int bpp) {
int stride = w*bpp;
if(stride&1) return 1;
if(stride&2) return 2;
return 4;
}
-static Texture *newtexture(Texture *t, const char *rname, ImageData &s, int clamp = 0, bool mipit = true, bool canreduce = false, bool transient = false, int compress = 0)
-{
- if(!t)
- {
+static Texture *newtexture(Texture *t, const char *rname, ImageData &s, int clamp = 0, bool mipit = true, bool canreduce = false, bool transient = false, int compress = 0) {
+ if(!t) {
char *key = newstring(rname);
t = &textures[key];
t->name = key;
}
-
t->clamp = clamp;
t->mipmap = mipit;
t->type = Texture::IMAGE;
if(transient) t->type |= Texture::TRANSIENT;
if(clamp&0x300) t->type |= Texture::MIRROR;
- if(!s.data)
- {
+ if(!s.data) {
t->type |= Texture::STUB;
t->w = t->h = t->xs = t->ys = t->bpp = 0;
return t;
}
-
bool swizzle = !(clamp&0x10000);
GLenum format;
- if(s.compressed)
- {
+ if(s.compressed) {
format = uncompressedformat(s.compressed);
t->bpp = formatsize(format);
t->type |= Texture::COMPRESSED;
}
- else
- {
+ else {
format = texformat(s.bpp, swizzle);
t->bpp = s.bpp;
- if(swizzle && hasTRG && !hasTSW && swizzlemask(format))
- {
+ if(swizzle && hasTRG && !hasTSW && swizzlemask(format)) {
swizzleimage(s);
format = texformat(s.bpp, swizzle);
t->bpp = s.bpp;
@@ -1053,23 +916,19 @@ static Texture *newtexture(Texture *t, const char *rname, ImageData &s, int clam
if(alphaformat(format)) t->type |= Texture::ALPHA;
t->w = t->xs = s.w;
t->h = t->ys = s.h;
-
int filter = !canreduce || reducefilter ? (mipit ? 2 : 1) : 0;
glGenTextures(1, &t->id);
- if(s.compressed)
- {
+ if(s.compressed) {
uchar *data = s.data;
int levels = s.levels, level = 0;
- if(canreduce && texreduce) loopi(min(texreduce, s.levels-1))
- {
+ if(canreduce && texreduce) loopi(min(texreduce, s.levels-1)) {
data += s.calclevelsize(level++);
levels--;
if(t->w > 1) t->w /= 2;
if(t->h > 1) t->h /= 2;
}
int sizelimit = mipit && maxtexsize ? min(maxtexsize, hwtexsize) : hwtexsize;
- while(t->w > sizelimit || t->h > sizelimit)
- {
+ while(t->w > sizelimit || t->h > sizelimit) {
data += s.calclevelsize(level++);
levels--;
if(t->w > 1) t->w /= 2;
@@ -1077,8 +936,7 @@ static Texture *newtexture(Texture *t, const char *rname, ImageData &s, int clam
}
createcompressedtexture(t->id, t->w, t->h, data, s.align, s.bpp, levels, clamp, filter, s.compressed, GL_TEXTURE_2D, swizzle);
}
- else
- {
+ else {
resizetexture(t->w, t->h, mipit, canreduce, GL_TEXTURE_2D, compress, t->w, t->h);
GLenum component = compressedformat(format, t->w, t->h, compress);
createtexture(t->id, t->w, t->h, s.data, clamp, filter, component, GL_TEXTURE_2D, t->xs, t->ys, s.pitch, false, format, swizzle);
@@ -1094,29 +952,24 @@ static Texture *newtexture(Texture *t, const char *rname, ImageData &s, int clam
#define RGBMASKS 0x0000ff, 0x00ff00, 0xff0000, 0
#endif
-SDL_Surface *wrapsurface(void *data, int width, int height, int bpp)
-{
- switch(bpp)
- {
+SDL_Surface *wrapsurface(void *data, int width, int height, int bpp) {
+ switch(bpp) {
case 3: return SDL_CreateRGBSurfaceFrom(data, width, height, 8*bpp, bpp*width, RGBMASKS);
case 4: return SDL_CreateRGBSurfaceFrom(data, width, height, 8*bpp, bpp*width, RGBAMASKS);
}
return NULL;
}
-SDL_Surface *creatergbsurface(SDL_Surface *os)
-{
+SDL_Surface *creatergbsurface(SDL_Surface *os) {
SDL_Surface *ns = SDL_CreateRGBSurface(SDL_SWSURFACE, os->w, os->h, 24, RGBMASKS);
if(ns) SDL_BlitSurface(os, NULL, ns, NULL);
SDL_FreeSurface(os);
return ns;
}
-SDL_Surface *creatergbasurface(SDL_Surface *os)
-{
+SDL_Surface *creatergbasurface(SDL_Surface *os) {
SDL_Surface *ns = SDL_CreateRGBSurface(SDL_SWSURFACE, os->w, os->h, 32, RGBAMASKS);
- if(ns)
- {
+ if(ns) {
SDL_SetSurfaceBlendMode(os, SDL_BLENDMODE_NONE);
SDL_BlitSurface(os, NULL, ns, NULL);
}
@@ -1124,11 +977,9 @@ SDL_Surface *creatergbasurface(SDL_Surface *os)
return ns;
}
-bool checkgrayscale(SDL_Surface *s)
-{
+bool checkgrayscale(SDL_Surface *s) {
// gray scale images have 256 levels, no colorkey, and the palette is a ramp
- if(s->format->palette)
- {
+ if(s->format->palette) {
if(s->format->palette->ncolors != 256 || SDL_GetColorKey(s, NULL) >= 0) return false;
const SDL_Color *colors = s->format->palette->colors;
loopi(256) if(colors[i].r != i || colors[i].g != i || colors[i].b != i) return false;
@@ -1136,17 +987,14 @@ bool checkgrayscale(SDL_Surface *s)
return true;
}
-SDL_Surface *fixsurfaceformat(SDL_Surface *s)
-{
+SDL_Surface *fixsurfaceformat(SDL_Surface *s) {
if(!s) return NULL;
- if(!s->pixels || min(s->w, s->h) <= 0 || s->format->BytesPerPixel <= 0)
- {
+ if(!s->pixels || min(s->w, s->h) <= 0 || s->format->BytesPerPixel <= 0) {
SDL_FreeSurface(s);
return NULL;
}
static const uint rgbmasks[] = { RGBMASKS }, rgbamasks[] = { RGBAMASKS };
- switch(s->format->BytesPerPixel)
- {
+ switch(s->format->BytesPerPixel) {
case 1:
if(!checkgrayscale(s)) return SDL_GetColorKey(s, NULL) >= 0 ? creatergbasurface(s) : creatergbsurface(s);
break;
@@ -1162,12 +1010,10 @@ SDL_Surface *fixsurfaceformat(SDL_Surface *s)
return s;
}
-void texflip(ImageData &s)
-{
+void texflip(ImageData &s) {
ImageData d(s.w, s.h, s.bpp);
uchar *dst = d.data, *src = &s.data[s.pitch*s.h];
- loopi(s.h)
- {
+ loopi(s.h) {
src -= s.pitch;
memcpy(dst, src, s.bpp*s.w);
dst += d.pitch;
@@ -1175,12 +1021,10 @@ void texflip(ImageData &s)
s.replace(d);
}
-void texnormal(ImageData &s, int emphasis)
-{
+void texnormal(ImageData &s, int emphasis) {
ImageData d(s.w, s.h, 3);
uchar *src = s.data, *dst = d.data;
- loop(y, s.h) loop(x, s.w)
- {
+ loop(y, s.h) loop(x, s.w) {
vec normal(0.0f, 0.0f, 255.0f/emphasis);
normal.x += src[y*s.pitch + ((x+s.w-1)%s.w)*s.bpp];
normal.x -= src[y*s.pitch + ((x+1)%s.w)*s.bpp];
@@ -1195,16 +1039,13 @@ void texnormal(ImageData &s, int emphasis)
}
template<int n, int bpp, bool normals>
-static void blurtexture(int w, int h, uchar *dst, const uchar *src, int margin)
-{
- static const int weights3x3[9] =
- {
+static void blurtexture(int w, int h, uchar *dst, const uchar *src, int margin) {
+ static const int weights3x3[9] = {
0x10, 0x20, 0x10,
0x20, 0x40, 0x20,
0x10, 0x20, 0x10
};
- static const int weights5x5[25] =
- {
+ static const int weights5x5[25] = {
0x05, 0x05, 0x09, 0x05, 0x05,
0x05, 0x0A, 0x14, 0x0A, 0x05,
0x09, 0x14, 0x28, 0x14, 0x09,
@@ -1219,15 +1060,12 @@ static void blurtexture(int w, int h, uchar *dst, const uchar *src, int margin)
nextoffset1 = stride + mstride*bpp,
nextoffset2 = stride - mstride*bpp;
src += margin*(stride + bpp);
- for(int y = margin; y < h-margin; y++)
- {
- for(int x = margin; x < w-margin; x++)
- {
+ for(int y = margin; y < h-margin; y++) {
+ for(int x = margin; x < w-margin; x++) {
int dr = 0, dg = 0, db = 0;
const uchar *p = src - startoffset;
const int *m = mat + mstartoffset;
- for(int t = y; t >= y-n; t--, p -= nextoffset1, m -= mstride)
- {
+ for(int t = y; t >= y-n; t--, p -= nextoffset1, m -= mstride) {
if(t < 0) p += stride;
int a = 0;
if(n > 1) { a += m[-2]; if(x >= 2) { dr += p[0] * a; dg += p[1] * a; db += p[2] * a; a = 0; } p += bpp; }
@@ -1238,8 +1076,7 @@ static void blurtexture(int w, int h, uchar *dst, const uchar *src, int margin)
}
p = src - startoffset + stride;
m = mat + mstartoffset + mstride;
- for(int t = y+1; t <= y+n; t++, p += nextoffset2, m += mstride)
- {
+ for(int t = y+1; t <= y+n; t++, p += nextoffset2, m += mstride) {
if(t >= h) p -= stride;
int a = 0;
if(n > 1) { a += m[-2]; if(x >= 2) { dr += p[0] * a; dg += p[1] * a; db += p[2] * a; a = 0; } p += bpp; }
@@ -1248,16 +1085,14 @@ static void blurtexture(int w, int h, uchar *dst, const uchar *src, int margin)
if(x+1 < w) { cr = p[0]; cg = p[1]; cb = p[2]; } dr += cr * m[1]; dg += cg * m[1]; db += cb * m[1]; p += bpp;
if(n > 1) { if(x+2 < w) { cr = p[0]; cg = p[1]; cb = p[2]; } dr += cr * m[2]; dg += cg * m[2]; db += cb * m[2]; p += bpp; }
}
- if(normals)
- {
+ if(normals) {
vec v(dr-0x7F80, dg-0x7F80, db-0x7F80);
float mag = 127.5f/v.magnitude();
dst[0] = uchar(v.x*mag + 127.5f);
dst[1] = uchar(v.y*mag + 127.5f);
dst[2] = uchar(v.z*mag + 127.5f);
}
- else
- {
+ else {
dst[0] = dr>>8;
dst[1] = dg>>8;
dst[2] = db>>8;
@@ -1270,10 +1105,8 @@ static void blurtexture(int w, int h, uchar *dst, const uchar *src, int margin)
}
}
-void blurtexture(int n, int bpp, int w, int h, uchar *dst, const uchar *src, int margin)
-{
- switch((clamp(n, 1, 2)<<4) | bpp)
- {
+void blurtexture(int n, int bpp, int w, int h, uchar *dst, const uchar *src, int margin) {
+ switch((clamp(n, 1, 2)<<4) | bpp) {
case 0x13: blurtexture<1, 3, false>(w, h, dst, src, margin); break;
case 0x23: blurtexture<2, 3, false>(w, h, dst, src, margin); break;
case 0x14: blurtexture<1, 4, false>(w, h, dst, src, margin); break;
@@ -1281,50 +1114,41 @@ void blurtexture(int n, int bpp, int w, int h, uchar *dst, const uchar *src, int
}
}
-void blurnormals(int n, int w, int h, bvec *dst, const bvec *src, int margin)
-{
- switch(clamp(n, 1, 2))
- {
+void blurnormals(int n, int w, int h, bvec *dst, const bvec *src, int margin) {
+ switch(clamp(n, 1, 2)) {
case 1: blurtexture<1, 3, true>(w, h, dst->v, src->v, margin); break;
case 2: blurtexture<2, 3, true>(w, h, dst->v, src->v, margin); break;
}
}
-void texblur(ImageData &s, int n, int r)
-{
+void texblur(ImageData &s, int n, int r) {
if(s.bpp < 3) return;
- loopi(r)
- {
+ loopi(r) {
ImageData d(s.w, s.h, s.bpp);
blurtexture(n, s.bpp, s.w, s.h, d.data, s.data);
s.replace(d);
}
}
-void scaleimage(ImageData &s, int w, int h)
-{
+void scaleimage(ImageData &s, int w, int h) {
ImageData d(w, h, s.bpp);
scaletexture(s.data, s.w, s.h, s.bpp, s.pitch, d.data, w, h);
s.replace(d);
}
-bool canloadsurface(const char *name)
-{
+bool canloadsurface(const char *name) {
stream *f = openfile(name, "rb");
if(!f) return false;
delete f;
return true;
}
-SDL_Surface *loadsurface(const char *name)
-{
+SDL_Surface *loadsurface(const char *name) {
SDL_Surface *s = NULL;
stream *z = openzipfile(name, "rb");
- if(z)
- {
+ if(z) {
SDL_RWops *rw = z->rwops();
- if(rw)
- {
+ if(rw) {
char *ext = (char *)strrchr(name, '.');
if(ext) ++ext;
s = IMG_LoadTyped_RW(rw, 0, ext);
@@ -1336,12 +1160,10 @@ SDL_Surface *loadsurface(const char *name)
return fixsurfaceformat(s);
}
-static vec parsevec(const char *arg)
-{
+static vec parsevec(const char *arg) {
vec v(0, 0, 0);
int i = 0;
- for(; arg[0] && (!i || arg[0]=='/') && i<3; arg += strcspn(arg, "/,><"), i++)
- {
+ for(; arg[0] && (!i || arg[0]=='/') && i<3; arg += strcspn(arg, "/,><"), i++) {
if(i) arg++;
v[i] = atof(arg);
}
@@ -1349,38 +1171,30 @@ static vec parsevec(const char *arg)
return v;
}
-static bool texturedata(ImageData &d, const char *tname, Slot::Tex *tex = NULL, bool msg = true, int *compress = NULL, int *wrap = NULL)
-{
+static bool texturedata(ImageData &d, const char *tname, Slot::Tex *tex = NULL, bool msg = true, int *compress = NULL, int *wrap = NULL) {
const char *cmds = NULL, *file = tname;
-
- if(!tname)
- {
+ if(!tname) {
if(!tex) return false;
- if(tex->name[0]=='<')
- {
+ if(tex->name[0]=='<') {
cmds = tex->name;
file = strrchr(tex->name, '>');
if(!file) { if(msg) conoutf(CON_ERROR, "could not load texture packages/%s", tex->name); return false; }
file++;
}
else file = tex->name;
-
static string pname;
formatstring(pname, "packages/%s", file);
file = path(pname);
}
- else if(tname[0]=='<')
- {
+ else if(tname[0]=='<') {
cmds = tname;
file = strrchr(tname, '>');
if(!file) { if(msg) conoutf(CON_ERROR, "could not load texture %s", tname); return false; }
file++;
}
-
int flen = strlen(file);
- bool raw = !compress, guess = false;
- for(const char *pcmds = cmds; pcmds;)
- {
+ bool guess = false;
+ for(const char *pcmds = cmds; pcmds;) {
#define PARSETEXCOMMANDS(cmds) \
const char *cmd = NULL, *end = NULL, *arg[4] = { NULL, NULL, NULL, NULL }; \
cmd = &cmds[1]; \
@@ -1388,32 +1202,25 @@ static bool texturedata(ImageData &d, const char *tname, Slot::Tex *tex = NULL,
if(!end) break; \
cmds = strchr(cmd, '<'); \
size_t len = strcspn(cmd, ":,><"); \
- loopi(4) \
- { \
+ loopi(4) { \
+ \
arg[i] = strchr(i ? arg[i-1] : cmd, i ? ',' : ':'); \
if(!arg[i] || arg[i] >= end) arg[i] = ""; \
else arg[i]++; \
}
PARSETEXCOMMANDS(pcmds);
- if(matchstring(cmd, len, "thumbnail"))
- {
- raw = true;
+ if(matchstring(cmd, len, "thumbnail")) {
guess = flen >= 4 && !strchr(file+flen-4, '.');
}
else if(matchstring(cmd, len, "stub")) return canloadsurface(file);
}
-
if(msg) renderprogress(loadprogress, file);
-
- if(!d.data)
- {
+ if(!d.data) {
SDL_Surface *s = NULL;
- if(guess)
- {
+ if(guess) {
static const char *exts[] = {".jpg", ".png"};
string ext;
- loopi(sizeof(exts)/sizeof(exts[0]))
- {
+ loopi(sizeof(exts)/sizeof(exts[0])) {
copystring(ext, file);
concatstring(ext, exts[i]);
s = loadsurface(ext);
@@ -1427,16 +1234,13 @@ static bool texturedata(ImageData &d, const char *tname, Slot::Tex *tex = NULL,
if(max(s->w, s->h) > (1<<12)) { SDL_FreeSurface(s); conoutf(CON_ERROR, "texture size exceeded %dx%d pixels: %s", 1<<12, 1<<12, file); return false; }
d.wrap(s);
}
-
- while(cmds)
- {
+ while(cmds) {
PARSETEXCOMMANDS(cmds);
if(d.compressed) goto compressed;
if(matchstring(cmd, len, "mad")) texmad(d, parsevec(arg[0]), parsevec(arg[1]));
else if(matchstring(cmd, len, "colorify")) texcolorify(d, parsevec(arg[0]), parsevec(arg[1]));
else if(matchstring(cmd, len, "colormask")) texcolormask(d, parsevec(arg[0]), *arg[1] ? parsevec(arg[1]) : vec(1, 1, 1));
- else if(matchstring(cmd, len, "normal"))
- {
+ else if(matchstring(cmd, len, "normal")) {
int emphasis = atoi(arg[0]);
texnormal(d, emphasis > 0 ? emphasis : 3);
}
@@ -1446,25 +1250,21 @@ static bool texturedata(ImageData &d, const char *tname, Slot::Tex *tex = NULL,
else if(matchstring(cmd, len, "reorient")) texreorient(d, atoi(arg[0])>0, atoi(arg[1])>0, atoi(arg[2])>0, tex ? tex->type : TEX_DIFFUSE);
else if(matchstring(cmd, len, "mix")) texmix(d, *arg[0] ? atoi(arg[0]) : -1, *arg[1] ? atoi(arg[1]) : -1, *arg[2] ? atoi(arg[2]) : -1, *arg[3] ? atoi(arg[3]) : -1);
else if(matchstring(cmd, len, "grey")) texgrey(d);
- else if(matchstring(cmd, len, "blur"))
- {
+ else if(matchstring(cmd, len, "blur")) {
int emphasis = atoi(arg[0]), repeat = atoi(arg[1]);
texblur(d, emphasis > 0 ? clamp(emphasis, 1, 2) : 1, repeat > 0 ? repeat : 1);
}
else if(matchstring(cmd, len, "premul")) texpremul(d);
else if(matchstring(cmd, len, "agrad")) texagrad(d, atof(arg[0]), atof(arg[1]), atof(arg[2]), atof(arg[3]));
- else if(matchstring(cmd, len, "compress"))
- {
+ else if(matchstring(cmd, len, "compress")) {
int scale = atoi(arg[0]);
if(scale <= 0) scale = 2;
if(compress) *compress = scale;
}
- else if(matchstring(cmd, len, "nocompress"))
- {
+ else if(matchstring(cmd, len, "nocompress")) {
if(compress) *compress = -1;
}
- else if(matchstring(cmd, len, "thumbnail"))
- {
+ else if(matchstring(cmd, len, "thumbnail")) {
int w = atoi(arg[0]), h = atoi(arg[1]);
if(w <= 0 || w > (1<<12)) w = 64;
if(h <= 0 || h > (1<<12)) h = w;
@@ -1472,32 +1272,26 @@ static bool texturedata(ImageData &d, const char *tname, Slot::Tex *tex = NULL,
}
else
compressed:
- if(matchstring(cmd, len, "mirror"))
- {
+ if(matchstring(cmd, len, "mirror")) {
if(wrap) *wrap |= 0x300;
}
- else if(matchstring(cmd, len, "noswizzle"))
- {
+ else if(matchstring(cmd, len, "noswizzle")) {
if(wrap) *wrap |= 0x10000;
}
}
-
return true;
}
-uchar *loadalphamask(Texture *t)
-{
+uchar *loadalphamask(Texture *t) {
if(t->alphamask) return t->alphamask;
if(!(t->type&Texture::ALPHA)) return NULL;
ImageData s;
if(!texturedata(s, t->name, NULL, false) || !s.data || s.compressed) return NULL;
t->alphamask = new uchar[s.h * ((s.w+7)/8)];
uchar *srcrow = s.data, *dst = t->alphamask-1;
- loop(y, s.h)
- {
+ loop(y, s.h) {
uchar *src = srcrow+s.bpp-1;
- loop(x, s.w)
- {
+ loop(x, s.w) {
int offset = x%8;
if(!offset) *++dst = 0;
if(*src) *dst |= 1<<offset;
@@ -1508,8 +1302,7 @@ uchar *loadalphamask(Texture *t)
return t->alphamask;
}
-Texture *textureload(const char *name, int clamp, bool mipit, bool msg)
-{
+Texture *textureload(const char *name, int clamp, bool mipit, bool msg) {
string tname;
copystring(tname, name);
Texture *t = textures.access(path(tname));
@@ -1520,8 +1313,7 @@ Texture *textureload(const char *name, int clamp, bool mipit, bool msg)
return notexture;
}
-bool settexture(const char *name, int clamp)
-{
+bool settexture(const char *name, int clamp) {
Texture *t = textureload(name, clamp, true, false);
glBindTexture(GL_TEXTURE_2D, t->id);
return t != notexture;
@@ -1532,20 +1324,17 @@ vector<Slot *> slots;
Slot dummyslot;
VSlot dummyvslot(&dummyslot);
-void texturereset(int *n)
-{
+void texturereset(int *n) {
if(!(identflags&IDF_OVERRIDDEN) && !game::allowedittoggle()) return;
resetslotshader();
int limit = clamp(*n, 0, slots.length());
- for(int i = limit; i < slots.length(); i++)
- {
+ for(int i = limit; i < slots.length(); i++) {
Slot *s = slots[i];
for(VSlot *vs = s->variants; vs; vs = vs->next) vs->slot = &dummyslot;
delete s;
}
slots.setsize(limit);
- while(vslots.length())
- {
+ while(vslots.length()) {
VSlot *vs = vslots.last();
if(vs->slot != &dummyslot || vs->changed) break;
delete vslots.pop();
@@ -1557,8 +1346,7 @@ COMMAND(texturereset, "i");
static int compactedvslots = 0, compactvslotsprogress = 0, clonedvslots = 0;
static bool markingvslots = false;
-void clearslots()
-{
+void clearslots() {
resetslotshader();
slots.deletecontents();
vslots.deletecontents();
@@ -1567,44 +1355,35 @@ void clearslots()
static void assignvslot(VSlot &vs);
-static inline void assignvslotlayer(VSlot &vs)
-{
- if(vs.layer && vslots.inrange(vs.layer))
- {
+static inline void assignvslotlayer(VSlot &vs) {
+ if(vs.layer && vslots.inrange(vs.layer)) {
VSlot &layer = *vslots[vs.layer];
if(layer.index < 0) assignvslot(layer);
}
}
-static void assignvslot(VSlot &vs)
-{
+static void assignvslot(VSlot &vs) {
vs.index = compactedvslots++;
assignvslotlayer(vs);
}
-void compactvslot(int &index)
-{
- if(vslots.inrange(index))
- {
+void compactvslot(int &index) {
+ if(vslots.inrange(index)) {
VSlot &vs = *vslots[index];
if(vs.index < 0) assignvslot(vs);
if(!markingvslots) index = vs.index;
}
}
-void compactvslot(VSlot &vs)
-{
+void compactvslot(VSlot &vs) {
if(vs.index < 0) assignvslot(vs);
}
-void compactvslots(cube *c, int n)
-{
+void compactvslots(cube *c, int n) {
if((compactvslotsprogress++&0xFFF)==0) renderprogress(min(float(compactvslotsprogress)/allocnodes, 1.0f), markingvslots ? "marking slots..." : "compacting slots...");
- loopi(n)
- {
+ loopi(n) {
if(c[i].children) compactvslots(c[i].children);
- else loopj(6) if(vslots.inrange(c[i].texture[j]))
- {
+ else loopj(6) if(vslots.inrange(c[i].texture[j])) {
VSlot &vs = *vslots[c[i].texture[j]];
if(vs.index < 0) assignvslot(vs);
if(!markingvslots) c[i].texture[j] = vs.index;
@@ -1612,8 +1391,7 @@ void compactvslots(cube *c, int n)
}
}
-int compactvslots()
-{
+int compactvslots() {
clonedvslots = 0;
markingvslots = false;
compactedvslots = 0;
@@ -1621,38 +1399,31 @@ int compactvslots()
loopv(vslots) vslots[i]->index = -1;
loopv(slots) slots[i]->variants->index = compactedvslots++;
loopv(slots) assignvslotlayer(*slots[i]->variants);
- loopv(vslots)
- {
+ loopv(vslots) {
VSlot &vs = *vslots[i];
if(!vs.changed && vs.index < 0) { markingvslots = true; break; }
}
compactvslots(worldroot);
int total = compactedvslots;
compacteditvslots();
- loopv(vslots)
- {
+ loopv(vslots) {
VSlot *vs = vslots[i];
if(vs->changed) continue;
- while(vs->next)
- {
+ while(vs->next) {
if(vs->next->index < 0) vs->next = vs->next->next;
else vs = vs->next;
}
}
- if(markingvslots)
- {
+ if(markingvslots) {
markingvslots = false;
compactedvslots = 0;
compactvslotsprogress = 0;
int lastdiscard = 0;
- loopv(vslots)
- {
+ loopv(vslots) {
VSlot &vs = *vslots[i];
if(vs.changed || (vs.index < 0 && !vs.next)) vs.index = -1;
- else
- {
- while(lastdiscard < i)
- {
+ else {
+ while(lastdiscard < i) {
VSlot &ds = *vslots[lastdiscard++];
if(!ds.changed && ds.index < 0) ds.index = compactedvslots++;
}
@@ -1664,13 +1435,11 @@ int compactvslots()
compacteditvslots();
}
compactmruvslots();
- loopv(vslots)
- {
+ loopv(vslots) {
VSlot &vs = *vslots[i];
if(vs.index >= 0 && vs.layer && vslots.inrange(vs.layer)) vs.layer = vslots[vs.layer]->index;
}
- loopv(vslots)
- {
+ loopv(vslots) {
while(vslots[i]->index >= 0 && vslots[i]->index != i)
swap(vslots[i], vslots[vslots[i]->index]);
}
@@ -1679,8 +1448,7 @@ int compactvslots()
return total;
}
-ICOMMAND(compactvslots, "", (),
-{
+ICOMMAND(compactvslots, "", (), {
extern int nompedit;
if(nompedit && multiplayer()) return;
compactvslots();
@@ -1689,11 +1457,9 @@ ICOMMAND(compactvslots, "", (),
static Slot &loadslot(Slot &s, bool forceload);
-static void clampvslotoffset(VSlot &dst, Slot *slot = NULL)
-{
+static void clampvslotoffset(VSlot &dst, Slot *slot = NULL) {
if(!slot) slot = dst.slot;
- if(slot && slot->sts.inrange(0))
- {
+ if(slot && slot->sts.inrange(0)) {
if(!slot->loaded) loadslot(*slot, false);
Texture *t = slot->sts[0].t;
int xs = t->xs, ys = t->ys;
@@ -1705,49 +1471,39 @@ static void clampvslotoffset(VSlot &dst, Slot *slot = NULL)
else dst.offset.max(0);
}
-static void propagatevslot(VSlot &dst, const VSlot &src, int diff, bool edit = false)
-{
+static void propagatevslot(VSlot &dst, const VSlot &src, int diff, bool edit = false) {
if(diff & (1<<VSLOT_SHPARAM)) loopv(src.params) dst.params.add(src.params[i]);
if(diff & (1<<VSLOT_SCALE)) dst.scale = src.scale;
- if(diff & (1<<VSLOT_ROTATION))
- {
+ if(diff & (1<<VSLOT_ROTATION)) {
dst.rotation = src.rotation;
if(edit && !dst.offset.iszero()) clampvslotoffset(dst);
}
- if(diff & (1<<VSLOT_OFFSET))
- {
+ if(diff & (1<<VSLOT_OFFSET)) {
dst.offset = src.offset;
if(edit) clampvslotoffset(dst);
}
if(diff & (1<<VSLOT_SCROLL)) dst.scroll = src.scroll;
if(diff & (1<<VSLOT_LAYER)) dst.layer = src.layer;
- if(diff & (1<<VSLOT_ALPHA))
- {
+ if(diff & (1<<VSLOT_ALPHA)) {
dst.alphafront = src.alphafront;
dst.alphaback = src.alphaback;
}
if(diff & (1<<VSLOT_COLOR)) dst.colorscale = src.colorscale;
}
-static void propagatevslot(VSlot *root, int changed)
-{
- for(VSlot *vs = root->next; vs; vs = vs->next)
- {
+static void propagatevslot(VSlot *root, int changed) {
+ for(VSlot *vs = root->next; vs; vs = vs->next) {
int diff = changed & ~vs->changed;
if(diff) propagatevslot(*vs, *root, diff);
}
}
-static void mergevslot(VSlot &dst, const VSlot &src, int diff, Slot *slot = NULL)
-{
- if(diff & (1<<VSLOT_SHPARAM)) loopv(src.params)
- {
+static void mergevslot(VSlot &dst, const VSlot &src, int diff, Slot *slot = NULL) {
+ if(diff & (1<<VSLOT_SHPARAM)) loopv(src.params) {
const SlotShaderParam &sp = src.params[i];
- loopvj(dst.params)
- {
+ loopvj(dst.params) {
SlotShaderParam &dp = dst.params[j];
- if(sp.name == dp.name)
- {
+ if(sp.name == dp.name) {
memcpy(dp.val, sp.val, sizeof(dp.val));
goto nextparam;
}
@@ -1755,42 +1511,35 @@ static void mergevslot(VSlot &dst, const VSlot &src, int diff, Slot *slot = NULL
dst.params.add(sp);
nextparam:;
}
- if(diff & (1<<VSLOT_SCALE))
- {
+ if(diff & (1<<VSLOT_SCALE)) {
dst.scale = clamp(dst.scale*src.scale, 1/8.0f, 8.0f);
}
- if(diff & (1<<VSLOT_ROTATION))
- {
+ if(diff & (1<<VSLOT_ROTATION)) {
dst.rotation = clamp(dst.rotation + src.rotation, 0, 7);
if(!dst.offset.iszero()) clampvslotoffset(dst, slot);
}
- if(diff & (1<<VSLOT_OFFSET))
- {
+ if(diff & (1<<VSLOT_OFFSET)) {
dst.offset.add(src.offset);
clampvslotoffset(dst, slot);
}
if(diff & (1<<VSLOT_SCROLL)) dst.scroll.add(src.scroll);
if(diff & (1<<VSLOT_LAYER)) dst.layer = src.layer;
- if(diff & (1<<VSLOT_ALPHA))
- {
+ if(diff & (1<<VSLOT_ALPHA)) {
dst.alphafront = src.alphafront;
dst.alphaback = src.alphaback;
}
if(diff & (1<<VSLOT_COLOR)) dst.colorscale.mul(src.colorscale);
}
-void mergevslot(VSlot &dst, const VSlot &src, const VSlot &delta)
-{
+void mergevslot(VSlot &dst, const VSlot &src, const VSlot &delta) {
dst.changed = src.changed | delta.changed;
propagatevslot(dst, src, (1<<VSLOT_NUM)-1);
mergevslot(dst, delta, delta.changed, src.slot);
}
-static VSlot *reassignvslot(Slot &owner, VSlot *vs)
-{
+static VSlot *reassignvslot(Slot &owner, VSlot *vs) {
owner.variants = vs;
- while(vs)
- {
+ while(vs) {
vs->slot = &owner;
vs->linked = false;
vs = vs->next;
@@ -1798,21 +1547,17 @@ static VSlot *reassignvslot(Slot &owner, VSlot *vs)
return owner.variants;
}
-static VSlot *emptyvslot(Slot &owner)
-{
+static VSlot *emptyvslot(Slot &owner) {
int offset = 0;
loopvrev(slots) if(slots[i]->variants) { offset = slots[i]->variants->index + 1; break; }
for(int i = offset; i < vslots.length(); i++) if(!vslots[i]->changed) return reassignvslot(owner, vslots[i]);
return vslots.add(new VSlot(&owner, vslots.length()));
}
-static bool comparevslot(const VSlot &dst, const VSlot &src, int diff)
-{
- if(diff & (1<<VSLOT_SHPARAM))
- {
+static bool comparevslot(const VSlot &dst, const VSlot &src, int diff) {
+ if(diff & (1<<VSLOT_SHPARAM)) {
if(src.params.length() != dst.params.length()) return false;
- loopv(src.params)
- {
+ loopv(src.params) {
const SlotShaderParam &sp = src.params[i], &dp = dst.params[i];
if(sp.name != dp.name || memcmp(sp.val, dp.val, sizeof(sp.val))) return false;
}
@@ -1827,53 +1572,43 @@ static bool comparevslot(const VSlot &dst, const VSlot &src, int diff)
return true;
}
-void packvslot(vector<uchar> &buf, const VSlot &src)
-{
- if(src.changed & (1<<VSLOT_SHPARAM))
- {
- loopv(src.params)
- {
+void packvslot(vector<uchar> &buf, const VSlot &src) {
+ if(src.changed & (1<<VSLOT_SHPARAM)) {
+ loopv(src.params) {
const SlotShaderParam &p = src.params[i];
buf.put(VSLOT_SHPARAM);
sendstring(p.name, buf);
loopj(4) putfloat(buf, p.val[j]);
}
}
- if(src.changed & (1<<VSLOT_SCALE))
- {
+ if(src.changed & (1<<VSLOT_SCALE)) {
buf.put(VSLOT_SCALE);
putfloat(buf, src.scale);
}
- if(src.changed & (1<<VSLOT_ROTATION))
- {
+ if(src.changed & (1<<VSLOT_ROTATION)) {
buf.put(VSLOT_ROTATION);
putint(buf, src.rotation);
}
- if(src.changed & (1<<VSLOT_OFFSET))
- {
+ if(src.changed & (1<<VSLOT_OFFSET)) {
buf.put(VSLOT_OFFSET);
putint(buf, src.offset.x);
putint(buf, src.offset.y);
}
- if(src.changed & (1<<VSLOT_SCROLL))
- {
+ if(src.changed & (1<<VSLOT_SCROLL)) {
buf.put(VSLOT_SCROLL);
putfloat(buf, src.scroll.x);
putfloat(buf, src.scroll.y);
}
- if(src.changed & (1<<VSLOT_LAYER))
- {
+ if(src.changed & (1<<VSLOT_LAYER)) {
buf.put(VSLOT_LAYER);
putuint(buf, vslots.inrange(src.layer) && !vslots[src.layer]->changed ? src.layer : 0);
}
- if(src.changed & (1<<VSLOT_ALPHA))
- {
+ if(src.changed & (1<<VSLOT_ALPHA)) {
buf.put(VSLOT_ALPHA);
putfloat(buf, src.alphafront);
putfloat(buf, src.alphaback);
}
- if(src.changed & (1<<VSLOT_COLOR))
- {
+ if(src.changed & (1<<VSLOT_COLOR)) {
buf.put(VSLOT_COLOR);
putfloat(buf, src.colorscale.r);
putfloat(buf, src.colorscale.g);
@@ -1882,28 +1617,22 @@ void packvslot(vector<uchar> &buf, const VSlot &src)
buf.put(0xFF);
}
-void packvslot(vector<uchar> &buf, int index)
-{
+void packvslot(vector<uchar> &buf, int index) {
if(vslots.inrange(index)) packvslot(buf, *vslots[index]);
else buf.put(0xFF);
}
-void packvslot(vector<uchar> &buf, const VSlot *vs)
-{
+void packvslot(vector<uchar> &buf, const VSlot *vs) {
if(vs) packvslot(buf, *vs);
else buf.put(0xFF);
}
-bool unpackvslot(ucharbuf &buf, VSlot &dst, bool delta)
-{
- while(buf.remaining())
- {
+bool unpackvslot(ucharbuf &buf, VSlot &dst, bool delta) {
+ while(buf.remaining()) {
int changed = buf.get();
if(changed >= 0x80) break;
- switch(changed)
- {
- case VSLOT_SHPARAM:
- {
+ switch(changed) {
+ case VSLOT_SHPARAM: {
string name;
getstring(name, buf);
SlotShaderParam p = { name[0] ? getshaderparamname(name) : NULL, -1, { 0, 0, 0, 0 } };
@@ -1929,8 +1658,7 @@ bool unpackvslot(ucharbuf &buf, VSlot &dst, bool delta)
dst.scroll.x = getfloat(buf);
dst.scroll.y = getfloat(buf);
break;
- case VSLOT_LAYER:
- {
+ case VSLOT_LAYER: {
int tex = getuint(buf);
dst.layer = vslots.inrange(tex) ? tex : 0;
break;
@@ -1953,10 +1681,8 @@ bool unpackvslot(ucharbuf &buf, VSlot &dst, bool delta)
return true;
}
-VSlot *findvslot(Slot &slot, const VSlot &src, const VSlot &delta)
-{
- for(VSlot *dst = slot.variants; dst; dst = dst->next)
- {
+VSlot *findvslot(Slot &slot, const VSlot &src, const VSlot &delta) {
+ for(VSlot *dst = slot.variants; dst; dst = dst->next) {
if((!dst->changed || dst->changed == (src.changed | delta.changed)) &&
comparevslot(*dst, src, src.changed & ~delta.changed) &&
comparevslot(*dst, delta, delta.changed))
@@ -1965,8 +1691,7 @@ VSlot *findvslot(Slot &slot, const VSlot &src, const VSlot &delta)
return NULL;
}
-static VSlot *clonevslot(const VSlot &src, const VSlot &delta)
-{
+static VSlot *clonevslot(const VSlot &src, const VSlot &delta) {
VSlot *dst = vslots.add(new VSlot(src.slot, vslots.length()));
dst->changed = src.changed | delta.changed;
propagatevslot(*dst, src, ((1<<VSLOT_NUM)-1) & ~delta.changed);
@@ -1976,28 +1701,23 @@ static VSlot *clonevslot(const VSlot &src, const VSlot &delta)
VARP(autocompactvslots, 0, 256, 0x10000);
-VSlot *editvslot(const VSlot &src, const VSlot &delta)
-{
+VSlot *editvslot(const VSlot &src, const VSlot &delta) {
VSlot *exists = findvslot(*src.slot, src, delta);
if(exists) return exists;
- if(vslots.length()>=0x10000)
- {
+ if(vslots.length()>=0x10000) {
compactvslots();
allchanged();
if(vslots.length()>=0x10000) return NULL;
}
- if(autocompactvslots && ++clonedvslots >= autocompactvslots)
- {
+ if(autocompactvslots && ++clonedvslots >= autocompactvslots) {
compactvslots();
allchanged();
}
return clonevslot(src, delta);
}
-static void fixinsidefaces(cube *c, const ivec &o, int size, int tex)
-{
- loopi(8)
- {
+static void fixinsidefaces(cube *c, const ivec &o, int size, int tex) {
+ loopi(8) {
ivec co(i, o, size);
if(c[i].children) fixinsidefaces(c[i].children, co, size>>1, tex);
else loopj(6) if(!visibletris(c[i], j, co, size))
@@ -2005,40 +1725,35 @@ static void fixinsidefaces(cube *c, const ivec &o, int size, int tex)
}
}
-ICOMMAND(fixinsidefaces, "i", (int *tex),
-{
+ICOMMAND(fixinsidefaces, "i", (int *tex), {
extern int nompedit;
if(noedit(true) || (nompedit && multiplayer())) return;
fixinsidefaces(worldroot, ivec(0, 0, 0), worldsize>>1, *tex && vslots.inrange(*tex) ? *tex : DEFAULT_GEOM);
allchanged();
});
-const struct slottex
-{
+const struct slottex {
const char *name;
int id;
-} slottexs[] =
-{
- {"c", TEX_DIFFUSE},
- {"u", TEX_UNKNOWN},
- {"d", TEX_DECAL},
- {"n", TEX_NORMAL},
- {"s", TEX_SPEC},
- {"z", TEX_DEPTH},
- {"a", TEX_ALPHA}
+} slottexs[] = {
+ {
+ "c", TEX_DIFFUSE}, {
+ "u", TEX_UNKNOWN}, {
+ "d", TEX_DECAL}, {
+ "n", TEX_NORMAL}, {
+ "s", TEX_SPEC}, {
+ "z", TEX_DEPTH}, {
+ "a", TEX_ALPHA}
};
-int findslottex(const char *name)
-{
- loopi(sizeof(slottexs)/sizeof(slottex))
- {
+int findslottex(const char *name) {
+ loopi(sizeof(slottexs)/sizeof(slottex)) {
if(!strcmp(slottexs[i].name, name)) return slottexs[i].id;
}
return -1;
}
-void texture(char *type, char *name, int *rot, int *xoffset, int *yoffset, float *scale)
-{
+void texture(char *type, char *name, int *rot, int *xoffset, int *yoffset, float *scale) {
if(slots.length()>=0x10000) return;
int tnum = findslottex(type);
if(tnum<0) tnum = atoi(type);
@@ -2052,8 +1767,7 @@ void texture(char *type, char *name, int *rot, int *xoffset, int *yoffset, float
st.t = NULL;
copystring(st.name, name);
path(st.name);
- if(tnum==TEX_DIFFUSE)
- {
+ if(tnum==TEX_DIFFUSE) {
setslotshader(s);
VSlot &vs = *emptyvslot(s);
vs.reset();
@@ -2066,8 +1780,7 @@ void texture(char *type, char *name, int *rot, int *xoffset, int *yoffset, float
COMMAND(texture, "ssiiif");
-void texscroll(float *scrollS, float *scrollT)
-{
+void texscroll(float *scrollS, float *scrollT) {
if(slots.empty()) return;
Slot &s = *slots.last();
s.variants->scroll = vec2(*scrollS, *scrollT).div(1000.0f);
@@ -2075,8 +1788,7 @@ void texscroll(float *scrollS, float *scrollT)
}
COMMAND(texscroll, "ff");
-void texoffset_(int *xoffset, int *yoffset)
-{
+void texoffset_(int *xoffset, int *yoffset) {
if(slots.empty()) return;
Slot &s = *slots.last();
s.variants->offset = ivec2(*xoffset, *yoffset).max(0);
@@ -2084,8 +1796,7 @@ void texoffset_(int *xoffset, int *yoffset)
}
COMMANDN(texoffset, texoffset_, "ii");
-void texrotate_(int *rot)
-{
+void texrotate_(int *rot) {
if(slots.empty()) return;
Slot &s = *slots.last();
s.variants->rotation = clamp(*rot, 0, 7);
@@ -2093,8 +1804,7 @@ void texrotate_(int *rot)
}
COMMANDN(texrotate, texrotate_, "i");
-void texscale(float *scale)
-{
+void texscale(float *scale) {
if(slots.empty()) return;
Slot &s = *slots.last();
s.variants->scale = *scale <= 0 ? 1 : *scale;
@@ -2102,8 +1812,7 @@ void texscale(float *scale)
}
COMMAND(texscale, "f");
-void texlayer(int *layer, char *name, int *mode, float *scale)
-{
+void texlayer(int *layer, char *name, int *mode, float *scale) {
if(slots.empty()) return;
Slot &s = *slots.last();
s.variants->layer = *layer < 0 ? max(slots.length()-1+*layer, 0) : *layer;
@@ -2114,8 +1823,7 @@ void texlayer(int *layer, char *name, int *mode, float *scale)
}
COMMAND(texlayer, "isif");
-void texalpha(float *front, float *back)
-{
+void texalpha(float *front, float *back) {
if(slots.empty()) return;
Slot &s = *slots.last();
s.variants->alphafront = clamp(*front, 0.0f, 1.0f);
@@ -2124,8 +1832,7 @@ void texalpha(float *front, float *back)
}
COMMAND(texalpha, "ff");
-void texcolor(float *r, float *g, float *b)
-{
+void texcolor(float *r, float *g, float *b) {
if(slots.empty()) return;
Slot &s = *slots.last();
s.variants->colorscale = vec(clamp(*r, 0.0f, 1.0f), clamp(*g, 0.0f, 1.0f), clamp(*b, 0.0f, 1.0f));
@@ -2133,48 +1840,40 @@ void texcolor(float *r, float *g, float *b)
}
COMMAND(texcolor, "fff");
-static int findtextype(Slot &s, int type, int last = -1)
-{
+static int findtextype(Slot &s, int type, int last = -1) {
for(int i = last+1; i<s.sts.length(); i++) if((type&(1<<s.sts[i].type)) && s.sts[i].combined<0) return i;
return -1;
}
-static void mergespec(ImageData &c, ImageData &s)
-{
+static void mergespec(ImageData &c, ImageData &s) {
if(s.bpp < 3) { readwritergbatex(c, s, dst[3] = src[0]; ); }
else { readwritergbatex(c, s, dst[3] = (int(src[0]) + int(src[1]) + int(src[2]))/3; ); }
}
-static void mergedepth(ImageData &c, ImageData &z)
-{
+static void mergedepth(ImageData &c, ImageData &z) {
readwritergbatex(c, z, dst[3] = src[0]; );
}
-static void mergealpha(ImageData &c, ImageData &s)
-{
+static void mergealpha(ImageData &c, ImageData &s) {
if(s.bpp < 3) { readwritergbatex(c, s, dst[3] = src[0]; ); }
else if(s.bpp == 3) { readwritergbatex(c, s, dst[3] = (int(src[0]) + int(src[1]) + int(src[2]))/3; ); }
else { readwritergbatex(c, s, dst[3] = src[3]; ); }
}
-static void addname(vector<char> &key, Slot &slot, Slot::Tex &t, bool combined = false, const char *prefix = NULL)
-{
+static void addname(vector<char> &key, Slot &slot, Slot::Tex &t, bool combined = false, const char *prefix = NULL) {
if(combined) key.add('&');
if(prefix) { while(*prefix) key.add(*prefix++); }
defformatstring(tname, "packages/%s", t.name);
for(const char *s = path(tname); *s; key.add(*s++));
}
-static void texcombine(Slot &s, int index, Slot::Tex &t, bool forceload = false)
-{
+static void texcombine(Slot &s, int index, Slot::Tex &t, bool forceload = false) {
vector<char> key;
addname(key, s, t);
int texmask = 0;
- if(!forceload) switch(t.type)
- {
+ if(!forceload) switch(t.type) {
case TEX_DIFFUSE:
- case TEX_NORMAL:
- {
+ case TEX_NORMAL: {
int i = findtextype(s, t.type==TEX_DIFFUSE ? (s.texmask&(1<<TEX_SPEC) ? 1<<TEX_SPEC : 1<<TEX_ALPHA) : (s.texmask&(1<<TEX_DEPTH) ? 1<<TEX_DEPTH : 1<<TEX_ALPHA));
if(i<0) break;
texmask |= 1<<s.sts[i].type;
@@ -2189,20 +1888,17 @@ static void texcombine(Slot &s, int index, Slot::Tex &t, bool forceload = false)
int compress = 0, wrap = 0;
ImageData ts;
if(!texturedata(ts, NULL, &t, true, &compress, &wrap)) { t.t = notexture; return; }
- if(!ts.compressed) switch(t.type)
- {
+ if(!ts.compressed) switch(t.type) {
case TEX_DIFFUSE:
case TEX_NORMAL:
- loopv(s.sts)
- {
+ loopv(s.sts) {
Slot::Tex &a = s.sts[i];
if(a.combined!=index) continue;
ImageData as;
if(!texturedata(as, NULL, &a)) continue;
//if(ts.bpp!=4) forcergbaimage(ts);
if(as.w!=ts.w || as.h!=ts.h) scaleimage(as, ts.w, ts.h);
- switch(a.type)
- {
+ switch(a.type) {
case TEX_SPEC: mergespec(ts, as); break;
case TEX_DEPTH: mergedepth(ts, as); break;
case TEX_ALPHA: mergealpha(ts, as); break;
@@ -2214,15 +1910,12 @@ static void texcombine(Slot &s, int index, Slot::Tex &t, bool forceload = false)
t.t = newtexture(NULL, key.getbuf(), ts, wrap, true, true, true, compress);
}
-static Slot &loadslot(Slot &s, bool forceload)
-{
+static Slot &loadslot(Slot &s, bool forceload) {
linkslotshader(s);
- loopv(s.sts)
- {
+ loopv(s.sts) {
Slot::Tex &t = s.sts[i];
if(t.combined >= 0) continue;
- switch(t.type)
- {
+ switch(t.type) {
default:
texcombine(s, i, t, forceload);
break;
@@ -2232,17 +1925,14 @@ static Slot &loadslot(Slot &s, bool forceload)
return s;
}
-Slot &lookupslot(int index, bool load)
-{
+Slot &lookupslot(int index, bool load) {
Slot &s = slots.inrange(index) ? *slots[index] : (slots.inrange(DEFAULT_GEOM) ? *slots[DEFAULT_GEOM] : dummyslot);
return s.loaded || !load ? s : loadslot(s, false);
}
-VSlot &lookupvslot(int index, bool load)
-{
+VSlot &lookupvslot(int index, bool load) {
VSlot &s = vslots.inrange(index) && vslots[index]->slot ? *vslots[index] : (slots.inrange(DEFAULT_GEOM) && slots[DEFAULT_GEOM]->variants ? *slots[DEFAULT_GEOM]->variants : dummyvslot);
- if(load && !s.linked)
- {
+ if(load && !s.linked) {
if(!s.slot->loaded) loadslot(*s.slot, false);
linkvslotshader(s);
s.linked = true;
@@ -2250,17 +1940,14 @@ VSlot &lookupvslot(int index, bool load)
return s;
}
-void linkslotshaders()
-{
+void linkslotshaders() {
loopv(slots) if(slots[i]->loaded) linkslotshader(*slots[i]);
loopv(vslots) if(vslots[i]->linked) linkvslotshader(*vslots[i]);
}
-Texture *loadthumbnail(Slot &slot)
-{
+Texture *loadthumbnail(Slot &slot) {
if(slot.thumbnail) return slot.thumbnail;
- if(!slot.variants)
- {
+ if(!slot.variants) {
slot.thumbnail = notexture;
return slot.thumbnail;
}
@@ -2269,17 +1956,14 @@ Texture *loadthumbnail(Slot &slot)
linkvslotshader(vslot, false);
vector<char> name;
if(vslot.colorscale == vec(1, 1, 1)) addname(name, slot, slot.sts[0], false, "<thumbnail>");
- else
- {
+ else {
defformatstring(prefix, "<thumbnail:%.2f/%.2f/%.2f>", vslot.colorscale.x, vslot.colorscale.y, vslot.colorscale.z);
addname(name, slot, slot.sts[0], false, prefix);
}
VSlot *layer = vslot.layer ? &lookupvslot(vslot.layer, false) : NULL;
- if(layer)
- {
+ if(layer) {
if(layer->colorscale == vec(1, 1, 1)) addname(name, *layer->slot, layer->slot->sts[0], true, "<layer>");
- else
- {
+ else {
defformatstring(prefix, "<layer:%.2f/%.2f/%.2f>", vslot.colorscale.x, vslot.colorscale.y, vslot.colorscale.z);
addname(name, *layer->slot, layer->slot->sts[0], true, prefix);
}
@@ -2287,30 +1971,25 @@ Texture *loadthumbnail(Slot &slot)
name.add('\0');
Texture *t = textures.access(path(name.getbuf()));
if(t) slot.thumbnail = t;
- else
- {
+ else {
ImageData s, g, l;
texturedata(s, NULL, &slot.sts[0], false);
if(layer) texturedata(l, NULL, &layer->slot->sts[0], false);
if(!s.data) t = slot.thumbnail = notexture;
- else
- {
+ else {
if(vslot.colorscale != vec(1, 1, 1)) texmad(s, vslot.colorscale, vec(0, 0, 0));
int xs = s.w, ys = s.h;
if(s.w > 64 || s.h > 64) scaleimage(s, min(s.w, 64), min(s.h, 64));
- if(g.data)
- {
+ if(g.data) {
if(g.w != s.w || g.h != s.h) scaleimage(g, s.w, s.h);
}
- if(l.data)
- {
+ if(l.data) {
if(layer->colorscale != vec(1, 1, 1)) texmad(l, layer->colorscale, vec(0, 0, 0));
if(l.w != s.w/2 || l.h != s.h/2) scaleimage(l, s.w/2, s.h/2);
forcergbimage(s);
forcergbimage(l);
uchar *dstrow = &s.data[s.pitch*l.h + s.bpp*l.w], *srcrow = l.data;
- loop(y, l.h)
- {
+ loop(y, l.h) {
for(uchar *dst = dstrow, *src = srcrow, *end = &srcrow[l.w*l.bpp]; src < end; dst += s.bpp, src += l.bpp)
loopk(3) dst[k] = src[k];
dstrow += s.pitch;
@@ -2327,13 +2006,10 @@ Texture *loadthumbnail(Slot &slot)
return t;
}
-void loadlayermasks()
-{
- loopv(slots)
- {
+void loadlayermasks() {
+ loopv(slots) {
Slot &slot = *slots[i];
- if(slot.loaded && slot.layermaskname && !slot.layermask)
- {
+ if(slot.loaded && slot.layermaskname && !slot.layermask) {
slot.layermask = new ImageData;
texturedata(*slot.layermask, slot.layermaskname);
if(!slot.layermask->data) DELETEP(slot.layermask);
@@ -2341,34 +2017,28 @@ void loadlayermasks()
}
}
-void cleanuptexture(Texture *t)
-{
+void cleanuptexture(Texture *t) {
DELETEA(t->alphamask);
if(t->id) { glDeleteTextures(1, &t->id); t->id = 0; }
if(t->type&Texture::TRANSIENT) textures.remove(t->name);
}
-void cleanuptextures()
-{
+void cleanuptextures() {
loopv(slots) slots[i]->cleanup();
loopv(vslots) vslots[i]->cleanup();
enumerate(textures, Texture, tex, cleanuptexture(&tex));
}
-bool reloadtexture(const char *name)
-{
+bool reloadtexture(const char *name) {
Texture *t = textures.access(path(name, true));
if(t) return reloadtexture(*t);
return true;
}
-bool reloadtexture(Texture &tex)
-{
+bool reloadtexture(Texture &tex) {
if(tex.id) return true;
- switch(tex.type&Texture::TYPE)
- {
- case Texture::IMAGE:
- {
+ switch(tex.type&Texture::TYPE) {
+ case Texture::IMAGE: {
int compress = 0;
ImageData s;
if(!texturedata(s, tex.name, NULL, true, &compress) || !newtexture(&tex, NULL, s, tex.clamp, tex.mipmap, false, false, compress)) return false;
@@ -2378,16 +2048,14 @@ bool reloadtexture(Texture &tex)
return true;
}
-void reloadtex(char *name)
-{
+void reloadtex(char *name) {
Texture *t = textures.access(path(name, true));
if(!t) { conoutf(CON_ERROR, "texture %s is not loaded", name); return; }
if(t->type&Texture::TRANSIENT) { conoutf(CON_ERROR, "can't reload transient texture %s", name); return; }
DELETEA(t->alphamask);
Texture oldtex = *t;
t->id = 0;
- if(!reloadtexture(*t))
- {
+ if(!reloadtexture(*t)) {
if(t->id) glDeleteTextures(1, &t->id);
*t = oldtex;
conoutf(CON_ERROR, "failed to reload texture %s", name);
@@ -2396,23 +2064,19 @@ void reloadtex(char *name)
COMMAND(reloadtex, "s");
-void reloadtextures()
-{
+void reloadtextures() {
int reloaded = 0;
- enumerate(textures, Texture, tex,
- {
+ enumerate(textures, Texture, tex, {
loadprogress = float(++reloaded)/textures.numelems;
reloadtexture(tex);
});
loadprogress = 0;
}
-void writepngchunk(stream *f, const char *type, uchar *data = NULL, uint len = 0)
-{
+void writepngchunk(stream *f, const char *type, uchar *data = NULL, uint len = 0) {
f->putbig<uint>(len);
f->write(type, 4);
f->write(data, len);
-
uint crc = crc32(0, Z_NULL, 0);
crc = crc32(crc, (const Bytef *)type, 4);
if(data) crc = crc32(crc, data, len);
@@ -2421,11 +2085,9 @@ void writepngchunk(stream *f, const char *type, uchar *data = NULL, uint len = 0
VARP(compresspng, 0, 9, 9);
-void savepng(const char *filename, ImageData &image, bool flip)
-{
+void savepng(const char *filename, ImageData &image, bool flip) {
uchar ctype = 0;
- switch(image.bpp)
- {
+ switch(image.bpp) {
case 1: ctype = 0; break;
case 2: ctype = 4; break;
case 3: ctype = 2; break;
@@ -2434,44 +2096,33 @@ void savepng(const char *filename, ImageData &image, bool flip)
}
stream *f = openfile(filename, "wb");
if(!f) { conoutf(CON_ERROR, "could not write to %s", filename); return; }
-
uchar signature[] = { 137, 80, 78, 71, 13, 10, 26, 10 };
f->write(signature, sizeof(signature));
-
- struct pngihdr
- {
+ struct pngihdr {
uint width, height;
uchar bitdepth, colortype, compress, filter, interlace;
} ihdr = { bigswap<uint>(image.w), bigswap<uint>(image.h), 8, ctype, 0, 0, 0 };
writepngchunk(f, "IHDR", (uchar *)&ihdr, 13);
-
stream::offset idat = f->tell();
uint len = 0;
f->write("\0\0\0\0IDAT", 8);
uint crc = crc32(0, Z_NULL, 0);
crc = crc32(crc, (const Bytef *)"IDAT", 4);
-
z_stream z;
z.zalloc = NULL;
z.zfree = NULL;
z.opaque = NULL;
-
if(deflateInit(&z, compresspng) != Z_OK)
goto error;
-
uchar buf[1<<12];
z.next_out = (Bytef *)buf;
z.avail_out = sizeof(buf);
-
- loopi(image.h)
- {
+ loopi(image.h) {
uchar filter = 0;
- loopj(2)
- {
+ loopj(2) {
z.next_in = j ? (Bytef *)image.data + (flip ? image.h-i-1 : i)*image.pitch : (Bytef *)&filter;
z.avail_in = j ? image.w*image.bpp : 1;
- while(z.avail_in > 0)
- {
+ while(z.avail_in > 0) {
if(deflate(&z, Z_NO_FLUSH) != Z_OK) goto cleanuperror;
#define FLUSHZ do { \
int flush = sizeof(buf) - z.avail_out; \
@@ -2485,24 +2136,18 @@ void savepng(const char *filename, ImageData &image, bool flip)
}
}
}
-
- for(;;)
- {
+ for(;;) {
int err = deflate(&z, Z_FINISH);
if(err != Z_OK && err != Z_STREAM_END) goto cleanuperror;
FLUSHZ;
if(err == Z_STREAM_END) break;
}
-
deflateEnd(&z);
-
f->seek(idat, SEEK_SET);
f->putbig<uint>(len);
f->seek(0, SEEK_END);
f->putbig<uint>(crc);
-
writepngchunk(f, "IEND");
-
delete f;
return;
@@ -2511,7 +2156,6 @@ cleanuperror:
error:
delete f;
-
conoutf(CON_ERROR, "failed saving png to %s", filename);
}
@@ -2522,31 +2166,25 @@ VARP(screenshotformat, 0, IMG_PNG, NUMIMG-1);
const char *imageexts[NUMIMG] = { ".bmp", ".png", ".jpg" };
-int guessimageformat(const char *filename, int format = IMG_BMP)
-{
+int guessimageformat(const char *filename, int format = IMG_BMP) {
int len = strlen(filename);
- loopi(NUMIMG)
- {
+ loopi(NUMIMG) {
int extlen = strlen(imageexts[i]);
if(len >= extlen && !strcasecmp(&filename[len-extlen], imageexts[i])) return i;
}
return format;
}
-void saveimage(const char *filename, int format, ImageData &image, bool flip = false)
-{
- switch(format)
- {
+void saveimage(const char *filename, int format, ImageData &image, bool flip = false) {
+ switch(format) {
case IMG_PNG: savepng(filename, image, flip); break;
- default:
- {
+ default: {
ImageData flipped(image.w, image.h, image.bpp, image.data);
if(flip) texflip(flipped);
SDL_Surface *s = wrapsurface(flipped.data, flipped.w, flipped.h, flipped.bpp);
if(!s) break;
stream *f = openfile(filename, "wb");
- if(f)
- {
+ if(f) {
switch(format) {
case IMG_JPG:
#if SDL_IMAGE_VERSION_ATLEAST(2, 0, 2)
@@ -2565,8 +2203,7 @@ void saveimage(const char *filename, int format, ImageData &image, bool flip = f
}
}
-bool loadimage(const char *filename, ImageData &image)
-{
+bool loadimage(const char *filename, ImageData &image) {
SDL_Surface *s = loadsurface(path(filename, true));
if(!s) return false;
image.wrap(s);
@@ -2575,51 +2212,41 @@ bool loadimage(const char *filename, ImageData &image)
SVARP(screenshotdir, "screenshot");
-void screenshot(char *filename)
-{
+void screenshot(char *filename) {
static string buf;
int format = -1, dirlen = 0;
copystring(buf, screenshotdir);
- if(screenshotdir[0])
- {
+ if(screenshotdir[0]) {
dirlen = strlen(buf);
if(buf[dirlen] != '/' && buf[dirlen] != '\\' && dirlen+1 < (int)sizeof(buf)) { buf[dirlen++] = '/'; buf[dirlen] = '\0'; }
const char *dir = findfile(buf, "w");
if(!fileexists(dir, "w")) createdir(dir);
}
- if(filename[0])
- {
+ if(filename[0]) {
concatstring(buf, filename);
format = guessimageformat(buf, -1);
}
- else
- {
+ else {
string sstime;
time_t t = time(NULL);
size_t len = strftime(sstime, sizeof(sstime), "%Y-%m-%d_%H.%M.%S", localtime(&t));
sstime[min(len, sizeof(sstime)-1)] = '\0';
concatstring(buf, sstime);
-
const char *map = game::getclientmap(), *ssinfo = game::getscreenshotinfo();
- if(map && map[0])
- {
+ if(map && map[0]) {
concatstring(buf, "_");
concatstring(buf, map);
}
- if(ssinfo && ssinfo[0])
- {
+ if(ssinfo && ssinfo[0]) {
concatstring(buf, "_");
concatstring(buf, ssinfo);
}
-
for(char *s = &buf[dirlen]; *s; s++) if(iscubespace(*s) || *s == '/' || *s == '\\') *s = '-';
}
- if(format < 0)
- {
+ if(format < 0) {
format = screenshotformat;
concatstring(buf, imageexts[format]);
}
-
ImageData image(screenw, screenh, 3);
glPixelStorei(GL_PACK_ALIGNMENT, texalign(image.data, screenw, 3));
glReadPixels(0, 0, screenw, screenh, GL_RGB, GL_UNSIGNED_BYTE, image.data);
diff --git a/src/engine/texture.h b/src/engine/texture.h
index 3679931..ef5a57b 100644
--- a/src/engine/texture.h
+++ b/src/engine/texture.h
@@ -1,43 +1,31 @@
-struct GlobalShaderParamState
-{
+struct GlobalShaderParamState {
const char *name;
- union
- {
+ union {
float fval[32];
int ival[32];
uint uval[32];
uchar buf[32*sizeof(float)];
};
int version;
-
static int nextversion;
-
void resetversions();
-
- void changed()
- {
+ void changed() {
if(++nextversion < 0) resetversions();
version = nextversion;
}
};
-struct ShaderParamBinding
-{
+struct ShaderParamBinding {
int loc, size;
GLenum format;
};
-struct GlobalShaderParamUse : ShaderParamBinding
-{
-
+struct GlobalShaderParamUse : ShaderParamBinding {
GlobalShaderParamState *param;
int version;
-
- void flush()
- {
+ void flush() {
if(version == param->version) return;
- switch(format)
- {
+ switch(format) {
case GL_BOOL:
case GL_FLOAT: glUniform1fv_(loc, size, param->fval); break;
case GL_BOOL_VEC2:
@@ -58,25 +46,20 @@ struct GlobalShaderParamUse : ShaderParamBinding
}
};
-struct LocalShaderParamState : ShaderParamBinding
-{
+struct LocalShaderParamState : ShaderParamBinding {
const char *name;
};
-struct SlotShaderParam
-{
+struct SlotShaderParam {
const char *name;
int loc;
float val[4];
};
-struct SlotShaderParamState : LocalShaderParamState
-{
+struct SlotShaderParamState : LocalShaderParamState {
float val[4];
-
SlotShaderParamState() {}
- SlotShaderParamState(const SlotShaderParam &p)
- {
+ SlotShaderParamState(const SlotShaderParam &p) {
name = p.name;
loc = -1;
size = 1;
@@ -85,12 +68,10 @@ struct SlotShaderParamState : LocalShaderParamState
}
};
-enum
-{
+enum {
SHADER_DEFAULT = 0,
SHADER_NORMALSLMS = 1<<0,
SHADER_OPTION = 1<<3,
-
SHADER_INVALID = 1<<8,
SHADER_DEFERRED = 1<<9
};
@@ -103,25 +84,21 @@ extern int shaderdetail;
struct Slot;
struct VSlot;
-struct UniformLoc
-{
+struct UniformLoc {
const char *name, *blockname;
int loc, version, binding, stride, offset, size;
void *data;
UniformLoc(const char *name = NULL, const char *blockname = NULL, int binding = -1, int stride = -1) : name(name), blockname(blockname), loc(-1), version(-1), binding(binding), stride(stride), offset(-1), size(-1), data(NULL) {}
};
-struct AttribLoc
-{
+struct AttribLoc {
const char *name;
int loc;
AttribLoc(const char *name = NULL, int loc = -1) : name(name), loc(loc) {}
};
-struct Shader
-{
+struct Shader {
static Shader *lastshader;
-
char *name, *vsstr, *psstr, *defer;
int type;
GLuint program, vsobj, psobj;
@@ -137,161 +114,115 @@ struct Shader
vector<UniformLoc> uniformlocs;
vector<AttribLoc> attriblocs;
const void *owner;
-
- Shader() : name(NULL), vsstr(NULL), psstr(NULL), defer(NULL), type(SHADER_DEFAULT), program(0), vsobj(0), psobj(0), detailshader(NULL), variantshader(NULL), altshader(NULL), variantrows(NULL), standard(false), forced(false), used(false), reusevs(NULL), reuseps(NULL), owner(NULL)
- {
+ Shader() : name(NULL), vsstr(NULL), psstr(NULL), defer(NULL), type(SHADER_DEFAULT), program(0), vsobj(0), psobj(0), detailshader(NULL), variantshader(NULL), altshader(NULL), variantrows(NULL), standard(false), forced(false), used(false), reusevs(NULL), reuseps(NULL), owner(NULL) {
loopi(MAXSHADERDETAIL) fastshader[i] = this;
}
-
- ~Shader()
- {
+ ~Shader() {
DELETEA(name);
DELETEA(vsstr);
DELETEA(psstr);
DELETEA(defer);
DELETEA(variantrows);
}
-
void fixdetailshader(bool force = true, bool recurse = true);
void allocparams(Slot *slot = NULL);
void setslotparams(Slot &slot);
void setslotparams(Slot &slot, VSlot &vslot);
void bindprograms();
-
- void flushparams(Slot *slot = NULL)
- {
+ void flushparams(Slot *slot = NULL) {
if(!used) { allocparams(slot); used = true; }
loopv(globalparams) globalparams[i].flush();
}
-
void force();
-
bool invalid() const { return (type&SHADER_INVALID)!=0; }
bool deferred() const { return (type&SHADER_DEFERRED)!=0; }
bool loaded() const { return detailshader!=NULL; }
-
static bool isnull(const Shader *s);
-
bool isnull() const { return isnull(this); }
-
- int numvariants(int row) const
- {
+ int numvariants(int row) const {
if(row < 0 || row >= MAXVARIANTROWS || !variantrows) return 0;
return variantrows[row+1] - variantrows[row];
}
-
- Shader *getvariant(int col, int row) const
- {
+ Shader *getvariant(int col, int row) const {
if(row < 0 || row >= MAXVARIANTROWS || col < 0 || !variantrows) return NULL;
int start = variantrows[row], end = variantrows[row+1];
return col < end - start ? variants[start + col] : NULL;
}
-
- bool hasoption(int row)
- {
- if(detailshader)
- {
+ bool hasoption(int row) {
+ if(detailshader) {
Shader *s = getvariant(0, row);
if(s) return (s->type&SHADER_OPTION)!=0;
}
return false;
}
-
- void addvariant(int row, Shader *s)
- {
+ void addvariant(int row, Shader *s) {
if(row < 0 || row >= MAXVARIANTROWS || variants.length() >= USHRT_MAX) return;
if(!variantrows) { variantrows = new ushort[MAXVARIANTROWS+1]; memset(variantrows, 0, (MAXVARIANTROWS+1)*sizeof(ushort)); }
variants.insert(variantrows[row+1], s);
for(int i = row+1; i <= MAXVARIANTROWS; ++i) ++variantrows[i];
}
-
- void setvariant_(int col, int row, Shader *fallbackshader)
- {
+ void setvariant_(int col, int row, Shader *fallbackshader) {
Shader *s = fallbackshader;
- if(detailshader->variantrows)
- {
+ if(detailshader->variantrows) {
int start = detailshader->variantrows[row], end = detailshader->variantrows[row+1];
- for(col = min(start + col, end-1); col >= start; --col)
- {
+ for(col = min(start + col, end-1); col >= start; --col) {
if(!detailshader->variants[col]->invalid()) { s = detailshader->variants[col]; break; }
}
}
if(lastshader!=s) s->bindprograms();
}
-
- void setvariant(int col, int row, Shader *fallbackshader)
- {
+ void setvariant(int col, int row, Shader *fallbackshader) {
if(isnull() || !loaded()) return;
setvariant_(col, row, fallbackshader);
lastshader->flushparams();
}
-
- void setvariant(int col, int row)
- {
+ void setvariant(int col, int row) {
if(isnull() || !loaded()) return;
setvariant_(col, row, detailshader);
lastshader->flushparams();
}
-
- void setvariant(int col, int row, Slot &slot, VSlot &vslot, Shader *fallbackshader)
- {
+ void setvariant(int col, int row, Slot &slot, VSlot &vslot, Shader *fallbackshader) {
if(isnull() || !loaded()) return;
setvariant_(col, row, fallbackshader);
lastshader->flushparams(&slot);
lastshader->setslotparams(slot, vslot);
}
-
- void setvariant(int col, int row, Slot &slot, VSlot &vslot)
- {
+ void setvariant(int col, int row, Slot &slot, VSlot &vslot) {
if(isnull() || !loaded()) return;
setvariant_(col, row, detailshader);
lastshader->flushparams(&slot);
lastshader->setslotparams(slot, vslot);
}
-
- void set_()
- {
+ void set_() {
if(lastshader!=detailshader) detailshader->bindprograms();
}
-
- void set()
- {
+ void set() {
if(isnull() || !loaded()) return;
set_();
lastshader->flushparams();
}
-
- void set(Slot &slot, VSlot &vslot)
- {
+ void set(Slot &slot, VSlot &vslot) {
if(isnull() || !loaded()) return;
set_();
lastshader->flushparams(&slot);
lastshader->setslotparams(slot, vslot);
}
-
bool compile();
void cleanup(bool invalid = false);
-
static int uniformlocversion();
};
-struct GlobalShaderParam
-{
+struct GlobalShaderParam {
const char *name;
GlobalShaderParamState *param;
-
GlobalShaderParam(const char *name) : name(name), param(NULL) {}
-
- GlobalShaderParamState *resolve()
- {
+ GlobalShaderParamState *resolve() {
extern GlobalShaderParamState *getglobalparam(const char *name);
if(!param) param = getglobalparam(name);
param->changed();
return param;
}
-
- void setf(float x = 0, float y = 0, float z = 0, float w = 0)
- {
+ void setf(float x = 0, float y = 0, float z = 0, float w = 0) {
GlobalShaderParamState *g = resolve();
g->fval[0] = x;
g->fval[1] = y;
@@ -305,12 +236,9 @@ struct GlobalShaderParam
void set(const matrix2 &m) { memcpy(resolve()->fval, m.a.v, sizeof(m)); }
void set(const matrix3 &m) { memcpy(resolve()->fval, m.a.v, sizeof(m)); }
void set(const matrix4 &m) { memcpy(resolve()->fval, m.a.v, sizeof(m)); }
-
template<class T>
void setv(const T *v, int n = 1) { memcpy(resolve()->buf, v, n*sizeof(T)); }
-
- void seti(int x = 0, int y = 0, int z = 0, int w = 0)
- {
+ void seti(int x = 0, int y = 0, int z = 0, int w = 0) {
GlobalShaderParamState *g = resolve();
g->ival[0] = x;
g->ival[1] = y;
@@ -320,33 +248,25 @@ struct GlobalShaderParam
void set(const ivec &v, int w = 0) { seti(v.x, v.y, v.z, w); }
void set(const ivec2 &v, int z = 0, int w = 0) { seti(v.x, v.y, z, w); }
void set(const ivec4 &v) { seti(v.x, v.y, v.z, v.w); }
-
- void setu(uint x = 0, uint y = 0, uint z = 0, uint w = 0)
- {
+ void setu(uint x = 0, uint y = 0, uint z = 0, uint w = 0) {
GlobalShaderParamState *g = resolve();
g->uval[0] = x;
g->uval[1] = y;
g->uval[2] = z;
g->uval[3] = w;
}
-
template<class T>
T *reserve(int n = 1) { return (T *)resolve()->buf; }
};
-struct LocalShaderParam
-{
+struct LocalShaderParam {
const char *name;
int loc;
-
LocalShaderParam(const char *name) : name(name), loc(-1) {}
-
- LocalShaderParamState *resolve()
- {
+ LocalShaderParamState *resolve() {
Shader *s = Shader::lastshader;
if(!s) return NULL;
- if(!s->localparamremap.inrange(loc))
- {
+ if(!s->localparamremap.inrange(loc)) {
extern int getlocalparam(const char *name);
if(loc == -1) loc = getlocalparam(name);
if(!s->localparamremap.inrange(loc)) return NULL;
@@ -354,12 +274,9 @@ struct LocalShaderParam
uchar remap = s->localparamremap[loc];
return s->localparams.inrange(remap) ? &s->localparams[remap] : NULL;
}
-
- void setf(float x = 0, float y = 0, float z = 0, float w = 0)
- {
+ void setf(float x = 0, float y = 0, float z = 0, float w = 0) {
ShaderParamBinding *b = resolve();
- if(b) switch(b->format)
- {
+ if(b) switch(b->format) {
case GL_BOOL:
case GL_FLOAT: glUniform1f_(b->loc, x); break;
case GL_BOOL_VEC2:
@@ -389,13 +306,10 @@ struct LocalShaderParam
void set(const matrix2 &m) { setv(&m); }
void set(const matrix3 &m) { setv(&m); }
void set(const matrix4 &m) { setv(&m); }
-
template<class T>
- void sett(T x, T y, T z, T w)
- {
+ void sett(T x, T y, T z, T w) {
ShaderParamBinding *b = resolve();
- if(b) switch(b->format)
- {
+ if(b) switch(b->format) {
case GL_FLOAT: glUniform1f_(b->loc, x); break;
case GL_FLOAT_VEC2: glUniform2f_(b->loc, x, y); break;
case GL_FLOAT_VEC3: glUniform3f_(b->loc, x, y, z); break;
@@ -442,35 +356,26 @@ struct LocalShaderParam
name##shader->setvariant(__VA_ARGS__); \
} while(0)
-struct ImageData
-{
+struct ImageData {
int w, h, bpp, levels, align, pitch;
GLenum compressed;
uchar *data;
void *owner;
void (*freefunc)(void *);
-
ImageData()
- : data(NULL), owner(NULL), freefunc(NULL)
- {}
-
+ : data(NULL), owner(NULL), freefunc(NULL) {
+ }
- ImageData(int nw, int nh, int nbpp, int nlevels = 1, int nalign = 0, GLenum ncompressed = GL_FALSE)
- {
+ ImageData(int nw, int nh, int nbpp, int nlevels = 1, int nalign = 0, GLenum ncompressed = GL_FALSE) {
setdata(NULL, nw, nh, nbpp, nlevels, nalign, ncompressed);
}
-
ImageData(int nw, int nh, int nbpp, uchar *data)
- : owner(NULL), freefunc(NULL)
- {
+ : owner(NULL), freefunc(NULL) {
setdata(data, nw, nh, nbpp);
}
-
ImageData(SDL_Surface *s) { wrap(s); }
~ImageData() { cleanup(); }
-
- void setdata(uchar *ndata, int nw, int nh, int nbpp, int nlevels = 1, int nalign = 0, GLenum ncompressed = GL_FALSE)
- {
+ void setdata(uchar *ndata, int nw, int nh, int nbpp, int nlevels = 1, int nalign = 0, GLenum ncompressed = GL_FALSE) {
w = nw;
h = nh;
bpp = nbpp;
@@ -481,16 +386,12 @@ struct ImageData
data = ndata ? ndata : new uchar[calcsize()];
if(!ndata) { owner = this; freefunc = NULL; }
}
-
int calclevelsize(int level) const { return ((max(w>>level, 1)+align-1)/align)*((max(h>>level, 1)+align-1)/align)*bpp; }
-
- int calcsize() const
- {
+ int calcsize() const {
if(!align) return w*h*bpp;
int lw = w, lh = h,
size = 0;
- loopi(levels)
- {
+ loopi(levels) {
if(lw<=0) lw = 1;
if(lh<=0) lh = 1;
size += ((lw+align-1)/align)*((lh+align-1)/align)*bpp;
@@ -500,31 +401,23 @@ struct ImageData
}
return size;
}
-
- void disown()
- {
+ void disown() {
data = NULL;
owner = NULL;
freefunc = NULL;
}
-
- void cleanup()
- {
+ void cleanup() {
if(owner==this) delete[] data;
else if(freefunc) (*freefunc)(owner);
disown();
}
-
- void replace(ImageData &d)
- {
+ void replace(ImageData &d) {
cleanup();
*this = d;
if(owner == &d) owner = this;
d.disown();
}
-
- void wrap(SDL_Surface *s)
- {
+ void wrap(SDL_Surface *s) {
setdata((uchar *)s->pixels, s->w, s->h, s->format->BytesPerPixel);
pitch = s->pitch;
owner = s;
@@ -536,14 +429,11 @@ struct ImageData
// each texture slot can have multiple texture frames, of which currently only the first is used
// additional frames can be used for various shaders
-struct Texture
-{
- enum
- {
+struct Texture {
+ enum {
IMAGE = 0,
CUBEMAP = 1,
TYPE = 0xFF,
-
STUB = 1<<8,
TRANSIENT = 1<<9,
COMPRESSED = 1<<10,
@@ -551,18 +441,15 @@ struct Texture
MIRROR = 1<<12,
FLAGS = 0xFF00
};
-
char *name;
int type, w, h, xs, ys, bpp, clamp;
bool mipmap, canreduce;
GLuint id;
uchar *alphamask;
-
Texture() : alphamask(NULL) {}
};
-enum
-{
+enum {
TEX_DIFFUSE = 0,
TEX_UNKNOWN,
TEX_DECAL,
@@ -572,8 +459,7 @@ enum
TEX_ALPHA
};
-enum
-{
+enum {
VSLOT_SHPARAM = 0,
VSLOT_SCALE,
VSLOT_ROTATION,
@@ -585,8 +471,7 @@ enum
VSLOT_NUM
};
-struct VSlot
-{
+struct VSlot {
Slot *slot;
VSlot *next;
int index, changed;
@@ -599,17 +484,12 @@ struct VSlot
int layer;
float alphafront, alphaback;
vec colorscale;
-
- VSlot(Slot *slot = NULL, int index = -1) : slot(slot), next(NULL), index(index), changed(0)
- {
+ VSlot(Slot *slot = NULL, int index = -1) : slot(slot), next(NULL), index(index), changed(0) {
reset();
if(slot) addvariant(slot);
}
-
void addvariant(Slot *slot);
-
- void reset()
- {
+ void reset() {
params.shrink(0);
linked = false;
scale = 1;
@@ -621,23 +501,18 @@ struct VSlot
alphaback = 0;
colorscale = vec(1, 1, 1);
}
-
- void cleanup()
- {
+ void cleanup() {
linked = false;
}
};
-struct Slot
-{
- struct Tex
- {
+struct Slot {
+ struct Tex {
int type;
Texture *t;
string name;
int combined;
};
-
int index;
vector<Tex> sts;
Shader *shader;
@@ -650,11 +525,8 @@ struct Slot
int layermaskmode;
float layermaskscale;
ImageData *layermask;
-
Slot(int index = -1) : index(index), variants(NULL), layermaskname(NULL), layermask(NULL) { reset(); }
-
- void reset()
- {
+ void reset() {
sts.shrink(0);
shader = NULL;
params.shrink(0);
@@ -666,13 +538,10 @@ struct Slot
layermaskscale = 1;
if(layermask) DELETEP(layermask);
}
-
- void cleanup()
- {
+ void cleanup() {
loaded = false;
thumbnail = NULL;
- loopv(sts)
- {
+ loopv(sts) {
Tex &t = sts[i];
t.t = NULL;
t.combined = -1;
@@ -680,41 +549,32 @@ struct Slot
}
};
-inline void VSlot::addvariant(Slot *slot)
-{
+inline void VSlot::addvariant(Slot *slot) {
if(!slot->variants) slot->variants = this;
- else
- {
+ else {
VSlot *prev = slot->variants;
while(prev->next) prev = prev->next;
prev->next = this;
}
}
-struct MSlot : Slot, VSlot
-{
+struct MSlot : Slot, VSlot {
MSlot() : VSlot(this) {}
-
- void reset()
- {
+ void reset() {
Slot::reset();
VSlot::reset();
}
-
- void cleanup()
- {
+ void cleanup() {
Slot::cleanup();
VSlot::cleanup();
}
};
-struct texrotation
-{
+struct texrotation {
bool flipx, flipy, swapxy;
};
-struct cubemapside
-{
+struct cubemapside {
GLenum target;
const char *name;
bool flipx, flipy, swapxy;
diff --git a/src/engine/vertmodel.h b/src/engine/vertmodel.h
deleted file mode 100644
index e9af1b0..0000000
--- a/src/engine/vertmodel.h
+++ /dev/null
@@ -1,490 +0,0 @@
-struct vertmodel : animmodel
-{
- struct vert { vec pos, norm; };
- struct vvert { vec pos; vec2 tc; };
- struct vvertn : vvert { vec norm; };
- struct vvertbump : vvert { squat tangent; };
- struct tcvert { vec2 tc; };
- struct bumpvert { vec4 tangent; };
- struct tri { ushort vert[3]; };
-
- struct vbocacheentry
- {
- GLuint vbuf;
- animstate as;
- int millis;
-
- vbocacheentry() : vbuf(0) { as.cur.fr1 = as.prev.fr1 = -1; }
- };
-
- struct vertmesh : mesh
- {
- vert *verts;
- tcvert *tcverts;
- bumpvert *bumpverts;
- tri *tris;
- int numverts, numtris;
-
- int voffset, eoffset, elen;
- ushort minvert, maxvert;
-
- vertmesh() : verts(0), tcverts(0), bumpverts(0), tris(0)
- {
- }
-
- virtual ~vertmesh()
- {
- DELETEA(verts);
- DELETEA(tcverts);
- DELETEA(bumpverts);
- DELETEA(tris);
- }
-
- void smoothnorms(float limit = 0, bool areaweight = true)
- {
- if(((vertmeshgroup *)group)->numframes == 1) mesh::smoothnorms(verts, numverts, tris, numtris, limit, areaweight);
- else buildnorms(areaweight);
- }
-
- void buildnorms(bool areaweight = true)
- {
- mesh::buildnorms(verts, numverts, tris, numtris, areaweight, ((vertmeshgroup *)group)->numframes);
- }
-
- void calctangents(bool areaweight = true)
- {
- if(bumpverts) return;
- bumpverts = new bumpvert[((vertmeshgroup *)group)->numframes*numverts];
- mesh::calctangents(bumpverts, verts, tcverts, numverts, tris, numtris, areaweight, ((vertmeshgroup *)group)->numframes);
- }
-
- void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m)
- {
- loopj(numverts)
- {
- vec v = m.transform(verts[j].pos);
- loopi(3)
- {
- bbmin[i] = min(bbmin[i], v[i]);
- bbmax[i] = max(bbmax[i], v[i]);
- }
- }
- }
-
- void genBIH(BIH::mesh &m)
- {
- m.tris = (const BIH::tri *)tris;
- m.numtris = numtris;
- m.pos = (const uchar *)&verts->pos;
- m.posstride = sizeof(vert);
- m.tc = (const uchar *)&tcverts->tc;
- m.tcstride = sizeof(tcvert);
- }
-
- static inline void assignvert(vvertn &vv, int j, tcvert &tc, vert &v)
- {
- vv.pos = v.pos;
- vv.norm = v.norm;
- vv.tc = tc.tc;
- }
-
- inline void assignvert(vvertbump &vv, int j, tcvert &tc, vert &v)
- {
- vv.pos = v.pos;
- vv.tc = tc.tc;
- vv.tangent = bumpverts[j].tangent;
- }
-
- template<class T>
- int genvbo(vector<ushort> &idxs, int offset, vector<T> &vverts, int *htdata, int htlen)
- {
- voffset = offset;
- eoffset = idxs.length();
- minvert = 0xFFFF;
- loopi(numtris)
- {
- tri &t = tris[i];
- loopj(3)
- {
- int index = t.vert[j];
- tcvert &tc = tcverts[index];
- vert &v = verts[index];
- T vv;
- assignvert(vv, index, tc, v);
- int htidx = hthash(v.pos)&(htlen-1);
- loopk(htlen)
- {
- int &vidx = htdata[(htidx+k)&(htlen-1)];
- if(vidx < 0) { vidx = idxs.add(ushort(vverts.length())); vverts.add(vv); break; }
- else if(!memcmp(&vverts[vidx], &vv, sizeof(vv))) { minvert = min(minvert, idxs.add(ushort(vidx))); break; }
- }
- }
- }
- minvert = min(minvert, ushort(voffset));
- maxvert = max(minvert, ushort(vverts.length()-1));
- elen = idxs.length()-eoffset;
- return vverts.length()-voffset;
- }
-
- int genvbo(vector<ushort> &idxs, int offset)
- {
- voffset = offset;
- eoffset = idxs.length();
- loopi(numtris)
- {
- tri &t = tris[i];
- loopj(3) idxs.add(voffset+t.vert[j]);
- }
- minvert = voffset;
- maxvert = voffset + numverts-1;
- elen = idxs.length()-eoffset;
- return numverts;
- }
-
- template<class T>
- static inline void fillvert(T &vv, int j, tcvert &tc, vert &v)
- {
- vv.tc = tc.tc;
- }
-
- template<class T>
- void fillverts(T *vdata)
- {
- vdata += voffset;
- loopi(numverts) fillvert(vdata[i], i, tcverts[i], verts[i]);
- }
-
- void interpverts(const animstate &as, bool tangents, void * RESTRICT vdata, skin &s)
- {
- const vert * RESTRICT vert1 = &verts[as.cur.fr1 * numverts],
- * RESTRICT vert2 = &verts[as.cur.fr2 * numverts],
- * RESTRICT pvert1 = as.interp<1 ? &verts[as.prev.fr1 * numverts] : NULL,
- * RESTRICT pvert2 = as.interp<1 ? &verts[as.prev.fr2 * numverts] : NULL;
- #define ipvert(attrib) v.attrib.lerp(vert1[i].attrib, vert2[i].attrib, as.cur.t)
- #define ipbvert(attrib, type) v.attrib.lerp(bvert1[i].attrib, bvert2[i].attrib, as.cur.t)
- #define ipvertp(attrib) v.attrib.lerp(pvert1[i].attrib, pvert2[i].attrib, as.prev.t).lerp(vec().lerp(vert1[i].attrib, vert2[i].attrib, as.cur.t), as.interp)
- #define ipbvertp(attrib, type) v.attrib.lerp(type().lerp(bpvert1[i].attrib, bpvert2[i].attrib, as.prev.t), type().lerp(bvert1[i].attrib, bvert2[i].attrib, as.cur.t), as.interp)
- #define iploop(type, body) \
- loopi(numverts) \
- { \
- type &v = ((type * RESTRICT)vdata)[i]; \
- body; \
- }
- if(tangents)
- {
- const bumpvert * RESTRICT bvert1 = &bumpverts[as.cur.fr1 * numverts],
- * RESTRICT bvert2 = &bumpverts[as.cur.fr2 * numverts],
- * RESTRICT bpvert1 = as.interp<1 ? &bumpverts[as.prev.fr1 * numverts] : NULL,
- * RESTRICT bpvert2 = as.interp<1 ? &bumpverts[as.prev.fr2 * numverts] : NULL;
- if(as.interp<1) iploop(vvertbump, { ipvertp(pos); ipbvertp(tangent, vec4); })
- else iploop(vvertbump, { ipvert(pos); ipbvert(tangent, vec4); })
- }
- else
- {
- if(as.interp<1) iploop(vvertn, { ipvertp(pos); ipvertp(norm); })
- else iploop(vvertn, { ipvert(pos); ipvert(norm); })
- }
- #undef iploop
- #undef ipvert
- #undef ipbvert
- #undef ipvertp
- #undef ipbvertp
- }
-
- void render(const animstate *as, skin &s, vbocacheentry &vc)
- {
- if(!Shader::lastshader) return;
- glDrawRangeElements_(GL_TRIANGLES, minvert, maxvert, elen, GL_UNSIGNED_SHORT, &((vertmeshgroup *)group)->edata[eoffset]);
- glde++;
- xtravertsva += numverts;
- }
- };
-
- struct tag
- {
- char *name;
- matrix4x3 transform;
-
- tag() : name(NULL) {}
- ~tag() { DELETEA(name); }
- };
-
- struct vertmeshgroup : meshgroup
- {
- int numframes;
- tag *tags;
- int numtags;
-
- static const int MAXVBOCACHE = 16;
- vbocacheentry vbocache[MAXVBOCACHE];
-
- ushort *edata;
- GLuint ebuf;
- bool vtangents;
- int vlen, vertsize;
- uchar *vdata;
-
- vertmeshgroup() : numframes(0), tags(NULL), numtags(0), edata(NULL), ebuf(0), vtangents(false), vlen(0), vertsize(0), vdata(NULL)
- {
- }
-
- virtual ~vertmeshgroup()
- {
- DELETEA(tags);
- if(ebuf) glDeleteBuffers_(1, &ebuf);
- loopi(MAXVBOCACHE)
- {
- if(vbocache[i].vbuf) glDeleteBuffers_(1, &vbocache[i].vbuf);
- }
- DELETEA(vdata);
- }
-
- int findtag(const char *name)
- {
- loopi(numtags) if(!strcmp(tags[i].name, name)) return i;
- return -1;
- }
-
- int totalframes() const { return numframes; }
-
- void concattagtransform(part *p, int i, const matrix4x3 &m, matrix4x3 &n)
- {
- n.mul(m, tags[numtags + i].transform);
- n.posttranslate(m.transformnormal(p->translate), p->model->scale);
- }
-
- void calctagmatrix(part *p, int i, const animstate &as, matrix4 &matrix)
- {
- const matrix4x3 &tag1 = tags[as.cur.fr1*numtags + i].transform,
- &tag2 = tags[as.cur.fr2*numtags + i].transform;
- matrix4x3 tag;
- tag.lerp(tag1, tag2, as.cur.t);
- if(as.interp<1)
- {
- const matrix4x3 &tag1p = tags[as.prev.fr1*numtags + i].transform,
- &tag2p = tags[as.prev.fr2*numtags + i].transform;
- matrix4x3 tagp;
- tagp.lerp(tag1p, tag2p, as.prev.t);
- tag.lerp(tagp, tag, as.interp);
- }
- tag.d.add(p->translate).mul(p->model->scale);
- matrix = matrix4(tag);
- }
-
- void genvbo(bool tangents, vbocacheentry &vc)
- {
- if(!vc.vbuf) glGenBuffers_(1, &vc.vbuf);
- if(ebuf) return;
-
- vector<ushort> idxs;
-
- if(tangents) loopv(meshes) ((vertmesh *)meshes[i])->calctangents();
-
- vtangents = tangents;
- vertsize = tangents ? sizeof(vvertbump) : sizeof(vvertn);
- vlen = 0;
- if(numframes>1)
- {
- loopv(meshes) vlen += ((vertmesh *)meshes[i])->genvbo(idxs, vlen);
- DELETEA(vdata);
- vdata = new uchar[vlen*vertsize];
- #define FILLVDATA(type) do { \
- loopv(meshes) ((vertmesh *)meshes[i])->fillverts((type *)vdata); \
- } while(0)
- if(tangents) FILLVDATA(vvertbump);
- else FILLVDATA(vvertn);
- #undef FILLVDATA
- }
- else
- {
- gle::bindvbo(vc.vbuf);
- #define GENVBO(type) do { \
- vector<type> vverts; \
- loopv(meshes) vlen += ((vertmesh *)meshes[i])->genvbo(idxs, vlen, vverts, htdata, htlen); \
- glBufferData_(GL_ARRAY_BUFFER, vverts.length()*sizeof(type), vverts.getbuf(), GL_STATIC_DRAW); \
- } while(0)
- int numverts = 0, htlen = 128;
- loopv(meshes) numverts += ((vertmesh *)meshes[i])->numverts;
- while(htlen < numverts) htlen *= 2;
- if(numverts*4 > htlen*3) htlen *= 2;
- int *htdata = new int[htlen];
- memset(htdata, -1, htlen*sizeof(int));
- if(tangents) GENVBO(vvertbump);
- else GENVBO(vvertn);
- delete[] htdata;
- #undef GENVBO
- gle::clearvbo();
- }
-
- glGenBuffers_(1, &ebuf);
- gle::bindebo(ebuf);
- glBufferData_(GL_ELEMENT_ARRAY_BUFFER, idxs.length()*sizeof(ushort), idxs.getbuf(), GL_STATIC_DRAW);
- gle::clearebo();
- }
-
- void bindvbo(const animstate *as, vbocacheentry &vc)
- {
- vvert *vverts = 0;
- bindpos(ebuf, vc.vbuf, &vverts->pos, vertsize);
- if(as->cur.anim&ANIM_NOSKIN)
- {
- if(enabletc) disabletc();
- if(enablenormals) disablenormals();
- if(enabletangents) disabletangents();
- }
- else
- {
- if(vtangents)
- {
- if(enablenormals) disablenormals();
- vvertbump *vvertbumps = 0;
- bindtangents(&vvertbumps->tangent, vertsize);
- }
- else
- {
- if(enabletangents) disabletangents();
- vvertn *vvertns = 0;
- bindnormals(&vvertns->norm, vertsize);
- }
-
- bindtc(&vverts->tc, vertsize);
- }
- if(enablebones) disablebones();
- }
-
- void cleanup()
- {
- loopi(MAXVBOCACHE)
- {
- vbocacheentry &c = vbocache[i];
- if(c.vbuf) { glDeleteBuffers_(1, &c.vbuf); c.vbuf = 0; }
- c.as.cur.fr1 = -1;
- }
- if(ebuf) { glDeleteBuffers_(1, &ebuf); ebuf = 0; }
- }
-
- void preload(part *p)
- {
- if(numframes > 1) return;
- bool tangents = p->tangents();
- if(tangents!=vtangents) cleanup();
- if(!vbocache->vbuf) genvbo(tangents, *vbocache);
- }
-
- void render(const animstate *as, float pitch, const vec &axis, const vec &forward, dynent *d, part *p)
- {
- if(as->cur.anim&ANIM_NORENDER)
- {
- loopv(p->links) calctagmatrix(p, p->links[i].tag, *as, p->links[i].matrix);
- return;
- }
-
- bool tangents = p->tangents();
- if(tangents!=vtangents) { cleanup(); disablevbo(); }
- vbocacheentry *vc = NULL;
- if(numframes<=1) vc = vbocache;
- else
- {
- loopi(MAXVBOCACHE)
- {
- vbocacheentry &c = vbocache[i];
- if(!c.vbuf) continue;
- if(c.as==*as) { vc = &c; break; }
- }
- if(!vc) loopi(MAXVBOCACHE) { vc = &vbocache[i]; if(!vc->vbuf || vc->millis < lastmillis) break; }
- }
- if(!vc->vbuf) genvbo(tangents, *vc);
- if(numframes>1)
- {
- if(vc->as!=*as)
- {
- vc->as = *as;
- vc->millis = lastmillis;
- loopv(meshes)
- {
- vertmesh &m = *(vertmesh *)meshes[i];
- m.interpverts(*as, tangents, vdata + m.voffset*vertsize, p->skins[i]);
- }
- gle::bindvbo(vc->vbuf);
- glBufferData_(GL_ARRAY_BUFFER, vlen*vertsize, vdata, GL_STREAM_DRAW);
- }
- vc->millis = lastmillis;
- }
-
- bindvbo(as, *vc);
- loopv(meshes)
- {
- vertmesh *m = (vertmesh *)meshes[i];
- p->skins[i].bind(m, as);
- m->render(as, p->skins[i], *vc);
- }
-
- loopv(p->links) calctagmatrix(p, p->links[i].tag, *as, p->links[i].matrix);
- }
- };
-
- vertmodel(const char *name) : animmodel(name)
- {
- }
-};
-
-template<class MDL> struct vertloader : modelloader<MDL, vertmodel>
-{
- vertloader(const char *name) : modelloader<MDL, vertmodel>(name) {}
-};
-
-template<class MDL> struct vertcommands : modelcommands<MDL, struct MDL::vertmesh>
-{
- typedef struct MDL::part part;
- typedef struct MDL::skin skin;
-
- static void loadpart(char *model, float *smooth)
- {
- if(!MDL::loading) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
- defformatstring(filename, "%s/%s", MDL::dir, model);
- part &mdl = MDL::loading->addpart();
- if(mdl.index) mdl.pitchscale = mdl.pitchoffset = mdl.pitchmin = mdl.pitchmax = 0;
- mdl.meshes = MDL::loading->sharemeshes(path(filename), double(*smooth > 0 ? cos(clamp(*smooth, 0.0f, 180.0f)*RAD) : 2));
- if(!mdl.meshes) conoutf(CON_ERROR, "could not load %s", filename);
- else mdl.initskins();
- }
-
- static void setpitch(float *pitchscale, float *pitchoffset, float *pitchmin, float *pitchmax)
- {
- if(!MDL::loading || MDL::loading->parts.empty()) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
- part &mdl = *MDL::loading->parts.last();
-
- mdl.pitchscale = *pitchscale;
- mdl.pitchoffset = *pitchoffset;
- if(*pitchmin || *pitchmax)
- {
- mdl.pitchmin = *pitchmin;
- mdl.pitchmax = *pitchmax;
- }
- else
- {
- mdl.pitchmin = -360*fabs(mdl.pitchscale) + mdl.pitchoffset;
- mdl.pitchmax = 360*fabs(mdl.pitchscale) + mdl.pitchoffset;
- }
- }
-
- static void setanim(char *anim, int *frame, int *range, float *speed, int *priority)
- {
- if(!MDL::loading || MDL::loading->parts.empty()) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
- vector<int> anims;
- findanims(anim, anims);
- if(anims.empty()) conoutf(CON_ERROR, "could not find animation %s", anim);
- else loopv(anims)
- {
- MDL::loading->parts.last()->setanim(0, anims[i], *frame, *range, *speed, *priority);
- }
- }
-
- vertcommands()
- {
- if(MDL::multiparted()) this->modelcommand(loadpart, "load", "sf");
- this->modelcommand(setpitch, "pitch", "ffff");
- if(MDL::animated()) this->modelcommand(setanim, "anim", "siiff");
- }
-};
-
diff --git a/src/engine/world.cpp b/src/engine/world.cpp
index 46aaa0f..489ea65 100644
--- a/src/engine/world.cpp
+++ b/src/engine/world.cpp
@@ -10,29 +10,23 @@ SVARR(maptitle, "Untitled Map by Unknown");
VAR(octaentsize, 0, 64, 1024);
VAR(entselradius, 0, 2, 10);
-static inline void mmboundbox(const entity &e, model *m, vec &center, vec &radius)
-{
+static inline void mmboundbox(const entity &e, model *m, vec &center, vec &radius) {
m->boundbox(center, radius);
rotatebb(center, radius, e.attr1);
}
-static inline void mmcollisionbox(const entity &e, model *m, vec &center, vec &radius)
-{
+static inline void mmcollisionbox(const entity &e, model *m, vec &center, vec &radius) {
m->collisionbox(center, radius);
rotatebb(center, radius, e.attr1);
}
-bool getentboundingbox(const extentity &e, ivec &o, ivec &r)
-{
- switch(e.type)
- {
+bool getentboundingbox(const extentity &e, ivec &o, ivec &r) {
+ switch(e.type) {
case ET_EMPTY:
return false;
- case ET_MAPMODEL:
- {
+ case ET_MAPMODEL: {
model *m = loadmapmodel(e.attr2);
- if(m)
- {
+ if(m) {
vec center, radius;
mmboundbox(e, m, center, radius);
center.add(e.o);
@@ -52,32 +46,25 @@ bool getentboundingbox(const extentity &e, ivec &o, ivec &r)
return true;
}
-enum
-{
+enum {
MODOE_ADD = 1<<0,
MODOE_UPDATEBB = 1<<1,
MODOE_LIGHTENT = 1<<2
};
-void modifyoctaentity(int flags, int id, extentity &e, cube *c, const ivec &cor, int size, const ivec &bo, const ivec &br, int leafsize, vtxarray *lastva = NULL)
-{
- loopoctabox(cor, size, bo, br)
- {
+void modifyoctaentity(int flags, int id, extentity &e, cube *c, const ivec &cor, int size, const ivec &bo, const ivec &br, int leafsize, vtxarray *lastva = NULL) {
+ loopoctabox(cor, size, bo, br) {
ivec o(i, cor, size);
vtxarray *va = c[i].ext && c[i].ext->va ? c[i].ext->va : lastva;
if(c[i].children != NULL && size > leafsize)
modifyoctaentity(flags, id, e, c[i].children, o, size>>1, bo, br, leafsize, va);
- else if(flags&MODOE_ADD)
- {
+ else if(flags&MODOE_ADD) {
if(!c[i].ext || !c[i].ext->ents) ext(c[i]).ents = new octaentities(o, size);
octaentities &oe = *c[i].ext->ents;
- switch(e.type)
- {
+ switch(e.type) {
case ET_MAPMODEL:
- if(loadmapmodel(e.attr2))
- {
- if(va)
- {
+ if(loadmapmodel(e.attr2)) {
+ if(va) {
va->bbmin.x = -1;
if(oe.mapmodels.empty()) va->mapmodels.add(&oe);
}
@@ -92,26 +79,20 @@ void modifyoctaentity(int flags, int id, extentity &e, cube *c, const ivec &cor,
oe.other.add(id);
break;
}
-
}
- else if(c[i].ext && c[i].ext->ents)
- {
+ else if(c[i].ext && c[i].ext->ents) {
octaentities &oe = *c[i].ext->ents;
- switch(e.type)
- {
+ switch(e.type) {
case ET_MAPMODEL:
- if(loadmapmodel(e.attr2))
- {
+ if(loadmapmodel(e.attr2)) {
oe.mapmodels.removeobj(id);
- if(va)
- {
+ if(va) {
va->bbmin.x = -1;
if(oe.mapmodels.empty()) va->mapmodels.removeobj(&oe);
}
oe.bbmin = oe.bbmax = oe.o;
oe.bbmin.add(oe.size);
- loopvj(oe.mapmodels)
- {
+ loopvj(oe.mapmodels) {
extentity &e = *entities::getents()[oe.mapmodels[j]];
ivec eo, er;
if(getentboundingbox(e, eo, er))
@@ -134,10 +115,8 @@ void modifyoctaentity(int flags, int id, extentity &e, cube *c, const ivec &cor,
freeoctaentities(c[i]);
}
if(c[i].ext && c[i].ext->ents) c[i].ext->ents->query = NULL;
- if(va && va!=lastva)
- {
- if(lastva)
- {
+ if(va && va!=lastva) {
+ if(lastva) {
if(va->bbmin.x < 0) lastva->bbmin.x = -1;
}
else if(flags&MODOE_UPDATEBB) updatevabb(va);
@@ -147,24 +126,18 @@ void modifyoctaentity(int flags, int id, extentity &e, cube *c, const ivec &cor,
vector<int> outsideents;
-static bool modifyoctaent(int flags, int id, extentity &e)
-{
+static bool modifyoctaent(int flags, int id, extentity &e) {
if(flags&MODOE_ADD ? e.flags&EF_OCTA : !(e.flags&EF_OCTA)) return false;
-
ivec o, r;
if(!getentboundingbox(e, o, r)) return false;
-
- if(!insideworld(e.o))
- {
+ if(!insideworld(e.o)) {
int idx = outsideents.find(id);
- if(flags&MODOE_ADD)
- {
+ if(flags&MODOE_ADD) {
if(idx < 0) outsideents.add(id);
}
else if(idx >= 0) outsideents.removeunordered(idx);
}
- else
- {
+ else {
int leafsize = octaentsize, limit = max(r.x - o.x, max(r.y - o.y, r.z - o.z));
while(leafsize < limit) leafsize *= 2;
int diff = ~(leafsize-1) & ((o.x^r.x)|(o.y^r.y)|(o.z^r.z));
@@ -178,8 +151,7 @@ static bool modifyoctaent(int flags, int id, extentity &e)
return true;
}
-static inline bool modifyoctaent(int flags, int id)
-{
+static inline bool modifyoctaent(int flags, int id) {
vector<extentity *> &ents = entities::getents();
return ents.inrange(id) && modifyoctaent(flags, id, *ents[id]);
}
@@ -187,68 +159,56 @@ static inline bool modifyoctaent(int flags, int id)
static inline void addentity(int id) { modifyoctaent(MODOE_ADD|MODOE_UPDATEBB|MODOE_LIGHTENT, id); }
static inline void removeentity(int id) { modifyoctaent(MODOE_UPDATEBB, id); }
-void freeoctaentities(cube &c)
-{
+void freeoctaentities(cube &c) {
if(!c.ext) return;
- if(entities::getents().length())
- {
+ if(entities::getents().length()) {
while(c.ext->ents && !c.ext->ents->mapmodels.empty()) removeentity(c.ext->ents->mapmodels.pop());
while(c.ext->ents && !c.ext->ents->other.empty()) removeentity(c.ext->ents->other.pop());
}
- if(c.ext->ents)
- {
+ if(c.ext->ents) {
delete c.ext->ents;
c.ext->ents = NULL;
}
}
-void entitiesinoctanodes()
-{
+void entitiesinoctanodes() {
vector<extentity *> &ents = entities::getents();
loopv(ents) modifyoctaent(MODOE_ADD, i, *ents[i]);
}
-static inline void findents(octaentities &oe, int low, int high, bool notspawned, const vec &pos, const vec &invradius, vector<int> &found)
-{
+static inline void findents(octaentities &oe, int low, int high, bool notspawned, const vec &pos, const vec &invradius, vector<int> &found) {
vector<extentity *> &ents = entities::getents();
- loopv(oe.other)
- {
+ loopv(oe.other) {
int id = oe.other[i];
extentity &e = *ents[id];
if(e.type >= low && e.type <= high && (e.spawned() || notspawned) && vec(e.o).sub(pos).mul(invradius).squaredlen() <= 1) found.add(id);
}
}
-static inline void findents(cube *c, const ivec &o, int size, const ivec &bo, const ivec &br, int low, int high, bool notspawned, const vec &pos, const vec &invradius, vector<int> &found)
-{
- loopoctabox(o, size, bo, br)
- {
+static inline void findents(cube *c, const ivec &o, int size, const ivec &bo, const ivec &br, int low, int high, bool notspawned, const vec &pos, const vec &invradius, vector<int> &found) {
+ loopoctabox(o, size, bo, br) {
if(c[i].ext && c[i].ext->ents) findents(*c[i].ext->ents, low, high, notspawned, pos, invradius, found);
- if(c[i].children && size > octaentsize)
- {
+ if(c[i].children && size > octaentsize) {
ivec co(i, o, size);
findents(c[i].children, co, size>>1, bo, br, low, high, notspawned, pos, invradius, found);
}
}
}
-void findents(int low, int high, bool notspawned, const vec &pos, const vec &radius, vector<int> &found)
-{
+void findents(int low, int high, bool notspawned, const vec &pos, const vec &radius, vector<int> &found) {
vec invradius(1/radius.x, 1/radius.y, 1/radius.z);
ivec bo(vec(pos).sub(radius).sub(1)),
br(vec(pos).add(radius).add(1));
int diff = (bo.x^br.x) | (bo.y^br.y) | (bo.z^br.z) | octaentsize,
scale = worldscale-1;
- if(diff&~((1<<scale)-1) || uint(bo.x|bo.y|bo.z|br.x|br.y|br.z) >= uint(worldsize))
- {
+ if(diff&~((1<<scale)-1) || uint(bo.x|bo.y|bo.z|br.x|br.y|br.z) >= uint(worldsize)) {
findents(worldroot, ivec(0, 0, 0), 1<<scale, bo, br, low, high, notspawned, pos, invradius, found);
return;
}
cube *c = &worldroot[octastep(bo.x, bo.y, bo.z, scale)];
if(c->ext && c->ext->ents) findents(*c->ext->ents, low, high, notspawned, pos, invradius, found);
scale--;
- while(c->children && !(diff&(1<<scale)))
- {
+ while(c->children && !(diff&(1<<scale))) {
c = &c->children[octastep(bo.x, bo.y, bo.z, scale)];
if(c->ext && c->ext->ents) findents(*c->ext->ents, low, high, notspawned, pos, invradius, found);
scale--;
@@ -256,13 +216,11 @@ void findents(int low, int high, bool notspawned, const vec &pos, const vec &rad
if(c->children && 1<<scale >= octaentsize) findents(c->children, ivec(bo).mask(~((2<<scale)-1)), 1<<scale, bo, br, low, high, notspawned, pos, invradius, found);
}
-char *entname(entity &e)
-{
+char *entname(entity &e) {
static string fullentname;
copystring(fullentname, entities::entname(e.type));
const char *einfo = entities::entnameinfo(e);
- if(*einfo)
- {
+ if(*einfo) {
concatstring(fullentname, ": ");
concatstring(fullentname, einfo);
}
@@ -277,14 +235,12 @@ bool undonext = true;
VARF(entediting, 0, 0, 1, { if(!entediting) { entcancel(); efocus = enthover = -1; } });
-bool noentedit()
-{
+bool noentedit() {
if(!editmode) { conoutf(CON_ERROR, "operation only allowed in edit mode"); return true; }
return !entediting;
}
-bool pointinsel(const selinfo &sel, const vec &o)
-{
+bool pointinsel(const selinfo &sel, const vec &o) {
return(o.x <= sel.o.x+sel.s.x*sel.grid
&& o.x >= sel.o.x
&& o.y <= sel.o.y+sel.s.y*sel.grid
@@ -295,31 +251,26 @@ bool pointinsel(const selinfo &sel, const vec &o)
vector<int> entgroup;
-bool haveselent()
-{
+bool haveselent() {
return entgroup.length() > 0;
}
-void entcancel()
-{
+void entcancel() {
entgroup.shrink(0);
}
-void entadd(int id)
-{
+void entadd(int id) {
undonext = true;
entgroup.add(id);
}
-undoblock *newundoent()
-{
+undoblock *newundoent() {
int numents = entgroup.length();
if(numents <= 0) return NULL;
undoblock *u = (undoblock *)new uchar[sizeof(undoblock) + numents*sizeof(undoent)];
u->numents = numents;
undoent *e = (undoent *)(u + 1);
- loopv(entgroup)
- {
+ loopv(entgroup) {
e->i = entgroup[i];
e->e = *entities::getents()[entgroup[i]];
e++;
@@ -327,8 +278,7 @@ undoblock *newundoent()
return u;
}
-void makeundoent()
-{
+void makeundoent() {
if(!undonext) return;
undonext = false;
oldhover = enthover;
@@ -336,8 +286,7 @@ void makeundoent()
if(u) addundo(u);
}
-void detachentity(extentity &e)
-{
+void detachentity(extentity &e) {
if(!e.attached) return;
e.attached->attached = NULL;
e.attached = NULL;
@@ -345,40 +294,31 @@ void detachentity(extentity &e)
VAR(attachradius, 1, 100, 1000);
-void attachentity(extentity &e)
-{
- switch(e.type)
- {
+void attachentity(extentity &e) {
+ switch(e.type) {
case ET_SPOTLIGHT:
break;
-
default:
if(e.type<ET_GAMESPECIFIC || !entities::mayattach(e)) return;
break;
}
-
detachentity(e);
-
vector<extentity *> &ents = entities::getents();
int closest = -1;
float closedist = 1e10f;
- loopv(ents)
- {
+ loopv(ents) {
extentity *a = ents[i];
if(a->attached) continue;
- switch(e.type)
- {
+ switch(e.type) {
case ET_SPOTLIGHT:
if(a->type!=ET_LIGHT) continue;
break;
-
default:
if(e.type<ET_GAMESPECIFIC || !entities::attachent(e, *a)) continue;
break;
}
float dist = e.o.dist(a->o);
- if(dist < closedist)
- {
+ if(dist < closedist) {
closest = i;
closedist = dist;
}
@@ -388,8 +328,7 @@ void attachentity(extentity &e)
ents[closest]->attached = &e;
}
-void attachentities()
-{
+void attachentities() {
vector<extentity *> &ents = entities::getents();
loopv(ents) attachentity(*ents[i]);
}
@@ -400,10 +339,10 @@ void attachentities()
#define addimplicit(f) { if(entgroup.empty() && enthover>=0) { entadd(enthover); undonext = (enthover != oldhover); f; entgroup.drop(); } else f; }
#define entfocusv(i, f, v){ int n = efocus = (i); if(n>=0) { extentity &e = *v[n]; f; } }
#define entfocus(i, f) entfocusv(i, f, entities::getents())
-#define enteditv(i, f, v) \
-{ \
- entfocusv(i, \
- { \
+#define enteditv(i, f, v) { \
+ \
+ entfocusv(i, { \
+ \
int oldtype = e.type; \
removeentity(n); \
f; \
@@ -413,23 +352,21 @@ void attachentities()
}, v); \
}
#define entedit(i, f) enteditv(i, f, entities::getents())
-#define addgroup(exp) { vector<extentity *> &ents = entities::getents(); loopv(ents) entfocusv(i, if(exp) entadd(n), ents); }
-#define setgroup(exp) { entcancel(); addgroup(exp); }
+#define addgroup(exp) { vector<extentity *> &ents = entities::getents(); loopv(ents) entfocusv(i, if(exp) entadd(n), ents); }
+#define setgroup(exp) { entcancel(); addgroup(exp); }
#define groupeditloop(f){ vector<extentity *> &ents = entities::getents(); entlooplevel++; int _ = efocus; loopv(entgroup) enteditv(entgroup[i], f, ents); efocus = _; entlooplevel--; }
#define groupeditpure(f){ if(entlooplevel>0) { entedit(efocus, f); } else groupeditloop(f); }
#define groupeditundo(f){ makeundoent(); groupeditpure(f); }
#define groupedit(f) { addimplicit(groupeditundo(f)); }
-vec getselpos()
-{
+vec getselpos() {
vector<extentity *> &ents = entities::getents();
if(entgroup.length() && ents.inrange(entgroup[0])) return ents[entgroup[0]]->o;
if(ents.inrange(enthover)) return ents[enthover]->o;
return vec(sel.o);
}
-undoblock *copyundoents(undoblock *u)
-{
+undoblock *copyundoents(undoblock *u) {
entcancel();
undoent *e = u->ents();
loopi(u->numents)
@@ -440,8 +377,7 @@ undoblock *copyundoents(undoblock *u)
return c;
}
-void pasteundoent(int idx, const entity &ue)
-{
+void pasteundoent(int idx, const entity &ue) {
if(idx < 0 || idx >= MAXENTS) return;
vector<extentity *> &ents = entities::getents();
while(ents.length() < idx) ents.add(entities::newentity())->type = ET_EMPTY;
@@ -449,23 +385,20 @@ void pasteundoent(int idx, const entity &ue)
entedit(idx, (entity &)e = ue);
}
-void pasteundoents(undoblock *u)
-{
+void pasteundoents(undoblock *u) {
undoent *ue = u->ents();
loopi(u->numents)
entedit(ue[i].i, (entity &)e = ue[i].e);
}
-void entflip()
-{
+void entflip() {
if(noentedit()) return;
int d = dimension(sel.orient);
float mid = sel.s[d]*sel.grid/2+sel.o[d];
groupeditundo(e.o[d] -= (e.o[d]-mid)*2);
}
-void entrotate(int *cw)
-{
+void entrotate(int *cw) {
if(noentedit()) return;
int d = dimension(sel.orient);
int dd = (*cw<0) == dimcoord(sel.orient) ? R[d] : C[d];
@@ -479,12 +412,10 @@ void entrotate(int *cw)
);
}
-void entselectionbox(const entity &e, vec &eo, vec &es)
-{
+void entselectionbox(const entity &e, vec &eo, vec &es) {
model *m = NULL;
const char *mname = entities::entmodel(e);
- if(mname && (m = loadmodel(mname)))
- {
+ if(mname && (m = loadmodel(mname))) {
m->collisionbox(eo, es);
if(es.x > es.y) es.y = es.x; else es.x = es.y; // square
es.z = (es.z + eo.z + 1 + entselradius)/2; // enclose ent radius box and model box
@@ -492,14 +423,12 @@ void entselectionbox(const entity &e, vec &eo, vec &es)
eo.y += e.o.y;
eo.z = e.o.z - entselradius + es.z;
}
- else if(e.type == ET_MAPMODEL && (m = loadmapmodel(e.attr2)))
- {
+ else if(e.type == ET_MAPMODEL && (m = loadmapmodel(e.attr2))) {
mmcollisionbox(e, m, eo, es);
es.max(entselradius);
eo.add(e.o);
}
- else
- {
+ else {
es = vec(entselradius);
eo = e.o;
}
@@ -517,31 +446,24 @@ extern bool editmoveplane(const vec &o, const vec &ray, int d, float off, vec &h
int entmoving = 0;
-void entdrag(const vec &ray)
-{
+void entdrag(const vec &ray) {
if(noentedit() || !haveselent()) return;
-
float r = 0, c = 0;
static vec v, handle;
vec eo, es;
int d = dimension(entorient),
dc= dimcoord(entorient);
-
entfocus(entgroup.last(),
entselectionbox(e, eo, es);
-
if(!editmoveplane(e.o, ray, d, eo[d] + (dc ? es[d] : 0), handle, v, entmoving==1))
return;
-
ivec g(v);
int z = g[d]&(~(sel.grid-1));
g.add(sel.grid/2).mask(~(sel.grid-1));
g[d] = z;
-
r = (entselsnap ? g[R[d]] : v[R[d]]) - e.o[R[d]];
c = (entselsnap ? g[C[d]] : v[C[d]]) - e.o[C[d]];
);
-
if(entmoving==1) makeundoent();
groupeditpure(e.o[R[d]] += r; e.o[C[d]] += c);
entmoving = 2;
@@ -549,13 +471,11 @@ void entdrag(const vec &ray)
VAR(showentradius, 0, 1, 1);
-void renderentring(const extentity &e, float radius, int axis)
-{
+void renderentring(const extentity &e, float radius, int axis) {
if(radius <= 0) return;
gle::defvertex();
gle::begin(GL_LINE_LOOP);
- loopi(15)
- {
+ loopi(15) {
vec p(e.o);
const vec2 &sc = sincos360[i*(360/15)];
p[axis>=2 ? 1 : 0] += radius*sc.x;
@@ -565,14 +485,12 @@ void renderentring(const extentity &e, float radius, int axis)
xtraverts += gle::end();
}
-void renderentsphere(const extentity &e, float radius)
-{
+void renderentsphere(const extentity &e, float radius) {
if(radius <= 0) return;
loopk(3) renderentring(e, radius, k);
}
-void renderentattachment(const extentity &e)
-{
+void renderentattachment(const extentity &e) {
if(!e.attached) return;
gle::defvertex();
gle::begin(GL_LINES);
@@ -581,63 +499,50 @@ void renderentattachment(const extentity &e)
xtraverts += gle::end();
}
-void renderentarrow(const extentity &e, const vec &dir, float radius)
-{
+void renderentarrow(const extentity &e, const vec &dir, float radius) {
if(radius <= 0) return;
float arrowsize = min(radius/8, 0.5f);
vec target = vec(dir).mul(radius).add(e.o), arrowbase = vec(dir).mul(radius - arrowsize).add(e.o), spoke;
spoke.orthogonal(dir);
spoke.normalize();
spoke.mul(arrowsize);
-
gle::defvertex();
-
gle::begin(GL_LINES);
gle::attrib(e.o);
gle::attrib(target);
xtraverts += gle::end();
-
gle::begin(GL_TRIANGLE_FAN);
gle::attrib(target);
loopi(5) gle::attrib(vec(spoke).rotate(2*M_PI*i/4.0f, dir).add(arrowbase));
xtraverts += gle::end();
}
-void renderentcone(const extentity &e, const vec &dir, float radius, float angle)
-{
+void renderentcone(const extentity &e, const vec &dir, float radius, float angle) {
if(radius <= 0) return;
vec spot = vec(dir).mul(radius*cosf(angle*RAD)).add(e.o), spoke;
spoke.orthogonal(dir);
spoke.normalize();
spoke.mul(radius*sinf(angle*RAD));
-
gle::defvertex();
-
gle::begin(GL_LINES);
- loopi(8)
- {
+ loopi(8) {
gle::attrib(e.o);
gle::attrib(vec(spoke).rotate(2*M_PI*i/8.0f, dir).add(spot));
}
xtraverts += gle::end();
-
gle::begin(GL_LINE_LOOP);
loopi(8) gle::attrib(vec(spoke).rotate(2*M_PI*i/8.0f, dir).add(spot));
xtraverts += gle::end();
}
-void renderentradius(extentity &e, bool color)
-{
- switch(e.type)
- {
+void renderentradius(extentity &e, bool color) {
+ switch(e.type) {
case ET_LIGHT:
if(color) gle::colorf(e.attr2/255.0f, e.attr3/255.0f, e.attr4/255.0f);
renderentsphere(e, e.attr1);
break;
-
case ET_SPOTLIGHT:
- if(e.attached)
- {
+ if(e.attached) {
if(color) gle::colorf(0, 1, 1);
float radius = e.attached->attr1;
if(!radius) radius = 2*e.o.dist(e.attached->o);
@@ -647,15 +552,12 @@ void renderentradius(extentity &e, bool color)
renderentcone(*e.attached, dir, radius, angle);
}
break;
-
case ET_SOUND:
if(color) gle::colorf(0, 1, 1);
renderentsphere(e, e.attr2);
break;
-
case ET_MAPMODEL:
- case ET_PLAYERSTART:
- {
+ case ET_PLAYERSTART: {
if(color) gle::colorf(0, 1, 1);
entities::entradius(e, color);
vec dir;
@@ -663,10 +565,8 @@ void renderentradius(extentity &e, bool color)
renderentarrow(e, dir, 4);
break;
}
-
default:
- if(e.type>=ET_GAMESPECIFIC)
- {
+ if(e.type>=ET_GAMESPECIFIC) {
if(color) gle::colorf(0, 1, 1);
entities::entradius(e, color);
}
@@ -674,22 +574,18 @@ void renderentradius(extentity &e, bool color)
}
}
-static void renderentbox(const vec &eo, vec es)
-{
+static void renderentbox(const vec &eo, vec es) {
es.add(eo);
-
// bottom quad
gle::attrib(eo.x, eo.y, eo.z); gle::attrib(es.x, eo.y, eo.z);
gle::attrib(es.x, eo.y, eo.z); gle::attrib(es.x, es.y, eo.z);
gle::attrib(es.x, es.y, eo.z); gle::attrib(eo.x, es.y, eo.z);
gle::attrib(eo.x, es.y, eo.z); gle::attrib(eo.x, eo.y, eo.z);
-
// top quad
gle::attrib(eo.x, eo.y, es.z); gle::attrib(es.x, eo.y, es.z);
gle::attrib(es.x, eo.y, es.z); gle::attrib(es.x, es.y, es.z);
gle::attrib(es.x, es.y, es.z); gle::attrib(eo.x, es.y, es.z);
gle::attrib(eo.x, es.y, es.z); gle::attrib(eo.x, eo.y, es.z);
-
// sides
gle::attrib(eo.x, eo.y, eo.z); gle::attrib(eo.x, eo.y, es.z);
gle::attrib(es.x, eo.y, eo.z); gle::attrib(es.x, eo.y, es.z);
@@ -697,13 +593,10 @@ static void renderentbox(const vec &eo, vec es)
gle::attrib(eo.x, es.y, eo.z); gle::attrib(eo.x, es.y, es.z);
}
-void renderentselection(const vec &o, const vec &ray, bool entmoving)
-{
+void renderentselection(const vec &o, bool entmoving) {
if(noentedit()) return;
vec eo, es;
-
- if(entgroup.length())
- {
+ if(entgroup.length()) {
gle::colorub(0, 40, 0);
gle::defvertex();
gle::begin(GL_LINES, entgroup.length()*24);
@@ -713,14 +606,11 @@ void renderentselection(const vec &o, const vec &ray, bool entmoving)
);
xtraverts += gle::end();
}
-
- if(enthover >= 0)
- {
+ if(enthover >= 0) {
gle::colorub(0, 40, 0);
entfocus(enthover, entselectionbox(e, eo, es)); // also ensures enthover is back in focus
boxs3D(eo, es, 1);
- if(entmoving && entmovingshadow==1)
- {
+ if(entmoving && entmovingshadow==1) {
vec a, b;
gle::colorub(20, 20, 20);
(a = eo).x = eo.x - fmod(eo.x, worldsize); (b = es).x = a.x + worldsize; boxs3D(a, b, 1);
@@ -731,9 +621,7 @@ void renderentselection(const vec &o, const vec &ray, bool entmoving)
boxs(entorient, eo, es);
boxs(entorient, eo, es, clamp(0.015f*camera1->o.dist(eo)*tan(fovy*0.5f*RAD), 0.1f, 1.0f));
}
-
- if(showentradius && (entgroup.length() || enthover >= 0))
- {
+ if(showentradius && (entgroup.length() || enthover >= 0)) {
glDepthFunc(GL_GREATER);
gle::colorf(0.25f, 0.25f, 0.25f);
loopv(entgroup) entfocus(entgroup[i], renderentradius(e, false));
@@ -744,8 +632,7 @@ void renderentselection(const vec &o, const vec &ray, bool entmoving)
}
}
-bool enttoggle(int id)
-{
+bool enttoggle(int id) {
undonext = true;
int i = entgroup.find(id);
if(i < 0)
@@ -755,8 +642,7 @@ bool enttoggle(int id)
return i < 0;
}
-bool hoveringonent(int ent, int orient)
-{
+bool hoveringonent(int ent, int orient) {
if(noentedit()) return false;
entorient = orient;
if((efocus = enthover = ent) >= 0)
@@ -768,28 +654,22 @@ bool hoveringonent(int ent, int orient)
VAR(entitysurf, 0, 0, 1);
-ICOMMAND(entadd, "", (),
-{
- if(enthover >= 0 && !noentedit())
- {
+ICOMMAND(entadd, "", (), {
+ if(enthover >= 0 && !noentedit()) {
if(entgroup.find(enthover) < 0) entadd(enthover);
if(entmoving > 1) entmoving = 1;
}
});
-ICOMMAND(enttoggle, "", (),
-{
+ICOMMAND(enttoggle, "", (), {
if(enthover < 0 || noentedit() || !enttoggle(enthover)) { entmoving = 0; intret(0); }
else { if(entmoving > 1) entmoving = 1; intret(1); }
});
-ICOMMAND(entmoving, "b", (int *n),
-{
- if(*n >= 0)
- {
+ICOMMAND(entmoving, "b", (int *n), {
+ if(*n >= 0) {
if(!*n || enthover < 0 || noentedit()) entmoving = 0;
- else
- {
+ else {
if(entgroup.find(enthover) < 0) { entadd(enthover); entmoving = 1; }
else if(!entmoving) entmoving = 1;
}
@@ -797,27 +677,23 @@ ICOMMAND(entmoving, "b", (int *n),
intret(entmoving);
});
-void entpush(int *dir)
-{
+void entpush(int *dir) {
if(noentedit()) return;
int d = dimension(entorient);
int s = dimcoord(entorient) ? -*dir : *dir;
- if(entmoving)
- {
+ if(entmoving) {
groupeditpure(e.o[d] += float(s*sel.grid)); // editdrag supplies the undo
}
else
groupedit(e.o[d] += float(s*sel.grid));
- if(entitysurf==1)
- {
+ if(entitysurf==1) {
player->o[d] += float(s*sel.grid);
player->resetinterp();
}
}
VAR(entautoviewdist, 0, 25, 100);
-void entautoview(int *dir)
-{
+void entautoview(int *dir) {
if(!haveselent()) return;
static int s = 0;
vec v(player->o);
@@ -839,15 +715,13 @@ COMMAND(entflip, "");
COMMAND(entrotate, "i");
COMMAND(entpush, "i");
-void delent()
-{
+void delent() {
if(noentedit()) return;
groupedit(e.type = ET_EMPTY;);
entcancel();
}
-int findtype(char *what)
-{
+int findtype(char *what) {
for(int i = 0; *entities::entname(i); i++) if(strcmp(what, entities::entname(i))==0) return i;
conoutf(CON_ERROR, "unknown entity type \"%s\"", what);
return ET_EMPTY;
@@ -855,15 +729,12 @@ int findtype(char *what)
VAR(entdrop, 0, 2, 3);
-bool dropentity(entity &e, int drop = -1)
-{
+bool dropentity(entity &e, int drop = -1) {
vec radius(4.0f, 4.0f, 4.0f);
if(drop<0) drop = entdrop;
- if(e.type == ET_MAPMODEL)
- {
+ if(e.type == ET_MAPMODEL) {
model *m = loadmapmodel(e.attr2);
- if(m)
- {
+ if(m) {
vec center;
mmboundbox(e, m, center, radius);
radius.x += fabs(center.x);
@@ -871,8 +742,7 @@ bool dropentity(entity &e, int drop = -1)
}
radius.z = 0.0f;
}
- switch(drop)
- {
+ switch(drop) {
case 1:
if(e.type != ET_LIGHT && e.type != ET_SPOTLIGHT)
dropenttofloor(&e);
@@ -880,8 +750,7 @@ bool dropentity(entity &e, int drop = -1)
case 2:
case 3:
int cx = 0, cy = 0;
- if(sel.cxs == 1 && sel.cys == 1)
- {
+ if(sel.cxs == 1 && sel.cys == 1) {
cx = (sel.cx ? 1 : -1) * sel.grid / 2;
cy = (sel.cy ? 1 : -1) * sel.grid / 2;
}
@@ -893,7 +762,6 @@ bool dropentity(entity &e, int drop = -1)
e.o[D[d]] -= radius[D[d]];
else
e.o[D[d]] += sel.grid + radius[D[d]];
-
if(drop == 3)
dropenttofloor(&e);
break;
@@ -901,14 +769,12 @@ bool dropentity(entity &e, int drop = -1)
return true;
}
-void dropent()
-{
+void dropent() {
if(noentedit()) return;
groupedit(dropentity(e));
}
-void attachent()
-{
+void attachent() {
if(noentedit()) return;
groupedit(attachentity(e));
}
@@ -919,11 +785,9 @@ VARP(entcamdir, 0, 1, 1);
static int keepents = 0;
-extentity *newentity(bool local, const vec &o, int type, int v1, int v2, int v3, int v4, int v5, int &idx)
-{
+extentity *newentity(bool local, const vec &o, int type, int v1, int v2, int v3, int v4, int v5, int &idx) {
vector<extentity *> &ents = entities::getents();
- if(local)
- {
+ if(local) {
idx = -1;
for(int i = keepents; i < ents.length(); i++) if(ents[i]->type == ET_EMPTY) { idx = i; break; }
if(idx < 0 && ents.length() >= MAXENTS) { conoutf(CON_ERROR, "too many entities"); return NULL; }
@@ -940,10 +804,8 @@ extentity *newentity(bool local, const vec &o, int type, int v1, int v2, int v3,
e.reserved = 0;
e.light.color = vec(1, 1, 1);
e.light.dir = vec(0, 0, 1);
- if(local)
- {
- if(entcamdir) switch(type)
- {
+ if(local) {
+ if(entcamdir) switch(type) {
case ET_MAPMODEL:
case ET_PLAYERSTART:
e.attr5 = e.attr4;
@@ -960,8 +822,7 @@ extentity *newentity(bool local, const vec &o, int type, int v1, int v2, int v3,
return &e;
}
-void newentity(int type, int a1, int a2, int a3, int a4, int a5)
-{
+void newentity(int type, int a1, int a2, int a3, int a4, int a5) {
int idx;
extentity *t = newentity(true, player->o, type, a1, a2, a3, a4, a5, idx);
if(!t) return;
@@ -972,8 +833,7 @@ void newentity(int type, int a1, int a2, int a3, int a4, int a5)
entedit(idx, e.type = type);
}
-void newent(char *what, int *a1, int *a2, int *a3, int *a4, int *a5)
-{
+void newent(char *what, int *a1, int *a2, int *a3, int *a4, int *a5) {
if(noentedit()) return;
int type = findtype(what);
if(type != ET_EMPTY)
@@ -983,8 +843,7 @@ void newent(char *what, int *a1, int *a2, int *a3, int *a4, int *a5)
int entcopygrid;
vector<entity> entcopybuf;
-void entcopy()
-{
+void entcopy() {
if(noentedit()) return;
entcopygrid = sel.grid;
entcopybuf.shrink(0);
@@ -992,14 +851,12 @@ void entcopy()
entfocus(entgroup[i], entcopybuf.add(e).o.sub(vec(sel.o)));
}
-void entpaste()
-{
+void entpaste() {
if(noentedit()) return;
if(entcopybuf.length()==0) return;
entcancel();
float m = float(sel.grid)/float(entcopygrid);
- loopv(entcopybuf)
- {
+ loopv(entcopybuf) {
entity &c = entcopybuf[i];
vec o(c.o);
o.mul(m).add(vec(sel.o));
@@ -1020,8 +877,7 @@ COMMAND(dropent, "");
COMMAND(entcopy, "");
COMMAND(entpaste, "");
-void entset(char *what, int *a1, int *a2, int *a3, int *a4, int *a5)
-{
+void entset(char *what, int *a1, int *a2, int *a3, int *a4, int *a5) {
if(noentedit()) return;
int type = findtype(what);
if(type != ET_EMPTY)
@@ -1033,14 +889,11 @@ void entset(char *what, int *a1, int *a2, int *a3, int *a4, int *a5)
e.attr5=*a5);
}
-void printent(extentity &e, char *buf, int len)
-{
- switch(e.type)
- {
+void printent(extentity &e, char *buf, int len) {
+ switch(e.type) {
case ET_PARTICLES:
if(printparticles(e, buf, len)) return;
break;
-
default:
if(e.type >= ET_GAMESPECIFIC && entities::printent(e, buf, len)) return;
break;
@@ -1048,19 +901,16 @@ void printent(extentity &e, char *buf, int len)
nformatstring(buf, len, "%s %d %d %d %d %d", entities::entname(e.type), e.attr1, e.attr2, e.attr3, e.attr4, e.attr5);
}
-void nearestent()
-{
+void nearestent() {
if(noentedit()) return;
int closest = -1;
float closedist = 1e16f;
vector<extentity *> &ents = entities::getents();
- loopv(ents)
- {
+ loopv(ents) {
extentity &e = *ents[i];
if(e.type == ET_EMPTY) continue;
float dist = e.o.dist(player->o);
- if(dist < closedist)
- {
+ if(dist < closedist) {
closest = i;
closedist = dist;
}
@@ -1077,27 +927,21 @@ ICOMMAND(entindex, "", (), intret(efocus));
COMMAND(entset, "siiiii");
COMMAND(nearestent, "");
-void enttype(char *type, int *numargs)
-{
- if(*numargs >= 1)
- {
+void enttype(char *type, int *numargs) {
+ if(*numargs >= 1) {
int typeidx = findtype(type);
if(typeidx != ET_EMPTY) groupedit(e.type = typeidx);
}
- else entfocus(efocus,
- {
+ else entfocus(efocus, {
result(entities::entname(e.type));
})
}
-void entattr(int *attr, int *val, int *numargs)
-{
- if(*numargs >= 2)
- {
+void entattr(int *attr, int *val, int *numargs) {
+ if(*numargs >= 2) {
if(*attr >= 0 && *attr <= 4)
groupedit(
- switch(*attr)
- {
+ switch(*attr) {
case 0: e.attr1 = *val; break;
case 1: e.attr2 = *val; break;
case 2: e.attr3 = *val; break;
@@ -1106,10 +950,8 @@ void entattr(int *attr, int *val, int *numargs)
}
);
}
- else entfocus(efocus,
- {
- switch(*attr)
- {
+ else entfocus(efocus, {
+ switch(*attr) {
case 0: intret(e.attr1); break;
case 1: intret(e.attr2); break;
case 2: intret(e.attr3); break;
@@ -1122,18 +964,15 @@ void entattr(int *attr, int *val, int *numargs)
COMMAND(enttype, "sN");
COMMAND(entattr, "iiN");
-int findentity(int type, int index, int attr1, int attr2)
-{
+int findentity(int type, int index, int attr1, int attr2) {
const vector<extentity *> &ents = entities::getents();
if(index > ents.length()) index = ents.length();
- else for(int i = index; i<ents.length(); i++)
- {
+ else for(int i = index; i<ents.length(); i++) {
extentity &e = *ents[i];
if(e.type==type && (attr1<0 || e.attr1==attr1) && (attr2<0 || e.attr2==attr2))
return i;
}
- loopj(index)
- {
+ loopj(index) {
extentity &e = *ents[j];
if(e.type==type && (attr1<0 || e.attr1==attr1) && (attr2<0 || e.attr2==attr2))
return j;
@@ -1145,12 +984,10 @@ struct spawninfo { const extentity *e; float weight; };
// Compiles a vector of available playerstarts, each with a non-zero weight
// which serves as a measure of its desirability for a spawning player.
-float gatherspawninfos(dynent *d, int tag, vector<spawninfo> &spawninfos)
-{
+float gatherspawninfos(dynent *d, int tag, vector<spawninfo> &spawninfos) {
const vector<extentity *> &ents = entities::getents();
float total = 0.0f;
- loopv(ents)
- {
+ loopv(ents) {
const extentity &e = *ents[i];
if(e.type != ET_PLAYERSTART || e.attr2 != tag) continue;
spawninfo &s = spawninfos.add();
@@ -1164,12 +1001,10 @@ float gatherspawninfos(dynent *d, int tag, vector<spawninfo> &spawninfos)
// Randomly picks a weighted spawn from the provided vector and removes it.
// The probability of a given spawn being picked is proportional to its weight.
// If all weights are zero, the index is picked uniformly.
-static const extentity *poprandomspawn(vector<spawninfo> &spawninfos, float &total)
-{
+static const extentity *poprandomspawn(vector<spawninfo> &spawninfos, float &total) {
if(spawninfos.empty()) return NULL;
int index = 0;
- if(total > 0.0f)
- {
+ if(total > 0.0f) {
float x = rndscale(total);
do x -= spawninfos[index].weight; while(x > 0 && ++index < spawninfos.length()-1);
}
@@ -1179,15 +1014,13 @@ static const extentity *poprandomspawn(vector<spawninfo> &spawninfos, float &tot
return s.e;
}
-static inline bool tryspawn(dynent *d, const extentity &e)
-{
+static inline bool tryspawn(dynent *d, const extentity &e) {
d->o = e.o;
d->yaw = e.attr1;
return entinmap(d, true);
}
-void findplayerspawn(dynent *d, int forceent, int tag)
-{
+void findplayerspawn(dynent *d, int forceent, int tag) {
const vector<extentity *> &ents = entities::getents();
d->pitch = 0;
d->roll = 0;
@@ -1200,18 +1033,15 @@ void findplayerspawn(dynent *d, int forceent, int tag)
entinmap(d);
}
-void splitocta(cube *c, int size)
-{
+void splitocta(cube *c, int size) {
if(size <= 0x1000) return;
- loopi(8)
- {
+ loopi(8) {
if(!c[i].children) c[i].children = newcubes(isempty(c[i]) ? F_EMPTY : F_SOLID);
splitocta(c[i].children, size>>1);
}
}
-void resetmap()
-{
+void resetmap() {
clearoverrides();
clearmapsounds();
resetlightmaps();
@@ -1222,101 +1052,74 @@ void resetmap()
cancelsel();
pruneundos();
clearmapcrc();
-
entities::clearents();
outsideents.setsize(0);
}
-void startmap(const char *name)
-{
+void startmap(const char *name) {
game::startmap(name);
}
-bool emptymap(int scale, bool force, const char *mname, bool usecfg) // main empty world creation routine
-{
- if(!force && !editmode)
- {
+bool emptymap(int scale, bool force, const char *mname, bool usecfg) { // main empty world creation routine {
+ if(!force && !editmode) {
conoutf(CON_ERROR, "newmap only allowed in edit mode");
return false;
}
-
resetmap();
-
setvar("mapscale", scale<10 ? 10 : (scale>16 ? 16 : scale), true, false);
setvar("mapsize", 1<<worldscale, true, false);
-
texmru.shrink(0);
freeocta(worldroot);
worldroot = newcubes(F_EMPTY);
loopi(4) solidfaces(worldroot[i]);
-
if(worldsize > 0x1000) splitocta(worldroot, worldsize>>1);
-
clearmainmenu();
-
- if(usecfg)
- {
+ if(usecfg) {
identflags |= IDF_OVERRIDDEN;
execfile("data/default_map.cfg", false);
identflags &= ~IDF_OVERRIDDEN;
}
-
initlights();
allchanged(true);
-
startmap(mname);
-
return true;
}
-bool enlargemap(bool force)
-{
- if(!force && !editmode)
- {
+bool enlargemap(bool force) {
+ if(!force && !editmode) {
conoutf(CON_ERROR, "mapenlarge only allowed in edit mode");
return false;
}
if(worldsize >= 1<<16) return false;
-
while(outsideents.length()) removeentity(outsideents.pop());
-
worldscale++;
worldsize *= 2;
cube *c = newcubes(F_EMPTY);
c[0].children = worldroot;
loopi(3) solidfaces(c[i+1]);
worldroot = c;
-
if(worldsize > 0x1000) splitocta(worldroot, worldsize>>1);
-
allchanged();
-
return true;
}
-static bool isallempty(cube &c)
-{
+static bool isallempty(cube &c) {
if(!c.children) return isempty(c);
loopi(8) if(!isallempty(c.children[i])) return false;
return true;
}
-void shrinkmap()
-{
+void shrinkmap() {
extern int nompedit;
if(noedit(true) || (nompedit && multiplayer())) return;
if(worldsize <= 1<<10) return;
-
int octant = -1;
- loopi(8) if(!isallempty(worldroot[i]))
- {
+ loopi(8) if(!isallempty(worldroot[i])) {
if(octant >= 0) return;
octant = i;
}
if(octant < 0) return;
-
while(outsideents.length()) removeentity(outsideents.pop());
-
if(!worldroot[octant].children) subdividecube(worldroot[octant], false, false);
cube *root = worldroot[octant].children;
worldroot[octant].children = NULL;
@@ -1324,13 +1127,10 @@ void shrinkmap()
worldroot = root;
worldscale--;
worldsize /= 2;
-
ivec offset(octant, ivec(0, 0, 0), worldsize);
vector<extentity *> &ents = entities::getents();
loopv(ents) ents[i]->o.sub(vec(offset));
-
allchanged();
-
conoutf("shrunk map to size %d", worldscale);
}
@@ -1340,26 +1140,22 @@ COMMAND(newmap, "i");
COMMAND(mapenlarge, "");
COMMAND(shrinkmap, "");
-void mapname()
-{
+void mapname() {
result(game::getclientmap());
}
COMMAND(mapname, "");
-void mpeditent(int i, const vec &o, int type, int attr1, int attr2, int attr3, int attr4, int attr5, bool local)
-{
+void mpeditent(int i, const vec &o, int type, int attr1, int attr2, int attr3, int attr4, int attr5, bool local) {
if(i < 0 || i >= MAXENTS) return;
vector<extentity *> &ents = entities::getents();
- if(ents.length()<=i)
- {
+ if(ents.length()<=i) {
extentity *e = newentity(local, o, type, attr1, attr2, attr3, attr4, attr5, i);
if(!e) return;
addentity(i);
attachentity(*e);
}
- else
- {
+ else {
extentity &e = *ents[i];
removeentity(i);
int oldtype = e.type;
diff --git a/src/engine/world.h b/src/engine/world.h
index 43ec470..91812b4 100644
--- a/src/engine/world.h
+++ b/src/engine/world.h
@@ -1,12 +1,10 @@
-enum // hardcoded texture numbers
-{
+enum { // hardcoded texture numbers {
DEFAULT_GEOM
};
#define MAPVERSION 34 // bump if map format changes, see worldio.cpp
-struct octaheader
-{
+struct octaheader {
char magic[4]; // "OCTA"
int version; // any >8bit quantity is little endian
int headersize; // sizeof(header)
@@ -18,8 +16,7 @@ struct octaheader
int numvslots;
};
-enum
-{
+enum {
MATSURF_NOT_VISIBLE = 0,
MATSURF_VISIBLE,
MATSURF_EDIT_ONLY
@@ -28,4 +25,3 @@ enum
#define TEX_SCALE 8.0f
struct vertex { vec pos; bvec4 norm; vec2 tc; svec2 lm; bvec4 tangent; };
-
diff --git a/src/engine/worldio.cpp b/src/engine/worldio.cpp
index 4e309a8..898b2bb 100644
--- a/src/engine/worldio.cpp
+++ b/src/engine/worldio.cpp
@@ -2,12 +2,10 @@
#include "engine.h"
-void validmapname(char *dst, const char *src, const char *prefix = NULL, const char *alt = "untitled", size_t maxlen = 100)
-{
+void validmapname(char *dst, const char *src, const char *prefix = NULL, const char *alt = "untitled", size_t maxlen = 100) {
if(prefix) while(*prefix) *dst++ = *prefix++;
const char *start = dst;
- if(src) loopi(maxlen)
- {
+ if(src) loopi(maxlen) {
char c = *src++;
if(iscubealnum(c) || c == '_' || c == '-' || c == '/' || c == '\\') *dst++ = c;
else break;
@@ -16,32 +14,27 @@ void validmapname(char *dst, const char *src, const char *prefix = NULL, const c
else if(dst != alt) copystring(dst, alt, maxlen);
}
-void fixmapname(char *name)
-{
+void fixmapname(char *name) {
validmapname(name, name, NULL, "");
}
-void getmapfilenames(const char *fname, const char *cname, char *pakname, char *mapname, char *cfgname)
-{
+void getmapfilenames(const char *fname, const char *cname, char *pakname, char *mapname, char *cfgname) {
if(!cname) cname = fname;
string name;
validmapname(name, cname);
char *slash = strpbrk(name, "/\\");
- if(slash)
- {
+ if(slash) {
copystring(pakname, name, slash-name+1);
copystring(cfgname, slash+1, MAXSTRLEN);
}
- else
- {
+ else {
copystring(pakname, "maps", MAXSTRLEN);
copystring(cfgname, name, MAXSTRLEN);
}
validmapname(mapname, fname, strpbrk(fname, "/\\") ? NULL : "maps/");
}
-bool loadents(const char *fname, vector<entity> &ents, uint *crc)
-{
+bool loadents(const char *fname, vector<entity> &ents, uint *crc) {
string pakname, mapname, mcfgname, ogzname;
getmapfilenames(fname, NULL, pakname, mapname, mcfgname);
formatstring(ogzname, "packages/%s.ogz", mapname);
@@ -53,21 +46,16 @@ bool loadents(const char *fname, vector<entity> &ents, uint *crc)
lilswap(&hdr.version, 6);
if(memcmp(hdr.magic, "OCTA", 4) || hdr.worldsize <= 0|| hdr.numents < 0) { conoutf(CON_ERROR, "map %s has malformatted header", ogzname); delete f; return false; }
if(hdr.version>MAPVERSION) { conoutf(CON_ERROR, "map %s requires a newer version of Cube 2: Sauerbraten", ogzname); delete f; return false; }
-
lilswap(&hdr.numvslots, 1);
-
- loopi(hdr.numvars)
- {
+ loopi(hdr.numvars) {
int type = f->getchar(), ilen = f->getlil<ushort>();
f->seek(ilen, SEEK_CUR);
- switch(type)
- {
+ switch(type) {
case ID_VAR: f->getlil<int>(); break;
case ID_FVAR: f->getlil<float>(); break;
case ID_SVAR: { int slen = f->getlil<ushort>(); f->seek(slen, SEEK_CUR); break; }
}
}
-
string gametype;
copystring(gametype, "fps");
int eif = 0;
@@ -76,32 +64,24 @@ bool loadents(const char *fname, vector<entity> &ents, uint *crc)
eif = f->getlil<ushort>();
int extrasize = f->getlil<ushort>();
f->seek(extrasize, SEEK_CUR);
-
ushort nummru = f->getlil<ushort>();
f->seek(nummru*sizeof(ushort), SEEK_CUR);
-
- loopi(min(hdr.numents, MAXENTS))
- {
+ loopi(min(hdr.numents, MAXENTS)) {
entity &e = ents.add();
f->read(&e, sizeof(entity));
lilswap(&e.o.x, 3);
lilswap(&e.attr1, 5);
if(eif > 0) f->seek(eif, SEEK_CUR);
- if(e.type>=ET_GAMESPECIFIC)
- {
+ if(e.type>=ET_GAMESPECIFIC) {
ents.pop();
continue;
}
}
-
- if(crc)
- {
+ if(crc) {
f->seek(0, SEEK_END);
*crc = f->getcrc();
}
-
delete f;
-
return true;
}
@@ -110,25 +90,21 @@ string ogzname, bakname, cfgname, picname;
VARP(savebak, 0, 2, 2);
-void setmapfilenames(const char *fname, const char *cname = NULL)
-{
+void setmapfilenames(const char *fname, const char *cname = NULL) {
string pakname, mapname, mcfgname;
getmapfilenames(fname, cname, pakname, mapname, mcfgname);
-
formatstring(ogzname, "packages/%s.ogz", mapname);
if(savebak==1) formatstring(bakname, "packages/%s.BAK", mapname);
else formatstring(bakname, "packages/%s_%d.BAK", mapname, totalmillis);
formatstring(cfgname, "packages/%s/%s.cfg", pakname, mcfgname);
formatstring(picname, "packages/%s.png", mapname);
-
path(ogzname);
path(bakname);
path(cfgname);
path(picname);
}
-void mapcfgname()
-{
+void mapcfgname() {
const char *mname = game::getclientmap();
string pakname, mapname, mcfgname;
getmapfilenames(mname, NULL, pakname, mapname, mcfgname);
@@ -139,8 +115,7 @@ void mapcfgname()
COMMAND(mapcfgname, "");
-void backup(char *name, char *backupname)
-{
+void backup(char *name, char *backupname) {
string backupfile;
copystring(backupfile, findfile(backupname, "wb"));
remove(backupfile);
@@ -151,30 +126,22 @@ enum { OCTSAV_CHILDREN = 0, OCTSAV_EMPTY, OCTSAV_SOLID, OCTSAV_NORMAL, OCTSAV_LO
static int savemapprogress = 0;
-void savec(cube *c, const ivec &o, int size, stream *f, bool nolms)
-{
+void savec(cube *c, const ivec &o, int size, stream *f, bool nolms) {
if((savemapprogress++&0xFFF)==0) renderprogress(float(savemapprogress)/allocnodes, "saving octree...");
-
- loopi(8)
- {
+ loopi(8) {
ivec co(i, o, size);
- if(c[i].children)
- {
+ if(c[i].children) {
f->putchar(OCTSAV_CHILDREN);
savec(c[i].children, co, size>>1, f, nolms);
}
- else
- {
+ else {
int oflags = 0, surfmask = 0, totalverts = 0;
if(c[i].material!=MAT_AIR) oflags |= 0x40;
if(isempty(c[i])) f->putchar(oflags | OCTSAV_EMPTY);
- else
- {
- if(!nolms)
- {
+ else {
+ if(!nolms) {
if(c[i].merged) oflags |= 0x80;
- if(c[i].ext) loopj(6)
- {
+ if(c[i].ext) loopj(6) {
const surfaceinfo &surf = c[i].ext->surfaces[j];
if(!surf.used()) continue;
oflags |= 0x20;
@@ -182,34 +149,26 @@ void savec(cube *c, const ivec &o, int size, stream *f, bool nolms)
totalverts += surf.totalverts();
}
}
-
if(isentirelysolid(c[i])) f->putchar(oflags | OCTSAV_SOLID);
- else
- {
+ else {
f->putchar(oflags | OCTSAV_NORMAL);
f->write(c[i].edges, 12);
}
}
-
loopj(6) f->putlil<ushort>(c[i].texture[j]);
-
if(oflags&0x40) f->putlil<ushort>(c[i].material);
if(oflags&0x80) f->putchar(c[i].merged);
- if(oflags&0x20)
- {
+ if(oflags&0x20) {
f->putchar(surfmask);
f->putchar(totalverts);
- loopj(6) if(surfmask&(1<<j))
- {
+ loopj(6) if(surfmask&(1<<j)) {
surfaceinfo surf = c[i].ext->surfaces[j];
vertinfo *verts = c[i].ext->verts() + surf.verts;
int layerverts = surf.numverts&MAXFACEVERTS, numverts = surf.totalverts(),
vertmask = 0, vertorder = 0, uvorder = 0,
dim = dimension(j), vc = C[dim], vr = R[dim];
- if(numverts)
- {
- if(c[i].merged&(1<<j))
- {
+ if(numverts) {
+ if(c[i].merged&(1<<j)) {
vertmask |= 0x04;
if(layerverts == 4)
{
@@ -226,22 +185,19 @@ void savec(cube *c, const ivec &o, int size, stream *f, bool nolms)
}
}
}
- else
- {
+ else {
int vis = visibletris(c[i], j, co, size);
if(vis&4 || faceconvexity(c[i], j) < 0) vertmask |= 0x01;
if(layerverts < 4 && vis&2) vertmask |= 0x02;
}
bool matchnorm = true;
- loopk(numverts)
- {
+ loopk(numverts) {
const vertinfo &v = verts[k];
if(v.u || v.v) vertmask |= 0x40;
if(v.norm) { vertmask |= 0x80; if(v.norm != verts[0].norm) matchnorm = false; }
}
if(matchnorm) vertmask |= 0x08;
- if(vertmask&0x40 && layerverts == 4)
- {
+ if(vertmask&0x40 && layerverts == 4) {
loopk(4)
{
const vertinfo &v0 = verts[k], &v1 = verts[(k+1)&3], &v2 = verts[(k+2)&3], &v3 = verts[(k+3)&3];
@@ -263,17 +219,14 @@ void savec(cube *c, const ivec &o, int size, stream *f, bool nolms)
surf.verts = vertmask;
f->write(&surf, sizeof(surfaceinfo));
bool hasxyz = (vertmask&0x04)!=0, hasuv = (vertmask&0x40)!=0, hasnorm = (vertmask&0x80)!=0;
- if(layerverts == 4)
- {
- if(hasxyz && vertmask&0x01)
- {
+ if(layerverts == 4) {
+ if(hasxyz && vertmask&0x01) {
ivec v0 = verts[vertorder].getxyz(), v2 = verts[(vertorder+2)&3].getxyz();
f->putlil<ushort>(v0[vc]); f->putlil<ushort>(v0[vr]);
f->putlil<ushort>(v2[vc]); f->putlil<ushort>(v2[vr]);
hasxyz = false;
}
- if(hasuv && vertmask&0x02)
- {
+ if(hasuv && vertmask&0x02) {
const vertinfo &v0 = verts[uvorder], &v2 = verts[(uvorder+2)&3];
f->putlil<ushort>(v0.u); f->putlil<ushort>(v0.v);
f->putlil<ushort>(v2.u); f->putlil<ushort>(v2.v);
@@ -287,19 +240,16 @@ void savec(cube *c, const ivec &o, int size, stream *f, bool nolms)
}
}
if(hasnorm && vertmask&0x08) { f->putlil<ushort>(verts[0].norm); hasnorm = false; }
- if(hasxyz || hasuv || hasnorm) loopk(layerverts)
- {
+ if(hasxyz || hasuv || hasnorm) loopk(layerverts) {
const vertinfo &v = verts[(k+vertorder)%layerverts];
- if(hasxyz)
- {
+ if(hasxyz) {
ivec xyz = v.getxyz();
f->putlil<ushort>(xyz[vc]); f->putlil<ushort>(xyz[vr]);
}
if(hasuv) { f->putlil<ushort>(v.u); f->putlil<ushort>(v.v); }
if(hasnorm) f->putlil<ushort>(v.norm);
}
- if(surf.numverts&LAYER_DUP) loopk(layerverts)
- {
+ if(surf.numverts&LAYER_DUP) loopk(layerverts) {
const vertinfo &v = verts[layerverts + (k+vertorder)%layerverts];
if(hasuv) { f->putlil<ushort>(v.u); f->putlil<ushort>(v.v); }
}
@@ -309,36 +259,30 @@ void savec(cube *c, const ivec &o, int size, stream *f, bool nolms)
}
}
-struct surfacecompat
-{
+struct surfacecompat {
uchar texcoords[8];
uchar w, h;
ushort x, y;
uchar lmid, layer;
};
-struct normalscompat
-{
+struct normalscompat {
bvec normals[4];
};
-struct mergecompat
-{
+struct mergecompat {
ushort u1, u2, v1, v2;
};
cube *loadchildren(stream *f, const ivec &co, int size, bool &failed);
-void loadc(stream *f, cube &c, const ivec &co, int size, bool &failed)
-{
+void loadc(stream *f, cube &c, const ivec &co, int size, bool &failed) {
bool haschildren = false;
int octsav = f->getchar();
- switch(octsav&0x7)
- {
+ switch(octsav&0x7) {
case OCTSAV_CHILDREN:
c.children = loadchildren(f, co, size>>1, failed);
return;
-
case OCTSAV_LODCUBE: haschildren = true; break;
case OCTSAV_EMPTY: emptyfaces(c); break;
case OCTSAV_SOLID: solidfaces(c); break;
@@ -346,12 +290,10 @@ void loadc(stream *f, cube &c, const ivec &co, int size, bool &failed)
default: failed = true; return;
}
loopi(6) c.texture[i] = mapversion<14 ? f->getchar() : f->getlil<ushort>();
-
- {
+ {
if(octsav&0x40) c.material = f->getlil<ushort>();
if(octsav&0x80) c.merged = f->getchar();
- if(octsav&0x20)
- {
+ if(octsav&0x20) {
int surfmask, totalverts;
surfmask = f->getchar();
totalverts = max(f->getchar(), 0);
@@ -359,8 +301,7 @@ void loadc(stream *f, cube &c, const ivec &co, int size, bool &failed)
memset(c.ext->surfaces, 0, sizeof(c.ext->surfaces));
memset(c.ext->verts(), 0, totalverts*sizeof(vertinfo));
int offset = 0;
- loopi(6) if(surfmask&(1<<i))
- {
+ loopi(6) if(surfmask&(1<<i)) {
surfaceinfo &surf = c.ext->surfaces[i];
f->read(&surf, sizeof(surfaceinfo));
int vertmask = surf.verts, numverts = surf.totalverts();
@@ -372,25 +313,21 @@ void loadc(stream *f, cube &c, const ivec &co, int size, bool &failed)
int layerverts = surf.numverts&MAXFACEVERTS, dim = dimension(i), vc = C[dim], vr = R[dim], bias = 0;
genfaceverts(c, i, v);
bool hasxyz = (vertmask&0x04)!=0, hasuv = (vertmask&0x40)!=0, hasnorm = (vertmask&0x80)!=0;
- if(hasxyz)
- {
+ if(hasxyz) {
ivec e1, e2, e3;
n.cross((e1 = v[1]).sub(v[0]), (e2 = v[2]).sub(v[0]));
if(n.iszero()) n.cross(e2, (e3 = v[3]).sub(v[0]));
bias = -n.dot(ivec(v[0]).mul(size).add(vo));
}
- else
- {
+ else {
int vis = layerverts < 4 ? (vertmask&0x02 ? 2 : 1) : 3, order = vertmask&0x01 ? 1 : 0, k = 0;
verts[k++].setxyz(v[order].mul(size).add(vo));
if(vis&1) verts[k++].setxyz(v[order+1].mul(size).add(vo));
verts[k++].setxyz(v[order+2].mul(size).add(vo));
if(vis&2) verts[k++].setxyz(v[(order+3)&3].mul(size).add(vo));
}
- if(layerverts == 4)
- {
- if(hasxyz && vertmask&0x01)
- {
+ if(layerverts == 4) {
+ if(hasxyz && vertmask&0x01) {
ushort c1 = f->getlil<ushort>(), r1 = f->getlil<ushort>(), c2 = f->getlil<ushort>(), r2 = f->getlil<ushort>();
ivec xyz;
xyz[vc] = c1; xyz[vr] = r1; xyz[dim] = n[dim] ? -(bias + n[vc]*xyz[vc] + n[vr]*xyz[vr])/n[dim] : vo[dim];
@@ -403,16 +340,14 @@ void loadc(stream *f, cube &c, const ivec &co, int size, bool &failed)
verts[3].setxyz(xyz);
hasxyz = false;
}
- if(hasuv && vertmask&0x02)
- {
+ if(hasuv && vertmask&0x02) {
int uvorder = (vertmask&0x30)>>4;
vertinfo &v0 = verts[uvorder], &v1 = verts[(uvorder+1)&3], &v2 = verts[(uvorder+2)&3], &v3 = verts[(uvorder+3)&3];
v0.u = f->getlil<ushort>(); v0.v = f->getlil<ushort>();
v2.u = f->getlil<ushort>(); v2.v = f->getlil<ushort>();
v1.u = v0.u; v1.v = v2.v;
v3.u = v2.u; v3.v = v0.v;
- if(surf.numverts&LAYER_DUP)
- {
+ if(surf.numverts&LAYER_DUP) {
vertinfo &b0 = verts[4+uvorder], &b1 = verts[4+((uvorder+1)&3)], &b2 = verts[4+((uvorder+2)&3)], &b3 = verts[4+((uvorder+3)&3)];
b0.u = f->getlil<ushort>(); b0.v = f->getlil<ushort>();
b2.u = f->getlil<ushort>(); b2.v = f->getlil<ushort>();
@@ -422,17 +357,14 @@ void loadc(stream *f, cube &c, const ivec &co, int size, bool &failed)
hasuv = false;
}
}
- if(hasnorm && vertmask&0x08)
- {
+ if(hasnorm && vertmask&0x08) {
ushort norm = f->getlil<ushort>();
loopk(layerverts) verts[k].norm = norm;
hasnorm = false;
}
- if(hasxyz || hasuv || hasnorm) loopk(layerverts)
- {
+ if(hasxyz || hasuv || hasnorm) loopk(layerverts) {
vertinfo &v = verts[k];
- if(hasxyz)
- {
+ if(hasxyz) {
ivec xyz;
xyz[vc] = f->getlil<ushort>(); xyz[vr] = f->getlil<ushort>();
xyz[dim] = n[dim] ? -(bias + n[vc]*xyz[vc] + n[vr]*xyz[vr])/n[dim] : vo[dim];
@@ -441,8 +373,7 @@ void loadc(stream *f, cube &c, const ivec &co, int size, bool &failed)
if(hasuv) { v.u = f->getlil<ushort>(); v.v = f->getlil<ushort>(); }
if(hasnorm) v.norm = f->getlil<ushort>();
}
- if(surf.numverts&LAYER_DUP) loopk(layerverts)
- {
+ if(surf.numverts&LAYER_DUP) loopk(layerverts) {
vertinfo &v = verts[k+layerverts], &t = verts[k];
v.setxyz(t.x, t.y, t.z);
if(hasuv) { v.u = f->getlil<ushort>(); v.v = f->getlil<ushort>(); }
@@ -451,30 +382,24 @@ void loadc(stream *f, cube &c, const ivec &co, int size, bool &failed)
}
}
}
-
c.children = (haschildren ? loadchildren(f, co, size>>1, failed) : NULL);
}
-cube *loadchildren(stream *f, const ivec &co, int size, bool &failed)
-{
+cube *loadchildren(stream *f, const ivec &co, int size, bool &failed) {
cube *c = newcubes();
- loopi(8)
- {
+ loopi(8) {
loadc(f, c[i], ivec(i, co, size), size, failed);
if(failed) break;
}
return c;
}
-void savevslot(stream *f, VSlot &vs, int prev)
-{
+void savevslot(stream *f, VSlot &vs, int prev) {
f->putlil<int>(vs.changed);
f->putlil<int>(prev);
- if(vs.changed & (1<<VSLOT_SHPARAM))
- {
+ if(vs.changed & (1<<VSLOT_SHPARAM)) {
f->putlil<ushort>(vs.params.length());
- loopv(vs.params)
- {
+ loopv(vs.params) {
SlotShaderParam &p = vs.params[i];
f->putlil<ushort>(strlen(p.name));
f->write(p.name, strlen(p.name));
@@ -483,39 +408,32 @@ void savevslot(stream *f, VSlot &vs, int prev)
}
if(vs.changed & (1<<VSLOT_SCALE)) f->putlil<float>(vs.scale);
if(vs.changed & (1<<VSLOT_ROTATION)) f->putlil<int>(vs.rotation);
- if(vs.changed & (1<<VSLOT_OFFSET))
- {
+ if(vs.changed & (1<<VSLOT_OFFSET)) {
f->putlil<int>(vs.offset.x);
f->putlil<int>(vs.offset.y);
}
- if(vs.changed & (1<<VSLOT_SCROLL))
- {
+ if(vs.changed & (1<<VSLOT_SCROLL)) {
f->putlil<float>(vs.scroll.x);
f->putlil<float>(vs.scroll.y);
}
if(vs.changed & (1<<VSLOT_LAYER)) f->putlil<int>(vs.layer);
- if(vs.changed & (1<<VSLOT_ALPHA))
- {
+ if(vs.changed & (1<<VSLOT_ALPHA)) {
f->putlil<float>(vs.alphafront);
f->putlil<float>(vs.alphaback);
}
- if(vs.changed & (1<<VSLOT_COLOR))
- {
+ if(vs.changed & (1<<VSLOT_COLOR)) {
loopk(3) f->putlil<float>(vs.colorscale[k]);
}
}
-void savevslots(stream *f, int numvslots)
-{
+void savevslots(stream *f, int numvslots) {
if(vslots.empty()) return;
int *prev = new int[numvslots];
for(int i=0;i<numvslots;++i)prev[i]=-1;
- loopi(numvslots)
- {
+ loopi(numvslots) {
VSlot *vs = vslots[i];
if(vs->changed) continue;
- for(;;)
- {
+ for(;;) {
VSlot *cur = vs;
do vs = vs->next; while(vs && vs->index >= numvslots);
if(!vs) break;
@@ -523,8 +441,7 @@ void savevslots(stream *f, int numvslots)
}
}
int lastroot = 0;
- loopi(numvslots)
- {
+ loopi(numvslots) {
VSlot &vs = *vslots[i];
if(!vs.changed) continue;
if(lastroot < i) f->putlil<int>(-(i - lastroot));
@@ -535,15 +452,12 @@ void savevslots(stream *f, int numvslots)
delete[] prev;
}
-void loadvslot(stream *f, VSlot &vs, int changed)
-{
+void loadvslot(stream *f, VSlot &vs, int changed) {
vs.changed = changed;
- if(vs.changed & (1<<VSLOT_SHPARAM))
- {
+ if(vs.changed & (1<<VSLOT_SHPARAM)) {
int numparams = f->getlil<ushort>();
string name;
- loopi(numparams)
- {
+ loopi(numparams) {
SlotShaderParam &p = vs.params.add();
int nlen = f->getlil<ushort>();
f->read(name, min(nlen, MAXSTRLEN-1));
@@ -556,43 +470,35 @@ void loadvslot(stream *f, VSlot &vs, int changed)
}
if(vs.changed & (1<<VSLOT_SCALE)) vs.scale = f->getlil<float>();
if(vs.changed & (1<<VSLOT_ROTATION)) vs.rotation = clamp(f->getlil<int>(), 0, 7);
- if(vs.changed & (1<<VSLOT_OFFSET))
- {
+ if(vs.changed & (1<<VSLOT_OFFSET)) {
vs.offset.x = f->getlil<int>();
vs.offset.y = f->getlil<int>();
}
- if(vs.changed & (1<<VSLOT_SCROLL))
- {
+ if(vs.changed & (1<<VSLOT_SCROLL)) {
vs.scroll.x = f->getlil<float>();
vs.scroll.y = f->getlil<float>();
}
if(vs.changed & (1<<VSLOT_LAYER)) vs.layer = f->getlil<int>();
- if(vs.changed & (1<<VSLOT_ALPHA))
- {
+ if(vs.changed & (1<<VSLOT_ALPHA)) {
vs.alphafront = f->getlil<float>();
vs.alphaback = f->getlil<float>();
}
- if(vs.changed & (1<<VSLOT_COLOR))
- {
+ if(vs.changed & (1<<VSLOT_COLOR)) {
loopk(3) vs.colorscale[k] = f->getlil<float>();
}
}
-void loadvslots(stream *f, int numvslots)
-{
+void loadvslots(stream *f, int numvslots) {
int *prev = new (false) int[numvslots];
if(!prev) return;
for(int i=0;i<numvslots;++i)prev[i]=-1;
- while(numvslots > 0)
- {
+ while(numvslots > 0) {
int changed = f->getlil<int>();
- if(changed < 0)
- {
+ if(changed < 0) {
loopi(-changed) vslots.add(new VSlot(NULL, vslots.length()));
numvslots += changed;
}
- else
- {
+ else {
prev[vslots.length()] = f->getlil<int>();
loadvslot(f, *vslots.add(new VSlot(NULL, vslots.length())), changed);
numvslots--;
@@ -602,24 +508,19 @@ void loadvslots(stream *f, int numvslots)
delete[] prev;
}
-bool save_world(const char *mname, bool nolms)
-{
+bool save_world(const char *mname, bool nolms) {
if(!*mname) mname = game::getclientmap();
setmapfilenames(mname);
if(savebak) backup(ogzname, bakname);
stream *f = opengzfile(ogzname, "wb");
if(!f) { conoutf(CON_WARN, "could not write map to %s", ogzname); return false; }
-
int numvslots = vslots.length();
- if(!nolms && !multiplayer(false))
- {
+ if(!nolms && !multiplayer(false)) {
numvslots = compactvslots();
allchanged();
}
-
savemapprogress = 0;
renderprogress(0, "saving map...");
-
octaheader hdr;
memcpy(hdr.magic, "OCTA", 4);
hdr.version = MAPVERSION;
@@ -632,36 +533,29 @@ bool save_world(const char *mname, bool nolms)
hdr.lightmaps = nolms ? 0 : lightmaps.length();
hdr.numvars = 0;
hdr.numvslots = numvslots;
- enumerate(idents, ident, id,
- {
+ enumerate(idents, ident, id, {
if((id.type == ID_VAR || id.type == ID_FVAR || id.type == ID_SVAR) && id.flags&IDF_OVERRIDE && !(id.flags&IDF_READONLY) && id.flags&IDF_OVERRIDDEN) hdr.numvars++;
});
lilswap(&hdr.version, 9);
f->write(&hdr, sizeof(hdr));
-
- enumerate(idents, ident, id,
- {
+ enumerate(idents, ident, id, {
if((id.type!=ID_VAR && id.type!=ID_FVAR && id.type!=ID_SVAR) || !(id.flags&IDF_OVERRIDE) || id.flags&IDF_READONLY || !(id.flags&IDF_OVERRIDDEN)) continue;
f->putchar(id.type);
f->putlil<ushort>(strlen(id.name));
f->write(id.name, strlen(id.name));
- switch(id.type)
- {
+ switch(id.type) {
case ID_VAR:
f->putlil<int>(*id.storage.i);
break;
-
case ID_FVAR:
f->putlil<float>(*id.storage.f);
break;
-
case ID_SVAR:
f->putlil<ushort>(strlen(*id.storage.s));
f->write(*id.storage.s, strlen(*id.storage.s));
break;
}
});
-
f->putchar((int)strlen(game::gameident()));
f->write(game::gameident(), (int)strlen(game::gameident())+1);
f->putlil<ushort>(entities::extraentinfosize());
@@ -669,14 +563,11 @@ bool save_world(const char *mname, bool nolms)
game::writegamedata(extras);
f->putlil<ushort>(extras.length());
f->write(extras.getbuf(), extras.length());
-
f->putlil<ushort>(texmru.length());
loopv(texmru) f->putlil<ushort>(texmru[i]);
char *ebuf = new char[entities::extraentinfosize()];
- loopv(ents)
- {
- if(ents[i]->type!=ET_EMPTY || nolms)
- {
+ loopv(ents) {
+ if(ents[i]->type!=ET_EMPTY || nolms) {
entity tmp = *ents[i];
lilswap(&tmp.o.x, 3);
lilswap(&tmp.attr1, 5);
@@ -685,21 +576,15 @@ bool save_world(const char *mname, bool nolms)
}
}
delete[] ebuf;
-
savevslots(f, numvslots);
-
renderprogress(0, "saving octree...");
savec(worldroot, ivec(0, 0, 0), worldsize>>1, f, nolms);
-
- if(!nolms)
- {
+ if(!nolms) {
if(lightmaps.length()) renderprogress(0, "saving lightmaps...");
- loopv(lightmaps)
- {
+ loopv(lightmaps) {
LightMap &lm = lightmaps[i];
f->putchar(lm.type | (lm.unlitx>=0 ? 0x80 : 0));
- if(lm.unlitx>=0)
- {
+ if(lm.unlitx>=0) {
f->putlil<ushort>(ushort(lm.unlitx));
f->putlil<ushort>(ushort(lm.unlity));
}
@@ -707,7 +592,6 @@ bool save_world(const char *mname, bool nolms)
renderprogress(float(i+1)/lightmaps.length(), "saving lightmaps...");
}
}
-
delete f;
conoutf("wrote map file %s", ogzname);
return true;
@@ -718,8 +602,7 @@ static uint mapcrc = 0;
uint getmapcrc() { return mapcrc; }
void clearmapcrc() { mapcrc = 0; }
-bool load_world(const char *mname, const char *cname) // still supports all map formats that have existed since the earliest cube betas!
-{
+bool load_world(const char *mname, const char *cname) { // still supports all map formats that have existed since the earliest cube betas! {
int loadingstart = SDL_GetTicks();
setmapfilenames(mname, cname);
stream *f = opengzfile(ogzname, "rb");
@@ -729,32 +612,21 @@ bool load_world(const char *mname, const char *cname) // still supports all map
lilswap(&hdr.version, 6);
if(memcmp(hdr.magic, "OCTA", 4) || hdr.worldsize <= 0|| hdr.numents < 0) { conoutf(CON_ERROR, "map %s has malformatted header", ogzname); delete f; return false; }
if(hdr.version>MAPVERSION) { conoutf(CON_ERROR, "map %s requires a newer version of Cube 2: Sauerbraten", ogzname); delete f; return false; }
-
resetmap();
-
Texture *mapshot = textureload(picname, 3, true, false);
renderbackground("loading...", mapshot, mname, game::getmapinfo());
-
game::loadingmap(cname ? cname : mname);
-
setvar("mapversion", hdr.version, true, false);
-
lilswap(&hdr.numvslots, 1);
-
renderprogress(0, "clearing world...");
-
freeocta(worldroot);
worldroot = NULL;
-
int worldscale = 0;
while(1<<worldscale < hdr.worldsize) worldscale++;
setvar("mapsize", 1<<worldscale, true, false);
setvar("mapscale", worldscale, true, false);
-
renderprogress(0, "loading vars...");
-
- loopi(hdr.numvars)
- {
+ loopi(hdr.numvars) {
int type = f->getchar(), ilen = f->getlil<ushort>();
string name;
f->read(name, min(ilen, MAXSTRLEN-1));
@@ -762,24 +634,18 @@ bool load_world(const char *mname, const char *cname) // still supports all map
if(ilen >= MAXSTRLEN) f->seek(ilen - (MAXSTRLEN-1), SEEK_CUR);
ident *id = getident(name);
bool exists = id && id->type == type && id->flags&IDF_OVERRIDE;
- switch(type)
- {
- case ID_VAR:
- {
+ switch(type) {
+ case ID_VAR: {
int val = f->getlil<int>();
if(exists && id->minval <= id->maxval) setvar(name, val);
break;
}
-
- case ID_FVAR:
- {
+ case ID_FVAR: {
float val = f->getlil<float>();
if(exists && id->minvalf <= id->maxvalf) setfvar(name, val);
break;
}
-
- case ID_SVAR:
- {
+ case ID_SVAR: {
int slen = f->getlil<ushort>();
string val;
f->read(val, min(slen, MAXSTRLEN-1));
@@ -790,73 +656,54 @@ bool load_world(const char *mname, const char *cname) // still supports all map
}
}
}
-
string gametype;
copystring(gametype, "fps");
- int eif = 0;
int len = f->getchar();
f->read(gametype, len+1);
- eif = f->getlil<ushort>();
int extrasize = f->getlil<ushort>();
vector<char> extras;
f->read(extras.pad(extrasize), extrasize);
game::readgamedata(extras);
-
texmru.shrink(0);
ushort nummru = f->getlil<ushort>();
loopi(nummru) texmru.add(f->getlil<ushort>());
-
renderprogress(0, "loading entities...");
-
vector<extentity *> &ents = entities::getents();
int einfosize = entities::extraentinfosize();
char *ebuf = einfosize > 0 ? new char[einfosize] : NULL;
- loopi(min(hdr.numents, MAXENTS))
- {
+ loopi(min(hdr.numents, MAXENTS)) {
extentity &e = *entities::newentity();
ents.add(&e);
f->read(&e, sizeof(entity));
lilswap(&e.o.x, 3);
lilswap(&e.attr1, 5);
if(einfosize > 0) f->read(ebuf, einfosize);
- if(!insideworld(e.o))
- {
- if(e.type != ET_LIGHT && e.type != ET_SPOTLIGHT)
- {
+ if(!insideworld(e.o)) {
+ if(e.type != ET_LIGHT && e.type != ET_SPOTLIGHT) {
conoutf(CON_WARN, "warning: ent outside of world: enttype[%s] index %d (%f, %f, %f)", entities::entname(e.type), i, e.o.x, e.o.y, e.o.z);
}
}
}
if(ebuf) delete[] ebuf;
-
- if(hdr.numents > MAXENTS)
- {
+ if(hdr.numents > MAXENTS) {
conoutf(CON_WARN, "warning: map has %d entities", hdr.numents);
f->seek((hdr.numents-MAXENTS)*(sizeof(entity) + einfosize), SEEK_CUR);
}
-
renderprogress(0, "loading slots...");
loadvslots(f, hdr.numvslots);
-
renderprogress(0, "loading octree...");
bool failed = false;
worldroot = loadchildren(f, ivec(0, 0, 0), hdr.worldsize>>1, failed);
if(failed) conoutf(CON_ERROR, "garbage in map");
-
renderprogress(0, "validating...");
validatec(worldroot, hdr.worldsize>>1);
-
- if(!failed)
- {
- loopi(hdr.lightmaps)
- {
+ if(!failed) {
+ loopi(hdr.lightmaps) {
renderprogress(i/(float)hdr.lightmaps, "loading lightmaps...");
- LightMap &lm = lightmaps.add();
- {
+ LightMap &lm = lightmaps.add(); {
int type = f->getchar();
lm.type = type&0x7F;
- if(type&0x80)
- {
+ if(type&0x80) {
lm.unlitx = f->getlil<ushort>();
lm.unlity = f->getlil<ushort>();
}
@@ -867,37 +714,25 @@ bool load_world(const char *mname, const char *cname) // still supports all map
lm.finalize();
}
}
-
mapcrc = f->getcrc();
delete f;
-
conoutf("read map %s (%.1f seconds)", ogzname, (SDL_GetTicks()-loadingstart)/1000.0f);
-
clearmainmenu();
-
identflags |= IDF_OVERRIDDEN;
execfile("data/default_map.cfg", false);
execfile(cfgname, false);
identflags &= ~IDF_OVERRIDDEN;
-
preloadusedmapmodels(true);
-
game::preload();
flushpreloadedmodels();
-
preloadmapsounds();
-
entitiesinoctanodes();
attachentities();
initlights();
allchanged(true);
-
renderbackground("loading...", mapshot, mname, game::getmapinfo());
-
if(maptitle[0] && strcmp(maptitle, "Untitled Map by Unknown")) conoutf(CON_ECHO, "%s", maptitle);
-
startmap(cname ? cname : mname);
-
return true;
}