2 * Graphics Routines -- graphics.c
3 * $Id: graphics.c,v 1.1.2.20 2004/01/14 05:18:19 sparrow_hawk Exp $
5 * Copyright (C) 2003 Kevin Riggle
6 * http://cmancala.sourcefoge.net
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details, a copy of which may be found in
17 * the file COPYING provided in the main directory of this release.
24 #include "SDL_endian.h" /* Used for the endian-dependent 24 bpp mode */
26 #include "SDL_image.h"
33 static SDL_Surface *ShiftColors(SDL_Surface *old, Uint8 red, Uint8 blue, Uint8 green, Uint8 alpha);
35 SDL_Surface *LoadRes(char *filename) {
37 return IMG_LoadPNG_RW(SDL_RWFromFile(filename, "r"));
42 SDL_Rect SurfaceToRect(SDL_Surface *src) {
55 /* create a new, blank surface with another's properties */
56 static SDL_Surface *NewSurfaceFrom(SDL_Surface *old, Uint32 flags) {
58 return SDL_CreateRGBSurface(
59 flags, old->w, old->h, old->format->BitsPerPixel,
60 old->format->Rmask, old->format->Gmask,
61 old->format->Bmask, old->format->Amask
66 static SDL_Surface *FillHole(int stones, TTF_Font *font,
67 SDL_Surface **stone_gfx) {
71 char stone_string[STRING_MAX];
74 /* do we have a graphic for this number of stones? */
75 if (stones <= STONE_MAX) {
77 return *(stone_gfx + stones);
83 /* convert the integer to text */
84 if (sprintf(stone_string, "%d", stones)<=0)
85 fprintf(stderr, "String conversion problem.\n");
86 /* get the size of the rendered text */
87 if (TTF_SizeText(font, stone_string, &w, &h)<0)
88 fprintf(stderr, "SDL_ttf: %s\n", TTF_GetError());
89 /* if the text is too large, render a '?' */
90 if ((w > (*stone_gfx)->w) || (h > (*stone_gfx)->h))
91 sprintf(stone_string, "?");
92 if (!(text = TTF_RenderText_Blended(font, stone_string,
94 fprintf(stderr, "SDL_ttf: %s\n", TTF_GetError());
105 SDL_Surface *DrawBoard(int *aiBoard, int *humanBoard,
106 TTF_Font *board_font, TTF_Font *home_font,
107 SDL_Surface *tile, SDL_Surface **stone_gfx,
108 int active, int highlight) {
110 SDL_Surface *board, *stones;
111 SDL_Rect tile_rect, blit_rect;
112 SDL_Color home_color;
113 char home_string[STRING_MAX];
116 /* initialize the board surface */
117 board = SDL_CreateRGBSurface(SDL_SWSURFACE, tile->w*(BOARD_MAX+2),
118 tile->h*2, tile->format->BitsPerPixel, 0, 0, 0, 0);
120 fprintf(stderr, "DrawBoard: %s\n", SDL_GetError());
124 tile_rect = SurfaceToRect(tile);
125 /*printf("tile is %dx%d\n", tile_rect.w, tile_rect.h);*/
127 /* set the color of text in the home */
132 for (i=0; i<=BOARD_MAX+1; i++)
134 /* update current tile location */
135 tile_rect.x = i * tile_rect.w;
137 /*printf("Currently a %dx%d rectangle at %d,%d.\n", tile_rect.w,
138 tile_rect.h, tile_rect.x, tile_rect.y);*/
139 blit_rect = tile_rect;
140 /* is this is the first or last tile? */
141 if ((i==0) || (i==BOARD_MAX+1)) {
143 if (SDL_BlitSurface(tile, NULL, board, &blit_rect)<0)
144 fprintf(stderr,"DrawBoard: %s\n",
146 blit_rect = tile_rect;
147 blit_rect.y = blit_rect.h;
148 SDL_BlitSurface(tile, NULL, board, &blit_rect);
149 /* render the number of stones in each home */
151 if (sprintf(home_string,"%d",humanBoard[0])<=0)
152 printf("Human string problems.\n");
155 if (sprintf(home_string, "%d", aiBoard[0])<=0)
156 printf("AI string problems.\n");
158 if (!(stones = TTF_RenderText_Blended(home_font,
159 home_string, home_color)))
160 fprintf(stderr, "DrawBoard: %s\n",
162 blit_rect.w = stones->w;
163 blit_rect.h = stones->h;
164 blit_rect.x += ((tile_rect.w - blit_rect.w)/2);
165 blit_rect.y = ((tile_rect.h*2 - blit_rect.h)/2);
166 SDL_BlitSurface(stones, NULL, board, &blit_rect);
168 /* otherwise, draw a hole and fill it */
170 SDL_BlitSurface(stone_gfx[0], NULL, board, &blit_rect);
171 if (humanBoard[i] > 0) {
172 if (!(stones = FillHole(humanBoard[i],
173 board_font, stone_gfx)))
174 fprintf(stderr,"FillHole() problems\n");
176 stones = ShiftColors(stones,128,128,128,255);
178 stones = ShiftColors(stones,0,0,0,160);
179 blit_rect.w = stones->w;
180 blit_rect.h = stones->h;
181 blit_rect.x += ((tile_rect.w - blit_rect.w)/2);
182 blit_rect.y += ((tile_rect.h - blit_rect.h)/2);
183 SDL_BlitSurface(stones,NULL,board,&blit_rect);
186 blit_rect = tile_rect;
187 blit_rect.y = blit_rect.h;
188 SDL_BlitSurface(stone_gfx[0], NULL, board, &blit_rect);
189 if (aiBoard[BOARD_MAX-i+1] > 0) {
190 if (!(stones = FillHole(aiBoard[BOARD_MAX-i+1],
191 board_font, stone_gfx)))
192 fprintf(stderr,"FillHole() problems\n");
194 stones = ShiftColors(stones,0,0,0,160);
195 blit_rect.w = stones->w;
196 blit_rect.h = stones->h;
197 blit_rect.x += ((tile_rect.w - blit_rect.w)/2);
198 blit_rect.y += ((tile_rect.h - blit_rect.h)/2);
199 SDL_BlitSurface(stones,NULL,board,&blit_rect);
204 SDL_FreeSurface(stones);
210 /* flagrantly stol^H^H^Hborrowed from SDL Introduction */
211 /* passing 0 for red, green, or blue leaves them alone */
212 /* passing 0 for alpha makes the image transparent */
214 SDL_Surface *ShiftColors(SDL_Surface *old, Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha)
220 new = NewSurfaceFrom(old, (SDL_SWSURFACE|SDL_SRCALPHA));
222 if ( SDL_MUSTLOCK(old) ) {
223 if (SDL_LockSurface(old) < 0 ) {
228 if ( SDL_MUSTLOCK(new) ) {
229 if ( SDL_LockSurface(new) < 0 ) {
234 for (x=0; x<old->w; x++)
235 for (y=0; y<old->h; y++) {
239 switch (old->format->BytesPerPixel) {
240 case 1: { /* Assuming 8-bpp */
243 bufp = (Uint8 *)old->pixels + y*old->pitch + x;
244 bufq = (Uint8 *)new->pixels + y*new->pitch + x;
245 SDL_GetRGBA((Uint32)*bufp, old->format, &r, &g, &b, &a);
246 a *= alpha/SDL_ALPHA_OPAQUE;
247 *bufq = (Uint8)SDL_MapRGBA(new->format, r, g, b, a);
251 case 2: { /* Probably 15-bpp or 16-bpp */
254 bufp = (Uint16 *)old->pixels + y*old->pitch/2 + x;
255 bufq = (Uint16 *)new->pixels + y*new->pitch + x;
256 SDL_GetRGBA((Uint32)*bufp, new->format, &r, &g, &b, &a);
257 a *= alpha/SDL_ALPHA_OPAQUE;
258 *bufq = (Uint8)SDL_MapRGBA(new->format, r, g, b, a);
262 case 3: { /* Slow 24-bpp mode, usually not used */
266 bufp = (Uint8 *)old->pixels + y*old->pitch + x * 3;
267 bufq = (Uint8 *)new->pixels + y*new->pitch + x * 3;
268 SDL_GetRGBA((Uint32)*bufp, old->format, &r, &g, &b, &a);
269 a *= alpha/SDL_ALPHA_OPAQUE;
270 color = SDL_MapRGBA(new->format, r, g, b, a);
271 if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {
273 bufq[1] = color >> 8;
274 bufq[2] = color >> 16;
277 bufq[1] = color >> 8;
278 bufq[0] = color >> 16;
283 case 4: { /* Probably 32-bpp */
286 bufp = (Uint32 *)old->pixels + y*old->pitch/4 + x;
287 bufq = (Uint32 *)new->pixels + y*new->pitch/4 + x;
288 SDL_GetRGBA(*bufp, old->format, &r, &g, &b, &a);
289 a = (int)((long)a * (long)alpha/SDL_ALPHA_OPAQUE);
290 r += (int)((long)(SDL_ALPHA_OPAQUE - r) * (long)red/SDL_ALPHA_OPAQUE);
291 g += (int)((long)(SDL_ALPHA_OPAQUE - g) * (long)green/SDL_ALPHA_OPAQUE);
292 b += (int)((long)(SDL_ALPHA_OPAQUE - b) * (long)blue/SDL_ALPHA_OPAQUE);
293 *bufq = SDL_MapRGBA(new->format, r, g, b, a);
299 if ( SDL_MUSTLOCK(new) ) {
300 SDL_UnlockSurface(new);
303 if ( SDL_MUSTLOCK(old) ) {
304 SDL_UnlockSurface(old);