Clean up file handling
FossilOrigin-Name: 3d55e077f74fc1c036e856cc4fdf0ae3c308c58f7d37eb9392f1a15f10cc237d
This commit is contained in:
parent
c6eebefd77
commit
ab582d3745
14 changed files with 278 additions and 231 deletions
59
src/Cube.mm
59
src/Cube.mm
|
@ -9,6 +9,7 @@ VARP(minmillis, 0, 5, 1000);
|
||||||
|
|
||||||
@implementation Cube {
|
@implementation Cube {
|
||||||
int _width, _height;
|
int _width, _height;
|
||||||
|
OFIRI *_userDataIRI;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (Cube *)sharedInstance
|
+ (Cube *)sharedInstance
|
||||||
|
@ -116,16 +117,43 @@ VARP(minmillis, 0, 5, 1000);
|
||||||
gl_init(_width, _height);
|
gl_init(_width, _height);
|
||||||
|
|
||||||
log("basetex");
|
log("basetex");
|
||||||
|
_gameDataIRI = [OFFileManager.defaultManager currentDirectoryIRI];
|
||||||
|
_userDataIRI = [OFFileManager.defaultManager currentDirectoryIRI];
|
||||||
int xs, ys;
|
int xs, ys;
|
||||||
if (!installtex(2, path(newstring("data/newchars.png")), xs, ys) ||
|
if (!installtex(2,
|
||||||
!installtex(3, path(newstring("data/martin/base.png")), xs, ys) ||
|
[_userDataIRI IRIByAppendingPathComponent:@"data/newchars.png"],
|
||||||
!installtex(6, path(newstring("data/martin/ball1.png")), xs, ys) ||
|
&xs, &ys, false) ||
|
||||||
!installtex(7, path(newstring("data/martin/smoke.png")), xs, ys) ||
|
!installtex(3,
|
||||||
!installtex(8, path(newstring("data/martin/ball2.png")), xs, ys) ||
|
[_userDataIRI
|
||||||
!installtex(9, path(newstring("data/martin/ball3.png")), xs, ys) ||
|
IRIByAppendingPathComponent:@"data/martin/base.png"],
|
||||||
!installtex(4, path(newstring("data/explosion.jpg")), xs, ys) ||
|
&xs, &ys, false) ||
|
||||||
!installtex(5, path(newstring("data/items.png")), xs, ys) ||
|
!installtex(6,
|
||||||
!installtex(1, path(newstring("data/crosshair.png")), xs, ys))
|
[_userDataIRI
|
||||||
|
IRIByAppendingPathComponent:@"data/martin/ball1.png"],
|
||||||
|
&xs, &ys, false) ||
|
||||||
|
!installtex(7,
|
||||||
|
[_userDataIRI
|
||||||
|
IRIByAppendingPathComponent:@"data/martin/smoke.png"],
|
||||||
|
&xs, &ys, false) ||
|
||||||
|
!installtex(8,
|
||||||
|
[_userDataIRI
|
||||||
|
IRIByAppendingPathComponent:@"data/martin/ball2.png"],
|
||||||
|
&xs, &ys, false) ||
|
||||||
|
!installtex(9,
|
||||||
|
[_userDataIRI
|
||||||
|
IRIByAppendingPathComponent:@"data/martin/ball3.png"],
|
||||||
|
&xs, &ys, false) ||
|
||||||
|
!installtex(4,
|
||||||
|
[_userDataIRI
|
||||||
|
IRIByAppendingPathComponent:@"data/explosion.jpg"],
|
||||||
|
&xs, &ys, false) ||
|
||||||
|
!installtex(5,
|
||||||
|
[_userDataIRI IRIByAppendingPathComponent:@"data/items.png"],
|
||||||
|
&xs, &ys, false) ||
|
||||||
|
!installtex(1,
|
||||||
|
[_userDataIRI
|
||||||
|
IRIByAppendingPathComponent:@"data/crosshair.png"],
|
||||||
|
&xs, &ys, false))
|
||||||
fatal(@"could not find core textures (hint: run cube from the "
|
fatal(@"could not find core textures (hint: run cube from the "
|
||||||
@"parent of the bin directory)");
|
@"parent of the bin directory)");
|
||||||
|
|
||||||
|
@ -269,9 +297,16 @@ VARP(minmillis, 0, 5, 1000);
|
||||||
endianswap(dest, 3, _width);
|
endianswap(dest, 3, _width);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf_sd(buf)(
|
@autoreleasepool {
|
||||||
"screenshots/screenshot_%d.bmp", lastmillis);
|
OFString *path = [OFString
|
||||||
SDL_SaveBMP(temp, path(buf));
|
stringWithFormat:
|
||||||
|
@"screenshots/screenshot_%d.bmp",
|
||||||
|
lastmillis];
|
||||||
|
SDL_SaveBMP(temp,
|
||||||
|
[_userDataIRI
|
||||||
|
IRIByAppendingPathComponent:path]
|
||||||
|
.fileSystemRepresentation.UTF8String);
|
||||||
|
}
|
||||||
SDL_FreeSurface(temp);
|
SDL_FreeSurface(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,8 +169,8 @@ sendmap(OFString *mapname)
|
||||||
changemap(mapname);
|
changemap(mapname);
|
||||||
mapname = getclientmap();
|
mapname = getclientmap();
|
||||||
int mapsize;
|
int mapsize;
|
||||||
uchar *mapdata = readmap(mapname.UTF8String, &mapsize);
|
OFData *mapdata = readmap(mapname);
|
||||||
if (!mapdata)
|
if (mapdata == nil)
|
||||||
return;
|
return;
|
||||||
ENetPacket *packet = enet_packet_create(
|
ENetPacket *packet = enet_packet_create(
|
||||||
NULL, MAXTRANS + mapsize, ENET_PACKET_FLAG_RELIABLE);
|
NULL, MAXTRANS + mapsize, ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
@ -179,16 +179,14 @@ sendmap(OFString *mapname)
|
||||||
putint(p, SV_SENDMAP);
|
putint(p, SV_SENDMAP);
|
||||||
sendstring(mapname.UTF8String, p);
|
sendstring(mapname.UTF8String, p);
|
||||||
putint(p, mapsize);
|
putint(p, mapsize);
|
||||||
if (65535 - (p - start) < mapsize) {
|
if (65535 - (p - start) < mapdata.count) {
|
||||||
conoutf(
|
conoutf(
|
||||||
@"map %s is too large to send", mapname.UTF8String);
|
@"map %s is too large to send", mapname.UTF8String);
|
||||||
free(mapdata);
|
|
||||||
enet_packet_destroy(packet);
|
enet_packet_destroy(packet);
|
||||||
return;
|
return;
|
||||||
};
|
}
|
||||||
memcpy(p, mapdata, mapsize);
|
memcpy(p, mapdata.items, mapdata.count);
|
||||||
p += mapsize;
|
p += mapsize;
|
||||||
free(mapdata);
|
|
||||||
*(ushort *)start = ENET_HOST_TO_NET_16(p - start);
|
*(ushort *)start = ENET_HOST_TO_NET_16(p - start);
|
||||||
enet_packet_resize(packet, p - start);
|
enet_packet_resize(packet, p - start);
|
||||||
sendpackettoserv(packet);
|
sendpackettoserv(packet);
|
||||||
|
|
|
@ -557,13 +557,17 @@ bool
|
||||||
execfile(OFString *cfgfile)
|
execfile(OFString *cfgfile)
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
string s;
|
OFMutableData *data;
|
||||||
strcpy_s(s, cfgfile.UTF8String);
|
@try {
|
||||||
char *buf = loadfile(path(s), NULL);
|
data = [OFMutableData dataWithContentsOfFile:cfgfile];
|
||||||
if (!buf)
|
} @catch (id e) {
|
||||||
return false;
|
return false;
|
||||||
execute(buf);
|
}
|
||||||
free(buf);
|
|
||||||
|
// Ensure \0 termination.
|
||||||
|
[data addItem:""];
|
||||||
|
|
||||||
|
execute((char *)data.mutableItems);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
@interface Cube : OFObject <OFApplicationDelegate>
|
@interface Cube : OFObject <OFApplicationDelegate>
|
||||||
@property (class, readonly, nonatomic) Cube *sharedInstance;
|
@property (class, readonly, nonatomic) Cube *sharedInstance;
|
||||||
@property (readonly, nonatomic) SDL_Window *window;
|
@property (readonly, nonatomic) SDL_Window *window;
|
||||||
|
@property (readonly, nonatomic) OFIRI *gameDataIRI;
|
||||||
@property (nonatomic) bool repeatsKeys;
|
@property (nonatomic) bool repeatsKeys;
|
||||||
@property (nonatomic) int framesInMap;
|
@property (nonatomic) int framesInMap;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -44,12 +44,11 @@ extern void writeservercfg();
|
||||||
extern void gl_init(int w, int h);
|
extern void gl_init(int w, int h);
|
||||||
extern void cleangl();
|
extern void cleangl();
|
||||||
extern void gl_drawframe(int w, int h, float curfps);
|
extern void gl_drawframe(int w, int h, float curfps);
|
||||||
extern bool installtex(
|
extern bool installtex(int tnum, OFIRI *IRI, int *xs, int *ys, bool clamp);
|
||||||
int tnum, char *texname, int &xs, int &ys, bool clamp = false);
|
|
||||||
extern void mipstats(int a, int b, int c);
|
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, sqr *ls, float t1, float t2);
|
||||||
extern void addstrip(int tex, int start, int n);
|
extern void addstrip(int tex, int start, int n);
|
||||||
extern int lookuptexture(int tex, int &xs, int &ys);
|
extern int lookuptexture(int tex, int *xs, int *ys);
|
||||||
|
|
||||||
// rendercubes
|
// rendercubes
|
||||||
extern void resetcubes();
|
extern void resetcubes();
|
||||||
|
@ -185,7 +184,7 @@ extern void render_particles(int time);
|
||||||
extern void save_world(OFString *fname);
|
extern void save_world(OFString *fname);
|
||||||
extern void load_world(char *mname);
|
extern void load_world(char *mname);
|
||||||
extern void writemap(char *mname, int msize, uchar *mdata);
|
extern void writemap(char *mname, int msize, uchar *mdata);
|
||||||
extern uchar *readmap(const char *mname, int *msize);
|
extern OFData *readmap(OFString *mname);
|
||||||
extern void loadgamerest();
|
extern void loadgamerest();
|
||||||
extern void incomingdemodata(uchar *buf, int len, bool extras = false);
|
extern void incomingdemodata(uchar *buf, int len, bool extras = false);
|
||||||
extern void demoplaybackstep();
|
extern void demoplaybackstep();
|
||||||
|
|
|
@ -103,7 +103,7 @@ render_flat(int wtex, int x, int y, int size, int h, sqr *l1, sqr *l2, sqr *l3,
|
||||||
};
|
};
|
||||||
|
|
||||||
int sx, sy;
|
int sx, sy;
|
||||||
int gltex = lookuptexture(wtex, sx, sy);
|
int gltex = lookuptexture(wtex, &sx, &sy);
|
||||||
float xf = TEXTURESCALE / sx;
|
float xf = TEXTURESCALE / sx;
|
||||||
float yf = TEXTURESCALE / sy;
|
float yf = TEXTURESCALE / sy;
|
||||||
float xs = size * xf;
|
float xs = size * xf;
|
||||||
|
@ -184,7 +184,7 @@ render_flatdelta(int wtex, int x, int y, int size, float h1, float h2, float h3,
|
||||||
};
|
};
|
||||||
|
|
||||||
int sx, sy;
|
int sx, sy;
|
||||||
int gltex = lookuptexture(wtex, sx, sy);
|
int gltex = lookuptexture(wtex, &sx, &sy);
|
||||||
float xf = TEXTURESCALE / sx;
|
float xf = TEXTURESCALE / sx;
|
||||||
float yf = TEXTURESCALE / sy;
|
float yf = TEXTURESCALE / sy;
|
||||||
float xs = size * xf;
|
float xs = size * xf;
|
||||||
|
@ -238,7 +238,7 @@ render_2tris(sqr *h, sqr *s, int x1, int y1, int x2, int y2, int x3, int y3,
|
||||||
vertcheck();
|
vertcheck();
|
||||||
|
|
||||||
int sx, sy;
|
int sx, sy;
|
||||||
int gltex = lookuptexture(h->ftex, sx, sy);
|
int gltex = lookuptexture(h->ftex, &sx, &sy);
|
||||||
float xf = TEXTURESCALE / sx;
|
float xf = TEXTURESCALE / sx;
|
||||||
float yf = TEXTURESCALE / sy;
|
float yf = TEXTURESCALE / sy;
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ render_2tris(sqr *h, sqr *s, int x1, int y1, int x2, int y2, int x3, int y3,
|
||||||
vertf((float)x3, h->floor, (float)y3, l3, xf * x3, yf * y3);
|
vertf((float)x3, h->floor, (float)y3, l3, xf * x3, yf * y3);
|
||||||
addstrip(gltex, curvert - 3, 3);
|
addstrip(gltex, curvert - 3, 3);
|
||||||
|
|
||||||
gltex = lookuptexture(h->ctex, sx, sy);
|
gltex = lookuptexture(h->ctex, &sx, &sy);
|
||||||
xf = TEXTURESCALE / sx;
|
xf = TEXTURESCALE / sx;
|
||||||
yf = TEXTURESCALE / sy;
|
yf = TEXTURESCALE / sy;
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@ render_square(int wtex, float floor1, float floor2, float ceil1, float ceil2,
|
||||||
};
|
};
|
||||||
|
|
||||||
int sx, sy;
|
int sx, sy;
|
||||||
int gltex = lookuptexture(wtex, sx, sy);
|
int gltex = lookuptexture(wtex, &sx, &sy);
|
||||||
float xf = TEXTURESCALE / sx;
|
float xf = TEXTURESCALE / sx;
|
||||||
float yf = TEXTURESCALE / sy;
|
float yf = TEXTURESCALE / sy;
|
||||||
float xs = size * xf;
|
float xs = size * xf;
|
||||||
|
@ -352,7 +352,7 @@ renderwater(float hf)
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_ONE, GL_SRC_COLOR);
|
glBlendFunc(GL_ONE, GL_SRC_COLOR);
|
||||||
int sx, sy;
|
int sx, sy;
|
||||||
glBindTexture(GL_TEXTURE_2D, lookuptexture(DEFAULT_LIQUID, sx, sy));
|
glBindTexture(GL_TEXTURE_2D, lookuptexture(DEFAULT_LIQUID, &sx, &sy));
|
||||||
|
|
||||||
wx1 &= ~(watersubdiv - 1);
|
wx1 &= ~(watersubdiv - 1);
|
||||||
wy1 &= ~(watersubdiv - 1);
|
wy1 &= ~(watersubdiv - 1);
|
||||||
|
|
|
@ -206,18 +206,27 @@ loadsky(OFString *basename)
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
static OFString *lastsky = @"";
|
static OFString *lastsky = @"";
|
||||||
|
|
||||||
if ([lastsky isEqual:basename])
|
if ([lastsky isEqual:basename])
|
||||||
return;
|
return;
|
||||||
char *side[] = {"ft", "bk", "lf", "rt", "dn", "up"};
|
|
||||||
|
static const OFString *side[] = {
|
||||||
|
@"ft", @"bk", @"lf", @"rt", @"dn", @"up"};
|
||||||
int texnum = 14;
|
int texnum = 14;
|
||||||
loopi(6)
|
loopi(6)
|
||||||
{
|
{
|
||||||
sprintf_sd(name)(
|
OFString *path =
|
||||||
"packages/%s_%s.jpg", basename.UTF8String, side[i]);
|
[OFString stringWithFormat:@"packages/%@_%@.jpg",
|
||||||
|
basename, side[i]];
|
||||||
|
|
||||||
int xs, ys;
|
int xs, ys;
|
||||||
if (!installtex(texnum + i, path(name), xs, ys, true))
|
if (!installtex(texnum + i,
|
||||||
|
[Cube.sharedInstance.gameDataIRI
|
||||||
|
IRIByAppendingPathComponent:path],
|
||||||
|
&xs, &ys, true))
|
||||||
conoutf(@"could not load sky textures");
|
conoutf(@"could not load sky textures");
|
||||||
}
|
}
|
||||||
|
|
||||||
lastsky = basename;
|
lastsky = basename;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
183
src/rendergl.mm
183
src/rendergl.mm
|
@ -73,79 +73,87 @@ cleangl()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
installtex(int tnum, char *texname, int &xs, int &ys, bool clamp)
|
installtex(int tnum, OFIRI *IRI, int *xs, int *ys, bool clamp)
|
||||||
{
|
{
|
||||||
SDL_Surface *s = IMG_Load(texname);
|
@autoreleasepool {
|
||||||
if (s == NULL) {
|
SDL_Surface *s =
|
||||||
conoutf(@"couldn't load texture %s", texname);
|
IMG_Load(IRI.fileSystemRepresentation.UTF8String);
|
||||||
return false;
|
if (s == NULL) {
|
||||||
}
|
conoutf(
|
||||||
|
@"couldn't load texture %s", IRI.string.UTF8String);
|
||||||
if (s->format->BitsPerPixel != 24) {
|
|
||||||
SDL_PixelFormat *format =
|
|
||||||
SDL_AllocFormat(SDL_PIXELFORMAT_RGB24);
|
|
||||||
if (format == NULL) {
|
|
||||||
conoutf(@"texture cannot be converted to 24bpp: %s",
|
|
||||||
texname);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@try {
|
if (s->format->BitsPerPixel != 24) {
|
||||||
SDL_Surface *converted =
|
SDL_PixelFormat *format =
|
||||||
SDL_ConvertSurface(s, format, 0);
|
SDL_AllocFormat(SDL_PIXELFORMAT_RGB24);
|
||||||
if (converted == NULL) {
|
if (format == NULL) {
|
||||||
conoutf(
|
conoutf(
|
||||||
@"texture cannot be converted to 24bpp: %s",
|
@"texture cannot be converted to 24bpp: %s",
|
||||||
texname);
|
IRI.string.UTF8String);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_FreeSurface(s);
|
@try {
|
||||||
s = converted;
|
SDL_Surface *converted =
|
||||||
} @finally {
|
SDL_ConvertSurface(s, format, 0);
|
||||||
SDL_FreeFormat(format);
|
if (converted == NULL) {
|
||||||
|
conoutf(@"texture cannot be converted "
|
||||||
|
@"to 24bpp: %s",
|
||||||
|
IRI.string.UTF8String);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_FreeSurface(s);
|
||||||
|
s = converted;
|
||||||
|
} @finally {
|
||||||
|
SDL_FreeFormat(format);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// loopi(s->w*s->h*3) { uchar *p = (uchar *)s->pixels+i; *p =
|
||||||
|
// 255-*p; };
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tnum);
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
|
||||||
|
clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
|
||||||
|
clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||||
|
glTexParameteri(
|
||||||
|
GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||||
|
GL_LINEAR_MIPMAP_LINEAR); // NEAREST);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
|
||||||
|
*xs = s->w;
|
||||||
|
*ys = s->h;
|
||||||
|
while (*xs > glmaxtexsize || *ys > glmaxtexsize) {
|
||||||
|
*xs /= 2;
|
||||||
|
*ys /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *scaledimg = s->pixels;
|
||||||
|
|
||||||
|
if (*xs != s->w) {
|
||||||
|
conoutf(@"warning: quality loss: scaling %s",
|
||||||
|
IRI.string
|
||||||
|
.UTF8String); // for voodoo cards under linux
|
||||||
|
scaledimg = alloc(*xs * *ys * 3);
|
||||||
|
gluScaleImage(GL_RGB, s->w, s->h, GL_UNSIGNED_BYTE,
|
||||||
|
s->pixels, *xs, *ys, GL_UNSIGNED_BYTE, scaledimg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, *xs, *ys, GL_RGB,
|
||||||
|
GL_UNSIGNED_BYTE, scaledimg))
|
||||||
|
fatal(@"could not build mipmaps");
|
||||||
|
|
||||||
|
if (*xs != s->w)
|
||||||
|
free(scaledimg);
|
||||||
|
|
||||||
|
SDL_FreeSurface(s);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// loopi(s->w*s->h*3) { uchar *p = (uchar *)s->pixels+i; *p = 255-*p; };
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tnum);
|
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
|
|
||||||
clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
|
|
||||||
clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
|
||||||
GL_LINEAR_MIPMAP_LINEAR); // NEAREST);
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
||||||
|
|
||||||
xs = s->w;
|
|
||||||
ys = s->h;
|
|
||||||
while (xs > glmaxtexsize || ys > glmaxtexsize) {
|
|
||||||
xs /= 2;
|
|
||||||
ys /= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *scaledimg = s->pixels;
|
|
||||||
|
|
||||||
if (xs != s->w) {
|
|
||||||
conoutf(@"warning: quality loss: scaling %s",
|
|
||||||
texname); // for voodoo cards under linux
|
|
||||||
scaledimg = alloc(xs * ys * 3);
|
|
||||||
gluScaleImage(GL_RGB, s->w, s->h, GL_UNSIGNED_BYTE, s->pixels,
|
|
||||||
xs, ys, GL_UNSIGNED_BYTE, scaledimg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, xs, ys, GL_RGB,
|
|
||||||
GL_UNSIGNED_BYTE, scaledimg))
|
|
||||||
fatal(@"could not build mipmaps");
|
|
||||||
|
|
||||||
if (xs != s->w)
|
|
||||||
free(scaledimg);
|
|
||||||
|
|
||||||
SDL_FreeSurface(s);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// management of texture slots
|
// management of texture slots
|
||||||
|
@ -189,36 +197,35 @@ texture(OFString *aframe, OFString *name)
|
||||||
mapping[num][frame] = 1;
|
mapping[num][frame] = 1;
|
||||||
char *n = mapname[num][frame];
|
char *n = mapname[num][frame];
|
||||||
strcpy_s(n, name.UTF8String);
|
strcpy_s(n, name.UTF8String);
|
||||||
path(n);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
COMMAND(texture, ARG_2STR)
|
COMMAND(texture, ARG_2STR)
|
||||||
|
|
||||||
int
|
int
|
||||||
lookuptexture(int tex, int &xs, int &ys)
|
lookuptexture(int tex, int *xs, int *ys)
|
||||||
{
|
{
|
||||||
int frame = 0; // other frames?
|
int frame = 0; // other frames?
|
||||||
int tid = mapping[tex][frame];
|
int tid = mapping[tex][frame];
|
||||||
|
|
||||||
if (tid >= FIRSTTEX) {
|
if (tid >= FIRSTTEX) {
|
||||||
xs = texx[tid - FIRSTTEX];
|
*xs = texx[tid - FIRSTTEX];
|
||||||
ys = texy[tid - FIRSTTEX];
|
*ys = texy[tid - FIRSTTEX];
|
||||||
return tid;
|
return tid;
|
||||||
};
|
}
|
||||||
|
|
||||||
xs = ys = 16;
|
*xs = *ys = 16;
|
||||||
if (!tid)
|
if (tid == 0)
|
||||||
return 1; // crosshair :)
|
return 1; // crosshair :)
|
||||||
|
|
||||||
loopi(curtex) // lazily happens once per "texture" command, basically
|
loopi(curtex) // lazily happens once per "texture" command, basically
|
||||||
{
|
{
|
||||||
if (strcmp(mapname[tex][frame], texname[i]) == 0) {
|
if (strcmp(mapname[tex][frame], texname[i]) == 0) {
|
||||||
mapping[tex][frame] = tid = i + FIRSTTEX;
|
mapping[tex][frame] = tid = i + FIRSTTEX;
|
||||||
xs = texx[i];
|
*xs = texx[i];
|
||||||
ys = texy[i];
|
*ys = texy[i];
|
||||||
return tid;
|
return tid;
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
if (curtex == MAXTEX)
|
if (curtex == MAXTEX)
|
||||||
fatal(@"loaded too many textures");
|
fatal(@"loaded too many textures");
|
||||||
|
@ -226,18 +233,24 @@ lookuptexture(int tex, int &xs, int &ys)
|
||||||
int tnum = curtex + FIRSTTEX;
|
int tnum = curtex + FIRSTTEX;
|
||||||
strcpy_s(texname[curtex], mapname[tex][frame]);
|
strcpy_s(texname[curtex], mapname[tex][frame]);
|
||||||
|
|
||||||
sprintf_sd(name)("packages%c%s", PATHDIV, texname[curtex]);
|
@autoreleasepool {
|
||||||
|
OFString *path =
|
||||||
|
[OFString stringWithFormat:@"packages/%s", texname[curtex]];
|
||||||
|
|
||||||
if (installtex(tnum, name, xs, ys)) {
|
if (installtex(tnum,
|
||||||
mapping[tex][frame] = tnum;
|
[Cube.sharedInstance.gameDataIRI
|
||||||
texx[curtex] = xs;
|
IRIByAppendingPathComponent:path],
|
||||||
texy[curtex] = ys;
|
xs, ys, false)) {
|
||||||
curtex++;
|
mapping[tex][frame] = tnum;
|
||||||
return tnum;
|
texx[curtex] = *xs;
|
||||||
} else {
|
texy[curtex] = *ys;
|
||||||
return mapping[tex][frame] = FIRSTTEX; // temp fix
|
curtex++;
|
||||||
};
|
return tnum;
|
||||||
};
|
} else {
|
||||||
|
return mapping[tex][frame] = FIRSTTEX; // temp fix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setupworld()
|
setupworld()
|
||||||
|
@ -418,7 +431,7 @@ gl_drawframe(int w, int h, float curfps)
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
int xs, ys;
|
int xs, ys;
|
||||||
skyoglid = lookuptexture(DEFAULT_SKY, xs, ys);
|
skyoglid = lookuptexture(DEFAULT_SKY, &xs, &ys);
|
||||||
|
|
||||||
resetcubes();
|
resetcubes();
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ struct md2_frame {
|
||||||
@property (nonatomic) int mdlnum;
|
@property (nonatomic) int mdlnum;
|
||||||
@property (nonatomic) bool loaded;
|
@property (nonatomic) bool loaded;
|
||||||
|
|
||||||
- (bool)loadWithPath:(char *)filename;
|
- (bool)loadWithIRI:(OFIRI *)IRI;
|
||||||
- (void)renderWithLight:(OFVector3D &)light
|
- (void)renderWithLight:(OFVector3D &)light
|
||||||
frame:(int)frame
|
frame:(int)frame
|
||||||
range:(int)range
|
range:(int)range
|
||||||
|
@ -79,51 +79,62 @@ static OFMutableArray<MD2 *> *mapmodels = nil;
|
||||||
delete[] _frames;
|
delete[] _frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (bool)loadWithPath:(char *)filename
|
- (bool)loadWithIRI:(OFIRI *)IRI
|
||||||
{
|
{
|
||||||
FILE *file;
|
@autoreleasepool {
|
||||||
md2_header header;
|
OFSeekableStream *stream;
|
||||||
|
@try {
|
||||||
|
stream = (OFSeekableStream *)[[OFIRIHandler
|
||||||
|
handlerForIRI:IRI] openItemAtIRI:IRI mode:@"r"];
|
||||||
|
} @catch (id e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ((file = fopen(filename, "rb")) == NULL)
|
if (![stream isKindOfClass:[OFSeekableStream class]])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fread(&header, sizeof(md2_header), 1, file);
|
md2_header header;
|
||||||
endianswap(&header, sizeof(int), sizeof(md2_header) / sizeof(int));
|
[stream readIntoBuffer:&header exactLength:sizeof(md2_header)];
|
||||||
|
endianswap(
|
||||||
|
&header, sizeof(int), sizeof(md2_header) / sizeof(int));
|
||||||
|
|
||||||
if (header.magic != 844121161 || header.version != 8)
|
if (header.magic != 844121161 || header.version != 8)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_frames = new char[header.frameSize * header.numFrames];
|
_frames = new char[header.frameSize * header.numFrames];
|
||||||
if (_frames == NULL)
|
if (_frames == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fseek(file, header.offsetFrames, SEEK_SET);
|
[stream seekToOffset:header.offsetFrames whence:OFSeekSet];
|
||||||
fread(_frames, header.frameSize * header.numFrames, 1, file);
|
[stream readIntoBuffer:_frames
|
||||||
|
exactLength:header.frameSize * header.numFrames];
|
||||||
|
|
||||||
for (int i = 0; i < header.numFrames; ++i)
|
for (int i = 0; i < header.numFrames; ++i)
|
||||||
endianswap(_frames + i * header.frameSize, sizeof(float), 6);
|
endianswap(
|
||||||
|
_frames + i * header.frameSize, sizeof(float), 6);
|
||||||
|
|
||||||
_glCommands = new int[header.numGlCommands];
|
_glCommands = new int[header.numGlCommands];
|
||||||
if (_glCommands == NULL)
|
if (_glCommands == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fseek(file, header.offsetGlCommands, SEEK_SET);
|
[stream seekToOffset:header.offsetGlCommands whence:OFSeekSet];
|
||||||
fread(_glCommands, header.numGlCommands * sizeof(int), 1, file);
|
[stream readIntoBuffer:_glCommands
|
||||||
|
exactLength:header.numGlCommands * sizeof(int)];
|
||||||
|
endianswap(_glCommands, sizeof(int), header.numGlCommands);
|
||||||
|
|
||||||
endianswap(_glCommands, sizeof(int), header.numGlCommands);
|
_numFrames = header.numFrames;
|
||||||
|
_numGlCommands = header.numGlCommands;
|
||||||
|
_frameSize = header.frameSize;
|
||||||
|
_numTriangles = header.numTriangles;
|
||||||
|
_numVerts = header.numVertices;
|
||||||
|
|
||||||
_numFrames = header.numFrames;
|
[stream close];
|
||||||
_numGlCommands = header.numGlCommands;
|
|
||||||
_frameSize = header.frameSize;
|
|
||||||
_numTriangles = header.numTriangles;
|
|
||||||
_numVerts = header.numVertices;
|
|
||||||
|
|
||||||
fclose(file);
|
_mverts = new OFVector3D *[_numFrames];
|
||||||
|
loopj(_numFrames) _mverts[j] = NULL;
|
||||||
|
|
||||||
_mverts = new OFVector3D *[_numFrames];
|
return true;
|
||||||
loopj(_numFrames) _mverts[j] = NULL;
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
|
@ -235,14 +246,20 @@ delayedload(MD2 *m)
|
||||||
{
|
{
|
||||||
if (!m.loaded) {
|
if (!m.loaded) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
sprintf_sd(name1)("packages/models/%s/tris.md2",
|
OFString *path = [OFString
|
||||||
m.loadname.UTF8String);
|
stringWithFormat:@"packages/models/%@", m.loadname];
|
||||||
if (![m loadWithPath:path(name1)])
|
OFIRI *baseIRI = [Cube.sharedInstance.gameDataIRI
|
||||||
fatal(@"loadmodel: ", @(name1));
|
IRIByAppendingPathComponent:path];
|
||||||
sprintf_sd(name2)("packages/models/%s/skin.jpg",
|
|
||||||
m.loadname.UTF8String);
|
OFIRI *IRI1 =
|
||||||
|
[baseIRI IRIByAppendingPathComponent:@"tris.md2"];
|
||||||
|
if (![m loadWithIRI:IRI1])
|
||||||
|
fatal(@"loadmodel: ", IRI1.string);
|
||||||
|
|
||||||
|
OFIRI *IRI2 =
|
||||||
|
[baseIRI IRIByAppendingPathComponent:@"skin.jpg"];
|
||||||
int xs, ys;
|
int xs, ys;
|
||||||
installtex(FIRSTMDL + m.mdlnum, path(name2), xs, ys);
|
installtex(FIRSTMDL + m.mdlnum, IRI2, &xs, &ys, false);
|
||||||
m.loaded = true;
|
m.loaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,7 +331,7 @@ rendermodel(OFString *mdl, int frame, int range, int tex, float rad, float x,
|
||||||
|
|
||||||
int xs, ys;
|
int xs, ys;
|
||||||
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)x;
|
||||||
int iy = (int)z;
|
int iy = (int)z;
|
||||||
|
|
41
src/sound.mm
41
src/sound.mm
|
@ -86,20 +86,25 @@ music(OFString *name)
|
||||||
stopsound();
|
stopsound();
|
||||||
if (soundvol && musicvol) {
|
if (soundvol && musicvol) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
string sn;
|
OFString *path =
|
||||||
strcpy_s(sn, "packages/");
|
[OFString stringWithFormat:@"packages/%@", name];
|
||||||
strcat_s(sn, name.UTF8String);
|
OFIRI *IRI = [Cube.sharedInstance.gameDataIRI
|
||||||
|
IRIByAppendingPathComponent:path];
|
||||||
|
|
||||||
#ifdef USE_MIXER
|
#ifdef USE_MIXER
|
||||||
if (mod = Mix_LoadMUS(path(sn))) {
|
if (mod = Mix_LoadMUS(
|
||||||
|
IRI.fileSystemRepresentation.UTF8String)) {
|
||||||
Mix_PlayMusic(mod, -1);
|
Mix_PlayMusic(mod, -1);
|
||||||
Mix_VolumeMusic((musicvol * MAXVOL) / 255);
|
Mix_VolumeMusic((musicvol * MAXVOL) / 255);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (mod = FMUSIC_LoadSong(path(sn))) {
|
if (mod = FMUSIC_LoadSong(
|
||||||
|
IRI.fileSystemRepresentation.UTF8String)) {
|
||||||
FMUSIC_PlaySong(mod);
|
FMUSIC_PlaySong(mod);
|
||||||
FMUSIC_SetMasterVolume(mod, musicvol);
|
FMUSIC_SetMasterVolume(mod, musicvol);
|
||||||
} else if (stream = FSOUND_Stream_Open(
|
} else if (stream = FSOUND_Stream_Open(
|
||||||
path(sn), FSOUND_LOOP_NORMAL, 0, 0)) {
|
IRI.fileSystemRepresentation.UTF8String,
|
||||||
|
FSOUND_LOOP_NORMAL, 0, 0)) {
|
||||||
int chan =
|
int chan =
|
||||||
FSOUND_Stream_Play(FSOUND_FREE, stream);
|
FSOUND_Stream_Play(FSOUND_FREE, stream);
|
||||||
if (chan >= 0) {
|
if (chan >= 0) {
|
||||||
|
@ -230,23 +235,29 @@ playsound(int n, OFVector3D *loc)
|
||||||
if (n < 0 || n >= samples.length()) {
|
if (n < 0 || n >= samples.length()) {
|
||||||
conoutf(@"unregistered sound: %d", n);
|
conoutf(@"unregistered sound: %d", n);
|
||||||
return;
|
return;
|
||||||
};
|
}
|
||||||
|
|
||||||
if (!samples[n]) {
|
if (!samples[n]) {
|
||||||
sprintf_sd(buf)("packages/sounds/%s.wav", snames[n]);
|
OFString *path = [OFString
|
||||||
|
stringWithFormat:@"packages/sounds/%s.wav", snames[n]];
|
||||||
|
OFIRI *IRI = [Cube.sharedInstance.gameDataIRI
|
||||||
|
IRIByAppendingPathComponent:path];
|
||||||
|
|
||||||
#ifdef USE_MIXER
|
#ifdef USE_MIXER
|
||||||
samples[n] = Mix_LoadWAV(path(buf));
|
|
||||||
#else
|
|
||||||
samples[n] =
|
samples[n] =
|
||||||
FSOUND_Sample_Load(n, path(buf), FSOUND_LOOP_OFF, 0, 0);
|
Mix_LoadWAV(IRI.fileSystemRepresentation.UTF8String);
|
||||||
|
#else
|
||||||
|
samples[n] = FSOUND_Sample_Load(n,
|
||||||
|
IRI.fileSystemRepresentation.UTF8String, FSOUND_LOOP_OFF, 0,
|
||||||
|
0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!samples[n]) {
|
if (!samples[n]) {
|
||||||
conoutf(@"failed to load sample: %s", buf);
|
conoutf(@"failed to load sample: %s",
|
||||||
|
IRI.string.UTF8String);
|
||||||
return;
|
return;
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
#ifdef USE_MIXER
|
#ifdef USE_MIXER
|
||||||
int chan = Mix_PlayChannel(-1, samples[n], 0);
|
int chan = Mix_PlayChannel(-1, samples[n], 0);
|
||||||
|
@ -261,7 +272,7 @@ playsound(int n, OFVector3D *loc)
|
||||||
#ifndef USE_MIXER
|
#ifndef USE_MIXER
|
||||||
FSOUND_SetPaused(chan, false);
|
FSOUND_SetPaused(chan, false);
|
||||||
#endif
|
#endif
|
||||||
};
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sound(int n)
|
sound(int n)
|
||||||
|
|
|
@ -122,8 +122,6 @@ struct sprintf_s_f {
|
||||||
|
|
||||||
#define fast_f2nat(val) ((int)(val))
|
#define fast_f2nat(val) ((int)(val))
|
||||||
|
|
||||||
extern char *path(char *s);
|
|
||||||
extern char *loadfile(char *fn, int *size);
|
|
||||||
extern void endianswap(void *, int, int);
|
extern void endianswap(void *, int, int);
|
||||||
|
|
||||||
// memory pool that uses buckets and linear allocation for small objects
|
// memory pool that uses buckets and linear allocation for small objects
|
||||||
|
|
32
src/tools.mm
32
src/tools.mm
|
@ -100,38 +100,6 @@ gp() // useful for global buffers that need to be initialisation order
|
||||||
|
|
||||||
///////////////////////// misc tools ///////////////////////
|
///////////////////////// misc tools ///////////////////////
|
||||||
|
|
||||||
char *
|
|
||||||
path(char *s)
|
|
||||||
{
|
|
||||||
for (char *t = s; t = strpbrk(t, "/\\"); *t++ = PATHDIV)
|
|
||||||
;
|
|
||||||
return s;
|
|
||||||
};
|
|
||||||
|
|
||||||
char *
|
|
||||||
loadfile(char *fn, int *size)
|
|
||||||
{
|
|
||||||
FILE *f = fopen(fn, "rb");
|
|
||||||
if (!f)
|
|
||||||
return NULL;
|
|
||||||
fseek(f, 0, SEEK_END);
|
|
||||||
int len = ftell(f);
|
|
||||||
fseek(f, 0, SEEK_SET);
|
|
||||||
char *buf = (char *)malloc(len + 1);
|
|
||||||
if (!buf)
|
|
||||||
return NULL;
|
|
||||||
buf[len] = 0;
|
|
||||||
size_t rlen = fread(buf, 1, len, f);
|
|
||||||
fclose(f);
|
|
||||||
if (len != rlen || len <= 0) {
|
|
||||||
free(buf);
|
|
||||||
return NULL;
|
|
||||||
};
|
|
||||||
if (size != NULL)
|
|
||||||
*size = len;
|
|
||||||
return buf;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
void
|
||||||
endianswap(
|
endianswap(
|
||||||
void *memory, int stride, int length) // little indians as storage format
|
void *memory, int stride, int length) // little indians as storage format
|
||||||
|
|
|
@ -7,12 +7,12 @@ struct guninfo {
|
||||||
OFString *name;
|
OFString *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
const int MONSTERDAMAGEFACTOR = 4;
|
static const int MONSTERDAMAGEFACTOR = 4;
|
||||||
const int SGRAYS = 20;
|
static const int SGRAYS = 20;
|
||||||
const float SGSPREAD = 2;
|
static const float SGSPREAD = 2;
|
||||||
OFVector3D sg[SGRAYS];
|
static OFVector3D sg[SGRAYS];
|
||||||
|
|
||||||
guninfo guns[NUMGUNS] = {
|
static const guninfo guns[NUMGUNS] = {
|
||||||
{S_PUNCH1, 250, 50, 0, 0, 1, @"fist"},
|
{S_PUNCH1, 250, 50, 0, 0, 1, @"fist"},
|
||||||
{S_SG, 1400, 10, 0, 0, 20, @"shotgun"}, // *SGRAYS
|
{S_SG, 1400, 10, 0, 0, 20, @"shotgun"}, // *SGRAYS
|
||||||
{S_CG, 100, 30, 0, 0, 7, @"chaingun"},
|
{S_CG, 100, 30, 0, 0, 7, @"chaingun"},
|
||||||
|
|
|
@ -28,9 +28,6 @@ setnames(const char *name)
|
||||||
"packages/%s/%s_%d.BAK", pakname, mapname, lastmillis);
|
"packages/%s/%s_%d.BAK", pakname, mapname, lastmillis);
|
||||||
sprintf_s(pcfname)("packages/%s/package.cfg", pakname);
|
sprintf_s(pcfname)("packages/%s/package.cfg", pakname);
|
||||||
sprintf_s(mcfname)("packages/%s/%s.cfg", pakname, mapname);
|
sprintf_s(mcfname)("packages/%s/%s.cfg", pakname, mapname);
|
||||||
|
|
||||||
path(cgzname);
|
|
||||||
path(bakname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the optimize routines below are here to reduce the detrimental effects of
|
// the optimize routines below are here to reduce the detrimental effects of
|
||||||
|
@ -137,16 +134,13 @@ writemap(char *mname, int msize, uchar *mdata)
|
||||||
conoutf(@"wrote map %s as file %s", mname, cgzname);
|
conoutf(@"wrote map %s as file %s", mname, cgzname);
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar *
|
OFData *
|
||||||
readmap(const char *mname, int *msize)
|
readmap(OFString *mname)
|
||||||
{
|
{
|
||||||
setnames(mname);
|
@autoreleasepool {
|
||||||
uchar *mdata = (uchar *)loadfile(cgzname, msize);
|
setnames(mname.UTF8String);
|
||||||
if (!mdata) {
|
|
||||||
conoutf(@"could not read map %s", cgzname);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
return mdata;
|
return [OFData dataWithContentsOfFile:mname];
|
||||||
}
|
}
|
||||||
|
|
||||||
// save map as .cgz file. uses 2 layers of compression: first does simple
|
// save map as .cgz file. uses 2 layers of compression: first does simple
|
||||||
|
@ -362,7 +356,7 @@ load_world(char *mname) // still supports all map formats that have existed
|
||||||
calclight();
|
calclight();
|
||||||
settagareas();
|
settagareas();
|
||||||
int xs, ys;
|
int xs, ys;
|
||||||
loopi(256) if (texuse) lookuptexture(i, xs, ys);
|
loopi(256) if (texuse) lookuptexture(i, &xs, &ys);
|
||||||
conoutf(@"read map %s (%d milliseconds)", cgzname,
|
conoutf(@"read map %s (%d milliseconds)", cgzname,
|
||||||
SDL_GetTicks() - lastmillis);
|
SDL_GetTicks() - lastmillis);
|
||||||
conoutf(@"%s", hdr.maptitle);
|
conoutf(@"%s", hdr.maptitle);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue