DELETED src/Client.mm Index: src/Client.mm ================================================================== --- src/Client.mm +++ /dev/null @@ -1,8 +0,0 @@ -#import "Client.h" - -@implementation Client -+ (instancetype)client -{ - return [[self alloc] init]; -} -@end ADDED src/Command.m Index: src/Command.m ================================================================== --- /dev/null +++ src/Command.m @@ -0,0 +1,163 @@ +#import "Command.h" +#import "OFString+Cube.h" + +#include + +static OFArray * +padArguments(OFArray *arguments, size_t count) +{ + OFMutableArray *copy; + + if (arguments.count >= count) + return arguments; + + copy = [arguments mutableCopy]; + while (copy.count < count) + [copy addObject:@""]; + + [copy makeImmutable]; + return copy; +} + +@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 + function:(void (*)())function + argumentsTypes:(int)argumentsTypes +{ + self = [super initWithName:name]; + + _function = function; + _argumentsTypes = argumentsTypes; + + return self; +} + +- (int)callWithArguments:(OFArray *)arguments isDown:(bool)isDown +{ + switch (_argumentsTypes) { + case ARG_1INT: + if (isDown) { + arguments = padArguments(arguments, 2); + ((void(__cdecl *)(int))_function)( + [arguments[1] cube_intValueWithBase:0]); + } + break; + case ARG_2INT: + if (isDown) { + arguments = padArguments(arguments, 3); + ((void(__cdecl *)(int, int))_function)( + [arguments[1] cube_intValueWithBase:0], + [arguments[2] cube_intValueWithBase:0]); + } + break; + case ARG_3INT: + if (isDown) { + arguments = padArguments(arguments, 4); + ((void(__cdecl *)(int, int, int))_function)( + [arguments[1] cube_intValueWithBase:0], + [arguments[2] cube_intValueWithBase:0], + [arguments[3] cube_intValueWithBase:0]); + } + break; + case ARG_4INT: + if (isDown) { + arguments = padArguments(arguments, 5); + ((void(__cdecl *)(int, int, int, int))_function)( + [arguments[1] cube_intValueWithBase:0], + [arguments[2] cube_intValueWithBase:0], + [arguments[3] cube_intValueWithBase:0], + [arguments[4] cube_intValueWithBase:0]); + } + break; + case ARG_NONE: + if (isDown) + ((void(__cdecl *)())_function)(); + break; + case ARG_1STR: + if (isDown) { + arguments = padArguments(arguments, 2); + ((void(__cdecl *)(OFString *))_function)(arguments[1]); + } + break; + case ARG_2STR: + if (isDown) { + arguments = padArguments(arguments, 3); + ((void(__cdecl *)(OFString *, OFString *))_function)( + arguments[1], arguments[2]); + } + break; + case ARG_3STR: + if (isDown) { + arguments = padArguments(arguments, 4); + ((void(__cdecl *)( + OFString *, OFString *, OFString *))_function)( + arguments[1], arguments[2], arguments[3]); + } + break; + case ARG_5STR: + if (isDown) { + arguments = padArguments(arguments, 6); + ((void(__cdecl *)(OFString *, OFString *, OFString *, + OFString *, OFString *))_function)(arguments[1], + arguments[2], arguments[3], arguments[4], + arguments[5]); + } + break; + case ARG_DOWN: + ((void(__cdecl *)(bool))_function)(isDown); + break; + case ARG_DWN1: + arguments = padArguments(arguments, 2); + ((void(__cdecl *)(bool, OFString *))_function)( + isDown, arguments[1]); + break; + case ARG_1EXP: + if (isDown) { + arguments = padArguments(arguments, 2); + return ((int(__cdecl *)(int))_function)( + execute(arguments[1], isDown)); + } + break; + case ARG_2EXP: + if (isDown) { + arguments = padArguments(arguments, 3); + return ((int(__cdecl *)(int, int))_function)( + execute(arguments[1], isDown), + execute(arguments[2], isDown)); + } + break; + case ARG_1EST: + if (isDown) { + arguments = padArguments(arguments, 2); + return ((int(__cdecl *)(OFString *))_function)( + arguments[1]); + } + break; + case ARG_2EST: + if (isDown) { + arguments = padArguments(arguments, 3); + return ((int(__cdecl *)(OFString *, + OFString *))_function)(arguments[1], arguments[2]); + } + break; + case ARG_VARI: + if (isDown) + // limit, remove + ((void(__cdecl *)(OFString *))_function)([[arguments + objectsInRange:OFMakeRange(1, arguments.count - 1)] + componentsJoinedByString:@" "]); + break; + } + + return 0; +} +@end DELETED src/Command.mm Index: src/Command.mm ================================================================== --- src/Command.mm +++ /dev/null @@ -1,163 +0,0 @@ -#import "Command.h" -#import "OFString+Cube.h" - -#include - -static OFArray * -padArguments(OFArray *arguments, size_t count) -{ - OFMutableArray *copy; - - if (arguments.count >= count) - return arguments; - - copy = [arguments mutableCopy]; - while (copy.count < count) - [copy addObject:@""]; - - [copy makeImmutable]; - return copy; -} - -@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 - function:(void (*)())function - argumentsTypes:(int)argumentsTypes -{ - self = [super initWithName:name]; - - _function = function; - _argumentsTypes = argumentsTypes; - - return self; -} - -- (int)callWithArguments:(OFArray *)arguments isDown:(bool)isDown -{ - switch (_argumentsTypes) { - case ARG_1INT: - if (isDown) { - arguments = padArguments(arguments, 2); - ((void(__cdecl *)(int))_function)( - [arguments[1] cube_intValueWithBase:0]); - } - break; - case ARG_2INT: - if (isDown) { - arguments = padArguments(arguments, 3); - ((void(__cdecl *)(int, int))_function)( - [arguments[1] cube_intValueWithBase:0], - [arguments[2] cube_intValueWithBase:0]); - } - break; - case ARG_3INT: - if (isDown) { - arguments = padArguments(arguments, 4); - ((void(__cdecl *)(int, int, int))_function)( - [arguments[1] cube_intValueWithBase:0], - [arguments[2] cube_intValueWithBase:0], - [arguments[3] cube_intValueWithBase:0]); - } - break; - case ARG_4INT: - if (isDown) { - arguments = padArguments(arguments, 5); - ((void(__cdecl *)(int, int, int, int))_function)( - [arguments[1] cube_intValueWithBase:0], - [arguments[2] cube_intValueWithBase:0], - [arguments[3] cube_intValueWithBase:0], - [arguments[4] cube_intValueWithBase:0]); - } - break; - case ARG_NONE: - if (isDown) - ((void(__cdecl *)())_function)(); - break; - case ARG_1STR: - if (isDown) { - arguments = padArguments(arguments, 2); - ((void(__cdecl *)(OFString *))_function)(arguments[1]); - } - break; - case ARG_2STR: - if (isDown) { - arguments = padArguments(arguments, 3); - ((void(__cdecl *)(OFString *, OFString *))_function)( - arguments[1], arguments[2]); - } - break; - case ARG_3STR: - if (isDown) { - arguments = padArguments(arguments, 4); - ((void(__cdecl *)( - OFString *, OFString *, OFString *))_function)( - arguments[1], arguments[2], arguments[3]); - } - break; - case ARG_5STR: - if (isDown) { - arguments = padArguments(arguments, 6); - ((void(__cdecl *)(OFString *, OFString *, OFString *, - OFString *, OFString *))_function)(arguments[1], - arguments[2], arguments[3], arguments[4], - arguments[5]); - } - break; - case ARG_DOWN: - ((void(__cdecl *)(bool))_function)(isDown); - break; - case ARG_DWN1: - arguments = padArguments(arguments, 2); - ((void(__cdecl *)(bool, OFString *))_function)( - isDown, arguments[1]); - break; - case ARG_1EXP: - if (isDown) { - arguments = padArguments(arguments, 2); - return ((int(__cdecl *)(int))_function)( - execute(arguments[1], isDown)); - } - break; - case ARG_2EXP: - if (isDown) { - arguments = padArguments(arguments, 3); - return ((int(__cdecl *)(int, int))_function)( - execute(arguments[1], isDown), - execute(arguments[2], isDown)); - } - break; - case ARG_1EST: - if (isDown) { - arguments = padArguments(arguments, 2); - return ((int(__cdecl *)(OFString *))_function)( - arguments[1]); - } - break; - case ARG_2EST: - if (isDown) { - arguments = padArguments(arguments, 3); - return ((int(__cdecl *)(OFString *, - OFString *))_function)(arguments[1], arguments[2]); - } - break; - case ARG_VARI: - if (isDown) - // limit, remove - ((void(__cdecl *)(OFString *))_function)([[arguments - objectsInRange:OFMakeRange(1, arguments.count - 1)] - componentsJoinedByString:@" "]); - break; - } - - return 0; -} -@end ADDED src/DynamicEntity.m Index: src/DynamicEntity.m ================================================================== --- /dev/null +++ src/DynamicEntity.m @@ -0,0 +1,235 @@ +#import "DynamicEntity.h" + +#include "cube.h" + +struct dynent { + OFVector3D o, vel; + float yaw, pitch, roll; + float maxspeed; + bool outsidemap; + bool inwater; + bool onfloor, jumpnext; + int move, strafe; + bool k_left, k_right, k_up, k_down; + int timeinair; + float radius, eyeheight, aboveeye; + int lastupdate, plag, ping; + int lifesequence; + int state; + int frags; + int health, armour, armourtype, quadmillis; + int gunselect, gunwait; + int lastaction, lastattackgun, lastmove; + bool attacking; + int ammo[NUMGUNS]; + int monsterstate; + int mtype; + void *enemy; + float targetyaw; + bool blocked, moving; + int trigger; + OFVector3D attacktarget; + int anger; + char name[260], team[260]; +}; + +@implementation DynamicEntity ++ (size_t)serializedSize +{ + return sizeof(struct dynent); +} + +- (instancetype)init +{ + self = [super init]; + + _ammo = (int *)OFAllocZeroedMemory(NUMGUNS, sizeof(int)); + + return self; +} + +- (void)dealloc +{ + OFFreeMemory(_ammo); +} + +- (id)copy +{ + DynamicEntity *copy = [[self.class alloc] init]; + + copy->_o = _o; + copy->_vel = _vel; + copy->_yaw = _yaw; + copy->_pitch = _pitch; + copy->_roll = _roll; + copy->_maxspeed = _maxspeed; + copy->_outsidemap = _outsidemap; + copy->_inwater = _inwater; + copy->_onfloor = _onfloor; + copy->_jumpnext = _jumpnext; + copy->_move = _move; + copy->_strafe = _strafe; + copy->_k_left = _k_left; + copy->_k_right = _k_right; + copy->_k_up = _k_up; + copy->_k_down = _k_down; + copy->_timeinair = _timeinair; + copy->_radius = _radius; + copy->_eyeheight = _eyeheight; + copy->_aboveeye = _aboveeye; + copy->_lastupdate = _lastupdate; + copy->_plag = _plag; + copy->_ping = _ping; + copy->_lifesequence = _lifesequence; + copy->_state = _state; + copy->_frags = _frags; + copy->_health = _health; + copy->_armour = _armour; + copy->_armourtype = _armourtype; + copy->_quadmillis = _quadmillis; + copy->_gunselect = _gunselect; + copy->_gunwait = _gunwait; + copy->_lastaction = _lastaction; + copy->_lastattackgun = _lastattackgun; + copy->_lastmove = _lastmove; + copy->_attacking = _attacking; + + for (size_t i = 0; i < NUMGUNS; i++) + copy->_ammo[i] = _ammo[i]; + + copy->_monsterstate = _monsterstate; + copy->_mtype = _mtype; + copy->_enemy = _enemy; + copy->_targetyaw = _targetyaw; + copy->_blocked = _blocked; + copy->_moving = _moving; + copy->_trigger = _trigger; + copy->_attacktarget = _attacktarget; + copy->_anger = _anger; + + copy->_name = [_name copy]; + copy->_team = [_team copy]; + + return copy; +} + +- (OFData *)dataBySerializing +{ + // This is frighteningly *TERRIBLE*, but the format used by existing + // savegames. + struct dynent data = { .o = _o, + .vel = _vel, + .yaw = _yaw, + .pitch = _pitch, + .roll = _roll, + .maxspeed = _maxspeed, + .outsidemap = _outsidemap, + .inwater = _inwater, + .onfloor = _onfloor, + .jumpnext = _jumpnext, + .move = _move, + .strafe = _strafe, + .k_left = _k_left, + .k_right = _k_right, + .k_up = _k_up, + .k_down = _k_down, + .timeinair = _timeinair, + .radius = _radius, + .eyeheight = _eyeheight, + .aboveeye = _aboveeye, + .lastupdate = _lastupdate, + .plag = _plag, + .ping = _ping, + .lifesequence = _lifesequence, + .state = _state, + .frags = _frags, + .health = _health, + .armour = _armour, + .armourtype = _armourtype, + .quadmillis = _quadmillis, + .gunselect = _gunselect, + .gunwait = _gunwait, + .lastaction = _lastaction, + .lastattackgun = _lastattackgun, + .lastmove = _lastmove, + .attacking = _attacking, + .monsterstate = _monsterstate, + .mtype = _mtype, + .targetyaw = _targetyaw, + .blocked = _blocked, + .moving = _moving, + .trigger = _trigger, + .attacktarget = _attacktarget, + .anger = _anger }; + + for (int i = 0; i < NUMGUNS; i++) + data.ammo[i] = _ammo[i]; + + memcpy(data.name, _name.UTF8String, min(_name.UTF8StringLength, 259)); + memcpy(data.team, _team.UTF8String, min(_team.UTF8StringLength, 259)); + + return [OFData dataWithItems:&data count:sizeof(data)]; +} + +- (void)setFromSerializedData:(OFData *)data +{ + struct dynent d; + + if (data.count != sizeof(struct dynent)) + @throw [OFOutOfRangeException exception]; + + memcpy(&d, data.items, data.count); + + _o = d.o; + _vel = d.vel; + _yaw = d.yaw; + _pitch = d.pitch; + _roll = d.roll; + _maxspeed = d.maxspeed; + _outsidemap = d.outsidemap; + _inwater = d.inwater; + _onfloor = d.onfloor; + _jumpnext = d.jumpnext; + _move = d.move; + _strafe = d.strafe; + _k_left = d.k_left; + _k_right = d.k_right; + _k_up = d.k_up; + _k_down = d.k_down; + _timeinair = d.timeinair; + _radius = d.radius; + _eyeheight = d.eyeheight; + _aboveeye = d.aboveeye; + _lastupdate = d.lastupdate; + _plag = d.plag; + _ping = d.ping; + _lifesequence = d.lifesequence; + _state = d.state; + _frags = d.frags; + _health = d.health; + _armour = d.armour; + _armourtype = d.armourtype; + _quadmillis = d.quadmillis; + _gunselect = d.gunselect; + _gunwait = d.gunwait; + _lastaction = d.lastaction; + _lastattackgun = d.lastattackgun; + _lastmove = d.lastmove; + _attacking = d.attacking; + + for (int i = 0; i < NUMGUNS; i++) + _ammo[i] = d.ammo[i]; + + _monsterstate = d.monsterstate; + _mtype = d.mtype; + _targetyaw = d.targetyaw; + _blocked = d.blocked; + _moving = d.moving; + _trigger = d.trigger; + _attacktarget = d.attacktarget; + _anger = d.anger; + + _name = [[OFString alloc] initWithUTF8String:d.name]; + _team = [[OFString alloc] initWithUTF8String:d.team]; +} +@end DELETED src/DynamicEntity.mm Index: src/DynamicEntity.mm ================================================================== --- src/DynamicEntity.mm +++ /dev/null @@ -1,235 +0,0 @@ -#import "DynamicEntity.h" - -#include "cube.h" - -struct dynent { - OFVector3D o, vel; - float yaw, pitch, roll; - float maxspeed; - bool outsidemap; - bool inwater; - bool onfloor, jumpnext; - int move, strafe; - bool k_left, k_right, k_up, k_down; - int timeinair; - float radius, eyeheight, aboveeye; - int lastupdate, plag, ping; - int lifesequence; - int state; - int frags; - int health, armour, armourtype, quadmillis; - int gunselect, gunwait; - int lastaction, lastattackgun, lastmove; - bool attacking; - int ammo[NUMGUNS]; - int monsterstate; - int mtype; - void *enemy; - float targetyaw; - bool blocked, moving; - int trigger; - OFVector3D attacktarget; - int anger; - char name[260], team[260]; -}; - -@implementation DynamicEntity -+ (size_t)serializedSize -{ - return sizeof(dynent); -} - -- (instancetype)init -{ - self = [super init]; - - _ammo = (int *)OFAllocZeroedMemory(NUMGUNS, sizeof(int)); - - return self; -} - -- (void)dealloc -{ - OFFreeMemory(_ammo); -} - -- (id)copy -{ - DynamicEntity *copy = [[self.class alloc] init]; - - copy->_o = _o; - copy->_vel = _vel; - copy->_yaw = _yaw; - copy->_pitch = _pitch; - copy->_roll = _roll; - copy->_maxspeed = _maxspeed; - copy->_outsidemap = _outsidemap; - copy->_inwater = _inwater; - copy->_onfloor = _onfloor; - copy->_jumpnext = _jumpnext; - copy->_move = _move; - copy->_strafe = _strafe; - copy->_k_left = _k_left; - copy->_k_right = _k_right; - copy->_k_up = _k_up; - copy->_k_down = _k_down; - copy->_timeinair = _timeinair; - copy->_radius = _radius; - copy->_eyeheight = _eyeheight; - copy->_aboveeye = _aboveeye; - copy->_lastupdate = _lastupdate; - copy->_plag = _plag; - copy->_ping = _ping; - copy->_lifesequence = _lifesequence; - copy->_state = _state; - copy->_frags = _frags; - copy->_health = _health; - copy->_armour = _armour; - copy->_armourtype = _armourtype; - copy->_quadmillis = _quadmillis; - copy->_gunselect = _gunselect; - copy->_gunwait = _gunwait; - copy->_lastaction = _lastaction; - copy->_lastattackgun = _lastattackgun; - copy->_lastmove = _lastmove; - copy->_attacking = _attacking; - - for (size_t i = 0; i < NUMGUNS; i++) - copy->_ammo[i] = _ammo[i]; - - copy->_monsterstate = _monsterstate; - copy->_mtype = _mtype; - copy->_enemy = _enemy; - copy->_targetyaw = _targetyaw; - copy->_blocked = _blocked; - copy->_moving = _moving; - copy->_trigger = _trigger; - copy->_attacktarget = _attacktarget; - copy->_anger = _anger; - - copy->_name = [_name copy]; - copy->_team = [_team copy]; - - return copy; -} - -- (OFData *)dataBySerializing -{ - // This is frighteningly *TERRIBLE*, but the format used by existing - // savegames. - dynent data = { .o = _o, - .vel = _vel, - .yaw = _yaw, - .pitch = _pitch, - .roll = _roll, - .maxspeed = _maxspeed, - .outsidemap = _outsidemap, - .inwater = _inwater, - .onfloor = _onfloor, - .jumpnext = _jumpnext, - .move = _move, - .strafe = _strafe, - .k_left = _k_left, - .k_right = _k_right, - .k_up = _k_up, - .k_down = _k_down, - .timeinair = _timeinair, - .radius = _radius, - .eyeheight = _eyeheight, - .aboveeye = _aboveeye, - .lastupdate = _lastupdate, - .plag = _plag, - .ping = _ping, - .lifesequence = _lifesequence, - .state = _state, - .frags = _frags, - .health = _health, - .armour = _armour, - .armourtype = _armourtype, - .quadmillis = _quadmillis, - .gunselect = _gunselect, - .gunwait = _gunwait, - .lastaction = _lastaction, - .lastattackgun = _lastattackgun, - .lastmove = _lastmove, - .attacking = _attacking, - .monsterstate = _monsterstate, - .mtype = _mtype, - .targetyaw = _targetyaw, - .blocked = _blocked, - .moving = _moving, - .trigger = _trigger, - .attacktarget = _attacktarget, - .anger = _anger }; - - for (int i = 0; i < NUMGUNS; i++) - data.ammo[i] = _ammo[i]; - - memcpy(data.name, _name.UTF8String, min(_name.UTF8StringLength, 259)); - memcpy(data.team, _team.UTF8String, min(_team.UTF8StringLength, 259)); - - return [OFData dataWithItems:&data count:sizeof(data)]; -} - -- (void)setFromSerializedData:(OFData *)data -{ - struct dynent d; - - if (data.count != sizeof(dynent)) - @throw [OFOutOfRangeException exception]; - - memcpy(&d, data.items, data.count); - - _o = d.o; - _vel = d.vel; - _yaw = d.yaw; - _pitch = d.pitch; - _roll = d.roll; - _maxspeed = d.maxspeed; - _outsidemap = d.outsidemap; - _inwater = d.inwater; - _onfloor = d.onfloor; - _jumpnext = d.jumpnext; - _move = d.move; - _strafe = d.strafe; - _k_left = d.k_left; - _k_right = d.k_right; - _k_up = d.k_up; - _k_down = d.k_down; - _timeinair = d.timeinair; - _radius = d.radius; - _eyeheight = d.eyeheight; - _aboveeye = d.aboveeye; - _lastupdate = d.lastupdate; - _plag = d.plag; - _ping = d.ping; - _lifesequence = d.lifesequence; - _state = d.state; - _frags = d.frags; - _health = d.health; - _armour = d.armour; - _armourtype = d.armourtype; - _quadmillis = d.quadmillis; - _gunselect = d.gunselect; - _gunwait = d.gunwait; - _lastaction = d.lastaction; - _lastattackgun = d.lastattackgun; - _lastmove = d.lastmove; - _attacking = d.attacking; - - for (int i = 0; i < NUMGUNS; i++) - _ammo[i] = d.ammo[i]; - - _monsterstate = d.monsterstate; - _mtype = d.mtype; - _targetyaw = d.targetyaw; - _blocked = d.blocked; - _moving = d.moving; - _trigger = d.trigger; - _attacktarget = d.attacktarget; - _anger = d.anger; - - _name = [[OFString alloc] initWithUTF8String:d.name]; - _team = [[OFString alloc] initWithUTF8String:d.team]; -} -@end ADDED src/MD2.m Index: src/MD2.m ================================================================== --- /dev/null +++ src/MD2.m @@ -0,0 +1,216 @@ +#import "MD2.h" + +#include "cube.h" + +struct md2_header { + int magic; + int version; + int skinWidth, skinHeight; + int frameSize; + int numSkins, numVertices, numTexcoords; + int numTriangles, numGlCommands, numFrames; + int offsetSkins, offsetTexcoords, offsetTriangles; + int offsetFrames, offsetGlCommands, offsetEnd; +}; + +struct md2_vertex { + uchar vertex[3], lightNormalIndex; +}; + +struct md2_frame { + float scale[3]; + float translate[3]; + char name[16]; + struct md2_vertex vertices[1]; +}; + +static float +snap(int sn, float f) +{ + return sn ? (float)(((int)(f + sn * 0.5f)) & (~(sn - 1))) : f; +} + +@implementation MD2 +{ + int _numGlCommands; + int *_glCommands; + int _numTriangles; + int _frameSize; + int _numFrames; + int _numVerts; + char *_frames; + OFVector3D **_mverts; + int _displaylist; + int _displaylistverts; +} + ++ (instancetype)md2 +{ + return [[self alloc] init]; +} + +- (void)dealloc +{ + OFFreeMemory(_glCommands); + OFFreeMemory(_frames); + + if (_mverts != NULL) + for (size_t i = 0; i < _numFrames; i++) + OFFreeMemory(_mverts[i]); + + OFFreeMemory(_mverts); +} + +- (bool)loadWithIRI:(OFIRI *)IRI +{ + OFSeekableStream *stream; + @try { + stream = (OFSeekableStream *)[[OFIRIHandler handlerForIRI:IRI] + openItemAtIRI:IRI + mode:@"r"]; + } @catch (id e) { + return false; + } + + if (![stream isKindOfClass:OFSeekableStream.class]) + return false; + + struct md2_header header; + [stream readIntoBuffer:&header exactLength:sizeof(header)]; + endianswap(&header, sizeof(int), sizeof(header) / sizeof(int)); + + if (header.magic != 844121161 || header.version != 8) + return false; + + @try { + _frames = OFAllocMemory(header.numFrames, header.frameSize); + } @catch (OFOutOfMemoryException *e) { + return false; + } + + [stream seekToOffset:header.offsetFrames whence:OFSeekSet]; + [stream readIntoBuffer:_frames + exactLength:header.frameSize * header.numFrames]; + + for (int i = 0; i < header.numFrames; ++i) + endianswap(_frames + i * header.frameSize, sizeof(float), 6); + + @try { + _glCommands = OFAllocMemory(header.numGlCommands, sizeof(int)); + } @catch (OFOutOfMemoryException *e) { + return false; + } + + [stream seekToOffset:header.offsetGlCommands whence:OFSeekSet]; + [stream readIntoBuffer:_glCommands + exactLength:header.numGlCommands * sizeof(int)]; + endianswap(_glCommands, sizeof(int), header.numGlCommands); + + _numFrames = header.numFrames; + _numGlCommands = header.numGlCommands; + _frameSize = header.frameSize; + _numTriangles = header.numTriangles; + _numVerts = header.numVertices; + + [stream close]; + + _mverts = OFAllocZeroedMemory(_numFrames, sizeof(OFVector3D *)); + + return true; +} + +- (void)scaleWithFrame:(int)frame scale:(float)scale snap:(int)sn +{ + OFAssert(_mverts[frame] == NULL); + + _mverts[frame] = OFAllocMemory(_numVerts, sizeof(OFVector3D)); + struct md2_frame *cf = + (struct md2_frame *)((char *)_frames + _frameSize * frame); + float sc = 16.0f / scale; + loop(vi, _numVerts) + { + uchar *cv = (uchar *)&cf->vertices[vi].vertex; + OFVector3D *v = &(_mverts[frame])[vi]; + v->x = (snap(sn, cv[0] * cf->scale[0]) + cf->translate[0]) / sc; + v->y = + -(snap(sn, cv[1] * cf->scale[1]) + cf->translate[1]) / sc; + v->z = (snap(sn, cv[2] * cf->scale[2]) + cf->translate[2]) / sc; + } +} + +- (void)renderWithLight:(OFVector3D)light + frame:(int)frame + range:(int)range + position:(OFVector3D)position + yaw:(float)yaw + pitch:(float)pitch + scale:(float)sc + speed:(float)speed + snap:(int)sn + basetime:(int)basetime +{ + loopi(range) if (!_mverts[frame + i])[self scaleWithFrame:frame + i + scale:sc + snap:sn]; + + glPushMatrix(); + glTranslatef(position.x, position.y, position.z); + glRotatef(yaw + 180, 0, -1, 0); + glRotatef(pitch, 0, 0, 1); + + glColor3fv((float *)&light); + + if (_displaylist && frame == 0 && range == 1) { + glCallList(_displaylist); + xtraverts += _displaylistverts; + } else { + if (frame == 0 && range == 1) { + static int displaylistn = 10; + glNewList(_displaylist = displaylistn++, GL_COMPILE); + _displaylistverts = xtraverts; + } + + int time = lastmillis - basetime; + int fr1 = (int)(time / speed); + float frac1 = (time - fr1 * speed) / speed; + float frac2 = 1 - frac1; + fr1 = fr1 % range + frame; + int fr2 = fr1 + 1; + if (fr2 >= frame + range) + fr2 = frame; + OFVector3D *verts1 = _mverts[fr1]; + OFVector3D *verts2 = _mverts[fr2]; + + for (int *command = _glCommands; (*command) != 0;) { + int numVertex = *command++; + if (numVertex > 0) { + glBegin(GL_TRIANGLE_STRIP); + } else { + glBegin(GL_TRIANGLE_FAN); + numVertex = -numVertex; + } + + loopi(numVertex) + { + float tu = *((float *)command++); + float tv = *((float *)command++); + glTexCoord2f(tu, tv); + int vn = *command++; +#define ip(c) verts1[vn].c *frac2 + verts2[vn].c *frac1 + glVertex3f(ip(x), ip(z), ip(y)); + } + + xtraverts += numVertex; + + glEnd(); + } + + if (_displaylist) { + glEndList(); + _displaylistverts = xtraverts - _displaylistverts; + } + } + + glPopMatrix(); +} +@end DELETED src/MD2.mm Index: src/MD2.mm ================================================================== --- src/MD2.mm +++ /dev/null @@ -1,208 +0,0 @@ -#import "MD2.h" - -#include "cube.h" - -struct md2_header { - int magic; - int version; - int skinWidth, skinHeight; - int frameSize; - int numSkins, numVertices, numTexcoords; - int numTriangles, numGlCommands, numFrames; - int offsetSkins, offsetTexcoords, offsetTriangles; - int offsetFrames, offsetGlCommands, offsetEnd; -}; - -struct md2_vertex { - uchar vertex[3], lightNormalIndex; -}; - -struct md2_frame { - float scale[3]; - float translate[3]; - char name[16]; - md2_vertex vertices[1]; -}; - -static float -snap(int sn, float f) -{ - return sn ? (float)(((int)(f + sn * 0.5f)) & (~(sn - 1))) : f; -} - -@implementation MD2 -{ - int _numGlCommands; - int *_glCommands; - int _numTriangles; - int _frameSize; - int _numFrames; - int _numVerts; - char *_frames; - OFVector3D **_mverts; - int _displaylist; - int _displaylistverts; -} - -+ (instancetype)md2 -{ - return [[self alloc] init]; -} - -- (void)dealloc -{ - if (_glCommands) - delete[] _glCommands; - if (_frames) - delete[] _frames; -} - -- (bool)loadWithIRI:(OFIRI *)IRI -{ - OFSeekableStream *stream; - @try { - stream = (OFSeekableStream *)[[OFIRIHandler handlerForIRI:IRI] - openItemAtIRI:IRI - mode:@"r"]; - } @catch (id e) { - return false; - } - - if (![stream isKindOfClass:OFSeekableStream.class]) - return false; - - md2_header header; - [stream readIntoBuffer:&header exactLength:sizeof(md2_header)]; - endianswap(&header, sizeof(int), sizeof(md2_header) / sizeof(int)); - - if (header.magic != 844121161 || header.version != 8) - return false; - - _frames = new char[header.frameSize * header.numFrames]; - if (_frames == NULL) - return false; - - [stream seekToOffset:header.offsetFrames whence:OFSeekSet]; - [stream readIntoBuffer:_frames - exactLength:header.frameSize * header.numFrames]; - - for (int i = 0; i < header.numFrames; ++i) - endianswap(_frames + i * header.frameSize, sizeof(float), 6); - - _glCommands = new int[header.numGlCommands]; - if (_glCommands == NULL) - return false; - - [stream seekToOffset:header.offsetGlCommands whence:OFSeekSet]; - [stream readIntoBuffer:_glCommands - exactLength:header.numGlCommands * sizeof(int)]; - endianswap(_glCommands, sizeof(int), header.numGlCommands); - - _numFrames = header.numFrames; - _numGlCommands = header.numGlCommands; - _frameSize = header.frameSize; - _numTriangles = header.numTriangles; - _numVerts = header.numVertices; - - [stream close]; - - _mverts = new OFVector3D *[_numFrames]; - loopj(_numFrames) _mverts[j] = NULL; - - return true; -} - -- (void)scaleWithFrame:(int)frame scale:(float)scale snap:(int)sn -{ - _mverts[frame] = new OFVector3D[_numVerts]; - md2_frame *cf = (md2_frame *)((char *)_frames + _frameSize * frame); - float sc = 16.0f / scale; - loop(vi, _numVerts) - { - uchar *cv = (uchar *)&cf->vertices[vi].vertex; - OFVector3D *v = &(_mverts[frame])[vi]; - v->x = (snap(sn, cv[0] * cf->scale[0]) + cf->translate[0]) / sc; - v->y = - -(snap(sn, cv[1] * cf->scale[1]) + cf->translate[1]) / sc; - v->z = (snap(sn, cv[2] * cf->scale[2]) + cf->translate[2]) / sc; - } -} - -- (void)renderWithLight:(OFVector3D)light - frame:(int)frame - range:(int)range - position:(OFVector3D)position - yaw:(float)yaw - pitch:(float)pitch - scale:(float)sc - speed:(float)speed - snap:(int)sn - basetime:(int)basetime -{ - loopi(range) if (!_mverts[frame + i])[self scaleWithFrame:frame + i - scale:sc - snap:sn]; - - glPushMatrix(); - glTranslatef(position.x, position.y, position.z); - glRotatef(yaw + 180, 0, -1, 0); - glRotatef(pitch, 0, 0, 1); - - glColor3fv((float *)&light); - - if (_displaylist && frame == 0 && range == 1) { - glCallList(_displaylist); - xtraverts += _displaylistverts; - } else { - if (frame == 0 && range == 1) { - static int displaylistn = 10; - glNewList(_displaylist = displaylistn++, GL_COMPILE); - _displaylistverts = xtraverts; - } - - int time = lastmillis - basetime; - int fr1 = (int)(time / speed); - float frac1 = (time - fr1 * speed) / speed; - float frac2 = 1 - frac1; - fr1 = fr1 % range + frame; - int fr2 = fr1 + 1; - if (fr2 >= frame + range) - fr2 = frame; - OFVector3D *verts1 = _mverts[fr1]; - OFVector3D *verts2 = _mverts[fr2]; - - for (int *command = _glCommands; (*command) != 0;) { - int numVertex = *command++; - if (numVertex > 0) { - glBegin(GL_TRIANGLE_STRIP); - } else { - glBegin(GL_TRIANGLE_FAN); - numVertex = -numVertex; - } - - loopi(numVertex) - { - float tu = *((float *)command++); - float tv = *((float *)command++); - glTexCoord2f(tu, tv); - int vn = *command++; - OFVector3D &v1 = verts1[vn]; - OFVector3D &v2 = verts2[vn]; -#define ip(c) v1.c *frac2 + v2.c *frac1 - glVertex3f(ip(x), ip(z), ip(y)); - } - - xtraverts += numVertex; - - glEnd(); - } - - if (_displaylist) { - glEndList(); - _displaylistverts = xtraverts - _displaylistverts; - } - } - - glPopMatrix(); -} -@end ADDED src/OFString+Cube.m Index: src/OFString+Cube.m ================================================================== --- /dev/null +++ src/OFString+Cube.m @@ -0,0 +1,32 @@ +#import "OFString+Cube.h" + +#include "cube.h" + +@implementation +OFString (Cube) +- (int)cube_intValue +{ + @try { + return self.intValue; + } @catch (OFInvalidFormatException *e) { + conoutf(@"invalid value: %@", self); + return 0; + } @catch (OFOutOfRangeException *e) { + conoutf(@"invalid value: %@", self); + return 0; + } +} + +- (int)cube_intValueWithBase:(unsigned char)base +{ + @try { + return [self intValueWithBase:base]; + } @catch (OFInvalidFormatException *e) { + conoutf(@"invalid value: %@", self); + return 0; + } @catch (OFOutOfRangeException *e) { + conoutf(@"invalid value: %@", self); + return 0; + } +} +@end DELETED src/OFString+Cube.mm Index: src/OFString+Cube.mm ================================================================== --- src/OFString+Cube.mm +++ /dev/null @@ -1,32 +0,0 @@ -#import "OFString+Cube.h" - -#include "cube.h" - -@implementation -OFString (Cube) -- (int)cube_intValue -{ - @try { - return self.intValue; - } @catch (OFInvalidFormatException *e) { - conoutf(@"invalid value: %@", self); - return 0; - } @catch (OFOutOfRangeException *e) { - conoutf(@"invalid value: %@", self); - return 0; - } -} - -- (int)cube_intValueWithBase:(unsigned char)base -{ - @try { - return [self intValueWithBase:base]; - } @catch (OFInvalidFormatException *e) { - conoutf(@"invalid value: %@", self); - return 0; - } @catch (OFOutOfRangeException *e) { - conoutf(@"invalid value: %@", self); - return 0; - } -} -@end ADDED src/ResolverResult.m Index: src/ResolverResult.m ================================================================== --- /dev/null +++ src/ResolverResult.m @@ -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 DELETED src/ResolverResult.mm Index: src/ResolverResult.mm ================================================================== --- src/ResolverResult.mm +++ /dev/null @@ -1,18 +0,0 @@ -#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 ADDED src/ResolverThread.m Index: src/ResolverThread.m ================================================================== --- /dev/null +++ src/ResolverThread.m @@ -0,0 +1,44 @@ +#import "ResolverThread.h" + +#import "ResolverResult.h" + +extern SDL_sem *resolversem; +extern OFMutableArray *resolverqueries; +extern OFMutableArray *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 DELETED src/ResolverThread.mm Index: src/ResolverThread.mm ================================================================== --- src/ResolverThread.mm +++ /dev/null @@ -1,44 +0,0 @@ -#import "ResolverThread.h" - -#import "ResolverResult.h" - -extern SDL_sem *resolversem; -extern OFMutableArray *resolverqueries; -extern OFMutableArray *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 ADDED src/ServerInfo.m Index: src/ServerInfo.m ================================================================== --- /dev/null +++ src/ServerInfo.m @@ -0,0 +1,42 @@ +#import "ServerInfo.h" + +#include "cube.h" + +@implementation ServerInfo ++ (instancetype)infoWithName:(OFString *)name; +{ + return [[self alloc] initWithName:name]; +} + +- (instancetype)initWithName:(OFString *)name +{ + self = [super init]; + + _name = [name copy]; + _full = @""; + _mode = 0; + _numplayers = 0; + _ping = 9999; + _protocol = 0; + _minremain = 0; + _map = @""; + _sdesc = @""; + _address.host = ENET_HOST_ANY; + _address.port = CUBE_SERVINFO_PORT; + + return self; +} + +- (OFComparisonResult)compare:(id)otherObject +{ + if (![otherObject isKindOfClass:ServerInfo.class]) + @throw [OFInvalidArgumentException exception]; + + if (_ping > [otherObject ping]) + return OFOrderedDescending; + if (_ping < [otherObject ping]) + return OFOrderedAscending; + + return [_name compare:[otherObject name]]; +} +@end DELETED src/ServerInfo.mm Index: src/ServerInfo.mm ================================================================== --- src/ServerInfo.mm +++ /dev/null @@ -1,42 +0,0 @@ -#import "ServerInfo.h" - -#include "cube.h" - -@implementation ServerInfo -+ (instancetype)infoWithName:(OFString *)name; -{ - return [[self alloc] initWithName:name]; -} - -- (instancetype)initWithName:(OFString *)name -{ - self = [super init]; - - _name = [name copy]; - _full = @""; - _mode = 0; - _numplayers = 0; - _ping = 9999; - _protocol = 0; - _minremain = 0; - _map = @""; - _sdesc = @""; - _address.host = ENET_HOST_ANY; - _address.port = CUBE_SERVINFO_PORT; - - return self; -} - -- (OFComparisonResult)compare:(id)otherObject -{ - if (![otherObject isKindOfClass:ServerInfo.class]) - @throw [OFInvalidArgumentException exception]; - - if (_ping > [otherObject ping]) - return OFOrderedDescending; - if (_ping < [otherObject ping]) - return OFOrderedAscending; - - return [_name compare:[otherObject name]]; -} -@end ADDED src/Variable.m Index: src/Variable.m ================================================================== --- /dev/null +++ src/Variable.m @@ -0,0 +1,72 @@ +#import "Variable.h" + +#include "cube.h" + +@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 + min:(int)min + max:(int)max + storage:(int *)storage + function:(void (*__cdecl)())function + persisted:(bool)persisted +{ + self = [super initWithName:name]; + + _min = min; + _max = max; + _storage = storage; + _function = function; + _persisted = persisted; + + return self; +} + +- (void)printValue +{ + conoutf(@"%@ = %d", self.name, *_storage); +} + +- (void)setValue:(int)value +{ + bool outOfRange = false; + + if (_min > _max) { + conoutf(@"variable is read-only"); + return; + } + + if (value < _min) { + value = _min; + outOfRange = true; + } + + if (value > _max) { + value = _max; + outOfRange = true; + } + + if (outOfRange) + conoutf(@"valid range for %@ is %d..%d", self.name, _min, _max); + + *_storage = value; + + if (_function != NULL) + // call trigger function if available + _function(); +} +@end DELETED src/Variable.mm Index: src/Variable.mm ================================================================== --- src/Variable.mm +++ /dev/null @@ -1,72 +0,0 @@ -#import "Variable.h" - -#include "cube.h" - -@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 - min:(int)min - max:(int)max - storage:(int *)storage - function:(void (*__cdecl)())function - persisted:(bool)persisted -{ - self = [super initWithName:name]; - - _min = min; - _max = max; - _storage = storage; - _function = function; - _persisted = persisted; - - return self; -} - -- (void)printValue -{ - conoutf(@"%@ = %d", self.name, *_storage); -} - -- (void)setValue:(int)value -{ - bool outOfRange = false; - - if (_min > _max) { - conoutf(@"variable is read-only"); - return; - } - - if (value < _min) { - value = _min; - outOfRange = true; - } - - if (value > _max) { - value = _max; - outOfRange = true; - } - - if (outOfRange) - conoutf(@"valid range for %@ is %d..%d", self.name, _min, _max); - - *_storage = value; - - if (_function != NULL) - // call trigger function if available - _function(); -} -@end ADDED src/client.m Index: src/client.m ================================================================== --- /dev/null +++ src/client.m @@ -0,0 +1,8 @@ +#import "Client.h" + +@implementation Client ++ (instancetype)client +{ + return [[self alloc] init]; +} +@end Index: src/cube.h ================================================================== --- src/cube.h +++ src/cube.h @@ -241,13 +241,16 @@ uchar r, g, b, a; }; // globals ooh naughty -extern sqr *world, - *wmip[]; // map data, the mips are sequential 2D arrays in memory -extern header hdr; // current map header +#ifdef __cplusplus +extern "C" { +#endif +// map data, the mips are sequential 2D arrays in memory +extern struct sqr *world, *wmip[]; +extern struct header hdr; // current map header extern int sfactor, ssize; // ssize = 2^sfactor extern int cubicsize, mipsize; // cubicsize = ssize^2 // special client ent that receives input and acts as camera extern DynamicEntity *player1; // all the other clients (in multiplayer) @@ -258,10 +261,13 @@ extern int lastmillis; // last time extern int curtime; // current frame time extern int gamemode, nextmode; extern int xtraverts; extern bool demoplayback; +#ifdef __cplusplus +} +#endif #define DMF 16.0f #define DAF 1.0f #define DVF 100.0f Index: src/meson.build ================================================================== --- src/meson.build +++ src/meson.build @@ -1,28 +1,28 @@ executable('client', [ 'Alias.m', - 'Client.mm', - 'Command.mm', + 'Client.m', + 'Command.m', 'ConsoleLine.m', 'Cube.mm', - 'DynamicEntity.mm', + 'DynamicEntity.m', 'Entity.m', 'Identifier.m', 'KeyMapping.m', - 'MD2.mm', + 'MD2.m', 'MapModelInfo.m', 'Menu.m', 'MenuItem.m', - 'OFString+Cube.mm', + 'OFString+Cube.m', 'PersistentEntity.m', 'Projectile.m', - 'ResolverResult.mm', - 'ResolverThread.mm', + 'ResolverResult.m', + 'ResolverThread.m', 'ServerEntity.m', - 'ServerInfo.mm', - 'Variable.mm', + 'ServerInfo.m', + 'Variable.m', 'clients.mm', 'clientextras.mm', 'clientgame.mm', 'clients2c.mm', 'commands.mm', @@ -67,11 +67,11 @@ link_with: [enet], win_subsystem: 'windows') executable('server', [ - 'Client.mm', + 'Client.m', 'ServerEntity.m', 'server.mm', 'serverms.mm', 'serverutil.mm', 'tools.mm', Index: src/protos.h ================================================================== --- src/protos.h +++ src/protos.h @@ -1,6 +1,10 @@ // protos for ALL external functions in cube... + +#ifdef __cplusplus +extern "C" { +#endif // command extern int variable(OFString *name, int min, int cur, int max, int *storage, void (*fun)(), bool persist); extern void setvar(OFString *name, int i); @@ -45,26 +49,27 @@ extern void gl_init(int w, int h); extern void cleangl(); extern void gl_drawframe(int w, int h, float curfps); extern bool installtex(int tnum, OFIRI *IRI, int *xs, int *ys, bool clamp); extern void mipstats(int a, int b, int c); -extern void vertf(float v1, float v2, float v3, sqr *ls, float t1, float t2); +extern void vertf( + float v1, float v2, float v3, struct sqr *ls, float t1, float t2); extern void addstrip(int tex, int start, int n); extern int lookuptexture(int tex, int *xs, int *ys); // rendercubes extern void resetcubes(); -extern void render_flat(int tex, int x, int y, int size, int h, sqr *l1, - sqr *l2, sqr *l3, sqr *l4, bool isceil); +extern void render_flat(int tex, int x, int y, int size, int h, struct sqr *l1, + struct sqr *l2, struct sqr *l3, struct sqr *l4, bool isceil); extern void render_flatdelta(int wtex, int x, int y, int size, float h1, - float h2, float h3, float h4, sqr *l1, sqr *l2, sqr *l3, sqr *l4, - bool isceil); + float h2, float h3, float h4, struct sqr *l1, struct sqr *l2, + struct sqr *l3, struct sqr *l4, bool isceil); extern void render_square(int wtex, float floor1, float floor2, float ceil1, - float ceil2, int x1, int y1, int x2, int y2, int size, sqr *l1, sqr *l2, - bool topleft); -extern void render_tris(int x, int y, int size, bool topleft, sqr *h1, sqr *h2, - sqr *s, sqr *t, sqr *u, sqr *v); + float ceil2, int x1, int y1, int x2, int y2, int size, struct sqr *l1, + struct sqr *l2, bool topleft); +extern void render_tris(int x, int y, int size, bool topleft, struct sqr *h1, + struct sqr *h2, struct sqr *s, struct sqr *t, struct sqr *u, struct sqr *v); extern void addwaterquad(int x, int y, int size); extern int renderwater(float hf); extern void finishstrips(); extern void setarraypointers(); @@ -112,12 +117,12 @@ extern void renderscores(); // world extern void setupworld(int factor); extern void empty_world(int factor, bool force); -extern void remip(const block *b, int level); -extern void remipmore(const block *b, int level); +extern void remip(const struct block *b, int level); +extern void remipmore(const struct block *b, int level); extern int closestent(); extern int findentity(int type, int index); extern void trigger(int tag, int type, bool savegame); extern void resettagareas(); extern void settagareas(); @@ -127,12 +132,12 @@ // worldlight extern void calclight(); extern void dodynlight(const OFVector3D *vold, const OFVector3D *v, int reach, int strength, DynamicEntity *owner); extern void cleardlights(); -extern block *blockcopy(const block *b); -extern void blockpaste(const block *b); +extern struct block *blockcopy(const struct block *b); +extern void blockpaste(const struct block *b); // worldrender extern void render_world(float vx, float vy, float vh, int yaw, int pitch, float widef, int w, int h); @@ -152,21 +157,21 @@ // editing extern void cursorupdate(); extern void toggleedit(); extern void editdrag(bool isdown); -extern void setvdeltaxy(int delta, const block *sel); -extern void editequalisexy(bool isfloor, const block *sel); -extern void edittypexy(int type, const block *sel); -extern void edittexxy(int type, int t, const block *sel); -extern void editheightxy(bool isfloor, int amount, const block *sel); +extern void setvdeltaxy(int delta, const struct block *sel); +extern void editequalisexy(bool isfloor, const struct block *sel); +extern void edittypexy(int type, const struct block *sel); +extern void edittexxy(int type, int t, const struct block *sel); +extern void editheightxy(bool isfloor, int amount, const struct block *sel); extern bool noteditmode(); extern void pruneundos(int maxremain); // renderextras extern void line(int x1, int y1, float z1, int x2, int y2, float z2); -extern void box(const block *b, float z1, float z2, float z3, float z4); +extern void box(const struct block *b, float z1, float z2, float z3, float z4); extern void dot(int x, int y, float z); extern void linestyle(float width, int r, int g, int b); extern void newsphere(const OFVector3D *o, float max, int type); extern void renderspheres(int time); extern void gl_drawhud( @@ -268,6 +273,10 @@ extern void setspawn(uint i, bool on); extern void teleport(int n, DynamicEntity *d); extern void baseammo(int gun); // rndmap -extern void perlinarea(const block *b, int scale, int seed, int psize); +extern void perlinarea(const struct block *b, int scale, int seed, int psize); + +#ifdef __cplusplus +} +#endif Index: src/tools.h ================================================================== --- src/tools.h +++ src/tools.h @@ -44,8 +44,14 @@ # define __cdecl #endif #define fast_f2nat(val) ((int)(val)) +#ifdef __cplusplus +extern "C" { +#endif extern void endianswap(void *, int, int); +#ifdef __cplusplus +} +#endif #endif