Handle-ify the mapgen call

scancodes-fix
Armin Burgmeier 2013-01-07 00:16:43 +01:00
parent 662d9bc4f4
commit 4b4da8646b
7 changed files with 395 additions and 224 deletions

View File

@ -561,6 +561,8 @@ set(OC_CLONK_SOURCES
set(MAPE_SOURCES
src/mape/cpp-handles/group-handle.h
src/mape/cpp-handles/group-handle.cpp
src/mape/cpp-handles/mapgen-handle.h
src/mape/cpp-handles/mapgen-handle.cpp
src/mape/cpp-handles/material-handle.h
src/mape/cpp-handles/material-handle.cpp
src/mape/cpp-handles/texture-handle.h
@ -581,7 +583,7 @@ set(MAPE_SOURCES
src/mape/iconview.c
src/mape/iconview.h
src/mape/mape.c
src/mape/mapgen.cpp
src/mape/mapgen.c
src/mape/mapgen.h
src/mape/material.c
src/mape/material.h

View File

@ -0,0 +1,121 @@
/*
* mape - C4 Landscape.txt editor
*
* Copyright (c) 2005-2009 Armin Burgmeier
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* See isc_license.txt for full license and disclaimer.
*
* "Clonk" is a registered trademark of Matthes Bender.
* See clonk_trademark_license.txt for full license.
*/
#include "C4Include.h"
//#include <C4Include.h>
//#include <Standard.h>
//#include <C4Scenario.h>
//#include <C4Texture.h>
//#include <C4Material.h>
#include <C4MapCreatorS2.h>
#include "mape/cpp-handles/material-handle.h"
#include "mape/cpp-handles/texture-handle.h"
#include "mape/cpp-handles/mapgen-handle.h"
#define HANDLE_TO_MATERIAL_MAP(handle) (reinterpret_cast<C4MaterialMap*>(handle))
#define HANDLE_TO_TEXTURE_MAP(handle) (reinterpret_cast<C4TextureMap*>(handle))
extern "C" {
struct _C4MapgenHandle {
unsigned int width;
unsigned int height;
StdCopyStrBuf error_message;
BYTE* data;
};
C4MapgenHandle* c4_mapgen_handle_new(const char* filename, const char* source, C4MaterialMapHandle* material_map, C4TextureMapHandle* texture_map, unsigned int map_width, unsigned int map_height)
{
try
{
C4SLandscape landscape;
landscape.Default();
landscape.MapWdt = map_width;
landscape.MapHgt = map_height;
landscape.MapPlayerExtend = 0;
C4MapCreatorS2 mapgen(
&landscape,
HANDLE_TO_TEXTURE_MAP(texture_map),
HANDLE_TO_MATERIAL_MAP(material_map),
1
);
C4MCParser parser(&mapgen);
parser.ParseMemFile(source, filename);
int32_t out_width, out_height;
BYTE* array = mapgen.RenderBuf(NULL, out_width, out_height);
if(array == NULL) throw C4MCParserErr(&parser, "No map definition in source file");
C4MapgenHandle* handle = new C4MapgenHandle;
handle->width = out_width;
handle->height = out_height;
handle->error_message = NULL;
handle->data = array;
return handle;
}
catch(const C4MCParserErr& err)
{
C4MapgenHandle* handle = new C4MapgenHandle;
handle->width = 0;
handle->height = 0;
handle->error_message.Copy(err.Msg);
handle->data = NULL;
return handle;
}
}
void c4_mapgen_handle_free(C4MapgenHandle* mapgen)
{
delete[] mapgen->data;
delete mapgen;
}
const unsigned char* c4_mapgen_handle_get_map(C4MapgenHandle* mapgen)
{
return reinterpret_cast<unsigned char*>(mapgen->data);
}
unsigned int c4_mapgen_handle_get_width(C4MapgenHandle* mapgen)
{
assert(mapgen->data != NULL);
return mapgen->width;
}
unsigned int c4_mapgen_handle_get_height(C4MapgenHandle* mapgen)
{
assert(mapgen->data != NULL);
return mapgen->height;
}
unsigned int c4_mapgen_handle_get_rowstride(C4MapgenHandle* mapgen)
{
assert(mapgen->data != NULL);
return DWordAligned(mapgen->width);
}
const char* c4_mapgen_handle_get_error(C4MapgenHandle* mapgen)
{
if(mapgen->data != NULL)
return NULL;
return mapgen->error_message.getData();
}
} // extern "C"

View File

@ -0,0 +1,41 @@
/*
* mape - C4 Landscape.txt editor
*
* Copyright (c) 2005-2009 Armin Burgmeier
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* See isc_license.txt for full license and disclaimer.
*
* "Clonk" is a registered trademark of Matthes Bender.
* See clonk_trademark_license.txt for full license.
*/
#ifndef INC_MAPE_C4_MAPGEN_HANDLE_H
#define INC_MAPE_C4_MAPGEN_HANDLE_H
#include <glib.h>
#include "mape/cpp-handles/material-handle.h"
#include "mape/cpp-handles/texture-handle.h"
G_BEGIN_DECLS
typedef struct _C4MapgenHandle C4MapgenHandle;
C4MapgenHandle* c4_mapgen_handle_new(const char* filename, const char* source, C4MaterialMapHandle* material_map, C4TextureMapHandle* texture_map, unsigned int map_width, unsigned int map_height);
void c4_mapgen_handle_free(C4MapgenHandle* mapgen);
const unsigned char* c4_mapgen_handle_get_map(C4MapgenHandle* mapgen);
unsigned int c4_mapgen_handle_get_width(C4MapgenHandle* mapgen);
unsigned int c4_mapgen_handle_get_height(C4MapgenHandle* mapgen);
unsigned int c4_mapgen_handle_get_rowstride(C4MapgenHandle* mapgen);
const char* c4_mapgen_handle_get_error(C4MapgenHandle* mapgen);
G_END_DECLS
#endif /* INC_MAPE_C4_MAPGEN_HANDLE_H */

View File

@ -87,13 +87,14 @@ static GdkPixbuf* mape_edit_view_render_map(const gchar* source,
return NULL;
}
pixbuf = mape_mapgen_generate(
pixbuf = mape_mapgen_render(
"Landscape.txt", /* TODO: Use actual filename */
source,
mat_map,
tex_map,
error,
map_width,
map_height
map_height,
error
);
return pixbuf;

199
src/mape/mapgen.c 100644
View File

@ -0,0 +1,199 @@
/*
* mape - C4 Landscape.txt editor
*
* Copyright (c) 2005-2009 Armin Burgmeier
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* See isc_license.txt for full license and disclaimer.
*
* "Clonk" is a registered trademark of Matthes Bender.
* See clonk_trademark_license.txt for full license.
*/
#include <string.h>
#include "mape/cpp-handles/mapgen-handle.h"
#include "mape/cpp-handles/material-handle.h"
#include "mape/cpp-handles/texture-handle.h"
#include "mape/mapgen.h"
/* Declare private API */
C4MaterialMapHandle*
_mape_material_map_get_handle(MapeMaterialMap* map);
C4TextureMapHandle*
_mape_texture_map_get_handle(MapeTextureMap* map);
static GQuark mape_mapgen_error_quark()
{
return g_quark_from_static_string("MAPE_MAPGEN_ERROR");
}
static void mape_mapgen_read_color(guint8* dest,
MapeMaterialMap* material_map,
unsigned int matnum)
{
const MapeMaterial* mat;
if(matnum == 0)
{
dest[matnum * 4 + 1] = 100;
dest[matnum * 4 + 2] = 100;
dest[matnum * 4 + 3] = 255;
}
else
{
/* TODO: matnum is actually texmap entry, so find matnum from
* it. Actually we don't need to know the material
* actually, just get color from texture + render... */
mat = mape_material_map_get_material(material_map, matnum - 1);
dest[matnum * 4 + 1] = 0xff;
dest[matnum * 4 + 2] = 0xff;
dest[matnum * 4 + 3] = 0xff;
}
}
/*
* Public API.
*/
/**
* mape_mapgen_render:
*
* @filename: The filename of the file that is being parsed. This is only used
* for display purposes.
* @source: The map generator source code for the map to generate.
* @material_map: The material map containing the materials to be used during
* map generation.
* @texture_map: The texture map containing the textures to be used during map
* generation.
* @width: The width of the map to generate.
* @height: The height of the map to generate.
* @error: Location to store error information, if any, or %NULL.
*
* Renders the map described by @source with the C4MapCreatorS2 into a pixbuf.
* The pixel color depends on the texture at the corresponding position and is
* determined by the average color of that texture.
*
* In case an error occurs, for example when the map generator source code is
* not valid, @error is set and the function returns %NULL.
*
* Return Value: A #GdkPixbuf with the generated map, or %NULL. Free with
* g_object_unref().
**/
GdkPixbuf*
mape_mapgen_render(const gchar* filename,
const gchar* source,
MapeMaterialMap* material_map,
MapeTextureMap* texture_map,
guint width,
guint height,
GError** error)
{
C4MapgenHandle* handle;
const char* error_message;
unsigned int out_width;
unsigned int out_height;
GdkPixbuf* pixbuf;
guint8* out_p;
const unsigned char* in_p;
guint out_rowstride;
unsigned int in_rowstride;
guint datawidth;
guint8 matclrs[128 * 4];
unsigned int x, y;
handle = c4_mapgen_handle_new(
filename,
source,
_mape_material_map_get_handle(material_map),
_mape_texture_map_get_handle(texture_map),
width,
height
);
error_message = c4_mapgen_handle_get_error(handle);
if(error_message)
{
g_set_error(
error,
mape_mapgen_error_quark(),
MAPE_MAPGEN_ERROR_COMPILE,
"%s",
error_message
);
c4_mapgen_handle_free(handle);
return NULL;
}
out_width = c4_mapgen_handle_get_width(handle);
out_height = c4_mapgen_handle_get_height(handle);
pixbuf = gdk_pixbuf_new(
GDK_COLORSPACE_RGB,
FALSE,
8,
out_width,
out_height
);
if(pixbuf == NULL)
{
g_set_error(
error,
mape_mapgen_error_quark(),
MAPE_MAPGEN_ERROR_MEMORY,
"Insufficient memory is available"
);
c4_mapgen_handle_free(handle);
return NULL;
}
out_p = gdk_pixbuf_get_pixels(pixbuf);
in_p = c4_mapgen_handle_get_map(handle);
out_rowstride = gdk_pixbuf_get_rowstride(pixbuf);
in_rowstride = c4_mapgen_handle_get_rowstride(handle);
datawidth = gdk_pixbuf_get_width(pixbuf) * 3;
memset(matclrs, 0, sizeof(matclrs) );
for(x = 0; x < out_width; ++x)
{
for(y = 0; y < out_height; ++y)
{
unsigned int matnum = *in_p & 0x7f;
if(matclrs[matnum * 4] == 0)
{
mape_mapgen_read_color(
matclrs,
material_map,
matnum
);
/* Color has been loaded */
matclrs[matnum * 4] = 1;
}
out_p[0] = matclrs[matnum * 4 + 1];
out_p[1] = matclrs[matnum * 4 + 2];
out_p[2] = matclrs[matnum * 4 + 3];
++in_p;
out_p += 3;
}
in_p += in_rowstride - out_width;
out_p += out_rowstride - datawidth;
}
c4_mapgen_handle_free(handle);
return pixbuf;
}
/* vim:set et sw=2 ts=2: */

View File

@ -1,202 +0,0 @@
/*
* mape - C4 Landscape.txt editor
*
* Copyright (c) 2005-2009 Armin Burgmeier
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* See isc_license.txt for full license and disclaimer.
*
* "Clonk" is a registered trademark of Matthes Bender.
* See clonk_trademark_license.txt for full license.
*/
#define MAPE_COMPILING_CPP
#include <C4Include.h>
#include <Standard.h>
#include <C4Scenario.h>
#include <C4Texture.h>
#include <C4Material.h>
#include <C4MapCreatorS2.h>
#include <gdk/gdk.h>
#include "mape/cpp-handles/material-handle.h"
#include "mape/cpp-handles/texture-handle.h"
#include "mape/mapgen.h"
extern "C" C4MaterialMapHandle* _mape_material_map_get_handle(MapeMaterialMap*);
extern "C" C4TextureMapHandle* _mape_texture_map_get_handle(MapeTextureMap*);
#define CPPTEXMAP(map) (reinterpret_cast<C4TextureMap*>(_mape_texture_map_get_handle(map)))
#define CPPMATMAP(map) (reinterpret_cast<C4MaterialMap*>(_mape_material_map_get_handle(map)))
extern "C"
{
static void mape_mapgen_read_color(guint8* dest,
MapeMaterialMap* material_map,
unsigned int matnum)
{
const MapeMaterial* mat;
GdkColor color;
if(matnum == 0)
{
dest[matnum * 4 + 1] = 100;
dest[matnum * 4 + 2] = 100;
dest[matnum * 4 + 3] = 255;
}
else
{
/* TODO: matnum is actually texmap entry, so find matnum from
* it. Actually we don't need to know the material
* actually, just get color from texture + render... */
mat = mape_material_map_get_material(material_map, matnum - 1);
/* TODO: Read color from texture, needs TexMap lookup */
color.red = 0xffff;
color.green = 0xffff;
color.blue = 0xffff;
dest[matnum * 4 + 1] = color.red * 0xff / 0xffff;
dest[matnum * 4 + 2] = color.green * 0xff / 0xffff;
dest[matnum * 4 + 3] = color.blue * 0xff / 0xffff;
}
}
GdkPixbuf* mape_mapgen_generate(const gchar* source,
MapeMaterialMap* material_map,
MapeTextureMap* texture_map,
GError** error,
unsigned int map_width,
unsigned int map_height)
{
int32_t width, height;
int32_t x, y;
guint8* pix;
BYTE* arry;
BYTE* index;
int aligned_width;
unsigned int rowstride;
unsigned int datawidth;
GdkPixbuf* pixbuf;
aligned_width = DWordAligned(map_width);
arry = NULL;
try
{
C4SLandscape landscape;
landscape.Default();
landscape.MapWdt = map_width;
landscape.MapHgt = map_height;
landscape.MapPlayerExtend = 0;
C4MapCreatorS2 mapgen(
&landscape,
CPPTEXMAP(texture_map),
CPPMATMAP(material_map),
1
);
C4MCParser parser(&mapgen);
// TODO: Pass correct filename
parser.ParseMemFile(source, "Landscape.txt");
arry = mapgen.RenderBuf(NULL, width, height);
if(arry == NULL)
{
g_set_error(
error,
g_quark_from_static_string("MAPE_MAPGEN_ERROR"),
MAPE_MAPGEN_ERROR_MISSING_MAP,
"No map definition in source file"
);
return NULL;
}
pixbuf = gdk_pixbuf_new(
GDK_COLORSPACE_RGB,
FALSE,
8,
map_width,
map_height
);
if(pixbuf == NULL)
{
g_set_error(
error,
g_quark_from_static_string("MAPE_MAPGEN_ERROR"),
MAPE_MAPGEN_ERROR_MEMORY,
"Insufficient memory is available"
);
delete[] arry;
return NULL;
}
pix = gdk_pixbuf_get_pixels(pixbuf);
rowstride = gdk_pixbuf_get_rowstride(pixbuf);
datawidth = gdk_pixbuf_get_width(pixbuf) * 3;
index = arry;
guint8 matclrs[128 * 4];
memset(matclrs, 0, sizeof(matclrs) );
for(x = 0; x < map_height; ++ x)
{
for(y = 0; y < map_width; ++ y)
{
BYTE matnum = *index & 0x7f;
if(matclrs[matnum * 4] == 0)
{
mape_mapgen_read_color(
matclrs,
material_map,
matnum
);
/* Color has been loaded */
matclrs[matnum * 4] = 1;
}
pix[0] = matclrs[matnum * 4 + 1];
pix[1] = matclrs[matnum * 4 + 2];
pix[2] = matclrs[matnum * 4 + 3];
++ index;
pix += 3;
}
index += aligned_width - map_width;
pix += rowstride - datawidth;
}
delete[] arry;
return pixbuf;
}
catch(const C4MCParserErr& err)
{
g_set_error(
error,
g_quark_from_static_string("MAPE_MAPGEN_ERROR"),
MAPE_MAPGEN_ERROR_COMPILE,
"%s",
err.Msg
);
delete[] arry;
return NULL;
}
}
} // extern "C"

View File

@ -18,31 +18,40 @@
#ifndef INC_MAPE_MAPGEN_H
#define INC_MAPE_MAPGEN_H
#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "mape/material.h"
#include "mape/texture.h"
#ifdef MAPE_COMPILING_CPP
extern "C" {
#endif
G_BEGIN_DECLS
typedef enum MapeMapgenError_ {
MAPE_MAPGEN_ERROR_MEMORY,
MAPE_MAPGEN_ERROR_COMPILE,
MAPE_MAPGEN_ERROR_MISSING_MAP,
MAPE_MAPGEN_ERROR_FAILED
/**
* MapeMapgenError:
* @MAPE_MAPGEN_ERROR_COMPILE: An error occured while compiling the
* Landscape.txt source code.
* @MAPE_GROUP_ERROR_MEMORY: Insufficient memory was available to render the
* map.
*
* These errors are from the MAPE_MAPGEN_ERROR error domain. They can occur
* when rendering a map from a Landscape.txt file.
*/
typedef enum _MapeMapgenError {
MAPE_MAPGEN_ERROR_COMPILE,
MAPE_MAPGEN_ERROR_MEMORY
} MapeMapgenError;
GdkPixbuf* mape_mapgen_generate(const gchar* source,
MapeMaterialMap* material_map,
MapeTextureMap* texture_map,
GError** error,
unsigned int map_with,
unsigned int map_height);
GdkPixbuf*
mape_mapgen_render(const gchar* filename,
const gchar* source,
MapeMaterialMap* material_map,
MapeTextureMap* texture_map,
guint width,
guint height,
GError** error);
#ifdef MAPE_COMPILING_CPP
} /* extern "C" */
#endif
G_END_DECLS
#endif /* INC_MAPE_MAPGEN_H */
/* vim:set et sw=2 ts=2: */