fix embedded scores in screenshots
embed game description and player scores in png and jpg comments update enet.lib
This commit is contained in:
@@ -31,10 +31,23 @@
|
||||
<Add option="-s" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Target title="lib">
|
||||
<Option output="enet_dll" prefix_auto="1" extension_auto="1" />
|
||||
<Option working_dir="" />
|
||||
<Option type="2" />
|
||||
<Option compiler="gcc" />
|
||||
<Option createDefFile="1" />
|
||||
<Compiler>
|
||||
<Add option="-fomit-frame-pointer" />
|
||||
<Add option="-O2" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
</Linker>
|
||||
</Target>
|
||||
</Build>
|
||||
<Compiler>
|
||||
<Add option="-Wall" />
|
||||
<Add option="-DENET_DLL" />
|
||||
<Add directory="include" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
|
||||
Binary file not shown.
+32
-10
@@ -51,6 +51,22 @@ struct APP0infotype
|
||||
};
|
||||
};
|
||||
|
||||
struct APP1infotype
|
||||
{
|
||||
WORD marker;
|
||||
WORD length;
|
||||
const char *sig1, *sig2;
|
||||
APP1infotype()
|
||||
{
|
||||
marker = 0xFFE1;
|
||||
length = 46;
|
||||
sig1 = "Exif\0\0MM";
|
||||
sig2 = "\0\x2a\0\0\0\10\0\1\1\x31\0\2\0\0\0\14"
|
||||
"\0\0\0\x1a\0\0\0\0\101\x73\x73\141\165"
|
||||
"\154\164\103\165\142\145";
|
||||
};
|
||||
};
|
||||
|
||||
struct SOF0infotype
|
||||
{
|
||||
WORD marker;
|
||||
@@ -189,6 +205,7 @@ class jpegenc
|
||||
static WORD mask[];
|
||||
|
||||
APP0infotype APP0info;
|
||||
APP1infotype APP1info;
|
||||
SOF0infotype SOF0info;
|
||||
DQTinfotype DQTinfo;
|
||||
SOSinfotype SOSinfo;
|
||||
@@ -198,6 +215,7 @@ class jpegenc
|
||||
SBYTE bytepos;
|
||||
|
||||
void write_APP0info(void);
|
||||
void write_APP1info(void);
|
||||
void write_SOF0info(void);
|
||||
void write_DQTinfo(void);
|
||||
void set_quant_table(BYTE *basic_table, BYTE scale_factor, BYTE *newtable);
|
||||
@@ -205,7 +223,7 @@ class jpegenc
|
||||
void write_DHTinfo(void);
|
||||
void set_DHTinfo(void);
|
||||
void write_SOSinfo(void);
|
||||
void write_comment(BYTE *comment);
|
||||
void write_comment(const char *comment);
|
||||
void writebits(bitstring bs);
|
||||
void compute_Huffman_table(BYTE *nrcodes, BYTE *std_table, bitstring *HT);
|
||||
void init_Huffman_tables(void);
|
||||
@@ -255,7 +273,7 @@ class jpegenc
|
||||
|
||||
stream *fp_jpeg_stream;
|
||||
|
||||
int encode(const char *filename, SDL_Surface *image, int jpegquality);
|
||||
int encode(const char *filename, SDL_Surface *image, int jpegquality, const char *comment);
|
||||
};
|
||||
|
||||
BYTE jpegenc::zigzag[64] = {
|
||||
@@ -347,11 +365,6 @@ BYTE jpegenc::std_ac_chrominance_values[162] = {
|
||||
|
||||
WORD jpegenc::mask[16] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
|
||||
|
||||
|
||||
//******************************************************************************
|
||||
//******************************************************************************
|
||||
// Toca: TODO: the following goes into jpegenc.cpp or some other .cpp file
|
||||
|
||||
void jpegenc::write_APP0info() //Nothing to overwrite for APP0info
|
||||
{
|
||||
writeword(APP0info.marker);
|
||||
@@ -370,6 +383,14 @@ void jpegenc::write_APP0info() //Nothing to overwrite for APP0info
|
||||
writebyte(APP0info.thumbnheight);
|
||||
}
|
||||
|
||||
void jpegenc::write_APP1info()
|
||||
{
|
||||
writeword(APP1info.marker);
|
||||
writeword(APP1info.length);
|
||||
loopi(8) writebyte(APP1info.sig1[i]);
|
||||
loopi(APP1info.length - 10) writebyte(APP1info.sig2[i]);
|
||||
}
|
||||
|
||||
void jpegenc::write_SOF0info()
|
||||
{
|
||||
writeword(SOF0info.marker);
|
||||
@@ -500,7 +521,7 @@ void jpegenc::write_SOSinfo() //Nothing to overwrite for SOSinfo
|
||||
writebyte(SOSinfo.Bf);
|
||||
}
|
||||
|
||||
void jpegenc::write_comment(BYTE *comment)
|
||||
void jpegenc::write_comment(const char *comment)
|
||||
{
|
||||
WORD i, length;
|
||||
writeword(0xFFFE);
|
||||
@@ -811,7 +832,7 @@ void jpegenc::main_encoder()
|
||||
}
|
||||
}
|
||||
|
||||
int jpegenc::encode(const char *filename, SDL_Surface *image, int jpegquality)
|
||||
int jpegenc::encode(const char *filename, SDL_Surface *image, int jpegquality, const char *comment)
|
||||
{
|
||||
RGB_buffer = (BYTE *)image->pixels;
|
||||
width = image->w;
|
||||
@@ -842,7 +863,8 @@ int jpegenc::encode(const char *filename, SDL_Surface *image, int jpegquality)
|
||||
|
||||
writeword(0xFFD8);
|
||||
write_APP0info();
|
||||
// write_comment("Cris made this JPEG with his own encoder");
|
||||
write_APP1info();
|
||||
if(comment) write_comment(comment);
|
||||
write_DQTinfo();
|
||||
write_SOF0info();
|
||||
write_DHTinfo();
|
||||
|
||||
+9
-6
@@ -175,16 +175,16 @@ void setprocesspriority(bool high)
|
||||
|
||||
VARP(pngcompress, 0, 9, 9);
|
||||
|
||||
void writepngchunk(stream *f, const char *type, uchar *data = NULL, uint len = 0)
|
||||
void writepngchunk(stream *f, const char *type, const void *data = NULL, uint len = 0)
|
||||
{
|
||||
f->putbig<uint>(len);
|
||||
f->write(type, 4);
|
||||
f->write(data, len);
|
||||
if(data) f->write(data, len);
|
||||
|
||||
uint crc = crc32(0, Z_NULL, 0);
|
||||
crc = crc32(crc, (const Bytef *)type, 4);
|
||||
if(data) crc = crc32(crc, data, len);
|
||||
f->putbig<uint>(crc);
|
||||
crc = ~crc32(crc, (const Bytef *)type, 4);
|
||||
if(data) loopi(len) enet_crc32_inc(&crc, ((const uchar *)data)[i]);
|
||||
f->putbig<uint>(~crc);
|
||||
}
|
||||
|
||||
int save_png(const char *filename, SDL_Surface *image)
|
||||
@@ -194,6 +194,7 @@ int save_png(const char *filename, SDL_Surface *image)
|
||||
|
||||
stream *f = openfile(filename, "wb");
|
||||
if(!f) { conoutf("could not write to %s", filename); return -1; }
|
||||
const char *scores = asciiscores(true);
|
||||
|
||||
uchar signature[] = { 137, 80, 78, 71, 13, 10, 26, 10 };
|
||||
f->write(signature, sizeof(signature));
|
||||
@@ -261,6 +262,8 @@ int save_png(const char *filename, SDL_Surface *image)
|
||||
f->seek(0, SEEK_END);
|
||||
f->putbig<uint>(crc);
|
||||
|
||||
writepngchunk(f, "tEXt", "\123o\165rc\145\0\101ss\141" "\165\154\164\103\165\142\145", 18);
|
||||
writepngchunk(f, "tEXt", scores - 8, strlen(scores) + 8);
|
||||
writepngchunk(f, "IEND");
|
||||
|
||||
delete f;
|
||||
@@ -367,7 +370,7 @@ void mapscreenshot(const char *imagepath, bool mapshot, int fileformat, float sc
|
||||
case 1: // jpeg
|
||||
{
|
||||
jpegenc jpegencoder;
|
||||
jpegencoder.encode(imagepath, image, quality);
|
||||
jpegencoder.encode(imagepath, image, quality, asciiscores(true));
|
||||
break;
|
||||
}
|
||||
case 2: // png
|
||||
|
||||
+12
-11
@@ -439,7 +439,7 @@ void renderscores(void *menu, bool init)
|
||||
|
||||
#define MAXJPGCOM 65533 // maximum JPEG comment length
|
||||
|
||||
void addstr(char *dest, const char *src) { if(strlen(dest) + strlen(src) < MAXJPGCOM) strcat(dest, src); }
|
||||
static void addstr(char *&dest, const char *end, const char *src) { size_t l = strlen(src); if(dest + l < end) copystring(dest, src, l + 1), dest += l; }
|
||||
|
||||
const char *asciiscores(bool destjpg)
|
||||
{
|
||||
@@ -455,16 +455,17 @@ const char *asciiscores(bool destjpg)
|
||||
loopv(players) if(players[i]) scores.add(players[i]);
|
||||
scores.sort(scorecmp);
|
||||
|
||||
buf[0] = '\0';
|
||||
copystring(buf, "Comment", MAXJPGCOM); // include PNG keyword and skip it (which looks like a hack because it is one)
|
||||
char *t = buf + 8, *e = buf + MAXJPGCOM;
|
||||
if(destjpg)
|
||||
{
|
||||
formatstring(text)("AssaultCube Screenshot (%s)\n", asctimestr());
|
||||
addstr(buf, text);
|
||||
addstr(t, e, text);
|
||||
}
|
||||
if(getclientmap()[0])
|
||||
{
|
||||
formatstring(text)("\n\"%s\" on map %s", modestr(gamemode, 0), getclientmap());
|
||||
addstr(buf, text);
|
||||
addstr(t, e, text);
|
||||
}
|
||||
if(multiplayer(NULL))
|
||||
{
|
||||
@@ -474,15 +475,15 @@ const char *asciiscores(bool destjpg)
|
||||
string sdesc;
|
||||
filtertext(sdesc, s->sdesc, FTXT__SERVDESC | FTXT_NOCOLOR);
|
||||
formatstring(text)(", %s:%d %s", s->name, s->port, sdesc);
|
||||
addstr(buf, text);
|
||||
addstr(t, e, text);
|
||||
}
|
||||
}
|
||||
if(destjpg)
|
||||
addstr(buf, "\n");
|
||||
addstr(t, e, "\n");
|
||||
else
|
||||
{
|
||||
formatstring(text)("\n%sfrags deaths cn%s name\n", m_flags ? "flags " : "", m_teammode ? " team" : "");
|
||||
addstr(buf, text);
|
||||
addstr(t, e, text);
|
||||
}
|
||||
loopv(scores)
|
||||
{
|
||||
@@ -495,7 +496,7 @@ const char *asciiscores(bool destjpg)
|
||||
else
|
||||
formatstring(text)("%s %4d %4d %2d%s %s%s\n", m_flags ? flags : "", d->frags, d->deaths, d->clientnum,
|
||||
m_teammode ? team : "", d->name, d->clientrole==CR_ADMIN ? " (admin)" : d==player1 ? " (you)" : "");
|
||||
addstr(buf, text);
|
||||
addstr(t, e, text);
|
||||
}
|
||||
discscores.sort(discscorecmp);
|
||||
loopv(discscores)
|
||||
@@ -508,15 +509,15 @@ const char *asciiscores(bool destjpg)
|
||||
formatstring(text)("%s(disconnected)%s (%s%d/%d)\n", d.name, m_teammode ? team : "", m_flags ? flags : "", d.frags, d.deaths);
|
||||
else
|
||||
formatstring(text)("%s %4d %4d --%s %s(disconnected)\n", m_flags ? flags : "", d.frags, d.deaths, m_teammode ? team : "", d.name);
|
||||
addstr(buf, text);
|
||||
addstr(t, e, text);
|
||||
}
|
||||
if(destjpg)
|
||||
{
|
||||
extern int minutesremaining;
|
||||
formatstring(text)("(%sfrags/deaths), %d minute%s remaining\n", m_flags ? "flags/" : "", minutesremaining, minutesremaining == 1 ? "" : "s");
|
||||
addstr(buf, text);
|
||||
addstr(t, e, text);
|
||||
}
|
||||
return buf;
|
||||
return buf + 8;
|
||||
}
|
||||
|
||||
void consolescores()
|
||||
|
||||
Reference in New Issue
Block a user