Make more use of convenience methods

FossilOrigin-Name: 89fbd7a1520ecb65809b4c1bd10006ce9bb3a662cb7e7804abaf85d1ee1da63a
This commit is contained in:
Jonathan Schleifer 2025-03-20 13:21:56 +00:00
parent 4bdb80410d
commit 34b31eb77f
44 changed files with 320 additions and 188 deletions

View file

@ -6,6 +6,9 @@ OF_ASSUME_NONNULL_BEGIN
@property (copy, nonatomic) OFString *action; @property (copy, nonatomic) OFString *action;
@property (readonly, nonatomic) bool persisted; @property (readonly, nonatomic) bool persisted;
+ (instancetype)aliasWithName:(OFString *)name
action:(OFString *)action
persisted:(bool)persisted;
- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE; - (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name - (instancetype)initWithName:(OFString *)name
action:(OFString *)action action:(OFString *)action

View file

@ -1,6 +1,15 @@
#import "Alias.h" #import "Alias.h"
@implementation Alias @implementation Alias
+ (instancetype)aliasWithName:(OFString *)name
action:(OFString *)action
persisted:(bool)persisted;
{
return [[self alloc] initWithName:name
action:action
persisted:persisted];
}
- (instancetype)initWithName:(OFString *)name - (instancetype)initWithName:(OFString *)name
action:(OFString *)action action:(OFString *)action
persisted:(bool)persisted persisted:(bool)persisted

15
src/Client.h Normal file
View file

@ -0,0 +1,15 @@
#import <ObjFW/ObjFW.h>
#import "cube.h"
// server side version of "dynent" type
@interface Client: OFObject
@property (nonatomic) int type;
@property (nonatomic) ENetPeer *peer;
@property (copy, nonatomic) OFString *hostname;
@property (copy, nonatomic) OFString *mapvote;
@property (copy, nonatomic) OFString *name;
@property (nonatomic) int modevote;
+ (instancetype)client;
@end

8
src/Client.mm Normal file
View file

@ -0,0 +1,8 @@
#import "Client.h"
@implementation Client
+ (instancetype)client
{
return [[self alloc] init];
}
@end

View file

@ -6,6 +6,9 @@ OF_ASSUME_NONNULL_BEGIN
@property (readonly, nonatomic) void (*function)(); @property (readonly, nonatomic) void (*function)();
@property (readonly, nonatomic) int argumentsTypes; @property (readonly, nonatomic) int argumentsTypes;
+ (instancetype)commandWithName:(OFString *)name
function:(void (*)())function
argumentsTypes:(int)argumentsTypes;
- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE; - (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name - (instancetype)initWithName:(OFString *)name
function:(void (*)())function function:(void (*)())function

View file

@ -20,6 +20,15 @@ padArguments(OFArray<OFString *> *arguments, size_t count)
} }
@implementation Command @implementation Command
+ (instancetype)commandWithName:(OFString *)name
function:(void (*)())function
argumentsTypes:(int)argumentsTypes
{
return [[self alloc] initWithName:name
function:function
argumentsTypes:argumentsTypes];
}
- (instancetype)initWithName:(OFString *)name - (instancetype)initWithName:(OFString *)name
function:(void (*)())function function:(void (*)())function
argumentsTypes:(int)argumentsTypes argumentsTypes:(int)argumentsTypes

9
src/ConsoleLine.h Normal file
View file

@ -0,0 +1,9 @@
#import <ObjFW/ObjFW.h>
@interface ConsoleLine: OFObject
@property (readonly, copy) OFString *text;
@property (readonly) int outtime;
+ (instancetype)lineWithText:(OFString *)text outtime:(int)outtime;
- (instancetype)initWithText:(OFString *)text outtime:(int)outtime;
@end

18
src/ConsoleLine.m Normal file
View file

@ -0,0 +1,18 @@
#import "ConsoleLine.h"
@implementation ConsoleLine
+ (instancetype)lineWithText:(OFString *)text outtime:(int)outtime
{
return [[self alloc] initWithText:text outtime:outtime];
}
- (instancetype)initWithText:(OFString *)text outtime:(int)outtime
{
self = [super init];
_text = [text copy];
_outtime = outtime;
return self;
}
@end

View file

@ -7,6 +7,8 @@ OF_ASSUME_NONNULL_BEGIN
@property (readonly, nonatomic) OFString *name; @property (readonly, nonatomic) OFString *name;
@property (copy, nonatomic) OFString *action; @property (copy, nonatomic) OFString *action;
+ (instancetype)mappingWithCode:(int)code name:(OFString *)name;
- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithCode:(int)code name:(OFString *)name; - (instancetype)initWithCode:(int)code name:(OFString *)name;
@end @end

View file

@ -1,6 +1,11 @@
#import "KeyMapping.h" #import "KeyMapping.h"
@implementation KeyMapping @implementation KeyMapping
+ (instancetype)mappingWithCode:(int)code name:(OFString *)name
{
return [[self alloc] initWithCode:code name:name];
}
- (instancetype)initWithCode:(int)code name:(OFString *)name - (instancetype)initWithCode:(int)code name:(OFString *)name
{ {
self = [super init]; self = [super init];

View file

@ -10,13 +10,12 @@ OF_ASSUME_NONNULL_BEGIN
@property (nonatomic) int mdlnum; @property (nonatomic) int mdlnum;
@property (nonatomic) bool loaded; @property (nonatomic) bool loaded;
+ (instancetype)md2;
- (bool)loadWithIRI:(OFIRI *)IRI; - (bool)loadWithIRI:(OFIRI *)IRI;
- (void)renderWithLight:(OFVector3D)light - (void)renderWithLight:(OFVector3D)light
frame:(int)frame frame:(int)frame
range:(int)range range:(int)range
x:(float)x position:(OFVector3D)position
y:(float)y
z:(float)z
yaw:(float)yaw yaw:(float)yaw
pitch:(float)pitch pitch:(float)pitch
scale:(float)scale scale:(float)scale

View file

@ -44,6 +44,11 @@ snap(int sn, float f)
int _displaylistverts; int _displaylistverts;
} }
+ (instancetype)md2
{
return [[self alloc] init];
}
- (void)dealloc - (void)dealloc
{ {
if (_glCommands) if (_glCommands)
@ -126,9 +131,7 @@ snap(int sn, float f)
- (void)renderWithLight:(OFVector3D)light - (void)renderWithLight:(OFVector3D)light
frame:(int)frame frame:(int)frame
range:(int)range range:(int)range
x:(float)x position:(OFVector3D)position
y:(float)y
z:(float)z
yaw:(float)yaw yaw:(float)yaw
pitch:(float)pitch pitch:(float)pitch
scale:(float)sc scale:(float)sc
@ -141,7 +144,7 @@ snap(int sn, float f)
snap:sn]; snap:sn];
glPushMatrix(); glPushMatrix();
glTranslatef(x, y, z); glTranslatef(position.x, position.y, position.z);
glRotatef(yaw + 180, 0, -1, 0); glRotatef(yaw + 180, 0, -1, 0);
glRotatef(pitch, 0, 0, 1); glRotatef(pitch, 0, 0, 1);

View file

@ -6,6 +6,12 @@ OF_ASSUME_NONNULL_BEGIN
@property (nonatomic) int rad, h, zoff, snap; @property (nonatomic) int rad, h, zoff, snap;
@property (copy, nonatomic) OFString *name; @property (copy, nonatomic) OFString *name;
+ (instancetype)infoWithRad:(int)rad
h:(int)h
zoff:(int)zoff
snap:(int)snap
name:(OFString *)name;
- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithRad:(int)rad - (instancetype)initWithRad:(int)rad
h:(int)h h:(int)h
zoff:(int)zoff zoff:(int)zoff

View file

@ -1,6 +1,15 @@
#import "MapModelInfo.h" #import "MapModelInfo.h"
@implementation MapModelInfo @implementation MapModelInfo
+ (instancetype)infoWithRad:(int)rad
h:(int)h
zoff:(int)zoff
snap:(int)snap
name:(OFString *)name
{
return [[self alloc] initWithRad:rad h:h zoff:zoff snap:snap name:name];
}
- (instancetype)initWithRad:(int)rad - (instancetype)initWithRad:(int)rad
h:(int)h h:(int)h
zoff:(int)zoff zoff:(int)zoff

View file

@ -10,6 +10,8 @@ OF_ASSUME_NONNULL_BEGIN
@property (nonatomic) int mwidth; @property (nonatomic) int mwidth;
@property (nonatomic) int menusel; @property (nonatomic) int menusel;
+ (instancetype)menuWithName:(OFString *)name;
- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name; - (instancetype)initWithName:(OFString *)name;
@end @end

View file

