Add support for algo=script overlays

scancodes-fix
Armin Burgmeier 2013-01-12 14:05:54 +01:00
parent 0b45ac83cf
commit 2cd91a56c4
9 changed files with 215 additions and 21 deletions

View File

@ -587,7 +587,6 @@ set(MAPE_BASE_SOURCES
src/lib/C4Real.h
src/lib/C4Rect.cpp
src/lib/C4Rect.h
src/lib/C4SimpleLog.cpp
src/lib/Standard.cpp
src/lib/Standard.h
src/lib/StdBuf.cpp
@ -611,6 +610,7 @@ set(MAPE_BASE_SOURCES
src/script/C4AulParse.cpp
src/script/C4PropList.cpp
src/script/C4PropList.h
src/script/C4Script.cpp
src/script/C4ScriptHost.cpp
src/script/C4ScriptHost.h
src/script/C4StringTable.cpp
@ -628,6 +628,8 @@ set(MAPE_BASE_SOURCES
set(MAPE_SOURCES
src/mape/cpp-handles/group-handle.h
src/mape/cpp-handles/group-handle.cpp
src/mape/cpp-handles/log-handle.h
src/mape/cpp-handles/log-handle.cpp
src/mape/cpp-handles/mapgen-handle.h
src/mape/cpp-handles/mapgen-handle.cpp
src/mape/cpp-handles/material-handle.h

View File

@ -0,0 +1,59 @@
/*
* 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 <C4Log.h>
// This implements the Log engine function such that the first log message
// is stored and can be retrieved later by the C API.
std::string first_log;
bool Log(const char *msg)
{
if(first_log.empty())
first_log = msg;
return true;
}
bool DebugLog(const char *strMessage) { return Log(strMessage); }
bool LogFatal(const char *strMessage) { return Log(strMessage); }
#define IMPLEMENT_LOGF(func) \
bool func(const char *msg, ...) { \
va_list args; va_start(args, msg); \
StdStrBuf Buf; \
Buf.FormatV(msg, args); \
return Log(Buf.getData()); \
}
IMPLEMENT_LOGF(DebugLogF)
IMPLEMENT_LOGF(LogF)
IMPLEMENT_LOGF(LogSilentF)
// C API follows here
extern "C" {
void c4_log_handle_clear()
{
first_log.clear();
}
const char* c4_log_handle_get_first_log_message()
{
if(first_log.empty()) return NULL;
return first_log.c_str();
}
} // extern "C"

View File

@ -0,0 +1,32 @@
/*
* 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_LOG_HANDLE_H
#define INC_MAPE_C4_LOG_HANDLE_H
#include <glib.h>
G_BEGIN_DECLS
typedef struct _C4MapgenHandle C4MapgenHandle;
void c4_log_handle_clear();
const char* c4_log_handle_get_first_log_message();
G_END_DECLS
#endif /* INC_MAPE_C4_LOG_HANDLE_H */

View File

@ -16,15 +16,14 @@
*/
#include "C4Include.h"
//#include <C4Include.h>
//#include <Standard.h>
//#include <C4Scenario.h>
//#include <C4Texture.h>
//#include <C4Material.h>
#include <C4MapCreatorS2.h>
#include <C4ScriptHost.h>
#include <C4DefList.h>
#include <C4Aul.h>
#include "mape/cpp-handles/material-handle.h"
#include "mape/cpp-handles/texture-handle.h"
#include "mape/cpp-handles/log-handle.h"
#include "mape/cpp-handles/mapgen-handle.h"
#define HANDLE_TO_MATERIAL_MAP(handle) (reinterpret_cast<C4MaterialMap*>(handle))
@ -55,7 +54,7 @@ struct _C4MapgenHandle {
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)
C4MapgenHandle* c4_mapgen_handle_new(const char* filename, const char* source, const char* script_path, C4MaterialMapHandle* material_map, C4TextureMapHandle* texture_map, unsigned int map_width, unsigned int map_height)
{
try
{
@ -79,11 +78,68 @@ C4MapgenHandle* c4_mapgen_handle_new(const char* filename, const char* source, C
C4MCMap* map = mapgen.GetMap(NULL);
if(!map) throw C4MCParserErr(&parser, "No map definition in source file");
// Setup the script engine if there is an algo=script overlay in the
// Landscape.txt file
if(HasAlgoScript(mapgen.GetMap(NULL)))
throw C4MCParserErr(&parser, "algo=script is not yet supported!");
{
if(script_path == NULL)
throw C4MCParserErr(&parser, "For algo=script overlays to work, save the file first at the location of the Script.c file");
gchar* dirname = g_path_get_dirname(script_path);
gchar* basename = g_path_get_basename(script_path);
C4Group File;
if(!File.Open(dirname))
{
g_free(dirname);
g_free(basename);
throw C4MCParserErr(&parser, File.GetError());
}
// get scripts
File.ResetSearch();
if(!File.FindNextEntry(basename, (char*)NULL))
{
g_free(dirname);
g_free(basename);
StdStrBuf error_msg = FormatString("Failed to load '%s': No such file", script_path);
throw C4MCParserErr(&parser, error_msg.getData());
}
// load core functions into script engine
InitCoreFunctionMap(&ScriptEngine);
c4_log_handle_clear();
GameScript.Load(File, basename, NULL, NULL);
g_free(dirname);
g_free(basename);
const char* parse_error = c4_log_handle_get_first_log_message();
if(parse_error)
throw C4MCParserErr(&parser, parse_error);
// Link script engine (resolve includes/appends, generate code)
c4_log_handle_clear();
ScriptEngine.Link(&::Definitions);
if(ScriptEngine.warnCnt > 0 || ScriptEngine.errCnt > 0)
throw C4MCParserErr(&parser, c4_log_handle_get_first_log_message());
// Set name list for globals
ScriptEngine.GlobalNamed.SetNameList(&ScriptEngine.GlobalNamedNames);
}
c4_log_handle_clear();
int32_t out_width, out_height;
BYTE* array = mapgen.RenderBuf(NULL, out_width, out_height);
GameScript.Clear();
ScriptEngine.Clear();
// Don't show any map if there was a script runtime error
const char* runtime_error = c4_log_handle_get_first_log_message();
if(runtime_error)
{
delete[] array;
throw C4MCParserErr(&parser, runtime_error);
}
C4MapgenHandle* handle = new C4MapgenHandle;
handle->width = map_width;

View File

@ -27,7 +27,7 @@ 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);
C4MapgenHandle* c4_mapgen_handle_new(const char* filename, const char* source, const char* script_path, 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);

View File

@ -43,6 +43,7 @@ C4Set<C4PropListNumbered *> C4PropListNumbered::PropLists;
int32_t C4PropListNumbered::EnumerationIndex = 0;
C4StringTable Strings;
C4AulScriptEngine ScriptEngine;
C4DefList Definitions;
/* These are just stubs used by dead code: */
C4Landscape Landscape;
@ -98,12 +99,16 @@ C4IDListChunk::~C4IDListChunk() {}
void C4Def::IncludeDefinition(C4Def*) {}
C4DefList::C4DefList() {}
C4DefList::~C4DefList() {}
C4Def* C4DefList::ID2Def(C4ID) {return NULL;}
void C4DefList::Draw(C4ID, C4Facet &, bool, int32_t) {}
C4Def * C4DefList::GetDef(int) {return 0;}
int C4DefList::GetDefCount() {return 0;}
void C4DefList::CallEveryDefinition() {}
void C4DefList::ResetIncludeDependencies() {}
bool C4DefList::DrawFontImage(const char* szImageTag, C4Facet& rTarget, C4DrawTransform* pTransform) { return false; }
float C4DefList::GetFontImageAspect(const char* szImageTag) { return -1.0f; }
C4Landscape::C4Landscape() {}
C4Landscape::~C4Landscape() {}

View File

@ -30,6 +30,7 @@ typedef struct _ThreadData ThreadData;
struct _ThreadData {
MapeEditView* view;
gchar* source;
gchar* file_path;
MapeMaterialMap* mat_map;
MapeTextureMap* tex_map;
guint map_width;
@ -68,6 +69,7 @@ static void mape_edit_view_cb_update(GtkWidget* widget,
}
static GdkPixbuf* mape_edit_view_render_map(const gchar* source,
const gchar* file_path,
MapeMaterialMap* mat_map,
MapeTextureMap* tex_map,
guint map_width,
@ -75,6 +77,11 @@ static GdkPixbuf* mape_edit_view_render_map(const gchar* source,
GError** error)
{
GdkPixbuf* pixbuf;
gchar* basename;
gchar* dirname;
gchar* scriptname;
const gchar* filename;
if(mat_map == NULL || tex_map == NULL)
{
g_set_error(
@ -87,9 +94,26 @@ static GdkPixbuf* mape_edit_view_render_map(const gchar* source,
return NULL;
}
if(file_path != NULL)
{
basename = g_path_get_basename(file_path);
filename = basename;
dirname = g_path_get_dirname(file_path);
scriptname = g_build_filename(dirname, "Script.c", NULL);
g_free(dirname);
}
else
{
basename = NULL;
filename = "Landscape.txt";
scriptname = NULL;
}
pixbuf = mape_mapgen_render(
"Landscape.txt", /* TODO: Use actual filename */
filename,
source,
scriptname,
mat_map,
tex_map,
map_width,
@ -97,6 +121,7 @@ static GdkPixbuf* mape_edit_view_render_map(const gchar* source,
error
);
g_free(basename);
return pixbuf;
}
@ -151,6 +176,7 @@ static gpointer mape_edit_view_thread_entry(gpointer data_)
res_buf = mape_edit_view_render_map(
data->source,
data->file_path,
data->mat_map,
data->tex_map,
data->map_width,
@ -164,6 +190,7 @@ static gpointer mape_edit_view_thread_entry(gpointer data_)
result->error = error;
g_free(data->source);
g_free(data->file_path);
g_slice_free(ThreadData, data);
result->idle_id = g_idle_add_full(
@ -337,6 +364,9 @@ void mape_edit_view_destroy(MapeEditView* view)
void mape_edit_view_clear(MapeEditView* view)
{
g_free(view->file_path);
view->file_path = NULL;
/* TODO: Undoable action dingsen */
/* (statische mape_edit_view_set_contents-Call?) */
gtk_text_buffer_set_text(
@ -349,9 +379,6 @@ void mape_edit_view_clear(MapeEditView* view)
gtk_text_view_get_buffer(GTK_TEXT_VIEW(view->view)),
FALSE
);
g_free(view->file_path);
view->file_path = NULL;
}
gboolean mape_edit_view_open(MapeEditView* view,
@ -422,6 +449,12 @@ gboolean mape_edit_view_open(MapeEditView* view,
view->encoding = "UTF-8";
}
/* TODO: Verify that filename is absolute and make it absolute if
it is not */
new_path = g_strdup(filename);
g_free(view->file_path);
view->file_path = new_path;
/* TODO: Undoable action dingsen */
/* (statische mape_edit_view_set_contents-Call?) */
gtk_text_buffer_set_text(
@ -436,12 +469,6 @@ gboolean mape_edit_view_open(MapeEditView* view,
gtk_text_view_get_buffer(GTK_TEXT_VIEW(view->view)),
FALSE
);
/* TODO: Verify that filename is absolute and make it absolute if
it is not */
new_path = g_strdup(filename);
g_free(view->file_path);
view->file_path = new_path;
return TRUE;
}
@ -488,7 +515,11 @@ gboolean mape_edit_view_save(MapeEditView* view,
new_path = g_strdup(filename);
g_free(view->file_path);
view->file_path = new_path;
/* Rerender with new file path --
* different Script.c lookup for algo=script overlays */
mape_edit_view_reload(view);
return TRUE;
}
@ -596,12 +627,13 @@ void mape_edit_view_reload(MapeEditView* edit_view)
* thread result handler */
data->view = edit_view;
data->source = gtk_text_buffer_get_text(buffer, &begin, &end, TRUE);
data->file_path = g_strdup(edit_view->file_path);
/* TODO: We need to ref these so noone can delete them while the thread
* uses them. */
data->mat_map = edit_view->pre_view->mat_tex->mat_map,
data->tex_map = edit_view->pre_view->mat_tex->tex_map,
data->map_width = edit_view->map_width;
data->map_height = edit_view->map_height;

View File

@ -104,6 +104,7 @@ static void mape_mapgen_read_color(guint8* dest,
* @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.
* @script_path: Path to the script source for algo=script overlays, or %NULL.
* @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
@ -116,6 +117,10 @@ static void mape_mapgen_read_color(guint8* dest,
* The pixel color depends on the texture at the corresponding position and is
* determined by the average color of that texture.
*
* If the source contains one or more algo=script overlays and @script_path is
* %NULL, an error is generated. Otherwise, the file at @script_path is opened
* and used to look up the relevant script functions.
*
* In case an error occurs, for example when the map generator source code is
* not valid, @error is set and the function returns %NULL.
*
@ -125,6 +130,7 @@ static void mape_mapgen_read_color(guint8* dest,
GdkPixbuf*
mape_mapgen_render(const gchar* filename,
const gchar* source,
const gchar* script_path,
MapeMaterialMap* material_map,
MapeTextureMap* texture_map,
guint width,
@ -148,6 +154,7 @@ mape_mapgen_render(const gchar* filename,
handle = c4_mapgen_handle_new(
filename,
source,
script_path,
_mape_material_map_get_handle(material_map),
_mape_texture_map_get_handle(texture_map),
width,

View File

@ -44,6 +44,7 @@ typedef enum _MapeMapgenError {
GdkPixbuf*
mape_mapgen_render(const gchar* filename,
const gchar* source,
const gchar* script_path,
MapeMaterialMap* material_map,
MapeTextureMap* texture_map,
guint width,