/* * htmlimages.c * * by Gary Wong , 1997-2002. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: htmlimages.c,v 1.26 2004/04/30 17:33:58 Superfly_Jon Exp $ */ #if HAVE_CONFIG_H #include #endif #include #if HAVE_SYS_STAT_H #include #endif #include #include #include #if HAVE_SYS_TYPES_H #include #endif #if HAVE_UNISTD_H #include #endif #if HAVE_LIBART #include #include #include #include #include #include #include #include #include #include #include #endif #include "backgammon.h" #include "export.h" #include "i18n.h" #include "render.h" #include "renderprefs.h" #include "boardpos.h" #include "boarddim.h" #if HAVE_LIBPNG char *szFile, *pchFile; int imagesWritten; #define NUM_IMAGES 344 /* Overall board size */ int s; /* Size of cube and dice - now same as rest of board */ #define ss s /* Helpers for 2d position in arrays */ #define boardStride (BOARD_WIDTH * s * 3) #define coord(x, y) ((x) * s * 3 + (y) * s * boardStride) #define coordStride(x, y, stride) ((x) * s * 3 + (y) * s * stride) unsigned char *auchBoard, *auchChequer[2], *auchChequerLabels, *auchLo, *auchHi, *auchLoRev, *auchHiRev, *auchCube, *auchCubeFaces, *auchDice[2], *auchPips[2], *auchLabel, *auchOff[2], *auchMidBoard, *auchBar[2], *auchPoint[2][2][2]; unsigned short *asRefract[2]; #if HAVE_LIBART unsigned char *auchArrow[ 2 ]; #endif unsigned char *auchMidlb; static void WriteImageStride(unsigned char* img, int stride, int cx, int cy) { if (WritePNG(szFile, img, stride, cx, cy) == -1) outputf("Error creating file %s\n", szFile); imagesWritten++; ProgressValueAdd(1); } static void WriteStride(const char* name, unsigned char* img, int stride, int cx, int cy) { strcpy(pchFile, name); WriteImageStride(img, stride, cx, cy); } static void WriteImage(unsigned char* img, int cx, int cy) { WriteImageStride(img, boardStride, cx, cy); } static void Write(const char* name, unsigned char* img, int cx, int cy) { strcpy(pchFile, name); WriteImage(img, cx, cy); } static void DrawArrow(int side, int player) { /* side 0 = left, 1 = right */ #if HAVE_LIBART int x, y; #endif int offset_x = 0; memcpy( auchMidlb, auchBoard, BOARD_WIDTH * s * BOARD_HEIGHT * s * 3 ); #if HAVE_LIBART ArrowPosition(side /* rd.fClockwise */, s, &x, &y); AlphaBlendClip2( auchMidlb, boardStride, x, y, BOARD_WIDTH * s, BOARD_HEIGHT * s, auchMidlb, boardStride, x, y, auchArrow[player], s * ARROW_WIDTH * 4, 0, 0, s * ARROW_WIDTH, s * ARROW_HEIGHT ); #endif sprintf( pchFile, "b-mid%cb-%c.png", side ? 'r' : 'l', player ? 'o' : 'x' ); if (side == 1) offset_x = BOARD_WIDTH - BEAROFF_WIDTH; WriteImage(auchMidlb + coord(offset_x, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2), BEAROFF_WIDTH * s, BOARD_CENTER_HEIGHT * s); } static void DrawPips(unsigned char *auchDest, int nStride, unsigned char *auchPip, int n) { int ix, iy, afPip[9]; afPip[0] = afPip[8] = (n == 2) || (n == 3) || (n == 4) || (n == 5) || (n == 6); afPip[1] = afPip[7] = 0; afPip[2] = afPip[6] = (n == 4) || (n == 5) || (n == 6); afPip[3] = afPip[5] = n == 6; afPip[4] = n & 1; for (iy = 0; iy < 3; iy++) { for (ix = 0; ix < 3; ix++) { if (afPip[iy * 3 + ix]) CopyArea(auchDest + (int)(1.5 * (ix + 1) * ss) * 3 + ((int)(1.5 * (iy + 1) * ss) * nStride), nStride, auchPip, ss * 3, ss, ss); } } } static void WriteBorder(char* file, unsigned char *auchSrc, unsigned char *auchBoardSrc) { CopyArea(auchLabel, boardStride, auchBoardSrc, boardStride, BOARD_WIDTH * s, BORDER_HEIGHT * s); AlphaBlendClip(auchLabel, boardStride, 0, 0, BOARD_WIDTH * s, BORDER_HEIGHT * s, auchLabel, boardStride, 0, 0, auchSrc, BOARD_WIDTH * s * 4, 0, 0, BOARD_WIDTH * s, BORDER_HEIGHT * s); Write(file, auchLabel, BOARD_WIDTH * s, BORDER_HEIGHT * s); } static void WriteImages() { int i, j, k; imagesWritten = 0; /* top border-high numbers */ WriteBorder("b-hitop.png", auchHi, auchBoard); WriteBorder("b-hitopr.png", auchHiRev, auchBoard); /* top border-low numbers */ WriteBorder("b-lotop.png", auchLo, auchBoard); WriteBorder("b-lotopr.png", auchLoRev, auchBoard); /* empty points */ Write("b-gd.png", auchBoard + coord(BEAROFF_WIDTH, BORDER_HEIGHT), POINT_WIDTH * s, POINT_HEIGHT * s); Write("b-rd.png", auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BORDER_HEIGHT), POINT_WIDTH * s, POINT_HEIGHT * s); Write("b-ru.png", auchBoard + coord(BEAROFF_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), POINT_WIDTH * s, POINT_HEIGHT * s); Write("b-gu.png", auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), POINT_WIDTH * s, POINT_HEIGHT * s); /* upper left bearoff tray */ Write("b-loff-x0.png", auchBoard + coord(0, BORDER_HEIGHT), BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s); /* upper right bearoff tray */ Write("b-roff-x0.png", auchBoard + coord(BOARD_WIDTH - BEAROFF_WIDTH, BORDER_HEIGHT), BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s); /* lower right bearoff tray */ Write("b-roff-o0.png", auchBoard + coord(BOARD_WIDTH - BEAROFF_WIDTH, BORDER_HEIGHT + POINT_HEIGHT + BOARD_CENTER_HEIGHT), BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s); /* lower left bearoff tray */ Write("b-loff-o0.png", auchBoard + coord(0, BORDER_HEIGHT + POINT_HEIGHT + BOARD_CENTER_HEIGHT), BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s); /* bar top */ Write("b-ct.png", auchBoard + coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BORDER_HEIGHT), BAR_WIDTH * s, CUBE_HEIGHT * s); /* bearoff tray dividers */ /* 4 arrows, left+right side for each player */ DrawArrow(0, 0); DrawArrow(0, 1); DrawArrow(1, 0); DrawArrow(1, 1); /* left bearoff centre */ strcpy( pchFile, "b-midlb.png" ); WriteImage(auchBoard + coord(0, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2), BEAROFF_WIDTH * s, BOARD_CENTER_HEIGHT * s); /* right bearoff centre */ strcpy( pchFile, "b-midrb.png" ); WriteImage(auchBoard + coord(BOARD_WIDTH - BEAROFF_WIDTH, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2), BEAROFF_WIDTH * s, BOARD_CENTER_HEIGHT * s); /* left board centre */ strcpy( pchFile, "b-midl.png" ); WriteImage(auchBoard + coord(BEAROFF_WIDTH, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2), BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s); /* bar centre */ strcpy( pchFile, "b-midc.png" ); WriteImage(auchBoard + coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2), BAR_WIDTH * s, BOARD_CENTER_HEIGHT * s); /* right board centre */ strcpy( pchFile, "b-midr.png" ); WriteImage(auchBoard + coord(BOARD_WIDTH / 2 + BAR_WIDTH / 2, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2), BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s); /* bar bottom */ Write("b-cb.png", auchBoard + coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BOARD_HEIGHT - CUBE_HEIGHT - BORDER_HEIGHT), BAR_WIDTH * s, CUBE_HEIGHT * s); /* bottom border-high numbers */ WriteBorder("b-hibot.png", auchHi, auchBoard + coord(0, BOARD_HEIGHT - BORDER_HEIGHT)); WriteBorder("b-hibotr.png", auchHiRev, auchBoard + coord(0, BOARD_HEIGHT - BORDER_HEIGHT)); /* bottom border-low numbers */ WriteBorder("b-lobot.png", auchLo, auchBoard + coord(0, BOARD_HEIGHT - BORDER_HEIGHT)); WriteBorder("b-lobotr.png", auchLoRev, auchBoard + coord(0, BOARD_HEIGHT - BORDER_HEIGHT)); /* Copy 4 points (top/bottom and both colours) */ CopyArea(auchPoint[0][0][0], POINT_WIDTH * s * 3, auchBoard + coord(BEAROFF_WIDTH, BORDER_HEIGHT), boardStride, POINT_WIDTH * s, POINT_HEIGHT * s); CopyArea(auchPoint[0][0][1], POINT_WIDTH * s * 3, auchBoard + coord(BEAROFF_WIDTH, BORDER_HEIGHT), boardStride, POINT_WIDTH * s, POINT_HEIGHT * s); CopyArea(auchPoint[0][1][0], POINT_WIDTH * s * 3, auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), boardStride, POINT_WIDTH * s, POINT_HEIGHT * s); CopyArea(auchPoint[0][1][1], POINT_WIDTH * s * 3, auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), boardStride, POINT_WIDTH * s, POINT_HEIGHT * s); CopyArea(auchPoint[1][0][0], POINT_WIDTH * s * 3, auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BORDER_HEIGHT), boardStride, POINT_WIDTH * s, POINT_HEIGHT * s); CopyArea(auchPoint[1][0][1], POINT_WIDTH * s * 3, auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BORDER_HEIGHT), boardStride, POINT_WIDTH * s, POINT_HEIGHT * s); CopyArea(auchPoint[1][1][0], POINT_WIDTH * s * 3, auchBoard + coord(BEAROFF_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), boardStride, POINT_WIDTH * s, POINT_HEIGHT * s); CopyArea(auchPoint[1][1][1], POINT_WIDTH * s * 3, auchBoard + coord(BEAROFF_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), boardStride, POINT_WIDTH * s, POINT_HEIGHT * s); /* Bear off trays */ CopyArea(auchOff[0], BEAROFF_WIDTH * s * 3, auchBoard + coord(BOARD_WIDTH - BEAROFF_WIDTH, BORDER_HEIGHT), boardStride, BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s); CopyArea(auchOff[1], BEAROFF_WIDTH * s * 3, auchBoard + coord(BOARD_WIDTH - BEAROFF_WIDTH, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), boardStride, BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s); /* Bar areas */ CopyArea(auchBar[0], BAR_WIDTH * s * 3, auchBoard + coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BORDER_HEIGHT + CUBE_HEIGHT), boardStride, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s); CopyArea(auchBar[1], BAR_WIDTH * s * 3, auchBoard + coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2), boardStride, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s); for (i = 1; i <= 5; i++) { for (j = 0; j < 2; j++) { /* 1-5 chequers, both colours, down point */ RefractBlend(auchPoint[0][0][j] + coordStride(0, CHEQUER_HEIGHT * (i - 1), POINT_WIDTH * s * 3), POINT_WIDTH * s * 3, auchBoard + coord(BEAROFF_WIDTH, BORDER_HEIGHT + CHEQUER_HEIGHT * (i - 1)), boardStride, auchChequer[j], CHEQUER_WIDTH * s * 4, asRefract[j], CHEQUER_WIDTH * s, CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s); sprintf(pchFile, "b-gd-%c%d.png", j ? 'o' : 'x', i); WriteImageStride(auchPoint[0][0][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s); } for (j = 0; j < 2; j++) { /* 1-5 chequers, both colours, other down point */ RefractBlend(auchPoint[1][0][j] + coordStride(0, CHEQUER_HEIGHT * (i - 1), POINT_WIDTH * s * 3), POINT_WIDTH * s * 3, auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BORDER_HEIGHT + CHEQUER_HEIGHT * (i - 1)), boardStride, auchChequer[j], CHEQUER_WIDTH * s * 4, asRefract[j], CHEQUER_WIDTH * s, CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s); sprintf(pchFile, "b-rd-%c%d.png", j ? 'o' : 'x', i); WriteImageStride(auchPoint[1][0][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s); } for (j = 0; j < 2; j++) { /* 1-5 chequers, both colours, up point */ RefractBlend(auchPoint[0][1][j] + coordStride(0, CHEQUER_HEIGHT * (5 - i), POINT_WIDTH * s * 3), POINT_WIDTH * s * 3, auchBoard + coord(BEAROFF_WIDTH + POINT_WIDTH, BOARD_HEIGHT - BORDER_HEIGHT - CHEQUER_HEIGHT * i), boardStride, auchChequer[j], CHEQUER_WIDTH * s * 4, asRefract[j], CHEQUER_WIDTH * s, CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s); sprintf(pchFile, "b-gu-%c%d.png", j ? 'o' : 'x', i); WriteImageStride(auchPoint[0][1][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s); } for (j = 0; j < 2; j++) { /* 1-5 chequers, both colours, other up point */ RefractBlend(auchPoint[1][1][j] + coordStride(0, CHEQUER_HEIGHT * (5 - i), POINT_WIDTH * s * 3), POINT_WIDTH * s * 3, auchBoard + coord(BEAROFF_WIDTH, BOARD_HEIGHT - BORDER_HEIGHT - CHEQUER_HEIGHT * i), boardStride, auchChequer[j], CHEQUER_WIDTH * s * 4, asRefract[j], CHEQUER_WIDTH * s, CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s); sprintf(pchFile, "b-ru-%c%d.png", j ? 'o' : 'x', i); WriteImageStride(auchPoint[1][1][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s); } /* 1-5 chequers in bear-off trays */ RefractBlend(auchOff[0] + coordStride(BORDER_WIDTH, CHEQUER_HEIGHT * (i - 1), BEAROFF_WIDTH * s * 3), BEAROFF_WIDTH * s * 3, auchBoard + coord(BOARD_WIDTH - BORDER_WIDTH - CHEQUER_WIDTH, BORDER_HEIGHT + CHEQUER_HEIGHT * (i - 1)), boardStride, auchChequer[0], CHEQUER_WIDTH * s * 4, asRefract[0], CHEQUER_WIDTH * s, CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s); sprintf(pchFile, "b-roff-x%d.png", i); WriteImageStride(auchOff[0], BEAROFF_WIDTH * s * 3, BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s); RefractBlend(auchOff[1] + coordStride(BORDER_WIDTH, CHEQUER_HEIGHT * (5 - i), BEAROFF_WIDTH * s * 3), BEAROFF_WIDTH * s * 3, auchBoard + coord(BOARD_WIDTH - BORDER_WIDTH - CHEQUER_WIDTH, BOARD_HEIGHT - BORDER_HEIGHT - CHEQUER_HEIGHT * i), boardStride, auchChequer[1], CHEQUER_WIDTH * s * 4, asRefract[1], CHEQUER_WIDTH * s, CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s); sprintf(pchFile, "b-roff-o%d.png", i); WriteImageStride(auchOff[1], BEAROFF_WIDTH * s * 3, BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s); } for (i = 6; i <= 15; i++) { for (j = 0; j < 2; j++) { /* 6-15 chequers, both colours, down point */ CopyArea(auchPoint[0][0][j] + coordStride(1, CHEQUER_HEIGHT * 4 + 1, POINT_WIDTH * s * 3), POINT_WIDTH * s * 3, auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3, CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s); sprintf(pchFile, "b-gd-%c%d.png", j ? 'o' : 'x', i); WriteImageStride(auchPoint[0][0][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s); } for (j = 0; j < 2; j++) { /* 6-15 chequers, both colours, other down point */ CopyArea(auchPoint[1][0][j] + coordStride(1, CHEQUER_HEIGHT * 4 + 1, POINT_WIDTH * s * 3), POINT_WIDTH * s * 3, auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3, CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s); sprintf(pchFile, "b-rd-%c%d.png", j ? 'o' : 'x', i); WriteImageStride(auchPoint[1][0][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s); } for (j = 0; j < 2; j++) { /* 6-15 chequers, both colours, up point */ CopyArea(auchPoint[0][1][j] + coordStride(1, 1, POINT_WIDTH * s * 3), POINT_WIDTH * s * 3, auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3, CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s); sprintf(pchFile, "b-gu-%c%d.png", j ? 'o' : 'x', i); WriteImageStride(auchPoint[0][1][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s); } for (j = 0; j < 2; j++) { /* 6-15 chequers, both colours, other up point */ CopyArea(auchPoint[1][1][j] + coordStride(1, 1, POINT_WIDTH * s * 3), POINT_WIDTH * s * 3, auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3, CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s); sprintf(pchFile, "b-ru-%c%d.png", j ? 'o' : 'x', i); WriteImageStride(auchPoint[1][1][j], POINT_WIDTH * s * 3, POINT_WIDTH * s, POINT_HEIGHT * s); } /* 6-15 chequers in bear-off trays */ CopyArea(auchOff[0] + coordStride(CHEQUER_LABEL_WIDTH, CHEQUER_HEIGHT * 4 + 1, BEAROFF_WIDTH * s * 3), BEAROFF_WIDTH * s * 3, auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3, CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s); sprintf(pchFile, "b-roff-x%d.png", i); WriteImageStride(auchOff[0], BEAROFF_WIDTH * s * 3, BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s); CopyArea(auchOff[1] + coordStride(CHEQUER_LABEL_WIDTH, 1, BEAROFF_WIDTH * s * 3), BEAROFF_WIDTH * s * 3, auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3, CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s); sprintf(pchFile, "b-roff-o%d.png", i); WriteImageStride(auchOff[1], BEAROFF_WIDTH * s * 3, BEAROFF_WIDTH * s, BEAROFF_HEIGHT * s); } /* 0-15 chequers on bar */ WriteStride("b-bar-o0.png", auchBar[0], BAR_WIDTH * s * 3, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s); WriteStride("b-bar-x0.png", auchBar[1], BAR_WIDTH * s * 3, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s); for (i = 1; i <= 3; i++) { RefractBlend(auchBar[0] + coordStride(BAR_WIDTH / 2 - CHEQUER_WIDTH / 2, (CHEQUER_HEIGHT + 1) * (3 - i) + 1, BAR_WIDTH * s * 3), BAR_WIDTH * s * 3, auchBoard + coord(BOARD_WIDTH / 2 - CHEQUER_WIDTH / 2, (BORDER_HEIGHT + CUBE_HEIGHT) + (CHEQUER_HEIGHT + 1) * (3 - i)), boardStride, auchChequer[0], CHEQUER_WIDTH * s * 4, asRefract[0], CHEQUER_WIDTH * s, CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s); sprintf(pchFile, "b-bar-o%d.png", i); WriteImageStride(auchBar[0], BAR_WIDTH * s * 3, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s); RefractBlend(auchBar[1] + coordStride(BAR_WIDTH / 2 - CHEQUER_WIDTH / 2, (CHEQUER_HEIGHT + 1) * (i - 1) + 1, BAR_WIDTH * s * 3), BAR_WIDTH * s * 3, auchBoard + coord(BOARD_WIDTH / 2 - CHEQUER_WIDTH / 2, (BOARD_HEIGHT / 2 + BOARD_CENTER_HEIGHT / 2) + (CHEQUER_HEIGHT + 1) * (i - 1)), boardStride, auchChequer[1], CHEQUER_WIDTH * s * 4, asRefract[1], CHEQUER_WIDTH * s, CHEQUER_WIDTH * s, CHEQUER_HEIGHT * s); sprintf(pchFile, "b-bar-x%d.png", i); WriteImageStride(auchBar[1], BAR_WIDTH * s * 3, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s); } for (i = 4; i <= 15; i++) { CopyArea(auchBar[0] + coordStride(CHEQUER_LABEL_WIDTH, 2, BAR_WIDTH * s * 3), BAR_WIDTH * s * 3, auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3, CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s); sprintf(pchFile, "b-bar-o%d.png", i); WriteImageStride(auchBar[0], BAR_WIDTH * s * 3, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s); CopyArea(auchBar[1] + coordStride(CHEQUER_LABEL_WIDTH, POINT_HEIGHT - CUBE_HEIGHT - CHEQUER_HEIGHT, BAR_WIDTH * s * 3), BAR_WIDTH * s * 3, auchChequerLabels + coordStride(0, (i - 4) * CHEQUER_LABEL_HEIGHT, CHEQUER_LABEL_WIDTH * s * 3), CHEQUER_LABEL_WIDTH * s * 3, CHEQUER_LABEL_WIDTH * s, CHEQUER_LABEL_HEIGHT * s); sprintf(pchFile, "b-bar-x%d.png", i); WriteImageStride(auchBar[1], BAR_WIDTH * s * 3, BAR_WIDTH * s, (POINT_HEIGHT - CUBE_HEIGHT) * s); } /* cube - top and bottom of bar */ for (i = 0; i < 2; i++) { int offset; int cube_y = i ? ((BOARD_HEIGHT - BORDER_HEIGHT) * s - CUBE_HEIGHT * ss) : (BORDER_HEIGHT * s); AlphaBlendBase(auchBoard + (BOARD_WIDTH / 2) * s * 3 - (CUBE_WIDTH / 2) * ss * 3 + cube_y * boardStride, boardStride, auchBoard + (BOARD_WIDTH / 2) * s * 3 - (CUBE_WIDTH / 2) * ss * 3 + cube_y * boardStride, boardStride, auchCube, CUBE_WIDTH * ss * 4, CUBE_WIDTH * ss, CUBE_HEIGHT * ss); offset = i ? coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BOARD_HEIGHT - BORDER_HEIGHT - CUBE_HEIGHT) : coord(BOARD_WIDTH / 2 - BAR_WIDTH / 2, BORDER_HEIGHT); for (j = 0; j < 12; j++) { CopyAreaRotateClip(auchBoard, boardStride, (BOARD_WIDTH / 2) * s - (CUBE_WIDTH / 2) * ss + ss, cube_y + ss, BOARD_WIDTH * s, BOARD_HEIGHT * s, auchCubeFaces, CUBE_LABEL_WIDTH * ss * 3, 0, CUBE_LABEL_HEIGHT * ss * j, ss * CUBE_LABEL_WIDTH, ss * CUBE_LABEL_HEIGHT, 2 - 2 * i); sprintf(pchFile, "b-%s-%d.png", i ? "cb" : "ct", 2 << j); WriteImage(auchBoard + offset, BAR_WIDTH * s, CUBE_HEIGHT * s); if (j == 5) { /* 64 cube is also the cube for 1 */ sprintf(pchFile, "b-%sc-1.png", i ? "cb" : "ct"); WriteImage(auchBoard + offset, BAR_WIDTH * s, CUBE_HEIGHT * s); } } } /* cube - doubles */ for (i = 0; i < 2; i++) { int offset; CopyArea(auchMidBoard, BOARD_CENTER_WIDTH * s * 3, auchBoard + coord(i ? BOARD_WIDTH / 2 + BAR_WIDTH / 2 : BEAROFF_WIDTH, BOARD_HEIGHT / 2 - BOARD_CENTER_HEIGHT / 2), boardStride, BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s); offset = ((BOARD_CENTER_HEIGHT / 2) * s - (CUBE_HEIGHT / 2) * ss) * BOARD_CENTER_WIDTH * s * 3 + 3 * POINT_WIDTH * s * 3 - (CUBE_WIDTH / 2) * ss * 3; AlphaBlendBase(auchMidBoard + offset, BOARD_CENTER_WIDTH * s * 3, auchMidBoard + offset, BOARD_CENTER_WIDTH * s * 3, auchCube, CUBE_WIDTH * ss * 4, CUBE_WIDTH * ss, CUBE_HEIGHT * ss); for (j = 0; j < 12; j++) { CopyAreaRotateClip( auchMidBoard, BOARD_CENTER_WIDTH * s * 3, POINT_WIDTH * s * 3 - ss * CUBE_LABEL_WIDTH / 2, (BOARD_CENTER_HEIGHT / 2) * s - (CUBE_LABEL_HEIGHT / 2) * ss, BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s, auchCubeFaces, CUBE_LABEL_WIDTH * ss * 3, 0, CUBE_LABEL_HEIGHT * ss * j, ss * CUBE_LABEL_WIDTH, ss * CUBE_LABEL_HEIGHT, i << 1); sprintf(pchFile, "b-mid%c-c%d.png", i ? 'r' : 'l', 2 << j); WriteImageStride(auchMidBoard, BOARD_CENTER_WIDTH * s * 3, BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s); } } /* cube - centered */ AlphaBlendBase( auchBoard + ((BOARD_HEIGHT / 2) * s - (CUBE_HEIGHT / 2) * ss) * boardStride + (BOARD_WIDTH / 2) * s * 3 - (CUBE_WIDTH / 2) * ss * 3, boardStride, auchBoard + ((BOARD_HEIGHT / 2) * s - (CUBE_HEIGHT / 2) * ss) * boardStride + (BOARD_WIDTH / 2) * s * 3 - (CUBE_WIDTH / 2) * ss * 3, boardStride, auchCube, CUBE_WIDTH * ss *4 , CUBE_WIDTH * ss, CUBE_HEIGHT * ss ); for (j = 0; j < 12; j++) { CopyAreaRotateClip(auchBoard, boardStride, (BOARD_WIDTH / 2) * s - (CUBE_WIDTH / 2) * ss + ss, (BOARD_HEIGHT / 2) * s - (CUBE_HEIGHT / 2) * ss + ss, BOARD_WIDTH * s, BOARD_HEIGHT * s, auchCubeFaces, CUBE_LABEL_WIDTH * ss * 3, 0, CUBE_LABEL_HEIGHT * ss * j, CUBE_LABEL_WIDTH * ss, CUBE_LABEL_HEIGHT * ss, 1); sprintf(pchFile, "b-midc-%d.png", 2 << j); WriteImage(auchBoard + coord((BOARD_WIDTH / 2) - (BAR_WIDTH / 2), ((BOARD_HEIGHT / 2) - (BOARD_CENTER_HEIGHT / 2))), BAR_WIDTH * s, BOARD_CENTER_HEIGHT * s); if (j == 5) { /* 64 cube is also the cube for 1 */ Write("b-midc-1.png", auchBoard + coord((BOARD_WIDTH / 2) - (BAR_WIDTH / 2), ((BOARD_HEIGHT / 2) - (BOARD_CENTER_HEIGHT / 2))), BAR_WIDTH * s, BOARD_CENTER_HEIGHT * s); } } /* dice rolls */ for (i = 0; i < 2; i++) { int dice_x = (BEAROFF_WIDTH + 3 * POINT_WIDTH + (6 * POINT_WIDTH + BAR_WIDTH) * i) * s * 3 - (DIE_WIDTH / 2) * ss * 3; int dice_y = ((BOARD_HEIGHT / 2) * s - (DIE_HEIGHT / 2) * ss) * boardStride; AlphaBlendBase(auchBoard + dice_x - DIE_WIDTH * ss * 3 + dice_y, boardStride, auchBoard + dice_x - DIE_WIDTH * ss * 3 + dice_y, boardStride, auchDice[i], DIE_WIDTH * ss * 4, DIE_WIDTH * ss, DIE_HEIGHT * ss); AlphaBlendBase(auchBoard + dice_x + DIE_WIDTH * ss * 3 + dice_y, boardStride, auchBoard + dice_x + DIE_WIDTH * ss * 3 + dice_y, boardStride, auchDice[i], DIE_WIDTH * ss * 4, DIE_WIDTH * ss, DIE_HEIGHT * ss); for( j = 0; j < 6; j++ ) { for( k = 0; k < 6; k++ ) { CopyArea(auchMidBoard, BOARD_CENTER_WIDTH * s * 3, auchBoard + coord(i ? BOARD_WIDTH / 2 + BAR_WIDTH / 2 : BEAROFF_WIDTH, BORDER_HEIGHT + POINT_HEIGHT), boardStride, BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s); DrawPips(auchMidBoard + 3 * POINT_WIDTH * s * 3 - (DIE_WIDTH / 2) * ss * 3 - DIE_WIDTH * ss * 3 + ((BOARD_CENTER_HEIGHT / 2) * s - (DIE_HEIGHT / 2) * ss ) * BOARD_CENTER_WIDTH * s * 3, BOARD_CENTER_WIDTH * s * 3, auchPips[i], j + 1); DrawPips(auchMidBoard + 3 * POINT_WIDTH * s * 3 - (DIE_WIDTH / 2) * ss * 3 + DIE_WIDTH * ss * 3 + ((BOARD_CENTER_HEIGHT / 2) * s - (DIE_HEIGHT / 2) * ss ) * BOARD_CENTER_WIDTH * s * 3, BOARD_CENTER_WIDTH * s * 3, auchPips[i], k + 1); sprintf(pchFile, "b-mid%c-%c%d%d.png", i ? 'r' : 'l', i ? 'o' : 'x', j + 1, k + 1); WriteImageStride(auchMidBoard, BOARD_CENTER_WIDTH * s * 3, BOARD_CENTER_WIDTH * s, BOARD_CENTER_HEIGHT * s); } } } if (imagesWritten != NUM_IMAGES) g_print("Wrong number of images generated - %d written, expected %d\n", imagesWritten, NUM_IMAGES); } static void RenderObjects() { int clockwise; renderdata rd; CopyAppearance(&rd); rd.fLabels = TRUE; rd.nSize = s; RenderBoard( &rd, auchBoard, boardStride ); RenderChequers( &rd, auchChequer[ 0 ], auchChequer[ 1 ], asRefract[ 0 ], asRefract[ 1 ], CHEQUER_WIDTH * s * 4 ); RenderChequerLabels( &rd, auchChequerLabels, CHEQUER_LABEL_WIDTH * s * 3 ); #if HAVE_LIBART RenderArrows( &rd, auchArrow[0], auchArrow[1], s * ARROW_WIDTH * 4 ); #endif /* HAVE_LIBART */ /* Render numbers in both directions */ clockwise = rd.fClockwise; rd.fClockwise = TRUE; RenderBoardLabels(&rd, auchLo, auchHi, BOARD_WIDTH * s * 4); rd.fClockwise = FALSE; RenderBoardLabels(&rd, auchLoRev, auchHiRev, BOARD_WIDTH * s * 4); rd.fClockwise = clockwise; /* cubes and dices are rendered a bit smaller */ rd.nSize = ss; RenderCube( &rd, auchCube, CUBE_WIDTH * ss * 4 ); RenderCubeFaces( &rd, auchCubeFaces, CUBE_LABEL_WIDTH * ss * 3, auchCube, CUBE_WIDTH * ss * 4 ); RenderDice( &rd, auchDice[ 0 ], auchDice[ 1 ], DIE_WIDTH * ss * 4 ); RenderPips( &rd, auchPips[ 0 ], auchPips[ 1 ], ss * 3 ); } static char* GetFilenameBase(char* sz) { sz = NextToken( &sz ); if( !sz || !*sz ) { outputf( _("You must specify a file to export to (see `%s')\n" ), "help export htmlimages" ); return 0; } if( mkdir( sz #ifndef WIN32 , 0777 #endif ) < 0 && errno != EEXIST ) { outputerr ( sz ); return 0; } szFile = malloc( strlen( sz ) + 32 ); strcpy( szFile, sz ); if( szFile[ strlen( szFile ) - 1 ] != '/' ) strcat( szFile, "/" ); pchFile = strchr(szFile, 0); return szFile; } static void AllocObjects() { int i, j, k; s = exsExport.nHtmlSize; auchMidlb = malloc((BOARD_WIDTH * s * 3 * BOARD_HEIGHT * s) * sizeof(char)); #if HAVE_LIBART for (i = 0; i < 2; i++) auchArrow[i] = art_new( art_u8, s * ARROW_WIDTH * 4 * s * ARROW_HEIGHT ); #endif auchBoard = malloc((BOARD_WIDTH * s * 3 * BOARD_HEIGHT * s) * sizeof(char)); for (i = 0; i < 2; i++) auchChequer[i] = malloc((CHEQUER_WIDTH * s * 4 * CHEQUER_HEIGHT * s) * sizeof(char)); auchChequerLabels = malloc((12 * CHEQUER_LABEL_WIDTH * s * 3 * CHEQUER_LABEL_HEIGHT * s) * sizeof(char)); auchLo = malloc((BOARD_WIDTH * s * 4 * BORDER_HEIGHT * s) * sizeof(char)); auchHi = malloc((BOARD_WIDTH * s * 4 * BORDER_HEIGHT * s) * sizeof(char)); auchLoRev = malloc((BOARD_WIDTH * s * 4 * BORDER_HEIGHT * s) * sizeof(char)); auchHiRev = malloc((BOARD_WIDTH * s * 4 * BORDER_HEIGHT * s) * sizeof(char)); auchCube = malloc((CUBE_WIDTH * ss * 4 * CUBE_HEIGHT * ss) * sizeof(char)); auchCubeFaces = malloc((12 * CUBE_LABEL_WIDTH * ss * 3 * CUBE_LABEL_HEIGHT * ss) * sizeof(char)); for (i = 0; i < 2; i++) { auchDice[i] = malloc((DIE_WIDTH * ss * 4 * DIE_HEIGHT * ss) * sizeof(char)); auchPips[i] = malloc((ss * ss * 3) * sizeof(char)); } auchLabel = malloc((BOARD_WIDTH * s * 3 * BOARD_HEIGHT * s) * sizeof(char)); for (i = 0; i < 2; i++) auchOff[i] = malloc((BEAROFF_WIDTH * s * 3 * DISPLAY_BEAROFF_HEIGHT * s) * sizeof(char)); auchMidBoard = malloc((BOARD_CENTER_WIDTH * s * 3 * BOARD_CENTER_HEIGHT * s) * sizeof(char)); for (i = 0; i < 2; i++) auchBar[i] = malloc((BAR_WIDTH * s * 3 * (POINT_HEIGHT - CUBE_HEIGHT) * s) * sizeof(char)); for (i = 0; i < 2; i++) for (j = 0; j < 2; j++) for (k = 0; k < 2; k++) auchPoint[i][j][k] = malloc((POINT_WIDTH * s * 3 * DISPLAY_POINT_HEIGHT * s) * sizeof(char)); for (i = 0; i < 2; i++) asRefract[i] = malloc((CHEQUER_WIDTH * s * CHEQUER_HEIGHT * s) * sizeof(short)); } static void TidyObjects() { int i, j, k; free(auchMidlb); #if HAVE_LIBART for (i = 0; i < 2; i++) art_free( auchArrow[ i ] ); #endif /* HAVE_LIBART */ free(szFile); free(auchBoard); for (i = 0; i < 2; i++) free(auchChequer[i]); free(auchChequerLabels); free(auchLo); free(auchHi); free(auchLoRev); free(auchHiRev); free(auchCube); free(auchCubeFaces); for (i = 0; i < 2; i++) { free(auchDice[i]); free(auchPips[i]); } free(auchLabel); for (i = 0; i < 2; i++) free(auchOff[i]); free(auchMidBoard); for (i = 0; i < 2; i++) free(auchBar[i]); for (i = 0; i < 2; i++) for (j = 0; j < 2; j++) for (k = 0; k < 2; k++) free(auchPoint[i][j][k]); for (i = 0; i < 2; i++) free(asRefract[i]); } extern void CommandExportHTMLImages( char *sz ) { szFile = GetFilenameBase(sz); if (!szFile) return; ProgressStartValue(_("Generating image:"), NUM_IMAGES); AllocObjects(); RenderObjects(); WriteImages(); ProgressEnd(); TidyObjects(); } #else /* not HAVE_LIBPNG */ extern void CommandExportHTMLImages( char *sz ) { outputl( _("This installation of GNU Backgammon was compiled without\n" "support for writing HTML images.") ); } #endif /* not HAVE_LIBPNG */