@ -1,6 +1,11 @@
#import "Menu.h" #import "Menu.h"
@implementation Menu @implementation Menu
+ (instancetype)menuWithName:(OFString *)name
{
return [[self alloc] initWithName:name];
}
- (instancetype)initWithName:(OFString *)name - (instancetype)initWithName:(OFString *)name
{ {
self = [super init]; self = [super init];

View file

@ -3,5 +3,7 @@
@interface MenuItem: OFObject @interface MenuItem: OFObject
@property (readonly, nonatomic) OFString *text, *action; @property (readonly, nonatomic) OFString *text, *action;
+ (instancetype)itemWithText:(OFString *)text action:(OFString *)action;
- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithText:(OFString *)text action:(OFString *)action; - (instancetype)initWithText:(OFString *)text action:(OFString *)action;
@end @end

View file

@ -1,6 +1,11 @@
#import "MenuItem.h" #import "MenuItem.h"
@implementation MenuItem @implementation MenuItem
+ (instancetype)itemWithText:(OFString *)text action:(OFString *)action
{
return [[self alloc] initWithText:text action:action];
}
- (instancetype)initWithText:(OFString *)text action:(OFString *)action - (instancetype)initWithText:(OFString *)text action:(OFString *)action
{ {
self = [super init]; self = [super init];

View file

@ -8,4 +8,6 @@
@property (nonatomic) DynamicEntity *owner; @property (nonatomic) DynamicEntity *owner;
@property (nonatomic) int gun; @property (nonatomic) int gun;
@property (nonatomic) bool inuse, local; @property (nonatomic) bool inuse, local;
+ (instancetype)projectile;
@end @end

View file

@ -1,4 +1,8 @@
#import "Projectile.h" #import "Projectile.h"
@implementation Projectile @implementation Projectile
+ (instancetype)projectile
{
return [[self alloc] init];
}
@end @end

12
src/ResolverResult.h Normal file
View file

@ -0,0 +1,12 @@
#import <ObjFW/ObjFW.h>
#import "cube.h"
@interface ResolverResult: OFObject
@property (readonly, nonatomic) OFString *query;
@property (readonly, nonatomic) ENetAddress address;
+ (instancetype)resultWithQuery:(OFString *)query address:(ENetAddress)address;
- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithQuery:(OFString *)query address:(ENetAddress)address;
@end

18
src/ResolverResult.mm Normal file
View file

@ -0,0 +1,18 @@
#import "ResolverResult.h"
@implementation ResolverResult
+ (instancetype)resultWithQuery:(OFString *)query address:(ENetAddress)address
{
return [[self alloc] initWithQuery:query address:address];
}
- (instancetype)initWithQuery:(OFString *)query address:(ENetAddress)address
{
self = [super init];
_query = query;
_address = address;
return self;
}
@end

12
src/ResolverThread.h Normal file
View file

@ -0,0 +1,12 @@
#import <ObjFW/ObjFW.h>
@interface ResolverThread: OFThread
{
volatile bool _stop;
}
@property (copy, nonatomic) OFString *query;
@property (nonatomic) int starttime;
- (void)stop;
@end

44
src/ResolverThread.mm Normal file
View file

@ -0,0 +1,44 @@
#import "ResolverThread.h"
#import "ResolverResult.h"
extern SDL_sem *resolversem;
extern OFMutableArray<OFString *> *resolverqueries;
extern OFMutableArray<ResolverResult *> *resolverresults;
@implementation ResolverThread
- (id)main
{
while (!_stop) {
SDL_SemWait(resolversem);
@synchronized(ResolverThread.class) {
if (resolverqueries.count == 0)
continue;
_query = resolverqueries.lastObject;
[resolverqueries removeLastObject];
_starttime = lastmillis;
}
ENetAddress address = { ENET_HOST_ANY, CUBE_SERVINFO_PORT };
enet_address_set_host(&address, _query.UTF8String);
@synchronized(ResolverThread.class) {
[resolverresults
addObject:[ResolverResult resultWithQuery:_query
address:address]];
_query = NULL;
_starttime = 0;
}
}
return nil;
}
- (void)stop
{
_stop = true;
}
@end

View file

@ -10,6 +10,7 @@
@property (nonatomic) int mode, numplayers, ping, protocol, minremain; @property (nonatomic) int mode, numplayers, ping, protocol, minremain;
@property (nonatomic) ENetAddress address; @property (nonatomic) ENetAddress address;
+ (instancetype)infoWithName:(OFString *)name;
- (instancetype)init OF_UNAVAILABLE; - (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name; - (instancetype)initWithName:(OFString *)name;
@end @end

View file

@ -3,6 +3,11 @@
#include "cube.h" #include "cube.h"
@implementation ServerInfo @implementation ServerInfo
+ (instancetype)infoWithName:(OFString *)name;
{
return [[self alloc] initWithName:name];
}
- (instancetype)initWithName:(OFString *)name - (instancetype)initWithName:(OFString *)name
{ {
self = [super init]; self = [super init];

View file

@ -8,6 +8,12 @@ OF_ASSUME_NONNULL_BEGIN
@property (readonly, nonatomic) void (*__cdecl function)(); @property (readonly, nonatomic) void (*__cdecl function)();
@property (readonly, nonatomic) bool persisted; @property (readonly, nonatomic) bool persisted;
+ (instancetype)variableWithName:(OFString *)name
min:(int)min
max:(int)max
storage:(int *)storage
function:(void (*__cdecl)())function
persisted:(bool)persisted;
- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE; - (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name - (instancetype)initWithName:(OFString *)name
min:(int)min min:(int)min

View file

@ -3,6 +3,21 @@
#include "cube.h" #include "cube.h"
@implementation Variable @implementation Variable
+ (instancetype)variableWithName:(OFString *)name
min:(int)min
max:(int)max
storage:(int *)storage
function:(void (*__cdecl)())function
persisted:(bool)persisted
{
return [[self alloc] initWithName:name
min:min
max:max
storage:storage
function:function
persisted:persisted];
}
- (instancetype)initWithName:(OFString *)name - (instancetype)initWithName:(OFString *)name
min:(int)min min:(int)min
max:(int)max max:(int)max

View file

@ -71,8 +71,9 @@ renderclient(
scale *= 32; scale *= 32;
mz -= 1.9f; mz -= 1.9f;
} }
rendermodel(mdlname, frame[n], range[n], 0, 1.5f, d.o.x, mz, d.o.y, rendermodel(mdlname, frame[n], range[n], 0, 1.5f,
d.yaw + 90, d.pitch / 2, team, scale, speed, 0, basetime); OFMakeVector3D(d.o.x, mz, d.o.y), d.yaw + 90, d.pitch / 2, team,
scale, speed, 0, basetime);
} }
extern int democlientnum; extern int democlientnum;
@ -161,7 +162,7 @@ renderscores()
addteamscore(player); addteamscore(player);
if (!demoplayback) if (!demoplayback)
addteamscore(player1); addteamscore(player1);
OFMutableString *teamScores = [[OFMutableString alloc] init]; OFMutableString *teamScores = [OFMutableString string];
for (size_t j = 0; j < teamsUsed; j++) for (size_t j = 0; j < teamsUsed; j++)
[teamScores appendFormat:@"[ %@: %d ]", teamName[j], [teamScores appendFormat:@"[ %@: %d ]", teamName[j],
teamScore[j]]; teamScore[j]];

View file

@ -471,8 +471,6 @@ getclient(int cn) // ensure valid entity
neterr(@"clientnum"); neterr(@"clientnum");
return nil; return nil;
} }
if (players == nil)
players = [[OFMutableArray alloc] init];
while (cn >= players.count) while (cn >= players.count)
[players addObject:[OFNull null]]; [players addObject:[OFNull null]];
return (players[cn] != [OFNull null] ? players[cn] return (players[cn] != [OFNull null] ? players[cn]
@ -484,8 +482,6 @@ setclient(int cn, id client)
{ {
if (cn < 0 || cn >= MAXCLIENTS) if (cn < 0 || cn >= MAXCLIENTS)
neterr(@"clientnum"); neterr(@"clientnum");
if (players == nil)
players = [[OFMutableArray alloc] init];
while (cn >= players.count) while (cn >= players.count)
[players addObject:[OFNull null]]; [players addObject:[OFNull null]];
players[cn] = client; players[cn] = client;

View file

@ -20,9 +20,7 @@ alias(OFString *name, OFString *action)
Alias *alias = identifiers[name]; Alias *alias = identifiers[name];
if (alias == nil) { if (alias == nil) {
alias = [[Alias alloc] initWithName:name alias = [Alias aliasWithName:name action:action persisted:true];
action:action
persisted:true];
if (identifiers == nil) if (identifiers == nil)
identifiers = [[OFMutableDictionary alloc] init]; identifiers = [[OFMutableDictionary alloc] init];
@ -42,7 +40,7 @@ int
variable(OFString *name, int min, int cur, int max, int *storage, variable(OFString *name, int min, int cur, int max, int *storage,
void (*function)(), bool persisted) void (*function)(), bool persisted)
{ {
Variable *variable = [[Variable alloc] initWithName:name Variable *variable = [Variable variableWithName:name
min:min min:min
max:max max:max
storage:storage storage:storage
@ -89,7 +87,7 @@ getalias(OFString *name)
bool bool
addcommand(OFString *name, void (*function)(), int argumentsTypes) addcommand(OFString *name, void (*function)(), int argumentsTypes)
{ {
Command *command = [[Command alloc] initWithName:name Command *command = [Command commandWithName:name
function:function function:function
argumentsTypes:argumentsTypes]; argumentsTypes:argumentsTypes];

View file

@ -4,35 +4,12 @@
#include <ctype.h> #include <ctype.h>
#import "ConsoleLine.h"
#import "KeyMapping.h" #import "KeyMapping.h"
#import "OFString+Cube.h" #import "OFString+Cube.h"
@interface ConsoleLine: OFObject
@property (readonly, copy) OFString *text;
@property (readonly) int outtime;
- (instancetype)initWithText:(OFString *)text outtime:(int)outtime;
@end
static OFMutableArray<ConsoleLine *> *conlines; 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;
int conskip = 0; int conskip = 0;
@ -59,7 +36,7 @@ conline(OFString *sf, bool highlight) // add a line to the console buffer
text = [conlines.lastObject.text mutableCopy]; text = [conlines.lastObject.text mutableCopy];
[conlines removeLastObject]; [conlines removeLastObject];
} else } else
text = [[OFMutableString alloc] init]; text = [OFMutableString string];
if (highlight) if (highlight)
// show line in a different colour, for chat etc. // show line in a different colour, for chat etc.
@ -70,7 +47,7 @@ conline(OFString *sf, bool highlight) // add a line to the console buffer
if (conlines == nil) if (conlines == nil)
conlines = [[OFMutableArray alloc] init]; conlines = [[OFMutableArray alloc] init];
[conlines insertObject:[[ConsoleLine alloc] initWithText:text [conlines insertObject:[ConsoleLine lineWithText:text
outtime:lastmillis] outtime:lastmillis]
atIndex:0]; atIndex:0];
@ -135,8 +112,8 @@ keymap(OFString *code, OFString *key, OFString *action)
if (keyMappings == nil) if (keyMappings == nil)
keyMappings = [[OFMutableArray alloc] init]; keyMappings = [[OFMutableArray alloc] init];
KeyMapping *mapping = KeyMapping *mapping = [KeyMapping mappingWithCode:code.cube_intValue
[[KeyMapping alloc] initWithCode:code.cube_intValue name:key]; name:key];
mapping.action = action; mapping.action = action;
[keyMappings addObject:mapping]; [keyMappings addObject:mapping];
} }

View file

@ -26,8 +26,9 @@ void
renderent(entity &e, OFString *mdlname, float z, float yaw, int frame = 0, renderent(entity &e, OFString *mdlname, float z, float yaw, int frame = 0,
int numf = 1, int basetime = 0, float speed = 10.0f) 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, rendermodel(mdlname, frame, numf, 0, 1.1f,
e.y, yaw, 0, false, 1.0f, speed, 0, basetime); OFMakeVector3D(e.x, z + S(e.x, e.y)->floor, e.y), yaw, 0, false,
1.0f, speed, 0, basetime);
} }
void void
@ -43,8 +44,10 @@ renderentities()
if (mmi == nil) if (mmi == nil)
continue; continue;
rendermodel(mmi.name, 0, 1, e.attr4, (float)mmi.rad, rendermodel(mmi.name, 0, 1, e.attr4, (float)mmi.rad,
e.x, (float)S(e.x, e.y)->floor + mmi.zoff + e.attr3, OFMakeVector3D(e.x,
e.y, (float)((e.attr1 + 7) - (e.attr1 + 7) % 15), 0, (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); false, 1.0f, 10.0f, mmi.snap);
} else { } else {
if (OUTBORD(e.x, e.y)) if (OUTBORD(e.x, e.y))

View file

@ -95,7 +95,7 @@ newmenu(OFString *name)
if (menus == nil) if (menus == nil)
menus = [[OFMutableArray alloc] init]; menus = [[OFMutableArray alloc] init];
[menus addObject:[[Menu alloc] initWithName:name]]; [menus addObject:[Menu menuWithName:name]];
} }
COMMAND(newmenu, ARG_1STR) COMMAND(newmenu, ARG_1STR)
@ -105,7 +105,7 @@ menumanual(int m, int n, OFString *text)
if (n == 0) if (n == 0)
[menus[m].items removeAllObjects]; [menus[m].items removeAllObjects];
MenuItem *item = [[MenuItem alloc] initWithText:text action:@""]; MenuItem *item = [MenuItem itemWithText:text action:@""];
[menus[m].items addObject:item]; [menus[m].items addObject:item];
} }
@ -115,7 +115,7 @@ menuitem(OFString *text, OFString *action)
Menu *menu = menus.lastObject; Menu *menu = menus.lastObject;
MenuItem *item = MenuItem *item =
[[MenuItem alloc] initWithText:text [MenuItem itemWithText:text
action:(action.length > 0 ? action : text)]; action:(action.length > 0 ? action : text)];
[menu.items addObject:item]; [menu.items addObject:item];
} }

View file

@ -1,7 +1,9 @@
executable('client', executable('client',
[ [
'Alias.m', 'Alias.m',
'Client.mm',
'Command.mm', 'Command.mm',
'ConsoleLine.m',
'Cube.mm', 'Cube.mm',
'DynamicEntity.mm', 'DynamicEntity.mm',
'Identifier.m', 'Identifier.m',
@ -12,9 +14,11 @@ executable('client',
'MenuItem.m', 'MenuItem.m',
'OFString+Cube.mm', 'OFString+Cube.mm',
'Projectile.m', 'Projectile.m',
'ResolverResult.mm',
'ResolverThread.mm',
'ServerInfo.mm', 'ServerInfo.mm',
'Variable.mm', 'Variable.mm',
'client.mm', 'clients.mm',
'clientextras.mm', 'clientextras.mm',
'clientgame.mm', 'clientgame.mm',
'clients2c.mm', 'clients2c.mm',
@ -62,6 +66,7 @@ executable('client',
executable('server', executable('server',
[ [
'Client.mm',
'server.mm', 'server.mm',
'serverms.mm', 'serverms.mm',
'serverutil.mm', 'serverutil.mm',

View file

@ -210,8 +210,8 @@ extern void cleansound();
// rendermd2 // rendermd2
extern void rendermodel(OFString *mdl, int frame, int range, int tex, float rad, 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, OFVector3D position, float yaw, float pitch, bool teammate, float scale,
float scale, float speed, int snap = 0, int basetime = 0); float speed, int snap = 0, int basetime = 0);
@class MapModelInfo; @class MapModelInfo;
extern MapModelInfo *getmminfo(int i); extern MapModelInfo *getmminfo(int i);

View file

@ -192,11 +192,11 @@ renderents() // show sparkly thingies for map entities in edit mode
int e = closestent(); int e = closestent();
if (e >= 0) { if (e >= 0) {
entity &c = ents[e]; entity &c = ents[e];
closeent = [[OFString alloc] closeent =
initWithFormat:@"closest entity = %@ (%d, %d, %d, %d), " [OFString stringWithFormat:@"closest entity = %@ (%d, %d, "
@"selection = (%d, %d)", @"%d, %d), selection = (%d, %d)",
entnames[c.type], c.attr1, c.attr2, c.attr3, c.attr4, entnames[c.type], c.attr1, c.attr2, c.attr3,
getvar(@"selxs"), getvar(@"selys")]; c.attr4, getvar(@"selxs"), getvar(@"selys")];
} }
} }

View file

@ -359,8 +359,8 @@ void
drawhudmodel(int start, int end, float speed, int base) drawhudmodel(int start, int end, float speed, int base)
{ {
rendermodel(hudgunnames[player1.gunselect], start, end, 0, 1.0f, rendermodel(hudgunnames[player1.gunselect], start, end, 0, 1.0f,
player1.o.x, player1.o.z, player1.o.y, player1.yaw + 90, OFMakeVector3D(player1.o.x, player1.o.z, player1.o.y),
player1.pitch, false, 1.0f, speed, 0, base); player1.yaw + 90, player1.pitch, false, 1.0f, speed, 0, base);
} }
void void

View file

@ -41,9 +41,9 @@ loadmodel(OFString *name)
if (m != nil) if (m != nil)
return m; return m;
m = [[MD2 alloc] init]; m = [MD2 md2];
m.mdlnum = modelnum++; m.mdlnum = modelnum++;
m.mmi = [[MapModelInfo alloc] initWithRad:2 h:2 zoff:0 snap:0 name:@""]; m.mmi = [MapModelInfo infoWithRad:2 h:2 zoff:0 snap:0 name:@""];
m.loadname = name; m.loadname = name;
if (mdllookup == nil) if (mdllookup == nil)
@ -60,7 +60,7 @@ mapmodel(
{ {
MD2 *m = loadmodel([name stringByReplacingOccurrencesOfString:@"\\" MD2 *m = loadmodel([name stringByReplacingOccurrencesOfString:@"\\"
withString:@"/"]); withString:@"/"]);
m.mmi = [[MapModelInfo alloc] initWithRad:rad.cube_intValue m.mmi = [MapModelInfo infoWithRad:rad.cube_intValue
h:h.cube_intValue h:h.cube_intValue
zoff:zoff.cube_intValue zoff:zoff.cube_intValue
snap:snap.cube_intValue snap:snap.cube_intValue
@ -87,13 +87,14 @@ getmminfo(int i)
} }
void void
rendermodel(OFString *mdl, int frame, int range, int tex, float rad, float x, rendermodel(OFString *mdl, int frame, int range, int tex, float rad,
float y, float z, float yaw, float pitch, bool teammate, float scale, OFVector3D position, float yaw, float pitch, bool teammate, float scale,
float speed, int snap, int basetime) float speed, int snap, int basetime)
{ {
MD2 *m = loadmodel(mdl); MD2 *m = loadmodel(mdl);
if (isoccluded(player1.o.x, player1.o.y, x - rad, z - rad, rad * 2)) if (isoccluded(player1.o.x, player1.o.y, position.x - rad,
position.z - rad, rad * 2))
return; return;
delayedload(m); delayedload(m);
@ -102,8 +103,8 @@ rendermodel(OFString *mdl, int frame, int range, int tex, float rad, float x,
glBindTexture(GL_TEXTURE_2D, glBindTexture(GL_TEXTURE_2D,
tex ? lookuptexture(tex, &xs, &ys) : FIRSTMDL + m.mdlnum); tex ? lookuptexture(tex, &xs, &ys) : FIRSTMDL + m.mdlnum);
int ix = (int)x; int ix = (int)position.x;
int iy = (int)z; int iy = (int)position.z;
OFVector3D light = OFMakeVector3D(1, 1, 1); OFVector3D light = OFMakeVector3D(1, 1, 1);
if (!OUTBORD(ix, iy)) { if (!OUTBORD(ix, iy)) {
@ -124,9 +125,7 @@ rendermodel(OFString *mdl, int frame, int range, int tex, float rad, float x,
[m renderWithLight:light [m renderWithLight:light
frame:frame frame:frame
range:range range:range
x:x position:position
y:y
z:z
yaw:yaw yaw:yaw
pitch:pitch pitch:pitch
scale:scale scale:scale

View file

@ -3,21 +3,10 @@
#include "cube.h" #include "cube.h"
#import "Client.h"
enum { ST_EMPTY, ST_LOCAL, ST_TCPIP }; enum { ST_EMPTY, ST_LOCAL, ST_TCPIP };
// server side version of "dynent" type
@interface Client: OFObject
@property (nonatomic) int type;
@property (nonatomic) ENetPeer *peer;
@property (copy, nonatomic) OFString *hostname;
@property (copy, nonatomic) OFString *mapvote;
@property (copy, nonatomic) OFString *name;
@property (nonatomic) int modevote;
@end
@implementation Client
@end
static OFMutableArray<Client *> *clients; static OFMutableArray<Client *> *clients;
int maxclients = 8; int maxclients = 8;
@ -359,7 +348,7 @@ addclient()
if (client.type == ST_EMPTY) if (client.type == ST_EMPTY)
return client; return client;
Client *client = [[Client alloc] init]; Client *client = [Client client];
if (clients == nil) if (clients == nil)
clients = [[OFMutableArray alloc] init]; clients = [[OFMutableArray alloc] init];

View file

@ -4,80 +4,16 @@
#include "SDL_thread.h" #include "SDL_thread.h"
#include "cube.h" #include "cube.h"
#import "ResolverResult.h"
#import "ResolverThread.h"
#import "ServerInfo.h" #import "ServerInfo.h"
@interface ResolverThread: OFThread
{
volatile bool _stop;
}
@property (copy, nonatomic) OFString *query;
@property (nonatomic) int starttime;
@end
@interface ResolverResult: OFObject
@property (readonly, nonatomic) OFString *query;
@property (readonly, nonatomic) ENetAddress address;
- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithQuery:(OFString *)query address:(ENetAddress)address;
@end
static OFMutableArray<ResolverThread *> *resolverthreads; static OFMutableArray<ResolverThread *> *resolverthreads;
static OFMutableArray<OFString *> *resolverqueries; OFMutableArray<OFString *> *resolverqueries;
static OFMutableArray<ResolverResult *> *resolverresults; OFMutableArray<ResolverResult *> *resolverresults;
static SDL_sem *resolversem; SDL_sem *resolversem;
static int resolverlimit = 1000; static int resolverlimit = 1000;
@implementation ResolverThread
- (id)main
{
while (!_stop) {
SDL_SemWait(resolversem);
@synchronized(ResolverThread.class) {
if (resolverqueries.count == 0)
continue;
_query = resolverqueries.lastObject;
[resolverqueries removeLastObject];
_starttime = lastmillis;
}
ENetAddress address = { ENET_HOST_ANY, CUBE_SERVINFO_PORT };
enet_address_set_host(&address, _query.UTF8String);
@synchronized(ResolverThread.class) {
[resolverresults addObject:[[ResolverResult alloc]
initWithQuery:_query
address:address]];
_query = NULL;
_starttime = 0;
}
}
return nil;
}
- (void)stop
{
_stop = true;
}
@end
@implementation ResolverResult
- (instancetype)initWithQuery:(OFString *)query address:(ENetAddress)address
{
self = [super init];
_query = query;
_address = address;
return self;
}
@end
void void
resolverinit(int threads, int limit) resolverinit(int threads, int limit)
{ {
@ -88,7 +24,7 @@ resolverinit(int threads, int limit)
resolversem = SDL_CreateSemaphore(0); resolversem = SDL_CreateSemaphore(0);
while (threads > 0) { while (threads > 0) {
ResolverThread *rt = [[ResolverThread alloc] init]; ResolverThread *rt = [ResolverThread thread];
rt.name = @"resolverthread"; rt.name = @"resolverthread";
[resolverthreads addObject:rt]; [resolverthreads addObject:rt];
[rt start]; [rt start];
@ -104,7 +40,7 @@ resolverstop(size_t i, bool restart)
[rt stop]; [rt stop];
if (restart) { if (restart) {
rt = [[ResolverThread alloc] init]; rt = [ResolverThread thread];
rt.name = @"resolverthread"; rt.name = @"resolverthread";
resolverthreads[i] = rt; resolverthreads[i] = rt;
@ -187,7 +123,7 @@ addserver(OFString *servername)
if (servers == nil) if (servers == nil)
servers = [[OFMutableArray alloc] init]; servers = [[OFMutableArray alloc] init];
[servers addObject:[[ServerInfo alloc] initWithName:servername]]; [servers addObject:[ServerInfo infoWithName:servername]];
} }
void void
@ -280,19 +216,19 @@ refreshservers()
ServerInfo *si, size_t i, bool *stop) { ServerInfo *si, size_t i, bool *stop) {
if (si.address.host != ENET_HOST_ANY && si.ping != 9999) { if (si.address.host != ENET_HOST_ANY && si.ping != 9999) {
if (si.protocol != PROTOCOL_VERSION) if (si.protocol != PROTOCOL_VERSION)
si.full = [[OFString alloc] si.full = [OFString
initWithFormat: stringWithFormat:
@"%@ [different cube protocol]", @"%@ [different cube protocol]",
si.name]; si.name];
else else
si.full = [[OFString alloc] si.full = [OFString
initWithFormat:@"%d\t%d\t%@, %@: %@ %@", stringWithFormat:@"%d\t%d\t%@, %@: %@ %@",
si.ping, si.numplayers, si.ping, si.numplayers,
si.map.length > 0 ? si.map : @"[unknown]", si.map.length > 0 ? si.map : @"[unknown]",
modestr(si.mode), si.name, si.sdesc]; modestr(si.mode), si.name, si.sdesc];
} else } else
si.full = [[OFString alloc] si.full = [OFString
initWithFormat: stringWithFormat:
(si.address.host != ENET_HOST_ANY (si.address.host != ENET_HOST_ANY
? @"%@ [waiting for server response]" ? @"%@ [waiting for server response]"
: @"%@ [unknown host]\t"), : @"%@ [unknown host]\t"),

View file

@ -158,8 +158,7 @@ servermsinit(OFString *master_, OFString *sdesc, bool listen)
if (!mid) if (!mid)
mid = master; mid = master;
masterpath = @(mid); masterpath = @(mid);
masterbase = [[OFString alloc] initWithUTF8String:master masterbase = [OFString stringWithUTF8String:master length:mid - master];
length:mid - master];
serverdesc = sdesc; serverdesc = sdesc;
if (listen) { if (listen) {

View file

@ -148,10 +148,8 @@ newprojectile(OFVector3D &from, OFVector3D &to, float speed, bool local,
for (size_t i = 0; i < MAXPROJ; i++) { for (size_t i = 0; i < MAXPROJ; i++) {
Projectile *p = projs[i]; Projectile *p = projs[i];
if (p == nil) { if (p == nil)
p = [[Projectile alloc] init]; projs[i] = p = [Projectile projectile];
projs[i] = p;
}
if (p.inuse) if (p.inuse)
continue; continue;
@ -354,8 +352,8 @@ hitpush(int target, int damage, DynamicEntity *d, DynamicEntity *at,
} }
void void
raydamage( raydamage(DynamicEntity *o, const OFVector3D &from, const OFVector3D &to,
DynamicEntity *o, const OFVector3D &from, const OFVector3D &to, DynamicEntity *d, int i) DynamicEntity *d, int i)
{ {
if (o.state != CS_ALIVE) if (o.state != CS_ALIVE)
return; return;