Migrate more strings
FossilOrigin-Name: 0d125c31daf305a4363234402dbf375ecd71b24da762aa8e8c59751678cf47ec
This commit is contained in:
parent
ce5944a7b1
commit
b00de734e8
25 changed files with 476 additions and 439 deletions
|
@ -85,8 +85,8 @@ screenshot()
|
|||
};
|
||||
}
|
||||
|
||||
COMMAND(screenshot, ARG_NONE);
|
||||
COMMAND(quit, ARG_NONE);
|
||||
COMMAND(screenshot, ARG_NONE)
|
||||
COMMAND(quit, ARG_NONE)
|
||||
|
||||
void
|
||||
keyrepeat(bool on)
|
||||
|
@ -215,8 +215,8 @@ int framesinmap = 0;
|
|||
|
||||
log("localconnect");
|
||||
localconnect();
|
||||
changemap(
|
||||
"metl3"); // if this map is changed, also change depthcorrect()
|
||||
// if this map is changed, also change depthcorrect()
|
||||
changemap(@"metl3");
|
||||
|
||||
log("mainloop");
|
||||
int ignore = 5;
|
||||
|
|
201
src/client.mm
201
src/client.mm
|
@ -70,8 +70,8 @@ newteam(char *name)
|
|||
strn0cpy(player1->team, name, 5);
|
||||
}
|
||||
|
||||
COMMANDN(team, newteam, ARG_1STR);
|
||||
COMMANDN(name, newname, ARG_1STR);
|
||||
COMMANDN(team, newteam, ARG_1CSTR)
|
||||
COMMANDN(name, newname, ARG_1CSTR)
|
||||
|
||||
void
|
||||
writeclientinfo(FILE *f)
|
||||
|
@ -171,10 +171,10 @@ 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);
|
||||
COMMAND(echo, ARG_VARI)
|
||||
COMMANDN(say, toserver, ARG_VARI)
|
||||
COMMANDN(connect, connects, ARG_1CSTR)
|
||||
COMMANDN(disconnect, trydisconnect, ARG_NONE)
|
||||
|
||||
// collect c2s messages conveniently
|
||||
|
||||
|
@ -212,7 +212,7 @@ server_err()
|
|||
}
|
||||
|
||||
int lastupdate = 0, lastping = 0;
|
||||
string toservermap;
|
||||
OFString *toservermap;
|
||||
bool senditemstoserver =
|
||||
false; // after a map change, since server doesn't have map data
|
||||
|
||||
|
@ -221,8 +221,8 @@ void
|
|||
password(char *p)
|
||||
{
|
||||
strcpy_s(clientpassword, p);
|
||||
};
|
||||
COMMAND(password, ARG_1STR);
|
||||
}
|
||||
COMMAND(password, ARG_1CSTR)
|
||||
|
||||
bool
|
||||
netmapstart()
|
||||
|
@ -235,11 +235,11 @@ void
|
|||
initclientnet()
|
||||
{
|
||||
ctext[0] = 0;
|
||||
toservermap[0] = 0;
|
||||
toservermap = @"";
|
||||
clientpassword[0] = 0;
|
||||
newname("unnamed");
|
||||
newteam("red");
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
sendpackettoserv(void *packet)
|
||||
|
@ -254,94 +254,103 @@ sendpackettoserv(void *packet)
|
|||
void
|
||||
c2sinfo(dynent *d) // send update to the server
|
||||
{
|
||||
if (clientnum < 0)
|
||||
return; // we haven't had a welcome message from the server yet
|
||||
if (lastmillis - lastupdate < 40)
|
||||
return; // don't update faster than 25fps
|
||||
ENetPacket *packet = enet_packet_create(NULL, MAXTRANS, 0);
|
||||
uchar *start = packet->data;
|
||||
uchar *p = start + 2;
|
||||
bool serveriteminitdone = false;
|
||||
if (toservermap[0]) // suggest server to change map
|
||||
{ // do this exclusively as map change may invalidate rest of update
|
||||
packet->flags = ENET_PACKET_FLAG_RELIABLE;
|
||||
putint(p, SV_MAPCHANGE);
|
||||
sendstring(toservermap, p);
|
||||
toservermap[0] = 0;
|
||||
putint(p, nextmode);
|
||||
} else {
|
||||
putint(p, SV_POS);
|
||||
putint(p, clientnum);
|
||||
putint(
|
||||
p, (int)(d->o.x * DMF)); // quantize coordinates to 1/16th
|
||||
// of a cube, between 1 and 3 bytes
|
||||
putint(p, (int)(d->o.y * DMF));
|
||||
putint(p, (int)(d->o.z * DMF));
|
||||
putint(p, (int)(d->yaw * DAF));
|
||||
putint(p, (int)(d->pitch * DAF));
|
||||
putint(p, (int)(d->roll * DAF));
|
||||
putint(
|
||||
p, (int)(d->vel.x *
|
||||
DVF)); // quantize to 1/100, almost always 1 byte
|
||||
putint(p, (int)(d->vel.y * DVF));
|
||||
putint(p, (int)(d->vel.z * DVF));
|
||||
// pack rest in 1 byte: strafe:2, move:2, onfloor:1, state:3
|
||||
putint(p, (d->strafe & 3) | ((d->move & 3) << 2) |
|
||||
(((int)d->onfloor) << 4) |
|
||||
((editmode ? CS_EDITING : d->state) << 5));
|
||||
@autoreleasepool {
|
||||
if (clientnum < 0)
|
||||
return; // we haven't had a welcome message from the
|
||||
// server yet
|
||||
if (lastmillis - lastupdate < 40)
|
||||
return; // don't update faster than 25fps
|
||||
ENetPacket *packet = enet_packet_create(NULL, MAXTRANS, 0);
|
||||
uchar *start = packet->data;
|
||||
uchar *p = start + 2;
|
||||
bool serveriteminitdone = false;
|
||||
if (toservermap.length > 0) // suggest server to change map
|
||||
{ // do this exclusively as map change may invalidate rest of
|
||||
// update
|
||||
packet->flags = ENET_PACKET_FLAG_RELIABLE;
|
||||
putint(p, SV_MAPCHANGE);
|
||||
sendstring(toservermap.UTF8String, p);
|
||||
toservermap = @"";
|
||||
putint(p, nextmode);
|
||||
} else {
|
||||
putint(p, SV_POS);
|
||||
putint(p, clientnum);
|
||||
putint(
|
||||
p, (int)(d->o.x *
|
||||
DMF)); // quantize coordinates to 1/16th
|
||||
// of a cube, between 1 and 3 bytes
|
||||
putint(p, (int)(d->o.y * DMF));
|
||||
putint(p, (int)(d->o.z * DMF));
|
||||
putint(p, (int)(d->yaw * DAF));
|
||||
putint(p, (int)(d->pitch * DAF));
|
||||
putint(p, (int)(d->roll * DAF));
|
||||
putint(
|
||||
p, (int)(d->vel.x * DVF)); // quantize to 1/100,
|
||||
// almost always 1 byte
|
||||
putint(p, (int)(d->vel.y * DVF));
|
||||
putint(p, (int)(d->vel.z * DVF));
|
||||
// pack rest in 1 byte: strafe:2, move:2, onfloor:1,
|
||||
// state:3
|
||||
putint(
|
||||
p, (d->strafe & 3) | ((d->move & 3) << 2) |
|
||||
(((int)d->onfloor) << 4) |
|
||||
((editmode ? CS_EDITING : d->state) << 5));
|
||||
|
||||
if (senditemstoserver) {
|
||||
packet->flags = ENET_PACKET_FLAG_RELIABLE;
|
||||
putint(p, SV_ITEMLIST);
|
||||
if (!m_noitems)
|
||||
putitems(p);
|
||||
putint(p, -1);
|
||||
senditemstoserver = false;
|
||||
serveriteminitdone = true;
|
||||
};
|
||||
if (ctext[0]) // player chat, not flood protected for now
|
||||
{
|
||||
packet->flags = ENET_PACKET_FLAG_RELIABLE;
|
||||
putint(p, SV_TEXT);
|
||||
sendstring(ctext, p);
|
||||
ctext[0] = 0;
|
||||
};
|
||||
if (!c2sinit) // tell other clients who I am
|
||||
{
|
||||
packet->flags = ENET_PACKET_FLAG_RELIABLE;
|
||||
c2sinit = true;
|
||||
putint(p, SV_INITC2S);
|
||||
sendstring(player1->name, p);
|
||||
sendstring(player1->team, p);
|
||||
putint(p, player1->lifesequence);
|
||||
};
|
||||
loopv(messages) // send messages collected during the previous
|
||||
// frames
|
||||
{
|
||||
ivector &msg = messages[i];
|
||||
if (msg[1])
|
||||
if (senditemstoserver) {
|
||||
packet->flags = ENET_PACKET_FLAG_RELIABLE;
|
||||
loopi(msg[0]) putint(p, msg[i + 2]);
|
||||
putint(p, SV_ITEMLIST);
|
||||
if (!m_noitems)
|
||||
putitems(p);
|
||||
putint(p, -1);
|
||||
senditemstoserver = false;
|
||||
serveriteminitdone = true;
|
||||
};
|
||||
if (ctext[0]) // player chat, not flood protected for
|
||||
// now
|
||||
{
|
||||
packet->flags = ENET_PACKET_FLAG_RELIABLE;
|
||||
putint(p, SV_TEXT);
|
||||
sendstring(ctext, p);
|
||||
ctext[0] = 0;
|
||||
};
|
||||
if (!c2sinit) // tell other clients who I am
|
||||
{
|
||||
packet->flags = ENET_PACKET_FLAG_RELIABLE;
|
||||
c2sinit = true;
|
||||
putint(p, SV_INITC2S);
|
||||
sendstring(player1->name, p);
|
||||
sendstring(player1->team, p);
|
||||
putint(p, player1->lifesequence);
|
||||
};
|
||||
loopv(messages) // send messages collected during the
|
||||
// previous frames
|
||||
{
|
||||
ivector &msg = messages[i];
|
||||
if (msg[1])
|
||||
packet->flags =
|
||||
ENET_PACKET_FLAG_RELIABLE;
|
||||
loopi(msg[0]) putint(p, msg[i + 2]);
|
||||
};
|
||||
messages.setsize(0);
|
||||
if (lastmillis - lastping > 250) {
|
||||
putint(p, SV_PING);
|
||||
putint(p, lastmillis);
|
||||
lastping = lastmillis;
|
||||
};
|
||||
};
|
||||
messages.setsize(0);
|
||||
if (lastmillis - lastping > 250) {
|
||||
putint(p, SV_PING);
|
||||
putint(p, lastmillis);
|
||||
lastping = lastmillis;
|
||||
};
|
||||
};
|
||||
*(ushort *)start = ENET_HOST_TO_NET_16(p - start);
|
||||
enet_packet_resize(packet, p - start);
|
||||
incomingdemodata(start, p - start, true);
|
||||
if (clienthost) {
|
||||
enet_host_broadcast(clienthost, 0, packet);
|
||||
enet_host_flush(clienthost);
|
||||
} else
|
||||
localclienttoserver(packet);
|
||||
lastupdate = lastmillis;
|
||||
if (serveriteminitdone)
|
||||
loadgamerest(); // hack
|
||||
};
|
||||
*(ushort *)start = ENET_HOST_TO_NET_16(p - start);
|
||||
enet_packet_resize(packet, p - start);
|
||||
incomingdemodata(start, p - start, true);
|
||||
if (clienthost) {
|
||||
enet_host_broadcast(clienthost, 0, packet);
|
||||
enet_host_flush(clienthost);
|
||||
} else
|
||||
localclienttoserver(packet);
|
||||
lastupdate = lastmillis;
|
||||
if (serveriteminitdone)
|
||||
loadgamerest(); // hack
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gets2c() // get updates from the server
|
||||
|
|
|
@ -161,39 +161,42 @@ renderscores()
|
|||
// sendmap/getmap commands, should be replaced by more intuitive map downloading
|
||||
|
||||
void
|
||||
sendmap(char *mapname)
|
||||
sendmap(const char *mapname)
|
||||
{
|
||||
if (*mapname)
|
||||
save_world(mapname);
|
||||
changemap(mapname);
|
||||
mapname = getclientmap();
|
||||
int mapsize;
|
||||
uchar *mapdata = readmap(mapname, &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, p);
|
||||
putint(p, mapsize);
|
||||
if (65535 - (p - start) < mapsize) {
|
||||
conoutf(@"map %s is too large to send", mapname);
|
||||
@autoreleasepool {
|
||||
if (*mapname)
|
||||
save_world(mapname);
|
||||
changemap(@(mapname));
|
||||
mapname = getclientmap().UTF8String;
|
||||
int mapsize;
|
||||
uchar *mapdata = readmap(mapname, &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, p);
|
||||
putint(p, mapsize);
|
||||
if (65535 - (p - start) < mapsize) {
|
||||
conoutf(@"map %s is too large to send", mapname);
|
||||
free(mapdata);
|
||||
enet_packet_destroy(packet);
|
||||
return;
|
||||
};
|
||||
memcpy(p, mapdata, mapsize);
|
||||
p += mapsize;
|
||||
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);
|
||||
sprintf_sd(msg)(
|
||||
"[map %s uploaded to server, \"getmap\" to receive it]", mapname);
|
||||
toserver(msg);
|
||||
*(ushort *)start = ENET_HOST_TO_NET_16(p - start);
|
||||
enet_packet_resize(packet, p - start);
|
||||
sendpackettoserv(packet);
|
||||
conoutf(@"sending map %s to server...", mapname);
|
||||
sprintf_sd(msg)(
|
||||
"[map %s uploaded to server, \"getmap\" to receive it]",
|
||||
mapname);
|
||||
toserver(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -210,5 +213,5 @@ getmap()
|
|||
conoutf(@"requesting map from server...");
|
||||
}
|
||||
|
||||
COMMAND(sendmap, ARG_1STR);
|
||||
COMMAND(getmap, ARG_NONE);
|
||||
COMMAND(sendmap, ARG_1CSTR)
|
||||
COMMAND(getmap, ARG_NONE)
|
||||
|
|
|
@ -10,7 +10,7 @@ mode(int n)
|
|||
{
|
||||
addmsg(1, 2, SV_GAMEMODE, nextmode = n);
|
||||
};
|
||||
COMMAND(mode, ARG_1INT);
|
||||
COMMAND(mode, ARG_1INT)
|
||||
|
||||
bool intermission = false;
|
||||
|
||||
|
@ -23,15 +23,15 @@ VARP(invmouse, 0, 0, 1);
|
|||
|
||||
int lastmillis = 0;
|
||||
int curtime = 10;
|
||||
string clientmap;
|
||||
OFString *clientmap;
|
||||
|
||||
extern int framesinmap;
|
||||
|
||||
char *
|
||||
OFString *
|
||||
getclientmap()
|
||||
{
|
||||
return clientmap;
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
resetmovement(dynent *d)
|
||||
|
@ -220,15 +220,15 @@ respawn()
|
|||
if (m_arena) {
|
||||
conoutf(@"waiting for new round to start...");
|
||||
return;
|
||||
};
|
||||
}
|
||||
if (m_sp) {
|
||||
nextmode = gamemode;
|
||||
changemap(clientmap);
|
||||
return;
|
||||
}; // if we die in SP we try the same map again
|
||||
} // if we die in SP we try the same map again
|
||||
respawnself();
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
int sleepwait = 0;
|
||||
string sleepcmd;
|
||||
|
@ -238,7 +238,7 @@ sleepf(char *msec, char *cmd)
|
|||
sleepwait = atoi(msec) + lastmillis;
|
||||
strcpy_s(sleepcmd, cmd);
|
||||
};
|
||||
COMMANDN(sleep, sleepf, ARG_2STR);
|
||||
COMMANDN(sleep, sleepf, ARG_2STR)
|
||||
|
||||
void
|
||||
updateworld(int millis) // main game update loop
|
||||
|
@ -361,13 +361,13 @@ jumpn(bool on)
|
|||
respawn();
|
||||
};
|
||||
|
||||
COMMAND(backward, ARG_DOWN);
|
||||
COMMAND(forward, ARG_DOWN);
|
||||
COMMAND(left, ARG_DOWN);
|
||||
COMMAND(right, ARG_DOWN);
|
||||
COMMANDN(jump, jumpn, ARG_DOWN);
|
||||
COMMAND(attack, ARG_DOWN);
|
||||
COMMAND(showscores, ARG_DOWN);
|
||||
COMMAND(backward, ARG_DOWN)
|
||||
COMMAND(forward, ARG_DOWN)
|
||||
COMMAND(left, ARG_DOWN)
|
||||
COMMAND(right, ARG_DOWN)
|
||||
COMMANDN(jump, jumpn, ARG_DOWN)
|
||||
COMMAND(attack, ARG_DOWN)
|
||||
COMMAND(showscores, ARG_DOWN)
|
||||
|
||||
void
|
||||
fixplayer1range()
|
||||
|
@ -484,9 +484,9 @@ getclient(int cn) // ensure valid entity
|
|||
void
|
||||
initclient()
|
||||
{
|
||||
clientmap[0] = 0;
|
||||
clientmap = @"";
|
||||
initclientnet();
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
startmap(char *name) // called just after a map load
|
||||
|
@ -503,7 +503,9 @@ startmap(char *name) // called just after a map load
|
|||
player1->frags = 0;
|
||||
loopv(players) if (players[i]) players[i]->frags = 0;
|
||||
resetspawns();
|
||||
strcpy_s(clientmap, name);
|
||||
@autoreleasepool {
|
||||
clientmap = @(name);
|
||||
}
|
||||
if (editmode)
|
||||
toggleedit();
|
||||
setvar("gamespeed", 100);
|
||||
|
@ -513,6 +515,6 @@ startmap(char *name) // called just after a map load
|
|||
intermission = false;
|
||||
framesinmap = 0;
|
||||
conoutf(@"game mode is %s", modestr(gamemode));
|
||||
};
|
||||
}
|
||||
|
||||
COMMANDN(map, changemap, ARG_1STR);
|
||||
COMMANDN(map, changemap, ARG_1STR)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
extern int clientnum;
|
||||
extern bool c2sinit, senditemstoserver;
|
||||
extern string toservermap;
|
||||
extern OFString *toservermap;
|
||||
extern string clientpassword;
|
||||
|
||||
void
|
||||
|
@ -12,20 +12,20 @@ neterr(char *s)
|
|||
{
|
||||
conoutf(@"illegal network message (%s)", s);
|
||||
disconnect();
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
changemapserv(char *name, int mode) // forced map change from the server
|
||||
{
|
||||
gamemode = mode;
|
||||
load_world(name);
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
changemap(char *name) // request map change, server may ignore
|
||||
changemap(OFString *name) // request map change, server may ignore
|
||||
{
|
||||
strcpy_s(toservermap, name);
|
||||
};
|
||||
toservermap = name;
|
||||
}
|
||||
|
||||
// update the position of other clients in the game in our world
|
||||
// don't care if he's in the scenery or other players,
|
||||
|
@ -82,12 +82,12 @@ localservertoclient(
|
|||
disconnect();
|
||||
return;
|
||||
};
|
||||
toservermap[0] = 0;
|
||||
toservermap = @"";
|
||||
clientnum = cn; // we are now fully connected
|
||||
if (!getint(p))
|
||||
strcpy_s(toservermap,
|
||||
getclientmap()); // we are the first client
|
||||
// on this server, set map
|
||||
// we are the first client on this server, set
|
||||
// map
|
||||
toservermap = getclientmap();
|
||||
sgetstr();
|
||||
if (text[0] && strcmp(text, clientpassword)) {
|
||||
conoutf(@"you need to set the correct password "
|
||||
|
@ -160,10 +160,11 @@ localservertoclient(
|
|||
case SV_MAPRELOAD: // server requests next map
|
||||
{
|
||||
getint(p);
|
||||
sprintf_sd(nextmapalias)("nextmap_%s", getclientmap());
|
||||
char *map =
|
||||
OFString *nextmapalias = [OFString
|
||||
stringWithFormat:@"nextmap_%@", getclientmap()];
|
||||
OFString *map =
|
||||
getalias(nextmapalias); // look up map in the cycle
|
||||
changemap(map ? map : getclientmap());
|
||||
changemap(map != nil ? map : getclientmap());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
121
src/command.mm
121
src/command.mm
|
@ -7,12 +7,12 @@ enum { ID_VAR, ID_COMMAND, ID_ALIAS };
|
|||
|
||||
@interface Ident : OFObject
|
||||
@property (nonatomic) int type; // one of ID_* above
|
||||
@property (nonatomic) char *name;
|
||||
@property (nonatomic) int min, max; // ID_VAR
|
||||
@property (nonatomic) int *storage; // ID_VAR
|
||||
@property (nonatomic) void (*fun)(); // ID_VAR, ID_COMMAND
|
||||
@property (nonatomic) int narg; // ID_VAR, ID_COMMAND
|
||||
@property (nonatomic) char *action; // ID_ALIAS
|
||||
@property (copy, nonatomic) OFString *name;
|
||||
@property (nonatomic) int min, max; // ID_VAR
|
||||
@property (nonatomic) int *storage; // ID_VAR
|
||||
@property (nonatomic) void (*fun)(); // ID_VAR, ID_COMMAND
|
||||
@property (nonatomic) int narg; // ID_VAR, ID_COMMAND
|
||||
@property (copy, nonatomic) OFString *action; // ID_ALIAS
|
||||
@property (nonatomic) bool persist;
|
||||
@end
|
||||
|
||||
|
@ -26,7 +26,7 @@ itoa(char *s, int i)
|
|||
}
|
||||
|
||||
char *
|
||||
exchangestr(char *o, char *n)
|
||||
exchangestr(char *o, const char *n)
|
||||
{
|
||||
gp()->deallocstr(o);
|
||||
return newstring(n);
|
||||
|
@ -44,14 +44,14 @@ alias(char *name, char *action)
|
|||
if (!b) {
|
||||
Ident *b = [[Ident alloc] init];
|
||||
b.type = ID_ALIAS;
|
||||
b.name = newstring(name);
|
||||
b.action = newstring(action);
|
||||
b.name = @(name);
|
||||
b.action = @(action);
|
||||
b.persist = true;
|
||||
|
||||
idents[@(name)] = b;
|
||||
idents[b.name] = b;
|
||||
} else {
|
||||
if (b.type == ID_ALIAS)
|
||||
b.action = exchangestr(b.action, action);
|
||||
b.action = @(action);
|
||||
else
|
||||
conoutf(
|
||||
@"cannot redefine builtin %s with an alias",
|
||||
|
@ -72,14 +72,14 @@ variable(char *name, int min, int cur, int max, int *storage, void (*fun)(),
|
|||
@autoreleasepool {
|
||||
Ident *v = [[Ident alloc] init];
|
||||
v.type = ID_VAR;
|
||||
v.name = name;
|
||||
v.name = @(name);
|
||||
v.min = min;
|
||||
v.max = max;
|
||||
v.storage = storage;
|
||||
v.fun = fun;
|
||||
v.persist = persist;
|
||||
|
||||
idents[@(name)] = v;
|
||||
idents[v.name] = v;
|
||||
}
|
||||
|
||||
return cur;
|
||||
|
@ -109,17 +109,15 @@ identexists(char *name)
|
|||
}
|
||||
}
|
||||
|
||||
char *
|
||||
getalias(char *name)
|
||||
OFString *
|
||||
getalias(OFString *name)
|
||||
{
|
||||
@autoreleasepool {
|
||||
Ident *i = idents[@(name)];
|
||||
return i != nil && i.type == ID_ALIAS ? i.action : NULL;
|
||||
}
|
||||
Ident *i = idents[name];
|
||||
return i != nil && i.type == ID_ALIAS ? i.action : nil;
|
||||
}
|
||||
|
||||
bool
|
||||
addcommand(char *name, void (*fun)(), int narg)
|
||||
addcommand(OFString *name, void (*fun)(), int narg)
|
||||
{
|
||||
if (idents == nil)
|
||||
idents = [[OFMutableDictionary alloc] init];
|
||||
|
@ -131,7 +129,7 @@ addcommand(char *name, void (*fun)(), int narg)
|
|||
c.fun = fun;
|
||||
c.narg = narg;
|
||||
|
||||
idents[@(name)] = c;
|
||||
idents[name] = c;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -206,7 +204,7 @@ lookup(char *n) // find value of ident referenced with $ in exp
|
|||
itoa(t, *(ID.storage));
|
||||
return exchangestr(n, t);
|
||||
case ID_ALIAS:
|
||||
return exchangestr(n, ID.action);
|
||||
return exchangestr(n, ID.action.UTF8String);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -298,7 +296,7 @@ execute(char *p, bool isdown) // all evaluation happens here, recursively
|
|||
((void(__cdecl *)())
|
||||
ID.fun)();
|
||||
break;
|
||||
case ARG_1STR:
|
||||
case ARG_1CSTR:
|
||||
if (isdown)
|
||||
((void(__cdecl *)(
|
||||
char *))ID.fun)(
|
||||
|
@ -385,6 +383,17 @@ execute(char *p, bool isdown) // all evaluation happens here, recursively
|
|||
char *))ID.fun)(r);
|
||||
break;
|
||||
}
|
||||
case ARG_1STR:
|
||||
if (isdown) {
|
||||
@autoreleasepool {
|
||||
((void(
|
||||
__cdecl *)(
|
||||
OFString *))
|
||||
ID.fun)(
|
||||
@(w[1]));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -478,7 +487,8 @@ execute(char *p, bool isdown) // all evaluation happens here, recursively
|
|||
}
|
||||
// create new string here because alias
|
||||
// could rebind itself
|
||||
char *action = newstring(ID.action);
|
||||
char *action =
|
||||
newstring(ID.action.UTF8String);
|
||||
val = execute(action, isdown);
|
||||
gp()->deallocstr(action);
|
||||
break;
|
||||
|
@ -519,10 +529,10 @@ complete(char *s)
|
|||
__block int idx = 0;
|
||||
[idents enumerateKeysAndObjectsUsingBlock:^(
|
||||
OFString *name, Ident *ident, bool *stop) {
|
||||
if (strncmp(ident.name, s + 1, completesize) == 0 &&
|
||||
if (strncmp(ident.name.UTF8String, s + 1, completesize) == 0 &&
|
||||
idx++ == completeidx) {
|
||||
strcpy_s(s, "/");
|
||||
strcat_s(s, ident.name);
|
||||
strcat_s(s, ident.name.UTF8String);
|
||||
}
|
||||
}];
|
||||
completeidx++;
|
||||
|
@ -565,7 +575,8 @@ writecfg()
|
|||
[idents enumerateKeysAndObjectsUsingBlock:^(
|
||||
OFString *name, Ident *ident, bool *stop) {
|
||||
if (ident.type == ID_VAR && ident.persist) {
|
||||
fprintf(f, "%s %d\n", ident.name, *ident.storage);
|
||||
fprintf(f, "%s %d\n", ident.name.UTF8String,
|
||||
*ident.storage);
|
||||
}
|
||||
}];
|
||||
fprintf(f, "\n");
|
||||
|
@ -573,15 +584,16 @@ writecfg()
|
|||
fprintf(f, "\n");
|
||||
[idents enumerateKeysAndObjectsUsingBlock:^(
|
||||
OFString *name, Ident *ident, bool *stop) {
|
||||
if (ident.type == ID_ALIAS && !strstr(ident.name, "nextmap_")) {
|
||||
fprintf(
|
||||
f, "alias \"%s\" [%s]\n", ident.name, ident.action);
|
||||
if (ident.type == ID_ALIAS &&
|
||||
!strstr(ident.name.UTF8String, "nextmap_")) {
|
||||
fprintf(f, "alias \"%s\" [%s]\n", ident.name.UTF8String,
|
||||
ident.action.UTF8String);
|
||||
}
|
||||
}];
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
COMMAND(writecfg, ARG_NONE);
|
||||
COMMAND(writecfg, ARG_NONE)
|
||||
|
||||
// below the commands that implement a small imperative language. thanks to the
|
||||
// semantics of
|
||||
|
@ -662,82 +674,89 @@ at(char *s, char *pos)
|
|||
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);
|
||||
COMMANDN(loop, loopa, ARG_2STR)
|
||||
COMMANDN(while, whilea, ARG_2STR)
|
||||
COMMANDN(if, ifthen, ARG_3STR)
|
||||
COMMAND(onrelease, ARG_DWN1)
|
||||
COMMAND(exec, ARG_1CSTR)
|
||||
COMMAND(concat, ARG_VARI)
|
||||
COMMAND(concatword, ARG_VARI)
|
||||
COMMAND(at, ARG_2STR)
|
||||
COMMAND(listlen, ARG_1EST)
|
||||
|
||||
int
|
||||
add(int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
COMMANDN(+, add, ARG_2EXP);
|
||||
COMMANDN(+, add, ARG_2EXP)
|
||||
|
||||
int
|
||||
mul(int a, int b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
COMMANDN(*, mul, ARG_2EXP);
|
||||
COMMANDN(*, mul, ARG_2EXP)
|
||||
|
||||
int
|
||||
sub(int a, int b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
COMMANDN(-, sub, ARG_2EXP);
|
||||
COMMANDN(-, sub, ARG_2EXP)
|
||||
|
||||
int
|
||||
divi(int a, int b)
|
||||
{
|
||||
return b ? a / b : 0;
|
||||
}
|
||||
COMMANDN(div, divi, ARG_2EXP);
|
||||
COMMANDN(div, divi, ARG_2EXP)
|
||||
|
||||
int
|
||||
mod(int a, int b)
|
||||
{
|
||||
return b ? a % b : 0;
|
||||
}
|
||||
COMMAND(mod, ARG_2EXP);
|
||||
COMMAND(mod, ARG_2EXP)
|
||||
|
||||
int
|
||||
equal(int a, int b)
|
||||
{
|
||||
return (int)(a == b);
|
||||
}
|
||||
COMMANDN(=, equal, ARG_2EXP);
|
||||
COMMANDN(=, equal, ARG_2EXP)
|
||||
|
||||
int
|
||||
lt(int a, int b)
|
||||
{
|
||||
return (int)(a < b);
|
||||
}
|
||||
COMMANDN(<, lt, ARG_2EXP);
|
||||
COMMANDN(<, lt, ARG_2EXP)
|
||||
|
||||
int
|
||||
gt(int a, int b)
|
||||
{
|
||||
return (int)(a > b);
|
||||
}
|
||||
COMMANDN(>, gt, ARG_2EXP);
|
||||
COMMANDN(>, gt, ARG_2EXP)
|
||||
|
||||
int
|
||||
strcmpa(char *a, char *b)
|
||||
{
|
||||
return strcmp(a, b) == 0;
|
||||
}
|
||||
COMMANDN(strcmp, strcmpa, ARG_2EST);
|
||||
COMMANDN(strcmp, strcmpa, ARG_2EST)
|
||||
|
||||
int
|
||||
rndn(int a)
|
||||
{
|
||||
return a > 0 ? rnd(a) : 0;
|
||||
}
|
||||
COMMANDN(rnd, rndn, ARG_1EXP);
|
||||
COMMANDN(rnd, rndn, ARG_1EXP)
|
||||
|
||||
int
|
||||
explastmillis()
|
||||
{
|
||||
return lastmillis;
|
||||
}
|
||||
COMMANDN(millis, explastmillis, ARG_1EXP);
|
||||
COMMANDN(millis, explastmillis, ARG_1EXP)
|
||||
|
|
|
@ -22,9 +22,8 @@ setconskip(int n)
|
|||
conskip += n;
|
||||
if (conskip < 0)
|
||||
conskip = 0;
|
||||
};
|
||||
|
||||
COMMANDN(conskip, setconskip, ARG_1INT);
|
||||
}
|
||||
COMMANDN(conskip, setconskip, ARG_1INT)
|
||||
|
||||
void
|
||||
conline(const char *sf, bool highlight) // add a line to the console buffer
|
||||
|
@ -100,9 +99,8 @@ keymap(char *code, char *key, char *action)
|
|||
keyms[numkm].code = atoi(code);
|
||||
keyms[numkm].name = newstring(key);
|
||||
keyms[numkm++].action = newstringbuf(action);
|
||||
};
|
||||
|
||||
COMMAND(keymap, ARG_3STR);
|
||||
}
|
||||
COMMAND(keymap, ARG_3STR)
|
||||
|
||||
void
|
||||
bindkey(char *key, char *action)
|
||||
|
@ -115,9 +113,8 @@ bindkey(char *key, char *action)
|
|||
return;
|
||||
};
|
||||
conoutf(@"unknown key \"%s\"", key);
|
||||
};
|
||||
|
||||
COMMANDN(bind, bindkey, ARG_2STR);
|
||||
}
|
||||
COMMANDN(bind, bindkey, ARG_2STR)
|
||||
|
||||
void
|
||||
saycommand(char *init) // turns input to the command line on or off
|
||||
|
@ -134,10 +131,10 @@ void
|
|||
mapmsg(char *s)
|
||||
{
|
||||
strn0cpy(hdr.maptitle, s, 128);
|
||||
};
|
||||
}
|
||||
|
||||
COMMAND(saycommand, ARG_VARI);
|
||||
COMMAND(mapmsg, ARG_1STR);
|
||||
COMMAND(saycommand, ARG_VARI)
|
||||
COMMAND(mapmsg, ARG_1CSTR)
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <SDL_syswm.h>
|
||||
|
@ -198,9 +195,8 @@ history(int n)
|
|||
execute(vhistory[vhistory.length() - n - 1]);
|
||||
rec = false;
|
||||
};
|
||||
};
|
||||
|
||||
COMMAND(history, ARG_1INT);
|
||||
}
|
||||
COMMAND(history, ARG_1INT)
|
||||
|
||||
void
|
||||
keypress(int code, bool isdown, int cooked)
|
||||
|
|
|
@ -379,7 +379,7 @@ enum // function signatures for script functions, see command.cpp
|
|||
ARG_3INT,
|
||||
ARG_4INT,
|
||||
ARG_NONE,
|
||||
ARG_1STR,
|
||||
ARG_1CSTR,
|
||||
ARG_2STR,
|
||||
ARG_3STR,
|
||||
ARG_5STR,
|
||||
|
@ -389,7 +389,8 @@ enum // function signatures for script functions, see command.cpp
|
|||
ARG_2EXP,
|
||||
ARG_1EST,
|
||||
ARG_2EST,
|
||||
ARG_VARI
|
||||
ARG_VARI,
|
||||
ARG_1STR
|
||||
};
|
||||
|
||||
// nasty macros for registering script functions, abuses globals to avoid
|
||||
|
@ -398,7 +399,7 @@ enum // function signatures for script functions, see command.cpp
|
|||
OF_CONSTRUCTOR() \
|
||||
{ \
|
||||
enqueueInit(^{ \
|
||||
addcommand(#name, (void (*)())fun, nargs); \
|
||||
addcommand(@ #name, (void (*)())fun, nargs); \
|
||||
}); \
|
||||
}
|
||||
#define COMMAND(name, nargs) COMMANDN(name, name, nargs)
|
||||
|
|
|
@ -65,9 +65,8 @@ toggleedit()
|
|||
keyrepeat(editmode);
|
||||
selset = false;
|
||||
editing = editmode;
|
||||
};
|
||||
|
||||
COMMANDN(edittoggle, toggleedit, ARG_NONE);
|
||||
}
|
||||
COMMANDN(edittoggle, toggleedit, ARG_NONE)
|
||||
|
||||
void
|
||||
correctsel() // ensures above invariant
|
||||
|
@ -355,9 +354,8 @@ editheight(int flr, int amount)
|
|||
bool isfloor = flr == 0;
|
||||
editheightxy(isfloor, amount, sel);
|
||||
addmsg(1, 7, SV_EDITH, sel.x, sel.y, sel.xs, sel.ys, isfloor, amount);
|
||||
};
|
||||
|
||||
COMMAND(editheight, ARG_2INT);
|
||||
}
|
||||
COMMAND(editheight, ARG_2INT)
|
||||
|
||||
void
|
||||
edittexxy(int type, int t, block &sel)
|
||||
|
@ -451,21 +449,22 @@ void
|
|||
heightfield(int t)
|
||||
{
|
||||
edittype(t == 0 ? FHF : CHF);
|
||||
};
|
||||
}
|
||||
COMMAND(heightfield, ARG_1INT)
|
||||
|
||||
void
|
||||
solid(int t)
|
||||
{
|
||||
edittype(t == 0 ? SPACE : SOLID);
|
||||
};
|
||||
}
|
||||
COMMAND(solid, ARG_1INT)
|
||||
|
||||
void
|
||||
corner()
|
||||
{
|
||||
edittype(CORNER);
|
||||
};
|
||||
|
||||
COMMAND(heightfield, ARG_1INT);
|
||||
COMMAND(solid, ARG_1INT);
|
||||
COMMAND(corner, ARG_NONE);
|
||||
}
|
||||
COMMAND(corner, ARG_NONE)
|
||||
|
||||
void
|
||||
editequalisexy(bool isfloor, block &sel)
|
||||
|
@ -494,9 +493,8 @@ equalize(int flr)
|
|||
EDITSEL;
|
||||
editequalisexy(isfloor, sel);
|
||||
addmsg(1, 6, SV_EDITE, sel.x, sel.y, sel.xs, sel.ys, isfloor);
|
||||
};
|
||||
|
||||
COMMAND(equalize, ARG_1INT);
|
||||
}
|
||||
COMMAND(equalize, ARG_1INT)
|
||||
|
||||
void
|
||||
setvdeltaxy(int delta, block &sel)
|
||||
|
@ -602,16 +600,16 @@ newent(char *what, char *a1, char *a2, char *a3, char *a4)
|
|||
ATOI(a3), ATOI(a4));
|
||||
};
|
||||
|
||||
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);
|
||||
COMMANDN(vdelta, setvdelta, ARG_1INT);
|
||||
COMMANDN(undo, editundo, ARG_NONE);
|
||||
COMMAND(copy, ARG_NONE);
|
||||
COMMAND(paste, ARG_NONE);
|
||||
COMMAND(edittex, ARG_2INT);
|
||||
COMMAND(newent, ARG_5STR);
|
||||
COMMAND(perlin, ARG_3INT);
|
||||
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)
|
||||
COMMANDN(vdelta, setvdelta, ARG_1INT)
|
||||
COMMANDN(undo, editundo, ARG_NONE)
|
||||
COMMAND(copy, ARG_NONE)
|
||||
COMMAND(paste, ARG_NONE)
|
||||
COMMAND(edittex, ARG_2INT)
|
||||
COMMAND(newent, ARG_5STR)
|
||||
COMMAND(perlin, ARG_3INT)
|
||||
|
|
12
src/init.mm
12
src/init.mm
|
@ -3,22 +3,22 @@
|
|||
#import "cube.h"
|
||||
#import "protos.h"
|
||||
|
||||
static OFMutableArray<void (^)(void)> *queue;
|
||||
static std::vector<void (^)(void)> *queue;
|
||||
|
||||
void
|
||||
enqueueInit(void (^init)(void))
|
||||
{
|
||||
if (queue == nil)
|
||||
queue = [[OFMutableArray alloc] init];
|
||||
if (queue == NULL)
|
||||
queue = new std::vector<void (^)(void)>();
|
||||
|
||||
[queue addObject:init];
|
||||
queue->push_back(init);
|
||||
}
|
||||
|
||||
void
|
||||
processInitQueue(void)
|
||||
{
|
||||
for (void (^init)(void) in queue)
|
||||
for (auto &init : *queue)
|
||||
init();
|
||||
|
||||
[queue removeAllObjects];
|
||||
queue->clear();
|
||||
}
|
||||
|
|
|
@ -127,11 +127,11 @@ menuitem(char *text, char *action)
|
|||
mitem &mi = menu.items.add();
|
||||
mi.text = newstring(text);
|
||||
mi.action = action[0] ? newstring(action) : mi.text;
|
||||
};
|
||||
}
|
||||
COMMAND(menuitem, ARG_2STR)
|
||||
|
||||
COMMAND(menuitem, ARG_2STR);
|
||||
COMMAND(showmenu, ARG_1STR);
|
||||
COMMAND(newmenu, ARG_1STR);
|
||||
COMMAND(showmenu, ARG_1CSTR)
|
||||
COMMAND(newmenu, ARG_1CSTR)
|
||||
|
||||
bool
|
||||
menukey(int code, bool isdown)
|
||||
|
|
12
src/protos.h
12
src/protos.h
|
@ -6,14 +6,14 @@ extern int variable(char *name, int min, int cur, int max, int *storage,
|
|||
extern void setvar(char *name, int i);
|
||||
extern int getvar(char *name);
|
||||
extern bool identexists(char *name);
|
||||
extern bool addcommand(char *name, void (*fun)(), int narg);
|
||||
extern bool addcommand(OFString *name, void (*fun)(), int narg);
|
||||
extern int execute(char *p, bool down = true);
|
||||
extern void exec(char *cfgfile);
|
||||
extern bool execfile(char *cfgfile);
|
||||
extern void resetcomplete();
|
||||
extern void complete(char *s);
|
||||
extern void alias(char *name, char *action);
|
||||
extern char *getalias(char *name);
|
||||
extern OFString *getalias(OFString *name);
|
||||
extern void writecfg();
|
||||
|
||||
// console
|
||||
|
@ -90,12 +90,12 @@ extern void writeclientinfo(FILE *f);
|
|||
extern void mousemove(int dx, int dy);
|
||||
extern void updateworld(int millis);
|
||||
extern void startmap(char *name);
|
||||
extern void changemap(char *name);
|
||||
extern void changemap(OFString *name);
|
||||
extern void initclient();
|
||||
extern void spawnplayer(dynent *d);
|
||||
extern void selfdamage(int damage, int actor, dynent *act);
|
||||
extern dynent *newdynent();
|
||||
extern char *getclientmap();
|
||||
extern OFString *getclientmap();
|
||||
extern const char *modestr(int n);
|
||||
extern void zapdynent(dynent *&d);
|
||||
extern dynent *getclient(int cn);
|
||||
|
@ -182,10 +182,10 @@ extern void particle_trail(int type, int fade, vec &from, vec &to);
|
|||
extern void render_particles(int time);
|
||||
|
||||
// worldio
|
||||
extern void save_world(char *fname);
|
||||
extern void save_world(const char *fname);
|
||||
extern void load_world(char *mname);
|
||||
extern void writemap(char *mname, int msize, uchar *mdata);
|
||||
extern uchar *readmap(char *mname, int *msize);
|
||||
extern uchar *readmap(const char *mname, int *msize);
|
||||
extern void loadgamerest();
|
||||
extern void incomingdemodata(uchar *buf, int len, bool extras = false);
|
||||
extern void demoplaybackstep();
|
||||
|
|
|
@ -66,15 +66,15 @@ void
|
|||
showmip()
|
||||
{
|
||||
showm = !showm;
|
||||
};
|
||||
}
|
||||
COMMAND(showmip, ARG_NONE)
|
||||
|
||||
void
|
||||
mipstats(int a, int b, int c)
|
||||
{
|
||||
if (showm)
|
||||
conoutf(@"1x1/2x2/4x4: %d / %d / %d", a, b, c);
|
||||
};
|
||||
|
||||
COMMAND(showmip, ARG_NONE);
|
||||
}
|
||||
|
||||
#define stripend() \
|
||||
{ \
|
||||
|
|
|
@ -213,9 +213,8 @@ loadsky(char *basename)
|
|||
conoutf(@"could not load sky textures");
|
||||
};
|
||||
strcpy_s(lastsky, basename);
|
||||
};
|
||||
|
||||
COMMAND(loadsky, ARG_1STR);
|
||||
}
|
||||
COMMAND(loadsky, ARG_1CSTR)
|
||||
|
||||
float cursordepth = 0.9f;
|
||||
GLint viewport[4];
|
||||
|
|
|
@ -146,7 +146,8 @@ void
|
|||
texturereset()
|
||||
{
|
||||
curtexnum = 0;
|
||||
};
|
||||
}
|
||||
COMMAND(texturereset, ARG_NONE)
|
||||
|
||||
void
|
||||
texture(char *aframe, char *name)
|
||||
|
@ -158,10 +159,8 @@ texture(char *aframe, char *name)
|
|||
char *n = mapname[num][frame];
|
||||
strcpy_s(n, name);
|
||||
path(n);
|
||||
};
|
||||
|
||||
COMMAND(texturereset, ARG_NONE);
|
||||
COMMAND(texture, ARG_2STR);
|
||||
}
|
||||
COMMAND(texture, ARG_2STR)
|
||||
|
||||
int
|
||||
lookuptexture(int tex, int &xs, int &ys)
|
||||
|
|
|
@ -246,22 +246,21 @@ mapmodel(char *rad, char *h, char *zoff, char *snap, char *name)
|
|||
atoi(rad), atoi(h), atoi(zoff), atoi(snap), 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;
|
||||
};
|
||||
|
||||
COMMAND(mapmodel, ARG_5STR);
|
||||
COMMAND(mapmodelreset, ARG_NONE);
|
||||
}
|
||||
|
||||
void
|
||||
rendermodel(char *mdl, int frame, int range, int tex, float rad, float x,
|
||||
|
|
|
@ -22,42 +22,47 @@ void
|
|||
gzput(int i)
|
||||
{
|
||||
gzputc(f, i);
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
gzputi(int i)
|
||||
{
|
||||
gzwrite(f, &i, sizeof(int));
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
gzputv(vec &v)
|
||||
{
|
||||
gzwrite(f, &v, sizeof(vec));
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
gzcheck(int a, int b)
|
||||
{
|
||||
if (a != b)
|
||||
fatal("savegame file corrupt (short)");
|
||||
};
|
||||
}
|
||||
|
||||
int
|
||||
gzget()
|
||||
{
|
||||
char c = gzgetc(f);
|
||||
return c;
|
||||
};
|
||||
}
|
||||
|
||||
int
|
||||
gzgeti()
|
||||
{
|
||||
int i;
|
||||
gzcheck(gzread(f, &i, sizeof(int)), sizeof(int));
|
||||
return i;
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
gzgetv(vec &v)
|
||||
{
|
||||
gzcheck(gzread(f, &v, sizeof(vec)), sizeof(vec));
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
stop()
|
||||
|
@ -73,14 +78,14 @@ stop()
|
|||
demoloading = false;
|
||||
loopv(playerhistory) zapdynent(playerhistory[i]);
|
||||
playerhistory.setsize(0);
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
stopifrecording()
|
||||
{
|
||||
if (demorecording)
|
||||
stop();
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
savestate(char *fn)
|
||||
|
@ -95,7 +100,9 @@ savestate(char *fn)
|
|||
gzputc(f, islittleendian);
|
||||
gzputi(SAVEGAMEVERSION);
|
||||
gzputi(sizeof(dynent));
|
||||
gzwrite(f, getclientmap(), _MAXDEFSTR);
|
||||
@autoreleasepool {
|
||||
gzwrite(f, getclientmap().UTF8String, _MAXDEFSTR);
|
||||
}
|
||||
gzputi(gamemode);
|
||||
gzputi(ents.length());
|
||||
loopv(ents) gzputc(f, ents[i].spawned);
|
||||
|
@ -123,6 +130,7 @@ savegame(char *name)
|
|||
stop();
|
||||
conoutf(@"wrote %s", fn);
|
||||
}
|
||||
COMMAND(savegame, ARG_1CSTR)
|
||||
|
||||
void
|
||||
loadstate(char *fn)
|
||||
|
@ -148,8 +156,11 @@ loadstate(char *fn)
|
|||
string mapname;
|
||||
gzread(f, mapname, _MAXDEFSTR);
|
||||
nextmode = gzgeti();
|
||||
changemap(mapname); // continue below once map has been loaded and
|
||||
// client & server have updated
|
||||
@autoreleasepool {
|
||||
changemap(
|
||||
@(mapname)); // continue below once map has been loaded and
|
||||
// client & server have updated
|
||||
}
|
||||
return;
|
||||
out:
|
||||
conoutf(@"aborting: savegame/demo from a different version of cube or "
|
||||
|
@ -163,6 +174,7 @@ loadgame(char *name)
|
|||
sprintf_sd(fn)("savegames/%s.csgz", name);
|
||||
loadstate(fn);
|
||||
}
|
||||
COMMAND(loadgame, ARG_1CSTR)
|
||||
|
||||
void
|
||||
loadgameout()
|
||||
|
@ -247,7 +259,8 @@ record(char *name)
|
|||
demorecording = true;
|
||||
starttime = lastmillis;
|
||||
ddamage = bdamage = 0;
|
||||
};
|
||||
}
|
||||
COMMAND(record, ARG_1CSTR)
|
||||
|
||||
void
|
||||
demodamage(int damage, vec &o)
|
||||
|
@ -299,6 +312,7 @@ demo(char *name)
|
|||
loadstate(fn);
|
||||
demoloading = true;
|
||||
}
|
||||
COMMAND(demo, ARG_1CSTR)
|
||||
|
||||
void
|
||||
stopreset()
|
||||
|
@ -488,11 +502,5 @@ stopn()
|
|||
else
|
||||
stop();
|
||||
conoutf(@"demo stopped");
|
||||
};
|
||||
|
||||
COMMAND(record, ARG_1STR);
|
||||
COMMAND(demo, ARG_1STR);
|
||||
COMMANDN(stop, stopn, ARG_NONE);
|
||||
|
||||
COMMAND(savegame, ARG_1STR);
|
||||
COMMAND(loadgame, ARG_1STR);
|
||||
}
|
||||
COMMANDN(stop, stopn, ARG_NONE)
|
||||
|
|
|
@ -312,11 +312,11 @@ updatefrommaster()
|
|||
execute((char *)reply);
|
||||
};
|
||||
servermenu();
|
||||
};
|
||||
}
|
||||
|
||||
COMMAND(addserver, ARG_1STR);
|
||||
COMMAND(servermenu, ARG_NONE);
|
||||
COMMAND(updatefrommaster, ARG_NONE);
|
||||
COMMAND(addserver, ARG_1CSTR)
|
||||
COMMAND(servermenu, ARG_NONE)
|
||||
COMMAND(updatefrommaster, ARG_NONE)
|
||||
|
||||
void
|
||||
writeservercfg()
|
||||
|
|
10
src/sound.mm
10
src/sound.mm
|
@ -110,9 +110,9 @@ music(char *name)
|
|||
};
|
||||
#endif
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
COMMAND(music, ARG_1STR);
|
||||
COMMAND(music, ARG_1CSTR)
|
||||
|
||||
#ifdef USE_MIXER
|
||||
vector<Mix_Chunk *> samples;
|
||||
|
@ -131,7 +131,7 @@ registersound(char *name)
|
|||
return samples.length() - 1;
|
||||
};
|
||||
|
||||
COMMAND(registersound, ARG_1EST);
|
||||
COMMAND(registersound, ARG_1EST)
|
||||
|
||||
void
|
||||
cleansound()
|
||||
|
@ -267,5 +267,5 @@ void
|
|||
sound(int n)
|
||||
{
|
||||
playsound(n, NULL);
|
||||
};
|
||||
COMMAND(sound, ARG_1INT);
|
||||
}
|
||||
COMMAND(sound, ARG_1INT)
|
||||
|
|
29
src/tools.h
29
src/tools.h
|
@ -166,22 +166,25 @@ struct pool {
|
|||
void dealloc(void *p, size_t size);
|
||||
void *realloc(void *p, size_t oldsize, size_t newsize);
|
||||
|
||||
char *string(char *s, size_t l);
|
||||
char *string(const char *s, size_t l);
|
||||
|
||||
char *
|
||||
string(char *s)
|
||||
string(const char *s)
|
||||
{
|
||||
return string(s, strlen(s));
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
deallocstr(char *s)
|
||||
{
|
||||
dealloc(s, strlen(s) + 1);
|
||||
};
|
||||
}
|
||||
|
||||
char *
|
||||
stringbuf(char *s)
|
||||
stringbuf(const char *s)
|
||||
{
|
||||
return string(s, _MAXDEFSTR - 1);
|
||||
};
|
||||
}
|
||||
|
||||
void dealloc_block(void *b);
|
||||
void allocnext(size_t allocsize);
|
||||
|
@ -379,19 +382,21 @@ template <class T> struct hashtable {
|
|||
}
|
||||
|
||||
inline char *
|
||||
newstring(char *s)
|
||||
newstring(const char *s)
|
||||
{
|
||||
return gp()->string(s);
|
||||
};
|
||||
}
|
||||
|
||||
inline char *
|
||||
newstring(char *s, size_t l)
|
||||
newstring(const char *s, size_t l)
|
||||
{
|
||||
return gp()->string(s, l);
|
||||
};
|
||||
}
|
||||
|
||||
inline char *
|
||||
newstringbuf(char *s)
|
||||
newstringbuf(const char *s)
|
||||
{
|
||||
return gp()->stringbuf(s);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -82,13 +82,13 @@ pool::allocnext(size_t allocsize)
|
|||
};
|
||||
|
||||
char *
|
||||
pool::string(char *s, size_t l)
|
||||
pool::string(const char *s, size_t l)
|
||||
{
|
||||
char *b = (char *)alloc(l + 1);
|
||||
strncpy(b, s, l);
|
||||
b[l] = 0;
|
||||
return b;
|
||||
};
|
||||
}
|
||||
|
||||
pool *
|
||||
gp() // useful for global buffers that need to be initialisation order
|
||||
|
|
|
@ -64,9 +64,8 @@ weapon(char *a1, char *a2, char *a3)
|
|||
{
|
||||
selectgun(a1[0] ? atoi(a1) : -1, a2[0] ? atoi(a2) : -1,
|
||||
a3[0] ? atoi(a3) : -1);
|
||||
};
|
||||
|
||||
COMMAND(weapon, ARG_3STR);
|
||||
}
|
||||
COMMAND(weapon, ARG_3STR)
|
||||
|
||||
void
|
||||
createrays(vec &from, vec &to) // create random spread of rays for the shotgun
|
||||
|
|
25
src/world.mm
25
src/world.mm
|
@ -66,9 +66,8 @@ trigger(int tag, int type, bool savegame)
|
|||
execute(aliasname);
|
||||
if (type == 2)
|
||||
endsp(false);
|
||||
};
|
||||
|
||||
COMMAND(trigger, ARG_2INT);
|
||||
}
|
||||
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
|
||||
|
@ -360,9 +359,8 @@ clearents(char *name)
|
|||
};
|
||||
if (type == LIGHT)
|
||||
calclight();
|
||||
};
|
||||
|
||||
COMMAND(clearents, ARG_1STR);
|
||||
}
|
||||
COMMAND(clearents, ARG_1CSTR)
|
||||
|
||||
void
|
||||
scalecomp(uchar &c, int intens)
|
||||
|
@ -393,9 +391,8 @@ scalelights(int f, int intens)
|
|||
};
|
||||
};
|
||||
calclight();
|
||||
};
|
||||
|
||||
COMMAND(scalelights, ARG_2INT);
|
||||
}
|
||||
COMMAND(scalelights, ARG_2INT)
|
||||
|
||||
int
|
||||
findentity(int type, int index)
|
||||
|
@ -504,8 +501,8 @@ newmap(int i)
|
|||
empty_world(i, false);
|
||||
};
|
||||
|
||||
COMMAND(mapenlarge, ARG_NONE);
|
||||
COMMAND(newmap, ARG_1INT);
|
||||
COMMANDN(recalc, calclight, ARG_NONE);
|
||||
COMMAND(delent, ARG_NONE);
|
||||
COMMAND(entproperty, ARG_2INT);
|
||||
COMMAND(mapenlarge, ARG_NONE)
|
||||
COMMAND(newmap, ARG_1INT)
|
||||
COMMANDN(recalc, calclight, ARG_NONE)
|
||||
COMMAND(delent, ARG_NONE)
|
||||
COMMAND(entproperty, ARG_2INT)
|
||||
|
|
155
src/worldio.mm
155
src/worldio.mm
|
@ -11,18 +11,18 @@ backup(char *name, char *backupname)
|
|||
|
||||
string cgzname, bakname, pcfname, mcfname;
|
||||
|
||||
void
|
||||
setnames(char *name)
|
||||
static void
|
||||
setnames(const char *name)
|
||||
{
|
||||
string pakname, mapname;
|
||||
char *slash = strpbrk(name, "/\\");
|
||||
const char *slash = strpbrk(name, "/\\");
|
||||
if (slash) {
|
||||
strn0cpy(pakname, name, slash - name + 1);
|
||||
strcpy_s(mapname, slash + 1);
|
||||
} else {
|
||||
strcpy_s(pakname, "base");
|
||||
strcpy_s(mapname, name);
|
||||
};
|
||||
}
|
||||
sprintf_s(cgzname)("packages/%s/%s.cgz", pakname, mapname);
|
||||
sprintf_s(bakname)(
|
||||
"packages/%s/%s_%d.BAK", pakname, mapname, lastmillis);
|
||||
|
@ -31,7 +31,7 @@ setnames(char *name)
|
|||
|
||||
path(cgzname);
|
||||
path(bakname);
|
||||
};
|
||||
}
|
||||
|
||||
// the optimize routines below are here to reduce the detrimental effects of
|
||||
// messy mapping by setting certain properties (vdeltas and textures) to
|
||||
|
@ -137,7 +137,7 @@ writemap(char *mname, int msize, uchar *mdata)
|
|||
}
|
||||
|
||||
uchar *
|
||||
readmap(char *mname, int *msize)
|
||||
readmap(const char *mname, int *msize)
|
||||
{
|
||||
setnames(mname);
|
||||
uchar *mdata = (uchar *)loadfile(cgzname, msize);
|
||||
|
@ -154,37 +154,39 @@ readmap(char *mname, int *msize)
|
|||
// miniscule map sizes.
|
||||
|
||||
void
|
||||
save_world(char *mname)
|
||||
save_world(const char *mname)
|
||||
{
|
||||
resettagareas(); // wouldn't be able to reproduce tagged areas otherwise
|
||||
voptimize();
|
||||
toptimize();
|
||||
if (!*mname)
|
||||
mname = getclientmap();
|
||||
setnames(mname);
|
||||
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));
|
||||
@autoreleasepool {
|
||||
resettagareas(); // wouldn't be able to reproduce tagged areas
|
||||
// otherwise
|
||||
voptimize();
|
||||
toptimize();
|
||||
if (!*mname)
|
||||
mname = getclientmap().UTF8String;
|
||||
setnames(mname);
|
||||
backup(cgzname, bakname);
|
||||
gzFile f = gzopen(cgzname, "wb9");
|
||||
if (!f) {
|
||||
conoutf(@"could not write map to %s", cgzname);
|
||||
return;
|
||||
};
|
||||
};
|
||||
sqr *t = NULL;
|
||||
int sc = 0;
|
||||
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); \
|
||||
|
@ -196,50 +198,51 @@ save_world(char *mname)
|
|||
sc = 0; \
|
||||
} \
|
||||
};
|
||||
loopk(cubicsize)
|
||||
{
|
||||
sqr *s = &world[k];
|
||||
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)
|
||||
// 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++;
|
||||
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 {
|
||||
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);
|
||||
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;
|
||||
};
|
||||
t = s;
|
||||
};
|
||||
spurge;
|
||||
gzclose(f);
|
||||
conoutf(@"wrote map file %s", cgzname);
|
||||
settagareas();
|
||||
};
|
||||
spurge;
|
||||
gzclose(f);
|
||||
conoutf(@"wrote map file %s", cgzname);
|
||||
settagareas();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
load_world(char *mname) // still supports all map formats that have existed
|
||||
|
@ -371,6 +374,6 @@ load_world(char *mname) // still supports all map formats that have existed
|
|||
execfile("data/default_map_settings.cfg");
|
||||
execfile(pcfname);
|
||||
execfile(mcfname);
|
||||
};
|
||||
}
|
||||
|
||||
COMMANDN(savemap, save_world, ARG_1STR);
|
||||
COMMANDN(savemap, save_world, ARG_1CSTR)
|
||||
|
|
|
@ -12,9 +12,8 @@ void
|
|||
toggleocull()
|
||||
{
|
||||
ocull = !ocull;
|
||||
};
|
||||
|
||||
COMMAND(toggleocull, ARG_NONE);
|
||||
}
|
||||
COMMAND(toggleocull, ARG_NONE)
|
||||
|
||||
// constructs occlusion map: cast rays in all directions on the 2d plane and
|
||||
// record distance. done exactly once per frame.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue