Merge branch 'master' of git://github.com/peterix/dfhack

develop
Warmist 2012-03-26 18:14:14 +03:00
commit 18c94f8000
52 changed files with 1109 additions and 1981 deletions

@ -103,10 +103,73 @@ Usage
-----
:list-equipped [all]: List armor and weapons equipped by your companions. If all is specified, also lists non-metal clothing.
changelayer
===========
Changes material of the geology layer under cursor to the specified inorganic RAW material. Can have impact on all surrounding regions, not only your embark! By default changing stone to soil and vice versa is not allowed. By default changes only the layer at the cursor position. Note that one layer can stretch across lots of z levels. By default changes only the geology which is linked to the biome under the cursor. That geology might be linked to other biomes as well, though. Mineral veins and gem clusters will stay on the map. Use 'changevein' for them.
tl;dr: You will end up with changing quite big areas in one go, especially if you use it in lower z levels. Use with care.
Options
-------
:all_biomes: Change layer for all biomes on your map.
Result may be undesirable since the same layer can AND WILL be on different z-levels for different biomes. Use the tool 'probe' to get an idea how layers and biomes are distributed on your map.
:all-layers: Change all layers on your map. Candy mountain, anyone? Will make your map quite boring, but tidy.
:force: Allow changing stone to soil and vice versa. !!THIS CAN HAVE WEIRD EFFECTS, USE WITH CARE!!
Note that soil will not be magically replaced with stone. You will, however, get a stone floor after digging so it will allow the floor to be engraved.
Note that stone will not be magically replaced with soil. You will, however, get a soil floor after digging so it could be helpful for creating farm plots on maps with no soil.
:verbose: Give some details about what is being changed.
:trouble: Give some advice about known problems.
Examples:
---------
``changelayer GRANITE`` : Convert layer at cursor position into granite.
``changelayer SILTY_CLAY force`` : Convert layer at cursor position into clay even if it's stone.
``changelayer MARBLE all_biomes all_layers`` : Convert all layers of all biomes which are not soil into marble.
.. note::
* If you use changelayer and nothing happens, try to pause/unpause the game for a while and try to move the cursor to another tile.
* You should be fine if you only change single layers without the use of 'force'. Still it's advisable to save your game before messing with the map.
* When you force changelayer to convert soil to stone you might experience weird stuff (flashing tiles, tiles changed all over the map, ...). Try reverting the changes manually or even better use an older savegame. You did save your game, right?
changevein
==========
Changes material of the vein under cursor to the specified inorganic RAW material.
Example:
---------
``changevein NATIVE_PLATINUM`` : Convert vein at cursor position into platinum ore.
cursecheck
==========
Checks a single map tile or the whole map/world for cursed creatures (ghosts, vampires, necromancers, werebeasts, zombies).
With an active in-game cursor only the selected tile will be observed. Without a cursor the whole map will be checked.
By default cursed creatures will be only counted in case you just want to find out if you have any of them running around in your fort.
By default dead and passive creatures (ghosts who were put to rest, killed vampires, ...) are ignored.
Undead skeletons, corpses, bodyparts and the like are all thrown into the curse category "zombie".
Anonymous zombies and resurrected body parts will show as "unnamed creature".
Options
-------
:detail: Print full name, date of birth, date of curse and some status info (some vampires might use fake identities in-game, though).
:nick: Set the type of curse as nickname (does not always show up in-game, some vamps don't like nicknames).
:all: Include dead and passive cursed creatures (can result in a quite long list after having FUN with necromancers).
:verbose: Print all curse tags (if you really want to know it all).
Examples:
---------
Check one single map tile if one of the creatures on it is cursed (in-game cursor required):
* cursecheck
Count all active cursed creatures who roam around on your map (no in-game cursor) without giving more details:
* cursecheck
Give detailed info about all cursed creatures including deceased ones (no in-game cursor):
* cursecheck detail all
Give a nickname all living/active cursed creatures on the map(no in-game cursor):
* cursecheck nick
.. note::
* If you do a full search (with the option "all") former ghosts will show up with the cursetype "unknown" because their ghostly flag is not set anymore. But if you happen to find a living/active creature with cursetype "unknown" please report that in the dfhack thread on the modding forum or per irc. This is likely to happen with mods which introduce new types of curses, for example.
follow
======
Makes the game view follow the currently highlighted unit after you exit from current menu/cursor mode. Handy for watching dwarves running around. Deactivated by moving the view manually.
@ -371,21 +434,16 @@ When multiple commands are bound to the same key combination, DFHack selects the
liquids
=======
Allows adding magma, water and obsidian to the game. It replaces the normal dfhack command line and can't be used from a hotkey.
For more information, refer to the command's internal help.
Allows adding magma, water and obsidian to the game. It replaces the normal dfhack command line and can't be used from a hotkey. Settings will be remembered as long as dfhack runs. Intended for use in combination with the command liquidsgo-here (which can be bound to a hotkey).
For more information, refer to the command's internal help.
.. note::
Spawning and deleting liquids can F up pathing data and
temperatures (creating heat traps). You've been warned.
liquidsgo
=========
Allows adding magma, water and obsidian to the game. It replaces the normal dfhack command line and can't be used from a hotkey. Settings will be remembered as long as dfhack runs. Intended for use in combination with the command liquidsgo-here (which can be bound to a hotkey).
For more information, refer to the command's internal help.
liquidsgo-here
==============
liquids-here
============
Run the liquid spawner with the current/last settings made in liquidsgo (if no settings in liquidsgo were made it paints a point of 7/7 magma by default).
Intended to be used as keybinding. Requires an active in-game cursor.
@ -542,37 +600,6 @@ tubefill
========
Fills all the adamantine veins again. Veins that were empty will be filled in too, but might still trigger a demon invasion (this is a known bug).
cursecheck
==========
Checks a single map tile or the whole map/world for cursed creatures (ghosts, vampires, necromancers, werebeasts, zombies).
With an active in-game cursor only the selected tile will be observed. Without a cursor the whole map will be checked.
By default cursed creatures will be only counted in case you just want to find out if you have any of them running around in your fort.
By default dead and passive creatures (ghosts who were put to rest, killed vampires, ...) are ignored.
Undead skeletons, corpses, bodyparts and the like are all thrown into the curse category "zombie".
Anonymous zombies and resurrected body parts will show as "unnamed creature".
Options
-------
:detail: Print full name, date of birth, date of curse and some status info (some vampires might use fake identities in-game, though).
:nick: Set the type of curse as nickname (does not always show up in-game, some vamps don't like nicknames).
:all: Include dead and passive cursed creatures (can result in a quite long list after having FUN with necromancers).
:verbose: Print all curse tags (if you really want to know it all).
Examples:
---------
Check one single map tile if one of the creatures on it is cursed (in-game cursor required):
* cursecheck
Count all active cursed creatures who roam around on your map (no in-game cursor) without giving more details:
* cursecheck
Give detailed info about all cursed creatures including deceased ones (no in-game cursor):
* cursecheck detail all
Give a nickname all living/active cursed creatures on the map(no in-game cursor):
* cursecheck nick
.. note::
* If you do a full search (with the option "all") former ghosts will show up with the cursetype "unknown" because their ghostly flag is not set anymore. But if you happen to find a living/active creature with cursetype "unknown" please report that in the dfhack thread on the modding forum or per irc. This is likely to happen with mods which introduce new types of curses, for example.
vdig
====
Designates a whole vein for digging. Requires an active in-game cursor placed over a vein tile. With the 'x' option, it will traverse z-levels (putting stairs between the same-material tiles).

@ -3,4 +3,4 @@ IF NOT EXIST DF_PATH.txt SET _DF_PATH=%CD%\DF
mkdir VC2010
cd VC2010
echo generating a build folder
cmake ..\.. -G"Visual Studio 10" -DCMAKE_INSTALL_PREFIX=%_DF_PATH% -DBUILD_DEVEL=1 -DBUILD_DEV_PLUGINS=1 -DBUILD_DF2MC=1 -DBUILD_DFUSION=1 -DBUILD_STONESENSE=1 -DBUILD_SERVER=1
cmake ..\.. -G"Visual Studio 10" -DCMAKE_INSTALL_PREFIX="%_DF_PATH%" -DBUILD_DEVEL=1 -DBUILD_DEV_PLUGINS=1 -DBUILD_DF2MC=1 -DBUILD_DFUSION=1 -DBUILD_STONESENSE=1 -DBUILD_SERVER=1

@ -3,5 +3,5 @@ IF NOT EXIST DF_PATH.txt SET _DF_PATH=%CD%\DF
mkdir VC2010
cd VC2010
echo Pre-generating a build folder
cmake ..\.. -G"Visual Studio 10" -DCMAKE_INSTALL_PREFIX=%_DF_PATH%
cmake-gui .
cmake ..\.. -G"Visual Studio 10" -DCMAKE_INSTALL_PREFIX="%_DF_PATH%"
cmake-gui .

@ -3,4 +3,4 @@ IF NOT EXIST DF_PATH.txt SET _DF_PATH=%CD%\DF
mkdir VC2010
cd VC2010
echo generating a build folder
cmake ..\.. -G"Visual Studio 10" -DCMAKE_INSTALL_PREFIX=%_DF_PATH% -DBUILD_DEVEL=0 -DBUILD_DEV_PLUGINS=0 -DBUILD_DF2MC=0 -DBUILD_DFUSION=0 -DBUILD_STONESENSE=0 -DBUILD_SERVER=0
cmake ..\.. -G"Visual Studio 10" -DCMAKE_INSTALL_PREFIX="%_DF_PATH%" -DBUILD_DEVEL=0 -DBUILD_DEV_PLUGINS=0 -DBUILD_DF2MC=0 -DBUILD_DFUSION=0 -DBUILD_STONESENSE=0 -DBUILD_SERVER=0

@ -152,7 +152,7 @@
** LUA_BUILD_AS_DLL to get it).
*/
#ifdef __cplusplus
#define LUA_API_EXTERN extern "C"
#define LUA_API_EXTERN extern
#else
#define LUA_API_EXTERN extern
#endif

@ -51,6 +51,11 @@ void type_identity::do_copy_pod(void *tgt, const void *src) {
memmove(tgt, src, size);
};
bool type_identity::do_destroy_pod(void *obj) {
free(obj);
return true;
}
void *type_identity::allocate() {
if (can_allocate())
return do_allocate();
@ -60,7 +65,17 @@ void *type_identity::allocate() {
bool type_identity::copy(void *tgt, const void *src) {
if (can_allocate() && tgt && src)
{
do_copy(tgt, src);
return true;
}
else
return false;
}
bool type_identity::destroy(void *obj) {
if (can_allocate() && obj)
return do_destroy(obj);
else
return false;
}
@ -137,10 +152,11 @@ enum_identity::enum_identity(size_t size,
compound_identity *scope_parent, const char *dfhack_name,
type_identity *base_type,
int64_t first_item_value, int64_t last_item_value,
const char *const *keys)
const char *const *keys,
const void *attrs, struct_identity *attr_type)
: compound_identity(size, NULL, scope_parent, dfhack_name),
first_item_value(first_item_value), last_item_value(last_item_value),
keys(keys), base_type(base_type)
keys(keys), base_type(base_type), attrs(attrs), attr_type(attr_type)
{
}

@ -8,6 +8,7 @@
#include "df/ui.h"
#include "DataIdentity.h"
#include "DataFuncs.h"
#include <stddef.h>
@ -30,6 +31,8 @@ namespace df {
bool_identity identity_traits<bool>::identity;
stl_string_identity identity_traits<std::string>::identity;
ptr_string_identity identity_traits<char*>::identity;
ptr_string_identity identity_traits<const char*>::identity;
pointer_identity identity_traits<void*>::identity;
stl_ptr_vector_identity identity_traits<std::vector<void*> >::identity;
stl_bit_vector_identity identity_traits<std::vector<bool> >::identity;
@ -43,6 +46,7 @@ namespace df {
#define FLD(mode, name) struct_field_info::mode, #name, offsetof(CUR_STRUCT, name)
#define GFLD(mode, name) struct_field_info::mode, #name, (size_t)&df::global::name
#define METHOD(mode, name) struct_field_info::mode, #name, 0, wrap_function(&CUR_STRUCT::name)
#define FLD_END struct_field_info::END
// Field definitions

@ -36,6 +36,7 @@ distribution.
#include "DataDefs.h"
#include "DataIdentity.h"
#include "LuaWrapper.h"
#include "DataFuncs.h"
#include "MiscUtils.h"
@ -49,6 +50,16 @@ using namespace DFHack::LuaWrapper;
* Identity object read/write methods *
**************************************/
void function_identity_base::lua_read(lua_State *state, int fname_idx, void *ptr)
{
field_error(state, fname_idx, "executable code", "read");
}
void function_identity_base::lua_write(lua_State *state, int fname_idx, void *ptr, int val_index)
{
field_error(state, fname_idx, "executable code", "write");
}
void constructed_identity::lua_read(lua_State *state, int fname_idx, void *ptr)
{
push_object_internal(state, this, ptr);
@ -99,6 +110,20 @@ void df::bool_identity::lua_write(lua_State *state, int fname_idx, void *ptr, in
field_error(state, fname_idx, "boolean or number expected", "write");
}
void df::ptr_string_identity::lua_read(lua_State *state, int fname_idx, void *ptr)
{
auto pstr = (char**)ptr;
if (*pstr)
lua_pushstring(state, *pstr);
else
lua_pushnil(state);
}
void df::ptr_string_identity::lua_write(lua_State *state, int fname_idx, void *ptr, int val_index)
{
field_error(state, fname_idx, "raw pointer string", "write");
}
void df::stl_string_identity::lua_read(lua_State *state, int fname_idx, void *ptr)
{
auto pstr = (std::string*)ptr;
@ -264,12 +289,31 @@ static void lookup_field(lua_State *state, int index, const char *mode)
field_error(state, index, "not found", mode);
}
// Resolve the field in the metatable and return
static int get_metafield(lua_State *state)
{
lua_rawget(state, UPVAL_METATABLE);
return 1;
}
static void *find_field(lua_State *state, int index, const char *mode)
{
lookup_field(state, index, mode);
// Methods
if (lua_isfunction(state, -1))
return NULL;
// Otherwise must be a pointer
if (!lua_isuserdata(state, -1))
field_error(state, index, "corrupted field table", mode);
void *p = lua_touserdata(state, -1);
lua_pop(state, 1);
// NULL => metafield
if (!p)
get_metafield(state);
return p;
}
@ -295,6 +339,10 @@ static void read_field(lua_State *state, const struct_field_info *field, void *p
return;
}
case struct_field_info::OBJ_METHOD:
case struct_field_info::CLASS_METHOD:
// error
case struct_field_info::PRIMITIVE:
case struct_field_info::SUBSTRUCT:
field->type->lua_read(state, 2, ptr);
@ -339,6 +387,10 @@ static void field_reference(lua_State *state, const struct_field_info *field, vo
push_adhoc_pointer(state, ptr, field->type);
return;
case struct_field_info::OBJ_METHOD:
case struct_field_info::CLASS_METHOD:
// error
case struct_field_info::CONTAINER:
read_field(state, field, ptr);
return;
@ -371,6 +423,10 @@ static void write_field(lua_State *state, const struct_field_info *field, void *
return;
}
case struct_field_info::OBJ_METHOD:
case struct_field_info::CLASS_METHOD:
// error
case struct_field_info::PRIMITIVE:
case struct_field_info::SUBSTRUCT:
case struct_field_info::CONTAINER:
@ -418,13 +474,6 @@ static int meta_ptr_tostring(lua_State *state)
return 1;
}
// Resolve the field in the metatable and return
static int get_metafield(lua_State *state)
{
lua_rawget(state, UPVAL_METATABLE);
return 1;
}
/**
* Metamethod: __index for structures.
*/
@ -433,7 +482,7 @@ static int meta_struct_index(lua_State *state)
uint8_t *ptr = get_object_addr(state, 1, 2, "read");
auto field = (struct_field_info*)find_field(state, 2, "read");
if (!field)
return get_metafield(state);
return 1;
read_field(state, field, ptr + field->offset);
return 1;
}
@ -448,7 +497,7 @@ static int meta_struct_field_reference(lua_State *state)
uint8_t *ptr = get_object_addr(state, 1, 2, "reference");
auto field = (struct_field_info*)find_field(state, 2, "reference");
if (!field)
field_error(state, 2, "builtin property", "reference");
field_error(state, 2, "builtin property or method", "reference");
field_reference(state, field, ptr + field->offset);
return 1;
}
@ -461,7 +510,7 @@ static int meta_struct_newindex(lua_State *state)
uint8_t *ptr = get_object_addr(state, 1, 2, "write");
auto field = (struct_field_info*)find_field(state, 2, "write");
if (!field)
field_error(state, 2, "builtin property", "write");
field_error(state, 2, "builtin property or method", "write");
write_field(state, field, ptr + field->offset, 3);
return 0;
}
@ -475,7 +524,7 @@ static int meta_primitive_index(lua_State *state)
uint8_t *ptr = get_object_addr(state, 1, 2, "read");
auto type = (type_identity*)find_field(state, 2, "read");
if (!type)
return get_metafield(state);
return 1;
type->lua_read(state, 2, ptr);
return 1;
}
@ -488,7 +537,7 @@ static int meta_primitive_newindex(lua_State *state)
uint8_t *ptr = get_object_addr(state, 1, 2, "write");
auto type = (type_identity*)find_field(state, 2, "write");
if (!type)
field_error(state, 2, "builtin property", "write");
field_error(state, 2, "builtin property or method", "write");
type->lua_write(state, 2, ptr, 3);
return 0;
}
@ -521,7 +570,7 @@ static int lookup_container_field(lua_State *state, int field, const char *mode
if (lua_isuserdata(state, -1) && !lua_touserdata(state, -1))
{
if (mode)
field_error(state, field, "builtin property", mode);
field_error(state, field, "builtin property or method", mode);
lua_pop(state, 1);
get_metafield(state);
@ -727,7 +776,7 @@ static int meta_global_index(lua_State *state)
{
auto field = (struct_field_info*)find_field(state, 2, "read");
if (!field)
return get_metafield(state);
return 1;
void *ptr = *(void**)field->offset;
if (!ptr)
field_error(state, 2, "global address not known", "read");
@ -742,7 +791,7 @@ static int meta_global_newindex(lua_State *state)
{
auto field = (struct_field_info*)find_field(state, 2, "write");
if (!field)
field_error(state, 2, "builtin property", "write");
field_error(state, 2, "builtin property or method", "write");
void *ptr = *(void**)field->offset;
if (!ptr)
field_error(state, 2, "global address not known", "write");
@ -750,27 +799,92 @@ static int meta_global_newindex(lua_State *state)
return 0;
}
/**
* Wrapper for c++ methods and functions.
*/
static int meta_call_function(lua_State *state)
{
auto id = (function_identity_base*)lua_touserdata(state, UPVAL_CONTAINER_ID);
if (lua_gettop(state) != id->getNumArgs())
field_error(state, UPVAL_METHOD_NAME, "invalid argument count", "invoke");
id->invoke(state, 1);
return 1;
}
/**
* Create a closure invoking the given function, and add it to the field table.
*/
static void AddMethodWrapper(lua_State *state, int meta_idx, int field_idx,
const char *name, function_identity_base *fun)
{
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME);
lua_pushvalue(state, meta_idx);
lua_pushfstring(state, "%s()", name);
lua_pushlightuserdata(state, fun);
lua_pushcclosure(state, meta_call_function, 4);
lua_setfield(state, field_idx, name);
}
/**
* Add fields in the array to the UPVAL_FIELDTABLE candidates on the stack.
*/
static void IndexFields(lua_State *state, struct_identity *pstruct)
{
// stack: fieldtable
// stack: metatable fieldtable
int base = lua_gettop(state);
int base = lua_gettop(state) - 2;
for (struct_identity *p = pstruct; p; p = p->getParent())
{
auto fields = p->getFields();
if (!fields)
continue;
for (int i = 0; fields[i].mode != struct_field_info::END; ++i)
{
switch (fields[i].mode)
{
case struct_field_info::OBJ_METHOD:
AddMethodWrapper(state, base+1, base+2, fields[i].name,
(function_identity_base*)fields[i].type);
break;
case struct_field_info::CLASS_METHOD:
break;
default:
lua_pushstring(state,fields[i].name);
lua_pushlightuserdata(state,(void*)&fields[i]);
lua_rawset(state,base+2);
break;
}
}
}
}
void LuaWrapper::IndexStatics(lua_State *state, int meta_idx, int ftable_idx, struct_identity *pstruct)
{
// stack: metatable fieldtable
for (struct_identity *p = pstruct; p; p = p->getParent())
{
auto fields = p->getFields();
if (!fields)
continue;
for (; fields; ++fields)
for (int i = 0; fields[i].mode != struct_field_info::END; ++i)
{
if (fields->mode == struct_field_info::END)
switch (fields[i].mode)
{
case struct_field_info::CLASS_METHOD:
AddMethodWrapper(state, meta_idx, ftable_idx, fields[i].name,
(function_identity_base*)fields[i].type);
break;
lua_pushstring(state,fields->name);
lua_pushlightuserdata(state,(void*)fields);
lua_rawset(state,base);
default:
break;
}
}
}
}

@ -593,10 +593,7 @@ static int meta_new(lua_State *state)
void *ptr = id->allocate();
if (!ptr)
{
lua_pushnil(state);
return 1;
}
luaL_error(state, "Cannot allocate %s", id->getFullName().c_str());
if (lua_isuserdata(state, 1))
{
@ -630,6 +627,30 @@ static int meta_assign(lua_State *state)
return 0;
}
/**
* Method: deallocation for DF object references.
*/
static int meta_delete(lua_State *state)
{
int argc = lua_gettop(state);
if (argc != 1)
luaL_error(state, "Usage: object:delete() or df.delete(object)");
if (lua_isnil(state, 1))
{
lua_pushboolean(state, true);
return 1;
}
type_identity *id = get_object_identity(state, 1, "df.delete()", false);
bool ok = id->destroy(get_object_ref(state, 1));
lua_pushboolean(state, ok);
return 1;
}
/**
* Verify that the object is a DF ref with UPVAL_METATABLE.
* If everything ok, extract the address.
@ -677,6 +698,30 @@ static int meta_ptr_tostring(lua_State *state)
return 1;
}
/**
* Metamethod: __index for enum.attrs
*/
static int meta_enum_attr_index(lua_State *state)
{
if (!lua_isnumber(state, 2))
lua_rawget(state, UPVAL_FIELDTABLE);
if (!lua_isnumber(state, 2))
luaL_error(state, "Invalid index in enum.attrs[]");
auto id = (enum_identity*)lua_touserdata(state, lua_upvalueindex(2));
int64_t idx = lua_tonumber(state, 2);
if (idx < id->getFirstItem() || idx > id->getLastItem())
idx = id->getLastItem()+1;
idx -= id->getFirstItem();
uint8_t *ptr = (uint8_t*)id->getAttrs();
auto atype = id->getAttrType();
push_object_internal(state, atype, ptr + unsigned(atype->byte_size()*idx));
return 1;
}
/**
* Make a metatable with most common fields, and an empty table for UPVAL_FIELDTABLE.
*/
@ -741,6 +786,10 @@ void LuaWrapper::SetPtrMethods(lua_State *state, int meta_idx, int read_idx)
lua_setfield(state, meta_idx, "new");
EnableMetaField(state, read_idx, "new");
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_DELETE_NAME);
lua_setfield(state, meta_idx, "delete");
EnableMetaField(state, read_idx, "delete");
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_ASSIGN_NAME);
lua_setfield(state, meta_idx, "assign");
EnableMetaField(state, read_idx, "assign");
@ -835,82 +884,152 @@ static void AssociateId(lua_State *state, int table, int val, const char *name)
lua_rawset(state, table);
}
static void FillEnumKeys(lua_State *state, int ftable, enum_identity *eid)
{
const char *const *keys = eid->getKeys();
// Create a new table attached to ftable as __index
lua_newtable(state);
lua_dup(state);
lua_setmetatable(state, ftable);
int base = lua_gettop(state);
lua_newtable(state);
// For enums, set mapping between keys and values
for (int64_t i = eid->getFirstItem(), j = 0; i <= eid->getLastItem(); i++, j++)
{
if (keys[j])
AssociateId(state, base+1, i, keys[j]);
}
if (eid->getFirstItem() <= eid->getLastItem())
{
lua_pushinteger(state, eid->getFirstItem());
lua_setfield(state, base+1, "_first_item");
lua_pushinteger(state, eid->getLastItem());
lua_setfield(state, base+1, "_last_item");
}
SaveInTable(state, eid, DFHACK_ENUM_TABLE_NAME);
// Add an attribute table if any
if (eid->getAttrs())
{
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME);
lua_pushlightuserdata(state, eid);
lua_pushvalue(state, base+1);
lua_pushcclosure(state, meta_enum_attr_index, 3);
freeze_table(state, false, (eid->getFullName()+".attrs").c_str());
lua_setfield(state, ftable, "attrs");
}
lua_setfield(state, base, "__index");
lua_pop(state, 1);
}
static void FillBitfieldKeys(lua_State *state, int ftable, bitfield_identity *eid)
{
auto bits = eid->getBits();
for (int i = 0; i < eid->getNumBits(); i++)
{
if (bits[i].name)
AssociateId(state, ftable, i, bits[i].name);
if (bits[i].size > 1)
i += bits[i].size-1;
}
lua_pushinteger(state, 0);
lua_setfield(state, ftable, "_first_item");
lua_pushinteger(state, eid->getNumBits()-1);
lua_setfield(state, ftable, "_last_item");
SaveInTable(state, eid, DFHACK_ENUM_TABLE_NAME);
}
static void RenderType(lua_State *state, compound_identity *node)
{
assert(node->getName());
std::string name = node->getFullName();
int base = lua_gettop(state);
lua_newtable(state);
if (!lua_checkstack(state, 20))
return;
int base = lua_gettop(state);
SaveInTable(state, node, DFHACK_TYPEID_TABLE_NAME);
// metatable
lua_newtable(state);
lua_dup(state);
lua_setmetatable(state, base+1);
lua_pushstring(state, name.c_str());
lua_setfield(state, base+2, "__metatable");
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPE_TOSTRING_NAME);
lua_setfield(state, base+2, "__tostring");
lua_pushlightuserdata(state, node);
lua_setfield(state, base+2, "_identity");
// inner table
lua_newtable(state);
lua_dup(state);
lua_setfield(state, base+2, "__index");
int ftable = base+3;
switch (node->type())
{
case IDTYPE_STRUCT:
lua_pushstring(state, "struct-type");
lua_setfield(state, base, "_kind");
lua_setfield(state, ftable, "_kind");
IndexStatics(state, base+2, base+3, (struct_identity*)node);
break;
case IDTYPE_CLASS:
lua_pushstring(state, "class-type");
lua_setfield(state, base, "_kind");
lua_setfield(state, ftable, "_kind");
IndexStatics(state, base+2, base+3, (struct_identity*)node);
break;
case IDTYPE_ENUM:
{
lua_pushstring(state, "enum-type");
lua_setfield(state, base, "_kind");
enum_identity *eid = (enum_identity*)node;
const char *const *keys = eid->getKeys();
// For enums, set mapping between keys and values
for (int64_t i = eid->getFirstItem(), j = 0; i <= eid->getLastItem(); i++, j++)
{
if (keys[j])
AssociateId(state, base, i, keys[j]);
}
if (eid->getFirstItem() <= eid->getLastItem())
{
lua_pushinteger(state, eid->getFirstItem());
lua_setfield(state, base, "_first_item");
lua_pushinteger(state, eid->getLastItem());
lua_setfield(state, base, "_last_item");
}
SaveInTable(state, node, DFHACK_ENUM_TABLE_NAME);
}
lua_pushstring(state, "enum-type");
lua_setfield(state, ftable, "_kind");
FillEnumKeys(state, ftable, (enum_identity*)node);
break;
case IDTYPE_BITFIELD:
{
lua_pushstring(state, "bitfield-type");
lua_setfield(state, base, "_kind");
lua_pushstring(state, "bitfield-type");
lua_setfield(state, ftable, "_kind");
FillBitfieldKeys(state, ftable, (bitfield_identity*)node);
break;
bitfield_identity *eid = (bitfield_identity*)node;
auto bits = eid->getBits();
case IDTYPE_GLOBAL:
{
RenderTypeChildren(state, node->getScopeChildren());
for (int i = 0; i < eid->getNumBits(); i++)
{
if (bits[i].name)
AssociateId(state, base, i, bits[i].name);
if (bits[i].size > 1)
i += bits[i].size-1;
}
BuildTypeMetatable(state, node);
lua_pushinteger(state, 0);
lua_setfield(state, base, "_first_item");
lua_dup(state);
lua_setmetatable(state, base+3);
lua_pushinteger(state, eid->getNumBits()-1);
lua_setfield(state, base, "_last_item");
lua_getfield(state, -1, "__newindex");
lua_setfield(state, base+2, "__newindex");
SaveInTable(state, node, DFHACK_ENUM_TABLE_NAME);
lua_pop(state, 3);
return;
}
break;
default:
break;
@ -918,44 +1037,13 @@ static void RenderType(lua_State *state, compound_identity *node)
RenderTypeChildren(state, node->getScopeChildren());
assert(base == lua_gettop(state));
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_SIZEOF_NAME);
lua_setfield(state, base, "sizeof");
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_NEW_NAME);
lua_setfield(state, base, "new");
if (node->type() == IDTYPE_GLOBAL)
{
BuildTypeMetatable(state, node);
// Set metatable for the inner table
lua_dup(state);
lua_setmetatable(state, base);
lua_swap(state); // -> meta curtable
lua_setfield(state, ftable, "sizeof");
freeze_table(state, true, "global");
// Copy __newindex to the outer metatable
lua_getfield(state, base, "__newindex");
lua_setfield(state, -2, "__newindex");
lua_remove(state, base);
}
else
{
freeze_table(state, true, name.c_str());
}
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPE_TOSTRING_NAME);
lua_setfield(state, -2, "__tostring");
lua_pushlightuserdata(state, node);
lua_setfield(state, -2, "_identity");
lua_pop(state, 1);
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_NEW_NAME);
lua_setfield(state, ftable, "new");
SaveInTable(state, node, DFHACK_TYPEID_TABLE_NAME);
lua_pop(state, 2);
}
static void RenderTypeChildren(lua_State *state, const std::vector<compound_identity*> &children)
@ -1007,6 +1095,10 @@ static void DoAttach(lua_State *state)
lua_pushcclosure(state, meta_assign, 1);
lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_ASSIGN_NAME);
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_TYPETABLE_NAME);
lua_pushcclosure(state, meta_delete, 1);
lua_setfield(state, LUA_REGISTRYINDEX, DFHACK_DELETE_NAME);
luaL_register(state, "df", no_functions);
{
@ -1020,6 +1112,8 @@ static void DoAttach(lua_State *state)
lua_setfield(state, -2, "sizeof");
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_NEW_NAME);
lua_setfield(state, -2, "new");
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_DELETE_NAME);
lua_setfield(state, -2, "delete");
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_DISPLACE_NAME);
lua_setfield(state, -2, "_displace");
lua_getfield(state, LUA_REGISTRYINDEX, DFHACK_ASSIGN_NAME);

@ -49,6 +49,7 @@ namespace DFHack
enum identity_type {
IDTYPE_GLOBAL,
IDTYPE_FUNCTION,
IDTYPE_PRIMITIVE,
IDTYPE_POINTER,
IDTYPE_CONTAINER,
@ -72,10 +73,12 @@ namespace DFHack
void *do_allocate_pod();
void do_copy_pod(void *tgt, const void *src);
bool do_destroy_pod(void *obj);
virtual bool can_allocate() { return true; }
virtual void *do_allocate() { return do_allocate_pod(); }
virtual void do_copy(void *tgt, const void *src) { do_copy_pod(tgt, src); }
virtual bool do_destroy(void *obj) { return do_destroy_pod(obj); }
public:
virtual ~type_identity() {}
@ -100,6 +103,7 @@ namespace DFHack
void *allocate();
bool copy(void *tgt, const void *src);
bool destroy(void *obj);
};
class DFHACK_EXPORT constructed_identity : public type_identity {
@ -109,12 +113,13 @@ namespace DFHack
constructed_identity(size_t size, TAllocateFn alloc)
: type_identity(size), allocator(alloc) {};
virtual bool isPrimitive() { return false; }
virtual bool isConstructed() { return true; }
virtual bool can_allocate() { return (allocator != NULL); }
virtual void *do_allocate() { return allocator(NULL,NULL); }
virtual void do_copy(void *tgt, const void *src) { allocator(tgt,src); }
virtual bool do_destroy(void *obj) { return allocator(NULL,obj) == obj; }
public:
virtual bool isPrimitive() { return false; }
virtual bool isConstructed() { return true; }
virtual void lua_read(lua_State *state, int fname_idx, void *ptr);
virtual void lua_write(lua_State *state, int fname_idx, void *ptr, int val_index);
@ -161,6 +166,7 @@ namespace DFHack
virtual bool can_allocate() { return true; }
virtual void *do_allocate() { return do_allocate_pod(); }
virtual void do_copy(void *tgt, const void *src) { do_copy_pod(tgt, src); }
virtual bool do_destroy(void *obj) { return do_destroy_pod(obj); }
public:
bitfield_identity(size_t size,
@ -177,6 +183,8 @@ namespace DFHack
virtual void build_metatable(lua_State *state);
};
class struct_identity;
class DFHACK_EXPORT enum_identity : public compound_identity {
const char *const *keys;
int64_t first_item_value;
@ -184,17 +192,22 @@ namespace DFHack
type_identity *base_type;
const void *attrs;
struct_identity *attr_type;
protected:
virtual bool can_allocate() { return true; }
virtual void *do_allocate();
virtual void do_copy(void *tgt, const void *src) { do_copy_pod(tgt, src); }
virtual bool do_destroy(void *obj) { return do_destroy_pod(obj); }
public:
enum_identity(size_t size,
compound_identity *scope_parent, const char *dfhack_name,
type_identity *base_type,
int64_t first_item_value, int64_t last_item_value,
const char *const *keys);
const char *const *keys,
const void *attrs, struct_identity *attr_type);
virtual identity_type type() { return IDTYPE_ENUM; }
@ -204,6 +217,8 @@ namespace DFHack
const char *const *getKeys() { return keys; }
type_identity *getBaseType() { return base_type; }
const void *getAttrs() { return attrs; }
struct_identity *getAttrType() { return attr_type; }
virtual bool isPrimitive() { return true; }
virtual bool isConstructed() { return false; }
@ -221,7 +236,9 @@ namespace DFHack
STATIC_ARRAY,
SUBSTRUCT,
CONTAINER,
STL_VECTOR_PTR
STL_VECTOR_PTR,
OBJ_METHOD,
CLASS_METHOD
};
Mode mode;
const char *name;
@ -409,6 +426,14 @@ namespace df
template<class T>
void *allocator_fn(void *out, const void *in) {
if (out) { *(T*)out = *(const T*)in; return out; }
else if (in) { delete (T*)in; return (T*)in; }
else return new T();
}
template<class T>
void *allocator_nodel_fn(void *out, const void *in) {
if (out) { *(T*)out = *(const T*)in; return out; }
else if (in) { return NULL; }
else return new T();
}

