Merge branch 'master' of git://github.com/peterix/dfhack
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
Subproject commit 8f2fdb4e0258db7a139e26f1084f05f9a45824c3
|
Subproject commit 3e1c728640d8f5a9501908064a2d5385a156058c
|
@ -1,17 +0,0 @@
|
|||||||
#ifndef BIT_H
|
|
||||||
#define BIT_H
|
|
||||||
|
|
||||||
#define LUA_BITOP_VERSION "1.0.1"
|
|
||||||
|
|
||||||
#define LUA_LIB
|
|
||||||
#include "lua.h"
|
|
||||||
#include "lauxlib.h"
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
LUALIB_API int luaopen_bit(lua_State *L);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif // BIT_H
|
|
||||||
|
|
@ -1,181 +0,0 @@
|
|||||||
/*
|
|
||||||
** Lua BitOp -- a bit operations library for Lua 5.1.
|
|
||||||
** http://bitop.luajit.org/
|
|
||||||
**
|
|
||||||
** Copyright (C) 2008-2009 Mike Pall. All rights reserved.
|
|
||||||
**
|
|
||||||
** Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
** a copy of this software and associated documentation files (the
|
|
||||||
** "Software"), to deal in the Software without restriction, including
|
|
||||||
** without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
** permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
** the following conditions:
|
|
||||||
**
|
|
||||||
** The above copyright notice and this permission notice shall be
|
|
||||||
** included in all copies or substantial portions of the Software.
|
|
||||||
**
|
|
||||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
**
|
|
||||||
** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "bit.h"
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
/* MSVC is stuck in the last century and doesn't have C99's stdint.h. */
|
|
||||||
typedef __int32 int32_t;
|
|
||||||
typedef unsigned __int32 uint32_t;
|
|
||||||
typedef unsigned __int64 uint64_t;
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef int32_t SBits;
|
|
||||||
typedef uint32_t UBits;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
lua_Number n;
|
|
||||||
#ifdef LUA_NUMBER_DOUBLE
|
|
||||||
uint64_t b;
|
|
||||||
#else
|
|
||||||
UBits b;
|
|
||||||
#endif
|
|
||||||
} BitNum;
|
|
||||||
|
|
||||||
/* Convert argument to bit type. */
|
|
||||||
static UBits barg(lua_State *L, int idx)
|
|
||||||
{
|
|
||||||
BitNum bn;
|
|
||||||
UBits b;
|
|
||||||
bn.n = lua_tonumber(L, idx);
|
|
||||||
#if defined(LUA_NUMBER_DOUBLE)
|
|
||||||
bn.n += 6755399441055744.0; /* 2^52+2^51 */
|
|
||||||
#ifdef SWAPPED_DOUBLE
|
|
||||||
b = (UBits)(bn.b >> 32);
|
|
||||||
#else
|
|
||||||
b = (UBits)bn.b;
|
|
||||||
#endif
|
|
||||||
#elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \
|
|
||||||
defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \
|
|
||||||
defined(LUA_NUMBER_LLONG)
|
|
||||||
if (sizeof(UBits) == sizeof(lua_Number))
|
|
||||||
b = bn.b;
|
|
||||||
else
|
|
||||||
b = (UBits)(SBits)bn.n;
|
|
||||||
#elif defined(LUA_NUMBER_FLOAT)
|
|
||||||
#error "A 'float' lua_Number type is incompatible with this library"
|
|
||||||
#else
|
|
||||||
#error "Unknown number type, check LUA_NUMBER_* in luaconf.h"
|
|
||||||
#endif
|
|
||||||
if (b == 0 && !lua_isnumber(L, idx))
|
|
||||||
luaL_typerror(L, idx, "number");
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return bit type. */
|
|
||||||
#define BRET(b) lua_pushnumber(L, (lua_Number)(SBits)(b)); return 1;
|
|
||||||
|
|
||||||
static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) }
|
|
||||||
static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) }
|
|
||||||
|
|
||||||
#define BIT_OP(func, opr) \
|
|
||||||
static int func(lua_State *L) { int i; UBits b = barg(L, 1); \
|
|
||||||
for (i = lua_gettop(L); i > 1; i--) b opr barg(L, i); BRET(b) }
|
|
||||||
BIT_OP(bit_band, &=)
|
|
||||||
BIT_OP(bit_bor, |=)
|
|
||||||
BIT_OP(bit_bxor, ^=)
|
|
||||||
|
|
||||||
#define bshl(b, n) (b << n)
|
|
||||||
#define bshr(b, n) (b >> n)
|
|
||||||
#define bsar(b, n) ((SBits)b >> n)
|
|
||||||
#define brol(b, n) ((b << n) | (b >> (32-n)))
|
|
||||||
#define bror(b, n) ((b << (32-n)) | (b >> n))
|
|
||||||
#define BIT_SH(func, fn) \
|
|
||||||
static int func(lua_State *L) { \
|
|
||||||
UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) }
|
|
||||||
BIT_SH(bit_lshift, bshl)
|
|
||||||
BIT_SH(bit_rshift, bshr)
|
|
||||||
BIT_SH(bit_arshift, bsar)
|
|
||||||
BIT_SH(bit_rol, brol)
|
|
||||||
BIT_SH(bit_ror, bror)
|
|
||||||
|
|
||||||
static int bit_bswap(lua_State *L)
|
|
||||||
{
|
|
||||||
UBits b = barg(L, 1);
|
|
||||||
b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24);
|
|
||||||
BRET(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bit_tohex(lua_State *L)
|
|
||||||
{
|
|
||||||
UBits b = barg(L, 1);
|
|
||||||
SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2);
|
|
||||||
const char *hexdigits = "0123456789abcdef";
|
|
||||||
char buf[8];
|
|
||||||
int i;
|
|
||||||
if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
|
|
||||||
if (n > 8) n = 8;
|
|
||||||
for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
|
|
||||||
lua_pushlstring(L, buf, (size_t)n);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct luaL_Reg bit_funcs[] = {
|
|
||||||
{ "tobit", bit_tobit },
|
|
||||||
{ "bnot", bit_bnot },
|
|
||||||
{ "band", bit_band },
|
|
||||||
{ "bor", bit_bor },
|
|
||||||
{ "bxor", bit_bxor },
|
|
||||||
{ "lshift", bit_lshift },
|
|
||||||
{ "rshift", bit_rshift },
|
|
||||||
{ "arshift", bit_arshift },
|
|
||||||
{ "rol", bit_rol },
|
|
||||||
{ "ror", bit_ror },
|
|
||||||
{ "bswap", bit_bswap },
|
|
||||||
{ "tohex", bit_tohex },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Signed right-shifts are implementation-defined per C89/C99.
|
|
||||||
** But the de facto standard are arithmetic right-shifts on two's
|
|
||||||
** complement CPUs. This behaviour is required here, so test for it.
|
|
||||||
*/
|
|
||||||
#define BAD_SAR (bsar(-8, 2) != (SBits)-2)
|
|
||||||
|
|
||||||
LUALIB_API int luaopen_bit(lua_State *L)
|
|
||||||
{
|
|
||||||
UBits b;
|
|
||||||
lua_pushnumber(L, (lua_Number)1437217655L);
|
|
||||||
b = barg(L, -1);
|
|
||||||
if (b != (UBits)1437217655L || BAD_SAR) { /* Perform a simple self-test. */
|
|
||||||
const char *msg = "compiled with incompatible luaconf.h";
|
|
||||||
#ifdef LUA_NUMBER_DOUBLE
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (b == (UBits)1610612736L)
|
|
||||||
msg = "use D3DCREATE_FPU_PRESERVE with DirectX";
|
|
||||||
#endif
|
|
||||||
if (b == (UBits)1127743488L)
|
|
||||||
msg = "not compiled with SWAPPED_DOUBLE";
|
|
||||||
#endif
|
|
||||||
if (BAD_SAR)
|
|
||||||
msg = "arithmetic right-shift broken";
|
|
||||||
luaL_error(L, "bit library self-test failed (%s)", msg);
|
|
||||||
}
|
|
||||||
luaL_register(L, "bit", bit_funcs);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,321 @@
|
|||||||
|
// changeitem plugin
|
||||||
|
// allows to change the material type and quality of selected items
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
#include <climits>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <set>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "Core.h"
|
||||||
|
#include "Console.h"
|
||||||
|
#include "Export.h"
|
||||||
|
#include "PluginManager.h"
|
||||||
|
#include "modules/Maps.h"
|
||||||
|
#include "modules/Gui.h"
|
||||||
|
#include "modules/Items.h"
|
||||||
|
#include "modules/Materials.h"
|
||||||
|
#include "modules/MapCache.h"
|
||||||
|
|
||||||
|
#include "DataDefs.h"
|
||||||
|
#include "df/item.h"
|
||||||
|
#include "df/world.h"
|
||||||
|
#include "df/general_ref.h"
|
||||||
|
|
||||||
|
using namespace DFHack;
|
||||||
|
using namespace df::enums;
|
||||||
|
|
||||||
|
using MapExtras::Block;
|
||||||
|
using MapExtras::MapCache;
|
||||||
|
using df::global::world;
|
||||||
|
|
||||||
|
DFHACK_PLUGIN("changeitem");
|
||||||
|
|
||||||
|
command_result df_changeitem(color_ostream &out, vector <string> & parameters);
|
||||||
|
|
||||||
|
const string changeitem_help =
|
||||||
|
"Changeitem allows to change some item attributes.\n"
|
||||||
|
"By default the item currently selected in the UI will be changed\n"
|
||||||
|
"(you can select items in the 'k' list or inside containers/inventory).\n"
|
||||||
|
"By default change is only allowed if materials is of the same subtype\n"
|
||||||
|
"(for example wood<->wood, stone<->stone etc). But since some transformations\n"
|
||||||
|
"work pretty well and may be desired you can override this with 'force'.\n"
|
||||||
|
"Note that some attributes will not be touched, possibly resulting in weirdness.\n"
|
||||||
|
"To get an idea how the RAW id should look like, check some items with 'info'.\n"
|
||||||
|
"Using 'force' might create items which are not touched by crafters/haulers.\n"
|
||||||
|
"Options:\n"
|
||||||
|
" info - don't change anything, print some item info instead\n"
|
||||||
|
" here - change all items at cursor position\n"
|
||||||
|
" material, m - change material. must be followed by material RAW id\n"
|
||||||
|
" quality, q - change base quality. must be followed by number (0-5)\n"
|
||||||
|
" force - ignore subtypes, force change to new material.\n"
|
||||||
|
"Example:\n"
|
||||||
|
" changeitem m INORGANIC:GRANITE here\n"
|
||||||
|
" change material of all items under the cursor to granite\n"
|
||||||
|
" changeitem q 5\n"
|
||||||
|
" change currently selected item to masterpiece quality\n";
|
||||||
|
|
||||||
|
|
||||||
|
DFhackCExport command_result plugin_init ( color_ostream &out, vector <PluginCommand> &commands)
|
||||||
|
{
|
||||||
|
commands.push_back(PluginCommand(
|
||||||
|
"changeitem", "Change item attributes (material, quality).",
|
||||||
|
df_changeitem, false,
|
||||||
|
changeitem_help.c_str()
|
||||||
|
));
|
||||||
|
|
||||||
|
return CR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
DFhackCExport command_result plugin_shutdown ( color_ostream &out )
|
||||||
|
{
|
||||||
|
return CR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// probably there is some method in the library which does the same
|
||||||
|
// todo: look for it :)
|
||||||
|
string describeQuality(int q)
|
||||||
|
{
|
||||||
|
switch(q)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "Basic";
|
||||||
|
case 1:
|
||||||
|
return "-Well-crafted-";
|
||||||
|
case 2:
|
||||||
|
return "+Finely-crafted+";
|
||||||
|
case 3:
|
||||||
|
return "*Superior quality*";
|
||||||
|
case 4:
|
||||||
|
return "#Exceptional#";
|
||||||
|
case 5:
|
||||||
|
return "$Masterful$";
|
||||||
|
default:
|
||||||
|
return "!INVALID!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
command_result changeitem_execute(
|
||||||
|
color_ostream &out, df::item * item,
|
||||||
|
bool info, bool force,
|
||||||
|
bool change_material, string new_material,
|
||||||
|
bool change_quality, int new_quality);
|
||||||
|
|
||||||
|
command_result df_changeitem(color_ostream &out, vector <string> & parameters)
|
||||||
|
{
|
||||||
|
CoreSuspender suspend;
|
||||||
|
|
||||||
|
bool here = false;
|
||||||
|
bool info = false;
|
||||||
|
bool force = false;
|
||||||
|
|
||||||
|
bool change_material = false;
|
||||||
|
string new_material = "none";
|
||||||
|
|
||||||
|
bool change_quality = false;
|
||||||
|
int new_quality = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < parameters.size(); i++)
|
||||||
|
{
|
||||||
|
string & p = parameters[i];
|
||||||
|
|
||||||
|
if (p == "help" || p == "?")
|
||||||
|
{
|
||||||
|
out << changeitem_help << endl;
|
||||||
|
return CR_OK;
|
||||||
|
}
|
||||||
|
else if (p == "here")
|
||||||
|
{
|
||||||
|
here = true;
|
||||||
|
}
|
||||||
|
else if (p == "info")
|
||||||
|
{
|
||||||
|
info = true;
|
||||||
|
}
|
||||||
|
else if (p == "force")
|
||||||
|
{
|
||||||
|
force = true;
|
||||||
|
}
|
||||||
|
else if (p == "material" || p == "m" )
|
||||||
|
{
|
||||||
|
// must be followed by material RAW id
|
||||||
|
// (string like 'INORGANIC:GRANITE', 'PLANT:MAPLE:WOOD', ...)
|
||||||
|
if(i == parameters.size()-1)
|
||||||
|
{
|
||||||
|
out.printerr("no material specified!\n");
|
||||||
|
}
|
||||||
|
change_material = true;
|
||||||
|
new_material = parameters[i+1];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else if (p == "quality" || p == "q")
|
||||||
|
{
|
||||||
|
// must be followed by numeric quality (allowed: 0-5)
|
||||||
|
if(i == parameters.size()-1)
|
||||||
|
{
|
||||||
|
out.printerr("no quality specified!\n");
|
||||||
|
}
|
||||||
|
string & q = parameters[i+1];
|
||||||
|
// meh. should use a stringstream instead. but it's only 6 numbers
|
||||||
|
if(q == "0")
|
||||||
|
new_quality = 0;
|
||||||
|
else if(q == "1")
|
||||||
|
new_quality = 1;
|
||||||
|
else if(q == "2")
|
||||||
|
new_quality = 2;
|
||||||
|
else if(q == "3")
|
||||||
|
new_quality = 3;
|
||||||
|
else if(q == "4")
|
||||||
|
new_quality = 4;
|
||||||
|
else if(q == "5")
|
||||||
|
new_quality = 5;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out << "Invalid quality specified!" << endl;
|
||||||
|
return CR_WRONG_USAGE;
|
||||||
|
}
|
||||||
|
out << "change to quality: " << describeQuality(new_quality) << endl;
|
||||||
|
change_quality = true;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out << p << ": Unknown command!" << endl;
|
||||||
|
return CR_WRONG_USAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Maps::IsValid())
|
||||||
|
{
|
||||||
|
out.printerr("Map is not available!\n");
|
||||||
|
return CR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialInfo mat_new;
|
||||||
|
if (change_material && !mat_new.find(new_material))
|
||||||
|
{
|
||||||
|
out.printerr("No such material!\n");
|
||||||
|
return CR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (here)
|
||||||
|
{
|
||||||
|
int processed_total = 0;
|
||||||
|
int cx, cy, cz;
|
||||||
|
DFCoord pos_cursor;
|
||||||
|
|
||||||
|
// needs a cursor
|
||||||
|
if (!Gui::getCursorCoords(cx,cy,cz))
|
||||||
|
{
|
||||||
|
out.printerr("Cursor position not found. Please enable the cursor.\n");
|
||||||
|
return CR_FAILURE;
|
||||||
|
}
|
||||||
|
pos_cursor = DFCoord(cx,cy,cz);
|
||||||
|
|
||||||
|
// uh. is this check necessary?
|
||||||
|
// changeitem doesn't do stuff with map blocks...
|
||||||
|
{
|
||||||
|
MapCache MC;
|
||||||
|
Block * b = MC.BlockAt(pos_cursor / 16);
|
||||||
|
if(!b)
|
||||||
|
{
|
||||||
|
out.printerr("Cursor is in an invalid/uninitialized area. Place it over a floor.\n");
|
||||||
|
return CR_FAILURE;
|
||||||
|
}
|
||||||
|
// when only changing material it doesn't matter if cursor is over a tile
|
||||||
|
//df::tiletype ttype = MC.tiletypeAt(pos_cursor);
|
||||||
|
//if(!DFHack::isFloorTerrain(ttype))
|
||||||
|
//{
|
||||||
|
// out.printerr("Cursor should be placed over a floor.\n");
|
||||||
|
// return CR_FAILURE;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterate over all items, process those where pos = pos_cursor
|
||||||
|
size_t numItems = world->items.all.size();
|
||||||
|
for(size_t i=0; i< numItems; i++)
|
||||||
|
{
|
||||||
|
df::item * item = world->items.all[i];
|
||||||
|
DFCoord pos_item(item->pos.x, item->pos.y, item->pos.z);
|
||||||
|
|
||||||
|
if (pos_item != pos_cursor)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
changeitem_execute(out, item, info, force, change_material, new_material, change_quality, new_quality);
|
||||||
|
processed_total++;
|
||||||
|
}
|
||||||
|
out.print("Done. %d items processed.\n", processed_total);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// needs a selected item
|
||||||
|
df::item *item = Gui::getSelectedItem(out);
|
||||||
|
if (!item)
|
||||||
|
{
|
||||||
|
out.printerr("No item selected.\n");
|
||||||
|
return CR_FAILURE;
|
||||||
|
}
|
||||||
|
changeitem_execute(out, item, info, force, change_material, new_material, change_quality, new_quality);
|
||||||
|
}
|
||||||
|
return CR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
command_result changeitem_execute(
|
||||||
|
color_ostream &out, df::item * item,
|
||||||
|
bool info, bool force,
|
||||||
|
bool change_material, string new_material,
|
||||||
|
bool change_quality, int new_quality )
|
||||||
|
{
|
||||||
|
MaterialInfo mat_new;
|
||||||
|
MaterialInfo mat_old;
|
||||||
|
|
||||||
|
if(change_material)
|
||||||
|
mat_new.find(new_material);
|
||||||
|
if(change_material || info)
|
||||||
|
mat_old.decode(item);
|
||||||
|
|
||||||
|
// print some info, don't change stuff
|
||||||
|
if(info)
|
||||||
|
{
|
||||||
|
out << "Item info: " << endl;
|
||||||
|
out << " quality: " << describeQuality(item->getQuality()) << endl;
|
||||||
|
//if(item->isImproved())
|
||||||
|
// out << " imp.quality: " << describeQuality(item->getImprovementQuality()) << endl;
|
||||||
|
out << " material: " << mat_old.getToken() << endl;
|
||||||
|
return CR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(change_quality)
|
||||||
|
{
|
||||||
|
item->setQuality(new_quality);
|
||||||
|
// it would be nice to be able to change the improved quality, too
|
||||||
|
// (only allowed if the item is already improved)
|
||||||
|
// but there is no method in item.h which supports that
|
||||||
|
// ok: hints from _Q/angavrilov: improvent is a vector, an item can have more than one improvement
|
||||||
|
// -> virtual_cast to item_constructedst
|
||||||
|
}
|
||||||
|
|
||||||
|
if(change_material)
|
||||||
|
{
|
||||||
|
// subtype and mode should match to avoid doing dumb stuff like changing boulders into meat whatever
|
||||||
|
// changing a stone cabinet to wood is fine, though. as well as lots of other combinations.
|
||||||
|
// still, it's better to make the user activate 'force' if he really wants to.
|
||||||
|
|
||||||
|
if(force||(mat_old.subtype == mat_new.subtype && mat_old.mode==mat_new.mode))
|
||||||
|
{
|
||||||
|
item->setMaterial(mat_new.type);
|
||||||
|
item->setMaterialIndex(mat_new.index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.printerr("change denied: subtype doesn't match. use 'force' to override.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
item->flags.bits.temps_computed = 0; // recalc temperatures next time touched
|
||||||
|
item->flags.bits.weight_computed = 0; // recalc weight next time touched
|
||||||
|
}
|
||||||
|
return CR_OK;
|
||||||
|
}
|
@ -0,0 +1,397 @@
|
|||||||
|
// 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"
|
||||||
|
" Pause/unpause the game and/or move the cursor a bit. Then retry.\n"
|
||||||
|
" Try changing another layer, undo the changes and try again.\n"
|
||||||
|
" Try saving and loading the game.\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");
|
||||||
|
|
||||||
|
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
DFhackCExport command_result plugin_shutdown ( color_ostream &out )
|
||||||
|
{
|
||||||
|
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 geo_index 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 can have less!
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if(!warned)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
allowed = false;
|
||||||
|
}
|
||||||
|
// avoid multiple warnings for the same stuff
|
||||||
|
warned = true;
|
||||||
|
}
|
||||||
|
return allowed;
|
||||||
|
}
|
@ -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
|
|
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 19 KiB |
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>
|
|
Before Width: | Height: | Size: 616 B |
Before Width: | Height: | Size: 1.3 KiB |
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>
|
|
Before Width: | Height: | Size: 308 KiB |
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();
|
|
||||||
}
|
|
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;
|
|
||||||
}
|
|
@ -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'
|
|
@ -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 906d6439d4cb694cf287d63badabb675a8b89329
|