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

View file

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

View file

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

View file

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

View file

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

View file

@ -55,31 +55,6 @@ typedef unsigned int uint;
# define _vsnprintf vsnprintf
#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))
extern void endianswap(void *, int, int);