forked from Mirrors/openclonk
418 lines
10 KiB
C
418 lines
10 KiB
C
/*
|
|
* 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.
|
|
*/
|
|
|
|
/**
|
|
* SECTION:mape-material-mape
|
|
* @title: MapeMaterialMap
|
|
* @short_description: C4MaterialMap interface
|
|
* @include: mape/material.h
|
|
* @stability: Unstable
|
|
*
|
|
* #MapeMaterialMap is a simple GObject-based interface to C4MaterialMap.
|
|
* It supports loading a material map from a Material.c4g material_map file. It can
|
|
* load multiple files, with newer entries overloading previous ones in case
|
|
* of name clashes to support material overloading.
|
|
**/
|
|
|
|
#include "mape/cpp-handles/material-handle.h"
|
|
#include "mape/material.h"
|
|
|
|
/* Declare private API */
|
|
C4GroupHandle*
|
|
_mape_group_get_handle(MapeGroup* group);
|
|
|
|
C4MaterialHandle*
|
|
_mape_material_map_get_handle(MapeMaterialMap* map);
|
|
|
|
struct _MapeMaterial {
|
|
MapeMaterialMap* map;
|
|
unsigned int mat_index;
|
|
};
|
|
|
|
typedef struct _MapeMaterialMapPrivate MapeMaterialMapPrivate;
|
|
struct _MapeMaterialMapPrivate {
|
|
C4MaterialHandle* handle;
|
|
};
|
|
|
|
enum {
|
|
PROP_0,
|
|
|
|
/* read only */
|
|
PROP_N_MATERIALS
|
|
};
|
|
|
|
#define MAPE_MATERIAL_MAP_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), MAPE_TYPE_MATERIAL_MAP, MapeMaterialMapPrivate))
|
|
|
|
static GQuark mape_material_map_error_quark;
|
|
|
|
G_DEFINE_TYPE(MapeMaterialMap, mape_material_map, G_TYPE_OBJECT)
|
|
|
|
/*
|
|
* MapeMaterial
|
|
*/
|
|
|
|
static MapeMaterial*
|
|
mape_material_new(MapeMaterialMap* map,
|
|
guint mat_index)
|
|
{
|
|
MapeMaterial* material;
|
|
|
|
material = g_slice_new(MapeMaterial);
|
|
material->map = map;
|
|
material->mat_index = mat_index;
|
|
|
|
g_object_ref(map);
|
|
return material;
|
|
}
|
|
|
|
/*
|
|
* GObject overrides.
|
|
*/
|
|
|
|
static void
|
|
mape_material_map_init(MapeMaterialMap* material_map)
|
|
{
|
|
MapeMaterialMapPrivate* priv;
|
|
priv = MAPE_MATERIAL_MAP_PRIVATE(material_map);
|
|
|
|
priv->handle = c4_material_handle_new();
|
|
}
|
|
|
|
static void
|
|
mape_material_map_finalize(GObject* object)
|
|
{
|
|
MapeMaterialMap* material_map;
|
|
MapeMaterialMapPrivate* priv;
|
|
|
|
material_map = MAPE_MATERIAL_MAP(object);
|
|
priv = MAPE_MATERIAL_MAP_PRIVATE(material_map);
|
|
|
|
c4_material_handle_free(priv->handle);
|
|
G_OBJECT_CLASS(mape_material_map_parent_class)->finalize(object);
|
|
}
|
|
|
|
static void
|
|
mape_material_map_set_property(GObject* object,
|
|
guint prop_id,
|
|
const GValue* value,
|
|
GParamSpec* pspec)
|
|
{
|
|
MapeMaterialMap* material_map;
|
|
MapeMaterialMapPrivate* priv;
|
|
|
|
material_map = MAPE_MATERIAL_MAP(object);
|
|
priv = MAPE_MATERIAL_MAP_PRIVATE(material_map);
|
|
|
|
switch(prop_id)
|
|
{
|
|
/* we have only readonly properties */
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(value, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
mape_material_map_get_property(GObject* object,
|
|
guint prop_id,
|
|
GValue* value,
|
|
GParamSpec* pspec)
|
|
{
|
|
MapeMaterialMap* material_map;
|
|
MapeMaterialMapPrivate* priv;
|
|
|
|
material_map = MAPE_MATERIAL_MAP(object);
|
|
priv = MAPE_MATERIAL_MAP_PRIVATE(material_map);
|
|
|
|
switch(prop_id)
|
|
{
|
|
case PROP_N_MATERIALS:
|
|
g_value_set_uint(value, c4_material_handle_get_num(priv->handle));
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Gype registration.
|
|
*/
|
|
|
|
static void
|
|
mape_material_map_class_init(MapeMaterialMapClass *class)
|
|
{
|
|
GObjectClass* object_class;
|
|
|
|
object_class = G_OBJECT_CLASS(class);
|
|
mape_material_map_parent_class =
|
|
G_OBJECT_CLASS(g_type_class_peek_parent(class));
|
|
g_type_class_add_private(class, sizeof(MapeMaterialMapPrivate));
|
|
|
|
object_class->finalize = mape_material_map_finalize;
|
|
object_class->set_property = mape_material_map_set_property;
|
|
object_class->get_property = mape_material_map_get_property;
|
|
|
|
mape_material_map_error_quark =
|
|
g_quark_from_static_string("MAPE_MATERIAL_MAP_ERROR");
|
|
|
|
g_object_class_install_property(
|
|
object_class,
|
|
PROP_N_MATERIALS,
|
|
g_param_spec_uint(
|
|
"n-materials",
|
|
"Material count",
|
|
"The number of loaded materials",
|
|
0,
|
|
G_MAXUINT,
|
|
0,
|
|
G_PARAM_READABLE
|
|
)
|
|
);
|
|
}
|
|
|
|
GType
|
|
mape_material_get_type(void)
|
|
{
|
|
static GType material_type = 0;
|
|
|
|
if(material_type == 0)
|
|
{
|
|
material_type = g_boxed_type_register_static(
|
|
"MapeMaterial",
|
|
(GBoxedCopyFunc)mape_material_copy,
|
|
(GBoxedFreeFunc)mape_material_free);
|
|
}
|
|
|
|
return material_type;
|
|
}
|
|
|
|
/*
|
|
* Public API.
|
|
*/
|
|
|
|
/**
|
|
* mape_material_map_new:
|
|
*
|
|
* Creates a new #MapeMaterialMap. The map is initially empty. Use
|
|
* mape_material_map_load() to load materials from one or more Material.c4g
|
|
* group files.
|
|
*
|
|
* Return Value: A new #MapeMaterialMap. Free with g_object_unref().
|
|
**/
|
|
MapeMaterialMap*
|
|
mape_material_map_new(void)
|
|
{
|
|
return MAPE_MATERIAL_MAP(g_object_new(MAPE_TYPE_MATERIAL_MAP, NULL));
|
|
}
|
|
|
|
/**
|
|
* mape_material_map_load:
|
|
* @map: A #MapeMaterialMap.
|
|
* @from: An open #MapeGroup to load materials from.
|
|
* @error: Location to store error information, if any.
|
|
*
|
|
* Loads all the material files (*.c4m) from the group @from. If this includes
|
|
* materials with the same name as materials already contained in @map, then
|
|
* the materials in @map will be replaced by the new ones. If an error occurs
|
|
* while loading the material map the function returns %FALSE and @error is
|
|
* set.
|
|
*
|
|
* Returns: %TRUE on success, %FALSE on failure.
|
|
*/
|
|
gboolean
|
|
mape_material_map_load(MapeMaterialMap* map,
|
|
MapeGroup* from,
|
|
GError** error)
|
|
{
|
|
MapeMaterialMapPrivate* priv;
|
|
guint new_count;
|
|
|
|
g_return_val_if_fail(MAPE_IS_MATERIAL_MAP(map), FALSE);
|
|
g_return_val_if_fail(MAPE_IS_GROUP(from), FALSE);
|
|
g_return_val_if_fail(mape_group_is_open(from), FALSE);
|
|
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
|
|
|
priv = MAPE_MATERIAL_MAP_PRIVATE(map);
|
|
|
|
new_count = c4_material_handle_load(
|
|
priv->handle, _mape_group_get_handle(from));
|
|
|
|
if(new_count > 0)
|
|
g_object_notify(G_OBJECT(map), "n-materials");
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* mape_material_map_get_material_count:
|
|
* @map: A #MapeMaterialMap.
|
|
*
|
|
* Returns the number of materials contained in @map.
|
|
*
|
|
* Return Value: The number of materials in @map.
|
|
**/
|
|
guint
|
|
mape_material_map_get_material_count(MapeMaterialMap* map)
|
|
{
|
|
g_return_val_if_fail(MAPE_IS_MATERIAL_MAP(map), 0);
|
|
return c4_material_handle_get_num(MAPE_MATERIAL_MAP_PRIVATE(map)->handle);
|
|
}
|
|
|
|
/**
|
|
* mape_material_map_get_material:
|
|
* @material: A #MapeMaterialMap.
|
|
* @index: A material index.
|
|
*
|
|
* Returns the entry with the given index in the map.
|
|
*
|
|
* Returns: A new #MapeMaterial to be freed with mape_material_free() when
|
|
* no longer needed.
|
|
**/
|
|
MapeMaterial*
|
|
mape_material_map_get_material(MapeMaterialMap* map,
|
|
guint index)
|
|
{
|
|
MapeMaterialMapPrivate* priv;
|
|
|
|
g_return_val_if_fail(MAPE_IS_MATERIAL_MAP(map), NULL);
|
|
|
|
priv = MAPE_MATERIAL_MAP_PRIVATE(map);
|
|
g_return_val_if_fail(index < c4_material_handle_get_num(priv->handle), NULL);
|
|
|
|
return mape_material_new(map, index);
|
|
}
|
|
|
|
#if 0
|
|
/*
|
|
* mape_material_map_get_material_by_name:
|
|
* @map: A #MapeMaterialMap.
|
|
* @name: The name of the material to retrieve.
|
|
*
|
|
* Returns the material in the map which has the given name, if any. If there
|
|
* is no such material the function returns %NULL.
|
|
*
|
|
* Returns: A new #MapeMaterial to be freed with mape_material_free() when
|
|
* no longer needed, or %NULL.
|
|
*/
|
|
MapeMaterial*
|
|
mape_material_map_get_material_by_name(MapeMaterialMap* map,
|
|
const gchar* name)
|
|
{
|
|
MapeMaterialMapPrivate* priv;
|
|
const gchar* cur_name;
|
|
guint i;
|
|
|
|
g_return_val_if_fail(MAPE_IS_MATERIAL_MAP(map), NULL);
|
|
g_return_val_if_fail(name != NULL, NULL);
|
|
|
|
priv = MAPE_MATERIAL_MAP_PRIVATE(map);
|
|
|
|
for(i = 0; i < c4_material_handle_get_num(priv->handle); ++i)
|
|
{
|
|
cur_name = c4_material_handle_get_name(priv->handle, i);
|
|
if(g_ascii_strcasecmp(cur_name, name) == 0)
|
|
return mape_material_new(map, i);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* mape_material_copy:
|
|
* @material: A #MapeMaterial.
|
|
*
|
|
* Creates a copy of @material.
|
|
*
|
|
* Returns: A new #MapeMaterial to be freed with mape_material_free() when
|
|
* no longer needed.
|
|
*/
|
|
MapeMaterial*
|
|
mape_material_copy(const MapeMaterial* material)
|
|
{
|
|
g_return_val_if_fail(material != NULL, NULL);
|
|
return mape_material_new(material->map, material->mat_index);
|
|
}
|
|
|
|
/**
|
|
* mape_material_free:
|
|
* @material: A #MapeMaterial.
|
|
*
|
|
* Releases all ressources taken up by @material.
|
|
*/
|
|
void
|
|
mape_material_free(MapeMaterial* material)
|
|
{
|
|
g_return_if_fail(material != NULL);
|
|
|
|
g_object_unref(material->map);
|
|
g_slice_free(MapeMaterial, material);
|
|
}
|
|
|
|
/**
|
|
* mape_material_get_name:
|
|
* @material: A #MapeMaterial.
|
|
*
|
|
* Returns the material's name.
|
|
*
|
|
* Return Value: The name of the material. The string is owned by the
|
|
* #MapeMaterial and must not be freed by the user.
|
|
*/
|
|
const gchar*
|
|
mape_material_get_name(const MapeMaterial* material)
|
|
{
|
|
MapeMaterialMapPrivate* priv;
|
|
|
|
g_return_val_if_fail(material != NULL, NULL);
|
|
priv = MAPE_MATERIAL_MAP_PRIVATE(material->map);
|
|
|
|
return c4_material_handle_get_name(priv->handle, material->mat_index);
|
|
}
|
|
|
|
/**
|
|
* mape_material_get_texture_overlay:
|
|
* @material: A #MapeMaterial.
|
|
*
|
|
* Returns the material's texture overlay as a string. This can be used to
|
|
* make a texture lookup in a corresponding #MapeTextureMap.
|
|
*
|
|
* Return Value: The texture overlay of the material. The string is owned by
|
|
* the #MapeMaterial and must not be freed by the user.
|
|
*/
|
|
const gchar*
|
|
mape_material_get_texture_overlay(const MapeMaterial* material)
|
|
{
|
|
MapeMaterialMapPrivate* priv;
|
|
|
|
g_return_val_if_fail(material != NULL, NULL);
|
|
priv = MAPE_MATERIAL_MAP_PRIVATE(material->map);
|
|
|
|
return c4_material_handle_get_texture_overlay(
|
|
priv->handle, material->mat_index);
|
|
}
|
|
|
|
/* This function is for internal use only */
|
|
C4MaterialHandle*
|
|
_mape_material_map_get_handle(MapeMaterialMap* map)
|
|
{
|
|
g_return_val_if_fail(MAPE_IS_MATERIAL_MAP(map), NULL);
|
|
return MAPE_MATERIAL_MAP_PRIVATE(map)->handle;
|
|
}
|
|
|
|
/* vim:set et sw=2 ts=2: */
|