[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