Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2005:
[Freeciv-Dev] (PR#12656) ftwl api reorganization
Home

[Freeciv-Dev] (PR#12656) ftwl api reorganization

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#12656) ftwl api reorganization
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Fri, 25 Mar 2005 13:02:57 -0800
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12656 >

This patch reorganizes the ftwl file tree a bit.

be_common_24_sprite.c is removed.

be_common_24.c|h now only contains struct image manipulation code, shared
by all code.

be_common_pixels.c|h now contains pixel/software manipulation code, shared
by SDL and X11 pixel based code.

be_sdl_pixels.c now contains pixel/software manipulation code for SDL,
while be_sdl.c only contains general SDL code, such as events.

Stub code added to configure.ac and Makefile.am for opengl support. This
will be added in the files be_sdl_opengl.c and be_common_opengl.c, and for
the ordinary version (SDL+OpenGL) will also use be_sdl.c. Hopefully this
wil be the only version, but at least it is left open that there may be
more/others.

  - Per

/**********************************************************************
 Freeciv - Copyright (C) 2004 - The Freeciv Project
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
***********************************************************************/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <assert.h>
#include <errno.h>
#include <stdio.h>

#include <SDL/SDL.h>

#include "back_end.h"
#include "be_common_24.h"
#include "be_common_pixels.h"

#include "shared.h"

#include "fcintl.h"
#include "log.h"
#include "mem.h"

static SDL_Surface *screen;

/* SDL interprets each pixel as a 32-bit number, so our masks must depend
 * on the endianness (byte order) of the machine */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
static Uint32 rmask = 0xff000000;
static Uint32 gmask = 0x00ff0000;
static Uint32 bmask = 0x0000ff00;
static Uint32 amask = 0x000000ff;
#else
static Uint32 rmask = 0x000000ff;
static Uint32 gmask = 0x0000ff00;
static Uint32 bmask = 0x00ff0000;
static Uint32 amask = 0xff000000;
#endif

/*************************************************************************
  Initialize video mode and SDL.
*************************************************************************/
void be_init(const struct ct_size *screen_size, bool fullscreen)
{
  Uint32 flags = SDL_SWSURFACE | (fullscreen ? SDL_FULLSCREEN : 0)
                 | SDL_ANYFORMAT;

  char device[20];

  /* auto center new windows in X enviroment */
  putenv((char *) "SDL_VIDEO_CENTERED=yes");

  if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
    freelog(LOG_FATAL, _("Unable to initialize SDL library: %s"),
            SDL_GetError());
    exit(EXIT_FAILURE);
  }
  atexit(SDL_Quit);

  freelog(LOG_NORMAL, "Using Video Output: %s",
          SDL_VideoDriverName(device, sizeof(device)));
  {
    const SDL_VideoInfo *info = SDL_GetVideoInfo();
    freelog(LOG_NORMAL, "Video memory of driver: %dkb", info->video_mem);
    freelog(LOG_NORMAL, "Preferred depth: %d bits per pixel",
            info->vfmt->BitsPerPixel);
  }

#if 0
  {
    SDL_Rect **modes;
    int i;

    modes = SDL_ListModes(NULL, flags);
    if (modes == (SDL_Rect **) 0) {
      printf("No modes available!\n");
      exit(-1);
    }
    if (modes == (SDL_Rect **) - 1) {
      printf("All resolutions available.\n");
    } else {
      /* Print valid modes */
      printf("Available Modes\n");
      for (i = 0; modes[i]; ++i)
        printf("  %d x %d\n", modes[i]->w, modes[i]->h);
    }
  }
#endif

  screen =
      SDL_SetVideoMode(screen_size->width, screen_size->height, 32, flags);
  if (screen == NULL) {
    freelog(LOG_FATAL, _("Can't set video mode: %s"), SDL_GetError());
    exit(1);
  }

  freelog(LOG_NORMAL, "Got a screen with size (%dx%d) and %d bits per pixel",
          screen->w, screen->h, screen->format->BitsPerPixel);
  freelog(LOG_NORMAL, "  format: red=0x%x green=0x%x blue=0x%x mask=0x%x",
          screen->format->Rmask, screen->format->Gmask,
          screen->format->Bmask, screen->format->Amask);
  freelog(LOG_NORMAL, "  format: bits-per-pixel=%d bytes-per-pixel=%d",
          screen->format->BitsPerPixel, screen->format->BytesPerPixel);
  SDL_EnableUNICODE(1);
  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
#if 0
  SDL_EventState(SDL_KEYUP, SDL_IGNORE);
  SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
#endif
}

/*************************************************************************
  Copy our osda to the screen.  No alpha-blending here.
*************************************************************************/
void be_copy_osda_to_screen(struct osda *src)
{
  SDL_Surface *buf;

  buf = SDL_CreateRGBSurfaceFrom(src->image->data, src->image->width,
                                 src->image->height, 32, src->image->pitch,
                                 rmask, gmask, bmask, amask);
  SDL_BlitSurface(buf, NULL, screen, NULL);
  SDL_Flip(screen);
  SDL_FreeSurface(buf);
}

/*************************************************************************
  ...
*************************************************************************/
void be_screen_get_size(struct ct_size *size)
{
  size->width = screen->w;
  size->height = screen->h;
}
/**********************************************************************
 Freeciv - Copyright (C) 2005 - The Freeciv Project
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
***********************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <assert.h>
#include <stdio.h>

#include "log.h"
#include "mem.h"
#include "support.h"

#include "back_end.h"
#include "be_common_pixels.h"

#include <ft2build.h>
#include FT_FREETYPE_H

/*************************************************************************
  Set a pixel in a given buffer (dest) to a given color (color).
*************************************************************************/
static void set_color(be_color color, unsigned char *dest)
{
  dest[0] = ((color >> 24) & 0xff);
  dest[1] = ((color >> 16) & 0xff);
  dest[2] = ((color >> 8) & 0xff);
  dest[3] = ((color) & 0xff);
}

/*************************************************************************
  Blit one osda onto another, using transparency value given on all 
  pixels that have alpha mask set. dest_pos and src_pos can be NULL.
*************************************************************************/
void be_copy_osda_to_osda(struct osda *dest,
                          struct osda *src,
                          const struct ct_size *size,
                          const struct ct_point *dest_pos,
                          const struct ct_point *src_pos)
{
  struct ct_point tmp_pos = { 0, 0 };

  if (!src_pos) {
    src_pos = &tmp_pos;
  }

  if (!dest_pos) {
    dest_pos = &tmp_pos;
  }

  if (!ct_size_empty(size)) {
    image_copy(dest->image, src->image, size, dest_pos, src_pos);
  }
}

/*************************************************************************
  Draw the given bitmap (ie a 1bpp pixmap) on the given osda in the given
  color and at the given position.
*************************************************************************/
void be_draw_bitmap(struct osda *target, be_color color,
                    const struct ct_point *position,
                    struct FT_Bitmap_ *bitmap)
{
  if (bitmap->pixel_mode == ft_pixel_mode_mono) {
    draw_mono_bitmap(target->image, color, position, bitmap);
  } else if (bitmap->pixel_mode == ft_pixel_mode_grays) {
    assert(bitmap->num_grays == 256);
    draw_alpha_bitmap(target->image, color, position, bitmap);
  } else {
    assert(0);
  }
}

/*************************************************************************
  Allocate and initialize an osda (off-screen drawing area).
*************************************************************************/
struct osda *be_create_osda(int width, int height)
{
  struct osda *result = fc_malloc(sizeof(*result));

  result->image = image_create(width, height);
  result->magic = 11223344;

  return result;
}

/*************************************************************************
  Free an allocated osda.
*************************************************************************/
void be_free_osda(struct osda *osda)
{
    /*
  assert(osda->magic == 11223344);
  osda->magic = 0;
  image_destroy(osda->image);
  free(osda);
    */
}


/* ========== drawing ================ */


/*************************************************************************
  Draw an empty rectangle in given osda with given drawing type.
*************************************************************************/
void be_draw_rectangle(struct osda *target, const struct ct_rect *spec,
                       int line_width, be_color color)
{
  int i;

  for (i = 0; i < line_width; i++) {
    struct ct_point nw = { spec->x + i, spec->y + i }, ne = nw, sw = ne, se =
        nw;

    ne.x += spec->width  - 2 * i;
    se.x += spec->width  - 2 * i;

    sw.y += spec->height  - 2 * i;
    se.y += spec->height  - 2 * i;

    be_draw_line(target, &nw, &ne, 1, FALSE, color);
    be_draw_line(target, &sw, &se, 1, FALSE, color);
    be_draw_line(target, &nw, &sw, 1, FALSE, color);
    be_draw_line(target, &ne, &se, 1, FALSE, color);
  }
}

/*************************************************************************
  Draw a vertical line (only).
*************************************************************************/
static void draw_vline(struct image *image, unsigned char *src,
                       int x, int y0, int y1, int line_width, bool dashed)
{
  int y;

  if (dashed) {
    for (y = y0; y < y1; y++) {
      if (y & (1 << 3)) {
        IMAGE_CHECK(image, x, y);
        memcpy(IMAGE_GET_ADDRESS(image, x, y), src, 4);
      }
    }
  } else {
    for (y = y0; y < y1; y++) {
      IMAGE_CHECK(image, x, y);
      memcpy(IMAGE_GET_ADDRESS(image, x, y), src, 4);
    }
  }
}

/*************************************************************************
  Draw a horisontal line (only).
*************************************************************************/
static void draw_hline(struct image *image, unsigned char *src,
                       int y, int x0, int x1, int line_width, bool dashed)
{
  int x;

  if (dashed) {
    for (x = x0; x < x1; x++) {
      if (x & (1 << 3)) {
        IMAGE_CHECK(image, x, y);
        memcpy(IMAGE_GET_ADDRESS(image, x, y), src, 4);
      }
    }
  } else {
    for (x = x0; x < x1; x++) {
      IMAGE_CHECK(image, x, y);
      memcpy(IMAGE_GET_ADDRESS(image, x, y), src, 4);
    }
  }
}

/*************************************************************************
  Draw any line.
*************************************************************************/
static void draw_line(struct image *image, unsigned char *src,
                      int x1, int y1, int x2, int y2, int line_width,
                      bool dashed)
{
  int dx = abs(x2 - x1);
  int dy = abs(y2 - y1);
  int xinc1, xinc2, yinc1, yinc2;
  int den, num, numadd, numpixels;
  int x, y;
  int curpixel;

  xinc1 = xinc2 = (x2 >= x1) ? 1 : -1;
  yinc1 = yinc2 = (y2 >= y1) ? 1 : -1;

  if (dx >= dy) {
    xinc1 = 0;
    yinc2 = 0;
    den = dx;
    num = dx / 2;
    numadd = dy;
    numpixels = dx;
  } else {
    xinc2 = 0;
    yinc1 = 0;
    den = dy;
    num = dy / 2;
    numadd = dx;
    numpixels = dy;
  }

  x = x1;
  y = y1;

  for (curpixel = 0; curpixel <= numpixels; curpixel++) {
    struct ct_point pos = { x, y };

    if (ct_point_in_rect(&pos, &image->full_rect)) {
      IMAGE_CHECK(image, x, y);
      memcpy(IMAGE_GET_ADDRESS(image, x, y), src, 4);
    }
    num += numadd;
    if (num >= den) {
      num -= den;
      x += xinc1;
      y += yinc1;
    }
    x += xinc2;
    y += yinc2;
  }
}

/*************************************************************************
  Draw a line in given osda with given drawing type.
*************************************************************************/
void be_draw_line(struct osda *target,
                  const struct ct_point *start,
                  const struct ct_point *end,
                  int line_width, bool dashed, be_color color)
{
  unsigned char tmp[4];
  struct ct_rect bounds =
      { 0, 0, target->image->width, target->image->height };

  set_color(color, tmp);

  if (start->x == end->x) {
    struct ct_point start2 = *start;
    struct ct_point end2 = *end;

    ct_clip_point(&start2, &bounds);
    ct_clip_point(&end2, &bounds);

    draw_vline(target->image, tmp, start2.x, MIN(start2.y, end2.y),
               MAX(start2.y, end2.y), line_width, dashed);
  } else if (start->y == end->y) {
    struct ct_point start2 = *start;
    struct ct_point end2 = *end;

    ct_clip_point(&start2, &bounds);
    ct_clip_point(&end2, &bounds);

    draw_hline(target->image, tmp, start2.y, MIN(start2.x, end2.x),
               MAX(start2.x, end2.x), line_width, dashed);
  } else {
    draw_line(target->image, tmp, start->x, start->y, end->x, end->y,
              line_width, dashed);
  }
}

/*************************************************************************
  Fill a square region in given osda with given colour and drawing type.
*************************************************************************/
void be_draw_region(struct osda *target, 
                    const struct ct_rect *region, be_color color)
{
  unsigned char tmp[4];
  int x, y;
  struct ct_rect actual = *region,
      bounds = { 0, 0, target->image->width, target->image->height };
  int width;

  set_color(color, tmp);

  ct_clip_rect(&actual, &bounds);

  width = actual.width;
  for (y = actual.y; y < actual.y + actual.height; y++) {
    unsigned char *pdest = IMAGE_GET_ADDRESS(target->image, actual.x, y);
    IMAGE_CHECK(target->image, actual.x, y);

    for (x = 0; x < width; x++) {
      memcpy(pdest, tmp, 4);
      pdest += 4;
    }
  }
}

/*************************************************************************
  Return TRUE iff pixel in given osda is transparent or out of bounds.
*************************************************************************/
bool be_is_transparent_pixel(struct osda *osda, const struct ct_point *pos)
{
  struct ct_rect bounds = { 0, 0, osda->image->width, osda->image->height };
  if (!ct_point_in_rect(pos, &bounds)) {
    return FALSE;
  }

  IMAGE_CHECK(osda->image, pos->x, pos->y);
  return IMAGE_GET_ADDRESS(osda->image, pos->x, pos->y)[3] != MAX_OPACITY;
}

/*************************************************************************
  size, dest_pos and src_pos can be NULL
*************************************************************************/
void be_draw_sprite(struct osda *target, 
                    const struct Sprite *sprite,
                    const struct ct_size *size,
                    const struct ct_point *dest_pos,
                    const struct ct_point *src_pos)
{
  struct ct_size tmp_size;
  struct ct_point tmp_pos = { 0, 0 };

  if (!src_pos) {
    src_pos = &tmp_pos;
  }

  if (!dest_pos) {
    dest_pos = &tmp_pos;
  }

  if (!size) {
    tmp_size.width = sprite->image->width;
    tmp_size.height = sprite->image->height;
    size = &tmp_size;
  }

  image_copy(target->image, sprite->image, size, dest_pos, src_pos);
}

/*************************************************************************
  Write an image buffer to file.
*************************************************************************/
void be_write_osda_to_file(struct osda *osda, const char *filename)
{
  FILE *file;
  unsigned char *line_buffer = malloc(3 * osda->image->width), *pout;
  int x, y;

  file = fopen(filename, "w");

  fprintf(file, "P6\n");
  fprintf(file, "%d %d\n", osda->image->width, osda->image->height);
  fprintf(file, "255\n");

  for (y = 0; y < osda->image->height; y++) {
    pout = line_buffer;

    for (x = 0; x < osda->image->width; x++) {
      IMAGE_CHECK(osda->image, x, y);
      memcpy(pout, IMAGE_GET_ADDRESS(osda->image, x, y), 3);
      pout += 3;
    }
    fwrite(line_buffer, 3 * osda->image->width, 1, file);
  }
  free(line_buffer);
  fclose(file);
}

/*************************************************************************
  Put size of osda into size.
*************************************************************************/
void be_osda_get_size(struct ct_size *size, const struct osda *osda)
{
  size->width = osda->image->width;
  size->height = osda->image->height;
}

/*************************************************************************
  ...
*************************************************************************/
void be_multiply_alphas(struct Sprite *dest, const struct Sprite *src,
                        const struct ct_point *src_pos)
{
  image_multiply_alphas(dest->image, src->image, src_pos);
}

/*************************************************************************
  ...
*************************************************************************/
static struct Sprite *ctor_sprite(struct image *image)
{
  struct Sprite *result = fc_malloc(sizeof(struct Sprite));
  result->image = image;
  return result;
}

/*************************************************************************
  ...
*************************************************************************/
void be_free_sprite(struct Sprite *sprite)
{
  free(sprite);
}

/*************************************************************************
  ...
*************************************************************************/
struct Sprite *be_crop_sprite(struct Sprite *source,
                              int x, int y, int width, int height)
{
  struct Sprite *result = ctor_sprite(image_create(width, height));
  struct ct_rect region = { x, y, width, height };

  ct_clip_rect(&region, &source->image->full_rect);

  image_copy_full(source->image, result->image, &region);

  return result;
}

/*************************************************************************
  ...
*************************************************************************/
struct Sprite *be_load_gfxfile(const char *filename)
{
  struct image *gfx = image_load_gfxfile(filename);

  return ctor_sprite(gfx);
}

/*************************************************************************
  ...
*************************************************************************/
void be_sprite_get_size(struct ct_size *size, const struct Sprite *sprite)
{
  size->width = sprite->image->width;
  size->height = sprite->image->height;
}
Index: configure.ac
===================================================================
RCS file: /home/freeciv/CVS/freeciv/configure.ac,v
retrieving revision 1.98
diff -u -r1.98 configure.ac
--- configure.ac        22 Mar 2005 20:04:42 -0000      1.98
+++ configure.ac        25 Mar 2005 20:55:56 -0000
@@ -80,11 +80,12 @@
 
 dnl You MUST build ftwl to use the ftwl client
 AC_ARG_ENABLE(ftwl,
-[  --enable-ftwl[=no/x11/sdl]
+[  --enable-ftwl[=no/x11/sdl/opengl]
                           compile ftwl [default=no]],
 [case "${enableval}" in
   x11)   ftwl=x11 ;;
   sdl)    ftwl=sdl ;;
+  opengl) ftwl=opengl ;;
   *)     AC_MSG_ERROR(bad value ${enableval} for --enable-ftwl) ;;
 esac], [ftwl=no])
 AM_CONDITIONAL(FTWL, test x$ftwl != xno)
@@ -350,6 +351,11 @@
      FTWL_LIBS=`sdl-config --libs`" -lpng "`freetype-config --libs`
 fi
 
+if test "$ftwl" = opengl ; then
+     FTWL_CFLAGS=`sdl-config --cflags`" "`freetype-config --cflags`
+     FTWL_LIBS=`sdl-config --libs`" -lpng "`freetype-config --libs -lGL -lGLU`
+fi
+
 dnl Check and choose clients
 if test x$client != xno; then
 
@@ -443,6 +449,7 @@
 AM_CONDITIONAL(FTWL, test "$ftwl" != "no")
 AM_CONDITIONAL(FTWL_X11, test "$ftwl" = "x11")
 AM_CONDITIONAL(FTWL_SDL, test "$ftwl" = "sdl")
+AM_CONDITIONAL(FTWL_OPENGL, test "$ftwl" = "opengl")
 
 dnl Checks for additional server libraries:
 if test x$server = xtrue; then
Index: utility/ftwl/Makefile.am
===================================================================
RCS file: /home/freeciv/CVS/freeciv/utility/ftwl/Makefile.am,v
retrieving revision 1.5
diff -u -r1.5 Makefile.am
--- utility/ftwl/Makefile.am    24 Aug 2004 06:51:43 -0000      1.5
+++ utility/ftwl/Makefile.am    25 Mar 2005 20:55:57 -0000
@@ -15,8 +15,20 @@
        be_common_24.h          \
        be_common_24_sprite.c
 
-ALL_BACKEND_X11_FILES=$(BACKEND_COMMON_FILES) be_x11_ximage.c
-ALL_BACKEND_SDL_FILES=$(BACKEND_COMMON_FILES) be_sdl.c
+ALL_BACKEND_X11_FILES=         \
+       $(BACKEND_COMMON_FILES) \
+       be_x11_ximage.c         \
+       be_common_pixels.c
+ALL_BACKEND_SDL_FILES=         \
+       $(BACKEND_COMMON_FILES) \
+       be_sdl.c                \
+       be_common_pixels.c      \
+       be_sdl_pixels.c
+ALL_BACKEND_SDL_OPENGL_FILES=  \
+       $(BACKEND_COMMON_FILES) \
+       be_common_opengl.c      \
+       be_sdl_opengl.c         \
+       be_sdl.c
 ALL_OTHER_FILES=       \
        back_end.h      \
        common_types.c  \
Index: utility/ftwl/be_common_24.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/utility/ftwl/be_common_24.c,v
retrieving revision 1.10
diff -u -r1.10 be_common_24.c
--- utility/ftwl/be_common_24.c 22 Mar 2005 21:40:54 -0000      1.10
+++ utility/ftwl/be_common_24.c 25 Mar 2005 20:55:57 -0000
@@ -1,5 +1,5 @@
 /**********************************************************************
- Freeciv - Copyright (C) 2004 - The Freeciv Project
+ Freeciv - Copyright (C) 2005 - The Freeciv Project
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
@@ -17,7 +17,9 @@
 
 #include <assert.h>
 #include <stdio.h>
+#include <png.h>
 
+#include "fcintl.h"
 #include "log.h"
 #include "mem.h"
 #include "support.h"
@@ -168,11 +170,9 @@
   Blit one image onto another, using transparency value given on all
   pixels that have alpha mask set.
 *************************************************************************/
-static void image_copy(struct image *dest,
-                      struct image *src,
-                      const struct ct_size *size,
-                      const struct ct_point *dest_pos,
-                      const struct ct_point *src_pos)
+void image_copy(struct image *dest, struct image *src,
+                const struct ct_size *size, const struct ct_point *dest_pos,
+                const struct ct_point *src_pos)
 {
   struct ct_point real_src_pos = *src_pos, real_dest_pos = *dest_pos;
   struct ct_size real_size = *size;
@@ -207,37 +207,11 @@
 }
 
 /*************************************************************************
-  Blit one osda onto another, using transparency value given on all 
-  pixels that have alpha mask set. dest_pos and src_pos can be NULL.
-*************************************************************************/
-void be_copy_osda_to_osda(struct osda *dest,
-                         struct osda *src,
-                         const struct ct_size *size,
-                         const struct ct_point *dest_pos,
-                         const struct ct_point *src_pos)
-{
-  struct ct_point tmp_pos = { 0, 0 };
-
-  if (!src_pos) {
-    src_pos = &tmp_pos;
-  }
-
-  if (!dest_pos) {
-    dest_pos = &tmp_pos;
-  }
-
-  if (!ct_size_empty(size)) {
-    image_copy(dest->image, src->image, size, dest_pos, src_pos);
-  }
-}
-
-/*************************************************************************
   See be_draw_bitmap() below.
 *************************************************************************/
-static void draw_mono_bitmap(struct image *image,
-                            be_color color,
-                            const struct ct_point *position,
-                            struct FT_Bitmap_ *bitmap)
+void draw_mono_bitmap(struct image *image, be_color color,
+                      const struct ct_point *position, 
+                      struct FT_Bitmap_ *bitmap)
 {
   int x, y;
   unsigned char *pbitmap = (unsigned char *) bitmap->buffer;
@@ -267,12 +241,12 @@
 }
 
 /*************************************************************************
-  See be_draw_bitmap() below.
+  Draw the given bitmap (ie a 1bpp pixmap) in the given color and 
+  position.
 *************************************************************************/
-static void draw_alpha_bitmap(struct image *image,
-                             be_color color_,
-                             const struct ct_point *position,
-                             struct FT_Bitmap_ *bitmap)
+void draw_alpha_bitmap(struct image *image, be_color color_,
+                       const struct ct_point *position,
+                       struct FT_Bitmap_ *bitmap)
 {
   int x, y;
   unsigned char color[4];
@@ -301,50 +275,6 @@
 }
 
 /*************************************************************************
-  Draw the given bitmap (ie a 1bpp pixmap) on the given osda in the given
-  color and at the givne position, using the given drawing type.
-*************************************************************************/
-void be_draw_bitmap(struct osda *target, be_color color,
-                   const struct ct_point *position,
-                   struct FT_Bitmap_ *bitmap)
-{
-  if (bitmap->pixel_mode == ft_pixel_mode_mono) {
-    draw_mono_bitmap(target->image, color, position, bitmap);
-  } else if (bitmap->pixel_mode == ft_pixel_mode_grays) {
-    assert(bitmap->num_grays == 256);
-    draw_alpha_bitmap(target->image, color, position, bitmap);
-  } else {
-    assert(0);
-  }
-}
-
-/*************************************************************************
-  Allocate and initialize an osda (off-screen drawing area).
-*************************************************************************/
-struct osda *be_create_osda(int width, int height)
-{
-  struct osda *result = fc_malloc(sizeof(*result));
-
-  result->image = image_create(width, height);
-  result->magic = 11223344;
-
-  return result;
-}
-
-/*************************************************************************
-  Free an allocated osda.
-*************************************************************************/
-void be_free_osda(struct osda *osda)
-{
-    /*
-  assert(osda->magic == 11223344);
-  osda->magic = 0;
-  image_destroy(osda->image);
-  free(osda);
-    */
-}
-
-/*************************************************************************
   Set the alpha mask of pixels in a given region of an image.
 *************************************************************************/
 void image_set_alpha(const struct image *image, const struct ct_rect *rect,
@@ -360,260 +290,17 @@
   }
 }
 
-
-/* ========== drawing ================ */
-
-
-/*************************************************************************
-  Draw an empty rectangle in given osda with given drawing type.
-*************************************************************************/
-void be_draw_rectangle(struct osda *target, const struct ct_rect *spec,
-                      int line_width, be_color color)
-{
-  int i;
-
-  for (i = 0; i < line_width; i++) {
-    struct ct_point nw = { spec->x + i, spec->y + i }, ne = nw, sw = ne, se =
-       nw;
-
-    ne.x += spec->width  - 2 * i;
-    se.x += spec->width  - 2 * i;
-
-    sw.y += spec->height  - 2 * i;
-    se.y += spec->height  - 2 * i;
-
-    be_draw_line(target, &nw, &ne, 1, FALSE, color);
-    be_draw_line(target, &sw, &se, 1, FALSE, color);
-    be_draw_line(target, &nw, &sw, 1, FALSE, color);
-    be_draw_line(target, &ne, &se, 1, FALSE, color);
-  }
-}
-
-/*************************************************************************
-  Draw a vertical line (only).
-*************************************************************************/
-static void draw_vline(struct image *image, unsigned char *src,
-                      int x, int y0, int y1, int line_width, bool dashed)
-{
-  int y;
-
-  if (dashed) {
-    for (y = y0; y < y1; y++) {
-      if (y & (1 << 3)) {
-       IMAGE_CHECK(image, x, y);
-       memcpy(IMAGE_GET_ADDRESS(image, x, y), src, 4);
-      }
-    }
-  } else {
-    for (y = y0; y < y1; y++) {
-      IMAGE_CHECK(image, x, y);
-      memcpy(IMAGE_GET_ADDRESS(image, x, y), src, 4);
-    }
-  }
-}
-
-/*************************************************************************
-  Draw a horisontal line (only).
-*************************************************************************/
-static void draw_hline(struct image *image, unsigned char *src,
-                      int y, int x0, int x1, int line_width, bool dashed)
-{
-  int x;
-
-  if (dashed) {
-    for (x = x0; x < x1; x++) {
-      if (x & (1 << 3)) {
-       IMAGE_CHECK(image, x, y);
-       memcpy(IMAGE_GET_ADDRESS(image, x, y), src, 4);
-      }
-    }
-  } else {
-    for (x = x0; x < x1; x++) {
-      IMAGE_CHECK(image, x, y);
-      memcpy(IMAGE_GET_ADDRESS(image, x, y), src, 4);
-    }
-  }
-}
-
-/*************************************************************************
-  Draw any line.
-*************************************************************************/
-static void draw_line(struct image *image, unsigned char *src,
-                     int x1, int y1, int x2, int y2, int line_width,
-                     bool dashed)
-{
-  int dx = abs(x2 - x1);
-  int dy = abs(y2 - y1);
-  int xinc1, xinc2, yinc1, yinc2;
-  int den, num, numadd, numpixels;
-  int x, y;
-  int curpixel;
-
-  xinc1 = xinc2 = (x2 >= x1) ? 1 : -1;
-  yinc1 = yinc2 = (y2 >= y1) ? 1 : -1;
-
-  if (dx >= dy) {
-    xinc1 = 0;
-    yinc2 = 0;
-    den = dx;
-    num = dx / 2;
-    numadd = dy;
-    numpixels = dx;
-  } else {
-    xinc2 = 0;
-    yinc1 = 0;
-    den = dy;
-    num = dy / 2;
-    numadd = dx;
-    numpixels = dy;
-  }
-
-  x = x1;
-  y = y1;
-
-  for (curpixel = 0; curpixel <= numpixels; curpixel++) {
-    struct ct_point pos = { x, y };
-
-    if (ct_point_in_rect(&pos, &image->full_rect)) {
-      IMAGE_CHECK(image, x, y);
-      memcpy(IMAGE_GET_ADDRESS(image, x, y), src, 4);
-    }
-    num += numadd;
-    if (num >= den) {
-      num -= den;
-      x += xinc1;
-      y += yinc1;
-    }
-    x += xinc2;
-    y += yinc2;
-  }
-}
-
-/*************************************************************************
-  Draw a line in given osda with given drawing type.
-*************************************************************************/
-void be_draw_line(struct osda *target,
-                 const struct ct_point *start,
-                 const struct ct_point *end,
-                 int line_width, bool dashed, be_color color)
-{
-  unsigned char tmp[4];
-  struct ct_rect bounds =
-      { 0, 0, target->image->width, target->image->height };
-
-  set_color(color, tmp);
-
-  if (start->x == end->x) {
-    struct ct_point start2 = *start;
-    struct ct_point end2 = *end;
-
-    ct_clip_point(&start2, &bounds);
-    ct_clip_point(&end2, &bounds);
-
-    draw_vline(target->image, tmp, start2.x, MIN(start2.y, end2.y),
-              MAX(start2.y, end2.y), line_width, dashed);
-  } else if (start->y == end->y) {
-    struct ct_point start2 = *start;
-    struct ct_point end2 = *end;
-
-    ct_clip_point(&start2, &bounds);
-    ct_clip_point(&end2, &bounds);
-
-    draw_hline(target->image, tmp, start2.y, MIN(start2.x, end2.x),
-              MAX(start2.x, end2.x), line_width, dashed);
-  } else {
-    draw_line(target->image, tmp, start->x, start->y, end->x, end->y,
-             line_width, dashed);
-  }
-}
-
-/*************************************************************************
-  Fill a square region in given osda with given colour and drawing type.
-*************************************************************************/
-void be_draw_region(struct osda *target, 
-                   const struct ct_rect *region, be_color color)
-{
-  unsigned char tmp[4];
-  int x, y;
-  struct ct_rect actual = *region,
-      bounds = { 0, 0, target->image->width, target->image->height };
-  int width;
-
-  set_color(color, tmp);
-
-  ct_clip_rect(&actual, &bounds);
-
-  width = actual.width;
-  for (y = actual.y; y < actual.y + actual.height; y++) {
-    unsigned char *pdest = IMAGE_GET_ADDRESS(target->image, actual.x, y);
-    IMAGE_CHECK(target->image, actual.x, y);
-
-    for (x = 0; x < width; x++) {
-      memcpy(pdest, tmp, 4);
-      pdest += 4;
-    }
-  }
-}
-
-/*************************************************************************
-  Return TRUE iff pixel in given osda is transparent or out of bounds.
-*************************************************************************/
-bool be_is_transparent_pixel(struct osda *osda, const struct ct_point *pos)
-{
-  struct ct_rect bounds = { 0, 0, osda->image->width, osda->image->height };
-  if (!ct_point_in_rect(pos, &bounds)) {
-    return FALSE;
-  }
-
-  IMAGE_CHECK(osda->image, pos->x, pos->y);
-  return IMAGE_GET_ADDRESS(osda->image, pos->x, pos->y)[3] != MAX_OPACITY;
-}
-
-/*************************************************************************
-  size, dest_pos and src_pos can be NULL
-*************************************************************************/
-void be_draw_sprite(struct osda *target, 
-                   const struct Sprite *sprite,
-                   const struct ct_size *size,
-                   const struct ct_point *dest_pos,
-                   const struct ct_point *src_pos)
-{
-  struct ct_size tmp_size;
-  struct ct_point tmp_pos = { 0, 0 };
-
-  if (!src_pos) {
-    src_pos = &tmp_pos;
-  }
-
-  if (!dest_pos) {
-    dest_pos = &tmp_pos;
-  }
-
-  if (!size) {
-    tmp_size.width = sprite->image->width;
-    tmp_size.height = sprite->image->height;
-    size = &tmp_size;
-  }
-
-  image_copy(target->image, sprite->image, size, dest_pos, src_pos);
-}
-
 /*************************************************************************
   Perform 
      dest_alpha = (dest_alpha * src_alpha)/256
 *************************************************************************/
-void be_multiply_alphas(struct Sprite *dest_sprite,
-                       const struct Sprite *src_sprite,
-                       const struct ct_point *src_pos)
+void image_multiply_alphas(struct image *dest, const struct image *src,
+                          const struct ct_point *src_pos)
 {
-  const struct image *src = src_sprite->image;
-  struct image *dest = dest_sprite->image;
-
   struct ct_point real_src_pos = *src_pos, real_dest_pos = { 0, 0 };
   struct ct_size real_size = { dest->width, dest->height };
 
-  clip_two_regions(dest_sprite->image, src, &real_size, &real_dest_pos,
-                  &real_src_pos);
+  clip_two_regions(dest, src, &real_size, &real_dest_pos, &real_src_pos);
   {
     int x, y;
 
@@ -634,35 +321,6 @@
 }
 
 /*************************************************************************
-  Write an image buffer to file.
-*************************************************************************/
-void be_write_osda_to_file(struct osda *osda, const char *filename)
-{
-  FILE *file;
-  unsigned char *line_buffer = malloc(3 * osda->image->width), *pout;
-  int x, y;
-
-  file = fopen(filename, "w");
-
-  fprintf(file, "P6\n");
-  fprintf(file, "%d %d\n", osda->image->width, osda->image->height);
-  fprintf(file, "255\n");
-
-  for (y = 0; y < osda->image->height; y++) {
-    pout = line_buffer;
-
-    for (x = 0; x < osda->image->width; x++) {
-      IMAGE_CHECK(osda->image, x, y);
-      memcpy(pout, IMAGE_GET_ADDRESS(osda->image, x, y), 3);
-      pout += 3;
-    }
-    fwrite(line_buffer, 3 * osda->image->width, 1, file);
-  }
-  free(line_buffer);
-  fclose(file);
-}
-
-/*************************************************************************
   Copy image buffer src to dest without doing any alpha-blending.
 *************************************************************************/
 void image_copy_full(struct image *src, struct image *dest,
@@ -712,10 +370,105 @@
 }
 
 /*************************************************************************
-  Put size of osda into size.
+  ...
 *************************************************************************/
-void be_osda_get_size(struct ct_size *size, const struct osda *osda)
+struct image *image_load_gfxfile(const char *filename)
 {
-  size->width = osda->image->width;
-  size->height = osda->image->height;
+  png_structp pngp;
+  png_infop infop;
+  png_int_32 width, height, x, y;
+  FILE *fp;
+  struct image *xi;
+
+  fp = fopen(filename, "rb");
+  if (!fp) {
+    freelog(LOG_FATAL, _("Failed reading PNG file: %s"), filename);
+    exit(EXIT_FAILURE);
+  }
+
+  pngp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+  if (!pngp) {
+    freelog(LOG_FATAL, _("Failed creating PNG struct"));
+    exit(EXIT_FAILURE);
+  }
+
+  infop = png_create_info_struct(pngp);
+  if (!infop) {
+    freelog(LOG_FATAL, _("Failed creating PNG struct"));
+    exit(EXIT_FAILURE);
+  }
+  
+  if (setjmp(pngp->jmpbuf)) {
+    freelog(LOG_FATAL, _("Failed while reading PNG file: %s"), filename);
+    exit(EXIT_FAILURE);
+  }
+
+  png_init_io(pngp, fp);
+  png_read_info(pngp, infop);
+
+  width = png_get_image_width(pngp, infop);
+  height = png_get_image_height(pngp, infop);
+
+  freelog(LOG_DEBUG, "reading '%s' (%ldx%ld) bit depth=%d color_type=%d",
+         filename, width, height, png_get_bit_depth(pngp, infop),
+         png_get_color_type(pngp, infop));
+
+  if (png_get_color_type(pngp,infop) == PNG_COLOR_TYPE_PALETTE) {
+    png_set_palette_to_rgb(pngp);
+  }
+
+  if (png_get_valid(pngp, infop, PNG_INFO_tRNS)) {
+    png_set_tRNS_to_alpha(pngp);
+  }
+
+  if (png_get_bit_depth(pngp,infop) == 16) {
+    png_set_strip_16(pngp);
+  }
+
+  if (png_get_bit_depth(pngp,infop) < 8) {
+    png_set_packing(pngp);
+  }
+
+  /* Add an alpha channel for RGB images */
+  if ((png_get_color_type(pngp, infop) & PNG_COLOR_MASK_ALPHA) == 0) {
+    png_set_filler(pngp, 0xff, PNG_FILLER_AFTER);
+  }
+
+  xi = image_create(width, height);
+
+  png_read_update_info(pngp, infop);
+
+  {
+    png_bytep pb;
+    png_uint_32 stride = png_get_rowbytes(pngp, infop);
+    png_bytep buf = fc_malloc(stride * height);
+    png_bytep *row_pointers = fc_malloc(height * sizeof(png_bytep));
+
+    assert(stride >= width * 4);
+
+    for (y = 0, pb = buf; y < height; y++, pb += stride) {
+      row_pointers[y] = pb;
+    }
+
+    png_read_image(pngp, row_pointers);
+    png_read_end(pngp, infop);
+    free(row_pointers);
+    png_destroy_read_struct(&pngp, &infop, NULL);
+    fclose(fp);
+
+    pb = buf;
+
+    for (y = 0; y < height; y++) {
+      for (x = 0; x < width; x++) {
+       png_bytep src = pb + 4 * x;
+       unsigned char *dest = IMAGE_GET_ADDRESS(xi, x, y);
+
+        memcpy(dest, src, 4);
+      }
+      pb += stride;
+    }
+    free(buf);
+  }
+
+  return xi;
 }
Index: utility/ftwl/be_common_24.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/utility/ftwl/be_common_24.h,v
retrieving revision 1.4
diff -u -r1.4 be_common_24.h
--- utility/ftwl/be_common_24.h 25 Mar 2005 10:20:49 -0000      1.4
+++ utility/ftwl/be_common_24.h 25 Mar 2005 20:55:57 -0000
@@ -26,15 +26,12 @@
   struct ct_rect full_rect;
 };
 
-struct Sprite {
-  struct image *image;
-};
-
-struct osda {
-  int magic;
-  struct image *image;
-  bool has_transparent_pixels;
-};
+void draw_mono_bitmap(struct image *image, be_color color,
+                      const struct ct_point *position,
+                      struct FT_Bitmap_ *bitmap);
+void draw_alpha_bitmap(struct image *image, be_color color_,
+                       const struct ct_point *position,
+                       struct FT_Bitmap_ *bitmap);
 
 struct image *image_create(int width, int height);
 void image_destroy(struct image *image);
@@ -42,8 +39,14 @@
                              const struct ct_size *size);
 void image_copy_full(struct image *src, struct image *dest,
                     struct ct_rect *region);
