Migrate last strings

FossilOrigin-Name: b81e2948d74e606b374ad69956719d748340eb128dc5e4c732781a2de71c2ba2
This commit is contained in:
Jonathan Schleifer 2025-03-15 23:42:51 +00:00
parent 71fff6f9a1
commit 9dff5ec70c
6 changed files with 76 additions and 69 deletions

View file

@ -7,11 +7,31 @@
#import "KeyMapping.h" #import "KeyMapping.h"
#import "OFString+Cube.h" #import "OFString+Cube.h"
struct cline { @interface ConsoleLine: OFObject
char *cref; @property (readonly, copy) OFString *text;
int outtime; @property (readonly) int outtime;
};
vector<cline> conlines; - (instancetype)initWithText:(OFString *)text outtime:(int)outtime;
@end
static OFMutableArray<ConsoleLine *> *conlines;
@implementation ConsoleLine
- (instancetype)initWithText:(OFString *)text outtime:(int)outtime
{
self = [super init];
_text = [text copy];
_outtime = outtime;
return self;
}
- (OFString *)description
{
return _text;
}
@end
const int ndraw = 5; const int ndraw = 5;
const int WORDWRAP = 80; const int WORDWRAP = 80;
@ -32,22 +52,29 @@ COMMANDN(conskip, setconskip, ARG_1INT)
static void static void
conline(OFString *sf, bool highlight) // add a line to the console buffer conline(OFString *sf, bool highlight) // add a line to the console buffer
{ {
cline cl; OFMutableString *text;
// constrain the buffer size // constrain the buffer size
cl.cref = conlines.length() > 100 ? conlines.pop().cref if (conlines.count > 100) {
: (char *)calloc(_MAXDEFSTR, 1); text = [conlines.lastObject.text mutableCopy];
// for how long to keep line on screen [conlines removeLastObject];
cl.outtime = lastmillis; } else
conlines.insert(0, cl); text = [[OFMutableString alloc] init];
if (highlight) {
if (highlight)
// show line in a different colour, for chat etc. // show line in a different colour, for chat etc.
cl.cref[0] = '\f'; [text appendString:@"\f"];
cl.cref[1] = 0;
strcat_s(cl.cref, sf.UTF8String); [text appendString:sf];
} else {
strcpy_s(cl.cref, sf.UTF8String); if (conlines == nil)
} conlines = [[OFMutableArray alloc] init];
puts(cl.cref);
[conlines insertObject:[[ConsoleLine alloc] initWithText:text
outtime:lastmillis]
atIndex:0];
puts(text.UTF8String);
#ifndef OF_WINDOWS #ifndef OF_WINDOWS
fflush(stdout); fflush(stdout);
#endif #endif
@ -74,28 +101,31 @@ conoutf(OFConstantString *format, ...)
} }
} }
// render buffer taking into account time & scrolling
void void
renderconsole() // render buffer taking into account time & scrolling renderconsole()
{ {
int nd = 0; int nd = 0;
char *refs[ndraw]; OFString *refs[ndraw];
loopv(conlines)
{ size_t i = 0;
if (conskip ? i >= conskip - 1 || i >= conlines.length() - ndraw for (ConsoleLine *conline in conlines) {
: lastmillis - conlines[i].outtime < 20000) { if (conskip ? i >= conskip - 1 || i >= conlines.count - ndraw
refs[nd++] = conlines[i].cref; : lastmillis - conline.outtime < 20000) {
refs[nd++] = conline.text;
if (nd == ndraw) if (nd == ndraw)
break; break;
} }
i++;
} }
@autoreleasepool {
loopj(nd) loopj(nd)
{ {
draw_text(@(refs[j]), FONTH / 3, draw_text(refs[j], FONTH / 3,
(FONTH / 4 * 5) * (nd - j - 1) + FONTH / 3, 2); (FONTH / 4 * 5) * (nd - j - 1) + FONTH / 3, 2);
} }
} }
}
// keymap is defined externally in keymap.cfg // keymap is defined externally in keymap.cfg

View file

@ -8,6 +8,8 @@
#include "tools.h" #include "tools.h"
#define _MAXDEFSTR 260
@class DynamicEntity; @class DynamicEntity;
@interface Cube: OFObject <OFApplicationDelegate> @interface Cube: OFObject <OFApplicationDelegate>

View file

