From 8e4a958eea326db65c7621b4c1840cdca97f6d07 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Wed, 30 Nov 2016 17:16:50 +0100 Subject: [PATCH] Make it possible to save XBoard piece images as Windows bitmaps A new option -bmpSave N would make XBoard save the images of the first N pieces of each color, plus the King, as a Windows .bmp file with alpha channel (32 bits/pixel). This happens in a sub-directory 'bmaps'. After the black King is saved, XBoard will exit. --- args.h | 4 +++- common.h | 1 + draw.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletions(-) diff --git a/args.h b/args.h index c6914b0..1da2448 100644 --- a/args.h +++ b/args.h @@ -112,6 +112,7 @@ char *firstEngineLine; char *secondEngineLine; char *icsNick; char *theme; +char *replace; void EnsureOnScreen(int *x, int *y, int minX, int minY); char StringGet(void *getClosure); @@ -620,6 +621,7 @@ ArgDescriptor argDescriptors[] = { { "replace", ArgString, (void *) &replace, FALSE, (ArgIniType) NULL }, { "fixedSize", ArgBoolean, (void *) &appData.fixedSize, TRUE, (ArgIniType) FALSE }, { "showMoveTime", ArgBoolean, (void *) &appData.moveTime, TRUE, (ArgIniType) FALSE }, + { "bmpSave", ArgInt, (void *) &appData.bmpSave, FALSE, 0 }, // [HGM] tournament options { "tourneyFile", ArgFilename, (void *) &appData.tourneyFile, FALSE, (ArgIniType) "" }, @@ -1184,7 +1186,7 @@ ParseArgs(GetFunc get, void *cl) break; } if(replace) { // previous -replace option makes this string option conditional - char *p = replace; + char *p = (char*) replace; free(replace); replace = NULL; // but expires in the process if(strcmp(*(char**) ad->argLoc, p)) break; // only use to replace the given string } diff --git a/common.h b/common.h index 2aff360..b1b239c 100644 --- a/common.h +++ b/common.h @@ -818,6 +818,7 @@ typedef struct { int tourneyType; int tourneyCycles; int seedBase; + int bmpSave; Boolean roundSync; Boolean cycleSync; Boolean numberTag; diff --git a/draw.c b/draw.c index 8b78892..79518a0 100644 --- a/draw.c +++ b/draw.c @@ -375,6 +375,38 @@ LoadSVG (char *dir, int color, int piece, int retry) return NULL; } +static void Wint(FILE *f, int n) +{ // write 32-bit int, lsb first + fprintf(f, "%c%c%c%c", n&255, n>>8&255, n>>16&255, n>>24&255); +} + +static void +SaveWindowsBitmap(ChessSquare piece, int color, int *data, int stride, int w, int h, int bpp) +{ + int i, v, line = (w*bpp + 3)>>2, size = line*4*h; + char buf[100]; + FILE *f; + snprintf(buf, 100, "bmaps/piece%d_%d%c.bmp", piece, w, color ? 's': 'o'); + if(piece >= appData.bmpSave && piece != WhiteKing) return; + f = fopen(buf, "wb"); + if(!f) return; + fprintf(f, "BM"); + Wint(f, size+54); Wint(f, 0); Wint(f, 54); Wint(f, 40); // file size, reserved, image offset, header size + Wint(f, w); Wint(f, h); Wint(f, 8*bpp << 16 | 1); // width, height, planes & bits/pix + Wint(f, 0); // compression + Wint(f, size); Wint(f, 3780); Wint(f, 3780); Wint(f, 0); Wint(f, 0); // image size, pix/m (H and V), color-table size (2x) + for(v=h-1; v>=0; v--) { + for(i=0; i>16&255, g=pix>>8&255, b=pix&255, a=pix>>24&255; + r = r*a/255; b = b*a/255; g = g*a/255; + if(bpp == 4) fprintf(f, "%c%c%c%c", b, g, r, a); else fprintf(f, "%c%c%c", b, g, r); + } + i *= bpp; while(i++ < line*4) fprintf(f, "%c", 0); // padding + } + fclose(f); + if(appData.bmpSave && piece == WhiteKing && color) exit(0); +} + static void ScaleOnePiece (int color, int piece, char *pieceDir) { @@ -431,6 +463,7 @@ ScaleOnePiece (int color, int piece, char *pieceDir) int i, j, p; sscanf(color ? appData.blackPieceColor+1 : appData.whitePieceColor+1, "%x", &p); // replacement color cairo_surface_flush(cs); + SaveWindowsBitmap(piece, color, buf, stride, squareSize, squareSize, 4); for(i=0; i