Comment: | Convert more files to pure Objective-C |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
46c577957085f072871cb93b46340fd8 |
User & Date: | js on 2025-03-20 21:52:26 |
Other Links: | manifest | tags |
2025-03-20
| ||
22:22 | Convert remaining files to pure Objective-C check-in: 12cac9666a user: js tags: trunk | |
21:52 | Convert more files to pure Objective-C check-in: 46c5779570 user: js tags: trunk | |
21:18 | Convert more files to pure Objective-C check-in: b250dfa8d4 user: js tags: trunk | |
Name change from src/Cube.mm to src/Cube.m.
Renamed and modified src/commands.mm [b377b2846b] to src/commands.m [5ae3539b0c].
1 2 3 4 5 | // command.cpp: implements the parsing and execution of a tiny script language // which is largely backwards compatible with the quake console language. #include "cube.h" | < < > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // command.cpp: implements the parsing and execution of a tiny script language // which is largely backwards compatible with the quake console language. #include "cube.h" #import "Alias.h" #import "Command.h" #import "Identifier.h" #import "OFString+Cube.h" #import "Variable.h" // contains ALL vars/commands/aliases static OFMutableDictionary<OFString *, __kindof Identifier *> *identifiers; static void cleanup(char **string) { free(*string); } void alias(OFString *name, OFString *action) { Alias *alias = identifiers[name]; if (alias == nil) { |
︙ | ︙ | |||
96 97 98 99 100 101 102 | identifiers[name] = command; return false; } // parse any nested set of () or [] | | | | | | | | | | | | | | | | | | | | | | | | | | | | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | identifiers[name] = command; return false; } // parse any nested set of () or [] static char * parseexp(char **p, int right) { int left = *(*p)++; char *word = *p; for (int brak = 1; brak;) { int c = *(*p)++; if (c == '\r') *(*p - 1) = ' '; // hack if (c == left) brak++; else if (c == right) brak--; else if (!c) { (*p)--; conoutf(@"missing \"%c\"", right); return NULL; } } char *s = strndup(word, *p - word - 1); if (left == '(') { OFString *t; @try { t = [OFString stringWithFormat:@"%d", execute(@(s), true)]; } @finally { free(s); } s = strdup(t.UTF8String); } return s; } // parse single argument, including expressions static char * parseword(char **p) { (*p) += strspn(*p, " \t\r"); if ((*p)[0] == '/' && (*p)[1] == '/') *p += strcspn(*p, "\n\0"); if (**p == '\"') { (*p)++; char *word = *p; *p += strcspn(*p, "\"\r\n\0"); char *s = strndup(word, *p - word); if (**p == '\"') (*p)++; return s; } if (**p == '(') return parseexp(p, ')'); if (**p == '[') return parseexp(p, ']'); char *word = *p; *p += strcspn(*p, "; \t\r\n\0"); if (*p - word == 0) return NULL; return strndup(word, *p - word); } // find value of ident referenced with $ in exp OFString * lookup(OFString *n) { __kindof Identifier *identifier = identifiers[[n substringFromIndex:1]]; |
︙ | ︙ | |||
223 224 225 226 227 228 229 | return 0; } // all evaluation happens here, recursively int execute(OFString *string, bool isDown) { | > | | | | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | return 0; } // all evaluation happens here, recursively int execute(OFString *string, bool isDown) { char *copy __attribute__((__cleanup__(cleanup))) = strdup(string.UTF8String); char *p = copy; const int MAXWORDS = 25; // limit, remove OFString *w[MAXWORDS]; int val = 0; for (bool cont = true; cont;) { // for each ; seperated statement int numargs = MAXWORDS; loopi(MAXWORDS) { // collect all argument values w[i] = @""; if (i > numargs) continue; // parse and evaluate exps char *s = parseword(&p); if (!s) { numargs = i; s = strdup(""); } @try { if (*s == '$') // substitute variables |
︙ | ︙ | |||
465 466 467 468 469 470 471 | return n + 1; } void at(OFString *s_, OFString *pos) { int n = pos.cube_intValue; | > | | > > | > > | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | return n + 1; } void at(OFString *s_, OFString *pos) { int n = pos.cube_intValue; char *copy __attribute__((__cleanup__(cleanup))) = strdup(s_.UTF8String); char *s = copy; loopi(n) { s += strcspn(s, " \0"); s += strspn(s, " "); } s[strcspn(s, " \0")] = 0; concat(@(s)); } COMMANDN(loop, loopa, ARG_2STR) COMMANDN(while, whilea, ARG_2STR) COMMANDN(if, ifthen, ARG_3STR) |
︙ | ︙ |
Modified src/editing.m from [1b9f6190f4] to [27b5ed2226].
︙ | ︙ | |||
25 26 27 28 29 30 31 | }; }); } int selh = 0; bool selset = false; | | | | | | | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | }; }); } int selh = 0; bool selset = false; #define loopselxy(b) \ { \ makeundo(); \ loop(x, sel->xs) loop(y, sel->ys) \ { \ struct sqr *s = S(sel->x + x, sel->y + y); \ b; \ } \ remip(sel, 0); \ } int cx, cy, ch; int curedittex[] = { -1, -1, -1 }; bool dragging = false; |
︙ | ︙ | |||
257 258 259 260 261 262 263 | } } void makeundo() { if (undos == nil) | | | | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | } } void makeundo() { if (undos == nil) undos = [[OFMutableData alloc] initWithItemSize:sizeof(struct block *)]; struct block *copy = blockcopy(&sel); [undos addItem:©]; pruneundos(undomegs << 20); } void |
︙ | ︙ |
Modified src/entities.m from [2808b0e950] to [df6381198b].
︙ | ︙ | |||
26 27 28 29 30 31 32 | void initEntities() { ents = [[OFMutableArray alloc] init]; } static void | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | void initEntities() { ents = [[OFMutableArray alloc] init]; } static void renderent(Entity *e, OFString *mdlname, float z, float yaw, int frame /* = 0*/, int numf /* = 1*/, int basetime /* = 0*/, float speed /* = 10.0f*/) { rendermodel(mdlname, frame, numf, 0, 1.1f, OFMakeVector3D(e.x, z + S(e.x, e.y)->floor, e.y), yaw, 0, false, 1.0f, speed, 0, basetime); } void |
︙ | ︙ | |||
63 64 65 66 67 68 69 | continue; if (e.type < I_SHELLS || e.type > TELEPORT) continue; renderent(e, entmdlnames[e.type - I_SHELLS], (float)(1 + sin(lastmillis / 100.0 + e.x + e.y) / 20), | | | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | continue; if (e.type < I_SHELLS || e.type > TELEPORT) continue; renderent(e, entmdlnames[e.type - I_SHELLS], (float)(1 + sin(lastmillis / 100.0 + e.x + e.y) / 20), lastmillis / 10.0f, 0, 1, 0, 10.0f); } else { switch (e.attr2) { case 1: case 3: continue; case 2: case 0: if (!e.spawned) continue; renderent(e, @"carrot", (float)(1 + sin(lastmillis / 100.0 + e.x + e.y) / 20), lastmillis / (e.attr2 ? 1.0f : 10.0f), 0, 1, 0, 10.0f); break; case 4: renderent(e, @"switch2", 3, (float)e.attr3 * 90, (!e.spawned && !triggertime) ? 1 : 0, |
︙ | ︙ |
Modified src/meson.build from [44296e0cb5] to [a429d4244b].
1 2 3 4 5 6 | executable('client', [ 'Alias.m', 'Client.m', 'Command.m', 'ConsoleLine.m', | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | executable('client', [ 'Alias.m', 'Client.m', 'Command.m', 'ConsoleLine.m', 'Cube.m', 'DynamicEntity.m', 'Entity.m', 'Identifier.m', 'KeyMapping.m', 'MD2.m', 'MapModelInfo.m', 'Menu.m', 'MenuItem.m', 'OFString+Cube.m', 'PersistentEntity.m', 'Projectile.m', 'ResolverResult.m', 'ResolverThread.m', 'ServerEntity.m', 'ServerInfo.m', 'Variable.m', 'clients.m', 'clientextras.m', 'clientgame.m', 'clients2c.m', 'commands.m', 'console.m', 'editing.m', 'entities.m', 'init.mm', 'menus.m', 'monster.m', 'physics.m', 'rendercubes.m', 'renderextras.m', 'rendergl.mm', 'rendermd2.mm', 'renderparticles.mm', 'rendertext.mm', 'rndmap.mm', 'savegamedemo.mm', 'server.m', 'serverbrowser.mm', 'serverms.m', 'serverutil.m', 'sound.m', 'tools.m', 'weapon.m', 'world.mm', 'worldio.mm', 'worldlight.mm', 'worldocull.mm', 'worldrender.mm', ], dependencies: [ |
︙ | ︙ | |||
67 68 69 70 71 72 73 | link_with: [enet], win_subsystem: 'windows') executable('server', [ 'Client.m', 'ServerEntity.m', | | | | | | | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | link_with: [enet], win_subsystem: 'windows') executable('server', [ 'Client.m', 'ServerEntity.m', 'server.m', 'serverms.m', 'serverutil.m', 'tools.m', ], objc_args: ['-DSTANDALONE'], dependencies: [ objfw_dep, sdl_dep ], include_directories: [enet_includes], link_args: server_link_args, link_with: [enet], win_subsystem: 'console') |
Renamed and modified src/physics.mm [c9005101f7] to src/physics.m [1c146ff92c].
1 2 3 4 5 6 7 8 9 10 11 12 13 | // physics.cpp: no physics books were hurt nor consulted in the construction of // this code. All physics computations and constants were invented on the fly // and simply tweaked until they "felt right", and have no basis in reality. // Collision detection is simplistic but very robust (uses discrete steps at // fixed fps). #include "cube.h" #import "DynamicEntity.h" #import "Entity.h" #import "MapModelInfo.h" // collide with player or monster | | | | | | | | | | > | | < | | | | > | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | // physics.cpp: no physics books were hurt nor consulted in the construction of // this code. All physics computations and constants were invented on the fly // and simply tweaked until they "felt right", and have no basis in reality. // Collision detection is simplistic but very robust (uses discrete steps at // fixed fps). #include "cube.h" #import "DynamicEntity.h" #import "Entity.h" #import "MapModelInfo.h" // collide with player or monster static bool plcollide( DynamicEntity *d, DynamicEntity *o, float *headspace, float *hi, float *lo) { if (o.state != CS_ALIVE) return true; const float r = o.radius + d.radius; if (fabs(o.o.x - d.o.x) < r && fabs(o.o.y - d.o.y) < r) { if (d.o.z - d.eyeheight < o.o.z - o.eyeheight) { if (o.o.z - o.eyeheight < *hi) *hi = o.o.z - o.eyeheight - 1; } else if (o.o.z + o.aboveeye > *lo) *lo = o.o.z + o.aboveeye + 1; if (fabs(o.o.z - d.o.z) < o.aboveeye + d.eyeheight) return false; if (d.monsterstate) return false; // hack *headspace = d.o.z - o.o.z - o.aboveeye - d.eyeheight; if (*headspace < 0) *headspace = 10; } return true; } // recursively collide with a mipmapped corner cube static bool cornertest(int mip, int x, int y, int dx, int dy, int *bx, int *by, int *bs) { struct sqr *w = wmip[mip]; int sz = ssize >> mip; bool stest = SOLID(SWS(w, x + dx, y, sz)) && SOLID(SWS(w, x, y + dy, sz)); mip++; x /= 2; y /= 2; if (SWS(wmip[mip], x, y, ssize >> mip)->type == CORNER) { *bx = x << mip; *by = y << mip; *bs = 1 << mip; return cornertest(mip, x, y, dx, dy, bx, by, bs); } return stest; } // collide with a mapmodel static void mmcollide(DynamicEntity *d, float *hi, float *lo) { for (Entity *e in ents) { if (e.type != MAPMODEL) continue; MapModelInfo *mmi = getmminfo(e.attr2); if (mmi == nil || !mmi.h) continue; const float r = mmi.rad + d.radius; if (fabs(e.x - d.o.x) < r && fabs(e.y - d.o.y) < r) { float mmz = (float)(S(e.x, e.y)->floor + mmi.zoff + e.attr3); if (d.o.z - d.eyeheight < mmz) { if (mmz < *hi) *hi = mmz; } else if (mmz + mmi.h > *lo) *lo = mmz + mmi.h; } } } // all collision happens here // spawn is a dirty side effect used in spawning // drop & rise are supplied by the physics below to indicate gravity/push for |
︙ | ︙ | |||
105 106 107 108 109 110 111 | : -1000.0f; for (int x = x1; x <= x2; x++) for (int y = y1; y <= y2; y++) { // collide with map if (OUTBORD(x, y)) return false; | | | | | | > | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | : -1000.0f; for (int x = x1; x <= x2; x++) for (int y = y1; y <= y2; y++) { // collide with map if (OUTBORD(x, y)) return false; struct sqr *s = S(x, y); float ceil = s->ceil; float floor = s->floor; switch (s->type) { case SOLID: return false; case CORNER: { int bx = x, by = y, bs = 1; if (x == x1 && y == y1 && cornertest( 0, x, y, -1, -1, &bx, &by, &bs) && fx1 - bx + fy1 - by <= bs || x == x2 && y == y1 && cornertest( 0, x, y, 1, -1, &bx, &by, &bs) && fx2 - bx >= fy1 - by || x == x1 && y == y2 && cornertest( 0, x, y, -1, 1, &bx, &by, &bs) && fx1 - bx <= fy2 - by || x == x2 && y == y2 && cornertest( 0, x, y, 1, 1, &bx, &by, &bs) && fx2 - bx + fy2 - by >= bs) return false; break; } case FHF: // FIXME: too simplistic collision with // slopes, makes it feels like tiny stairs |
︙ | ︙ | |||
162 163 164 165 166 167 168 | if (hi - lo < d.eyeheight + d.aboveeye) return false; float headspace = 10; for (id player in players) { if (player == [OFNull null] || player == d) continue; | | | | | | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | if (hi - lo < d.eyeheight + d.aboveeye) return false; float headspace = 10; for (id player in players) { if (player == [OFNull null] || player == d) continue; if (!plcollide(d, player, &headspace, &hi, &lo)) return false; } if (d != player1) if (!plcollide(d, player1, &headspace, &hi, &lo)) return false; // this loop can be a performance bottleneck with many monster on a slow // cpu, should replace with a blockmap but seems mostly fast enough for (DynamicEntity *monster in getmonsters()) if (!vreject(d.o, monster.o, 7.0f) && d != monster && !plcollide(d, monster, &headspace, &hi, &lo)) return false; headspace -= 0.01f; mmcollide(d, &hi, &lo); // collide with map models if (spawn) { // just drop to floor (sideeffect) d.o = OFMakeVector3D(d.o.x, d.o.y, lo + d.eyeheight); d.onfloor = true; } else { const float space = d.o.z - d.eyeheight - lo; |
︙ | ︙ | |||
242 243 244 245 246 247 248 | } } // main physics routine, moves a player/monster for a curtime step // moveres indicated the physics precision (which is lower for monsters and // multiplayer prediction) local is false for multiplayer prediction | | | | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | } } // main physics routine, moves a player/monster for a curtime step // moveres indicated the physics precision (which is lower for monsters and // multiplayer prediction) local is false for multiplayer prediction static void moveplayer4(DynamicEntity *pl, int moveres, bool local, int curtime) { const bool water = hdr.waterlevel > pl.o.z - 0.5f; const bool floating = (editmode && local) || pl.state == CS_EDITING; OFVector3D d; // vector of direction we ideally want to move in d.x = (float)(pl.move * cos(rad(pl.yaw - 90))); |
︙ | ︙ | |||
373 374 375 376 377 378 379 | // detect wether player is outside map, used for skipping zbuffer clear // mostly if (pl.o.x < 0 || pl.o.x >= ssize || pl.o.y < 0 || pl.o.y > ssize) pl.outsidemap = true; else { | | | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | // detect wether player is outside map, used for skipping zbuffer clear // mostly if (pl.o.x < 0 || pl.o.x >= ssize || pl.o.y < 0 || pl.o.y > ssize) pl.outsidemap = true; else { struct sqr *s = S((int)pl.o.x, (int)pl.o.y); pl.outsidemap = SOLID(s) || pl.o.z < s->floor - (s->type == FHF ? s->vdelta / 4 : 0) || pl.o.z > s->ceil + (s->type == CHF ? s->vdelta / 4 : 0); } // automatically apply smooth roll when strafing |
︙ | ︙ | |||
407 408 409 410 411 412 413 | } pl.inwater = water; } void moveplayer(DynamicEntity *pl, int moveres, bool local) { | | | 409 410 411 412 413 414 415 416 417 418 419 | } pl.inwater = water; } void moveplayer(DynamicEntity *pl, int moveres, bool local) { loopi(physicsrepeat) moveplayer4(pl, moveres, local, i ? curtime / physicsrepeat : curtime - curtime / physicsrepeat * (physicsrepeat - 1)); } |
Renamed and modified src/rendercubes.mm [a098c5d67b] to src/rendercubes.m [9b7cf3b555].
1 2 3 4 5 | // rendercubes.cpp: sits in between worldrender.cpp and rendergl.cpp and fills // the vertex array for different cube surfaces. #include "cube.h" | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | // rendercubes.cpp: sits in between worldrender.cpp and rendergl.cpp and fills // the vertex array for different cube surfaces. #include "cube.h" static struct vertex *verts = NULL; int curvert; static int curmaxverts = 10000; void setarraypointers() { glVertexPointer(3, GL_FLOAT, sizeof(struct vertex), &verts[0].x); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(struct vertex), &verts[0].r); glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), &verts[0].u); } void reallocv() { verts = OFResizeMemory(verts, (curmaxverts *= 2), sizeof(struct vertex)); curmaxverts -= 10; setarraypointers(); } // generating the actual vertices is done dynamically every frame and sits at // the leaves of all these functions, and are part of the cpu bottleneck on // really slow machines, hence the macros. #define vertcheck() \ { \ if (curvert >= curmaxverts) \ reallocv(); \ } #define vertf(v1, v2, v3, ls, t1, t2) \ { \ struct vertex *v = &verts[curvert++]; \ v->u = t1; \ v->v = t2; \ v->x = v1; \ v->y = v2; \ v->z = v3; \ v->r = ls->r; \ v->g = ls->g; \ v->b = ls->b; \ v->a = 255; \ } #define vert(v1, v2, v3, ls, t1, t2) \ { \ vertf((float)(v1), (float)(v2), (float)(v3), ls, t1, t2); \ } |
︙ | ︙ | |||
84 85 86 87 88 89 90 | } void finishstrips() { stripend(); } | | > | | | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | } void finishstrips() { stripend(); } static struct sqr sbright, sdark; VAR(lighterror, 1, 8, 100); // floor/ceil quads void render_flat(int wtex, int x, int y, int size, int h, struct sqr *l1, struct sqr *l2, struct sqr *l3, struct sqr *l4, bool isceil) { vertcheck(); if (showm) { l3 = l1 = &sbright; l4 = l2 = &sdark; } |
︙ | ︙ | |||
167 168 169 170 171 172 173 174 175 | vert(x + size, h, y + size, l3, xo + xs, yo + ys); } oy = y; nquads++; } void render_flatdelta(int wtex, int x, int y, int size, float h1, float h2, float h3, | > | | | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | vert(x + size, h, y + size, l3, xo + xs, yo + ys); } oy = y; nquads++; } // floor/ceil quads on a slope void render_flatdelta(int wtex, int x, int y, int size, float h1, float h2, float h3, float h4, struct sqr *l1, struct sqr *l2, struct sqr *l3, struct sqr *l4, bool isceil) { vertcheck(); if (showm) { l3 = l1 = &sbright; l4 = l2 = &sdark; } |
︙ | ︙ | |||
225 226 227 228 229 230 231 232 | (float)x + size, h3, (float)y + size, l3, xo + xs, yo + ys); } oy = y; nquads++; } void | > | | | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | (float)x + size, h3, (float)y + size, l3, xo + xs, yo + ys); } oy = y; nquads++; } // floor/ceil tris on a corner cube void render_2tris(struct sqr *h, struct sqr *s, int x1, int y1, int x2, int y2, int x3, int y3, struct sqr *l1, struct sqr *l2, struct sqr *l3) { stripend(); vertcheck(); int sx, sy; int gltex = lookuptexture(h->ftex, &sx, &sy); float xf = TEXTURESCALE / sx; |
︙ | ︙ | |||
254 255 256 257 258 259 260 | vertf((float)x2, h->ceil, (float)y2, l2, xf * x2, yf * y2); vertf((float)x1, h->ceil, (float)y1, l1, xf * x1, yf * y1); addstrip(gltex, curvert - 3, 3); nquads++; } void | | | | | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | vertf((float)x2, h->ceil, (float)y2, l2, xf * x2, yf * y2); vertf((float)x1, h->ceil, (float)y1, l1, xf * x1, yf * y1); addstrip(gltex, curvert - 3, 3); nquads++; } void render_tris(int x, int y, int size, bool topleft, struct sqr *h1, struct sqr *h2, struct sqr *s, struct sqr *t, struct sqr *u, struct sqr *v) { if (topleft) { if (h1) render_2tris(h1, s, x + size, y + size, x, y + size, x, y, u, v, s); if (h2) render_2tris(h2, s, x, y, x + size, y, x + size, y + size, s, t, v); } else { if (h1) render_2tris( h1, s, x, y, x + size, y, x, y + size, s, t, u); if (h2) render_2tris(h2, s, x + size, y, x + size, y + size, x, y + size, t, u, v); } } void render_square(int wtex, float floor1, float floor2, float ceil1, float ceil2, int x1, int y1, int x2, int y2, int size, struct sqr *l1, struct sqr *l2, bool flip) // wall quads { stripend(); vertcheck(); if (showm) { l1 = &sbright; l2 = &sdark; |
︙ | ︙ | |||
315 316 317 318 319 320 321 | int wx1, wy1, wx2, wy2; VAR(watersubdiv, 1, 4, 64); VARF(waterlevel, -128, -128, 127, if (!noteditmode()) hdr.waterlevel = waterlevel); | | | | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | int wx1, wy1, wx2, wy2; VAR(watersubdiv, 1, 4, 64); VARF(waterlevel, -128, -128, 127, if (!noteditmode()) hdr.waterlevel = waterlevel); static inline void vertw(int v1, float v2, int v3, struct sqr *c, float t1, float t2, float t) { vertcheck(); vertf((float)v1, v2 - (float)sin(v1 * v3 * 0.1 + t) * 0.2f, (float)v3, c, t1, t2); } inline float |
︙ | ︙ | |||
359 360 361 362 363 364 365 | float xf = TEXTURESCALE / sx; float yf = TEXTURESCALE / sy; float xs = watersubdiv * xf; float ys = watersubdiv * yf; float t1 = lastmillis / 300.0f; float t2 = lastmillis / 4000.0f; | | | 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | float xf = TEXTURESCALE / sx; float yf = TEXTURESCALE / sy; float xs = watersubdiv * xf; float ys = watersubdiv * yf; float t1 = lastmillis / 300.0f; float t2 = lastmillis / 4000.0f; struct sqr dl; dl.r = dl.g = dl.b = 255; for (int xx = wx1; xx < wx2; xx += watersubdiv) { for (int yy = wy1; yy < wy2; yy += watersubdiv) { float xo = xf * (xx + t2); float yo = yf * (yy + t2); if (yy == wy1) { |
︙ | ︙ |
Renamed and modified src/renderextras.mm [5a2fb82c3f] to src/renderextras.m [866128604e].
︙ | ︙ | |||
21 22 23 24 25 26 27 | linestyle(float width, int r, int g, int b) { glLineWidth(width); glColor3ub(r, g, b); } void | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | linestyle(float width, int r, int g, int b) { glLineWidth(width); glColor3ub(r, g, b); } void box(const struct 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); glEnd(); |
︙ | ︙ | |||
82 83 84 85 86 87 88 | } const int MAXSPHERES = 50; struct sphere { OFVector3D o; float size, max; int type; | | | | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | } const int MAXSPHERES = 50; struct sphere { OFVector3D o; float size, max; int type; struct sphere *next; }; static struct sphere spheres[MAXSPHERES], *slist = NULL, *sempty = NULL; bool sinit = false; void newsphere(const OFVector3D *o, float max, int type) { if (!sinit) { loopi(MAXSPHERES) { spheres[i].next = sempty; sempty = &spheres[i]; } sinit = true; } if (sempty) { struct sphere *p = sempty; sempty = p->next; p->o = *o; p->max = max; p->size = 1; p->type = type; p->next = slist; slist = p; } } void renderspheres(int time) { glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glBindTexture(GL_TEXTURE_2D, 4); for (struct sphere *p, **pp = &slist; (p = *pp) != NULL;) { glPushMatrix(); float size = p->size / p->max; glColor4f(1.0f, 1.0f, 1.0f, 1.0f - size); glTranslatef(p->o.x, p->o.z, p->o.y); glRotatef(lastmillis / 5.0f, 1, 1, 1); glScalef(p->size, p->size, p->size); glCallList(1); |
︙ | ︙ |
Renamed and modified src/server.mm [e4950a7889] to src/server.m [761c67a79c].
︙ | ︙ | |||
42 43 44 45 46 47 48 | #define MAXOBUF 100000 void process(ENetPacket *packet, int sender); void multicast(ENetPacket *packet, int sender); void disconnect_client(int n, OFString *reason); | | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #define MAXOBUF 100000 void process(ENetPacket *packet, int sender); void multicast(ENetPacket *packet, int sender); void disconnect_client(int n, OFString *reason); static void send_(int n, ENetPacket *packet) { if (!packet) return; switch (clients[n].type) { case ST_TCPIP: enet_peer_send(clients[n].peer, 0, packet); |
︙ | ︙ | |||
73 74 75 76 77 78 79 | 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 | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | 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 send_(cn, packet); if (packet->referenceCount == 0) enet_packet_destroy(packet); } void sendservmsg(OFString *msg) { |
︙ | ︙ | |||
111 112 113 114 115 116 117 | void resetitems() { [sents removeAllObjects]; notgotitems = true; } | > | | < | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | void resetitems() { [sents removeAllObjects]; notgotitems = true; } // server side item pickup, acknowledge first client that gets it static void pickup(uint i, int sec, int sender) { if (i >= (uint)sents.count) return; if (sents[i].spawned) { sents[i].spawned = false; sents[i].spawnsecs = sec; send2(true, sender, SV_ITEMACC, i); |
︙ | ︙ | |||
261 262 263 264 265 266 267 | sgetstr(); int mapsize = getint(&p); sendmaps(sender, @(text), mapsize, p); return; } case SV_RECVMAP: | | | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | sgetstr(); int mapsize = getint(&p); sendmaps(sender, @(text), mapsize, p); return; } case SV_RECVMAP: 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); break; |
︙ | ︙ | |||
316 317 318 319 320 321 322 | if (e.spawned) putint(&p, i); }]; putint(&p, -1); } *(ushort *)start = ENET_HOST_TO_NET_16(p - start); enet_packet_resize(packet, p - start); | | | | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | if (e.spawned) putint(&p, i); }]; putint(&p, -1); } *(ushort *)start = ENET_HOST_TO_NET_16(p - start); enet_packet_resize(packet, p - start); send_(n, packet); } void multicast(ENetPacket *packet, int sender) { size_t count = clients.count; for (size_t i = 0; i < count; i++) if (i != sender) send_(i, packet); } void localclienttoserver(ENetPacket *packet) { process(packet, 0); |
︙ | ︙ |
Renamed and modified src/serverms.mm [67d3e10cf2] to src/serverms.m [c145a0420f].
1 2 3 4 5 6 7 | // all server side masterserver and pinging functionality #include "cube.h" static ENetSocket mssock = ENET_SOCKET_NULL; static void | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | // all server side masterserver and pinging functionality #include "cube.h" static ENetSocket mssock = ENET_SOCKET_NULL; static void httpgetsend(ENetAddress *ad, OFString *hostname, OFString *req, OFString *ref, OFString *agent) { if (ad->host == ENET_HOST_ANY) { [OFStdOut writeFormat:@"looking up %@...\n", hostname]; enet_address_set_host(ad, hostname.UTF8String); if (ad->host == ENET_HOST_ANY) return; } if (mssock != ENET_SOCKET_NULL) enet_socket_destroy(mssock); mssock = enet_socket_create(ENET_SOCKET_TYPE_STREAM, NULL); if (mssock == ENET_SOCKET_NULL) { printf("could not open socket\n"); return; } if (enet_socket_connect(mssock, ad) < 0) { printf("could not connect\n"); return; } ENetBuffer buf; OFString *httpget = [OFString stringWithFormat:@"GET %@ HTTP/1.0\n" @"Host: %@\n" @"Referer: %@\n" @"User-Agent: %@\n\n", req, hostname, ref, agent]; buf.data = (void *)httpget.UTF8String; buf.dataLength = httpget.UTF8StringLength; [OFStdOut writeFormat:@"sending request to %@...\n", hostname]; enet_socket_send(mssock, NULL, &buf, 1); } static void httpgetrecieve(ENetBuffer *buf) { if (mssock == ENET_SOCKET_NULL) return; enet_uint32 events = ENET_SOCKET_WAIT_RECEIVE; if (enet_socket_wait(mssock, &events, 0) >= 0 && events) { int len = enet_socket_receive(mssock, NULL, buf, 1); if (len <= 0) { enet_socket_destroy(mssock); mssock = ENET_SOCKET_NULL; return; } buf->data = ((char *)buf->data) + len; ((char *)buf->data)[0] = 0; buf->dataLength -= len; } } static uchar * stripheader(uchar *b) { char *s = strstr((char *)b, "\n\r\n"); |
︙ | ︙ | |||
75 76 77 78 79 80 81 | static void updatemasterserver(int seconds) { // send alive signal to masterserver every hour of uptime if (seconds > updmaster) { OFString *path = [OFString stringWithFormat:@"%@register.do?action=add", masterpath]; | | | | | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | static void updatemasterserver(int seconds) { // send alive signal to masterserver every hour of uptime if (seconds > updmaster) { OFString *path = [OFString stringWithFormat:@"%@register.do?action=add", masterpath]; httpgetsend(&masterserver, masterbase, path, @"cubeserver", @"Cube Server"); masterrep[0] = 0; masterb.data = masterrep; masterb.dataLength = MAXTRANS - 1; updmaster = seconds + 60 * 60; } } static void checkmasterreply() { bool busy = mssock != ENET_SOCKET_NULL; httpgetrecieve(&masterb); if (busy && mssock == ENET_SOCKET_NULL) printf("masterserver reply: %s\n", stripheader(masterrep)); } uchar * retrieveservers(uchar *buf, int buflen) { OFString *path = [OFString stringWithFormat:@"%@retrieve.do?item=list", masterpath]; httpgetsend( &masterserver, masterbase, path, @"cubeserver", @"Cube Server"); ENetBuffer eb; buf[0] = 0; eb.data = buf; eb.dataLength = buflen - 1; while (mssock != ENET_SOCKET_NULL) httpgetrecieve(&eb); return stripheader(buf); } static ENetSocket pongsock = ENET_SOCKET_NULL; static OFString *serverdesc; void |
︙ | ︙ |
Name change from src/serverutil.mm to src/serverutil.m.
Renamed and modified src/sound.mm [eeaee8a784] to src/sound.m [fab11a9b01].
︙ | ︙ | |||
33 34 35 36 37 38 39 | } VAR(soundbufferlen, 128, 1024, 4096); void initsound() { | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | } VAR(soundbufferlen, 128, 1024, 4096); void initsound() { memset(soundlocs, 0, sizeof(struct soundloc) * MAXCHAN); if (Mix_OpenAudio(SOUNDFREQ, MIX_DEFAULT_FORMAT, 2, soundbufferlen) < 0) { conoutf(@"sound init failed (SDL_mixer): %s", (size_t)Mix_GetError()); nosound = true; } Mix_AllocateChannels(MAXCHAN); |
︙ | ︙ | |||
121 122 123 124 125 126 127 | vol -= (int)(dist * 3 * soundvol / 255); // simple mono distance attenuation if (stereo && (v.x != 0 || v.y != 0)) { // relative angle of sound along X-Y axis float yaw = -atan2(v.x, v.y) - player1.yaw * (PI / 180.0f); // range is from 0 (left) to 255 (right) | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | vol -= (int)(dist * 3 * soundvol / 255); // simple mono distance attenuation if (stereo && (v.x != 0 || v.y != 0)) { // relative angle of sound along X-Y axis float yaw = -atan2(v.x, v.y) - player1.yaw * (PI / 180.0f); // range is from 0 (left) to 255 (right) pan = (int)(255.9f * (0.5 * sin(yaw) + 0.5f)); } } vol = (vol * MAXVOL) / 255; Mix_Volume(chan, vol); Mix_SetPanning(chan, 255 - pan, pan); } |
︙ | ︙ |
Renamed and modified src/tools.mm [22d3464477] to src/tools.m [f9cb2ee264].
1 2 3 | // implementation of generic tools #include "tools.h" | < | 1 2 3 4 5 6 7 8 9 10 | // implementation of generic tools #include "tools.h" ///////////////////////// misc tools /////////////////////// void endianswap( void *memory, int stride, int length) // little indians as storage format { |
︙ | ︙ |
Renamed and modified src/weapon.mm [b2ede2d0f5] to src/weapon.m [2e4de9f255].
︙ | ︙ | |||
238 239 240 241 242 243 244 | DynamicEntity *monster, size_t i, bool *stop) { if (i != notthismonster) radialeffect(monster, v, i, qdam, p.owner); }]; } } | | | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | DynamicEntity *monster, size_t i, bool *stop) { if (i != notthismonster) radialeffect(monster, v, i, qdam, p.owner); }]; } } static inline void projdamage(DynamicEntity *o, Projectile *p, const OFVector3D *v, int i, int im, int qdam) { if (o.state != CS_ALIVE) return; OFVector3D po = p.o; |
︙ | ︙ |