@ -0,0 +1,142 @@
/*
https://github.com/peterix/dfhack
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#pragma once
#include <string>
#include <sstream>
#include <vector>
#include <map>
#include "DataIdentity.h"
#include "LuaWrapper.h"
namespace df {
// A very simple and stupid implementation of some stuff from boost
template<class U, class V> struct is_same_type { static const bool value = false; };
template<class T> struct is_same_type<T,T> { static const bool value = true; };
template<class T> struct return_type {};
/*
* Workaround for a msvc bug suggested by:
*
* http://stackoverflow.com/questions/5110529/class-template-partial-specialization-parametrized-on-member-function-return-typ
*/
template<class T, bool isvoid = is_same_type<typename return_type<T>::type,void>::value>
struct function_wrapper {};
/*
* Since templates can't match variable arg count,
* a separate specialization is needed for every
* supported count value...
*
* The FW_TARGS ugliness is needed because of
* commas not wrapped in ()
*/
#define INVOKE_VOID(call) \
call; lua_pushnil(state);
#define INVOKE_RV(call) \
RT rv = call; df::identity_traits<RT>::get()->lua_read(state, UPVAL_METHOD_NAME, &rv);
#define LOAD_CLASS() \
CT *self = (CT*)DFHack::LuaWrapper::get_object_addr(state, base++, UPVAL_METHOD_NAME, "invoke");
#define LOAD_ARG(type) \
type v##type; df::identity_traits<type>::get()->lua_write(state, UPVAL_METHOD_NAME, &v##type, base++);
#define INSTANTIATE_WRAPPERS(Count, FArgs, Args, Loads) \
template<FW_TARGSC class RT> struct return_type<RT (*) FArgs> { typedef RT type; }; \
template<FW_TARGSC class RT, class CT> struct return_type<RT (CT::*) FArgs> { typedef RT type; }; \
template<FW_TARGS> struct function_wrapper<void (*) FArgs, true> { \
static const bool is_method = false; \
static const int num_args = Count; \
static void execute(lua_State *state, int base, void (*cb) FArgs) { Loads; INVOKE_VOID(cb Args); } \
}; \
template<FW_TARGSC class RT> struct function_wrapper<RT (*) FArgs, false> { \
static const bool is_method = false; \
static const int num_args = Count; \
static void execute(lua_State *state, int base, RT (*cb) FArgs) { Loads; INVOKE_RV(cb Args); } \
}; \
template<FW_TARGSC class CT> struct function_wrapper<void (CT::*) FArgs, true> { \
static const bool is_method = true; \
static const int num_args = Count+1; \
static void execute(lua_State *state, int base, void (CT::*cb) FArgs) { \
LOAD_CLASS() Loads; INVOKE_VOID((self->*cb) Args); } \
}; \
template<FW_TARGSC class RT, class CT> struct function_wrapper<RT (CT::*) FArgs, false> { \
static const bool is_method = true; \
static const int num_args = Count+1; \
static void execute(lua_State *state, int base, RT (CT::*cb) FArgs) { \
LOAD_CLASS(); Loads; INVOKE_RV((self->*cb) Args); } \
};
#define FW_TARGSC
#define FW_TARGS
INSTANTIATE_WRAPPERS(0, (), (), ;)
#undef FW_TARGS
#undef FW_TARGSC
#define FW_TARGSC FW_TARGS,
#define FW_TARGS class A1
INSTANTIATE_WRAPPERS(1, (A1), (vA1), LOAD_ARG(A1);)
#undef FW_TARGS
#define FW_TARGS class A1, class A2
INSTANTIATE_WRAPPERS(2, (A1,A2), (vA1,vA2), LOAD_ARG(A1); LOAD_ARG(A2);)
#undef FW_TARGS
#define FW_TARGS class A1, class A2, class A3
INSTANTIATE_WRAPPERS(3, (A1,A2,A3), (vA1,vA2,vA3), LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3);)
#undef FW_TARGS
#define FW_TARGS class A1, class A2, class A3, class A4
INSTANTIATE_WRAPPERS(4, (A1,A2,A3,A4), (vA1,vA2,vA3,vA4),
LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3); LOAD_ARG(A4);)
#undef FW_TARGS
#undef FW_TARGSC
#undef INSTANTIATE_WRAPPERS
#undef INVOKE_VOID
#undef INVOKE_RV
#undef LOAD_CLASS
#undef LOAD_ARG
template<class T>
class function_identity : public function_identity_base {
T ptr;
public:
typedef function_wrapper<T> wrapper;
function_identity(T ptr)
: function_identity_base(wrapper::num_args), ptr(ptr) {};
virtual void invoke(lua_State *state, int base) { wrapper::execute(state, base, ptr); }
};
template<class T>
inline function_identity_base *wrap_function(T ptr) {
// bah, but didn't have any idea how to allocate statically
return new function_identity<T>(ptr);
}
}

@ -37,6 +37,23 @@ distribution.
namespace DFHack
{
class DFHACK_EXPORT function_identity_base : public type_identity {
int num_args;
public:
function_identity_base(int num_args) : type_identity(0), num_args(num_args) {};
virtual identity_type type() { return IDTYPE_FUNCTION; }
int getNumArgs() { return num_args; }
std::string getFullName() { return "function"; }
virtual void invoke(lua_State *state, int base) = 0;
virtual void lua_read(lua_State *state, int fname_idx, void *ptr);
virtual void lua_write(lua_State *state, int fname_idx, void *ptr, int val_index);
};
class DFHACK_EXPORT primitive_identity : public type_identity {
public:
primitive_identity(size_t size) : type_identity(size) {};
@ -145,6 +162,7 @@ namespace DFHack
namespace df
{
using DFHack::function_identity_base;
using DFHack::primitive_identity;
using DFHack::pointer_identity;
using DFHack::container_identity;
@ -187,6 +205,16 @@ namespace df
virtual void lua_write(lua_State *state, int fname_idx, void *ptr, int val_index);
};
class ptr_string_identity : public primitive_identity {
public:
ptr_string_identity() : primitive_identity(sizeof(char*)) {};
std::string getFullName() { return "char*"; }
virtual void lua_read(lua_State *state, int fname_idx, void *ptr);
virtual void lua_write(lua_State *state, int fname_idx, void *ptr, int val_index);
};
class stl_string_identity : public DFHack::constructed_identity {
public:
stl_string_identity()
@ -370,6 +398,28 @@ namespace df
}
};
template<class T>
class enum_list_attr_identity : public container_identity {
public:
typedef enum_list_attr<T> container;
enum_list_attr_identity(type_identity *item)
: container_identity(sizeof(container), NULL, item, NULL)
{}
std::string getFullName(type_identity *item) {
return "enum_list_attr" + container_identity::getFullName(item);
}
protected:
virtual int item_count(void *ptr, CountMode cm) {
return cm == COUNT_WRITE ? 0 : ((container*)ptr)->size;
}
virtual void *item_pointer(type_identity *item, void *ptr, int idx) {
return (void*)&((container*)ptr)->items[idx];
}
};
#define NUMBER_IDENTITY_TRAITS(type) \
template<> struct identity_traits<type> { \
static number_identity<type> identity; \
@ -397,6 +447,16 @@ namespace df
static stl_string_identity *get() { return &identity; }
};
template<> struct identity_traits<char*> {
static ptr_string_identity identity;
static ptr_string_identity *get() { return &identity; }
};
template<> struct identity_traits<const char*> {
static ptr_string_identity identity;
static ptr_string_identity *get() { return &identity; }
};
template<> struct identity_traits<void*> {
static pointer_identity identity;
static pointer_identity *get() { return &identity; }
@ -448,47 +508,51 @@ namespace df
static container_identity *get();
};
template<class T> struct identity_traits<enum_list_attr<T> > {
static container_identity *get();
};
// Container definitions
template<class Enum, class FT>
primitive_identity *identity_traits<enum_field<Enum,FT> >::get() {
inline primitive_identity *identity_traits<enum_field<Enum,FT> >::get() {
return identity_traits<FT>::get();
}
template<class T>
pointer_identity *identity_traits<T *>::get() {
inline pointer_identity *identity_traits<T *>::get() {
static pointer_identity identity(identity_traits<T>::get());
return &identity;
}
template<class T, int sz>
container_identity *identity_traits<T [sz]>::get() {
inline container_identity *identity_traits<T [sz]>::get() {
static buffer_container_identity identity(sz, identity_traits<T>::get());
return &identity;
}
template<class T>
container_identity *identity_traits<std::vector<T> >::get() {
inline container_identity *identity_traits<std::vector<T> >::get() {
typedef std::vector<T> container;
static stl_container_identity<container> identity("vector", identity_traits<T>::get());
return &identity;
}
template<class T>
stl_ptr_vector_identity *identity_traits<std::vector<T*> >::get() {
inline stl_ptr_vector_identity *identity_traits<std::vector<T*> >::get() {
static stl_ptr_vector_identity identity(identity_traits<T>::get());
return &identity;
}
template<class T>
container_identity *identity_traits<std::deque<T> >::get() {
inline container_identity *identity_traits<std::deque<T> >::get() {
typedef std::deque<T> container;
static stl_container_identity<container> identity("deque", identity_traits<T>::get());
return &identity;
}
template<class T>
bit_container_identity *identity_traits<BitArray<T> >::get() {
inline bit_container_identity *identity_traits<BitArray<T> >::get() {
static type_identity *eid = identity_traits<T>::get();
static enum_identity *reid = eid->type() == DFHack::IDTYPE_ENUM ? (enum_identity*)eid : NULL;
static bit_array_identity identity(reid);
@ -496,10 +560,16 @@ namespace df
}
template<class T>
container_identity *identity_traits<DfArray<T> >::get() {
inline container_identity *identity_traits<DfArray<T> >::get() {
typedef DfArray<T> container;
static stl_container_identity<container> identity("DfArray", identity_traits<T>::get());
return &identity;
}
template<class T>
inline container_identity *identity_traits<enum_list_attr<T> >::get() {
static enum_list_attr_identity<T> identity(identity_traits<T>::get());
return &identity;
}
}

@ -68,6 +68,7 @@ namespace DFHack { namespace LuaWrapper {
#define DFHACK_DISPLACE_NAME "DFHack::Displace"
#define DFHACK_NEW_NAME "DFHack::New"
#define DFHACK_ASSIGN_NAME "DFHack::Assign"
#define DFHACK_DELETE_NAME "DFHack::Delete"
/*
* Upvalue: contents of DFHACK_TYPETABLE_NAME
@ -186,5 +187,7 @@ namespace DFHack { namespace LuaWrapper {
* and the enum itself to the _enum metafield.
*/
void AttachEnumKeys(lua_State *state, int meta_idx, int ftable_idx, type_identity *ienum);
void IndexStatics(lua_State *state, int meta_idx, int ftable_idx, struct_identity *pstruct);
}}

@ -54,6 +54,8 @@ distribution.
// just shut up already.
#pragma warning( disable: 4244)
#pragma warning( disable: 4018)
// nonstandard extension used: enum 'df::whatever::etc' used in qualified name
#pragma warning( disable: 4482)
#endif
#endif

@ -40,7 +40,7 @@ namespace df
namespace DFHack
{
class MaterialInfo;
struct MaterialInfo;
using google::protobuf::RepeatedField;
using google::protobuf::RepeatedPtrField;

@ -1 +1 @@
Subproject commit a0358a422cc5142f87da9d731915887b142f052e
Subproject commit b41c666c6be6fe18906a98dababdc4ff681b8382

@ -10,11 +10,6 @@ if(BUILD_DFUSION)
add_subdirectory (Dfusion)
endif()
OPTION(BUILD_QTPLUG "Build the experimental Qt plugin." OFF)
if(BUILD_QTPLUG)
add_subdirectory (qtplug)
endif()
OPTION(BUILD_STONESENSE "Build stonesense (needs a checkout first)." OFF)
if(BUILD_STONESENSE)
add_subdirectory (stonesense)
@ -25,11 +20,6 @@ if(BUILD_DEV_PLUGINS)
add_subdirectory (devel)
endif()
OPTION(BUILD_SERVER "Build server." OFF)
if(BUILD_SERVER)
add_subdirectory (server)
endif()
OPTION(BUILD_DF2MC "Build DF2MC (needs a checkout first)." OFF)
if(BUILD_DF2MC)
add_subdirectory (df2mc)
@ -115,3 +105,9 @@ if(BUILD_SKELETON)
add_subdirectory(skeleton)
endif()
# this is the changelayer plugin.
OPTION(BUILD_CHANGELAYER "Build the changelayer plugin." ON)
if(BUILD_CHANGELAYER)
add_subdirectory(changelayer)
endif()

@ -0,0 +1,32 @@
PROJECT (changelayer)
# A list of source files
SET(PROJECT_SRCS
changelayer.cpp
)
# A list of headers
SET(PROJECT_HDRS
)
SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE)
# mash them together (headers are marked as headers and nothing will try to compile them)
LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS})
# option to use a thread for no particular reason
OPTION(CHANGELAYER_THREAD "Use threads in the changelayer plugin." ON)
#linux
IF(UNIX)
add_definitions(-DLINUX_BUILD)
SET(PROJECT_LIBS
# add any extra linux libs here
${PROJECT_LIBS}
)
# windows
ELSE(UNIX)
SET(PROJECT_LIBS
# add any extra linux libs here
${PROJECT_LIBS}
$(NOINHERIT)
)
ENDIF(UNIX)
# this makes sure all the stuff is put in proper places and linked to dfhack
DFHACK_PLUGIN(changelayer ${PROJECT_SRCS} LINK_LIBRARIES ${PROJECT_LIBS})

@ -0,0 +1,398 @@
// changelayer plugin
// allows changing the material type of geological layers
// some headers required for a plugin. Nothing special, just the basics.
#include "Core.h"
#include <Console.h>
#include <Export.h>
#include <PluginManager.h>
// DF data structure definition headers
#include "DataDefs.h"
#include "modules/Maps.h"
#include "modules/Materials.h"
#include "modules/MapCache.h"
#include "modules/Gui.h"
#include "TileTypes.h"
#include "df/world_data.h"
#include "df/world_geo_biome.h"
#include "df/world_geo_layer.h"
using namespace DFHack;
using namespace df::enums;
using namespace std;
using std::vector;
using std::string;
using df::global::world;
using df::global::cursor;
const string changelayer_help =
" Allows to change the material of whole geology layers.\n"
" Can have impact on all surrounding regions, not only your embark!\n"
" By default changing stone to soil and vice versa is not allowed.\n"
" By default changes only the layer at the cursor position.\n"
" Note that one layer can stretch across lots of z levels.\n"
" By default changes only the geology which is linked to the biome under the\n"
" cursor. That geology might be linked to other biomes as well, though.\n"
" Mineral veins and gem clusters will stay on the map.\n"
" Use 'changevein' for them.\n\n"
" tl;dr: You will end up with changing quite big areas in one go.\n\n"
"Options (first parameter MUST be the material id):\n"
" all_biomes - Change layer for all biomes on your map.\n"
" Result may be undesirable since the same layer\n"
" can AND WILL be on different z-levels for different biomes.\n"
" Use the tool 'probe' to get an idea how layers and biomes\n"
" are distributed on your map.\n"
" all_layers - Change all layers on your map.\n"
" Candy mountain, anyone?\n"
" Will make your map quite boring, but tidy.\n"
" force - Allow changing stone to soil and vice versa.\n"
" !!THIS CAN HAVE WEIRD EFFECTS, USE WITH CARE!!\n"
" Note that soil will not be magically replaced with stone.\n"
" You will, however, get a stone floor after digging so it\n"
" will allow the floor to be engraved.\n"
" Note that stone will not be magically replaced with soil.\n"
" You will, however, get a soil floor after digging so it\n"
" could be helpful for creating farm plots on maps with no soil.\n"
" verbose - Give some more details about what is being changed.\n"
" trouble - Give some advice for known problems.\n"
"Example:\n"
" changelayer GRANITE\n"
" Convert layer at cursor position into granite.\n"
" changelayer SILTY_CLAY force\n"
" Convert layer at cursor position into clay even if it's stone.\n"
" changelayer MARBLE allbiomes alllayers\n"
" Convert all layers of all biomes into marble.\n";
const string changelayer_trouble =
"Known problems with changelayer:\n\n"
" Nothing happens, the material stays the old.\n"
" Try pausing/unpausing the game or moving the cursor a bit.\n\n"
" Weird stuff happening after using the 'force' option.\n"
" Change former stone layers back to stone, soil back to soil.\n"
" If in doubt, use the 'probe' tool to find tiles with soil walls\n"
" and stone layer type or the other way round.\n";
command_result changelayer (color_ostream &out, std::vector <std::string> & parameters);
DFHACK_PLUGIN("changelayer");
// Mandatory init function. If you have some global state, create it here.
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{
// Fill the command list with your commands.
commands.clear();
commands.push_back(PluginCommand(
"changelayer", "Change a whole geology layer.",
changelayer, false, /* true means that the command can't be used from non-interactive user interface */
// Extended help string. Used by CR_WRONG_USAGE and the help command:
changelayer_help.c_str()
));
return CR_OK;
}
// This is called right before the plugin library is removed from memory.
DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{
// You *MUST* kill all threads you created before this returns.
// If everything fails, just return CR_FAILURE. Your plugin will be
// in a zombie state, but things won't crash.
return CR_OK;
}
bool conversionAllowed(color_ostream &out, MaterialInfo mi, MaterialInfo ml, bool force);
// no need to spam the "stone to soil" warning more than once
// in case multiple biomes and/or layers are going to be changed
static bool warned = false;
command_result changelayer (color_ostream &out, std::vector <std::string> & parameters)
{
CoreSuspender suspend;
string material;
bool force = false;
bool all_biomes = false;
bool all_layers = false;
bool verbose = false;
warned = false;
for(size_t i = 0; i < parameters.size();i++)
{
if(parameters[i] == "help" || parameters[i] == "?")
{
out.print(changelayer_help.c_str());
return CR_OK;
}
if(parameters[i] == "trouble")
{
out.print(changelayer_trouble.c_str());
return CR_OK;
}
if(parameters[i] == "force")
force = true;
if(parameters[i] == "all_biomes")
all_biomes = true;
if(parameters[i] == "all_layers")
all_layers = true;
if(parameters[i] == "verbose")
verbose = true;
}
if (!Maps::IsValid())
{
out.printerr("Map is not available!\n");
return CR_FAILURE;
}
if (parameters.empty())
{
out.printerr("You need to specify a material!\n");
return CR_WRONG_USAGE;
}
material = parameters[0];
MaterialInfo mat_new;
if (!mat_new.findInorganic(material))
{
out.printerr("No such material!\n");
return CR_FAILURE;
}
// check if specified material is stone or gem or soil
if (mat_new.inorganic->material.flags.is_set(material_flags::IS_METAL) ||
mat_new.inorganic->material.flags.is_set(material_flags::NO_STONE_STOCKPILE))
{
out.printerr("Invalid material - you must select a type of stone or gem or soil.\n");
return CR_FAILURE;
}
MapExtras::MapCache mc;
int32_t regionX, regionY, regionZ;
Maps::getPosition(regionX,regionY,regionZ);
int32_t cursorX, cursorY, cursorZ;
Gui::getCursorCoords(cursorX,cursorY,cursorZ);
if(cursorX == -30000)
{
out.printerr("No cursor; place cursor over tile.\n");
return CR_FAILURE;
}
DFCoord cursor (cursorX,cursorY,cursorZ);
uint32_t blockX = cursorX / 16;
uint32_t tileX = cursorX % 16;
uint32_t blockY = cursorY / 16;
uint32_t tileY = cursorY % 16;
MapExtras::Block * b = mc.BlockAt(cursor/16);
if(!b && !b->valid)
{
out.printerr("No data.\n");
return CR_OK;
}
mapblock40d & block = b->raw;
df::tile_designation &des = block.designation[tileX][tileY];
// get biome and geolayer at cursor position
uint32_t biome = des.bits.biome;
uint32_t layer = des.bits.geolayer_index;
if(verbose)
{
out << "biome: " << biome << endl
<< "geolayer: " << layer << endl;
}
// there is no Maps::WriteGeology or whatever, and I didn't want to mess with the library and add it
// so I copied the stuff which reads the geology information and modified it to be able to change it
//
// a more elegant solution would probably look like this:
// 1) modify Maps::ReadGeology to accept and fill one more optional vector
// where the geolayer ids of the 9 biomes are stored
// 2) call ReadGeology here, modify the data in the vectors without having to do all that map stuff
// 3) write Maps::WriteGeology, pass the vectors, let it do it's work
// Step 1) is optional, but it would make implementing 3) easier.
// Otherwise that "check which geolayer is used by biome X" loop would need to be done again.
// no need to touch the same geology more than once
// though it wouldn't matter much since there is not much data to be processed
vector<uint16_t> v_geoprocessed;
v_geoprocessed.clear();
// iterate over 8 surrounding regions + local region
for (int i = eNorthWest; i < eBiomeCount; i++)
{
if(verbose)
out << "---Biome: " << i;
if(!all_biomes && i!=biome)
{
if(verbose)
out << "-skipping" << endl;
continue;
}
else
{
if(verbose)
out << "-checking" << endl;
}
// check against worldmap boundaries, fix if needed
// regionX is in embark squares
// regionX/16 is in 16x16 embark square regions
// i provides -1 .. +1 offset from the current region
int bioRX = world->map.region_x / 16 + ((i % 3) - 1);
if (bioRX < 0) bioRX = 0;
if (bioRX >= world->world_data->world_width) bioRX = world->world_data->world_width - 1;
int bioRY = world->map.region_y / 16 + ((i / 3) - 1);
if (bioRY < 0) bioRY = 0;
if (bioRY >= world->world_data->world_height) bioRY = world->world_data->world_height - 1;
// get index into geoblock vector
uint16_t geoindex = world->world_data->region_map[bioRX][bioRY].geo_index;
if(verbose)
out << "geoindex: " << geoindex << endl;
bool skip = false;
for(int g=0; g<v_geoprocessed.size(); g++)
{
if(v_geoprocessed.at(g)==geoindex)
{
if(verbose)
out << "already processed" << endl;
skip = true;
break;
}
}
if(skip)
continue;
v_geoprocessed.push_back(geoindex);
/// geology blocks have a vector of layer descriptors
// get the vector with pointer to layers
df::world_geo_biome *geo_biome = df::world_geo_biome::find(geoindex);
if (!geo_biome)
{
if(verbose)
out << "no geology found here." << endl;
continue;
}
vector <df::world_geo_layer*> &geolayers = geo_biome->layers;
// complain if layer is out of range
// geology has up to 16 layers currently, but size can be < 15 sometimes!
if(layer >= geolayers.size() || layer < 0)
{
if(verbose)
out << "layer out of range!";
continue;
}
// now let's actually write the new mat id to the layer(s)
if(all_layers)
{
for (size_t j = 0; j < geolayers.size(); j++)
{
MaterialInfo mat_old;
mat_old.decode(0, geolayers[j]->mat_index);
if(conversionAllowed(out, mat_new, mat_old, force))
{
if(verbose)
out << "changing geolayer " << j
<< " from " << mat_old.getToken()
<< " to " << mat_new.getToken()
<< endl;
geolayers[j]->mat_index = mat_new.index;
}
}
}
else
{
MaterialInfo mat_old;
mat_old.decode(0, geolayers[layer]->mat_index);
if(conversionAllowed(out, mat_new, mat_old, force))
{
if(verbose)
out << "changing geolayer " << layer
<< " from " << mat_old.getToken()
<< " to " << mat_new.getToken()
<< endl;
geolayers[layer]->mat_index = mat_new.index;
}
}
}
out.print("Done.\n");
// Give control back to DF.
return CR_OK;
}
// check if user tries to convert soil <-> stone
// throw some warning if he does
bool conversionAllowed(color_ostream &out, MaterialInfo mat_new, MaterialInfo mat_old, bool force)
{
// check if current layer mat is stone or soil:
// by default don't allow to turn stone to soil and vice versa
bool unsafe = false;
bool allowed = true;
// throw warning if user wants to change soil to stone or vice versa
// while it does work it might be unsafe and can have weird results
// you can't simply convert stone to soil, the rock walls will remain (same the other way round)
// the floor will turn into soil, though, so it might be useful for creating farm plots
// therefore it's not completely forbidden and can be enabled by the 'force' option
if ( mat_new.inorganic->flags.is_set(inorganic_flags::SOIL_ANY)
&& !mat_old.inorganic->flags.is_set(inorganic_flags::SOIL_ANY))
{
if(!warned)
{
out << "Changing a stone layer into soil is probably not wise." << endl
<< "The stone will remain and you get a soil floor after digging." << endl;
}
unsafe = true;
}
else if ( !mat_new.inorganic->flags.is_set(inorganic_flags::SOIL_ANY)
&& mat_old.inorganic->flags.is_set(inorganic_flags::SOIL_ANY))
{
if(!warned)
{
out << "Changing a soil layer into stone is probably not wise." << endl
<< "The soil will remain and you only get a stone floor after digging." << endl;
}
unsafe = true;
}
if(unsafe)
{
if(force)
{
out << "You've been warned, good luck." << endl;
allowed = true;
}
else
{
if(!warned)
{
out << "Use the option 'force' if you REALLY want to do that." << endl
<< "Weird things can happen with your map, so save your game before trying!" << endl
<< "Example: 'changelayer GRANITE force'" << endl;
warned = true;
}
allowed = false;
}
}
return allowed;
}

@ -11,7 +11,7 @@
// detail - print full name, date of birth, date of curse (vamp might use fake identity, though)
// show if the creature is active or dead, missing, ghostly (ghost vampires should not exist in 34.05)
// identify type of curse (works fine for vanilla ghosts, vamps, werebeasts, zombies and necromancers)
// nick - set nickname to 'CURSED' (does not always show up ingame, some vamps don't like nicknames)
// nick - set nickname to type of curse(does not always show up ingame, some vamps don't like nicknames)
// all - don't ignore dead and inactive creatures (former ghosts, dead necromancers, ...)
// verbose - acts like detail but also lists all curse tags (if you want to know it all).
@ -125,13 +125,13 @@ void setUnitNickname(df::unit *unit, const std::string &nick)
}
}
void cursedump (color_ostream &out, df::unit * unit);
std::string determineCurse(df::unit * unit)
{
string cursetype = "unknown";
// ghosts: ghostly, duh
// as of DF 34.05 and higher vampire ghosts and the like should not be possible
// if they get reintroduced later it will become necessary to watch 'ghostly' seperately
if(unit->flags3.bits.ghostly)
cursetype = "ghost";
@ -287,7 +287,9 @@ command_result cursecheck (color_ostream &out, vector <string> & parameters)
// dump all curse flags on demand
if (verbose)
{
cursedump(out, unit);
out << "Curse flags: "
<< bitfield_to_string(unit->curse.add_tags1) << endl
<< bitfield_to_string(unit->curse.add_tags2) << endl;
}
}
}
@ -300,73 +302,3 @@ command_result cursecheck (color_ostream &out, vector <string> & parameters)
return CR_OK;
}
void cursedump (color_ostream &out, df::unit * unit)
{
out << "Curse flags: ";
if(unit->curse.add_tags1.bits.BLOODSUCKER)
out << "bloodsucker ";
if(unit->curse.add_tags1.bits.EXTRAVISION)
out << "extravision ";
if(unit->curse.add_tags1.bits.OPPOSED_TO_LIFE)
out << "opposed_to_life ";
if(unit->curse.add_tags1.bits.NOT_LIVING)
out << "not_living ";
if(unit->curse.add_tags1.bits.NOEXERT)
out << "noexpert ";
if(unit->curse.add_tags1.bits.NOPAIN)
out << "nopain ";
if(unit->curse.add_tags1.bits.NOBREATHE)
out << "nobreathe ";
if(unit->curse.add_tags1.bits.HAS_BLOOD)
out << "has_blood ";
if(unit->curse.add_tags1.bits.NOSTUN)
out << "nostun ";
if(unit->curse.add_tags1.bits.NONAUSEA)
out << "nonausea ";
if(unit->curse.add_tags1.bits.NO_DIZZINESS)
out << "no_dizziness ";
if(unit->curse.add_tags1.bits.TRANCES)
out << "trances ";
if(unit->curse.add_tags1.bits.NOEMOTION)
out << "noemotion ";
if(unit->curse.add_tags1.bits.PARALYZEIMMUNE)
out << "paralyzeimmune ";
if(unit->curse.add_tags1.bits.NOFEAR)
out << "nofear ";
if(unit->curse.add_tags1.bits.NO_EAT)
out << "no_eat ";
if(unit->curse.add_tags1.bits.NO_DRINK)
out << "no_drink ";
if(unit->curse.add_tags1.bits.MISCHIEVOUS)
out << "mischievous ";
if(unit->curse.add_tags1.bits.NO_PHYS_ATT_GAIN)
out << "no_phys_att_gain ";
if(unit->curse.add_tags1.bits.NO_PHYS_ATT_RUST)
out << "no_phys_att_rust ";
if(unit->curse.add_tags1.bits.NOTHOUGHT)
out << "nothought ";
if(unit->curse.add_tags1.bits.NO_THOUGHT_CENTER_FOR_MOVEMENT)
out << "no_thought_center_for_movement ";
if(unit->curse.add_tags1.bits.CAN_SPEAK)
out << "can_speak ";
if(unit->curse.add_tags1.bits.CAN_LEARN)
out << "can_learn ";
if(unit->curse.add_tags1.bits.CRAZED)
out << "crazed ";
if(unit->curse.add_tags1.bits.BLOODSUCKER)
out << "bloodsucker ";
if(unit->curse.add_tags1.bits.SUPERNATURAL)
out << "supernatural ";
if(unit->curse.add_tags2.bits.NO_AGING)
out << "no_aging ";
if(unit->curse.add_tags2.bits.STERILE)
out << "sterile ";
if(unit->curse.add_tags2.bits.FIT_FOR_ANIMATION)
out << "fit_for_animation ";
if(unit->curse.add_tags2.bits.FIT_FOR_RESURRECTION)
out << "fit_for_resurrection ";
out << endl << endl;
}

@ -1,42 +0,0 @@
find_package(Qt4 QUIET)
find_package(OpenGL QUIET)
if(QT4_FOUND AND OPENGL_FOUND AND OPENGL_GLU_FOUND)
IF(QT_VERSION_MAJOR MATCHES 4 AND QT_VERSION_MINOR GREATER 6)
set( QT_USE_QTGUI TRUE )
set( QT_USE_QTOPENGL TRUE )
INCLUDE( ${QT_USE_FILE} )
include_directories(${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR} "${dfhack_SOURCE_DIR}/library/depends/tthread")
set ( qtplug_SRCS
qtplug.cpp
blankslade.cpp
glwidget.cpp
${dfhack_SOURCE_DIR}/library/depends/tthread/tinythread.cpp
)
SET ( qtplug_UI
gui/main.ui
)
SET( qtplug_RCS
gui/resources.qrc
)
# this command will generate rules that will run rcc on all files from blankslade_RCS
# in result blankslade_RC_SRCS variable will contain paths to files produced by rcc
QT4_ADD_RESOURCES( qtplug_RC_SRCS ${qtplug_RCS} )
QT4_WRAP_UI(qtplug_UI_h ${qtplug_UI})
qt4_automoc(${qtplug_SRCS})
DFHACK_PLUGIN(qtplug ${qtplug_SRCS} ${qtplug_RC_SRCS} ${qtplug_UI_h})
# a small texture file
install(FILES terrain.png DESTINATION ${DFHACK_LIBRARY_DESTINATION})
target_link_libraries(qtplug ${OPENGL_LIBRARIES} ${QT_LIBRARIES} )
ELSE(QT_VERSION_MAJOR MATCHES 4 AND QT_VERSION_MINOR GREATER 6)
MESSAGE(STATUS "Can't build the Qt plugin. Your Qt is too old.")
ENDIF(QT_VERSION_MAJOR MATCHES 4 AND QT_VERSION_MINOR GREATER 6)
else(QT4_FOUND AND OPENGL_FOUND AND OPENGL_GLU_FOUND)
MESSAGE(STATUS "Required libraries (Qt, GL, GLU) not found - Qt plugin can't be built.")
endif(QT4_FOUND AND OPENGL_FOUND AND OPENGL_GLU_FOUND)

@ -1,98 +0,0 @@
/*
* Copyright (c) 2010 Petr Mrázek (peterix)
* See LICENSE for details.
*/
#include "blankslade.h"
#include <QFileDialog>
#include <QDebug>
#include "glwidget.h"
blankslade::blankslade(QWidget *parent): QMainWindow(parent)
{
ui.setupUi(this);
GLWidget * glw = new GLWidget();
ui.gridding->addWidget(glw);
connect(ui.actionOpen,SIGNAL(triggered(bool)),this,SLOT(slotOpen(bool)));
connect(ui.actionQuit,SIGNAL(triggered(bool)),this,SLOT(slotQuit(bool)));
connect(ui.actionSave,SIGNAL(triggered(bool)),this,SLOT(slotSave(bool)));
connect(ui.actionSave_As,SIGNAL(triggered(bool)),this,SLOT(slotSaveAs(bool)));
ui.actionOpen->setIcon(QIcon::fromTheme("document-open"));
ui.actionOpen->setIconText(tr("Open"));
ui.actionSave->setIcon(QIcon::fromTheme("document-save"));
ui.actionSave->setIconText(tr("Save"));
ui.actionSave_As->setIcon(QIcon::fromTheme("document-save-as"));
ui.actionSave_As->setIconText(tr("Save As"));
ui.actionQuit->setIcon(QIcon::fromTheme("application-exit"));
ui.actionQuit->setIconText(tr("Run DF"));
}
blankslade::~blankslade()
{}
void blankslade::slotOpen(bool )
{
/*
QFileDialog fd(this,tr("Locate the Memoxy.xml file"));
fd.setNameFilter(tr("Memory definition (*.xml)"));
fd.setFileMode(QFileDialog::ExistingFile);
fd.setAcceptMode(QFileDialog::AcceptOpen);
int result = fd.exec();
if(result == QDialog::Accepted)
{
QStringList files = fd.selectedFiles();
QString fileName = files[0];
QDomDocument doc("memxml");
QFile file(fileName);
if(!file.open(QIODevice::ReadOnly))
{
return;
}
if(!doc.setContent(&file))
{
file.close();
return;
}
mod = new MemXMLModel(doc,this);
ui.entryView->setModel(mod);
file.close();
}
*/
}
void blankslade::slotQuit(bool )
{
close();
}
void blankslade::slotSave(bool )
{
// blah
}
void blankslade::slotRunDF(bool )
{
// blah
}
void blankslade::slotSaveAs(bool )
{
QFileDialog fd(this,tr("Choose file to save as..."));
fd.setNameFilter(tr("Memory definition (*.xml)"));
fd.setFileMode(QFileDialog::AnyFile);
fd.selectFile("Memory.xml");
fd.setAcceptMode(QFileDialog::AcceptSave);
int result = fd.exec();
if(result == QDialog::Accepted)
{
QStringList files = fd.selectedFiles();
QString file = files[0];
qDebug() << "File:" << file;
}
}
void blankslade::slotSetupDFs(bool )
{
}
#include "blankslade.moc"

@ -1,29 +0,0 @@
/*
* Copyright (c) 2010 Petr Mrázek (peterix)
* See LICENSE for details.
*/
#ifndef blankslade_H
#define blankslade_H
#include <QtGui/QMainWindow>
#include "ui_main.h"
class blankslade : public QMainWindow
{
Q_OBJECT
public:
blankslade(QWidget *parent = 0);
virtual ~blankslade();
private:
Ui::MainWindow ui;
public slots:
void slotOpen(bool);
void slotQuit(bool);
void slotSave(bool);
void slotSaveAs(bool);
void slotRunDF(bool);
void slotSetupDFs(bool);
};
#endif // blankslade_H

@ -1,246 +0,0 @@
/*
* Copyright (c) 2010 Petr Mrázek (peterix)
* See LICENSE for details.
*/
#include "glwidget.h"
#include <QtOpenGL>
#include <QGLBuffer>
#include <QGLShaderProgram>
#include <QGLPixelBuffer>
#include <iostream>
#include <GL/gl.h>
struct Vertex
{
float texcoord[2];
float color[3];
float position[3];
};
#define FRS 0.0625
#define FRX FRS/2
// this is crap
const Vertex house_vert[] =
{
// walls
{ { 0.0, 0.0 }, { 0.0, 0.0, 1.0 }, { -4.0, -4.0, -4.0 } },
{ { 0.0, FRS }, { 0.0, 1.0, 0.0 }, { -4.0, -4.0, 4.0 } },
{ { FRS, FRS }, { 0.0, 1.0, 1.0 }, { 4.0, -4.0, 4.0 } },
{ { FRS, 0.0 }, { 1.0, 0.0, 0.0 }, { 4.0, -4.0, -4.0 } },
{ { 0.0, 0.0 }, { 1.0, 0.0, 1.0 }, { -4.0, 4.0, -4.0 } },
{ { 0.0, FRS }, { 1.0, 1.0, 0.0 }, { -4.0, 4.0, 4.0 } },
{ { FRS, FRS }, { 1.0, 1.0, 1.0 }, { 4.0, 4.0, 4.0 } },
{ { FRS, 0.0 }, { 0.0, 0.0, 1.0 }, { 4.0, 4.0, -4.0 } },
{ { 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { -4.0, -4.0, -4.0 } },
{ { 0.0, FRS }, { 0.0, 1.0, 1.0 }, { -4.0, -4.0, 4.0 } },
{ { FRS, FRS }, { 1.0, 0.0, 0.0 }, { -4.0, 4.0, 4.0 } },
{ { FRS, 0.0 }, { 1.0, 0.0, 1.0 }, { -4.0, 4.0, -4.0 } },
{ { 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 4.0, -4.0, -4.0 } },
{ { 0.0, FRS }, { 0.0, 1.0, 1.0 }, { 4.0, -4.0, 4.0 } },
{ { FRS, FRS }, { 1.0, 0.0, 0.0 }, { 4.0, 4.0, 4.0 } },
{ { FRS, 0.0 }, { 1.0, 0.0, 1.0 }, { 4.0, 4.0, -4.0 } },
// roof
{ { 0.0, 0.0 }, { 0.0, 0.0, 1.0 }, { -4.0, 4.0, -4.0 } },
{ { FRS, 0.0 }, { 0.0, 1.0, 1.0 }, { 4.0, 4.0, -4.0 } },
{ { FRX, FRX }, { 1.0, 1.0, 1.0 }, { 0.0, 9.0, 0.0 } },
{ { FRS, 0.0 }, { 1.0, 0.0, 0.0 }, { 4.0, 4.0, -4.0 } },
{ { FRS, FRS }, { 1.0, 1.0, 0.0 }, { 4.0, 4.0, 4.0 } },
{ { FRX, FRX }, { 1.0, 1.0, 1.0 }, { 0.0, 9.0, 0.0 } },
{ { FRS, FRS }, { 0.0, 1.0, 0.0 }, { 4.0, 4.0, 4.0 } },
{ { 0.0, FRS }, { 0.0, 1.0, 1.0 }, { -4.0, 4.0, 4.0 } },
{ { FRX, FRX }, { 1.0, 1.0, 1.0 }, { 0.0, 9.0, 0.0 } },
{ { 0.0, FRS }, { 0.0, 1.0, 0.0 }, { -4.0, 4.0, 4.0 } },
{ { 0.0, 0.0 }, { 1.0, 1.0, 0.0 }, { -4.0, 4.0, -4.0 } },
{ { FRX, FRX }, { 1.0, 1.0, 1.0 }, { 0.0, 9.0, 0.0 } }
};
const unsigned char house_idx[] =
{
// walls
0, 1, 2, 0, 2, 3,
4, 5, 6, 4, 6, 7,
8, 9, 10, 8, 10, 11,
12, 13, 14, 12, 14, 15,
// roof
16, 17, 18,
19, 20, 21,
22, 23, 24,
25, 26, 27
};
class GLWPrivate
{
public:
QGLBuffer *VBO;
QGLBuffer *EBO;
QGLShaderProgram prog;
int positionAttrib;
int colorAttrib;
int texcoordsAttrib;
int mvpUniform;
int textureUniform;
int terrain;
float pz,rx,ry;
QPoint lastMouse;
};
GLWidget::GLWidget()
{
d = new GLWPrivate;
d->pz = -140.0f;
d->rx = d->ry = 0.0f;
d->VBO = d->EBO = 0;
startTimer( 10 );
}
GLWidget::~GLWidget()
{
if(d->VBO) delete d->VBO;
if(d->EBO) delete d->EBO;
delete d;
}
const char * VS_src =
"#version 130\n"
"in vec3 position; in vec3 color; uniform mat4 mvp; out vec3 c;"
"in vec2 tc_in; out vec2 coord;"
"void main()"
"{"
"gl_Position = mvp*vec4(position,1);"
"c = color;"
"coord = tc_in;"
"}";
const char * FS_src =
"#version 130\n"
"in vec3 c;"
//"out vec4 gl_FragColor;"
"in vec2 coord; uniform sampler2D tex;"
"void main()"
"{"
// "gl_FragColor = vec4(c,1);"
// "gl_FragColor = mix( texture(tex, coord), vec4(c,1), 0.5);"
// "gl_FragColor = vec4(c,1) - texture(tex, coord);"
"gl_FragColor = vec4(c,1) * texture(tex, coord);"
"}";
//initialization of OpenGL
void GLWidget::initializeGL()
{
bool test = 1;
test &= d->prog.addShaderFromSourceCode(QGLShader::Vertex,VS_src);
test &= d->prog.addShaderFromSourceCode(QGLShader::Fragment,FS_src);
test &= d->prog.link();
if(!test)
std::cout << "OUCH!" << std::endl;
d->positionAttrib = d->prog.attributeLocation("position");
d->colorAttrib = d->prog.attributeLocation("color");
d->texcoordsAttrib = d->prog.attributeLocation("tc_in");
d->mvpUniform = d->prog.uniformLocation("mvp");
d->textureUniform = d->prog.uniformLocation("tex");
if(d->positionAttrib == -1 || d->colorAttrib == -1 || d->mvpUniform == -1)
std::cout << "Bad attribs!" << std::endl;
QGLBuffer &VBO = *(d->VBO = new QGLBuffer(QGLBuffer::VertexBuffer));
VBO.create();
VBO.bind();
VBO.allocate(sizeof(house_vert));
VBO.write(0,house_vert,sizeof(house_vert));
QGLBuffer &EBO = *(d->EBO = new QGLBuffer(QGLBuffer::IndexBuffer));
EBO.create();
EBO.bind();
EBO.allocate(sizeof(house_idx));
EBO.write(0,house_idx,sizeof(house_idx));
QImage texture;
texture.load("terrain.png");
d->terrain = bindTexture(texture);
glClearColor(0.0f, 0.0f, 0.0f, 0.f);
glShadeModel( GL_SMOOTH );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
glEnable( GL_TEXTURE_2D );
glEnable( GL_DEPTH_TEST );
}
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
d->prog.bind();
QMatrix4x4 projection;
QMatrix4x4 mvp;
//projection.ortho(-10,10,-10,10,1,1000);
float aspect = (float)width()/(float)height();
projection.perspective(10,aspect,1,1000);
mvp = projection;
mvp.translate(0,0,d->pz);
mvp.rotate(d->ry,1,0,0);
mvp.rotate(d->rx,0,1,0);
d->prog.setUniformValue(d->mvpUniform,mvp);
//glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, d->terrain);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
d->prog.setUniformValue(d->textureUniform,0);
d->prog.enableAttributeArray(d->positionAttrib);
d->prog.enableAttributeArray(d->colorAttrib);
d->prog.enableAttributeArray(d->texcoordsAttrib);
d->VBO->bind();
d->prog.setAttributeBuffer(d->texcoordsAttrib, GL_FLOAT, offsetof(Vertex, texcoord), 2, sizeof(Vertex));
d->prog.setAttributeBuffer(d->positionAttrib, GL_FLOAT, offsetof(Vertex, position), 3, sizeof(Vertex));
d->prog.setAttributeBuffer(d->colorAttrib, GL_FLOAT, offsetof(Vertex, color), 3, sizeof(Vertex));
d->EBO->bind();
glDrawElements(GL_TRIANGLES, d->EBO->size(), GL_UNSIGNED_BYTE, NULL);
d->prog.release();
}
void GLWidget::resizeGL(int width, int height)
{
glViewport(0, 0, width, height);
}
void GLWidget::mousePressEvent(QMouseEvent *event)
{
d->lastMouse = event->pos();
}
void GLWidget::mouseMoveEvent(QMouseEvent *event)
{
int dx = event->x() - d->lastMouse.x();
int dy = event->y() - d->lastMouse.y();
if (event->buttons() & Qt::LeftButton)
{
d->rx = d->rx + dx;
d->ry = d->ry + dy;
}
d->lastMouse = event->pos();
}
void GLWidget::timerEvent(QTimerEvent *event)
{
updateGL();
}

@ -1,32 +0,0 @@
/*
* Copyright (c) 2010 Petr Mrázek (peterix)
* See LICENSE for details.
*/
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QGLWidget>
class GLWPrivate;
class GLWidget : public QGLWidget
{
public:
GLWidget();
~GLWidget();
float rot;
void resizeGL(int width, int height);
protected:
void initializeGL();
void paintGL();
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void timerEvent(QTimerEvent *event);
private:
GLWPrivate * d;
};
#endif // GLWIDGET_H

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

@ -1,361 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>662</width>
<height>836</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="windowIcon">
<iconset resource="resources.qrc">
<normaloff>:/main_icon/main_64.png</normaloff>:/main_icon/main_64.png</iconset>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridding">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
</layout>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QDockWidget" name="scene_dock">
<property name="features">
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
</property>
<property name="allowedAreas">
<set>Qt::RightDockWidgetArea</set>
</property>
<property name="windowTitle">
<string>Scéna</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Exponent n</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QSlider" name="slideExponentN">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="spinExponentN"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Exponent e</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QSlider" name="slideExponentE">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="spinExponentE"/>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<widget class="QDial" name="dialLight"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Světlo</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Objekt</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDial" name="dial_2"/>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Textura</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>96</width>
<height>96</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/blah/tileable.jpg</normaloff>:/blah/tileable.jpg</iconset>
</property>
<property name="iconSize">
<size>
<width>80</width>
<height>80</height>
</size>
</property>
<property name="default">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>Render</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
<zorder>pushButton_2</zorder>
<zorder>verticalLayoutWidget</zorder>
<zorder>pushButton</zorder>
<zorder>gridLayoutWidget</zorder>
</widget>
</widget>
<widget class="QDockWidget" name="dock_example">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="features">
<set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
</property>
<property name="allowedAreas">
<set>Qt::BottomDockWidgetArea|Qt::LeftDockWidgetArea|Qt::TopDockWidgetArea</set>
</property>
<property name="windowTitle">
<string>Ukázky</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_3">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QListWidget" name="listWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="movement">
<enum>QListView::Static</enum>
</property>
<property name="flow">
<enum>QListView::TopToBottom</enum>
</property>
<property name="isWrapping" stdset="0">
<bool>true</bool>
</property>
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="layoutMode">
<enum>QListView::SinglePass</enum>
</property>
<property name="spacing">
<number>10</number>
</property>
<property name="viewMode">
<enum>QListView::ListMode</enum>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="selectionRectVisible">
<bool>false</bool>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>Koule</string>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/blah/koule.png</normaloff>:/blah/koule.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Krychle</string>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/blah/krychle.png</normaloff>:/blah/krychle.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Válec</string>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/blah/valec.png</normaloff>:/blah/valec.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Diamant</string>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/blah/diamant.png</normaloff>:/blah/diamant.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>a=3,b=3</string>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/blah/33.png</normaloff>:/blah/33.png</iconset>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</widget>
<action name="actionOpen">
<property name="text">
<string>Open</string>
</property>
</action>
<action name="actionSave">
<property name="text">
<string>Save</string>
</property>
</action>
<action name="actionSave_As">
<property name="text">
<string>Save As</string>
</property>
</action>
<action name="actionQuit">
<property name="text">
<string>Quit</string>
</property>
</action>
</widget>
<resources>
<include location="resources.qrc"/>
</resources>
<connections/>
</ui>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

@ -1,15 +0,0 @@
<RCC>
<qresource prefix="main_icon">
<file>main_64.png</file>
<file>main_16.png</file>
<file>main_32.png</file>
</qresource>
<qresource prefix="blah">
<file>tileable.jpg</file>
<file>33.png</file>
<file>diamant.png</file>
<file>koule.png</file>
<file>krychle.png</file>
<file>valec.png</file>
</qresource>
</RCC>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

@ -1,69 +0,0 @@
#include "Core.h"
#include <Console.h>
#include <Export.h>
#include <PluginManager.h>
#include <modules/Maps.h>
#include <modules/Gui.h>
//#include <extra/MapExtras.h>
#include <vector>
#include <cstdio>
#include <stack>
#include <string>
#include <QtGui/QApplication>
#include "blankslade.h"
#include "tinythread.h"
using std::vector;
using std::string;
using std::stack;
using namespace DFHack;
static void runnable(void *);
static tthread::mutex * instance_mutex = 0;
static bool running = false;
static tthread::thread * QTThread;
command_result runqt (Core * c, vector <string> & parameters);
DFHACK_PLUGIN("qtplug");
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
{
instance_mutex = new tthread::mutex();
commands.clear();
commands.push_back(PluginCommand("runqt","Open an interactive Qt gui.",runqt));
return CR_OK;
}
DFhackCExport command_result plugin_shutdown ( Core * c )
{
return CR_FAILURE;
}
command_result runqt (Core * c, vector <string> & parameters)
{
instance_mutex->lock();
if(!running)
{
running = true;
QTThread = new tthread::thread(runnable, 0);
}
else
{
c->con.printerr("The Qt test plugin is already running!\n");
}
instance_mutex->unlock();
return CR_OK;
}
static void runnable(void *)
{
int zero = 0;
QApplication app(zero, 0);
blankslade appGui;
appGui.show();
app.exec();
instance_mutex->lock();
running = false;
instance_mutex->unlock();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

@ -1,42 +0,0 @@
PROJECT (server)
SET(PROJECT_SRCS
main.cpp
)
include_directories( ${CMAKE_SOURCE_DIR} )
IF(UNIX)
OPTION(SERVER_INTERNAL_SO "Link with prebuilt internal zeromq lib and headers." ON)
IF(SERVER_INTERNAL_SO)
SET(PROJECT_LIBS
${server_SOURCE_DIR}/zeromq/libzmq.so.1
${PROJECT_LIBS}
)
include_directories (
${include_directories}
${server_SOURCE_DIR}/zeromq
)
install(PROGRAMS ${server_SOURCE_DIR}/zeromq/libzmq.so.1 DESTINATION ${DFHACK_LIBRARY_DESTINATION})
ELSE()
SET(PROJECT_LIBS
zmq
${PROJECT_LIBS}
)
ENDIF()
ELSE()
SET(PROJECT_LIBS
${server_SOURCE_DIR}/zeromq/libzmq.lib
${PROJECT_LIBS}
)
include_directories (
${include_directories}
${server_SOURCE_DIR}/zeromq
)
install(PROGRAMS ${server_SOURCE_DIR}/zeromq/libzmq.dll DESTINATION ${DFHACK_LIBRARY_DESTINATION})
ENDIF()
DFHACK_PLUGIN(server ${PROJECT_SRCS} LINK_LIBRARIES ${PROJECT_LIBS})
add_executable ( helloclient hello.cpp )
target_link_libraries ( helloclient ${PROJECT_LIBS})
install(TARGETS helloclient RUNTIME DESTINATION . )

@ -1,39 +0,0 @@
//
// Hello World client
// Connects REQ socket to tcp://localhost:5555
// Sends "Hello" to server, expects "World" back
//
#include <zmq.h>
#include <string.h>
#include <stdio.h>
//#include <unistd.h>
int main (void)
{
void *context = zmq_init (1);
// Socket to talk to server
printf ("Connecting to hello world server...\n");
void *requester = zmq_socket (context, ZMQ_REQ);
zmq_connect (requester, "tcp://localhost:5555");
int request_nbr;
for (request_nbr = 0; request_nbr != 10; request_nbr++)
{
zmq_msg_t request;
zmq_msg_init_size (&request, 5);
memcpy (zmq_msg_data (&request), "Hello", 5);
printf ("Sending Hello %d...\n", request_nbr);
zmq_send (requester, &request, 0);
zmq_msg_close (&request);
zmq_msg_t reply;
zmq_msg_init (&reply);
zmq_recv (requester, &reply, 0);
printf ("Received World %d\n", request_nbr);
zmq_msg_close (&reply);
}
zmq_close (requester);
zmq_term (context);
return 0;
}

@ -1,79 +0,0 @@
#include "Core.h"
#include <Console.h>
#include <Export.h>
#include <PluginManager.h>
#include <zmq.hpp>
#ifndef LINUX_BUILD
#include <windows.h>
#endif
using namespace DFHack;
// Here go all the command declarations...
// mostly to allow having the mandatory stuff on top of the file and commands on the bottom
command_result server (color_ostream &out, std::vector <std::string> & parameters);
// A plugins must be able to return its name. This must correspond to the filename - skeleton.plug.so or skeleton.plug.dll
DFHACK_PLUGIN("server");
// Mandatory init function. If you have some global state, create it here.
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{
// Fill the command list with your commands.
commands.clear();
commands.push_back(PluginCommand("server",
"Inane zeromq example turned into a plugin.",
server));
return CR_OK;
}
// This is called right before the plugin library is removed from memory.
DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{
// You *MUST* kill all threads you created before this returns.
// If everythin fails, just return CR_FAILURE. Your plugin will be
// in a zombie state, but things won't crash.
return CR_OK;
}
// This is WRONG and STUPID. Never use this as an example!
command_result server (color_ostream &out, std::vector <std::string> & parameters)
{
// It's nice to provide a 'help' option for your command.
// It's also nice to print the same help if you get invalid options from the user instead of just acting strange
for(int i = 0; i < parameters.size();i++)
{
if(parameters[i] == "help" || parameters[i] == "?")
{
// Core has a handle to the console. The console is thread-safe.
// Only one thing can read from it at a time though...
out.print("This command is a simple Hello World example for zeromq!\n");
return CR_OK;
}
}
// Prepare our context and socket
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_REP);
socket.bind ("tcp://*:5555");
while (true)
{
zmq::message_t request;
// Wait for next request from client
socket.recv (&request);
out.print("Received Hello\n");
// Do some 'work'
#ifdef LINUX_BUILD
sleep (1);
#else
Sleep(1000);
#endif
// Send reply back to client
zmq::message_t reply (5);
memcpy ((void *) reply.data (), "World", 5);
socket.send (reply);
}
return CR_OK;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,41 +0,0 @@
# libzmq.la - a libtool library file
# Generated by ltmain.sh (GNU libtool) 2.2.6b Debian-2.2.6b-2ubuntu1
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname='libzmq.so.1'
# Names of this library.
library_names='libzmq.so.1.0.0 libzmq.so.1 libzmq.so'
# The name of the static archive.
old_library='libzmq.a'
# Linker flags that can not go in dependency_libs.
inherited_linker_flags=''
# Libraries that this one depends upon.
dependency_libs=' -luuid -lrt -lpthread'
# Names of additional weak libraries provided by this library
weak_library_names=''
# Version information for libzmq.
current=1
age=0
revision=0
# Is this an already installed library?
installed=yes
# Should we warn about portability when linking against -modules?
shouldnotlink=no
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/home/peterix/zeromq/lib'

Binary file not shown.

Binary file not shown.

@ -1,269 +0,0 @@
/*
Copyright (c) 2007-2011 iMatix Corporation
Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ZMQ_H_INCLUDED__
#define __ZMQ_H_INCLUDED__
#ifdef __cplusplus
extern "C" {
#endif
#include <errno.h>
#include <stddef.h>
#if defined _WIN32
#include <winsock2.h>
#endif
/* Handle DSO symbol visibility */
#if defined _WIN32
# if defined DLL_EXPORT
# define ZMQ_EXPORT __declspec(dllexport)
# else
# define ZMQ_EXPORT __declspec(dllimport)
# endif
#else
# if defined __SUNPRO_C || defined __SUNPRO_CC
# define ZMQ_EXPORT __global
# elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER
# define ZMQ_EXPORT __attribute__ ((visibility("default")))
# else
# define ZMQ_EXPORT
# endif
#endif
/******************************************************************************/
/* 0MQ versioning support. */
/******************************************************************************/
/* Version macros for compile-time API version detection */
#define ZMQ_VERSION_MAJOR 2
#define ZMQ_VERSION_MINOR 1
#define ZMQ_VERSION_PATCH 10
#define ZMQ_MAKE_VERSION(major, minor, patch) \
((major) * 10000 + (minor) * 100 + (patch))
#define ZMQ_VERSION \
ZMQ_MAKE_VERSION(ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH)
/* Run-time API version detection */
ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch);
/******************************************************************************/
/* 0MQ errors. */
/******************************************************************************/
/* A number random enough not to collide with different errno ranges on */
/* different OSes. The assumption is that error_t is at least 32-bit type. */
#define ZMQ_HAUSNUMERO 156384712
/* On Windows platform some of the standard POSIX errnos are not defined. */
#ifndef ENOTSUP
#define ENOTSUP (ZMQ_HAUSNUMERO + 1)
#endif
#ifndef EPROTONOSUPPORT
#define EPROTONOSUPPORT (ZMQ_HAUSNUMERO + 2)
#endif
#ifndef ENOBUFS
#define ENOBUFS (ZMQ_HAUSNUMERO + 3)
#endif
#ifndef ENETDOWN
#define ENETDOWN (ZMQ_HAUSNUMERO + 4)
#endif
#ifndef EADDRINUSE
#define EADDRINUSE (ZMQ_HAUSNUMERO + 5)
#endif
#ifndef EADDRNOTAVAIL
#define EADDRNOTAVAIL (ZMQ_HAUSNUMERO + 6)
#endif
#ifndef ECONNREFUSED
#define ECONNREFUSED (ZMQ_HAUSNUMERO + 7)
#endif
#ifndef EINPROGRESS
#define EINPROGRESS (ZMQ_HAUSNUMERO + 8)
#endif
#ifndef ENOTSOCK
#define ENOTSOCK (ZMQ_HAUSNUMERO + 9)
#endif
/* Native 0MQ error codes. */
#define EFSM (ZMQ_HAUSNUMERO + 51)
#define ENOCOMPATPROTO (ZMQ_HAUSNUMERO + 52)
#define ETERM (ZMQ_HAUSNUMERO + 53)
#define EMTHREAD (ZMQ_HAUSNUMERO + 54)
/* This function retrieves the errno as it is known to 0MQ library. The goal */
/* of this function is to make the code 100% portable, including where 0MQ */
/* compiled with certain CRT library (on Windows) is linked to an */
/* application that uses different CRT library. */
ZMQ_EXPORT int zmq_errno (void);
/* Resolves system errors and 0MQ errors to human-readable string. */
ZMQ_EXPORT const char *zmq_strerror (int errnum);
/******************************************************************************/
/* 0MQ message definition. */
/******************************************************************************/
/* Maximal size of "Very Small Message". VSMs are passed by value */
/* to avoid excessive memory allocation/deallocation. */
/* If VMSs larger than 255 bytes are required, type of 'vsm_size' */
/* field in zmq_msg_t structure should be modified accordingly. */
#define ZMQ_MAX_VSM_SIZE 30
/* Message types. These integers may be stored in 'content' member of the */
/* message instead of regular pointer to the data. */
#define ZMQ_DELIMITER 31
#define ZMQ_VSM 32
/* Message flags. ZMQ_MSG_SHARED is strictly speaking not a message flag */
/* (it has no equivalent in the wire format), however, making it a flag */
/* allows us to pack the stucture tigher and thus improve performance. */
#define ZMQ_MSG_MORE 1
#define ZMQ_MSG_SHARED 128
#define ZMQ_MSG_MASK 129 /* Merges all the flags */
/* A message. Note that 'content' is not a pointer to the raw data. */
/* Rather it is pointer to zmq::msg_content_t structure */
/* (see src/msg_content.hpp for its definition). */
typedef struct
{
void *content;
unsigned char flags;
unsigned char vsm_size;
unsigned char vsm_data [ZMQ_MAX_VSM_SIZE];
} zmq_msg_t;
typedef void (zmq_free_fn) (void *data, void *hint);
ZMQ_EXPORT int zmq_msg_init (zmq_msg_t *msg);
ZMQ_EXPORT int zmq_msg_init_size (zmq_msg_t *msg, size_t size);
ZMQ_EXPORT int zmq_msg_init_data (zmq_msg_t *msg, void *data,
size_t size, zmq_free_fn *ffn, void *hint);
ZMQ_EXPORT int zmq_msg_close (zmq_msg_t *msg);
ZMQ_EXPORT int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src);
ZMQ_EXPORT int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src);
ZMQ_EXPORT void *zmq_msg_data (zmq_msg_t *msg);
ZMQ_EXPORT size_t zmq_msg_size (zmq_msg_t *msg);
/******************************************************************************/
/* 0MQ infrastructure (a.k.a. context) initialisation & termination. */
/******************************************************************************/
ZMQ_EXPORT void *zmq_init (int io_threads);
ZMQ_EXPORT int zmq_term (void *context);
/******************************************************************************/
/* 0MQ socket definition. */
/******************************************************************************/
/* Socket types. */
#define ZMQ_PAIR 0
#define ZMQ_PUB 1
#define ZMQ_SUB 2
#define ZMQ_REQ 3
#define ZMQ_REP 4
#define ZMQ_DEALER 5
#define ZMQ_ROUTER 6
#define ZMQ_PULL 7
#define ZMQ_PUSH 8
#define ZMQ_XPUB 9
#define ZMQ_XSUB 10
#define ZMQ_XREQ ZMQ_DEALER /* Old alias, remove in 3.x */
#define ZMQ_XREP ZMQ_ROUTER /* Old alias, remove in 3.x */
#define ZMQ_UPSTREAM ZMQ_PULL /* Old alias, remove in 3.x */
#define ZMQ_DOWNSTREAM ZMQ_PUSH /* Old alias, remove in 3.x */
/* Socket options. */
#define ZMQ_HWM 1
#define ZMQ_SWAP 3
#define ZMQ_AFFINITY 4
#define ZMQ_IDENTITY 5
#define ZMQ_SUBSCRIBE 6
#define ZMQ_UNSUBSCRIBE 7
#define ZMQ_RATE 8
#define ZMQ_RECOVERY_IVL 9
#define ZMQ_MCAST_LOOP 10
#define ZMQ_SNDBUF 11
#define ZMQ_RCVBUF 12
#define ZMQ_RCVMORE 13
#define ZMQ_FD 14
#define ZMQ_EVENTS 15
#define ZMQ_TYPE 16
#define ZMQ_LINGER 17
#define ZMQ_RECONNECT_IVL 18
#define ZMQ_BACKLOG 19
#define ZMQ_RECOVERY_IVL_MSEC 20 /* opt. recovery time, reconcile in 3.x */
#define ZMQ_RECONNECT_IVL_MAX 21
/* Send/recv options. */
#define ZMQ_NOBLOCK 1
#define ZMQ_SNDMORE 2
ZMQ_EXPORT void *zmq_socket (void *context, int type);
ZMQ_EXPORT int zmq_close (void *s);
ZMQ_EXPORT int zmq_setsockopt (void *s, int option, const void *optval,
size_t optvallen);
ZMQ_EXPORT int zmq_getsockopt (void *s, int option, void *optval,
size_t *optvallen);
ZMQ_EXPORT int zmq_bind (void *s, const char *addr);
ZMQ_EXPORT int zmq_connect (void *s, const char *addr);
ZMQ_EXPORT int zmq_send (void *s, zmq_msg_t *msg, int flags);
ZMQ_EXPORT int zmq_recv (void *s, zmq_msg_t *msg, int flags);
/******************************************************************************/
/* I/O multiplexing. */
/******************************************************************************/
#define ZMQ_POLLIN 1
#define ZMQ_POLLOUT 2
#define ZMQ_POLLERR 4
typedef struct
{
void *socket;
#if defined _WIN32
SOCKET fd;
#else
int fd;
#endif
short events;
short revents;
} zmq_pollitem_t;
ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout);
/******************************************************************************/
/* Built-in devices */
/******************************************************************************/
#define ZMQ_STREAMER 1
#define ZMQ_FORWARDER 2
#define ZMQ_QUEUE 3
ZMQ_EXPORT int zmq_device (int device, void * insocket, void* outsocket);
#undef ZMQ_EXPORT
#ifdef __cplusplus
}
#endif
#endif

