(svn r631) Merge r440, r444, r485, r630 to trunk:

r440
Move screenshot function declarations to new file screenshot.h
Clean up screenshot.c a bit, mostly whitespace, alloca() -> malloc() and checking return values
r485
Remove unused field from struct ScreenshotFormat
This commit is contained in:
tron 2004-11-15 19:25:59 +00:00
parent fb4b5fa841
commit 450c669eb2
8 changed files with 111 additions and 53 deletions

View File

@ -257,17 +257,12 @@ void ttd_strlcpy(char *dst, const char *src, size_t len);
// callback from drivers that is called if the game size changes dynamically // callback from drivers that is called if the game size changes dynamically
void GameSizeChanged(); void GameSizeChanged();
bool MakeScreenshot();
bool MakeWorldScreenshot(int left, int top, int width, int height, int zoom);
bool FileExists(const char *filename); bool FileExists(const char *filename);
bool ReadLanguagePack(int index); bool ReadLanguagePack(int index);
void InitializeLanguagePacks(); void InitializeLanguagePacks();
byte *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize); byte *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize);
int GetLanguageList(char **languages, int max); int GetLanguageList(char **languages, int max);
const char *GetScreenshotFormatDesc(int i);
void InitializeScreenshotFormats();
void SetScreenshotFormat(int i);
void CheckSwitchToEuro(); void CheckSwitchToEuro();
void LoadFromConfig(); void LoadFromConfig();

View File

