Index: src/clientextras.mm ================================================================== --- src/clientextras.mm +++ src/clientextras.mm @@ -185,13 +185,13 @@ return; ENetPacket *packet = enet_packet_create( NULL, MAXTRANS + mapdata.count, ENET_PACKET_FLAG_RELIABLE); uchar *start = packet->data; uchar *p = start + 2; - putint(p, SV_SENDMAP); - sendstring(mapname, p); - putint(p, mapdata.count); + putint(&p, SV_SENDMAP); + sendstring(mapname, &p); + putint(&p, mapdata.count); if (65535 - (p - start) < mapdata.count) { conoutf(@"map %@ is too large to send", mapname); enet_packet_destroy(packet); return; } @@ -213,14 +213,14 @@ { ENetPacket *packet = enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE); uchar *start = packet->data; uchar *p = start + 2; - putint(p, SV_RECVMAP); + putint(&p, SV_RECVMAP); *(ushort *)start = ENET_HOST_TO_NET_16(p - start); enet_packet_resize(packet, p - start); sendpackettoserv(packet); conoutf(@"requesting map from server..."); } COMMAND(sendmap, ARG_1STR) COMMAND(getmap, ARG_NONE) Index: src/clientgame.mm ================================================================== --- src/clientgame.mm +++ src/clientgame.mm @@ -259,14 +259,15 @@ arenarespawn(); moveprojectiles((float)curtime); demoplaybackstep(); if (!demoplayback) { if (getclientnum() >= 0) - shoot(player1, worldpos); // only shoot when - // connected to server - gets2c(); // do this first, so we have most accurate - // information when our player moves + // only shoot when connected to server + shoot(player1, &worldpos); + // do this first, so we have most accurate information + // when our player moves + gets2c(); } otherplayers(); if (!demoplayback) { monsterthink(); if (player1.state == CS_DEAD) { Index: src/clients.mm ================================================================== --- src/clients.mm +++ src/clients.mm @@ -291,71 +291,71 @@ // suggest server to change map if (toservermap.length > 0) { // do this exclusively as map change may invalidate rest of // update packet->flags = ENET_PACKET_FLAG_RELIABLE; - putint(p, SV_MAPCHANGE); - sendstring(toservermap, p); + putint(&p, SV_MAPCHANGE); + sendstring(toservermap, &p); toservermap = @""; - putint(p, nextmode); + putint(&p, nextmode); } else { - putint(p, SV_POS); - putint(p, clientnum); + putint(&p, SV_POS); + putint(&p, clientnum); // quantize coordinates to 1/16th of a cube, between 1 and 3 // bytes - putint(p, (int)(d.o.x * DMF)); - putint(p, (int)(d.o.y * DMF)); - putint(p, (int)(d.o.z * DMF)); - putint(p, (int)(d.yaw * DAF)); - putint(p, (int)(d.pitch * DAF)); - putint(p, (int)(d.roll * DAF)); + putint(&p, (int)(d.o.x * DMF)); + putint(&p, (int)(d.o.y * DMF)); + putint(&p, (int)(d.o.z * DMF)); + putint(&p, (int)(d.yaw * DAF)); + putint(&p, (int)(d.pitch * DAF)); + putint(&p, (int)(d.roll * DAF)); // quantize to 1/100, almost always 1 byte - putint(p, (int)(d.vel.x * DVF)); - putint(p, (int)(d.vel.y * DVF)); - putint(p, (int)(d.vel.z * DVF)); + putint(&p, (int)(d.vel.x * DVF)); + putint(&p, (int)(d.vel.y * DVF)); + putint(&p, (int)(d.vel.z * DVF)); // pack rest in 1 byte: strafe:2, move:2, onfloor:1, state:3 - putint(p, + putint(&p, (d.strafe & 3) | ((d.move & 3) << 2) | (((int)d.onfloor) << 4) | ((editmode ? CS_EDITING : d.state) << 5)); if (senditemstoserver) { packet->flags = ENET_PACKET_FLAG_RELIABLE; - putint(p, SV_ITEMLIST); + putint(&p, SV_ITEMLIST); if (!m_noitems) - putitems(p); - putint(p, -1); + putitems(&p); + putint(&p, -1); senditemstoserver = false; serveriteminitdone = true; } // player chat, not flood protected for now if (ctext.length > 0) { packet->flags = ENET_PACKET_FLAG_RELIABLE; - putint(p, SV_TEXT); - sendstring(ctext, p); + putint(&p, SV_TEXT); + sendstring(ctext, &p); ctext = @""; } // tell other clients who I am if (!c2sinit) { packet->flags = ENET_PACKET_FLAG_RELIABLE; c2sinit = true; - putint(p, SV_INITC2S); - sendstring(player1.name, p); - sendstring(player1.team, p); - putint(p, player1.lifesequence); + putint(&p, SV_INITC2S); + sendstring(player1.name, &p); + sendstring(player1.team, &p); + putint(&p, player1.lifesequence); } for (OFData *msg in messages) { // send messages collected during the previous frames if (*(int *)[msg itemAtIndex:1]) packet->flags = ENET_PACKET_FLAG_RELIABLE; loopi(*(int *)[msg itemAtIndex:0]) - putint(p, *(int *)[msg itemAtIndex:i + 2]); + putint(&p, *(int *)[msg itemAtIndex:i + 2]); } [messages removeAllObjects]; if (lastmillis - lastping > 250) { - putint(p, SV_PING); - putint(p, lastmillis); + putint(&p, SV_PING); + putint(&p, lastmillis); lastping = lastmillis; } } *(ushort *)start = ENET_HOST_TO_NET_16(p - start); enet_packet_resize(packet, p - start); Index: src/clients2c.mm ================================================================== --- src/clients2c.mm +++ src/clients2c.mm @@ -75,25 +75,25 @@ int cn = -1, type; DynamicEntity *d = nil; bool mapchanged = false; while (p < end) - switch (type = getint(p)) { + switch (type = getint(&p)) { case SV_INITS2C: // welcome messsage from the server { - cn = getint(p); - int prot = getint(p); + cn = getint(&p); + int prot = getint(&p); if (prot != PROTOCOL_VERSION) { conoutf(@"you are using a different game " @"protocol (you: %d, server: %d)", PROTOCOL_VERSION, prot); disconnect(); return; } toservermap = @""; clientnum = cn; // we are now fully connected - if (!getint(p)) + if (!getint(&p)) // we are the first client on this server, set // map toservermap = getclientmap(); sgetstr(); if (text[0] && @@ -101,29 +101,34 @@ conoutf(@"you need to set the correct password " @"to join this server!"); disconnect(); return; } - if (getint(p) == 1) + if (getint(&p) == 1) conoutf(@"server is FULL, disconnecting.."); break; } case SV_POS: { // position of another client - cn = getint(p); + cn = getint(&p); d = getclient(cn); if (d == nil) return; - d.o = OFMakeVector3D( - getint(p) / DMF, getint(p) / DMF, getint(p) / DMF); - d.yaw = getint(p) / DAF; - d.pitch = getint(p) / DAF; - d.roll = getint(p) / DAF; - d.vel = OFMakeVector3D( - getint(p) / DVF, getint(p) / DVF, getint(p) / DVF); - int f = getint(p); + OFVector3D tmp; + tmp.x = getint(&p) / DMF; + tmp.y = getint(&p) / DMF; + tmp.z = getint(&p) / DMF; + d.o = tmp; + d.yaw = getint(&p) / DAF; + d.pitch = getint(&p) / DAF; + d.roll = getint(&p) / DAF; + tmp.x = getint(&p) / DVF; + tmp.y = getint(&p) / DVF; + tmp.z = getint(&p) / DVF; + d.vel = tmp; + int f = getint(&p); d.strafe = (f & 3) == 3 ? -1 : f & 3; f >>= 2; d.move = (f & 3) == 3 ? -1 : f & 3; d.onfloor = (f >> 2) & 1; int state = f >> 3; @@ -135,11 +140,11 @@ break; } case SV_SOUND: { OFVector3D loc = d.o; - playsound(getint(p), &loc); + playsound(getint(&p), &loc); break; } case SV_TEXT: sgetstr(); @@ -146,29 +151,28 @@ conoutf(@"%@:\f %s", d.name, text); break; case SV_MAPCHANGE: sgetstr(); - changemapserv(@(text), getint(p)); + changemapserv(@(text), getint(&p)); mapchanged = true; break; case SV_ITEMLIST: { int n; if (mapchanged) { senditemstoserver = false; resetspawns(); } - while ((n = getint(p)) != -1) + while ((n = getint(&p)) != -1) if (mapchanged) setspawn(n, true); break; } - - case SV_MAPRELOAD: // server requests next map - { - getint(p); + // server requests next map + case SV_MAPRELOAD: { + getint(&p); OFString *nextmapalias = [OFString stringWithFormat:@"nextmap_%@", getclientmap()]; OFString *map = getalias(nextmapalias); // look up map in the cycle changemap(map != nil ? map : getclientmap()); @@ -191,42 +195,42 @@ conoutf(@"connected: %s", text); } d.name = @(text); sgetstr(); d.team = @(text); - d.lifesequence = getint(p); + d.lifesequence = getint(&p); break; } case SV_CDIS: - cn = getint(p); + cn = getint(&p); if ((d = getclient(cn)) == nil) break; conoutf(@"player %@ disconnected", d.name.length ? d.name : @"[incompatible client]"); players[cn] = [OFNull null]; break; case SV_SHOT: { - int gun = getint(p); + int gun = getint(&p); OFVector3D s, e; - s.x = getint(p) / DMF; - s.y = getint(p) / DMF; - s.z = getint(p) / DMF; - e.x = getint(p) / DMF; - e.y = getint(p) / DMF; - e.z = getint(p) / DMF; + s.x = getint(&p) / DMF; + s.y = getint(&p) / DMF; + s.z = getint(&p) / DMF; + e.x = getint(&p) / DMF; + e.y = getint(&p) / DMF; + e.z = getint(&p) / DMF; if (gun == GUN_SG) - createrays(s, e); - shootv(gun, s, e, d); + createrays(&s, &e); + shootv(gun, &s, &e, d); break; } case SV_DAMAGE: { - int target = getint(p); - int damage = getint(p); - int ls = getint(p); + int target = getint(&p); + int damage = getint(&p); + int ls = getint(&p); if (target == clientnum) { if (ls == player1.lifesequence) selfdamage(damage, cn, d); } else { OFVector3D loc = getclient(target).o; @@ -234,11 +238,11 @@ } break; } case SV_DIED: { - int actor = getint(p); + int actor = getint(&p); if (actor == cn) { conoutf(@"%@ suicided", d.name); } else if (actor == clientnum) { int frags; if (isteam(player1.team, d.team)) { @@ -268,119 +272,118 @@ d.lifesequence++; break; } case SV_FRAGS: - [players[cn] setFrags:getint(p)]; + [players[cn] setFrags:getint(&p)]; break; case SV_ITEMPICKUP: - setspawn(getint(p), false); - getint(p); + setspawn(getint(&p), false); + getint(&p); break; case SV_ITEMSPAWN: { - uint i = getint(p); + uint i = getint(&p); setspawn(i, true); if (i >= (uint)ents.count) break; OFVector3D v = OFMakeVector3D(ents[i].x, ents[i].y, ents[i].z); playsound(S_ITEMSPAWN, &v); break; } - - case SV_ITEMACC: // server acknowledges that I picked up this - // item - realpickup(getint(p), player1); + // server acknowledges that I picked up this item + case SV_ITEMACC: + realpickup(getint(&p), player1); break; case SV_EDITH: // coop editing messages, should be extended to // include all possible editing ops case SV_EDITT: case SV_EDITS: case SV_EDITD: case SV_EDITE: { - int x = getint(p); - int y = getint(p); - int xs = getint(p); - int ys = getint(p); - int v = getint(p); + int x = getint(&p); + int y = getint(&p); + int xs = getint(&p); + int ys = getint(&p); + int v = getint(&p); block b = { x, y, xs, ys }; switch (type) { case SV_EDITH: - editheightxy(v != 0, getint(p), b); + editheightxy(v != 0, getint(&p), &b); break; case SV_EDITT: - edittexxy(v, getint(p), b); + edittexxy(v, getint(&p), &b); break; case SV_EDITS: - edittypexy(v, b); + edittypexy(v, &b); break; case SV_EDITD: - setvdeltaxy(v, b); + setvdeltaxy(v, &b); break; case SV_EDITE: - editequalisexy(v != 0, b); + editequalisexy((v != 0), &b); break; } break; } case SV_EDITENT: // coop edit of ent { - uint i = getint(p); + uint i = getint(&p); while ((uint)ents.count <= i) { Entity *e = [Entity entity]; e.type = NOTUSED; [ents addObject:e]; } int to = ents[i].type; - ents[i].type = getint(p); - ents[i].x = getint(p); - ents[i].y = getint(p); - ents[i].z = getint(p); - ents[i].attr1 = getint(p); - ents[i].attr2 = getint(p); - ents[i].attr3 = getint(p); - ents[i].attr4 = getint(p); + ents[i].type = getint(&p); + ents[i].x = getint(&p); + ents[i].y = getint(&p); + ents[i].z = getint(&p); + ents[i].attr1 = getint(&p); + ents[i].attr2 = getint(&p); + ents[i].attr3 = getint(&p); + ents[i].attr4 = getint(&p); ents[i].spawned = false; if (ents[i].type == LIGHT || to == LIGHT) calclight(); break; } case SV_PING: - getint(p); + getint(&p); break; case SV_PONG: addmsg(0, 2, SV_CLIENTPING, player1.ping = - (player1.ping * 5 + lastmillis - getint(p)) / + (player1.ping * 5 + lastmillis - getint(&p)) / 6); break; case SV_CLIENTPING: - [players[cn] setPing:getint(p)]; + [players[cn] setPing:getint(&p)]; break; case SV_GAMEMODE: - nextmode = getint(p); + nextmode = getint(&p); break; case SV_TIMEUP: - timeupdate(getint(p)); + timeupdate(getint(&p)); break; case SV_RECVMAP: { sgetstr(); conoutf(@"received map \"%s\" from server, reloading..", text); - int mapsize = getint(p); + int mapsize = getint(&p); OFString *string = @(text); writemap(string, mapsize, p); p += mapsize; changemapserv(string, gamemode); break; @@ -392,15 +395,15 @@ break; case SV_EXT: // so we can messages without breaking previous // clients/servers, if necessary { - for (int n = getint(p); n; n--) - getint(p); + for (int n = getint(&p); n; n--) + getint(&p); break; } default: neterr(@"type"); return; } } Index: src/cube.h ================================================================== --- src/cube.h +++ src/cube.h @@ -313,16 +313,16 @@ (v).x = (v).x * f + (u).x * g; \ (v).y = (v).y * f + (u).y * g; \ (v).z = (v).z * f + (u).z * g; \ } -#define sgetstr() \ - { \ - char *t = text; \ - do { \ - *t = getint(p); \ - } while (*t++); \ +#define sgetstr() \ + { \ + char *t = text; \ + do { \ + *t = getint(&p); \ + } while (*t++); \ } // used by networking #define m_noitems (gamemode >= 4) #define m_noitemsrail (gamemode <= 5) #define m_arena (gamemode >= 8) Index: src/editing.mm ================================================================== --- src/editing.mm +++ src/editing.mm @@ -27,19 +27,19 @@ } int selh = 0; bool selset = false; -#define loopselxy(b) \ - { \ - makeundo(); \ - loop(x, sel.xs) loop(y, sel.ys) \ - { \ - sqr *s = S(sel.x + x, sel.y + y); \ - b; \ - } \ - remip(sel); \ +#define loopselxy(b) \ + { \ + makeundo(); \ + loop(x, sel->xs) loop(y, sel->ys) \ + { \ + sqr *s = S(sel->x + x, sel->y + y); \ + b; \ + } \ + remip(sel); \ } int cx, cy, ch; int curedittex[] = { -1, -1, -1 }; @@ -206,11 +206,11 @@ else if (s->type == FHF || s->type == CHF) linestyle(GRIDW, 0x80, 0xFF, 0x80); else linestyle(GRIDW, 0x80, 0x80, 0x80); block b = { ix, iy, 1, 1 }; - box(b, h1, h2, h3, h4); + box(&b, h1, h2, h3, h4); linestyle(GRID8, 0x40, 0x40, 0xFF); if (!(ix & GRIDM)) line(ix, iy, h1, ix, iy + 1, h4); if (!(ix + 1 & GRIDM)) line(ix + 1, iy, h2, ix + 1, iy + 1, h3); @@ -223,21 +223,21 @@ if (!SOLID(s)) { float ih = sheight(s, s, z); linestyle(GRIDS, 0xFF, 0xFF, 0xFF); block b = { cx, cy, 1, 1 }; - box(b, ih, sheight(s, SWS(s, 1, 0, ssize), z), + box(&b, ih, sheight(s, SWS(s, 1, 0, ssize), z), sheight(s, SWS(s, 1, 1, ssize), z), sheight(s, SWS(s, 0, 1, ssize), z)); linestyle(GRIDS, 0xFF, 0x00, 0x00); dot(cx, cy, ih); ch = (int)ih; } if (selset) { linestyle(GRIDS, 0xFF, 0x40, 0x40); - box(sel, (float)selh, (float)selh, (float)selh, (float)selh); + box(&sel, (float)selh, (float)selh, (float)selh, (float)selh); } } static OFMutableData *undos; // unlimited undo VARP(undomegs, 0, 1, 10); // bounded by n megs @@ -262,11 +262,11 @@ { if (undos == nil) undos = [[OFMutableData alloc] initWithItemSize:sizeof(block *)]; - block *copy = blockcopy(sel); + block *copy = blockcopy(&sel); [undos addItem:©]; pruneundos(undomegs << 20); } void @@ -277,11 +277,11 @@ conoutf(@"nothing more to undo"); return; } block *p = *(block **)undos.lastItem; [undos removeLastItem]; - blockpaste(*p); + blockpaste(p); OFFreeMemory(p); } block *copybuf = NULL; @@ -289,11 +289,11 @@ copy() { EDITSELMP; if (copybuf) OFFreeMemory(copybuf); - copybuf = blockcopy(sel); + copybuf = blockcopy(&sel); } void paste() { @@ -310,11 +310,11 @@ return; } makeundo(); copybuf->x = sel.x; copybuf->y = sel.y; - blockpaste(*copybuf); + blockpaste(copybuf); } void tofronttex() // maintain most recently used of the texture lists when applying // texture @@ -349,11 +349,11 @@ // the core editing function. all the *xy functions perform the core operations // and are also called directly from the network, the function below it is // strictly triggered locally. They all have very similar structure. void -editheightxy(bool isfloor, int amount, block &sel) +editheightxy(bool isfloor, int amount, const block *sel) { loopselxy( if (isfloor) { s->floor += amount; if (s->floor >= s->ceil) @@ -368,17 +368,17 @@ void editheight(int flr, int amount) { EDITSEL; bool isfloor = flr == 0; - editheightxy(isfloor, amount, sel); + editheightxy(isfloor, amount, &sel); addmsg(1, 7, SV_EDITH, sel.x, sel.y, sel.xs, sel.ys, isfloor, amount); } COMMAND(editheight, ARG_2INT) void -edittexxy(int type, int t, block &sel) +edittexxy(int type, int t, const block *sel) { loopselxy(switch (type) { case 0: s->ftex = t; break; @@ -407,11 +407,11 @@ int atype = type == 3 ? 1 : type; int i = curedittex[atype]; i = i < 0 ? 0 : i + dir; curedittex[atype] = i = min(max(i, 0), 255); int t = lasttex = hdr.texlists[atype][i]; - edittexxy(type, t, sel); + edittexxy(type, t, &sel); addmsg(1, 7, SV_EDITT, sel.x, sel.y, sel.xs, sel.ys, type, t); } void replace() @@ -438,15 +438,15 @@ s->utex = lasttex; break; } } block b = { 0, 0, ssize, ssize }; - remip(b); + remip(&b); } void -edittypexy(int type, block &sel) +edittypexy(int type, const block *sel) { loopselxy(s->type = type); } void @@ -457,11 +457,11 @@ (sel.xs != sel.ys || sel.xs == 3 || sel.xs > 4 && sel.xs != 8 || sel.x & ~-sel.xs || sel.y & ~-sel.ys)) { conoutf(@"corner selection must be power of 2 aligned"); return; } - edittypexy(type, sel); + edittypexy(type, &sel); addmsg(1, 6, SV_EDITS, sel.x, sel.y, sel.xs, sel.ys, type); } void heightfield(int t) @@ -483,11 +483,11 @@ edittype(CORNER); } COMMAND(corner, ARG_NONE) void -editequalisexy(bool isfloor, block &sel) +editequalisexy(bool isfloor, const block *sel) { int low = 127, hi = -128; loopselxy({ if (s->floor < low) low = s->floor; @@ -507,27 +507,27 @@ void equalize(int flr) { bool isfloor = flr == 0; EDITSEL; - editequalisexy(isfloor, sel); + editequalisexy(isfloor, &sel); addmsg(1, 6, SV_EDITE, sel.x, sel.y, sel.xs, sel.ys, isfloor); } COMMAND(equalize, ARG_1INT) void -setvdeltaxy(int delta, block &sel) +setvdeltaxy(int delta, const block *sel) { loopselxy(s->vdelta = max(s->vdelta + delta, 0)); remipmore(sel); } void setvdelta(int delta) { EDITSEL; - setvdeltaxy(delta, sel); + setvdeltaxy(delta, &sel); addmsg(1, 6, SV_EDITD, sel.x, sel.y, sel.xs, sel.ys, delta); } const int MAXARCHVERT = 50; int archverts[MAXARCHVERT][MAXARCHVERT]; @@ -553,15 +553,18 @@ sel.ys++; if (sel.xs > MAXARCHVERT) sel.xs = MAXARCHVERT; if (sel.ys > MAXARCHVERT) sel.ys = MAXARCHVERT; - loopselxy(s->vdelta = sel.xs > sel.ys - ? (archverts[sel.xs - 1][x] + - (y == 0 || y == sel.ys - 1 ? sidedelta : 0)) - : (archverts[sel.ys - 1][y] + - (x == 0 || x == sel.xs - 1 ? sidedelta : 0))); + block *sel_ = &sel; + // Ugly hack to make the macro work. + block *sel = sel_; + loopselxy(s->vdelta = sel->xs > sel->ys + ? (archverts[sel->xs - 1][x] + + (y == 0 || y == sel->ys - 1 ? sidedelta : 0)) + : (archverts[sel->ys - 1][y] + + (x == 0 || x == sel->xs - 1 ? sidedelta : 0))); remipmore(sel); } void slope(int xd, int yd) @@ -572,10 +575,13 @@ off -= xd * sel.xs; if (yd < 0) off -= yd * sel.ys; sel.xs++; sel.ys++; + block *sel_ = &sel; + // Ugly hack to make the macro work. + block *sel = sel_; loopselxy(s->vdelta = xd * x + yd * y + off); remipmore(sel); } void @@ -585,14 +591,14 @@ sel.xs++; sel.ys++; makeundo(); sel.xs--; sel.ys--; - perlinarea(sel, scale, seed, psize); + perlinarea(&sel, scale, seed, psize); sel.xs++; sel.ys++; - remipmore(sel); + remipmore(&sel); sel.xs--; sel.ys--; } VARF( @@ -604,10 +610,13 @@ void edittag(int tag) { EDITSELMP; + block *sel_ = &sel; + // Ugly hack to make the macro work. + block *sel = sel_; loopselxy(s->tag = tag); } void newent(OFString *what, OFString *a1, OFString *a2, OFString *a3, OFString *a4) Index: src/entities.mm ================================================================== --- src/entities.mm +++ src/entities.mm @@ -334,11 +334,11 @@ conoutf(@"quad damage is over"); } } void -putitems(uchar *&p) // puts items in network stream and also spawns them locally +putitems(uchar **p) // puts items in network stream and also spawns them locally { [ents enumerateObjectsUsingBlock:^(Entity *e, size_t i, bool *stop) { if ((e.type >= I_SHELLS && e.type <= I_QUAD) || e.type == CARROT) { putint(p, i); Index: src/monster.mm ================================================================== --- src/monster.mm +++ src/monster.mm @@ -281,11 +281,12 @@ // this state is the delay between wanting to shoot and actually // firing if (m.trigger < lastmillis) { m.lastaction = 0; m.attacking = true; - shoot(m, m.attacktarget); + OFVector3D attacktarget = m.attacktarget; + shoot(m, &attacktarget); transition(m, M_ATTACKING, 0, 600, 0); } break; case M_HOME: Index: src/protos.h ================================================================== --- src/protos.h +++ src/protos.h @@ -112,12 +112,12 @@ extern void renderscores(); // world extern void setupworld(int factor); extern void empty_world(int factor, bool force); -extern void remip(block &b, int level = 0); -extern void remipmore(const block &b, int level = 0); +extern void remip(const block *b, int level = 0); +extern void remipmore(const block *b, int level = 0); extern int closestent(); extern int findentity(int type, int index = 0); extern void trigger(int tag, int type, bool savegame); extern void resettagareas(); extern void settagareas(); @@ -124,15 +124,15 @@ extern Entity *newentity( int x, int y, int z, OFString *what, int v1, int v2, int v3, int v4); // worldlight extern void calclight(); -extern void dodynlight(const OFVector3D &vold, const OFVector3D &v, int reach, +extern void dodynlight(const OFVector3D *vold, const OFVector3D *v, int reach, int strength, DynamicEntity *owner); extern void cleardlights(); -extern block *blockcopy(block &b); -extern void blockpaste(const block &b); +extern block *blockcopy(const block *b); +extern void blockpaste(const block *b); // worldrender extern void render_world(float vx, float vy, float vh, int yaw, int pitch, float widef, int w, int h); @@ -152,36 +152,36 @@ // editing extern void cursorupdate(); extern void toggleedit(); extern void editdrag(bool isdown); -extern void setvdeltaxy(int delta, block &sel); -extern void editequalisexy(bool isfloor, block &sel); -extern void edittypexy(int type, block &sel); -extern void edittexxy(int type, int t, block &sel); -extern void editheightxy(bool isfloor, int amount, block &sel); +extern void setvdeltaxy(int delta, const block *sel); +extern void editequalisexy(bool isfloor, const block *sel); +extern void edittypexy(int type, const block *sel); +extern void edittexxy(int type, int t, const block *sel); +extern void editheightxy(bool isfloor, int amount, const block *sel); extern bool noteditmode(); extern void pruneundos(int maxremain = 0); // renderextras extern void line(int x1, int y1, float z1, int x2, int y2, float z2); -extern void box(block &b, float z1, float z2, float z3, float z4); +extern void box(const block *b, float z1, float z2, float z3, float z4); extern void dot(int x, int y, float z); extern void linestyle(float width, int r, int g, int b); -extern void newsphere(const OFVector3D &o, float max, int type); +extern void newsphere(const OFVector3D *o, float max, int type); extern void renderspheres(int time); extern void gl_drawhud( int w, int h, int curfps, int nquads, int curvert, bool underwater); extern void readdepth(int w, int h); extern void blendbox(int x1, int y1, int x2, int y2, bool border); extern void damageblend(int n); // renderparticles -extern void setorient(OFVector3D &r, OFVector3D &u); -extern void particle_splash(int type, int num, int fade, const OFVector3D &p); +extern void setorient(const OFVector3D *r, const OFVector3D *u); +extern void particle_splash(int type, int num, int fade, const OFVector3D *p); extern void particle_trail( - int type, int fade, OFVector3D &from, OFVector3D &to); + int type, int fade, const OFVector3D *from, const OFVector3D *to); extern void render_particles(int time); // worldio extern void save_world(OFString *fname); extern void load_world(OFString *mname); @@ -190,11 +190,11 @@ extern void loadgamerest(); extern void incomingdemodata(uchar *buf, int len, bool extras = false); extern void demoplaybackstep(); extern void stop(); extern void stopifrecording(); -extern void demodamage(int damage, const OFVector3D &o); +extern void demodamage(int damage, const OFVector3D *o); extern void demoblend(int damage); // physics extern void moveplayer(DynamicEntity *pl, int moveres, bool local); extern bool collide(DynamicEntity *d, bool spawn, float drop, float rise); @@ -221,13 +221,13 @@ extern void cleanupserver(); extern void localconnect(); extern void localdisconnect(); extern void localclienttoserver(struct _ENetPacket *); extern void serverslice(int seconds, unsigned int timeout); -extern void putint(uchar *&p, int n); -extern int getint(uchar *&p); -extern void sendstring(OFString *t, uchar *&p); +extern void putint(uchar **p, int n); +extern int getint(uchar **p); +extern void sendstring(OFString *t, uchar **p); extern void startintermission(); extern void restoreserverstate(OFArray *ents); extern uchar *retrieveservers(uchar *buf, int buflen); extern char msgsizelookup(int msg); extern void serverms(int mode, int numplayers, int minremain, @@ -236,14 +236,14 @@ extern void sendmaps(int n, OFString *mapname, int mapsize, uchar *mapdata); extern ENetPacket *recvmap(int n); // weapon extern void selectgun(int a = -1, int b = -1, int c = -1); -extern void shoot(DynamicEntity *d, const OFVector3D &to); -extern void shootv(int gun, OFVector3D &from, OFVector3D &to, +extern void shoot(DynamicEntity *d, const OFVector3D *to); +extern void shootv(int gun, const OFVector3D *from, const OFVector3D *to, DynamicEntity *d = 0, bool local = false); -extern void createrays(OFVector3D &from, OFVector3D &to); +extern void createrays(const OFVector3D *from, const OFVector3D *to); extern void moveprojectiles(float time); extern void projreset(); extern OFString *playerincrosshair(); extern int reloadtime(int gun); @@ -257,11 +257,11 @@ extern void endsp(bool allkilled); // entities extern void initEntities(); extern void renderents(); -extern void putitems(uchar *&p); +extern void putitems(uchar **p); extern void checkquad(int time); extern void checkitems(); extern void realpickup(int n, DynamicEntity *d); extern void renderentities(); extern void resetspawns(); @@ -268,6 +268,6 @@ extern void setspawn(uint i, bool on); extern void teleport(int n, DynamicEntity *d); extern void baseammo(int gun); // rndmap -extern void perlinarea(block &b, int scale, int seed, int psize); +extern void perlinarea(const block *b, int scale, int seed, int psize); Index: src/renderextras.mm ================================================================== --- src/renderextras.mm +++ src/renderextras.mm @@ -23,17 +23,17 @@ glLineWidth(width); glColor3ub(r, g, b); } void -box(block &b, float z1, float z2, float z3, float z4) +box(const block *b, float z1, float z2, float z3, float z4) { glBegin(GL_POLYGON); - glVertex3f((float)b.x, z1, (float)b.y); - glVertex3f((float)b.x + b.xs, z2, (float)b.y); - glVertex3f((float)b.x + b.xs, z3, (float)b.y + b.ys); - glVertex3f((float)b.x, z4, (float)b.y + b.ys); + glVertex3f((float)b->x, z1, (float)b->y); + glVertex3f((float)b->x + b->xs, z2, (float)b->y); + glVertex3f((float)b->x + b->xs, z3, (float)b->y + b->ys); + glVertex3f((float)b->x, z4, (float)b->y + b->ys); glEnd(); xtraverts += 4; } void @@ -90,11 +90,11 @@ }; sphere spheres[MAXSPHERES], *slist = NULL, *sempty = NULL; bool sinit = false; void -newsphere(const OFVector3D &o, float max, int type) +newsphere(const OFVector3D *o, float max, int type) { if (!sinit) { loopi(MAXSPHERES) { spheres[i].next = sempty; @@ -103,11 +103,11 @@ sinit = true; } if (sempty) { sphere *p = sempty; sempty = p->next; - p->o = o; + p->o = *o; p->max = max; p->size = 1; p->type = type; p->next = slist; slist = p; @@ -188,11 +188,11 @@ for (Entity *e in ents) { if (e.type == NOTUSED) continue; OFVector3D v = OFMakeVector3D(e.x, e.y, e.z); - particle_splash(2, 2, 40, v); + particle_splash(2, 2, 40, &v); } int e = closestent(); if (e >= 0) { Entity *c = ents[e]; @@ -274,11 +274,11 @@ worldpos.x = (float)worldx; worldpos.y = (float)worldy; worldpos.z = (float)worldz; OFVector3D r = OFMakeVector3D(mm[0], mm[4], mm[8]); OFVector3D u = OFMakeVector3D(mm[1], mm[5], mm[9]); - setorient(r, u); + setorient(&r, &u); } void drawicon(float tx, float ty, int x, int y) { Index: src/renderparticles.mm ================================================================== --- src/renderparticles.mm +++ src/renderparticles.mm @@ -16,11 +16,11 @@ bool parinit = false; VARP(maxparticles, 100, 2000, MAXPARTICLES - 500); static void -newparticle(const OFVector3D &o, const OFVector3D &d, int fade, int type) +newparticle(const OFVector3D *o, const OFVector3D *d, int fade, int type) { if (!parinit) { loopi(MAXPARTICLES) { particles[i].next = parempty; @@ -29,12 +29,12 @@ parinit = true; } if (parempty) { particle *p = parempty; parempty = p->next; - p->o = o; - p->d = d; + p->o = *o; + p->d = *d; p->fade = fade; p->type = type; p->millis = lastmillis; p->next = parlist; parlist = p; @@ -45,22 +45,23 @@ VARP(particlesize, 20, 100, 500); OFVector3D right, up; void -setorient(OFVector3D &r, OFVector3D &u) +setorient(const OFVector3D *r, const OFVector3D *u) { - right = r; - up = u; + right = *r; + up = *u; } void render_particles(int time) { if (demoplayback && demotracking) { + OFVector3D o = player1.o; OFVector3D nom = OFMakeVector3D(0, 0, 0); - newparticle(player1.o, nom, 100000000, 8); + newparticle(&o, &nom, 100000000, 8); } glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA); @@ -133,11 +134,11 @@ glDisable(GL_BLEND); glDepthMask(GL_TRUE); } void -particle_splash(int type, int num, int fade, const OFVector3D &p) +particle_splash(int type, int num, int fade, const OFVector3D *p) { loopi(num) { const int radius = type == 5 ? 50 : 150; int x, y, z; @@ -144,23 +145,24 @@ do { x = rnd(radius * 2) - radius; y = rnd(radius * 2) - radius; z = rnd(radius * 2) - radius; } while (x * x + y * y + z * z > radius * radius); - newparticle(p, OFMakeVector3D(x, y, z), rnd(fade * 3), type); + OFVector3D d = OFMakeVector3D(x, y, z); + newparticle(p, &d, rnd(fade * 3), type); } } void -particle_trail(int type, int fade, OFVector3D &s, OFVector3D &e) +particle_trail(int type, int fade, const OFVector3D *s, const OFVector3D *e) { - vdist(d, v, s, e); + vdist(d, v, *s, *e); vdiv(v, d * 2 + 0.1f); - OFVector3D p = s; + OFVector3D p = *s; loopi((int)d * 2) { vadd(p, v); OFVector3D d = OFMakeVector3D(rnd(11) - 5, rnd(11) - 5, rnd(11) - 5); - newparticle(p, d, rnd(fade) + fade, type); + newparticle(&p, &d, rnd(fade) + fade, type); } } Index: src/rndmap.mm ================================================================== --- src/rndmap.mm +++ src/rndmap.mm @@ -65,20 +65,20 @@ } return total; } void -perlinarea(block &b, int scale, int seed, int psize) +perlinarea(const block *b, int scale, int seed, int psize) { srand(seed); seed = rnd(10000); if (!scale) scale = 10; - for (int x = b.x; x <= b.x + b.xs; x++) { - for (int y = b.y; y <= b.y + b.ys; y++) { + for (int x = b->x; x <= b->x + b->xs; x++) { + for (int y = b->y; y <= b->y + b->ys; y++) { sqr *s = S(x, y); - if (!SOLID(s) && x != b.x + b.xs && y != b.y + b.ys) + if (!SOLID(s) && x != b->x + b->xs && y != b->y + b->ys) s->type = FHF; s->vdelta = (int)(perlinnoise_2D(x / ((float)scale) + seed, y / ((float)scale) + seed, 1000, 0.01f) * 50 + Index: src/savegamedemo.mm ================================================================== --- src/savegamedemo.mm +++ src/savegamedemo.mm @@ -289,14 +289,14 @@ ddamage = bdamage = 0; } COMMAND(record, ARG_1STR) void -demodamage(int damage, const OFVector3D &o) +demodamage(int damage, const OFVector3D *o) { ddamage = damage; - dorig = o; + dorig = *o; } void demoblend(int damage) { @@ -452,11 +452,11 @@ target.lastmove = playbacktime; if ((bdamage = gzgeti())) damageblend(bdamage); if ((ddamage = gzgeti())) { gzgetv(dorig); - particle_splash(3, ddamage, 1000, dorig); + particle_splash(3, ddamage, 1000, &dorig); } // FIXME: set more client state here } // insert latest copy of player into history Index: src/server.mm ================================================================== --- src/server.mm +++ src/server.mm @@ -68,12 +68,12 @@ { ENetPacket *packet = enet_packet_create(NULL, 32, rel ? ENET_PACKET_FLAG_RELIABLE : 0); uchar *start = packet->data; uchar *p = start + 2; - putint(p, a); - putint(p, b); + putint(&p, a); + putint(&p, b); *(ushort *)start = ENET_HOST_TO_NET_16(p - start); enet_packet_resize(packet, p - start); if (cn < 0) process(packet, -1); else @@ -87,12 +87,12 @@ { ENetPacket *packet = enet_packet_create( NULL, _MAXDEFSTR + 10, ENET_PACKET_FLAG_RELIABLE); uchar *start = packet->data; uchar *p = start + 2; - putint(p, SV_SERVMSG); - sendstring(msg, p); + putint(&p, SV_SERVMSG); + sendstring(msg, &p); *(ushort *)start = ENET_HOST_TO_NET_16(p - start); enet_packet_resize(packet, p - start); multicast(packet, -1); if (packet->referenceCount == 0) enet_packet_destroy(packet); @@ -188,25 +188,25 @@ uchar *p = packet->data + 2; char text[MAXTRANS]; int cn = -1, type; while (p < end) { - switch ((type = getint(p))) { + switch ((type = getint(&p))) { case SV_TEXT: sgetstr(); break; case SV_INITC2S: sgetstr(); clients[cn].name = @(text); sgetstr(); - getint(p); + getint(&p); break; case SV_MAPCHANGE: { sgetstr(); - int reqmode = getint(p); + int reqmode = getint(&p); if (reqmode < 0) reqmode = 0; if (smapname.length > 0 && !mapreload && !vote(@(text), reqmode, sender)) return; @@ -221,11 +221,11 @@ break; } case SV_ITEMLIST: { int n; - while ((n = getint(p)) != -1) + while ((n = getint(&p)) != -1) if (notgotitems) { while (sents.count <= n) [sents addObject:[ServerEntity entity]]; sents[n].spawned = true; @@ -233,35 +233,35 @@ notgotitems = false; break; } case SV_ITEMPICKUP: { - int n = getint(p); - pickup(n, getint(p), sender); + int n = getint(&p); + pickup(n, getint(&p), sender); break; } case SV_PING: - send2(false, cn, SV_PONG, getint(p)); + send2(false, cn, SV_PONG, getint(&p)); break; case SV_POS: { - cn = getint(p); + cn = getint(&p); if (cn < 0 || cn >= clients.count || clients[cn].type == ST_EMPTY) { disconnect_client(sender, @"client num"); return; } int size = msgsizelookup(type); assert(size != -1); - loopi(size - 2) getint(p); + loopi(size - 2) getint(&p); break; } case SV_SENDMAP: { sgetstr(); - int mapsize = getint(p); + int mapsize = getint(&p); sendmaps(sender, @(text), mapsize, p); return; } case SV_RECVMAP: @@ -268,21 +268,21 @@ send(sender, recvmap(sender)); return; // allows for new features that require no server updates case SV_EXT: - for (int n = getint(p); n; n--) - getint(p); + for (int n = getint(&p); n; n--) + getint(&p); break; default: { int size = msgsizelookup(type); if (size == -1) { disconnect_client(sender, @"tag type"); return; } - loopi(size - 1) getint(p); + loopi(size - 1) getint(&p); } } } if (p > end) { @@ -298,27 +298,27 @@ { ENetPacket *packet = enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE); uchar *start = packet->data; __block uchar *p = start + 2; - putint(p, SV_INITS2C); - putint(p, n); - putint(p, PROTOCOL_VERSION); - putint(p, *smapname.UTF8String); - sendstring(serverpassword, p); - putint(p, clients.count > maxclients); + putint(&p, SV_INITS2C); + putint(&p, n); + putint(&p, PROTOCOL_VERSION); + putint(&p, *smapname.UTF8String); + sendstring(serverpassword, &p); + putint(&p, clients.count > maxclients); if (smapname.length > 0) { - putint(p, SV_MAPCHANGE); - sendstring(smapname, p); - putint(p, mode); - putint(p, SV_ITEMLIST); + putint(&p, SV_MAPCHANGE); + sendstring(smapname, &p); + putint(&p, mode); + putint(&p, SV_ITEMLIST); [sents enumerateObjectsUsingBlock:^( ServerEntity *e, size_t i, bool *stop) { if (e.spawned) - putint(p, i); + putint(&p, i); }]; - putint(p, -1); + putint(&p, -1); } *(ushort *)start = ENET_HOST_TO_NET_16(p - start); enet_packet_resize(packet, p - start); send(n, packet); } Index: src/serverbrowser.mm ================================================================== --- src/serverbrowser.mm +++ src/serverbrowser.mm @@ -136,11 +136,11 @@ for (ServerInfo *si in servers) { if (si.address.host == ENET_HOST_ANY) continue; p = ping; - putint(p, lastmillis); + putint(&p, lastmillis); buf.data = ping; buf.dataLength = p - ping; ENetAddress address = si.address; enet_socket_send(pingsock, &address, &buf, 1); } @@ -183,17 +183,17 @@ return; for (ServerInfo *si in servers) { if (addr.host == si.address.host) { p = ping; - si.ping = lastmillis - getint(p); - si.protocol = getint(p); + si.ping = lastmillis - getint(&p); + si.protocol = getint(&p); if (si.protocol != PROTOCOL_VERSION) si.ping = 9998; - si.mode = getint(p); - si.numplayers = getint(p); - si.minremain = getint(p); + si.mode = getint(&p); + si.numplayers = getint(&p); + si.minremain = getint(&p); sgetstr(); si.map = @(text); sgetstr(); si.sdesc = @(text); break; Index: src/serverms.mm ================================================================== --- src/serverms.mm +++ src/serverms.mm @@ -134,19 +134,19 @@ buf.dataLength = sizeof(pong); len = enet_socket_receive(pongsock, &addr, &buf, 1); if (len < 0) return; p = &pong[len]; - putint(p, PROTOCOL_VERSION); - putint(p, mode); - putint(p, numplayers); - putint(p, minremain); + putint(&p, PROTOCOL_VERSION); + putint(&p, mode); + putint(&p, numplayers); + putint(&p, minremain); OFString *mname = [OFString stringWithFormat:@"%@%@", (isfull ? @"[FULL] " : @""), smapname]; - sendstring(mname, p); - sendstring(serverdesc, p); + sendstring(mname, &p); + sendstring(serverdesc, &p); buf.dataLength = p - pong; enet_socket_send(pongsock, &addr, &buf, 1); } } Index: src/serverutil.mm ================================================================== --- src/serverutil.mm +++ src/serverutil.mm @@ -4,48 +4,48 @@ // all network traffic is in 32bit ints, which are then compressed using the // following simple scheme (assumes that most values are small). void -putint(uchar *&p, int n) +putint(uchar **p, int n) { if (n < 128 && n > -127) { - *p++ = n; + *(*p)++ = n; } else if (n < 0x8000 && n >= -0x8000) { - *p++ = 0x80; - *p++ = n; - *p++ = n >> 8; + *(*p)++ = 0x80; + *(*p)++ = n; + *(*p)++ = n >> 8; } else { - *p++ = 0x81; - *p++ = n; - *p++ = n >> 8; - *p++ = n >> 16; - *p++ = n >> 24; + *(*p)++ = 0x81; + *(*p)++ = n; + *(*p)++ = n >> 8; + *(*p)++ = n >> 16; + *(*p)++ = n >> 24; } } int -getint(uchar *&p) +getint(uchar **p) { - int c = *((char *)p); - p++; + int c = *((char *)*p); + (*p)++; if (c == -128) { - int n = *p++; - n |= *((char *)p) << 8; - p++; + int n = *(*p)++; + n |= *((char *)*p) << 8; + (*p)++; return n; } else if (c == -127) { - int n = *p++; - n |= *p++ << 8; - n |= *p++ << 16; - return n | (*p++ << 24); + int n = *(*p)++; + n |= *(*p)++ << 8; + n |= *(*p)++ << 16; + return n | (*(*p)++ << 24); } else return c; } void -sendstring(OFString *t_, uchar *&p) +sendstring(OFString *t_, uchar **p) { const char *t = t_.UTF8String; for (size_t i = 0; i < _MAXDEFSTR && *t != '\0'; i++) putint(p, *t++); @@ -120,13 +120,13 @@ return NULL; ENetPacket *packet = enet_packet_create( NULL, MAXTRANS + copysize, ENET_PACKET_FLAG_RELIABLE); uchar *start = packet->data; uchar *p = start + 2; - putint(p, SV_RECVMAP); - sendstring(copyname, p); - putint(p, copysize); + putint(&p, SV_RECVMAP); + sendstring(copyname, &p); + putint(&p, copysize); memcpy(p, copydata, copysize); p += copysize; *(ushort *)start = ENET_HOST_TO_NET_16(p - start); enet_packet_resize(packet, p - start); return packet; Index: src/weapon.mm ================================================================== --- src/weapon.mm +++ src/weapon.mm @@ -68,45 +68,45 @@ (a2.length > 0 ? a2.cube_intValue : -1), (a3.length > 0 ? a3.cube_intValue : -1)); } COMMAND(weapon, ARG_3STR) +// create random spread of rays for the shotgun void -createrays(OFVector3D &from, - OFVector3D &to) // create random spread of rays for the shotgun +createrays(const OFVector3D *from, const OFVector3D *to) { - vdist(dist, dvec, from, to); + vdist(dist, dvec, *from, *to); float f = dist * SGSPREAD / 1000; loopi(SGRAYS) { #define RNDD (rnd(101) - 50) * f OFVector3D r = OFMakeVector3D(RNDD, RNDD, RNDD); - sg[i] = to; + sg[i] = *to; vadd(sg[i], r); } } // if lineseg hits entity bounding box -bool -intersect(DynamicEntity *d, const OFVector3D &from, const OFVector3D &to) +static bool +intersect(DynamicEntity *d, const OFVector3D *from, const OFVector3D *to) { - OFVector3D v = to, w = d.o; + OFVector3D v = *to, w = d.o; const OFVector3D *p; - vsub(v, from); - vsub(w, from); + vsub(v, *from); + vsub(w, *from); float c1 = dotprod(w, v); if (c1 <= 0) - p = &from; + p = from; else { float c2 = dotprod(v, v); if (c2 <= c1) - p = &to; + p = to; else { float f = c1 / c2; vmul(v, f); - vadd(v, from); + vadd(v, *from); p = &v; } } return (p->x <= d.o.x + d.radius && p->x >= d.o.x - d.radius && @@ -122,11 +122,12 @@ for (id player in players) { if (player == [OFNull null]) continue; - if (intersect(player, player1.o, worldpos)) + OFVector3D o = player1.o; + if (intersect(player, &o, &worldpos)) return [player name]; } return nil; } @@ -140,12 +141,12 @@ for (size_t i = 0; i < MAXPROJ; i++) projs[i].inuse = false; } void -newprojectile(OFVector3D &from, OFVector3D &to, float speed, bool local, - DynamicEntity *owner, int gun) +newprojectile(const OFVector3D *from, const OFVector3D *to, float speed, + bool local, DynamicEntity *owner, int gun) { for (size_t i = 0; i < MAXPROJ; i++) { Projectile *p = projs[i]; if (p == nil) @@ -153,12 +154,12 @@ if (p.inuse) continue; p.inuse = true; - p.o = from; - p.to = to; + p.o = *from; + p.to = *to; p.speed = speed; p.local = local; p.owner = owner; p.gun = gun; return; @@ -166,33 +167,33 @@ } void hit(int target, int damage, DynamicEntity *d, DynamicEntity *at) { + OFVector3D o = d.o; if (d == player1) selfdamage(damage, at == player1 ? -1 : -2, at); else if (d.monsterstate) monsterpain(d, damage, at); else { addmsg(1, 4, SV_DAMAGE, target, damage, d.lifesequence); - OFVector3D loc = d.o; - playsound(S_PAIN1 + rnd(5), &loc); + playsound(S_PAIN1 + rnd(5), &o); } - particle_splash(3, damage, 1000, d.o); - demodamage(damage, d.o); + particle_splash(3, damage, 1000, &o); + demodamage(damage, &o); } const float RL_RADIUS = 5; const float RL_DAMRAD = 7; // hack static void radialeffect( - DynamicEntity *o, const OFVector3D &v, int cn, int qdam, DynamicEntity *at) + DynamicEntity *o, const OFVector3D *v, int cn, int qdam, DynamicEntity *at) { if (o.state != CS_ALIVE) return; - vdist(dist, temp, v, o.o); + vdist(dist, temp, *v, o.o); dist -= 2; // account for eye distance imprecision if (dist < RL_DAMRAD) { if (dist < 0) dist = 0; int damage = (int)(qdam * (1 - (dist / RL_DAMRAD))); @@ -201,21 +202,21 @@ vadd(o.vel, temp); } } void -splash(Projectile *p, const OFVector3D &v, const OFVector3D &vold, +splash(Projectile *p, const OFVector3D *v, const OFVector3D *vold, int notthisplayer, int notthismonster, int qdam) { particle_splash(0, 50, 300, v); p.inuse = false; if (p.gun != GUN_RL) { - playsound(S_FEXPLODE, &v); + playsound(S_FEXPLODE, v); // no push? } else { - playsound(S_RLHIT, &v); + playsound(S_RLHIT, v); newsphere(v, RL_RADIUS, 0); dodynlight(vold, v, 0, 0, p.owner); if (!p.local) return; @@ -240,18 +241,19 @@ }]; } } inline void -projdamage( - DynamicEntity *o, Projectile *p, OFVector3D &v, int i, int im, int qdam) +projdamage(DynamicEntity *o, Projectile *p, const OFVector3D *v, int i, int im, + int qdam) { if (o.state != CS_ALIVE) return; - if (intersect(o, p.o, v)) { - splash(p, v, p.o, i, im, qdam); + OFVector3D po = p.o; + if (intersect(o, &po, v)) { + splash(p, v, &po, i, im, qdam); hit(i, qdam, o, p.owner); } } void @@ -273,51 +275,54 @@ vmul(v, time / dtime); vadd(v, p.o); if (p.local) { for (id player in players) if (player != [OFNull null]) - projdamage(player, p, v, i, -1, qdam); + projdamage(player, p, &v, i, -1, qdam); if (p.owner != player1) - projdamage(player1, p, v, -1, -1, qdam); + projdamage(player1, p, &v, -1, -1, qdam); for (DynamicEntity *monster in getmonsters()) if (!vreject(monster.o, v, 10.0f) && monster != p.owner) - projdamage(monster, p, v, -1, i, qdam); + projdamage(monster, p, &v, -1, i, qdam); } if (p.inuse) { + OFVector3D po = p.o; + if (time == dtime) - splash(p, v, p.o, -1, -1, qdam); + splash(p, &v, &po, -1, -1, qdam); else { if (p.gun == GUN_RL) { - dodynlight(p.o, v, 0, 255, p.owner); - particle_splash(5, 2, 200, v); + dodynlight(&po, &v, 0, 255, p.owner); + particle_splash(5, 2, 200, &v); } else { - particle_splash(1, 1, 200, v); + particle_splash(1, 1, 200, &v); particle_splash( - guns[p.gun].part, 1, 1, v); + guns[p.gun].part, 1, 1, &v); } } } p.o = v; } } // create visual effect from a shot void -shootv(int gun, OFVector3D &from, OFVector3D &to, DynamicEntity *d, bool local) +shootv(int gun, const OFVector3D *from, const OFVector3D *to, DynamicEntity *d, + bool local) { OFVector3D loc = d.o; playsound(guns[gun].sound, d == player1 ? NULL : &loc); int pspeed = 25; switch (gun) { case GUN_FIST: break; case GUN_SG: { - loopi(SGRAYS) particle_splash(0, 5, 200, sg[i]); + loopi(SGRAYS) particle_splash(0, 5, 200, &sg[i]); break; } case GUN_CG: particle_splash(0, 100, 250, to); @@ -341,20 +346,20 @@ } } void hitpush(int target, int damage, DynamicEntity *d, DynamicEntity *at, - const OFVector3D &from, const OFVector3D &to) + const OFVector3D *from, const OFVector3D *to) { hit(target, damage, d, at); - vdist(dist, v, from, to); + vdist(dist, v, *from, *to); vmul(v, damage / dist / 50); vadd(d.vel, v); } void -raydamage(DynamicEntity *o, const OFVector3D &from, const OFVector3D &to, +raydamage(DynamicEntity *o, const OFVector3D *from, const OFVector3D *to, DynamicEntity *d, int i) { if (o.state != CS_ALIVE) return; int qdam = guns[d.gunselect].damage; @@ -362,19 +367,19 @@ qdam *= 4; if (d.monsterstate) qdam /= MONSTERDAMAGEFACTOR; if (d.gunselect == GUN_SG) { int damage = 0; - loop(r, SGRAYS) if (intersect(o, from, sg[r])) damage += qdam; + loop(r, SGRAYS) if (intersect(o, from, &sg[r])) damage += qdam; if (damage) hitpush(i, damage, o, d, from, to); } else if (intersect(o, from, to)) hitpush(i, qdam, o, d, from, to); } void -shoot(DynamicEntity *d, const OFVector3D &targ) +shoot(DynamicEntity *d, const OFVector3D *targ) { int attacktime = lastmillis - d.lastaction; if (attacktime < d.gunwait) return; d.gunwait = 0; @@ -389,11 +394,11 @@ return; } if (d.gunselect) d.ammo[d.gunselect]--; OFVector3D from = d.o; - OFVector3D to = targ; + OFVector3D to = *targ; from.z -= 0.2f; // below eye vdist(dist, unitv, from, to); vdiv(unitv, dist); OFVector3D kickback = unitv; @@ -406,15 +411,15 @@ vmul(unitv, 3); // punch range to = from; vadd(to, unitv); } if (d.gunselect == GUN_SG) - createrays(from, to); + createrays(&from, &to); if (d.quadmillis && attacktime > 200) playsoundc(S_ITEMPUP); - shootv(d.gunselect, from, to, d, true); + shootv(d.gunselect, &from, &to, d, true); if (!d.monsterstate) addmsg(1, 8, SV_SHOT, d.gunselect, (int)(from.x * DMF), (int)(from.y * DMF), (int)(from.z * DMF), (int)(to.x * DMF), (int)(to.y * DMF), (int)(to.z * DMF)); d.gunwait = guns[d.gunselect].attackdelay; @@ -422,15 +427,15 @@ if (guns[d.gunselect].projspeed) return; [players enumerateObjectsUsingBlock:^(id player, size_t i, bool *stop) { if (player != [OFNull null]) - raydamage(player, from, to, d, i); + raydamage(player, &from, &to, d, i); }]; for (DynamicEntity *monster in getmonsters()) if (monster != d) - raydamage(monster, from, to, d, -2); + raydamage(monster, &from, &to, d, -2); if (d.monsterstate) - raydamage(player1, from, to, d, -1); + raydamage(player1, &from, &to, d, -1); } Index: src/world.mm ================================================================== --- src/world.mm +++ src/world.mm @@ -40,11 +40,11 @@ miny = y; } } block b = { minx, miny, maxx - minx + 1, maxy - miny + 1 }; if (maxx) - remip(b); // remip minimal area of changed geometry + remip(&b); // remip minimal area of changed geometry } void resettagareas() { @@ -88,20 +88,21 @@ // defer to 0 if mipped cube is a perfect mip, i.e. can be rendered at this mip // level indistinguishable from its constituent cubes (saves considerable // rendering time if this is possible). void -remip(block &b, int level) +remip(const block *b, int level) { if (level >= SMALLEST_FACTOR) return; + int lighterr = getvar(@"lighterror") * 3; sqr *w = wmip[level]; sqr *v = wmip[level + 1]; int ws = ssize >> level; int vs = ssize >> (level + 1); - block s = b; + block s = *b; if (s.x & 1) { s.x--; s.xs++; } if (s.y & 1) { @@ -115,19 +116,19 @@ sqr *o[4]; o[0] = SWS(w, x, y, ws); // the 4 constituent cubes o[1] = SWS(w, x + 1, y, ws); o[2] = SWS(w, x + 1, y + 1, ws); o[3] = SWS(w, x, y + 1, ws); - sqr *r = SWS(v, x / 2, y / 2, - vs); // the target cube in the higher mip level + // the target cube in the higher mip level + sqr *r = SWS(v, x / 2, y / 2, vs); *r = *o[0]; uchar nums[MAXTYPE]; loopi(MAXTYPE) nums[i] = 0; loopj(4) nums[o[j]->type]++; - r->type = - SEMISOLID; // cube contains both solid and space, - // treated specially in the renderer + // cube contains both solid and space, treated + // specially in the renderer + r->type = SEMISOLID; loopk(MAXTYPE) if (nums[k] == 4) r->type = k; if (!SOLID(r)) { int floor = 127, ceil = -128, num = 0; loopi(4) if (!SOLID(o[i])) { @@ -134,77 +135,75 @@ num++; int fh = o[i]->floor; int ch = o[i]->ceil; if (r->type == SEMISOLID) { if (o[i]->type == FHF) + // crap hack, needed + // for rendering large + // mips next to hfs fh -= o[i]->vdelta / 4 + - 2; // crap hack, - // needed for - // rendering - // large mips - // next to hfs + 2; if (o[i]->type == CHF) + // FIXME: needs to + // somehow take into + // account middle + // vertices on higher + // mips ch += o[i]->vdelta / 4 + - 2; // FIXME: needs - // to somehow - // take into - // account middle - // vertices on - // higher mips + 2; } if (fh < floor) - floor = - fh; // take lowest floor and - // highest ceil, so we - // never have to see - // missing lower/upper - // from the side + // take lowest floor and + // highest ceil, so we never + // have to see missing + // lower/upper from the side + floor = fh; if (ch > ceil) ceil = ch; } r->floor = floor; r->ceil = ceil; } if (r->type == CORNER) - goto mip; // special case: don't ever split even - // if textures etc are different + // special case: don't ever split even if + // textures etc are different + goto mip; r->defer = 1; if (SOLID(r)) { loopi(3) { if (o[i]->wtex != o[3]->wtex) - goto c; // on an all solid cube, - // only thing that needs - // to be equal for a - // perfect mip is the - // wall texture + // on an all solid cube, only + // thing that needs to be equal + // for a perfect mip is the + // wall texture + goto c; } } else { loopi(3) { + // perfect mip even if light is not + // exactly equal if (o[i]->type != o[3]->type || o[i]->floor != o[3]->floor || o[i]->ceil != o[3]->ceil || o[i]->ftex != o[3]->ftex || o[i]->ctex != o[3]->ctex || abs(o[i + 1]->r - o[0]->r) > - lighterr // perfect mip even if - // light is not exactly - // equal - || abs(o[i + 1]->g - o[0]->g) > + lighterr || + abs(o[i + 1]->g - o[0]->g) > lighterr || abs(o[i + 1]->b - o[0]->b) > lighterr || o[i]->utex != o[3]->utex || o[i]->wtex != o[3]->wtex) goto c; } - if (r->type == CHF || - r->type == - FHF) // can make a perfect mip out of a - // hf if slopes lie on one line - { + + // can make a perfect mip out of a hf if slopes + // lie on one line + if (r->type == CHF || r->type == FHF) { if (o[0]->vdelta - o[1]->vdelta != o[1]->vdelta - SWS(w, x + 2, y, ws) ->vdelta || o[0]->vdelta - o[2]->vdelta != @@ -225,37 +224,40 @@ ->vdelta) goto c; } } { + // if any of the constituents is not perfect, + // then this one isn't either loopi(4) if (o[i]->defer) goto c; - } // if any of the constituents is not perfect, then - // this one isn't either + } mip: r->defer = 0; c:; } s.x /= 2; s.y /= 2; s.xs /= 2; s.ys /= 2; - remip(s, level + 1); + remip(&s, level + 1); } void -remipmore(const block &b, int level) +remipmore(const block *b, int level) { - block bb = b; + block bb = *b; + if (bb.x > 1) bb.x--; if (bb.y > 1) bb.y--; if (bb.xs < ssize - 3) bb.xs++; if (bb.ys < ssize - 3) bb.ys++; - remip(bb, level); + + remip(&bb, level); } int closestent() // used for delent and edit mode ent display { @@ -504,11 +506,11 @@ hdr.waterlevel = -100000; loopi(15) hdr.reserved[i] = 0; loopk(3) loopi(256) hdr.texlists[k][i] = i; [ents removeAllObjects]; block b = { 8, 8, ssize - 16, ssize - 16 }; - edittypexy(SPACE, b); + edittypexy(SPACE, &b); } calclight(); startmap(@"base/unnamed"); if (oldworld) { Index: src/worldlight.mm ================================================================== --- src/worldlight.mm +++ src/worldlight.mm @@ -163,11 +163,11 @@ median(r); median(g); median(b); } - remip(a); + remip(&a); } void calclight() { @@ -194,30 +194,30 @@ cleardlights() { while (dlights.count > 0) { block *backup = *(block **)[dlights lastItem]; [dlights removeLastItem]; - blockpaste(*backup); + blockpaste(backup); OFFreeMemory(backup); } } void -dodynlight(const OFVector3D &vold, const OFVector3D &v, int reach, int strength, +dodynlight(const OFVector3D *vold, const OFVector3D *v, int reach, int strength, DynamicEntity *owner) { if (!reach) reach = dynlight; if (owner.monsterstate) reach = reach / 2; if (!reach) return; - if (v.x < 0 || v.y < 0 || v.x > ssize || v.y > ssize) + if (v->x < 0 || v->y < 0 || v->x > ssize || v->y > ssize) return; int creach = reach + 16; // dependant on lightray random offsets! - block b = { (int)v.x - creach, (int)v.y - creach, creach * 2 + 1, + block b = { (int)v->x - creach, (int)v->y - creach, creach * 2 + 1, creach * 2 + 1 }; if (b.x < 1) b.x = 1; if (b.y < 1) @@ -230,17 +230,17 @@ if (dlights == nil) dlights = [[OFMutableData alloc] initWithItemSize:sizeof(block *)]; // backup area before rendering in dynlight - block *copy = blockcopy(b); + block *copy = blockcopy(&b); [dlights addItem:©]; PersistentEntity *l = [Entity entity]; - l.x = v.x; - l.y = v.y; - l.z = v.z; + l.x = v->x; + l.y = v->y; + l.z = v->z; l.attr1 = reach; l.type = LIGHT; l.attr2 = strength; calclightsource(l); postlightarea(b); @@ -247,26 +247,26 @@ } // utility functions also used by editing code block * -blockcopy(block &s) +blockcopy(const block *s) { block *b = (block *)OFAllocZeroedMemory( - 1, sizeof(block) + s.xs * s.ys * sizeof(sqr)); - *b = s; + 1, sizeof(block) + s->xs * s->ys * sizeof(sqr)); + *b = *s; sqr *q = (sqr *)(b + 1); - for (int x = s.x; x < s.xs + s.x; x++) - for (int y = s.y; y < s.ys + s.y; y++) + for (int x = s->x; x < s->xs + s->x; x++) + for (int y = s->y; y < s->ys + s->y; y++) *q++ = *S(x, y); return b; } void -blockpaste(const block &b) +blockpaste(const block *b) { - sqr *q = (sqr *)((&b) + 1); - for (int x = b.x; x < b.xs + b.x; x++) - for (int y = b.y; y < b.ys + b.y; y++) + sqr *q = (sqr *)(b + 1); + for (int x = b->x; x < b->xs + b->x; x++) + for (int y = b->y; y < b->ys + b->y; y++) *S(x, y) = *q++; remipmore(b); }