@ -1,301 +0,0 @@
/*
Copyright (c) 2007-2011 iMatix Corporation
Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ZMQ_HPP_INCLUDED__
#define __ZMQ_HPP_INCLUDED__
#include "zmq.h"
#include <cassert>
#include <cstring>
#include <exception>
namespace zmq
{
typedef zmq_free_fn free_fn;
typedef zmq_pollitem_t pollitem_t;
class error_t : public std::exception
{
public:
error_t () : errnum (zmq_errno ()) {}
virtual const char *what () const throw ()
{
return zmq_strerror (errnum);
}
int num () const
{
return errnum;
}
private:
int errnum;
};
inline int poll (zmq_pollitem_t *items_, int nitems_, long timeout_ = -1)
{
int rc = zmq_poll (items_, nitems_, timeout_);
if (rc < 0)
throw error_t ();
return rc;
}
inline void device (int device_, void * insocket_, void* outsocket_)
{
int rc = zmq_device (device_, insocket_, outsocket_);
if (rc != 0)
throw error_t ();
}
inline void version (int *major_, int *minor_, int *patch_)
{
zmq_version (major_, minor_, patch_);
}
class message_t : private zmq_msg_t
{
friend class socket_t;
public:
inline message_t ()
{
int rc = zmq_msg_init (this);
if (rc != 0)
throw error_t ();
}
inline message_t (size_t size_)
{
int rc = zmq_msg_init_size (this, size_);
if (rc != 0)
throw error_t ();
}
inline message_t (void *data_, size_t size_, free_fn *ffn_,
void *hint_ = NULL)
{
int rc = zmq_msg_init_data (this, data_, size_, ffn_, hint_);
if (rc != 0)
throw error_t ();
}
inline ~message_t ()
{
int rc = zmq_msg_close (this);
assert (rc == 0);
}
inline void rebuild ()
{
int rc = zmq_msg_close (this);
if (rc != 0)
throw error_t ();
rc = zmq_msg_init (this);
if (rc != 0)
throw error_t ();
}
inline void rebuild (size_t size_)
{
int rc = zmq_msg_close (this);
if (rc != 0)
throw error_t ();
rc = zmq_msg_init_size (this, size_);
if (rc != 0)
throw error_t ();
}
inline void rebuild (void *data_, size_t size_, free_fn *ffn_,
void *hint_ = NULL)
{
int rc = zmq_msg_close (this);
if (rc != 0)
throw error_t ();
rc = zmq_msg_init_data (this, data_, size_, ffn_, hint_);
if (rc != 0)
throw error_t ();
}
inline void move (message_t *msg_)
{
int rc = zmq_msg_move (this, (zmq_msg_t*) msg_);
if (rc != 0)
throw error_t ();
}
inline void copy (message_t *msg_)
{
int rc = zmq_msg_copy (this, (zmq_msg_t*) msg_);
if (rc != 0)
throw error_t ();
}
inline void *data ()
{
return zmq_msg_data (this);
}
inline size_t size ()
{
return zmq_msg_size (this);
}
private:
// Disable implicit message copying, so that users won't use shared
// messages (less efficient) without being aware of the fact.
message_t (const message_t&);
void operator = (const message_t&);
};
class context_t
{
friend class socket_t;
public:
inline context_t (int io_threads_)
{
ptr = zmq_init (io_threads_);
if (ptr == NULL)
throw error_t ();
}
inline ~context_t ()
{
int rc = zmq_term (ptr);
assert (rc == 0);
}
// Be careful with this, it's probably only useful for
// using the C api together with an existing C++ api.
// Normally you should never need to use this.
inline operator void* ()
{
return ptr;
}
private:
void *ptr;
context_t (const context_t&);
void operator = (const context_t&);
};
class socket_t
{
public:
inline socket_t (context_t &context_, int type_)
{
ptr = zmq_socket (context_.ptr, type_);
if (ptr == NULL)
throw error_t ();
}
inline ~socket_t ()
{
close();
}
inline operator void* ()
{
return ptr;
}
inline void close()
{
if(ptr == NULL)
// already closed
return ;
int rc = zmq_close (ptr);
if (rc != 0)
throw error_t ();
ptr = 0 ;
}
inline void setsockopt (int option_, const void *optval_,
size_t optvallen_)
{
int rc = zmq_setsockopt (ptr, option_, optval_, optvallen_);
if (rc != 0)
throw error_t ();
}
inline void getsockopt (int option_, void *optval_,
size_t *optvallen_)
{
int rc = zmq_getsockopt (ptr, option_, optval_, optvallen_);
if (rc != 0)
throw error_t ();
}
inline void bind (const char *addr_)
{
int rc = zmq_bind (ptr, addr_);
if (rc != 0)
throw error_t ();
}
inline void connect (const char *addr_)
{
int rc = zmq_connect (ptr, addr_);
if (rc != 0)
throw error_t ();
}
inline bool send (message_t &msg_, int flags_ = 0)
{
int rc = zmq_send (ptr, &msg_, flags_);
if (rc == 0)
return true;
if (rc == -1 && zmq_errno () == EAGAIN)
return false;
throw error_t ();
}
inline bool recv (message_t *msg_, int flags_ = 0)
{
int rc = zmq_recv (ptr, msg_, flags_);
if (rc == 0)
return true;
if (rc == -1 && zmq_errno () == EAGAIN)
return false;
throw error_t ();
}
private:
void *ptr;
socket_t (const socket_t&);
void operator = (const socket_t&);
};
}
#endif

@ -1,64 +0,0 @@
/*
Copyright (c) 2007-2011 iMatix Corporation
Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ZMQ_UTILS_H_INCLUDED__
#define __ZMQ_UTILS_H_INCLUDED__
#ifdef __cplusplus
extern "C" {
#endif
/* Handle DSO symbol visibility */
#if defined _WIN32
# if defined DLL_EXPORT
# define ZMQ_EXPORT __declspec(dllexport)
# else
# define ZMQ_EXPORT __declspec(dllimport)
# endif
#else
# if defined __SUNPRO_C || defined __SUNPRO_CC
# define ZMQ_EXPORT __global
# elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER
# define ZMQ_EXPORT __attribute__ ((visibility("default")))
# else
# define ZMQ_EXPORT
# endif
#endif
/* Helper functions are used by perf tests so that they don't have to care */
/* about minutiae of time-related functions on different OS platforms. */
/* Starts the stopwatch. Returns the handle to the watch. */
ZMQ_EXPORT void *zmq_stopwatch_start (void);
/* Stops the stopwatch. Returns the number of microseconds elapsed since */
/* the stopwatch was started. */
ZMQ_EXPORT unsigned long zmq_stopwatch_stop (void *watch_);
/* Sleeps for specified number of seconds. */
ZMQ_EXPORT void zmq_sleep (int seconds_);
#undef ZMQ_EXPORT
#ifdef __cplusplus
}
#endif
#endif

@ -1 +1 @@
Subproject commit 7525c003089367823183eaf5093a90271a5eb9b4
Subproject commit f854810fb76a6c83a9ccd3a50f526963b5c85b90