@ -4,6 +4,7 @@
#include "viewport.h" #include "viewport.h"
#include "player.h" #include "player.h"
#include "gui.h" #include "gui.h"
#include "screenshot.h"
// called by the ScreenShot proc to generate screenshot lines. // called by the ScreenShot proc to generate screenshot lines.
typedef void ScreenshotCallback(void *userdata, byte *buf, uint y, uint pitch, uint n); typedef void ScreenshotCallback(void *userdata, byte *buf, uint y, uint pitch, uint n);
@ -13,7 +14,6 @@ typedef struct {
const char *name; const char *name;
const char *extension; const char *extension;
ScreenshotHandlerProc *proc; ScreenshotHandlerProc *proc;
byte id;
} ScreenshotFormat; } ScreenshotFormat;
//************************************************ //************************************************
@ -97,15 +97,19 @@ static bool MakeBmpImage(const char *name, ScreenshotCallback *callb, void *user
} }
// write file header and info header and palette // write file header and info header and palette
fwrite(&bfh, 1, sizeof(bfh), f); if (fwrite(&bfh, sizeof(bfh), 1, f) != 1) return false;
fwrite(&bih, 1, sizeof(bih), f); if (fwrite(&bih, sizeof(bih), 1, f) != 1) return false;
fwrite(rq, 1, sizeof(rq), f); if (fwrite(rq, sizeof(rq), 1, f) != 1) return false;
// use by default 64k temp memory // use by default 64k temp memory
maxlines = clamp(65536 / padw, 16, 128); maxlines = clamp(65536 / padw, 16, 128);
// now generate the bitmap bits // now generate the bitmap bits
buff = (byte*)alloca(padw * maxlines); // by default generate 128 lines at a time. buff = malloc(padw * maxlines); // by default generate 128 lines at a time.
if (buff == NULL) {
fclose(f);
return false;
}
memset(buff, 0, padw * maxlines); // zero the buffer to have the padding bytes set to 0 memset(buff, 0, padw * maxlines); // zero the buffer to have the padding bytes set to 0
// start at the bottom, since bitmaps are stored bottom up. // start at the bottom, since bitmaps are stored bottom up.
@ -119,9 +123,14 @@ static bool MakeBmpImage(const char *name, ScreenshotCallback *callb, void *user
// write each line // write each line
while (n) while (n)
fwrite(buff + (--n) * padw, 1, padw, f); if (fwrite(buff + (--n) * padw, padw, 1, f) != 1) {
} while (h); free(buff);
fclose(f);
return false;
}
} while (h != 0);
free(buff);
fclose(f); fclose(f);
return true; return true;
@ -163,13 +172,13 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (char *)name, png_my_error, png_my_warning); png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (char *)name, png_my_error, png_my_warning);
if (!png_ptr) { if (png_ptr == NULL) {
fclose(f); fclose(f);
return false; return false;
} }
info_ptr = png_create_info_struct(png_ptr); info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) { if (info_ptr == NULL) {
png_destroy_write_struct(&png_ptr, (png_infopp)NULL); png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
fclose(f); fclose(f);
return false; return false;
@ -185,8 +194,8 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user
png_set_filter(png_ptr, 0, PNG_FILTER_NONE); png_set_filter(png_ptr, 0, PNG_FILTER_NONE);
png_set_IHDR(png_ptr, info_ptr, w, h, pixelformat, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, png_set_IHDR(png_ptr, info_ptr, w, h, pixelformat, PNG_COLOR_TYPE_PALETTE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
// convert the palette to the .PNG format. // convert the palette to the .PNG format.
{ {
@ -208,7 +217,12 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user
maxlines = clamp(65536 / w, 16, 128); maxlines = clamp(65536 / w, 16, 128);
// now generate the bitmap bits // now generate the bitmap bits
buff = (byte*)alloca(w * maxlines); // by default generate 128 lines at a time. buff = malloc(w * maxlines); // by default generate 128 lines at a time.
if (buff == NULL) {
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(f);
return false;
}
memset(buff, 0, w * maxlines); // zero the buffer to have the padding bytes set to 0 memset(buff, 0, w * maxlines); // zero the buffer to have the padding bytes set to 0
y = 0; y = 0;
@ -228,6 +242,7 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user
png_write_end(png_ptr, info_ptr); png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr);
free(buff);
fclose(f); fclose(f);
return true; return true;
} }
@ -289,19 +304,27 @@ static bool MakePCXImage(const char *name, ScreenshotCallback *callb, void *user
pcx.height = TO_LE16(h); pcx.height = TO_LE16(h);
// write pcx header // write pcx header
fwrite(&pcx, sizeof(pcx), 1, f); if (fwrite(&pcx, sizeof(pcx), 1, f) != 1) {
fclose(f);
return false;
}
// use by default 64k temp memory // use by default 64k temp memory
maxlines = clamp(65536 / w, 16, 128); maxlines = clamp(65536 / w, 16, 128);
// now generate the bitmap bits // now generate the bitmap bits
buff = (byte*)alloca(w * maxlines); // by default generate 128 lines at a time. buff = malloc(w * maxlines); // by default generate 128 lines at a time.
if (buff == NULL) {
fclose(f);
return false;
}
memset(buff, 0, w * maxlines); // zero the buffer to have the padding bytes set to 0 memset(buff, 0, w * maxlines); // zero the buffer to have the padding bytes set to 0
y = 0; y = 0;
do { do {
// determine # lines to write // determine # lines to write
uint n = min(h - y, maxlines), i; uint n = min(h - y, maxlines);
uint i;
// render the pixels into the buffer // render the pixels into the buffer
callb(userdata, buff, y, w, n); callb(userdata, buff, y, w, n);
@ -312,30 +335,55 @@ static bool MakePCXImage(const char *name, ScreenshotCallback *callb, void *user
int runcount = 1; int runcount = 1;
byte *bufp = buff + i * w; byte *bufp = buff + i * w;
byte runchar = buff[0]; byte runchar = buff[0];
uint left = w - 1; uint left;
// for each pixel... // for each pixel...
while (left) { for (left = w - 1; left > 0; --left) {
byte ch = *bufp++; byte ch = *bufp++;
if (ch != runchar || runcount >= 0x3f) { if (ch != runchar || runcount >= 0x3f) {
if (runcount > 1 || (runchar & 0xC0) == 0xC0) fputc(0xC0 | runcount, f); if (runcount > 1 || (runchar & 0xC0) == 0xC0)
fputc(runchar,f); if (fputc(0xC0 | runcount, f) == EOF) {
free(buff);
fclose(f);
return false;
}
if (fputc(runchar, f) == EOF) {
free(buff);
fclose(f);
return false;
}
runcount = 0; runcount = 0;
runchar = ch; runchar = ch;
} }
runcount++; runcount++;
left--;
} }
// write remaining bytes.. // write remaining bytes..
if (runcount > 1 || (runchar & 0xC0) == 0xC0) fputc(0xC0 | runcount, f); if (runcount > 1 || (runchar & 0xC0) == 0xC0)
fputc(runchar,f); if (fputc(0xC0 | runcount, f) == EOF) {
free(buff);
fclose(f);
return false;
}
if (fputc(runchar, f) == EOF) {
free(buff);
fclose(f);
return false;
}
} }
} while (y != h); } while (y != h);
free(buff);
// write 8-bit color palette // write 8-bit color palette
fputc(12, f); if (fputc(12, f) == EOF) {
fwrite(palette, 256*3, 1, f); fclose(f);
return false;
}
if (fwrite(palette, 256 * 3, 1, f) != 1) {
fclose(f);
return false;
}
fclose(f); fclose(f);
return true; return true;
@ -353,11 +401,14 @@ static const ScreenshotFormat _screenshot_formats[] = {
{"PCX", "pcx", &MakePCXImage}, {"PCX", "pcx", &MakePCXImage},
}; };
void InitializeScreenshotFormats() void InitializeScreenshotFormats(void)
{ {
int i, j; int i, j;
for (i = 0, j = 0; i != lengthof(_screenshot_formats); i++) for (i = 0, j = 0; i != lengthof(_screenshot_formats); i++)
if (!strcmp(_screenshot_format_name, _screenshot_formats[i].extension)) { j=i; break; } if (!strcmp(_screenshot_format_name, _screenshot_formats[i].extension)) {
j = i;
break;
}
_cur_screenshot_format = j; _cur_screenshot_format = j;
_num_screenshot_formats = lengthof(_screenshot_formats); _num_screenshot_formats = lengthof(_screenshot_formats);
} }
@ -376,16 +427,13 @@ void SetScreenshotFormat(int i)
// screenshot generator that dumps the current video buffer // screenshot generator that dumps the current video buffer
static void CurrentScreenCallback(void *userdata, byte *buf, uint y, uint pitch, uint n) static void CurrentScreenCallback(void *userdata, byte *buf, uint y, uint pitch, uint n)
{ {
for (; n > 0; --n) for (; n > 0; --n) {
{
memcpy(buf, _screen.dst_ptr + y * _screen.pitch, _screen.width); memcpy(buf, _screen.dst_ptr + y * _screen.pitch, _screen.width);
++y; ++y;
buf += pitch; buf += pitch;
} }
} }
extern void ViewportDoDraw(ViewPort *vp, int left, int top, int right, int bottom);
// generate a large piece of the world // generate a large piece of the world
static void LargeWorldCallback(void *userdata, byte *buf, uint y, uint pitch, uint n) static void LargeWorldCallback(void *userdata, byte *buf, uint y, uint pitch, uint n)
{ {
@ -450,9 +498,7 @@ static char *MakeScreenshotName(const char *ext)
return filename; return filename;
} }
extern byte _cur_palette[768]; bool MakeScreenshot(void)
bool MakeScreenshot()
{ {
const ScreenshotFormat *sf = _screenshot_formats + _cur_screenshot_format; const ScreenshotFormat *sf = _screenshot_formats + _cur_screenshot_format;
return sf->proc(MakeScreenshotName(sf->extension), CurrentScreenCallback, NULL, _screen.width, _screen.height, 8, _cur_palette); return sf->proc(MakeScreenshotName(sf->extension), CurrentScreenCallback, NULL, _screen.width, _screen.height, 8, _cur_palette);

12
screenshot.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef SCREENSHOT_H
#define SCREENSHOT_H
void InitializeScreenshotFormats(void);
const char *GetScreenshotFormatDesc(int i);
void SetScreenshotFormat(int i);
bool MakeScreenshot(void);
bool MakeWorldScreenshot(int left, int top, int width, int height, int zoom);
#endif

View File

@ -6,6 +6,7 @@
#include "gfx.h" #include "gfx.h"
#include "command.h" #include "command.h"
#include "engine.h" #include "engine.h"
#include "screenshot.h"
static uint32 _difficulty_click_a; static uint32 _difficulty_click_a;
static uint32 _difficulty_click_b; static uint32 _difficulty_click_b;

View File

@ -4,6 +4,7 @@
#include "town.h" #include "town.h"
#include "vehicle.h" #include "vehicle.h"
#include "news.h" #include "news.h"
#include "screenshot.h"
#define USE_TABLE(x) { assert(index < lengthof(x)); str = x[index]; break; } #define USE_TABLE(x) { assert(index < lengthof(x)); str = x[index]; break; }

1
ttd.c
View File

@ -22,6 +22,7 @@
#include "saveload.h" #include "saveload.h"
#include "ai.h" #include "ai.h"
#include "console.h" #include "console.h"
#include "screenshot.h"
#include <stdarg.h> #include <stdarg.h>

View File

@ -1132,7 +1132,7 @@ static void ViewportDrawStrings(DrawPixelInfo *dpi, StringSpriteToDraw *ss)
_cur_dpi = dpi; _cur_dpi = dpi;
} }
void ViewportDoDraw(ViewPort *vp, int left, int top, int right, int bottom) void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom)
{ {
ViewportDrawer vd; ViewportDrawer vd;
int mask; int mask;

View File

@ -116,4 +116,6 @@ VARDEF Point _tile_fract_coords;
extern TileHighlightData * const _thd_ptr; extern TileHighlightData * const _thd_ptr;
#endif void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom);
#endif /* VIEWPORT_H */