+void image_copy(struct image *dest, struct image *src,
+                const struct ct_size *size, const struct ct_point *dest_pos,
+                const struct ct_point *src_pos);
 void image_set_alpha(const struct image *image, const struct ct_rect *rect,
                     unsigned char alpha);
+void image_multiply_alphas(struct image *dest, const struct image *src,
+                           const struct ct_point *src_pos);
+struct image *image_load_gfxfile(const char *filename);
 
 #define IMAGE_GET_ADDRESS(image, x, y) ((image)->data + (image)->pitch * (y) + 
4 * (x))
 
Index: utility/ftwl/be_sdl.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/utility/ftwl/be_sdl.c,v
retrieving revision 1.4
diff -u -r1.4 be_sdl.c
--- utility/ftwl/be_sdl.c       9 Oct 2004 11:59:38 -0000       1.4
+++ utility/ftwl/be_sdl.c       25 Mar 2005 20:55:57 -0000
@@ -1,5 +1,5 @@
 /**********************************************************************
- Freeciv - Copyright (C) 2004 - The Freeciv Project
+ Freeciv - Copyright (C) 2005 - The Freeciv Project
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
@@ -22,7 +22,6 @@
 #include <SDL/SDL.h>
 
 #include "back_end.h"
-#include "be_common_24.h"
 
 #include "shared.h"
 
@@ -30,95 +29,8 @@
 #include "log.h"
 #include "mem.h"
 
-static SDL_Surface *screen;
 static int other_fd = -1;
 
-/* SDL interprets each pixel as a 32-bit number, so our masks must depend
- * on the endianness (byte order) of the machine */
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
-static Uint32 rmask = 0xff000000;
-static Uint32 gmask = 0x00ff0000;
-static Uint32 bmask = 0x0000ff00;
-static Uint32 amask = 0x000000ff;
-#else
-static Uint32 rmask = 0x000000ff;
-static Uint32 gmask = 0x0000ff00;
-static Uint32 bmask = 0x00ff0000;
-static Uint32 amask = 0xff000000;
-#endif
-
-/*************************************************************************
-  Initialize video mode and SDL.
-*************************************************************************/
-void be_init(const struct ct_size *screen_size, bool fullscreen)
-{
-  Uint32 flags = SDL_SWSURFACE | (fullscreen ? SDL_FULLSCREEN : 0)
-                 | SDL_ANYFORMAT;
-
-  char device[20];
-
-  /* auto center new windows in X enviroment */
-  putenv((char *) "SDL_VIDEO_CENTERED=yes");
-
-  if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
-    freelog(LOG_FATAL, _("Unable to initialize SDL library: %s"),
-           SDL_GetError());
-    exit(EXIT_FAILURE);
-  }
-  atexit(SDL_Quit);
-
-  freelog(LOG_NORMAL, "Using Video Output: %s",
-         SDL_VideoDriverName(device, sizeof(device)));
-  {
-    const SDL_VideoInfo *info = SDL_GetVideoInfo();
-    freelog(LOG_NORMAL, "Video memory of driver: %dkb", info->video_mem);
-    freelog(LOG_NORMAL, "Preferred depth: %d bits per pixel",
-           info->vfmt->BitsPerPixel);
-  }
-
-#if 0
-  {
-    SDL_Rect **modes;
-    int i;
-
-    modes = SDL_ListModes(NULL, flags);
-    if (modes == (SDL_Rect **) 0) {
-      printf("No modes available!\n");
-      exit(-1);
-    }
-    if (modes == (SDL_Rect **) - 1) {
-      printf("All resolutions available.\n");
-    } else {
-      /* Print valid modes */
-      printf("Available Modes\n");
-      for (i = 0; modes[i]; ++i)
-       printf("  %d x %d\n", modes[i]->w, modes[i]->h);
-    }
-  }
-#endif
-
-  screen =
-      SDL_SetVideoMode(screen_size->width, screen_size->height, 32, flags);
-  if (screen == NULL) {
-    freelog(LOG_FATAL, _("Can't set video mode: %s"), SDL_GetError());
-    exit(1);
-  }
-
-  freelog(LOG_NORMAL, "Got a screen with size (%dx%d) and %d bits per pixel",
-         screen->w, screen->h, screen->format->BitsPerPixel);
-  freelog(LOG_NORMAL, "  format: red=0x%x green=0x%x blue=0x%x mask=0x%x",
-         screen->format->Rmask, screen->format->Gmask,
-         screen->format->Bmask, screen->format->Amask);
-  freelog(LOG_NORMAL, "  format: bits-per-pixel=%d bytes-per-pixel=%d",
-         screen->format->BitsPerPixel, screen->format->BytesPerPixel);
-  SDL_EnableUNICODE(1);
-  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
-#if 0
-  SDL_EventState(SDL_KEYUP, SDL_IGNORE);
-  SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
-#endif
-}
-
 /*************************************************************************
   ...
 *************************************************************************/
@@ -301,33 +213,10 @@
 }
 
 /*************************************************************************
-  Copy our osda to the screen.  No alpha-blending here.
-*************************************************************************/
-void be_copy_osda_to_screen(struct osda *src)
-{
-  SDL_Surface *buf;
-
-  buf = SDL_CreateRGBSurfaceFrom(src->image->data, src->image->width,
-                                 src->image->height, 32, src->image->pitch,
-                                 rmask, gmask, bmask, amask);
-  SDL_BlitSurface(buf, NULL, screen, NULL);
-  SDL_Flip(screen);
-  SDL_FreeSurface(buf);
-}
-
-/*************************************************************************
-  ...
-*************************************************************************/
-void be_screen_get_size(struct ct_size *size)
-{
-  size->width = screen->w;
-  size->height = screen->h;
-}
-
-/*************************************************************************
   ...
 *************************************************************************/
 bool be_supports_fullscreen(void)
 {
   return TRUE;
 }
+

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#12656) ftwl api reorganization, Per I. Mathisen <=