Comment: | Migrate more strings |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
e7b5d33cada1ff8db653655ab2c77ead |
User & Date: | js on 2025-03-03 23:52:52 |
Other Links: | manifest | tags |
2025-03-03
| ||
23:54 | Merge accidental fork check-in: a6544d60c4 user: js tags: trunk | |
23:52 | Migrate more strings check-in: e7b5d33cad user: js tags: trunk | |
2025-03-02
| ||
19:52 | Migrate more strings check-in: 0d125c31da user: js tags: trunk | |
Modified src/Cube.mm from [008a05c64e] to [1c90efecc5].
︙ | ︙ | |||
198 199 200 201 202 203 204 | fatal("could not find core textures (hint: run cube from the " "parent of the bin directory)"); log("sound"); initsound(); log("cfg"); | | | | | | | | | | | | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | fatal("could not find core textures (hint: run cube from the " "parent of the bin directory)"); log("sound"); initsound(); log("cfg"); newmenu(@"frags\tpj\tping\tteam\tname"); newmenu(@"ping\tplr\tserver"); exec(@"data/keymap.cfg"); exec(@"data/menus.cfg"); exec(@"data/prefabs.cfg"); exec(@"data/sounds.cfg"); exec(@"servers.cfg"); if (!execfile(@"config.cfg")) execfile(@"data/defaults.cfg"); exec(@"autoexec.cfg"); log("localconnect"); localconnect(); // if this map is changed, also change depthcorrect() changemap(@"metl3"); log("mainloop"); |
︙ | ︙ |
Modified src/client.mm from [72369d5670] to [f8f6147037].
︙ | ︙ | |||
53 54 55 56 57 58 59 | return; assert(ENET_PEER_PACKET_THROTTLE_SCALE == 32); enet_peer_throttle_configure(clienthost->peers, throttle_interval * 1000, throttle_accel, throttle_decel); } void | | > | | | > > | > | | | | < | > | | | | | > | | < | > | | | | | | | | | > | 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 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 | return; assert(ENET_PEER_PACKET_THROTTLE_SCALE == 32); enet_peer_throttle_configure(clienthost->peers, throttle_interval * 1000, throttle_accel, throttle_decel); } void newname(OFString *name) { c2sinit = false; @autoreleasepool { strn0cpy(player1->name, name.UTF8String, 16); } } COMMANDN(name, newname, ARG_1STR) void newteam(OFString *name) { c2sinit = false; @autoreleasepool { strn0cpy(player1->team, name.UTF8String, 5); } } COMMANDN(team, newteam, ARG_1STR) void writeclientinfo(FILE *f) { fprintf(f, "name \"%s\"\nteam \"%s\"\n", player1->name, player1->team); } void connects(OFString *servername) { @autoreleasepool { disconnect(1); // reset state addserver(servername); conoutf(@"attempting to connect to %s", servername.UTF8String); ENetAddress address = {ENET_HOST_ANY, CUBE_SERVER_PORT}; if (enet_address_set_host(&address, servername.UTF8String) < 0) { conoutf(@"could not resolve server %s", servername); return; } clienthost = enet_host_create(NULL, 1, rate, rate); if (clienthost) { enet_host_connect(clienthost, &address, 1); enet_host_flush(clienthost); connecting = lastmillis; connattempts = 0; } else { conoutf(@"could not connect to server"); disconnect(); } } } void disconnect(int onlyclean, int async) { if (clienthost) { |
︙ | ︙ | |||
169 170 171 172 173 174 175 | echo(char *text) { conoutf(@"%s", text); } COMMAND(echo, ARG_VARI) COMMANDN(say, toserver, ARG_VARI) | | | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | echo(char *text) { conoutf(@"%s", text); } COMMAND(echo, ARG_VARI) COMMANDN(say, toserver, ARG_VARI) COMMANDN(connect, connects, ARG_1STR) COMMANDN(disconnect, trydisconnect, ARG_NONE) // collect c2s messages conveniently vector<ivector> messages; void |
︙ | ︙ | |||
214 215 216 217 218 219 220 | int lastupdate = 0, lastping = 0; OFString *toservermap; bool senditemstoserver = false; // after a map change, since server doesn't have map data string clientpassword; void | | > | | > | | | | 220 221 222 223 224 225 226 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 | int lastupdate = 0, lastping = 0; OFString *toservermap; bool senditemstoserver = false; // after a map change, since server doesn't have map data string clientpassword; void password(OFString *p) { @autoreleasepool { strcpy_s(clientpassword, p.UTF8String); } } COMMAND(password, ARG_1STR) bool netmapstart() { senditemstoserver = true; return clienthost != NULL; }; void initclientnet() { ctext[0] = 0; toservermap = @""; clientpassword[0] = 0; newname(@"unnamed"); newteam(@"red"); } void sendpackettoserv(void *packet) { if (clienthost) { enet_host_broadcast(clienthost, 0, (ENetPacket *)packet); |
︙ | ︙ |
Modified src/clientextras.mm from [d11e243f24] to [138c74a711].
︙ | ︙ | |||
9 10 11 12 13 14 15 | // D D D D' D D D D' A A' P P' I I' // R, R' E L J J' int frame[] = {178, 184, 190, 137, 183, 189, 197, 164, 46, 51, 54, 32, 0, 0, 40, 1, 162, 162, 67, 168}; int range[] = {6, 6, 8, 28, 1, 1, 1, 1, 8, 19, 4, 18, 40, 1, 6, 15, 1, 1, 1, 1}; void | | < > | 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 | // D D D D' D D D D' A A' P P' I I' // R, R' E L J J' int frame[] = {178, 184, 190, 137, 183, 189, 197, 164, 46, 51, 54, 32, 0, 0, 40, 1, 162, 162, 67, 168}; int range[] = {6, 6, 8, 28, 1, 1, 1, 1, 8, 19, 4, 18, 40, 1, 6, 15, 1, 1, 1, 1}; void renderclient(dynent *d, bool team, OFString *mdlname, bool hellpig, float scale) { int n = 3; float speed = 100.0f; float mz = d->o.z - d->eyeheight + 1.55f * scale; int basetime = -((intptr_t)d & 0xFFF); if (d->state == CS_DEAD) { int r; if (hellpig) { n = 2; r = range[3]; } else { n = (intptr_t)d % 3; r = range[n]; } basetime = d->lastaction; int t = lastmillis - d->lastaction; if (t < 0 || t > 20000) return; if (t > (r - 1) * 100) { n += 4; if (t > (r + 10) * 100) { |
︙ | ︙ | |||
57 58 59 60 61 62 63 | } else if (!d->onfloor && d->timeinair > 100) { n = 18; } else { n = 14; speed = 1200 / d->maxspeed * scale; if (hellpig) speed = 300 / d->maxspeed; | < > < > < > | | < > | 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 88 89 90 91 | } else if (!d->onfloor && d->timeinair > 100) { n = 18; } else { n = 14; speed = 1200 / d->maxspeed * scale; if (hellpig) speed = 300 / d->maxspeed; } if (hellpig) { n++; scale *= 32; mz -= 1.9f; } rendermodel(mdlname, frame[n], range[n], 0, 1.5f, d->o.x, mz, d->o.y, d->yaw + 90, d->pitch / 2, team, scale, speed, 0, basetime); } extern int democlientnum; void renderclients() { dynent *d; loopv(players) if ((d = players[i]) && (!demoplayback || i != democlientnum)) renderclient(d, isteam(player1->team, d->team), @"monster/ogro", false, 1.0f); } // creation of scoreboard pseudo-menu bool scoreson = false; void showscores(bool on) |
︙ | ︙ | |||
157 158 159 160 161 162 163 | menumanual(0, scorelines.length() + 1, teamscores); }; }; // sendmap/getmap commands, should be replaced by more intuitive map downloading void | | | | | | | > | | | | | 157 158 159 160 161 162 163 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 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | menumanual(0, scorelines.length() + 1, teamscores); }; }; // sendmap/getmap commands, should be replaced by more intuitive map downloading void sendmap(OFString *mapname) { @autoreleasepool { if (mapname.length > 0) save_world(mapname); changemap(mapname); mapname = getclientmap(); int mapsize; uchar *mapdata = readmap(mapname.UTF8String, &mapsize); if (!mapdata) return; ENetPacket *packet = enet_packet_create( NULL, MAXTRANS + mapsize, ENET_PACKET_FLAG_RELIABLE); uchar *start = packet->data; uchar *p = start + 2; putint(p, SV_SENDMAP); sendstring(mapname.UTF8String, p); putint(p, mapsize); if (65535 - (p - start) < mapsize) { conoutf( @"map %s is too large to send", mapname.UTF8String); free(mapdata); enet_packet_destroy(packet); return; }; memcpy(p, mapdata, mapsize); p += mapsize; free(mapdata); *(ushort *)start = ENET_HOST_TO_NET_16(p - start); enet_packet_resize(packet, p - start); sendpackettoserv(packet); conoutf(@"sending map %s to server...", mapname.UTF8String); sprintf_sd(msg)( "[map %s uploaded to server, \"getmap\" to receive it]", mapname.UTF8String); toserver(msg); } } void getmap() { ENetPacket *packet = enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE); uchar *start = packet->data; uchar *p = start + 2; 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) |
Modified src/clientgame.mm from [e35d803d58] to [7f736a9f83].
1 2 3 4 5 6 7 8 9 10 | // clientgame.cpp: core game related stuff #include "cube.h" int nextmode = 0; // nextmode becomes gamemode after next map load VAR(gamemode, 1, 0, 0); void mode(int n) { | > > | 1 2 3 4 5 6 7 8 9 10 11 12 | // clientgame.cpp: core game related stuff #include "cube.h" #include <memory> int nextmode = 0; // nextmode becomes gamemode after next map load VAR(gamemode, 1, 0, 0); void mode(int n) { |
︙ | ︙ | |||
227 228 229 230 231 232 233 | return; } // if we die in SP we try the same map again respawnself(); } } int sleepwait = 0; | | | | | < > > > > | < > > | 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 258 259 260 261 262 263 264 | return; } // if we die in SP we try the same map again respawnself(); } } int sleepwait = 0; static OFString *sleepcmd = nil; void sleepf(OFString *msec, OFString *cmd) { sleepwait = (int)msec.longLongValue + lastmillis; sleepcmd = cmd; } COMMANDN(sleep, sleepf, ARG_2STR) void updateworld(int millis) // main game update loop { if (lastmillis) { curtime = millis - lastmillis; if (sleepwait && lastmillis > sleepwait) { sleepwait = 0; @autoreleasepool { std::unique_ptr<char> cmd( strdup(sleepcmd.UTF8String)); execute(cmd.get()); } } physicsframe(); checkquad(curtime); if (m_arena) arenarespawn(); moveprojectiles((float)curtime); demoplaybackstep(); if (!demoplayback) { |
︙ | ︙ | |||
504 505 506 507 508 509 510 | loopv(players) if (players[i]) players[i]->frags = 0; resetspawns(); @autoreleasepool { clientmap = @(name); } if (editmode) toggleedit(); | | | | | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 | loopv(players) if (players[i]) players[i]->frags = 0; resetspawns(); @autoreleasepool { clientmap = @(name); } if (editmode) toggleedit(); setvar(@"gamespeed", 100); setvar(@"fog", 180); setvar(@"fogcolour", 0x8099B3); showscores(false); intermission = false; framesinmap = 0; conoutf(@"game mode is %s", modestr(gamemode)); } COMMANDN(map, changemap, ARG_1STR) |
Modified src/command.mm from [a0d92d1a92] to [ddbc7f66e7].
1 2 3 4 5 6 7 8 9 10 11 | // 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" enum { ID_VAR, ID_COMMAND, ID_ALIAS }; @interface Ident : OFObject @property (nonatomic) int type; // one of ID_* above @property (copy, nonatomic) OFString *name; @property (nonatomic) int min, max; // ID_VAR | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | // 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" #include <memory> enum { ID_VAR, ID_COMMAND, ID_ALIAS }; @interface Ident : OFObject @property (nonatomic) int type; // one of ID_* above @property (copy, nonatomic) OFString *name; @property (nonatomic) int min, max; // ID_VAR |
︙ | ︙ | |||
32 33 34 35 36 37 38 | return newstring(n); } // contains ALL vars/commands/aliases OFMutableDictionary<OFString *, Ident *> *idents; void | | < | | | | | | | | | | | | | | < | | < < | < | | | | | | | | | < | < | < | < | < | < | < | 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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | return newstring(n); } // contains ALL vars/commands/aliases OFMutableDictionary<OFString *, Ident *> *idents; void alias(OFString *name, OFString *action) { Ident *b = idents[name]; if (b == nil) { Ident *b = [[Ident alloc] init]; b.type = ID_ALIAS; b.name = name; b.action = action; b.persist = true; idents[b.name] = b; } else { if (b.type == ID_ALIAS) b.action = action; else conoutf( @"cannot redefine builtin %s with an alias", name.UTF8String); } } COMMAND(alias, ARG_2STR) int variable(OFString *name, int min, int cur, int max, int *storage, void (*fun)(), bool persist) { if (idents == nil) idents = [[OFMutableDictionary alloc] init]; Ident *v = [[Ident alloc] init]; v.type = ID_VAR; v.name = name; v.min = min; v.max = max; v.storage = storage; v.fun = fun; v.persist = persist; idents[name] = v; return cur; } void setvar(OFString *name, int i) { *idents[name].storage = i; } int getvar(OFString *name) { return *idents[name].storage; } bool identexists(OFString *name) { return (idents[name] != nil); } OFString * getalias(OFString *name) { Ident *i = idents[name]; return i != nil && i.type == ID_ALIAS ? i.action : nil; |
︙ | ︙ | |||
292 293 294 295 296 297 298 | ATOI(w[4])); break; case ARG_NONE: if (isdown) ((void(__cdecl *)()) ID.fun)(); break; | | | > | > > | | > > | > | > | > | > | > > | > | > | > > | > > | > > | > | > | | > > > | | > > > | > > | 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | ATOI(w[4])); break; case ARG_NONE: if (isdown) ((void(__cdecl *)()) ID.fun)(); break; case ARG_1STR: if (isdown) { @autoreleasepool { ((void( __cdecl *)( OFString *)) ID.fun)( @(w[1])); } } break; case ARG_2STR: if (isdown) { @autoreleasepool { ((void( __cdecl *)( OFString *, OFString *)) ID.fun)( @(w[1]), @(w[2])); } } break; case ARG_3STR: if (isdown) { @autoreleasepool { ((void( __cdecl *)( OFString *, OFString *, OFString *)) ID.fun)( @(w[1]), @(w[2]), @(w[3])); } } break; case ARG_5STR: if (isdown) { @autoreleasepool { ((void( __cdecl *)( OFString *, OFString *, OFString *, OFString *, OFString *)) ID.fun)( @(w[1]), @(w[2]), @(w[3]), @(w[4]), @(w[5])); } } break; case ARG_DOWN: ((void(__cdecl *)(bool))ID.fun)( isdown); break; case ARG_DWN1: ((void(__cdecl *)( |
︙ | ︙ | |||
379 380 381 382 383 384 385 | strcat_s( r, " "); } ((void(__cdecl *)( char *))ID.fun)(r); break; } | < < < < < < < < < < < | 398 399 400 401 402 403 404 405 406 407 408 409 410 411 | strcat_s( r, " "); } ((void(__cdecl *)( char *))ID.fun)(r); break; } } break; // game defined variables case ID_VAR: if (isdown) { if (!w[1][0]) |
︙ | ︙ | |||
475 476 477 478 479 480 481 | } break; // alias, also used as functions and (global) // variables case ID_ALIAS: for (int i = 1; i < numargs; i++) { | > | | > | > > | | > | 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 | } break; // alias, also used as functions and (global) // variables case ID_ALIAS: for (int i = 1; i < numargs; i++) { @autoreleasepool { // set any arguments as // (global) arg values // so functions can // access them OFString *t = [OFString stringWithFormat: @"arg%d", i]; alias(t, @(w[i])); } } // create new string here because alias // could rebind itself char *action = newstring(ID.action.UTF8String); val = execute(action, isdown); gp()->deallocstr(action); |
︙ | ︙ | |||
537 538 539 540 541 542 543 | }]; completeidx++; if (completeidx >= idx) completeidx = 0; } bool | | > | | | | | | | | | | > | | > | > > | 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 | }]; completeidx++; if (completeidx >= idx) completeidx = 0; } bool execfile(OFString *cfgfile) { @autoreleasepool { string s; strcpy_s(s, cfgfile.UTF8String); char *buf = loadfile(path(s), NULL); if (!buf) return false; execute(buf); free(buf); return true; } } void exec(OFString *cfgfile) { if (!execfile(cfgfile)) { @autoreleasepool { conoutf(@"could not read \"%s\"", cfgfile.UTF8String); } } } void writecfg() { FILE *f = fopen("config.cfg", "w"); if (!f) |
︙ | ︙ | |||
596 597 598 599 600 601 602 | COMMAND(writecfg, ARG_NONE) // below the commands that implement a small imperative language. thanks to the // semantics of // () and [] expressions, any control construct can be defined trivially. void | | < | | | | > | > > | | > | > > | > > > | | | | | | | | > | > > > > | | < > > > | > | 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 | COMMAND(writecfg, ARG_NONE) // below the commands that implement a small imperative language. thanks to the // semantics of // () and [] expressions, any control construct can be defined trivially. void intset(OFString *name, int v) { @autoreleasepool { alias(name, [OFString stringWithFormat:@"%d", v]); } } void ifthen(OFString *cond, OFString *thenp, OFString *elsep) { @autoreleasepool { std::unique_ptr<char> cmd(strdup( (cond.UTF8String[0] != '0' ? thenp : elsep).UTF8String)); execute(cmd.get()); } } void loopa(OFString *times, OFString *body_) { @autoreleasepool { int t = (int)times.longLongValue; std::unique_ptr<char> body(strdup(body_.UTF8String)); loopi(t) { intset(@"i", i); execute(body.get()); } } } void whilea(OFString *cond_, OFString *body_) { @autoreleasepool { std::unique_ptr<char> cond(strdup(cond_.UTF8String)); std::unique_ptr<char> body(strdup(body_.UTF8String)); while (execute(cond.get())) execute(body.get()); } } void onrelease(bool on, char *body) { if (!on) execute(body); } void concat(char *s) { @autoreleasepool { alias(@"s", @(s)); } } void concatword(char *s) { for (char *a = s, *b = s; *a = *b; b++) if (*a != ' ') |
︙ | ︙ | |||
662 663 664 665 666 667 668 | while (*a) if (*a++ == ' ') n++; return n + 1; } void | | > | > > > | | | > | | 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 | while (*a) if (*a++ == ' ') n++; return n + 1; } void at(OFString *s_, OFString *pos) { @autoreleasepool { int n = (int)pos.longLongValue; std::unique_ptr<char> copy(strdup(s_.UTF8String)); char *s = copy.get(); loopi(n) s += strspn(s += strcspn(s, " \0"), " "); s[strcspn(s, " \0")] = 0; concat(s); } } COMMANDN(loop, loopa, ARG_2STR) COMMANDN(while, whilea, ARG_2STR) COMMANDN(if, ifthen, ARG_3STR) COMMAND(onrelease, ARG_DWN1) COMMAND(exec, ARG_1STR) COMMAND(concat, ARG_VARI) COMMAND(concatword, ARG_VARI) COMMAND(at, ARG_2STR) COMMAND(listlen, ARG_1EST) int add(int a, int b) |
︙ | ︙ |
Modified src/console.mm from [e55e1dd6f3] to [dd3dab2434].
1 2 3 4 5 6 7 8 9 10 11 | // console.cpp: the console buffer, its display, and command line control #include "cube.h" #include <ctype.h> struct cline { char *cref; int outtime; }; vector<cline> conlines; | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | // console.cpp: the console buffer, its display, and command line control #include "cube.h" #include <ctype.h> #include <memory> struct cline { char *cref; int outtime; }; vector<cline> conlines; |
︙ | ︙ | |||
90 91 92 93 94 95 96 | int code; char *name; char *action; } keyms[256]; int numkm = 0; void | | > | | | > | > > | | | | | | < > | > < | > > | > | | | < | | 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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | int code; char *name; char *action; } keyms[256]; int numkm = 0; void keymap(OFString *code, OFString *key, OFString *action) { @autoreleasepool { keyms[numkm].code = (int)code.longLongValue; keyms[numkm].name = newstring(key.UTF8String); keyms[numkm++].action = newstringbuf(action.UTF8String); } } COMMAND(keymap, ARG_3STR) void bindkey(OFString *key_, OFString *action) { @autoreleasepool { std::unique_ptr<char> key(strdup(key_.UTF8String)); for (char *x = key.get(); *x; x++) *x = toupper(*x); loopi(numkm) if (strcmp(keyms[i].name, key.get()) == 0) { strcpy_s(keyms[i].action, action.UTF8String); return; } conoutf(@"unknown key \"%s\"", key.get()); } } COMMANDN(bind, bindkey, ARG_2STR) void saycommand(char *init) // turns input to the command line on or off { SDL_EnableUNICODE(saycommandon = (init != NULL)); if (!editmode) keyrepeat(saycommandon); if (!init) init = ""; strcpy_s(commandbuf, init); } COMMAND(saycommand, ARG_VARI) void mapmsg(OFString *s) { @autoreleasepool { strn0cpy(hdr.maptitle, s.UTF8String, 128); } } COMMAND(mapmsg, ARG_1STR) #ifndef _WIN32 # include <SDL_syswm.h> # include <X11/Xlib.h> #endif void |
︙ | ︙ |
Modified src/cube.h from [6a3965a96d] to [ea9ed1c660].
︙ | ︙ | |||
106 107 108 109 110 111 112 | float x, y, z; }; struct block { int x, y, xs, ys; }; struct mapmodelinfo { int rad, h, zoff, snap; | | | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | float x, y, z; }; struct block { int x, y, xs, ys; }; struct mapmodelinfo { int rad, h, zoff, snap; const char *name; }; enum { GUN_FIST = 0, GUN_SG, GUN_CG, GUN_RL, |
︙ | ︙ | |||
375 376 377 378 379 380 381 | enum // function signatures for script functions, see command.cpp { ARG_1INT, ARG_2INT, ARG_3INT, ARG_4INT, ARG_NONE, | | | < | | | | | | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 | enum // function signatures for script functions, see command.cpp { ARG_1INT, ARG_2INT, ARG_3INT, ARG_4INT, ARG_NONE, ARG_1STR, ARG_2STR, ARG_3STR, ARG_5STR, ARG_DOWN, ARG_DWN1, ARG_1EXP, ARG_2EXP, ARG_1EST, ARG_2EST, ARG_VARI }; // nasty macros for registering script functions, abuses globals to avoid // excessive infrastructure #define COMMANDN(name, fun, nargs) \ OF_CONSTRUCTOR() \ { \ enqueueInit(^{ \ addcommand(@ #name, (void (*)())fun, nargs); \ }); \ } #define COMMAND(name, nargs) COMMANDN(name, name, nargs) #define VARP(name, min, cur, max) \ int name; \ OF_CONSTRUCTOR() \ { \ enqueueInit(^{ \ name = variable( \ @ #name, min, cur, max, &name, NULL, true); \ }); \ } #define VAR(name, min, cur, max) \ int name; \ OF_CONSTRUCTOR() \ { \ enqueueInit(^{ \ name = variable( \ @ #name, min, cur, max, &name, NULL, false); \ }); \ } #define VARF(name, min, cur, max, body) \ void var_##name(); \ static int name; \ OF_CONSTRUCTOR() \ { \ enqueueInit(^{ \ name = variable( \ @ #name, min, cur, max, &name, var_##name, false); \ }); \ } \ void var_##name() { body; } #define VARFP(name, min, cur, max, body) \ void var_##name(); \ static int name; \ OF_CONSTRUCTOR() \ { \ enqueueInit(^{ \ name = variable( \ @ #name, min, cur, max, &name, var_##name, true); \ }); \ } \ void var_##name() { body; } #define ATOI(s) strtol(s, NULL, 0) // supports hexadecimal numbers #ifdef WIN32 |
︙ | ︙ |
Modified src/editing.mm from [90f4cefa84] to [3bf42210f7].
1 2 3 4 5 6 7 8 9 10 11 | // editing.cpp: most map editing commands go here, entity editing commands are // in world.cpp #include "cube.h" bool editmode = false; // the current selection, used by almost all editing commands // invariant: all code assumes that these are kept inside MINBORD distance of // the edge of the map | | > > > > > | | | | | > > | 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 | // editing.cpp: most map editing commands go here, entity editing commands are // in world.cpp #include "cube.h" bool editmode = false; // the current selection, used by almost all editing commands // invariant: all code assumes that these are kept inside MINBORD distance of // the edge of the map block sel; OF_CONSTRUCTOR() { enqueueInit(^{ sel = { variable(@"selx", 0, 0, 4096, &sel.x, NULL, false), variable(@"sely", 0, 0, 4096, &sel.y, NULL, false), variable(@"selxs", 0, 0, 4096, &sel.xs, NULL, false), variable(@"selys", 0, 0, 4096, &sel.ys, NULL, false), }; }); } int selh = 0; bool selset = false; #define loopselxy(b) \ { \ makeundo(); \ |
︙ | ︙ | |||
589 590 591 592 593 594 595 | edittag(int tag) { EDITSELMP; loopselxy(s->tag = tag); }; void | | > | < < > > > > | 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 | edittag(int tag) { EDITSELMP; loopselxy(s->tag = tag); }; void newent(OFString *what, OFString *a1, OFString *a2, OFString *a3, OFString *a4) { EDITSEL; @autoreleasepool { newentity(sel.x, sel.y, (int)player1->o.z, what, (int)a1.longLongValue, (int)a2.longLongValue, (int)a3.longLongValue, (int)a4.longLongValue); } } COMMANDN(select, selectpos, ARG_4INT) COMMAND(edittag, ARG_1INT) COMMAND(replace, ARG_NONE) COMMAND(archvertex, ARG_3INT) COMMAND(arch, ARG_2INT) COMMAND(slope, ARG_2INT) |
︙ | ︙ |
Modified src/entities.mm from [2a578e1163] to [22648f5295].
1 2 3 4 5 6 | // entities.cpp: map entity related functions (pickup etc.) #include "cube.h" vector<entity> ents; | | | | | | | | | | | | | > | | | > > | | > | 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 | // entities.cpp: map entity related functions (pickup etc.) #include "cube.h" vector<entity> ents; static OFString *entmdlnames[] = { @"shells", @"bullets", @"rockets", @"rrounds", @"health", @"boost", @"g_armour", @"y_armour", @"quad", @"teleporter", }; int triggertime = 0; 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, e.x, z + S(e.x, e.y)->floor, e.y, yaw, 0, false, 1.0f, speed, 0, basetime); }; void renderentities() { if (lastmillis > triggertime + 1000) triggertime = 0; loopv(ents) { entity &e = ents[i]; if (e.type == MAPMODEL) { mapmodelinfo *mmi = getmminfo(e.attr2); if (!mmi) continue; @autoreleasepool { rendermodel(@(mmi->name), 0, 1, e.attr4, (float)mmi->rad, e.x, (float)S(e.x, e.y)->floor + mmi->zoff + e.attr3, e.y, (float)((e.attr1 + 7) - (e.attr1 + 7) % 15), 0, false, 1.0f, 10.0f, mmi->snap); } } else { if (OUTBORD(e.x, e.y)) continue; if (e.type != CARROT) { if (!e.spawned && e.type != TELEPORT) continue; if (e.type < I_SHELLS || e.type > TELEPORT) |
︙ | ︙ | |||
63 64 65 66 67 68 69 | case 3: continue; case 2: case 0: if (!e.spawned) continue; | | | | | 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 96 97 98 | 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)); break; case 4: renderent(e, @"switch2", 3, (float)e.attr3 * 90, (!e.spawned && !triggertime) ? 1 : 0, (e.spawned || !triggertime) ? 1 : 2, triggertime, 1050.0f); break; case 5: renderent(e, @"switch1", -0.15f, (float)e.attr3 * 90, (!e.spawned && !triggertime) ? 30 : 0, (e.spawned || !triggertime) ? 1 : 30, triggertime, 35.0f); break; |
︙ | ︙ |
Modified src/menus.mm from [f8da5ecd7e] to [b007e3d965].
︙ | ︙ | |||
22 23 24 25 26 27 28 | void menuset(int menu) { if ((vmenu = menu) >= 1) resetmovement(player1); if (vmenu == 1) menus[1].menusel = 0; | < | > | > > | | | | < < > > > > | 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 | void menuset(int menu) { if ((vmenu = menu) >= 1) resetmovement(player1); if (vmenu == 1) menus[1].menusel = 0; } void showmenu(OFString *name_) { @autoreleasepool { const char *name = name_.UTF8String; loopv(menus) if (i > 1 && strcmp(menus[i].name, name) == 0) { menuset(i); return; } } } COMMAND(showmenu, ARG_1STR) int menucompare(mitem *a, mitem *b) { int x = atoi(a->text); int y = atoi(b->text); if (x > y) |
︙ | ︙ | |||
99 100 101 102 103 104 105 | draw_text(m.items[j].text, x, y, 2); y += step; }; return true; }; void | | > | | | < > > > | > | | | | > > < < < | 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 | draw_text(m.items[j].text, x, y, 2); y += step; }; return true; }; void newmenu(OFString *name) { @autoreleasepool { gmenu &menu = menus.add(); menu.name = newstring(name.UTF8String); menu.menusel = 0; } } COMMAND(newmenu, ARG_1STR) void menumanual(int m, int n, char *text) { if (!n) menus[m].items.setsize(0); mitem &mitem = menus[m].items.add(); mitem.text = text; mitem.action = ""; } void menuitem(OFString *text, OFString *action) { @autoreleasepool { gmenu &menu = menus.last(); mitem &mi = menu.items.add(); mi.text = newstring(text.UTF8String); mi.action = action.length > 0 ? newstring(action.UTF8String) : mi.text; } } COMMAND(menuitem, ARG_2STR) bool menukey(int code, bool isdown) { if (vmenu <= 0) return false; int menusel = menus[vmenu].menusel; if (isdown) { |
︙ | ︙ | |||
154 155 156 157 158 159 160 | menusel = n - 1; else if (menusel >= n) menusel = 0; menus[vmenu].menusel = menusel; } else { if (code == SDLK_RETURN || code == -2) { char *action = menus[vmenu].items[menusel].action; | | > | > > < < > > | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | menusel = n - 1; else if (menusel >= n) menusel = 0; menus[vmenu].menusel = menusel; } else { if (code == SDLK_RETURN || code == -2) { char *action = menus[vmenu].items[menusel].action; if (vmenu == 1) { @autoreleasepool { connects(@(getservername(menusel))); } } menustack.add(vmenu); menuset(-1); execute(action, true); } } return true; }; |
Modified src/monster.mm from [1a6c1928af] to [89afc85b2b].
︙ | ︙ | |||
22 23 24 25 26 27 28 | #define NUMMONSTERTYPES 8 struct monstertype // see docs for how these values modify behaviour { short gun, speed, health, freq, lag, rate, pain, loyalty, mscale, bscale; short painsound, diesound; | | | | | | | | | | | | < > | 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 | #define NUMMONSTERTYPES 8 struct monstertype // see docs for how these values modify behaviour { short gun, speed, health, freq, lag, rate, pain, loyalty, mscale, bscale; short painsound, diesound; OFConstantString *name, *mdlname; } monstertypes[NUMMONSTERTYPES] = { {GUN_FIREBALL, 15, 100, 3, 0, 100, 800, 1, 10, 10, S_PAINO, S_DIE1, @"an ogre", @"monster/ogro"}, {GUN_CG, 18, 70, 2, 70, 10, 400, 2, 8, 9, S_PAINR, S_DEATHR, @"a rhino", @"monster/rhino"}, {GUN_SG, 14, 120, 1, 100, 300, 400, 4, 14, 14, S_PAINE, S_DEATHE, @"ratamahatta", @"monster/rat"}, {GUN_RIFLE, 15, 200, 1, 80, 300, 300, 4, 18, 18, S_PAINS, S_DEATHS, @"a slith", @"monster/slith"}, {GUN_RL, 13, 500, 1, 0, 100, 200, 6, 24, 24, S_PAINB, S_DEATHB, @"bauul", @"monster/bauul"}, {GUN_BITE, 22, 50, 3, 0, 100, 400, 1, 12, 15, S_PAINP, S_PIGGR2, @"a hellpig", @"monster/hellpig"}, {GUN_ICEBALL, 12, 250, 1, 0, 10, 400, 6, 18, 18, S_PAINH, S_DEATHH, @"a knight", @"monster/knight"}, {GUN_SLIMEBALL, 15, 100, 1, 0, 200, 400, 2, 13, 10, S_PAIND, S_DEATHD, @"a goblin", @"monster/goblin"}, }; dynent * basicmonster(int type, int yaw, int state, int trigger, int move) { if (type >= NUMMONSTERTYPES) { conoutf(@"warning: unknown monster in spawn: %d", type); type = 0; } dynent *m = newdynent(); monstertype *t = &monstertypes[m->mtype = type]; m->eyeheight = 2.0f; m->aboveeye = 1.9f; m->radius *= t->bscale / 10.0f; m->eyeheight *= t->bscale / 10.0f; m->aboveeye *= t->bscale / 10.0f; |
︙ | ︙ | |||
74 75 76 77 78 79 80 | m->health = t->health; m->armour = 0; loopi(NUMGUNS) m->ammo[i] = 10000; m->pitch = 0; m->roll = 0; m->state = CS_ALIVE; m->anger = 0; | > | > | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | m->health = t->health; m->armour = 0; loopi(NUMGUNS) m->ammo[i] = 10000; m->pitch = 0; m->roll = 0; m->state = CS_ALIVE; m->anger = 0; @autoreleasepool { strcpy_s(m->name, t->name.UTF8String); } monsters.add(m); return m; }; void spawnmonster() // spawn a random monster according to freq distribution in DMSP { |
︙ | ︙ | |||
402 403 404 405 406 407 408 | void monsterrender() { loopv(monsters) renderclient(monsters[i], false, monstertypes[monsters[i]->mtype].mdlname, monsters[i]->mtype == 5, monstertypes[monsters[i]->mtype].mscale / 10.0f); | < > | 404 405 406 407 408 409 410 411 | void monsterrender() { loopv(monsters) renderclient(monsters[i], false, monstertypes[monsters[i]->mtype].mdlname, monsters[i]->mtype == 5, monstertypes[monsters[i]->mtype].mscale / 10.0f); } |
Modified src/protos.h from [caa998f8bf] to [e663cdaad7].
1 2 3 | // protos for ALL external functions in cube... // command | | | | | | | | | | | 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 | // protos for ALL external functions in cube... // command extern int variable(OFString *name, int min, int cur, int max, int *storage, void (*fun)(), bool persist); extern void setvar(OFString *name, int i); extern int getvar(OFString *name); extern bool identexists(OFString *name); extern bool addcommand(OFString *name, void (*fun)(), int narg); extern int execute(char *p, bool down = true); extern void exec(OFString *cfgfile); extern bool execfile(OFString *cfgfile); extern void resetcomplete(); extern void complete(char *s); extern void alias(OFString *name, OFString *action); extern OFString *getalias(OFString *name); extern void writecfg(); // console extern void keypress(int code, bool isdown, int cooked); extern void renderconsole(); extern void conoutf(OFString *s, ...); extern char *getcurcommand(); extern void writebinds(FILE *f); // init extern void enqueueInit(void (^init)(void)); extern void processInitQueue(void); // menus extern bool rendermenu(); extern void menuset(int menu); extern void menumanual(int m, int n, char *text); extern void sortmenu(int start, int num); extern bool menukey(int code, bool isdown); extern void newmenu(OFString *name); // serverbrowser extern void addserver(OFString *servername); extern char *getservername(int n); extern void writeservercfg(); // rendergl extern void gl_init(int w, int h); extern void cleangl(); extern void gl_drawframe(int w, int h, float curfps); |
︙ | ︙ | |||
66 67 68 69 70 71 72 | extern void addwaterquad(int x, int y, int size); extern int renderwater(float hf); extern void finishstrips(); extern void setarraypointers(); // client extern void localservertoclient(uchar *buf, int len); | | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | extern void addwaterquad(int x, int y, int size); extern int renderwater(float hf); extern void finishstrips(); extern void setarraypointers(); // client extern void localservertoclient(uchar *buf, int len); extern void connects(OFString *servername); extern void disconnect(int onlyclean = 0, int async = 0); extern void toserver(char *text); extern void addmsg(int rel, int num, int type, ...); extern bool multiplayer(); extern bool allowedittoggle(); extern void sendpackettoserv(void *packet); extern void gets2c(); |
︙ | ︙ | |||
102 103 104 105 106 107 108 | extern void timeupdate(int timeremain); extern void resetmovement(dynent *d); extern void fixplayer1range(); // clientextras extern void renderclients(); extern void renderclient( | | | | 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 | extern void timeupdate(int timeremain); extern void resetmovement(dynent *d); extern void fixplayer1range(); // clientextras extern void renderclients(); extern void renderclient( dynent *d, bool team, OFString *mdlname, bool hellpig, float scale); void showscores(bool on); 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(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(); 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( vec &vold, vec &v, int reach, int strength, dynent *owner); extern void cleardlights(); extern block *blockcopy(block &b); |
︙ | ︙ | |||
178 179 180 181 182 183 184 | // renderparticles extern void setorient(vec &r, vec &u); extern void particle_splash(int type, int num, int fade, vec &p); extern void particle_trail(int type, int fade, vec &from, vec &to); extern void render_particles(int time); // worldio | | | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | // renderparticles extern void setorient(vec &r, vec &u); extern void particle_splash(int type, int num, int fade, vec &p); extern void particle_trail(int type, int fade, vec &from, vec &to); extern void render_particles(int time); // worldio extern void save_world(OFString *fname); extern void load_world(char *mname); extern void writemap(char *mname, int msize, uchar *mdata); extern uchar *readmap(const char *mname, int *msize); extern void loadgamerest(); extern void incomingdemodata(uchar *buf, int len, bool extras = false); extern void demoplaybackstep(); extern void stop(); |
︙ | ︙ | |||
204 205 206 207 208 209 210 | // sound extern void playsound(int n, vec *loc = 0); extern void playsoundc(int n); extern void initsound(); extern void cleansound(); // rendermd2 | | | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | // sound extern void playsound(int n, vec *loc = 0); extern void playsoundc(int n); extern void initsound(); extern void cleansound(); // rendermd2 extern void rendermodel(OFString *mdl, int frame, int range, int tex, float rad, float x, float y, float z, float yaw, float pitch, bool teammate, float scale, float speed, int snap = 0, int basetime = 0); extern mapmodelinfo *getmminfo(int i); // server extern void initserver(bool dedicated, int uprate, const char *sdesc, const char *ip, const char *master, OFString *passwd, int maxcl); |
︙ | ︙ |
Modified src/renderextras.mm from [92e074465e] to [a7072e43d2].
︙ | ︙ | |||
143 144 145 146 147 148 149 | }; glDisable(GL_BLEND); glDepthMask(GL_TRUE); }; string closeent; | | | | | | | | | | | | | | | | | | | | | | | | | > > | | | > | < < | > > > | > | | | | | | | | > | | | < > | | > | | 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 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | }; glDisable(GL_BLEND); glDepthMask(GL_TRUE); }; string closeent; OFString *entnames[] = { @"none?", @"light", @"playerstart", @"shells", @"bullets", @"rockets", @"riflerounds", @"health", @"healthboost", @"greenarmour", @"yellowarmour", @"quaddamage", @"teleport", @"teledest", @"mapmodel", @"monster", @"trigger", @"jumppad", @"?", @"?", @"?", @"?", @"?", }; void renderents() // show sparkly thingies for map entities in edit mode { closeent[0] = 0; if (!editmode) return; loopv(ents) { entity &e = ents[i]; if (e.type == NOTUSED) continue; vec v = {(float)e.x, (float)e.y, (float)e.z}; particle_splash(2, 2, 40, v); }; int e = closestent(); if (e >= 0) { entity &c = ents[e]; @autoreleasepool { sprintf_s(closeent)( "closest entity = %s (%d, %d, %d, %d), " "selection = (%d, %d)", entnames[c.type].UTF8String, c.attr1, c.attr2, c.attr3, c.attr4, getvar(@"selxs"), getvar(@"selys")); } } } void loadsky(OFString *basename) { @autoreleasepool { static OFString *lastsky = @""; if ([lastsky isEqual:basename]) return; char *side[] = {"ft", "bk", "lf", "rt", "dn", "up"}; int texnum = 14; loopi(6) { sprintf_sd(name)( "packages/%s_%s.jpg", basename.UTF8String, side[i]); int xs, ys; if (!installtex(texnum + i, path(name), xs, ys, true)) conoutf(@"could not load sky textures"); } lastsky = basename; } } COMMAND(loadsky, ARG_1STR) float cursordepth = 0.9f; GLint viewport[4]; GLdouble mm[16], pm[16]; vec worldpos; void |
︙ | ︙ |
Modified src/rendergl.mm from [d502cbc841] to [6ee2ffc9ed].
︙ | ︙ | |||
146 147 148 149 150 151 152 | texturereset() { curtexnum = 0; } COMMAND(texturereset, ARG_NONE) void | | > | | | | | | | > | 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 | texturereset() { curtexnum = 0; } COMMAND(texturereset, ARG_NONE) void texture(OFString *aframe, OFString *name) { @autoreleasepool { int num = curtexnum++, frame = (int)aframe.longLongValue; if (num < 0 || num >= 256 || frame < 0 || frame >= MAXFRAMES) return; mapping[num][frame] = 1; char *n = mapname[num][frame]; strcpy_s(n, name.UTF8String); path(n); } } COMMAND(texture, ARG_2STR) int lookuptexture(int tex, int &xs, int &ys) { int frame = 0; // other frames? |
︙ | ︙ | |||
298 299 300 301 302 303 304 | int xtraverts; VAR(fog, 64, 180, 1024); VAR(fogcolour, 0, 0x8099B3, 0xFFFFFF); VARP(hudgun, 0, 1, 1); | | | < > | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | int xtraverts; VAR(fog, 64, 180, 1024); VAR(fogcolour, 0, 0x8099B3, 0xFFFFFF); VARP(hudgun, 0, 1, 1); OFString *hudgunnames[] = {@"hudguns/fist", @"hudguns/shotg", @"hudguns/chaing", @"hudguns/rocket", @"hudguns/rifle"}; void drawhudmodel(int start, int end, float speed, int base) { rendermodel(hudgunnames[player1->gunselect], start, end, 0, 1.0f, player1->o.x, player1->o.z, player1->o.y, player1->yaw + 90, player1->pitch, false, 1.0f, speed, 0, base); } void drawhudgun(float fovy, float aspect, int farplane) { if (!hudgun /*|| !player1->gunselect*/) return; |
︙ | ︙ |
Modified src/rendermd2.mm from [8c996c1951] to [567a64e197].
︙ | ︙ | |||
212 213 214 215 216 217 218 | sprintf_sd(name1)("packages/models/%s/tris.md2", m->loadname); if (!m->load(path(name1))) fatal("loadmodel: ", name1); sprintf_sd(name2)("packages/models/%s/skin.jpg", m->loadname); int xs, ys; installtex(FIRSTMDL + m->mdlnum, path(name2), xs, ys); m->loaded = true; | < < | > > | > | | | | | | | | | | | | < | > > | > | | | | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 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 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | sprintf_sd(name1)("packages/models/%s/tris.md2", m->loadname); if (!m->load(path(name1))) fatal("loadmodel: ", name1); sprintf_sd(name2)("packages/models/%s/skin.jpg", m->loadname); int xs, ys; installtex(FIRSTMDL + m->mdlnum, path(name2), xs, ys); m->loaded = true; } } int modelnum = 0; md2 * loadmodel(OFString *name) { @autoreleasepool { if (!mdllookup) mdllookup = new hashtable<md2 *>; md2 **mm = mdllookup->access(name.UTF8String); if (mm) return *mm; md2 *m = new md2(); m->mdlnum = modelnum++; mapmodelinfo mmi = {2, 2, 0, 0, ""}; m->mmi = mmi; m->loadname = newstring(name.UTF8String); mdllookup->access(m->loadname, &m); return m; } } void mapmodel( OFString *rad, OFString *h, OFString *zoff, OFString *snap, OFString *name) { md2 *m = loadmodel(name); mapmodelinfo mmi = {(int)rad.longLongValue, (int)h.longLongValue, (int)zoff.longLongValue, (int)snap.longLongValue, m->loadname}; m->mmi = mmi; mapmodels.add(m); } COMMAND(mapmodel, ARG_5STR) void mapmodelreset() { mapmodels.setsize(0); } COMMAND(mapmodelreset, ARG_NONE) mapmodelinfo * getmminfo(int i) { return i < mapmodels.length() ? &mapmodels[i]->mmi : NULL; } void rendermodel(OFString *mdl, int frame, int range, int tex, float rad, float x, float y, float z, float yaw, float pitch, bool teammate, float scale, float speed, int snap, int basetime) { md2 *m = loadmodel(mdl); if (isoccluded(player1->o.x, player1->o.y, x - rad, z - rad, rad * 2)) return; |
︙ | ︙ |
Modified src/savegamedemo.mm from [173411f8b2] to [8854cf5de9].
︙ | ︙ | |||
115 116 117 118 119 120 121 | { gzput(players[i] == NULL); gzwrite(f, players[i], sizeof(dynent)); } } void | | > | | | | | | | | | > | | 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 | { gzput(players[i] == NULL); gzwrite(f, players[i], sizeof(dynent)); } } void savegame(OFString *name) { @autoreleasepool { if (!m_classicsp) { conoutf(@"can only save classic sp games"); return; } sprintf_sd(fn)("savegames/%s.csgz", name.UTF8String); savestate(fn); stop(); conoutf(@"wrote %s", fn); } } COMMAND(savegame, ARG_1STR) void loadstate(char *fn) { stop(); if (multiplayer()) return; |
︙ | ︙ | |||
153 154 155 156 157 158 159 | // architectures simpifies things a LOT if (gzgeti() != SAVEGAMEVERSION || gzgeti() != sizeof(dynent)) goto out; string mapname; gzread(f, mapname, _MAXDEFSTR); nextmode = gzgeti(); @autoreleasepool { | < | | > | > | | | > | | 155 156 157 158 159 160 161 162 163 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 | // architectures simpifies things a LOT if (gzgeti() != SAVEGAMEVERSION || gzgeti() != sizeof(dynent)) goto out; string mapname; gzread(f, mapname, _MAXDEFSTR); nextmode = gzgeti(); @autoreleasepool { // continue below once map has been loaded and client & server // have updated changemap(@(mapname)); } return; out: conoutf(@"aborting: savegame/demo from a different version of cube or " @"cpu architecture"); stop(); } void loadgame(OFString *name) { @autoreleasepool { sprintf_sd(fn)("savegames/%s.csgz", name.UTF8String); loadstate(fn); } } COMMAND(loadgame, ARG_1STR) void loadgameout() { stop(); conoutf(@"loadgame incomplete: savegame from a different version of " @"this map"); |
︙ | ︙ | |||
239 240 241 242 243 244 245 | int starttime = 0; int playbacktime = 0; int ddamage, bdamage; vec dorig; void | | > | | | < > | | | | | | | | | | | > | | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | int starttime = 0; int playbacktime = 0; int ddamage, bdamage; vec dorig; void record(OFString *name) { @autoreleasepool { if (m_sp) { conoutf(@"cannot record singleplayer games"); return; } int cn = getclientnum(); if (cn < 0) return; sprintf_sd(fn)("demos/%s.cdgz", name.UTF8String); savestate(fn); gzputi(cn); conoutf(@"started recording demo to %s", fn); demorecording = true; starttime = lastmillis; ddamage = bdamage = 0; } } COMMAND(record, ARG_1STR) void demodamage(int damage, vec &o) { ddamage = damage; dorig = o; }; |
︙ | ︙ | |||
302 303 304 305 306 307 308 | } // FIXME: add all other client state which is not send through // the network } } void | | > | | | | > | | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | } // FIXME: add all other client state which is not send through // the network } } void demo(OFString *name) { @autoreleasepool { sprintf_sd(fn)("demos/%s.cdgz", name.UTF8String); loadstate(fn); demoloading = true; } } COMMAND(demo, ARG_1STR) void stopreset() { conoutf(@"demo stopped (%d msec elapsed)", lastmillis - starttime); stop(); loopv(players) zapdynent(players[i]); |
︙ | ︙ |
Modified src/serverbrowser.mm from [28e1977716] to [b2e734a52a].
︙ | ︙ | |||
143 144 145 146 147 148 149 | ENetSocket pingsock = ENET_SOCKET_NULL; int lastinfo = 0; char * getservername(int n) { return servers[n].name; | < | > | > > | > | | | | | | | | | | | | < > > | 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 172 173 174 175 176 177 178 179 | ENetSocket pingsock = ENET_SOCKET_NULL; int lastinfo = 0; char * getservername(int n) { return servers[n].name; } void addserver(OFString *servername_) { @autoreleasepool { const char *servername = servername_.UTF8String; loopv(servers) if (strcmp(servers[i].name, servername) == 0) return; serverinfo &si = servers.insert(0, serverinfo()); strcpy_s(si.name, servername); si.full[0] = 0; si.mode = 0; si.numplayers = 0; si.ping = 9999; si.protocol = 0; si.minremain = 0; si.map[0] = 0; si.sdesc[0] = 0; si.address.host = ENET_HOST_ANY; si.address.port = CUBE_SERVINFO_PORT; } } void pingservers() { ENetBuffer buf; uchar ping[MAXTRANS]; uchar *p; |
︙ | ︙ | |||
310 311 312 313 314 315 316 | else { servers.setsize(0); execute((char *)reply); }; servermenu(); } | | < > | 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | else { servers.setsize(0); execute((char *)reply); }; servermenu(); } COMMAND(addserver, ARG_1STR) COMMAND(servermenu, ARG_NONE) COMMAND(updatefrommaster, ARG_NONE) void writeservercfg() { FILE *f = fopen("servers.cfg", "w"); if (!f) return; fprintf(f, "// servers connected to are added here automatically\n\n"); loopvrev(servers) fprintf(f, "addserver %s\n", servers[i].name); fclose(f); } |
Modified src/sound.mm from [45fff0426a] to [143b0d78b9].
︙ | ︙ | |||
70 71 72 73 74 75 76 | Mix_AllocateChannels(MAXCHAN); #else if (FSOUND_GetVersion() < FMOD_VERSION) fatal("old FMOD dll"); if (!FSOUND_Init(SOUNDFREQ, MAXCHAN, FSOUND_INIT_GLOBALFOCUS)) { conoutf(@"sound init failed (FMOD): %d", FSOUND_GetError()); nosound = true; | < > < | > | > | | | | | | < > | | | | | > | | | | | < > | | < > < | | > | < | | 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 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 133 134 135 136 137 138 139 140 141 | Mix_AllocateChannels(MAXCHAN); #else if (FSOUND_GetVersion() < FMOD_VERSION) fatal("old FMOD dll"); if (!FSOUND_Init(SOUNDFREQ, MAXCHAN, FSOUND_INIT_GLOBALFOCUS)) { conoutf(@"sound init failed (FMOD): %d", FSOUND_GetError()); nosound = true; } #endif } void music(OFString *name) { if (nosound) return; stopsound(); if (soundvol && musicvol) { @autoreleasepool { string sn; strcpy_s(sn, "packages/"); strcat_s(sn, name.UTF8String); #ifdef USE_MIXER if (mod = Mix_LoadMUS(path(sn))) { Mix_PlayMusic(mod, -1); Mix_VolumeMusic((musicvol * MAXVOL) / 255); } #else if (mod = FMUSIC_LoadSong(path(sn))) { FMUSIC_PlaySong(mod); FMUSIC_SetMasterVolume(mod, musicvol); } else if (stream = FSOUND_Stream_Open( path(sn), FSOUND_LOOP_NORMAL, 0, 0)) { int chan = FSOUND_Stream_Play(FSOUND_FREE, stream); if (chan >= 0) { FSOUND_SetVolume( chan, (musicvol * MAXVOL) / 255); FSOUND_SetPaused(chan, false); } } else { conoutf(@"could not play music: %s", sn); } #endif } } } COMMAND(music, ARG_1STR) #ifdef USE_MIXER vector<Mix_Chunk *> samples; #else vector<FSOUND_SAMPLE *> samples; #endif cvector snames; int registersound(char *name) { loopv(snames) if (strcmp(snames[i], name) == 0) return i; snames.add(newstring(name)); samples.add(NULL); return samples.length() - 1; } COMMAND(registersound, ARG_1EST) void cleansound() { if (nosound) return; |
︙ | ︙ | |||
157 158 159 160 161 162 163 | vol -= (int)(dist * 3 * soundvol / 255); // simple mono distance attenuation if (stereo && (v.x != 0 || v.y != 0)) { float yaw = -atan2(v.x, v.y) - player1->yaw * (PI / 180.0f); // relative angle of // sound along X-Y axis | < < | | > | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | vol -= (int)(dist * 3 * soundvol / 255); // simple mono distance attenuation if (stereo && (v.x != 0 || v.y != 0)) { float yaw = -atan2(v.x, v.y) - player1->yaw * (PI / 180.0f); // relative angle of // sound along X-Y axis pan = int(255.9f * (0.5 * sin(yaw) + 0.5f)); // range is from 0 (left) // to 255 (right) }; }; vol = (vol * MAXVOL) / 255; #ifdef USE_MIXER Mix_Volume(chan, vol); Mix_SetPanning(chan, 255 - pan, pan); #else |
︙ | ︙ | |||
221 222 223 224 225 226 227 | return; if (lastmillis == lastsoundmillis) soundsatonce++; else soundsatonce = 1; lastsoundmillis = lastmillis; if (soundsatonce > 5) | | | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | return; if (lastmillis == lastsoundmillis) soundsatonce++; else soundsatonce = 1; lastsoundmillis = lastmillis; if (soundsatonce > 5) return; // avoid bursts of sounds with heavy packetloss // and in sp if (n < 0 || n >= samples.length()) { conoutf(@"unregistered sound: %d", n); return; }; if (!samples[n]) { sprintf_sd(buf)("packages/sounds/%s.wav", snames[n]); |
︙ | ︙ |
Modified src/tools.h from [2f2caef516] to [fe738f21a1].
︙ | ︙ | |||
316 317 318 319 320 321 322 | if (false) { \ } else \ for (int i = (v).length() - 1; i >= 0; i--) template <class T> struct hashtable { struct chain { chain *next; | | | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | if (false) { \ } else \ for (int i = (v).length() - 1; i >= 0; i--) template <class T> struct hashtable { struct chain { chain *next; const char *key; T data; }; int size; int numelems; chain **table; pool *parent; |
︙ | ︙ | |||
340 341 342 343 344 345 346 | table[i] = NULL; }; hashtable(hashtable<T> &v); void operator=(hashtable<T> &v); T * | | > | < < > > < > < > | 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | table[i] = NULL; }; hashtable(hashtable<T> &v); void operator=(hashtable<T> &v); T * access(const char *key, T *data = NULL) { unsigned int h = 5381; for (int i = 0, k; k = key[i]; i++) h = ((h << 5) + h) ^ k; // bernstein k=33 xor h = h & (size - 1); // primes not much of an advantage for (chain *c = table[h]; c; c = c->next) { char ch; for (const char *p1 = key, *p2 = c->key; (ch = *p1++) == *p2++;) if (!ch) // if(strcmp(key,c->key)==0) { T *d = &c->data; if (data) c->data = *data; return d; } } if (data) { chain *c = (chain *)parent->alloc(sizeof(chain)); c->data = *data; c->key = key; c->next = table[h]; table[h] = c; numelems++; } return NULL; } }; #define enumerate(ht, t, e, b) \ loopi(ht->size) for (ht->enumc = ht->table[i]; ht->enumc; \ ht->enumc = ht->enumc->next) \ { \ t e = &ht->enumc->data; \ |
︙ | ︙ |
Modified src/weapon.mm from [61c62f225e] to [d7fe676e8d].
︙ | ︙ | |||
56 57 58 59 60 61 62 | int reloadtime(int gun) { return guns[gun].attackdelay; }; void | | > > | | > | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | int reloadtime(int gun) { return guns[gun].attackdelay; }; void weapon(OFString *a1, OFString *a2, OFString *a3) { @autoreleasepool { selectgun(a1.UTF8String[0] ? atoi(a1.UTF8String) : -1, a2.UTF8String[0] ? atoi(a2.UTF8String) : -1, a3.UTF8String[0] ? atoi(a3.UTF8String) : -1); } } COMMAND(weapon, ARG_3STR) void createrays(vec &from, vec &to) // create random spread of rays for the shotgun { vdist(dist, dvec, from, to); |
︙ | ︙ |
Modified src/world.mm from [a8778ab451] to [da94b33242].
1 2 3 4 | // world.cpp: core map management stuff #include "cube.h" | > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // world.cpp: core map management stuff #include "cube.h" #include <memory> extern OFString *entnames[]; // lookup from map entities above to strings sqr *world = NULL; int sfactor, ssize, cubicsize, mipsize; header hdr; void |
︙ | ︙ | |||
54 55 56 57 58 59 60 61 62 63 | }; // set for playing void trigger(int tag, int type, bool savegame) { if (!tag) return; settag(tag, type); if (!savegame && type != 3) playsound(S_RUMBLE); | > > > > > | > | > | > > > | | 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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | }; // set for playing void trigger(int tag, int type, bool savegame) { if (!tag) return; settag(tag, type); if (!savegame && type != 3) playsound(S_RUMBLE); @autoreleasepool { OFString *aliasname = [OFString stringWithFormat:@"level_trigger_%d", tag]; if (identexists(aliasname)) { std::unique_ptr<char> cmd(strdup(aliasname.UTF8String)); execute(cmd.get()); } } if (type == 2) endsp(false); } COMMAND(trigger, ARG_2INT) // main geometric mipmapping routine, recursively rebuild mipmaps within block // b. tries to produce cube out of 4 lower level mips as well as possible, sets // 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) { 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; if (s.x & 1) { s.x--; |
︙ | ︙ | |||
292 293 294 295 296 297 298 | { int e = closestent(); if (e < 0) { conoutf(@"no more entities"); return; }; int t = ents[e].type; | > | > < | > | > | | | > | | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | { int e = closestent(); if (e < 0) { conoutf(@"no more entities"); return; }; int t = ents[e].type; @autoreleasepool { conoutf(@"%s entity deleted", entnames[t].UTF8String); } ents[e].type = NOTUSED; addmsg(1, 10, SV_EDITENT, e, NOTUSED, 0, 0, 0, 0, 0, 0, 0); if (t == LIGHT) calclight(); } int findtype(OFString *what) { @autoreleasepool { loopi(MAXENTTYPES) if ([what isEqual:entnames[i]]) return i; conoutf(@"unknown entity type \"%s\"", what.UTF8String); return NOTUSED; } } entity * newentity(int x, int y, int z, OFString *what, int v1, int v2, int v3, int v4) { int type = findtype(what); persistent_entity e = {(short)x, (short)y, (short)z, (short)v1, (uchar)type, (uchar)v2, (uchar)v3, (uchar)v4}; switch (type) { case LIGHT: if (v1 > 32) |
︙ | ︙ | |||
342 343 344 345 346 347 348 | ents.add(*((entity *)&e)); // unsafe! if (type == LIGHT) calclight(); return &ents.last(); }; void | | | | 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | ents.add(*((entity *)&e)); // unsafe! if (type == LIGHT) calclight(); return &ents.last(); }; void clearents(OFString *name) { int type = findtype(name); if (noteditmode() || multiplayer()) return; loopv(ents) { entity &e = ents[i]; if (e.type == type) e.type = NOTUSED; }; if (type == LIGHT) calclight(); } COMMAND(clearents, ARG_1STR) void scalecomp(uchar &c, int intens) { int n = c * intens / 100; if (n > 255) n = 255; |
︙ | ︙ |
Modified src/worldio.mm from [6ed752d022] to [4981361189].
1 2 3 4 5 6 7 8 9 | // worldio.cpp: loading & saving of maps and savegames #include "cube.h" void backup(char *name, char *backupname) { remove(backupname); rename(name, backupname); | < > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // worldio.cpp: loading & saving of maps and savegames #include "cube.h" void backup(char *name, char *backupname) { remove(backupname); rename(name, backupname); } string cgzname, bakname, pcfname, mcfname; static void setnames(const char *name) { string pakname, mapname; |
︙ | ︙ | |||
39 40 41 42 43 44 45 | // mipmapper to generate more efficient mips. the reason it is done on save is // to reduce the amount spend in the mipmapper (as that is done in realtime). inline bool nhf(sqr *s) { return s->type != FHF && s->type != CHF; | < > < < > > < > < > < < < < > > > > | < < < > > > > < > < > | | | | < > < < > > < > < > < < > > < > > < > < > < < > > < > < > < > < > < > < > < < > > < > > > | | | | < > > | > | | | | < | 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 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 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 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 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 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 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | // mipmapper to generate more efficient mips. the reason it is done on save is // to reduce the amount spend in the mipmapper (as that is done in realtime). inline bool nhf(sqr *s) { return s->type != FHF && s->type != CHF; } void voptimize() // reset vdeltas on non-hf cubes { loop(x, ssize) loop(y, ssize) { sqr *s = S(x, y); if (x && y) { if (nhf(s) && nhf(S(x - 1, y)) && nhf(S(x - 1, y - 1)) && nhf(S(x, y - 1))) s->vdelta = 0; } else s->vdelta = 0; } } void topt(sqr *s, bool &wf, bool &uf, int &wt, int &ut) { sqr *o[4]; o[0] = SWS(s, 0, -1, ssize); o[1] = SWS(s, 0, 1, ssize); o[2] = SWS(s, 1, 0, ssize); o[3] = SWS(s, -1, 0, ssize); wf = true; uf = true; if (SOLID(s)) { loopi(4) if (!SOLID(o[i])) { wf = false; wt = s->wtex; ut = s->utex; return; } } else { loopi(4) if (!SOLID(o[i])) { if (o[i]->floor < s->floor) { wt = s->wtex; wf = false; } if (o[i]->ceil > s->ceil) { ut = s->utex; uf = false; } } } } void toptimize() // FIXME: only does 2x2, make atleast for 4x4 also { bool wf[4], uf[4]; sqr *s[4]; for (int x = 2; x < ssize - 4; x += 2) { for (int y = 2; y < ssize - 4; y += 2) { s[0] = S(x, y); int wt = s[0]->wtex, ut = s[0]->utex; topt(s[0], wf[0], uf[0], wt, ut); topt(s[1] = SWS(s[0], 0, 1, ssize), wf[1], uf[1], wt, ut); topt(s[2] = SWS(s[0], 1, 1, ssize), wf[2], uf[2], wt, ut); topt(s[3] = SWS(s[0], 1, 0, ssize), wf[3], uf[3], wt, ut); loopi(4) { if (wf[i]) s[i]->wtex = wt; if (uf[i]) s[i]->utex = ut; } } } } // these two are used by getmap/sendmap.. transfers compressed maps directly void writemap(char *mname, int msize, uchar *mdata) { setnames(mname); backup(cgzname, bakname); FILE *f = fopen(cgzname, "wb"); if (!f) { conoutf(@"could not write map to %s", cgzname); return; } fwrite(mdata, 1, msize, f); fclose(f); conoutf(@"wrote map %s as file %s", mname, cgzname); } uchar * readmap(const char *mname, int *msize) { setnames(mname); uchar *mdata = (uchar *)loadfile(cgzname, msize); if (!mdata) { conoutf(@"could not read map %s", cgzname); return NULL; } return mdata; } // save map as .cgz file. uses 2 layers of compression: first does simple // run-length encoding and leaves out data for certain kinds of cubes, then zlib // removes the last bits of redundancy. Both passes contribute greatly to the // miniscule map sizes. void save_world(OFString *mname) { @autoreleasepool { resettagareas(); // wouldn't be able to reproduce tagged areas // otherwise voptimize(); toptimize(); if (mname.length == 0) mname = getclientmap(); setnames(mname.UTF8String); backup(cgzname, bakname); gzFile f = gzopen(cgzname, "wb9"); if (!f) { conoutf(@"could not write map to %s", cgzname); return; } hdr.version = MAPVERSION; hdr.numents = 0; loopv(ents) if (ents[i].type != NOTUSED) hdr.numents++; header tmp = hdr; endianswap(&tmp.version, sizeof(int), 4); endianswap(&tmp.waterlevel, sizeof(int), 16); gzwrite(f, &tmp, sizeof(header)); loopv(ents) { if (ents[i].type != NOTUSED) { entity tmp = ents[i]; endianswap(&tmp, sizeof(short), 4); gzwrite(f, &tmp, sizeof(persistent_entity)); } } sqr *t = NULL; int sc = 0; #define spurge \ while (sc) { \ gzputc(f, 255); \ if (sc > 255) { \ gzputc(f, 255); \ sc -= 255; \ } else { \ gzputc(f, sc); \ sc = 0; \ } \ } loopk(cubicsize) { sqr *s = &world[k]; #define c(f) (s->f == t->f) // 4 types of blocks, to compress a bit: // 255 (2): same as previous block + count // 254 (3): same as previous, except light // deprecated // SOLID (5) // anything else (9) if (SOLID(s)) { if (t && c(type) && c(wtex) && c(vdelta)) { sc++; } else { spurge; gzputc(f, s->type); gzputc(f, s->wtex); gzputc(f, s->vdelta); } } else { if (t && c(type) && c(floor) && c(ceil) && c(ctex) && c(ftex) && c(utex) && c(wtex) && c(vdelta) && c(tag)) { sc++; } else { spurge; gzputc(f, s->type); gzputc(f, s->floor); gzputc(f, s->ceil); gzputc(f, s->wtex); gzputc(f, s->ftex); gzputc(f, s->ctex); gzputc(f, s->vdelta); gzputc(f, s->utex); gzputc(f, s->tag); } } t = s; } spurge; gzclose(f); conoutf(@"wrote map file %s", cgzname); settagareas(); } } COMMANDN(savemap, save_world, ARG_1STR) void load_world(char *mname) // still supports all map formats that have existed // since the earliest cube betas! { stopifrecording(); cleardlights(); pruneundos(); setnames(mname); gzFile f = gzopen(cgzname, "rb9"); if (!f) { conoutf(@"could not read map %s", cgzname); return; } gzread(f, &hdr, sizeof(header) - sizeof(int) * 16); endianswap(&hdr.version, sizeof(int), 4); if (strncmp(hdr.head, "CUBE", 4) != 0) fatal("while reading map: header malformatted"); if (hdr.version > MAPVERSION) fatal("this map requires a newer version of cube"); if (sfactor < SMALLEST_FACTOR || sfactor > LARGEST_FACTOR) fatal("illegal map size"); if (hdr.version >= 4) { gzread(f, &hdr.waterlevel, sizeof(int) * 16); endianswap(&hdr.waterlevel, sizeof(int), 16); } else { hdr.waterlevel = -100000; } ents.setsize(0); loopi(hdr.numents) { entity &e = ents.add(); gzread(f, &e, sizeof(persistent_entity)); endianswap(&e, sizeof(short), 4); e.spawned = false; if (e.type == LIGHT) { if (!e.attr2) e.attr2 = 255; // needed for MAPVERSION<=2 if (e.attr1 > 32) e.attr1 = 32; // 12_03 and below } } free(world); setupworld(hdr.sfactor); char texuse[256]; loopi(256) texuse[i] = 0; sqr *t = NULL; loopk(cubicsize) { sqr *s = &world[k]; int type = gzgetc(f); switch (type) { case 255: { int n = gzgetc(f); for (int i = 0; i < n; i++, k++) memcpy(&world[k], t, sizeof(sqr)); k--; break; } case 254: // only in MAPVERSION<=2 { memcpy(s, t, sizeof(sqr)); s->r = s->g = s->b = gzgetc(f); gzgetc(f); break; } case SOLID: { s->type = SOLID; s->wtex = gzgetc(f); s->vdelta = gzgetc(f); if (hdr.version <= 2) { gzgetc(f); gzgetc(f); } s->ftex = DEFAULT_FLOOR; s->ctex = DEFAULT_CEIL; s->utex = s->wtex; s->tag = 0; s->floor = 0; s->ceil = 16; break; } default: { if (type < 0 || type >= MAXTYPE) { sprintf_sd(t)("%d @ %d", type, k); fatal("while reading map: type out of range: ", t); } s->type = type; s->floor = gzgetc(f); s->ceil = gzgetc(f); if (s->floor >= s->ceil) s->floor = s->ceil - 1; // for pre 12_13 s->wtex = gzgetc(f); s->ftex = gzgetc(f); s->ctex = gzgetc(f); if (hdr.version <= 2) { gzgetc(f); gzgetc(f); } s->vdelta = gzgetc(f); s->utex = (hdr.version >= 2) ? gzgetc(f) : s->wtex; s->tag = (hdr.version >= 5) ? gzgetc(f) : 0; s->type = type; } } s->defer = 0; t = s; texuse[s->wtex] = 1; if (!SOLID(s)) texuse[s->utex] = texuse[s->ftex] = texuse[s->ctex] = 1; } gzclose(f); calclight(); settagareas(); int xs, ys; loopi(256) if (texuse) lookuptexture(i, xs, ys); conoutf(@"read map %s (%d milliseconds)", cgzname, SDL_GetTicks() - lastmillis); conoutf(@"%s", hdr.maptitle); startmap(mname); loopl(256) { @autoreleasepool { // can this be done smarter? OFString *aliasname = [OFString stringWithFormat:@"level_trigger_%d", l]; if (identexists(aliasname)) alias(aliasname, @""); } } execfile(@"data/default_map_settings.cfg"); @autoreleasepool { execfile(@(pcfname)); execfile(@(mcfname)); } } |
Modified src/worldlight.mm from [73836e692f] to [ae7e6c7975].
︙ | ︙ | |||
167 168 169 170 171 172 173 | void calclight() { loop(x, ssize) loop(y, ssize) { sqr *s = S(x, y); s->r = s->g = s->b = 10; | < > < > | < > < < > > | 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 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | void calclight() { loop(x, ssize) loop(y, ssize) { sqr *s = S(x, y); s->r = s->g = s->b = 10; } loopv(ents) { entity &e = ents[i]; if (e.type == LIGHT) calclightsource(e); } block b = {1, 1, ssize - 2, ssize - 2}; postlightarea(b); setvar(@"fullbright", 0); } VARP(dynlight, 0, 16, 32); vector<block *> dlights; void cleardlights() { while (!dlights.empty()) { block *backup = dlights.pop(); blockpaste(*backup); free(backup); } } void dodynlight(vec &vold, vec &v, int reach, int strength, dynent *owner) { if (!reach) reach = dynlight; if (owner->monsterstate) |
︙ | ︙ | |||
226 227 228 229 230 231 232 | dlights.add(blockcopy(b)); // backup area before rendering in dynlight persistent_entity l = {(short)v.x, (short)v.y, (short)v.z, (short)reach, LIGHT, (uchar)strength, 0, 0}; calclightsource(l); postlightarea(b); | < > < > < > | 226 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 | dlights.add(blockcopy(b)); // backup area before rendering in dynlight persistent_entity l = {(short)v.x, (short)v.y, (short)v.z, (short)reach, LIGHT, (uchar)strength, 0, 0}; calclightsource(l); postlightarea(b); } // utility functions also used by editing code block * blockcopy(block &s) { block *b = (block *)alloc(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++) *q++ = *S(x, y); return b; } void blockpaste(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++) *S(x, y) = *q++; remipmore(b); } |
Modified src/worldocull.mm from [70fd16d6e2] to [8bad2cc9f5].
︙ | ︙ | |||
20 21 22 23 24 25 26 | void computeraytable(float vx, float vy) { if (!ocull) return; | | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | void computeraytable(float vx, float vy) { if (!ocull) return; odist = getvar(@"fog") * 1.5f; float apitch = (float)fabs(player1->pitch); float af = getvar(@"fov") / 2 + apitch / 1.5f + 3; float byaw = (player1->yaw - 90 + af) / 360 * PI2; float syaw = (player1->yaw - 90 - af) / 360 * PI2; loopi(NUMRAYS) { float angle = i * PI2 / NUMRAYS; if ((apitch > 45 // must be bigger if fov>120 |
︙ | ︙ |