@ -105,9 +105,9 @@ savestate(OFIRI *IRI)
gzputi(SAVEGAMEVERSION); gzputi(SAVEGAMEVERSION);
OFData *data = [player1 dataBySerializing]; OFData *data = [player1 dataBySerializing];
gzputi(data.count); gzputi(data.count);
char map[260] = { 0 }; char map[_MAXDEFSTR] = { 0 };
memcpy(map, getclientmap().UTF8String, memcpy(map, getclientmap().UTF8String,
min(getclientmap().UTF8StringLength, 259)); min(getclientmap().UTF8StringLength, _MAXDEFSTR - 1));
gzwrite(f, map, _MAXDEFSTR); gzwrite(f, map, _MAXDEFSTR);
gzputi(gamemode); gzputi(gamemode);
gzputi(ents.length()); gzputi(ents.length());
@ -163,7 +163,8 @@ loadstate(OFIRI *IRI)
return; return;
} }
string buf; char mapname[_MAXDEFSTR] = { 0 };
char buf[8];
gzread(f, buf, 8); gzread(f, buf, 8);
if (strncmp(buf, "CUBESAVE", 8)) if (strncmp(buf, "CUBESAVE", 8))
goto out; goto out;
@ -174,7 +175,6 @@ loadstate(OFIRI *IRI)
if (gzgeti() != SAVEGAMEVERSION || if (gzgeti() != SAVEGAMEVERSION ||
gzgeti() != DynamicEntity.serializedSize) gzgeti() != DynamicEntity.serializedSize)
goto out; goto out;
string mapname;
gzread(f, mapname, _MAXDEFSTR); gzread(f, mapname, _MAXDEFSTR);
nextmode = gzgeti(); nextmode = gzgeti();
@autoreleasepool { @autoreleasepool {
@ -453,7 +453,7 @@ demoplaybackstep()
int extras; int extras;
// read additional client side state not present in normal // read additional client side state not present in normal
// network stream // network stream
if (extras = gzget()) { if ((extras = gzget())) {
target.gunselect = gzget(); target.gunselect = gzget();
target.lastattackgun = gzget(); target.lastattackgun = gzget();
target.lastaction = scaletime(gzgeti()); target.lastaction = scaletime(gzgeti());
@ -464,9 +464,9 @@ demoplaybackstep()
loopi(NUMGUNS) target.ammo[i] = gzget(); loopi(NUMGUNS) target.ammo[i] = gzget();
target.state = gzget(); target.state = gzget();
target.lastmove = playbacktime; target.lastmove = playbacktime;
if (bdamage = gzgeti()) if ((bdamage = gzgeti()))
damageblend(bdamage); damageblend(bdamage);
if (ddamage = gzgeti()) { if ((ddamage = gzgeti())) {
gzgetv(dorig); gzgetv(dorig);
particle_splash(3, ddamage, 1000, dorig); particle_splash(3, ddamage, 1000, dorig);
} }

View file

@ -40,8 +40,7 @@ static int resolverlimit = 1000;
continue; continue;
_query = resolverqueries.lastObject; _query = resolverqueries.lastObject;
[resolverqueries [resolverqueries removeLastObject];
removeObjectAtIndex:resolverqueries.count - 1];
_starttime = lastmillis; _starttime = lastmillis;
} }
@ -148,8 +147,7 @@ resolvercheck(OFString **name, ENetAddress *address)
ResolverResult *rr = resolverresults.lastObject; ResolverResult *rr = resolverresults.lastObject;
*name = rr.query; *name = rr.query;
*address = rr.address; *address = rr.address;
[resolverresults [resolverresults removeLastObject];
removeObjectAtIndex:resolverresults.count - 1];
return true; return true;
} }

View file

@ -47,8 +47,10 @@ sendstring(OFString *t_, uchar *&p)
{ {
@autoreleasepool { @autoreleasepool {
const char *t = t_.UTF8String; const char *t = t_.UTF8String;
while (*t)
for (size_t i = 0; i < _MAXDEFSTR && *t != '\0'; i++)
putint(p, *t++); putint(p, *t++);
putint(p, 0); putint(p, 0);
} }
} }

View file

@ -55,31 +55,6 @@ typedef unsigned int uint;
# define _vsnprintf vsnprintf # define _vsnprintf vsnprintf
#endif #endif
// easy safe strings
#define _MAXDEFSTR 260
typedef char string[_MAXDEFSTR];
inline void
strn0cpy(char *d, const char *s, size_t m)
{
strncpy(d, s, m);
d[(m)-1] = 0;
}
inline void
strcpy_s(char *d, const char *s)
{
strn0cpy(d, s, _MAXDEFSTR);
}
inline void
strcat_s(char *d, const char *s)
{
size_t n = strlen(d);
strn0cpy(d + n, s, _MAXDEFSTR - n);
}
#define fast_f2nat(val) ((int)(val)) #define fast_f2nat(val) ((int)(val))
extern void endianswap(void *, int, int); extern void endianswap(void *, int, int);