[Tux4kids-commits] r1295 - in branches/commonification: tux4kids-common/trunk/src tuxmath/trunk/src
Bolesław Kulbabiński
bolekk-guest at alioth.debian.org
Thu Jul 30 16:23:36 UTC 2009
Author: bolekk-guest
Date: 2009-07-30 16:23:36 +0000 (Thu, 30 Jul 2009)
New Revision: 1295
Added:
branches/commonification/tux4kids-common/trunk/src/t4k-globals.h
branches/commonification/tux4kids-common/trunk/src/t4k-main.c
branches/commonification/tux4kids-common/trunk/src/t4k-sdl.c
Removed:
branches/commonification/tux4kids-common/trunk/src/SDL_extras.c
Modified:
branches/commonification/tux4kids-common/trunk/src/tux4kids-common.h
branches/commonification/tuxmath/trunk/src/setup.c
Log:
made tux4kids-common take debug flags
Deleted: branches/commonification/tux4kids-common/trunk/src/SDL_extras.c
===================================================================
--- branches/commonification/tux4kids-common/trunk/src/SDL_extras.c 2009-07-30 16:22:41 UTC (rev 1294)
+++ branches/commonification/tux4kids-common/trunk/src/SDL_extras.c 2009-07-30 16:23:36 UTC (rev 1295)
@@ -1,1132 +0,0 @@
-/*
-* C Implementation: SDL_extras
-*
-* Description: a few handy functions for using SDL graphics.
-*
-*
-* Author: David Bruce,,, <dbruce at tampabay.rr.com>, (C) 2007
-*
-* Copyright: GPL v3 or later
-*
-*/
-#include <math.h>
-
-#include "tux4kids-common.h"
-
-static SDL_Surface* screen = NULL;
-
-/*
-Return a pointer to the screen we're using, as an alternative to making screen
-global. Not sure what is involved performance-wise in SDL_GetVideoSurface,
-or if this check is even necessary -Cheez
-*/
-SDL_Surface* GetScreen()
-{
-#ifdef TUXMATH_DEBUG
- {
- if (screen != SDL_GetVideoSurface() )
- {
- fprintf(stderr, "Video Surface changed from outside of SDL_Extras!\n");
- screen = SDL_GetVideoSurface();
- }
- }
-#endif
- return screen;
-}
-
-
-/* DrawButton() creates a translucent button with rounded ends
- and draws it on the screen.
- All colors and alpha values are supported.*/
-void DrawButton(SDL_Rect* target_rect,
- int radius,
- Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- DrawButtonOn(screen, target_rect, radius, r, g, b, a);
-}
-
-void DrawButtonOn(SDL_Surface* target,
- SDL_Rect* target_rect,
- int radius,
- Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-
-{
- SDL_Surface* tmp_surf = CreateButton(target_rect->w, target_rect->h,
- radius, r, g, b, a);
- SDL_BlitSurface(tmp_surf, NULL, target, target_rect);
- SDL_FreeSurface(tmp_surf);
-}
-
-/* CreateButton() creates a translucent button with rounded ends
- All colors and alpha values are supported.*/
-SDL_Surface* CreateButton(int w, int h, int radius,
- Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
- /* NOTE - we use a 32-bit temp surface even if we have a 16-bit */
- /* screen - it gets converted during blitting. */
- SDL_Surface* tmp_surf = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,
- w,
- h,
- 32,
- rmask, gmask, bmask, amask);
-
- Uint32 color = SDL_MapRGBA(tmp_surf->format, r, g, b, a);
- SDL_FillRect(tmp_surf, NULL, color);
- RoundCorners(tmp_surf, radius);
- return tmp_surf;
-}
-
-void RoundCorners(SDL_Surface* s, Uint16 radius)
-{
- int y = 0;
- int x_dist, y_dist;
- Uint32* p = NULL;
- Uint32 alpha_mask;
- int bytes_per_pix;
-
- if (!s)
- return;
- if (SDL_LockSurface(s) == -1)
- return;
-
- bytes_per_pix = s->format->BytesPerPixel;
- if (bytes_per_pix != 4)
- return;
-
- /* radius cannot be more than half of width or height: */
- if (radius > (s->w)/2)
- radius = (s->w)/2;
- if (radius > (s->h)/2)
- radius = (s->h)/2;
-
-
- alpha_mask = s->format->Amask;
-
- /* Now round off corners: */
- /* upper left: */
- for (y = 0; y < radius; y++)
- {
- p = (Uint32*)(s->pixels + (y * s->pitch));
- x_dist = radius;
- y_dist = radius - y;
-
- while (((x_dist * x_dist) + (y_dist * y_dist)) > (radius * radius))
- {
- /* (make pixel (x,y) transparent) */
- *p = *p & ~alpha_mask;
- p++;
- x_dist--;
- }
- }
-
- /* upper right: */
- for (y = 0; y < radius; y++)
- {
- /* start at end of top row: */
- p = (Uint32*)(s->pixels + ((y + 1) * s->pitch) - bytes_per_pix);
-
- x_dist = radius;
- y_dist = radius - y;
-
- while (((x_dist * x_dist) + (y_dist * y_dist)) > (radius * radius))
- {
- /* (make pixel (x,y) transparent) */
- *p = *p & ~alpha_mask;
- p--;
- x_dist--;
- }
- }
-
- /* bottom left: */
- for (y = (s->h - 1); y > (s->h - radius); y--)
- {
- /* start at beginning of bottom row */
- p = (Uint32*)(s->pixels + (y * s->pitch));
- x_dist = radius;
- y_dist = y - (s->h - radius);
-
- while (((x_dist * x_dist) + (y_dist * y_dist)) > (radius * radius))
- {
- /* (make pixel (x,y) transparent) */
- *p = *p & ~alpha_mask;
- p++;
- x_dist--;
- }
- }
-
- /* bottom right: */
- for (y = (s->h - 1); y > (s->h - radius); y--)
- {
- /* start at end of bottom row */
- p = (Uint32*)(s->pixels + ((y + 1) * s->pitch) - bytes_per_pix);
- x_dist = radius;
- y_dist = y - (s->h - radius);
-
- while (((x_dist * x_dist) + (y_dist * y_dist)) > (radius * radius))
- {
- /* (make pixel (x,y) transparent) */
- *p = *p & ~alpha_mask;
- p--;
- x_dist--;
- }
- }
- SDL_UnlockSurface(s);
-}
-
-/**
- * TODO ***Migrate other functions! Oh, and test on Win/Mac
- */
-
-#if 0
-/**********************
- Flip:
- input: a SDL_Surface, x, y
- output: a copy of the SDL_Surface flipped via rules:
-
- if x is a nonzero value, then flip horizontally
- if y is a nonzero value, then flip vertically
-
- note: you can have it flip both
-**********************/
-SDL_Surface* Flip( SDL_Surface *in, int x, int y ) {
- SDL_Surface *out, *tmp;
- SDL_Rect from_rect, to_rect;
- Uint32 flags;
- Uint32 colorkey=0;
-
- /* --- grab the settings for the incoming pixmap --- */
-
- SDL_LockSurface(in);
- flags = in->flags;
-
- /* --- change in's flags so ignore colorkey & alpha --- */
-
- if (flags & SDL_SRCCOLORKEY) {
- in->flags &= ~SDL_SRCCOLORKEY;
- colorkey = in->format->colorkey;
- }
- if (flags & SDL_SRCALPHA) {
- in->flags &= ~SDL_SRCALPHA;
- }
-
- SDL_UnlockSurface(in);
-
- /* --- create our new surface --- */
-
- out = SDL_CreateRGBSurface(
- SDL_SWSURFACE,
- in->w, in->h, 32, rmask, gmask, bmask, amask);
-
- /* --- flip horizontally if requested --- */
-
- if (x) {
- from_rect.h = to_rect.h = in->h;
- from_rect.w = to_rect.w = 1;
- from_rect.y = to_rect.y = 0;
- from_rect.x = 0;
- to_rect.x = in->w - 1;
-
- do {
- SDL_BlitSurface(in, &from_rect, out, &to_rect);
- from_rect.x++;
- to_rect.x--;
- } while (to_rect.x >= 0);
- }
-
- /* --- flip vertically if requested --- */
-
- if (y) {
- from_rect.h = to_rect.h = 1;
- from_rect.w = to_rect.w = in->w;
- from_rect.x = to_rect.x = 0;
- from_rect.y = 0;
- to_rect.y = in->h - 1;
-
- do {
- SDL_BlitSurface(in, &from_rect, out, &to_rect);
- from_rect.y++;
- to_rect.y--;
- } while (to_rect.y >= 0);
- }
-
- /* --- restore colorkey & alpha on in and setup out the same --- */
-
- SDL_LockSurface(in);
-
- if (flags & SDL_SRCCOLORKEY) {
- in->flags |= SDL_SRCCOLORKEY;
- in->format->colorkey = colorkey;
- tmp = SDL_DisplayFormat(out);
- SDL_FreeSurface(out);
- out = tmp;
- out->flags |= SDL_SRCCOLORKEY;
- out->format->colorkey = colorkey;
- } else if (flags & SDL_SRCALPHA) {
- in->flags |= SDL_SRCALPHA;
- tmp = SDL_DisplayFormatAlpha(out);
- SDL_FreeSurface(out);
- out = tmp;
- } else {
- tmp = SDL_DisplayFormat(out);
- SDL_FreeSurface(out);
- out = tmp;
- }
-
- SDL_UnlockSurface(in);
-
- return out;
-}
-
-/* Blend two surfaces together. The third argument is between 0.0 and
- 1.0, and represents the weight assigned to the first surface. If
- the pointer to the second surface is NULL, this performs fading.
-
- Currently this works only with RGBA images, but this is largely to
- make the (fast) pointer arithmetic work out; it could be easily
- generalized to other image types. */
-SDL_Surface* Blend(SDL_Surface *S1, SDL_Surface *S2, float gamma)
-{
- SDL_PixelFormat *fmt1, *fmt2;
- Uint8 r1, r2, g1, g2, b1, b2, a1, a2;
- SDL_Surface *tmpS, *ret;
- Uint32 *cpix1, *epix1, *cpix2, *epix2;
- float gamflip;
-
- if (!S1)
- return NULL;
-
- fmt1 = fmt2 = NULL;
- tmpS = ret = NULL;
-
- gamflip = 1.0 - gamma;
- if (gamma < 0 || gamflip < 0)
- {
- perror("gamma must be between 0 and 1");
- exit(0);
- }
-
- fmt1 = S1->format;
-
- if (fmt1 && fmt1->BitsPerPixel != 32)
- {
- perror("This works only with RGBA images");
- return S1;
- }
- if (S2 != NULL)
- {
- fmt2 = S2->format;
- if (fmt2->BitsPerPixel != 32)
- {
- perror("This works only with RGBA images");
- return S1;
- }
- // Check that both images have the same width dimension
- if (S1->w != S2->w)
- {
- printf("S1->w %d, S2->w %d; S1->h %d, S2->h %d\n",
- S1->w, S2->w, S1->h, S2->h);
- printf("Both images must have the same width dimensions\n");
- return S1;
- }
- }
-
- tmpS = SDL_ConvertSurface(S1, fmt1, SDL_SWSURFACE);
- if (tmpS == NULL)
- {
- perror("SDL_ConvertSurface() failed");
- return S1;
- }
- if (-1 == SDL_LockSurface(tmpS))
- {
- perror("SDL_LockSurface() failed");
- return S1;
- }
-
- // We're going to go through the pixels in reverse order, to start
- // from the bottom of each image. That way, we can blend things that
- // are not of the same height and have them align at the bottom.
- // So the "ending pixel" (epix) will be before the first pixel, and
- // the current pixel (cpix) will be the last pixel.
- epix1 = (Uint32*) tmpS->pixels - 1;
- cpix1 = epix1 + tmpS->w * tmpS->h;
- if (S2 != NULL
- && (SDL_LockSurface(S2) != -1))
- {
- epix2 = (Uint32*) S2->pixels - 1;
- cpix2 = epix2 + S2->w * S2->h;
- }
- else
- {
- epix2 = epix1;
- cpix2 = cpix1;
- }
-
- for (; cpix1 > epix1; cpix1--, cpix2--)
- {
- SDL_GetRGBA(*cpix1, fmt1, &r1, &g1, &b1, &a1);
- a1 = gamma * a1;
- if (S2 != NULL && cpix2 > epix2)
- {
- SDL_GetRGBA(*cpix2, fmt2, &r2, &g2, &b2, &a2);
- r1 = gamma * r1 + gamflip * r2;
- g1 = gamma * g1 + gamflip * g2;
- b1 = gamma * b1 + gamflip * b2;
- a1 += gamflip * a2;
- }
- *cpix1 = SDL_MapRGBA(fmt1,r1,g1,b1,a1);
- }
-
- SDL_UnlockSurface(tmpS);
-
- if (S2 != NULL)
- SDL_UnlockSurface(S2);
-
- ret = SDL_DisplayFormatAlpha(tmpS);
- SDL_FreeSurface(tmpS);
-
- return ret;
-}
-
-
-/* free every surface in the array together with the array itself */
-void FreeSurfaceArray(SDL_Surface** surfs, int length)
-{
- int i;
-
- if(surfs == NULL)
- return;
-
- for(i = 0; i < length; i++)
- if(surfs[i] != NULL)
- SDL_FreeSurface(surfs[i]);
- free(surfs);
-}
-
-int inRect( SDL_Rect r, int x, int y) {
- if ((x < r.x) || (y < r.y) || (x > r.x + r.w) || (y > r.y + r.h))
- return 0;
- return 1;
-}
-
-void UpdateRect(SDL_Surface* surf, SDL_Rect* rect)
-{
- SDL_UpdateRect(surf, rect->x, rect->y, rect->w, rect->h);
-}
-
-void SetRect(SDL_Rect* rect, const float* pos)
-{
- rect->x = pos[0] * screen->w;
- rect->y = pos[1] * screen->h;
- rect->w = pos[2] * screen->w;
- rect->h = pos[3] * screen->h;
-}
-
-/* Darkens the screen by a factor of 2^bits */
-void DarkenScreen(Uint8 bits)
-{
-#if PIXEL_BITS == 32
- Uint32* p;
-#elif PIXEL_BITS == 16
- Uint16* p;
-#else
- return;
-#endif
- Uint32 rm = screen->format->Rmask;
- Uint32 gm = screen->format->Gmask;
- Uint32 bm = screen->format->Bmask;
-
-
- int x, y;
-
- /* (realistically, 1 and 2 are the only useful values) */
- if (bits > 8)
- return;
-
- p = screen->pixels;
-
- for (y = 0; y < screen->h; y++)
- {
- for (x = 0; x < screen->w; x++)
- {
- *p = (((*p&rm)>>bits)&rm)
- | (((*p&gm)>>bits)&gm)
- | (((*p&bm)>>bits)&bm);
- p++;
- }
- }
-}
-
-/* change window size (works only in windowed mode) */
-void ChangeWindowSize(int new_res_x, int new_res_y)
-{
- SDL_Surface* oldscreen = screen;
-
- if(!(screen->flags & SDL_FULLSCREEN))
- {
- screen = SDL_SetVideoMode(new_res_x,
- new_res_y,
- PIXEL_BITS,
- SDL_SWSURFACE|SDL_HWPALETTE);
-
- if(screen == NULL)
- {
- fprintf(stderr,
- "\nError: I could not change screen mode into %d x %d.\n",
- new_res_x, new_res_y);
- screen = oldscreen;
- }
- else
- {
- DEBUGMSG(debug_sdl, "ChangeWindowSize(): Changed window size to %d x %d\n", screen->w, screen->h);
- oldscreen = NULL;
- win_res_x = screen->w;
- win_res_y = screen->h;
- SDL_UpdateRect(screen, 0, 0, 0, 0);
- }
- }
- else
- DEBUGMSG(debug_sdl, "ChangeWindowSize() can be run only in windowed mode !");
-}
-
-/* switch between fullscreen and windowed mode */
-void SwitchScreenMode(void)
-{
- int window = (screen->flags & SDL_FULLSCREEN);
- SDL_Surface* oldscreen = screen;
-
- screen = SDL_SetVideoMode(window ? win_res_x : fs_res_x,
- window ? win_res_y : fs_res_y,
- PIXEL_BITS,
- screen->flags ^ SDL_FULLSCREEN);
-
- if (screen == NULL)
- {
- fprintf(stderr,
- "\nError: I could not switch to %s mode.\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n",
- window ? "windowed" : "fullscreen",
- SDL_GetError());
- screen = oldscreen;
- }
- else
- {
- //success, no need to free the old video surface
- DEBUGMSG(debug_sdl, "Switched screen mode to %s\n", window ? "windowed" : "fullscreen");
- oldscreen = NULL;
- SDL_UpdateRect(screen, 0, 0, 0, 0);
- }
-}
-
-/*
-Block application until SDL receives an appropriate event. Events can be
-a single or OR'd combination of event masks.
-e.g. e = WaitForEvent(SDL_KEYDOWNMASK | SDL_QUITMASK)
-*/
-SDL_EventType WaitForEvent(SDL_EventMask events)
-{
- SDL_Event evt;
- while (1)
- {
- while (SDL_PollEvent(&evt) )
- {
- if (SDL_EVENTMASK(evt.type) & events)
- return evt.type;
- else
- SDL_Delay(50);
- }
- }
-}
-/* Swiped shamelessly from TuxPaint
- Based on code from: http://www.codeproject.com/cs/media/imageprocessing4.asp
- copyright 2002 Christian Graus */
-
-SDL_Surface* zoom(SDL_Surface* src, int new_w, int new_h)
-{
- SDL_Surface* s;
-
- /* These function pointers will point to the appropriate */
- /* putpixel() and getpixel() variants to be used in the */
- /* current colorspace: */
- void (*putpixel) (SDL_Surface*, int, int, Uint32);
- Uint32(*getpixel) (SDL_Surface*, int, int);
-
- float xscale, yscale;
- int x, y;
- int floor_x, ceil_x,
- floor_y, ceil_y;
- float fraction_x, fraction_y,
- one_minus_x, one_minus_y;
- float n1, n2;
- Uint8 r1, g1, b1, a1;
- Uint8 r2, g2, b2, a2;
- Uint8 r3, g3, b3, a3;
- Uint8 r4, g4, b4, a4;
- Uint8 r, g, b, a;
-
- DEBUGMSG(debug_sdl, "Entering zoom():\n");
-
- /* Create surface for zoom: */
-
- s = SDL_CreateRGBSurface(src->flags, /* SDL_SWSURFACE, */
- new_w, new_h, src->format->BitsPerPixel,
- src->format->Rmask,
- src->format->Gmask,
- src->format->Bmask,
- src->format->Amask);
-
- if (s == NULL)
- {
- fprintf(stderr, "\nError: Can't build zoom surface\n"
- "The Simple DirectMedia Layer error that occurred was:\n"
- "%s\n\n", SDL_GetError());
- return NULL;
-// cleanup();
-// exit(1);
- }
-
- DEBUGMSG(debug_sdl, "zoom(): orig surface %dx%d, %d bytes per pixel\n",
- src->w, src->h, src->format->BytesPerPixel);
- DEBUGMSG(debug_sdl, "zoom(): new surface %dx%d, %d bytes per pixel\n",
- s->w, s->h, s->format->BytesPerPixel);
-
- /* Now assign function pointers to correct functions based */
- /* on data format of original and zoomed surfaces: */
- getpixel = getpixels[src->format->BytesPerPixel];
- putpixel = putpixels[s->format->BytesPerPixel];
-
- SDL_LockSurface(src);
- SDL_LockSurface(s);
-
- xscale = (float) src->w / (float) new_w;
- yscale = (float) src->h / (float) new_h;
-
- for (x = 0; x < new_w; x++)
- {
- for (y = 0; y < new_h; y++)
- {
- /* Here we calculate the new RGBA values for each pixel */
- /* using a "weighted average" of the four pixels in the */
- /* corresponding location in the orginal surface: */
-
- /* figure out which original pixels to use in the calc: */
- floor_x = floor((float) x * xscale);
- ceil_x = floor_x + 1;
- if (ceil_x >= src->w)
- ceil_x = floor_x;
-
- floor_y = floor((float) y * yscale);
- ceil_y = floor_y + 1;
- if (ceil_y >= src->h)
- ceil_y = floor_y;
-
- fraction_x = x * xscale - floor_x;
- fraction_y = y * yscale - floor_y;
-
- one_minus_x = 1.0 - fraction_x;
- one_minus_y = 1.0 - fraction_y;
-
- /* Grab their values: */
- SDL_GetRGBA(getpixel(src, floor_x, floor_y), src->format,
- &r1, &g1, &b1, &a1);
- SDL_GetRGBA(getpixel(src, ceil_x, floor_y), src->format,
- &r2, &g2, &b2, &a2);
- SDL_GetRGBA(getpixel(src, floor_x, ceil_y), src->format,
- &r3, &g3, &b3, &a3);
- SDL_GetRGBA(getpixel(src, ceil_x, ceil_y), src->format,
- &r4, &g4, &b4, &a4);
-
- /* Create the weighted averages: */
- n1 = (one_minus_x * r1 + fraction_x * r2);
- n2 = (one_minus_x * r3 + fraction_x * r4);
- r = (one_minus_y * n1 + fraction_y * n2);
-
- n1 = (one_minus_x * g1 + fraction_x * g2);
- n2 = (one_minus_x * g3 + fraction_x * g4);
- g = (one_minus_y * n1 + fraction_y * n2);
-
- n1 = (one_minus_x * b1 + fraction_x * b2);
- n2 = (one_minus_x * b3 + fraction_x * b4);
- b = (one_minus_y * n1 + fraction_y * n2);
-
- n1 = (one_minus_x * a1 + fraction_x * a2);
- n2 = (one_minus_x * a3 + fraction_x * a4);
- a = (one_minus_y * n1 + fraction_y * n2);
-
- /* and put them into our new surface: */
- putpixel(s, x, y, SDL_MapRGBA(s->format, r, g, b, a));
-
- }
- }
-
- SDL_UnlockSurface(s);
- SDL_UnlockSurface(src);
-
- DEBUGMSG(debug_sdl, "Leaving zoom():\n");
-
- return s;
-}
-
-/************************************************************************/
-/* */
-/* Begin text drawing functions */
-/* */
-/* These functions support text drawing using either SDL_Pango */
-/* or SDL_ttf. SDL_Pango is preferable but is not available on all */
-/* platforms. Code outside of this file does not have to worry about */
-/* which library is used to do the actual rendering. */
-/************************************************************************/
-
-#define MAX_FONT_SIZE 40
-
-//NOTE to test program with SDL_ttf, do "./configure --without-sdlpango"
-
-
-/*-- file-scope variables and local file prototypes for SDL_Pango-based code: */
-#ifdef HAVE_LIBSDL_PANGO
-#include "SDL_Pango.h"
-SDLPango_Context* context = NULL;
-static SDLPango_Matrix* SDL_Colour_to_SDLPango_Matrix(const SDL_Color* cl);
-static int Set_SDL_Pango_Font_Size(int size);
-
-/*-- file-scope variables and local file prototypes for SDL_ttf-based code: */
-#else
-#include "SDL_ttf.h"
-/* We cache fonts here once loaded to improve performance: */
-TTF_Font* font_list[MAX_FONT_SIZE + 1] = {NULL};
-static void free_font_list(void);
-static TTF_Font* get_font(int size);
-static TTF_Font* load_font(const char* font_name, int font_size);
-#endif
-
-
-/* "Public" functions called from other files that use either */
-/*SDL_Pango or SDL_ttf: */
-
-
-/* For setup, we either initialize SDL_Pango and set its context, */
-/* or we initialize SDL_ttf: */
-int Setup_SDL_Text(void)
-{
-#ifdef HAVE_LIBSDL_PANGO
-
- DEBUGMSG(debug_sdl, "Setup_SDL_Text() - using SDL_Pango\n");
-
- SDLPango_Init();
- if (!Set_SDL_Pango_Font_Size(DEFAULT_MENU_FONT_SIZE))
- {
- fprintf(stderr, "\nError: I could not set SDL_Pango context\n");
- return 0;
- }
- return 1;
-
-#else
-/* using SDL_ttf: */
- DEBUGMSG(debug_sdl, "Setup_SDL_Text() - using SDL_ttf\n");
-
- if (TTF_Init() < 0)
- {
- fprintf(stderr, "\nError: I could not initialize SDL_ttf\n");
- return 0;
- }
- return 1;
-#endif
-}
-
-
-
-void Cleanup_SDL_Text(void)
-{
-#ifdef HAVE_LIBSDL_PANGO
- if(context != NULL)
- SDLPango_FreeContext(context);
- context = NULL;
-#else
- free_font_list();
- TTF_Quit();
-#endif
-}
-
-
-/* BlackOutline() creates a surface containing text of the designated */
-/* foreground color, surrounded by a black shadow, on a transparent */
-/* background. The appearance can be tuned by adjusting the number of */
-/* background copies and the offset where the foreground text is */
-/* finally written (see below). */
-//SDL_Surface* BlackOutline(const char *t, TTF_Font *font, SDL_Color *c)
-SDL_Surface* BlackOutline(const char* t, int size, SDL_Color* c)
-{
- SDL_Surface* out = NULL;
- SDL_Surface* black_letters = NULL;
- SDL_Surface* white_letters = NULL;
- SDL_Surface* bg = NULL;
- SDL_Rect dstrect;
- Uint32 color_key;
-
-/* Make sure everything is sane before we proceed: */
-#ifdef HAVE_LIBSDL_PANGO
- if (!context)
- {
- fprintf(stderr, "BlackOutline(): invalid SDL_Pango context - returning.");
- return NULL;
- }
-#else
- TTF_Font* font = get_font(size);
- if (!font)
- {
- fprintf(stderr, "BlackOutline(): could not load needed font - returning.");
- return NULL;
- }
-#endif
-
- if (!t || !c)
- {
- fprintf(stderr, "BlackOutline(): invalid ptr parameter, returning.");
- return NULL;
- }
-
- if (t[0] == '\0')
- {
- fprintf(stderr, "BlackOutline(): empty string, returning");
- return NULL;
- }
-
- DEBUGMSG(debug_sdl, "Entering BlackOutline():\n");
- DEBUGMSG(debug_sdl, "BlackOutline of \"%s\"\n", t );
-
-#ifdef HAVE_LIBSDL_PANGO
- Set_SDL_Pango_Font_Size(size);
- SDLPango_SetDefaultColor(context, MATRIX_TRANSPARENT_BACK_BLACK_LETTER);
- SDLPango_SetText(context, t, -1);
- black_letters = SDLPango_CreateSurfaceDraw(context);
-#else
- black_letters = TTF_RenderUTF8_Blended(font, t, black);
-#endif
-
- if (!black_letters)
- {
- fprintf (stderr, "Warning - BlackOutline() could not create image for %s\n", t);
- return NULL;
- }
-
- bg = SDL_CreateRGBSurface(SDL_SWSURFACE,
- (black_letters->w) + 5,
- (black_letters->h) + 5,
- 32,
- rmask, gmask, bmask, amask);
- /* Use color key for eventual transparency: */
- color_key = SDL_MapRGB(bg->format, 01, 01, 01);
- SDL_FillRect(bg, NULL, color_key);
-
- /* Now draw black outline/shadow 2 pixels on each side: */
- dstrect.w = black_letters->w;
- dstrect.h = black_letters->h;
-
- /* NOTE: can make the "shadow" more or less pronounced by */
- /* changing the parameters of these loops. */
- for (dstrect.x = 1; dstrect.x < 4; dstrect.x++)
- for (dstrect.y = 1; dstrect.y < 3; dstrect.y++)
- SDL_BlitSurface(black_letters , NULL, bg, &dstrect );
-
- SDL_FreeSurface(black_letters);
-
- /* --- Put the color version of the text on top! --- */
-#ifdef HAVE_LIBSDL_PANGO
- /* convert color arg: */
- SDLPango_Matrix* color_matrix = SDL_Colour_to_SDLPango_Matrix(c);
-
- if (color_matrix)
- {
- SDLPango_SetDefaultColor(context, color_matrix);
- free(color_matrix);
- }
- else /* fall back to just using white if conversion fails: */
- SDLPango_SetDefaultColor(context, MATRIX_TRANSPARENT_BACK_WHITE_LETTER);
-
- white_letters = SDLPango_CreateSurfaceDraw(context);
-
-#else
- white_letters = TTF_RenderUTF8_Blended(font, t, *c);
-#endif
-
- if (!white_letters)
- {
- fprintf (stderr, "Warning - BlackOutline() could not create image for %s\n", t);
- return NULL;
- }
-
- dstrect.x = 1;
- dstrect.y = 1;
- SDL_BlitSurface(white_letters, NULL, bg, &dstrect);
- SDL_FreeSurface(white_letters);
-
- /* --- Convert to the screen format for quicker blits --- */
- SDL_SetColorKey(bg, SDL_SRCCOLORKEY|SDL_RLEACCEL, color_key);
- out = SDL_DisplayFormatAlpha(bg);
- SDL_FreeSurface(bg);
-
- DEBUGMSG(debug_sdl, "\nLeaving BlackOutline(): \n");
-
- return out;
-}
-
-
-/* This (fast) function just returns a non-outlined surf */
-/* using either SDL_Pango or SDL_ttf */
-SDL_Surface* SimpleText(const char *t, int size, SDL_Color* col)
-{
- SDL_Surface* surf = NULL;
-
- if (!t||!col)
- return NULL;
-
-#ifdef HAVE_LIBSDL_PANGO
- if (!context)
- {
- fprintf(stderr, "SimpleText() - context not valid!\n");
- return NULL;
- }
- else
- {
- SDLPango_Matrix colormatrix =
- {{
- {col->r, col->r, 0, 0},
- {col->g, col->g, 0, 0},
- {col->b, col->b, 0, 0},
- {0, 255, 0, 0}
- }};
- Set_SDL_Pango_Font_Size(size);
- SDLPango_SetDefaultColor(context, &colormatrix );
- SDLPango_SetText(context, t, -1);
- surf = SDLPango_CreateSurfaceDraw(context);
- }
-
-#else
- {
- TTF_Font* font = get_font(size);
- if (!font)
- return NULL;
- surf = TTF_RenderUTF8_Blended(font, t, *col);
- }
-#endif
-
- return surf;
-}
-
-/* This (fast) function just returns a non-outlined surf */
-/* using SDL_Pango if available, SDL_ttf as fallback */
-SDL_Surface* SimpleTextWithOffset(const char *t, int size, SDL_Color* col, int *glyph_offset)
-{
- SDL_Surface* surf = NULL;
-
- if (!t||!col)
- return NULL;
-
-#ifdef HAVE_LIBSDL_PANGO
- if (!context)
- {
- fprintf(stderr, "SimpleText() - context not valid!\n");
- return NULL;
- }
- else
- {
- SDLPango_Matrix colormatrix =
- {{
- {col->r, col->r, 0, 0},
- {col->g, col->g, 0, 0},
- {col->b, col->b, 0, 0},
- {0, 255, 0, 0}
- }};
- Set_SDL_Pango_Font_Size(size);
- SDLPango_SetDefaultColor(context, &colormatrix );
- SDLPango_SetText(context, t, -1);
- surf = SDLPango_CreateSurfaceDraw(context);
- *glyph_offset = 0; // fixme?
- }
-
-#else
- {
- TTF_Font* font = get_font(size);
- if (!font)
- return NULL;
- surf = TTF_RenderUTF8_Blended(font, t, *col);
- {
- int h;
- int hmax = 0;
- int len = strlen(t);
- int i;
- for (i = 0; i < len; i++)
- {
- TTF_GlyphMetrics(font, t[i], NULL, NULL, NULL, &h, NULL);
- if (h > hmax)
- hmax = h;
- }
- *glyph_offset = hmax - TTF_FontAscent(font);
- }
- }
-#endif
-
- return surf;
-}
-
-
-
-/*-----------------------------------------------------------*/
-/* Local functions, callable only within SDL_extras, divided */
-/* according with which text lib we are using: */
-/*-----------------------------------------------------------*/
-
-
-
-#ifdef HAVE_LIBSDL_PANGO
-/* Local functions when using SDL_Pango: */
-
-
-/* NOTE the scaling by 3/4 a few lines down represents a conversion from */
-/* the usual text dpi of 72 to the typical screen dpi of 96. It gives */
-/* font sizes fairly similar to a SDL_ttf font with the same numerical value. */
-static int Set_SDL_Pango_Font_Size(int size)
-{
- /* static so we can "remember" values from previous time through: */
- static int prev_pango_font_size;
- static char prev_font_name[FONT_NAME_LENGTH];
- /* Do nothing unless we need to change size or font: */
- if ((size == prev_pango_font_size)
- &&
- (0 == strncmp(prev_font_name, Opts_FontName(), sizeof(prev_font_name))))
- return 1;
- else
- {
- char buf[64];
-
- DEBUGMSG(debug_sdl, "Setting font size to %d\n", size);
-
- if(context != NULL)
- SDLPango_FreeContext(context);
- context = NULL;
- snprintf(buf, sizeof(buf), "%s %d", Opts_FontName(), (int)((size * 3)/4));
- context = SDLPango_CreateContext_GivenFontDesc(buf);
- }
-
- if (!context)
- return 0;
- else
- {
- prev_pango_font_size = size;
- strncpy(prev_font_name, Opts_FontName(), sizeof(prev_font_name));
- return 1;
- }
-}
-
-
-SDLPango_Matrix* SDL_Colour_to_SDLPango_Matrix(const SDL_Color *cl)
-{
- int k = 0;
- SDLPango_Matrix* colour = NULL;
-
- if (!cl)
- {
- fprintf(stderr, "Invalid SDL_Color* arg\n");
- return NULL;
- }
-
- colour = (SDLPango_Matrix*)malloc(sizeof(SDLPango_Matrix));
-
- for(k = 0; k < 4; k++)
- {
- (*colour).m[0][k] = (*cl).r;
- (*colour).m[1][k] = (*cl).g;
- (*colour).m[2][k] = (*cl).b;
- }
- (*colour).m[3][0] = 0;
- (*colour).m[3][1] = 255;
- (*colour).m[3][2] = 0;
- (*colour).m[3][3] = 0;
-
- return colour;
-}
-
-#else
-/* Local functions when using SDL_ttf: */
-
-static void free_font_list(void)
-{
- int i;
- for(i = 0; i < MAX_FONT_SIZE; i++)
- {
- if(font_list[i])
- {
- TTF_CloseFont(font_list[i]);
- font_list[i] = NULL;
- }
- }
-}
-
-/* FIXME - could combine this with load_font() below: */
-/* Loads and caches fonts in each size as they are requested: */
-/* We use the font size as an array index, keeping each size */
-/* font in memory once loaded until cleanup. */
-static TTF_Font* get_font(int size)
-{
- static char prev_font_name[FONT_NAME_LENGTH];
- if (size < 0)
- {
- fprintf(stderr, "Error - requested font size %d is negative\n", size);
- return NULL;
- }
-
- if (size > MAX_FONT_SIZE)
- {
- fprintf(stderr, "Error - requested font size %d exceeds max = %d, resetting.\n",
- size, MAX_FONT_SIZE);
- size = MAX_FONT_SIZE;
- }
-
- /* If the font has changed, we need to wipe out the old ones: */
- if (0 != strncmp(prev_font_name, Opts_FontName(),sizeof(prev_font_name)))
- {
- free_font_list();
- strncpy(prev_font_name, Opts_FontName(), sizeof(prev_font_name));
- }
-
- if(font_list[size] == NULL)
- font_list[size] = load_font(DEFAULT_FONT_NAME, size);
- return font_list[size];
-}
-
-
-/* FIXME: I think we need to provide a single default font with the program data, */
-/* then more flexible code to try to locate or load system fonts. DSB */
-/* Returns ptr to loaded font if successful, NULL otherwise. */
-static TTF_Font* load_font(const char* font_name, int font_size)
-{
- TTF_Font* f;
- char fontfile[PATH_MAX];
- sprintf(fontfile, "%s/fonts/%s", DATA_PREFIX, font_name);
-
- f = TTF_OpenFont(fontfile, font_size);
-
- /* HACK - better font searching needed! */
- /* This should mean that font wasn't bundled into data path, which for */
- /* now means we are using Debian, so grab from Debian installation loc: */
- if (!f)
- {
- sprintf(fontfile, "/usr/share/fonts/truetype/ttf-sil-andika/AndikaDesRevG.ttf");
- f = TTF_OpenFont(fontfile, font_size);
- }
-
-
- if (f)
- {
- DEBUGMSG(debug_sdl, "LoadFont(): %s loaded successfully\n\n", fontfile);
- return f;
- }
- else
- {
- fprintf(stderr, "LoadFont(): %s NOT loaded successfully.\n", fontfile);
- return NULL;
- }
-}
-#endif
-
-#endif
Added: branches/commonification/tux4kids-common/trunk/src/t4k-globals.h
===================================================================
--- branches/commonification/tux4kids-common/trunk/src/t4k-globals.h (rev 0)
+++ branches/commonification/tux4kids-common/trunk/src/t4k-globals.h 2009-07-30 16:23:36 UTC (rev 1295)
@@ -0,0 +1,29 @@
+/*
+ tk4-globals.h
+
+ Part of "Tux4Kids" Project
+ http://www.tux4kids.org/
+
+ Copyright: See COPYING file that comes with this distribution
+*/
+
+#ifndef GLOBALS_H
+#define GLOBALS_H
+
+typedef enum { false, true } bool;
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+extern int dbg_status;
+
+extern const int dbg_menu;
+extern const int dbg_menu_parser;
+extern const int dbg_sdl;
+extern const int dbg_all;
+
+/* debug macros */
+#define DEBUGCODE(mask) if((mask) & dbg_status)
+#define DEBUGMSG(mask, ...) if((mask) & dbg_status){ fprintf(stderr, __VA_ARGS__); fflush(stderr); }
+
+#endif
Added: branches/commonification/tux4kids-common/trunk/src/t4k-main.c
===================================================================
--- branches/commonification/tux4kids-common/trunk/src/t4k-main.c (rev 0)
+++ branches/commonification/tux4kids-common/trunk/src/t4k-main.c 2009-07-30 16:23:36 UTC (rev 1295)
@@ -0,0 +1,29 @@
+/*
+ t4k-main.c
+
+ Functions used to initialize the tux4kids-common library.
+
+ Part of "Tux4Kids" Project
+ http://www.tux4kids.com/
+
+ Author: Boleslaw Kulbabinski <bkulbabinski at gmail.com>, (C) 2009
+
+ Copyright: See COPYING file that comes with this distribution.
+*/
+
+#include "tux4kids-common.h"
+#include "t4k-globals.h"
+
+int dbg_status;
+
+/* these values have to match those used in games */
+const int dbg_menu = 1 << 4;
+const int dbg_menu_parser = 1 << 5;
+const int dbg_sdl = 1 << 10;
+const int dbg_all = ~0;
+
+void SetDebugMode(int dbg_flags)
+{
+ dbg_status = dbg_flags;
+}
+
Added: branches/commonification/tux4kids-common/trunk/src/t4k-sdl.c
===================================================================
--- branches/commonification/tux4kids-common/trunk/src/t4k-sdl.c (rev 0)
+++ branches/commonification/tux4kids-common/trunk/src/t4k-sdl.c 2009-07-30 16:23:36 UTC (rev 1295)
@@ -0,0 +1,1134 @@
+/*
+* C Implementation: SDL_extras
+*
+* Description: a few handy functions for using SDL graphics.
+*
+*
+* Author: David Bruce,,, <dbruce at tampabay.rr.com>, (C) 2007
+*
+* Copyright: GPL v3 or later
+*
+*/
+
+#include <math.h>
+
+#include "tux4kids-common.h"
+#include "t4k-globals.h"
+
+static SDL_Surface* screen = NULL;
+
+/*
+Return a pointer to the screen we're using, as an alternative to making screen
+global. Not sure what is involved performance-wise in SDL_GetVideoSurface,
+or if this check is even necessary -Cheez
+*/
+SDL_Surface* GetScreen()
+{
+#ifdef TUXMATH_DEBUG
+ {
+ if (screen != SDL_GetVideoSurface() )
+ {
+ fprintf(stderr, "Video Surface changed from outside of SDL_Extras!\n");
+ screen = SDL_GetVideoSurface();
+ }
+ }
+#endif
+ return screen;
+}
+
+
+/* DrawButton() creates a translucent button with rounded ends
+ and draws it on the screen.
+ All colors and alpha values are supported.*/
+void DrawButton(SDL_Rect* target_rect,
+ int radius,
+ Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+ DrawButtonOn(screen, target_rect, radius, r, g, b, a);
+}
+
+void DrawButtonOn(SDL_Surface* target,
+ SDL_Rect* target_rect,
+ int radius,
+ Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+
+{
+ SDL_Surface* tmp_surf = CreateButton(target_rect->w, target_rect->h,
+ radius, r, g, b, a);
+ SDL_BlitSurface(tmp_surf, NULL, target, target_rect);
+ SDL_FreeSurface(tmp_surf);
+}
+
+/* CreateButton() creates a translucent button with rounded ends
+ All colors and alpha values are supported.*/
+SDL_Surface* CreateButton(int w, int h, int radius,
+ Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+ /* NOTE - we use a 32-bit temp surface even if we have a 16-bit */
+ /* screen - it gets converted during blitting. */
+ SDL_Surface* tmp_surf = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,
+ w,
+ h,
+ 32,
+ rmask, gmask, bmask, amask);
+
+ Uint32 color = SDL_MapRGBA(tmp_surf->format, r, g, b, a);
+ SDL_FillRect(tmp_surf, NULL, color);
+ RoundCorners(tmp_surf, radius);
+ return tmp_surf;
+}
+
+void RoundCorners(SDL_Surface* s, Uint16 radius)
+{
+ int y = 0;
+ int x_dist, y_dist;
+ Uint32* p = NULL;
+ Uint32 alpha_mask;
+ int bytes_per_pix;
+
+ if (!s)
+ return;
+ if (SDL_LockSurface(s) == -1)
+ return;
+
+ bytes_per_pix = s->format->BytesPerPixel;
+ if (bytes_per_pix != 4)
+ return;
+
+ /* radius cannot be more than half of width or height: */
+ if (radius > (s->w)/2)
+ radius = (s->w)/2;
+ if (radius > (s->h)/2)
+ radius = (s->h)/2;
+
+
+ alpha_mask = s->format->Amask;
+
+ /* Now round off corners: */
+ /* upper left: */
+ for (y = 0; y < radius; y++)
+ {
+ p = (Uint32*)(s->pixels + (y * s->pitch));
+ x_dist = radius;
+ y_dist = radius - y;
+
+ while (((x_dist * x_dist) + (y_dist * y_dist)) > (radius * radius))
+ {
+ /* (make pixel (x,y) transparent) */
+ *p = *p & ~alpha_mask;
+ p++;
+ x_dist--;
+ }
+ }
+
+ /* upper right: */
+ for (y = 0; y < radius; y++)
+ {
+ /* start at end of top row: */
+ p = (Uint32*)(s->pixels + ((y + 1) * s->pitch) - bytes_per_pix);
+
+ x_dist = radius;
+ y_dist = radius - y;
+
+ while (((x_dist * x_dist) + (y_dist * y_dist)) > (radius * radius))
+ {
+ /* (make pixel (x,y) transparent) */
+ *p = *p & ~alpha_mask;
+ p--;
+ x_dist--;
+ }
+ }
+
+ /* bottom left: */
+ for (y = (s->h - 1); y > (s->h - radius); y--)
+ {
+ /* start at beginning of bottom row */
+ p = (Uint32*)(s->pixels + (y * s->pitch));
+ x_dist = radius;
+ y_dist = y - (s->h - radius);
+
+ while (((x_dist * x_dist) + (y_dist * y_dist)) > (radius * radius))
+ {
+ /* (make pixel (x,y) transparent) */
+ *p = *p & ~alpha_mask;
+ p++;
+ x_dist--;
+ }
+ }
+
+ /* bottom right: */
+ for (y = (s->h - 1); y > (s->h - radius); y--)
+ {
+ /* start at end of bottom row */
+ p = (Uint32*)(s->pixels + ((y + 1) * s->pitch) - bytes_per_pix);
+ x_dist = radius;
+ y_dist = y - (s->h - radius);
+
+ while (((x_dist * x_dist) + (y_dist * y_dist)) > (radius * radius))
+ {
+ /* (make pixel (x,y) transparent) */
+ *p = *p & ~alpha_mask;
+ p--;
+ x_dist--;
+ }
+ }
+ SDL_UnlockSurface(s);
+}
+
+/**
+ * TODO ***Migrate other functions! Oh, and test on Win/Mac
+ */
+
+#if 0
+/**********************
+ Flip:
+ input: a SDL_Surface, x, y
+ output: a copy of the SDL_Surface flipped via rules:
+
+ if x is a nonzero value, then flip horizontally
+ if y is a nonzero value, then flip vertically
+
+ note: you can have it flip both
+**********************/
+SDL_Surface* Flip( SDL_Surface *in, int x, int y ) {
+ SDL_Surface *out, *tmp;
+ SDL_Rect from_rect, to_rect;
+ Uint32 flags;
+ Uint32 colorkey=0;
+
+ /* --- grab the settings for the incoming pixmap --- */
+
+ SDL_LockSurface(in);
+ flags = in->flags;
+
+ /* --- change in's flags so ignore colorkey & alpha --- */
+
+ if (flags & SDL_SRCCOLORKEY) {
+ in->flags &= ~SDL_SRCCOLORKEY;
+ colorkey = in->format->colorkey;
+ }
+ if (flags & SDL_SRCALPHA) {
+ in->flags &= ~SDL_SRCALPHA;
+ }
+
+ SDL_UnlockSurface(in);
+
+ /* --- create our new surface --- */
+
+ out = SDL_CreateRGBSurface(
+ SDL_SWSURFACE,
+ in->w, in->h, 32, rmask, gmask, bmask, amask);
+
+ /* --- flip horizontally if requested --- */
+
+ if (x) {
+ from_rect.h = to_rect.h = in->h;
+ from_rect.w = to_rect.w = 1;
+ from_rect.y = to_rect.y = 0;
+ from_rect.x = 0;
+ to_rect.x = in->w - 1;
+
+ do {
+ SDL_BlitSurface(in, &from_rect, out, &to_rect);
+ from_rect.x++;
+ to_rect.x--;
+ } while (to_rect.x >= 0);
+ }
+
+ /* --- flip vertically if requested --- */
+
+ if (y) {
+ from_rect.h = to_rect.h = 1;
+ from_rect.w = to_rect.w = in->w;
+ from_rect.x = to_rect.x = 0;
+ from_rect.y = 0;
+ to_rect.y = in->h - 1;
+
+ do {
+ SDL_BlitSurface(in, &from_rect, out, &to_rect);
+ from_rect.y++;
+ to_rect.y--;
+ } while (to_rect.y >= 0);
+ }
+
+ /* --- restore colorkey & alpha on in and setup out the same --- */
+
+ SDL_LockSurface(in);
+
+ if (flags & SDL_SRCCOLORKEY) {
+ in->flags |= SDL_SRCCOLORKEY;
+ in->format->colorkey = colorkey;
+ tmp = SDL_DisplayFormat(out);
+ SDL_FreeSurface(out);
+ out = tmp;
+ out->flags |= SDL_SRCCOLORKEY;
+ out->format->colorkey = colorkey;
+ } else if (flags & SDL_SRCALPHA) {
+ in->flags |= SDL_SRCALPHA;
+ tmp = SDL_DisplayFormatAlpha(out);
+ SDL_FreeSurface(out);
+ out = tmp;
+ } else {
+ tmp = SDL_DisplayFormat(out);
+ SDL_FreeSurface(out);
+ out = tmp;
+ }
+
+ SDL_UnlockSurface(in);
+
+ return out;
+}
+
+/* Blend two surfaces together. The third argument is between 0.0 and
+ 1.0, and represents the weight assigned to the first surface. If
+ the pointer to the second surface is NULL, this performs fading.
+
+ Currently this works only with RGBA images, but this is largely to
+ make the (fast) pointer arithmetic work out; it could be easily
+ generalized to other image types. */
+SDL_Surface* Blend(SDL_Surface *S1, SDL_Surface *S2, float gamma)
+{
+ SDL_PixelFormat *fmt1, *fmt2;
+ Uint8 r1, r2, g1, g2, b1, b2, a1, a2;
+ SDL_Surface *tmpS, *ret;
+ Uint32 *cpix1, *epix1, *cpix2, *epix2;
+ float gamflip;
+
+ if (!S1)
+ return NULL;
+
+ fmt1 = fmt2 = NULL;
+ tmpS = ret = NULL;
+
+ gamflip = 1.0 - gamma;
+ if (gamma < 0 || gamflip < 0)
+ {
+ perror("gamma must be between 0 and 1");
+ exit(0);
+ }
+
+ fmt1 = S1->format;
+
+ if (fmt1 && fmt1->BitsPerPixel != 32)
+ {
+ perror("This works only with RGBA images");
+ return S1;
+ }
+ if (S2 != NULL)
+ {
+ fmt2 = S2->format;
+ if (fmt2->BitsPerPixel != 32)
+ {
+ perror("This works only with RGBA images");
+ return S1;
+ }
+ // Check that both images have the same width dimension
+ if (S1->w != S2->w)
+ {
+ printf("S1->w %d, S2->w %d; S1->h %d, S2->h %d\n",
+ S1->w, S2->w, S1->h, S2->h);
+ printf("Both images must have the same width dimensions\n");
+ return S1;
+ }
+ }
+
+ tmpS = SDL_ConvertSurface(S1, fmt1, SDL_SWSURFACE);
+ if (tmpS == NULL)
+ {
+ perror("SDL_ConvertSurface() failed");
+ return S1;
+ }
+ if (-1 == SDL_LockSurface(tmpS))
+ {
+ perror("SDL_LockSurface() failed");
+ return S1;
+ }
+
+ // We're going to go through the pixels in reverse order, to start
+ // from the bottom of each image. That way, we can blend things that
+ // are not of the same height and have them align at the bottom.
+ // So the "ending pixel" (epix) will be before the first pixel, and
+ // the current pixel (cpix) will be the last pixel.
+ epix1 = (Uint32*) tmpS->pixels - 1;
+ cpix1 = epix1 + tmpS->w * tmpS->h;
+ if (S2 != NULL
+ && (SDL_LockSurface(S2) != -1))
+ {
+ epix2 = (Uint32*) S2->pixels - 1;
+ cpix2 = epix2 + S2->w * S2->h;
+ }
+ else
+ {
+ epix2 = epix1;
+ cpix2 = cpix1;
+ }
+
+ for (; cpix1 > epix1; cpix1--, cpix2--)
+ {
+ SDL_GetRGBA(*cpix1, fmt1, &r1, &g1, &b1, &a1);
+ a1 = gamma * a1;
+ if (S2 != NULL && cpix2 > epix2)
+ {
+ SDL_GetRGBA(*cpix2, fmt2, &r2, &g2, &b2, &a2);
+ r1 = gamma * r1 + gamflip * r2;
+ g1 = gamma * g1 + gamflip * g2;
+ b1 = gamma * b1 + gamflip * b2;
+ a1 += gamflip * a2;
+ }
+ *cpix1 = SDL_MapRGBA(fmt1,r1,g1,b1,a1);
+ }
+
+ SDL_UnlockSurface(tmpS);
+
+ if (S2 != NULL)
+ SDL_UnlockSurface(S2);
+
+ ret = SDL_DisplayFormatAlpha(tmpS);
+ SDL_FreeSurface(tmpS);
+
+ return ret;
+}
+
+
+/* free every surface in the array together with the array itself */
+void FreeSurfaceArray(SDL_Surface** surfs, int length)
+{
+ int i;
+
+ if(surfs == NULL)
+ return;
+
+ for(i = 0; i < length; i++)
+ if(surfs[i] != NULL)
+ SDL_FreeSurface(surfs[i]);
+ free(surfs);
+}
+
+int inRect( SDL_Rect r, int x, int y) {
+ if ((x < r.x) || (y < r.y) || (x > r.x + r.w) || (y > r.y + r.h))
+ return 0;
+ return 1;
+}
+
+void UpdateRect(SDL_Surface* surf, SDL_Rect* rect)
+{
+ SDL_UpdateRect(surf, rect->x, rect->y, rect->w, rect->h);
+}
+
+void SetRect(SDL_Rect* rect, const float* pos)
+{
+ rect->x = pos[0] * screen->w;
+ rect->y = pos[1] * screen->h;
+ rect->w = pos[2] * screen->w;
+ rect->h = pos[3] * screen->h;
+}
+
+/* Darkens the screen by a factor of 2^bits */
+void DarkenScreen(Uint8 bits)
+{
+#if PIXEL_BITS == 32
+ Uint32* p;
+#elif PIXEL_BITS == 16
+ Uint16* p;
+#else
+ return;
+#endif
+ Uint32 rm = screen->format->Rmask;
+ Uint32 gm = screen->format->Gmask;
+ Uint32 bm = screen->format->Bmask;
+
+
+ int x, y;
+
+ /* (realistically, 1 and 2 are the only useful values) */
+ if (bits > 8)
+ return;
+
+ p = screen->pixels;
+
+ for (y = 0; y < screen->h; y++)
+ {
+ for (x = 0; x < screen->w; x++)
+ {
+ *p = (((*p&rm)>>bits)&rm)
+ | (((*p&gm)>>bits)&gm)
+ | (((*p&bm)>>bits)&bm);
+ p++;
+ }
+ }
+}
+
+/* change window size (works only in windowed mode) */
+void ChangeWindowSize(int new_res_x, int new_res_y)
+{
+ SDL_Surface* oldscreen = screen;
+
+ if(!(screen->flags & SDL_FULLSCREEN))
+ {
+ screen = SDL_SetVideoMode(new_res_x,
+ new_res_y,
+ PIXEL_BITS,
+ SDL_SWSURFACE|SDL_HWPALETTE);
+
+ if(screen == NULL)
+ {
+ fprintf(stderr,
+ "\nError: I could not change screen mode into %d x %d.\n",
+ new_res_x, new_res_y);
+ screen = oldscreen;
+ }
+ else
+ {
+ DEBUGMSG(debug_sdl, "ChangeWindowSize(): Changed window size to %d x %d\n", screen->w, screen->h);
+ oldscreen = NULL;
+ win_res_x = screen->w;
+ win_res_y = screen->h;
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
+ }
+ }
+ else
+ DEBUGMSG(debug_sdl, "ChangeWindowSize() can be run only in windowed mode !");
+}
+
+/* switch between fullscreen and windowed mode */
+void SwitchScreenMode(void)
+{
+ int window = (screen->flags & SDL_FULLSCREEN);
+ SDL_Surface* oldscreen = screen;
+
+ screen = SDL_SetVideoMode(window ? win_res_x : fs_res_x,
+ window ? win_res_y : fs_res_y,
+ PIXEL_BITS,
+ screen->flags ^ SDL_FULLSCREEN);
+
+ if (screen == NULL)
+ {
+ fprintf(stderr,
+ "\nError: I could not switch to %s mode.\n"
+ "The Simple DirectMedia error that occured was:\n"
+ "%s\n\n",
+ window ? "windowed" : "fullscreen",
+ SDL_GetError());
+ screen = oldscreen;
+ }
+ else
+ {
+ //success, no need to free the old video surface
+ DEBUGMSG(debug_sdl, "Switched screen mode to %s\n", window ? "windowed" : "fullscreen");
+ oldscreen = NULL;
+ SDL_UpdateRect(screen, 0, 0, 0, 0);
+ }
+}
+
+/*
+Block application until SDL receives an appropriate event. Events can be
+a single or OR'd combination of event masks.
+e.g. e = WaitForEvent(SDL_KEYDOWNMASK | SDL_QUITMASK)
+*/
+SDL_EventType WaitForEvent(SDL_EventMask events)
+{
+ SDL_Event evt;
+ while (1)
+ {
+ while (SDL_PollEvent(&evt) )
+ {
+ if (SDL_EVENTMASK(evt.type) & events)
+ return evt.type;
+ else
+ SDL_Delay(50);
+ }
+ }
+}
+/* Swiped shamelessly from TuxPaint
+ Based on code from: http://www.codeproject.com/cs/media/imageprocessing4.asp
+ copyright 2002 Christian Graus */
+
+SDL_Surface* zoom(SDL_Surface* src, int new_w, int new_h)
+{
+ SDL_Surface* s;
+
+ /* These function pointers will point to the appropriate */
+ /* putpixel() and getpixel() variants to be used in the */
+ /* current colorspace: */
+ void (*putpixel) (SDL_Surface*, int, int, Uint32);
+ Uint32(*getpixel) (SDL_Surface*, int, int);
+
+ float xscale, yscale;
+ int x, y;
+ int floor_x, ceil_x,
+ floor_y, ceil_y;
+ float fraction_x, fraction_y,
+ one_minus_x, one_minus_y;
+ float n1, n2;
+ Uint8 r1, g1, b1, a1;
+ Uint8 r2, g2, b2, a2;
+ Uint8 r3, g3, b3, a3;
+ Uint8 r4, g4, b4, a4;
+ Uint8 r, g, b, a;
+
+ DEBUGMSG(debug_sdl, "Entering zoom():\n");
+
+ /* Create surface for zoom: */
+
+ s = SDL_CreateRGBSurface(src->flags, /* SDL_SWSURFACE, */
+ new_w, new_h, src->format->BitsPerPixel,
+ src->format->Rmask,
+ src->format->Gmask,
+ src->format->Bmask,
+ src->format->Amask);
+
+ if (s == NULL)
+ {
+ fprintf(stderr, "\nError: Can't build zoom surface\n"
+ "The Simple DirectMedia Layer error that occurred was:\n"
+ "%s\n\n", SDL_GetError());
+ return NULL;
+// cleanup();
+// exit(1);
+ }
+
+ DEBUGMSG(debug_sdl, "zoom(): orig surface %dx%d, %d bytes per pixel\n",
+ src->w, src->h, src->format->BytesPerPixel);
+ DEBUGMSG(debug_sdl, "zoom(): new surface %dx%d, %d bytes per pixel\n",
+ s->w, s->h, s->format->BytesPerPixel);
+
+ /* Now assign function pointers to correct functions based */
+ /* on data format of original and zoomed surfaces: */
+ getpixel = getpixels[src->format->BytesPerPixel];
+ putpixel = putpixels[s->format->BytesPerPixel];
+
+ SDL_LockSurface(src);
+ SDL_LockSurface(s);
+
+ xscale = (float) src->w / (float) new_w;
+ yscale = (float) src->h / (float) new_h;
+
+ for (x = 0; x < new_w; x++)
+ {
+ for (y = 0; y < new_h; y++)
+ {
+ /* Here we calculate the new RGBA values for each pixel */
+ /* using a "weighted average" of the four pixels in the */
+ /* corresponding location in the orginal surface: */
+
+ /* figure out which original pixels to use in the calc: */
+ floor_x = floor((float) x * xscale);
+ ceil_x = floor_x + 1;
+ if (ceil_x >= src->w)
+ ceil_x = floor_x;
+
+ floor_y = floor((float) y * yscale);
+ ceil_y = floor_y + 1;
+ if (ceil_y >= src->h)
+ ceil_y = floor_y;
+
+ fraction_x = x * xscale - floor_x;
+ fraction_y = y * yscale - floor_y;
+
+ one_minus_x = 1.0 - fraction_x;
+ one_minus_y = 1.0 - fraction_y;
+
+ /* Grab their values: */
+ SDL_GetRGBA(getpixel(src, floor_x, floor_y), src->format,
+ &r1, &g1, &b1, &a1);
+ SDL_GetRGBA(getpixel(src, ceil_x, floor_y), src->format,
+ &r2, &g2, &b2, &a2);
+ SDL_GetRGBA(getpixel(src, floor_x, ceil_y), src->format,
+ &r3, &g3, &b3, &a3);
+ SDL_GetRGBA(getpixel(src, ceil_x, ceil_y), src->format,
+ &r4, &g4, &b4, &a4);
+
+ /* Create the weighted averages: */
+ n1 = (one_minus_x * r1 + fraction_x * r2);
+ n2 = (one_minus_x * r3 + fraction_x * r4);
+ r = (one_minus_y * n1 + fraction_y * n2);
+
+ n1 = (one_minus_x * g1 + fraction_x * g2);
+ n2 = (one_minus_x * g3 + fraction_x * g4);
+ g = (one_minus_y * n1 + fraction_y * n2);
+
+ n1 = (one_minus_x * b1 + fraction_x * b2);
+ n2 = (one_minus_x * b3 + fraction_x * b4);
+ b = (one_minus_y * n1 + fraction_y * n2);
+
+ n1 = (one_minus_x * a1 + fraction_x * a2);
+ n2 = (one_minus_x * a3 + fraction_x * a4);
+ a = (one_minus_y * n1 + fraction_y * n2);
+
+ /* and put them into our new surface: */
+ putpixel(s, x, y, SDL_MapRGBA(s->format, r, g, b, a));
+
+ }
+ }
+
+ SDL_UnlockSurface(s);
+ SDL_UnlockSurface(src);
+
+ DEBUGMSG(debug_sdl, "Leaving zoom():\n");
+
+ return s;
+}
+
+/************************************************************************/
+/* */
+/* Begin text drawing functions */
+/* */
+/* These functions support text drawing using either SDL_Pango */
+/* or SDL_ttf. SDL_Pango is preferable but is not available on all */
+/* platforms. Code outside of this file does not have to worry about */
+/* which library is used to do the actual rendering. */
+/************************************************************************/
+
+#define MAX_FONT_SIZE 40
+
+//NOTE to test program with SDL_ttf, do "./configure --without-sdlpango"
+
+
+/*-- file-scope variables and local file prototypes for SDL_Pango-based code: */
+#ifdef HAVE_LIBSDL_PANGO
+#include "SDL_Pango.h"
+SDLPango_Context* context = NULL;
+static SDLPango_Matrix* SDL_Colour_to_SDLPango_Matrix(const SDL_Color* cl);
+static int Set_SDL_Pango_Font_Size(int size);
+
+/*-- file-scope variables and local file prototypes for SDL_ttf-based code: */
+#else
+#include "SDL_ttf.h"
+/* We cache fonts here once loaded to improve performance: */
+TTF_Font* font_list[MAX_FONT_SIZE + 1] = {NULL};
+static void free_font_list(void);
+static TTF_Font* get_font(int size);
+static TTF_Font* load_font(const char* font_name, int font_size);
+#endif
+
+
+/* "Public" functions called from other files that use either */
+/*SDL_Pango or SDL_ttf: */
+
+
+/* For setup, we either initialize SDL_Pango and set its context, */
+/* or we initialize SDL_ttf: */
+int Setup_SDL_Text(void)
+{
+#ifdef HAVE_LIBSDL_PANGO
+
+ DEBUGMSG(debug_sdl, "Setup_SDL_Text() - using SDL_Pango\n");
+
+ SDLPango_Init();
+ if (!Set_SDL_Pango_Font_Size(DEFAULT_MENU_FONT_SIZE))
+ {
+ fprintf(stderr, "\nError: I could not set SDL_Pango context\n");
+ return 0;
+ }
+ return 1;
+
+#else
+/* using SDL_ttf: */
+ DEBUGMSG(debug_sdl, "Setup_SDL_Text() - using SDL_ttf\n");
+
+ if (TTF_Init() < 0)
+ {
+ fprintf(stderr, "\nError: I could not initialize SDL_ttf\n");
+ return 0;
+ }
+ return 1;
+#endif
+}
+
+
+
+void Cleanup_SDL_Text(void)
+{
+#ifdef HAVE_LIBSDL_PANGO
+ if(context != NULL)
+ SDLPango_FreeContext(context);
+ context = NULL;
+#else
+ free_font_list();
+ TTF_Quit();
+#endif
+}
+
+
+/* BlackOutline() creates a surface containing text of the designated */
+/* foreground color, surrounded by a black shadow, on a transparent */
+/* background. The appearance can be tuned by adjusting the number of */
+/* background copies and the offset where the foreground text is */
+/* finally written (see below). */
+//SDL_Surface* BlackOutline(const char *t, TTF_Font *font, SDL_Color *c)
+SDL_Surface* BlackOutline(const char* t, int size, SDL_Color* c)
+{
+ SDL_Surface* out = NULL;
+ SDL_Surface* black_letters = NULL;
+ SDL_Surface* white_letters = NULL;
+ SDL_Surface* bg = NULL;
+ SDL_Rect dstrect;
+ Uint32 color_key;
+
+/* Make sure everything is sane before we proceed: */
+#ifdef HAVE_LIBSDL_PANGO
+ if (!context)
+ {
+ fprintf(stderr, "BlackOutline(): invalid SDL_Pango context - returning.");
+ return NULL;
+ }
+#else
+ TTF_Font* font = get_font(size);
+ if (!font)
+ {
+ fprintf(stderr, "BlackOutline(): could not load needed font - returning.");
+ return NULL;
+ }
+#endif
+
+ if (!t || !c)
+ {
+ fprintf(stderr, "BlackOutline(): invalid ptr parameter, returning.");
+ return NULL;
+ }
+
+ if (t[0] == '\0')
+ {
+ fprintf(stderr, "BlackOutline(): empty string, returning");
+ return NULL;
+ }
+
+ DEBUGMSG(debug_sdl, "Entering BlackOutline():\n");
+ DEBUGMSG(debug_sdl, "BlackOutline of \"%s\"\n", t );
+
+#ifdef HAVE_LIBSDL_PANGO
+ Set_SDL_Pango_Font_Size(size);
+ SDLPango_SetDefaultColor(context, MATRIX_TRANSPARENT_BACK_BLACK_LETTER);
+ SDLPango_SetText(context, t, -1);
+ black_letters = SDLPango_CreateSurfaceDraw(context);
+#else
+ black_letters = TTF_RenderUTF8_Blended(font, t, black);
+#endif
+
+ if (!black_letters)
+ {
+ fprintf (stderr, "Warning - BlackOutline() could not create image for %s\n", t);
+ return NULL;
+ }
+
+ bg = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ (black_letters->w) + 5,
+ (black_letters->h) + 5,
+ 32,
+ rmask, gmask, bmask, amask);
+ /* Use color key for eventual transparency: */
+ color_key = SDL_MapRGB(bg->format, 01, 01, 01);
+ SDL_FillRect(bg, NULL, color_key);
+
+ /* Now draw black outline/shadow 2 pixels on each side: */
+ dstrect.w = black_letters->w;
+ dstrect.h = black_letters->h;
+
+ /* NOTE: can make the "shadow" more or less pronounced by */
+ /* changing the parameters of these loops. */
+ for (dstrect.x = 1; dstrect.x < 4; dstrect.x++)
+ for (dstrect.y = 1; dstrect.y < 3; dstrect.y++)
+ SDL_BlitSurface(black_letters , NULL, bg, &dstrect );
+
+ SDL_FreeSurface(black_letters);
+
+ /* --- Put the color version of the text on top! --- */
+#ifdef HAVE_LIBSDL_PANGO
+ /* convert color arg: */
+ SDLPango_Matrix* color_matrix = SDL_Colour_to_SDLPango_Matrix(c);
+
+ if (color_matrix)
+ {
+ SDLPango_SetDefaultColor(context, color_matrix);
+ free(color_matrix);
+ }
+ else /* fall back to just using white if conversion fails: */
+ SDLPango_SetDefaultColor(context, MATRIX_TRANSPARENT_BACK_WHITE_LETTER);
+
+ white_letters = SDLPango_CreateSurfaceDraw(context);
+
+#else
+ white_letters = TTF_RenderUTF8_Blended(font, t, *c);
+#endif
+
+ if (!white_letters)
+ {
+ fprintf (stderr, "Warning - BlackOutline() could not create image for %s\n", t);
+ return NULL;
+ }
+
+ dstrect.x = 1;
+ dstrect.y = 1;
+ SDL_BlitSurface(white_letters, NULL, bg, &dstrect);
+ SDL_FreeSurface(white_letters);
+
+ /* --- Convert to the screen format for quicker blits --- */
+ SDL_SetColorKey(bg, SDL_SRCCOLORKEY|SDL_RLEACCEL, color_key);
+ out = SDL_DisplayFormatAlpha(bg);
+ SDL_FreeSurface(bg);
+
+ DEBUGMSG(debug_sdl, "\nLeaving BlackOutline(): \n");
+
+ return out;
+}
+
+
+/* This (fast) function just returns a non-outlined surf */
+/* using either SDL_Pango or SDL_ttf */
+SDL_Surface* SimpleText(const char *t, int size, SDL_Color* col)
+{
+ SDL_Surface* surf = NULL;
+
+ if (!t||!col)
+ return NULL;
+
+#ifdef HAVE_LIBSDL_PANGO
+ if (!context)
+ {
+ fprintf(stderr, "SimpleText() - context not valid!\n");
+ return NULL;
+ }
+ else
+ {
+ SDLPango_Matrix colormatrix =
+ {{
+ {col->r, col->r, 0, 0},
+ {col->g, col->g, 0, 0},
+ {col->b, col->b, 0, 0},
+ {0, 255, 0, 0}
+ }};
+ Set_SDL_Pango_Font_Size(size);
+ SDLPango_SetDefaultColor(context, &colormatrix );
+ SDLPango_SetText(context, t, -1);
+ surf = SDLPango_CreateSurfaceDraw(context);
+ }
+
+#else
+ {
+ TTF_Font* font = get_font(size);
+ if (!font)
+ return NULL;
+ surf = TTF_RenderUTF8_Blended(font, t, *col);
+ }
+#endif
+
+ return surf;
+}
+
+/* This (fast) function just returns a non-outlined surf */
+/* using SDL_Pango if available, SDL_ttf as fallback */
+SDL_Surface* SimpleTextWithOffset(const char *t, int size, SDL_Color* col, int *glyph_offset)
+{
+ SDL_Surface* surf = NULL;
+
+ if (!t||!col)
+ return NULL;
+
+#ifdef HAVE_LIBSDL_PANGO
+ if (!context)
+ {
+ fprintf(stderr, "SimpleText() - context not valid!\n");
+ return NULL;
+ }
+ else
+ {
+ SDLPango_Matrix colormatrix =
+ {{
+ {col->r, col->r, 0, 0},
+ {col->g, col->g, 0, 0},
+ {col->b, col->b, 0, 0},
+ {0, 255, 0, 0}
+ }};
+ Set_SDL_Pango_Font_Size(size);
+ SDLPango_SetDefaultColor(context, &colormatrix );
+ SDLPango_SetText(context, t, -1);
+ surf = SDLPango_CreateSurfaceDraw(context);
+ *glyph_offset = 0; // fixme?
+ }
+
+#else
+ {
+ TTF_Font* font = get_font(size);
+ if (!font)
+ return NULL;
+ surf = TTF_RenderUTF8_Blended(font, t, *col);
+ {
+ int h;
+ int hmax = 0;
+ int len = strlen(t);
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ TTF_GlyphMetrics(font, t[i], NULL, NULL, NULL, &h, NULL);
+ if (h > hmax)
+ hmax = h;
+ }
+ *glyph_offset = hmax - TTF_FontAscent(font);
+ }
+ }
+#endif
+
+ return surf;
+}
+
+
+
+/*-----------------------------------------------------------*/
+/* Local functions, callable only within SDL_extras, divided */
+/* according with which text lib we are using: */
+/*-----------------------------------------------------------*/
+
+
+
+#ifdef HAVE_LIBSDL_PANGO
+/* Local functions when using SDL_Pango: */
+
+
+/* NOTE the scaling by 3/4 a few lines down represents a conversion from */
+/* the usual text dpi of 72 to the typical screen dpi of 96. It gives */
+/* font sizes fairly similar to a SDL_ttf font with the same numerical value. */
+static int Set_SDL_Pango_Font_Size(int size)
+{
+ /* static so we can "remember" values from previous time through: */
+ static int prev_pango_font_size;
+ static char prev_font_name[FONT_NAME_LENGTH];
+ /* Do nothing unless we need to change size or font: */
+ if ((size == prev_pango_font_size)
+ &&
+ (0 == strncmp(prev_font_name, Opts_FontName(), sizeof(prev_font_name))))
+ return 1;
+ else
+ {
+ char buf[64];
+
+ DEBUGMSG(debug_sdl, "Setting font size to %d\n", size);
+
+ if(context != NULL)
+ SDLPango_FreeContext(context);
+ context = NULL;
+ snprintf(buf, sizeof(buf), "%s %d", Opts_FontName(), (int)((size * 3)/4));
+ context = SDLPango_CreateContext_GivenFontDesc(buf);
+ }
+
+ if (!context)
+ return 0;
+ else
+ {
+ prev_pango_font_size = size;
+ strncpy(prev_font_name, Opts_FontName(), sizeof(prev_font_name));
+ return 1;
+ }
+}
+
+
+SDLPango_Matrix* SDL_Colour_to_SDLPango_Matrix(const SDL_Color *cl)
+{
+ int k = 0;
+ SDLPango_Matrix* colour = NULL;
+
+ if (!cl)
+ {
+ fprintf(stderr, "Invalid SDL_Color* arg\n");
+ return NULL;
+ }
+
+ colour = (SDLPango_Matrix*)malloc(sizeof(SDLPango_Matrix));
+
+ for(k = 0; k < 4; k++)
+ {
+ (*colour).m[0][k] = (*cl).r;
+ (*colour).m[1][k] = (*cl).g;
+ (*colour).m[2][k] = (*cl).b;
+ }
+ (*colour).m[3][0] = 0;
+ (*colour).m[3][1] = 255;
+ (*colour).m[3][2] = 0;
+ (*colour).m[3][3] = 0;
+
+ return colour;
+}
+
+#else
+/* Local functions when using SDL_ttf: */
+
+static void free_font_list(void)
+{
+ int i;
+ for(i = 0; i < MAX_FONT_SIZE; i++)
+ {
+ if(font_list[i])
+ {
+ TTF_CloseFont(font_list[i]);
+ font_list[i] = NULL;
+ }
+ }
+}
+
+/* FIXME - could combine this with load_font() below: */
+/* Loads and caches fonts in each size as they are requested: */
+/* We use the font size as an array index, keeping each size */
+/* font in memory once loaded until cleanup. */
+static TTF_Font* get_font(int size)
+{
+ static char prev_font_name[FONT_NAME_LENGTH];
+ if (size < 0)
+ {
+ fprintf(stderr, "Error - requested font size %d is negative\n", size);
+ return NULL;
+ }
+
+ if (size > MAX_FONT_SIZE)
+ {
+ fprintf(stderr, "Error - requested font size %d exceeds max = %d, resetting.\n",
+ size, MAX_FONT_SIZE);
+ size = MAX_FONT_SIZE;
+ }
+
+ /* If the font has changed, we need to wipe out the old ones: */
+ if (0 != strncmp(prev_font_name, Opts_FontName(),sizeof(prev_font_name)))
+ {
+ free_font_list();
+ strncpy(prev_font_name, Opts_FontName(), sizeof(prev_font_name));
+ }
+
+ if(font_list[size] == NULL)
+ font_list[size] = load_font(DEFAULT_FONT_NAME, size);
+ return font_list[size];
+}
+
+
+/* FIXME: I think we need to provide a single default font with the program data, */
+/* then more flexible code to try to locate or load system fonts. DSB */
+/* Returns ptr to loaded font if successful, NULL otherwise. */
+static TTF_Font* load_font(const char* font_name, int font_size)
+{
+ TTF_Font* f;
+ char fontfile[PATH_MAX];
+ sprintf(fontfile, "%s/fonts/%s", DATA_PREFIX, font_name);
+
+ f = TTF_OpenFont(fontfile, font_size);
+
+ /* HACK - better font searching needed! */
+ /* This should mean that font wasn't bundled into data path, which for */
+ /* now means we are using Debian, so grab from Debian installation loc: */
+ if (!f)
+ {
+ sprintf(fontfile, "/usr/share/fonts/truetype/ttf-sil-andika/AndikaDesRevG.ttf");
+ f = TTF_OpenFont(fontfile, font_size);
+ }
+
+
+ if (f)
+ {
+ DEBUGMSG(debug_sdl, "LoadFont(): %s loaded successfully\n\n", fontfile);
+ return f;
+ }
+ else
+ {
+ fprintf(stderr, "LoadFont(): %s NOT loaded successfully.\n", fontfile);
+ return NULL;
+ }
+}
+#endif
+
+#endif
Modified: branches/commonification/tux4kids-common/trunk/src/tux4kids-common.h
===================================================================
--- branches/commonification/tux4kids-common/trunk/src/tux4kids-common.h 2009-07-30 16:22:41 UTC (rev 1294)
+++ branches/commonification/tux4kids-common/trunk/src/tux4kids-common.h 2009-07-30 16:23:36 UTC (rev 1295)
@@ -1,15 +1,14 @@
-//
-// C Interface: SDL_extras
-//
-// Description: A few handy functions for using SDL graphics.
-//
-//
-// Author: David Bruce,,, <dbruce at tampabay.rr.com>, (C) 2007
-//
-// Copyright: See COPYING file that comes with this distribution
-// (briefly, GPL v3 or later).
-//
+/*
+ tux4kids-common
+ Library of common functions used in Tux4Kids games.
+
+ Part of "Tux4Kids" Project
+ http://www.tux4kids.com/
+
+ Copyright: See COPYING file that comes with this distribution.
+*/
+
#ifndef TUX4KIDS_COMMON_H
#define TUX4KIDS_COMMON_H
@@ -28,10 +27,11 @@
#endif
-/* FIXME get rid of as much global data as possible, esp. pointers */
+/* functions from t4k-main.c */
+void SetDebugMode(int dbg_flags);
+
+/* functions from tk4-sdl.c */
SDL_Surface* GetScreen();
-
-/* Non-text graphics functions: */
void DrawButton(SDL_Rect* target_rect, int radius, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
void DrawButtonOn(SDL_Surface* target, SDL_Rect* target_rect, int radius, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
SDL_Surface* CreateButton(int w, int h, int radius, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
Modified: branches/commonification/tuxmath/trunk/src/setup.c
===================================================================
--- branches/commonification/tuxmath/trunk/src/setup.c 2009-07-30 16:22:41 UTC (rev 1294)
+++ branches/commonification/tuxmath/trunk/src/setup.c 2009-07-30 16:23:36 UTC (rev 1295)
@@ -118,6 +118,10 @@
initialize_options();
/* Command-line code now in own function: */
handle_command_args(argc, argv);
+
+#ifdef HAVE_LIBT4KCOMMON
+ SetDebugMode(debug_status);
+#endif
/* SDL setup in own function:*/
initialize_SDL();
/* Read image and sound files: */
More information about the Tux4kids-commits
mailing list