Added reading/writing support for effects like mist

Veinlook shows effects for it's middle block
Veinlook now uses wide-character ncurses
develop
Petr Mrázek 2010-03-20 17:30:13 +01:00
parent c283197b71
commit 71f8474e11
7 changed files with 175 additions and 8 deletions

@ -59,7 +59,7 @@ TARGET_LINK_LIBRARIES(dfvecc dfhack)
IF(UNIX)
# veinlook - look at the map... sort of
ADD_EXECUTABLE(dfveinlook veinlook.cpp)
TARGET_LINK_LIBRARIES(dfveinlook dfhack ncurses)
TARGET_LINK_LIBRARIES(dfveinlook dfhack ncursesw)
ENDIF(UNIX)
# renamer - change the custom names and professions of creatures, sends keys to df directly

@ -15,13 +15,15 @@ using namespace std;
#include <DFMemInfo.h>
using namespace DFHack;
#include <sstream>
#include <curses.h>
#include <cursesw.h>
#include <stdlib.h>
#include <signal.h>
#include <locale.h>
string error;
API * pDF = 0;
static void finish(int sig);
int gotoxy(int x, int y)
@ -36,6 +38,12 @@ int putch(int x, int y, int znak, int color)
mvwaddch(stdscr, y, x, znak);
attroff(COLOR_PAIR(color));
}
int putwch(int x, int y, int znak, int color)
{
attron(COLOR_PAIR(color));
mvwaddch(stdscr, y, x, znak);
attroff(COLOR_PAIR(color));
}
/*
enum TileClass
{
@ -71,6 +79,11 @@ int puttile(int x, int y, int tiletype, int color)
znak = ' ';
break;
case WALL:
attron(COLOR_PAIR(color));
mvwaddwstr(stdscr, y, x, L"\u2593");
attroff(COLOR_PAIR(color));
//znak = ;
return 0;
case FORTIFICATION:
znak = '#';
break;
@ -235,7 +248,7 @@ main(int argc, char *argv[])
/* initialize your non-curses data structures here */
signal(SIGINT, finish); /* arrange interrupts to terminate */
setlocale(LC_ALL,"");
initscr(); /* initialize the curses library */
keypad(stdscr, TRUE); /* enable keyboard mapping */
nonl(); /* tell curses not to do NL->CR/NL on output */
@ -279,6 +292,7 @@ main(int argc, char *argv[])
materials.clear();
mapblock40d blocks[3][3];
vector<DFHack::t_matgloss> stonetypes;
vector<DFHack::t_effect_df40d> effects;
vector< vector <uint16_t> > layerassign;
vector<t_vein> veinVector;
vector<t_frozenliquidvein> IceVeinVector;
@ -402,14 +416,26 @@ main(int argc, char *argv[])
memset(blocks,0,sizeof(blocks));
veinVector.clear();
IceVeinVector.clear();
effects.clear();
dirtybit = 0;
// Supend, read/write data
DF.Suspend();
uint32_t effectnum;
if(DF.InitReadEffects(effectnum))
{
for(uint32_t i = 0; i < effectnum;i++)
{
t_effect_df40d effect;
DF.ReadEffect(i,effect);
effects.push_back(effect);
}
}
for(int i = -1; i <= 1; i++) for(int j = -1; j <= 1; j++)
{
mapblock40d * Block = &blocks[i+1][j+1];
if(DF.isValidBlock(cursorX+i,cursorY+j,cursorZ))
{
DF.ReadBlock40d(cursorX+i,cursorY+j,cursorZ, Block);
@ -463,17 +489,35 @@ main(int argc, char *argv[])
{
int color = COLOR_BLACK;
color = pickColor(Block->tiletypes[x][y]);
if(Block->designaton[x][y].bits.hidden)
{
if(!Block->designaton[x][y].bits.hidden)
/*{
puttile(x+(i+1)*16,y+(j+1)*16,Block->tiletypes[x][y], color);
}
else
else*/
{
attron(A_STANDOUT);
puttile(x+(i+1)*16,y+(j+1)*16,Block->tiletypes[x][y], color);
attroff(A_STANDOUT);
}
}
// print effects for the center tile
if(i == 0 && j == 0)
{
for(uint zz = 0; zz < effects.size();zz++)
{
if(effects[zz].z == cursorZ && !effects[zz].isHidden)
{
// block coords to tile coords
uint16_t x = effects[zz].x - (cursorX * 16);
uint16_t y = effects[zz].y - (cursorY * 16);
if(x < 16 && y < 16)
{
putch(x + 16,y + 16,'@',COLOR_WHITE);
}
}
}
}
}
gotoxy(0,48);
cprintf("arrow keys, PGUP, PGDN = navigate");
@ -500,6 +544,10 @@ main(int argc, char *argv[])
//iterate through the bits
for (uint32_t k = 0; k< 16;k++)
{
if(tileTypeTable[blocks[1][1].tiletypes[k][j]].m != VEIN)
continue;
if(blocks[1][1].designaton[k][j].bits.hidden)
continue;
// and the bit array with a one-bit mask, check if the bit is set
bool set = !!(((1 << k) & veinVector[realvein].assignment[j]) >> k);
if(set)

@ -124,6 +124,7 @@ public:
bool constructionsInited;
bool buildingsInited;
bool effectsInited;
bool vegetationInited;
bool creaturesInited;
bool cursorWindowInited;
@ -141,6 +142,7 @@ public:
DfVector *p_cre;
DfVector *p_cons;
DfVector *p_bld;
DfVector *p_effect;
DfVector *p_veg;
DfVector *p_itm;
DfVector *p_notes;
@ -174,12 +176,15 @@ API::API (const string path_to_xml)
d->constructionsInited = false;
d->creaturesInited = false;
d->buildingsInited = false;
d->effectsInited = false;
d->vegetationInited = false;
d->cursorWindowInited = false;
d->viewSizeInited = false;
d->itemsInited = false;
d->notesInited = false;
d->hotkeyInited = false;
d->namesInited = false;
d->nameTablesInited = false;
d->pm = NULL;
d->shm_start = 0;
d->maps_module = 0;
@ -854,6 +859,55 @@ void API::FinishReadBuildings()
d->buildingsInited = false;
}
bool API::InitReadEffects ( uint32_t & numeffects )
{
if(d->effectsInited)
FinishReadEffects();
int effects = d->offset_descriptor->getAddress ("effects_vector");
d->effectsInited = true;
d->p_effect = new DfVector (d->p->readVector (effects, 4));
numeffects = d->p_effect->getSize();
return true;
}
bool API::ReadEffect(const int32_t index, t_effect_df40d & effect)
{
if(!d->effectsInited)
return false;
if(index >= d->p_effect->getSize())
return false;
// read pointer from vector at position
uint32_t temp = * (uint32_t *) d->p_effect->at (index);
//read effect from memory
g_pProcess->read (temp, sizeof (t_effect_df40d), (uint8_t *) &effect);
return true;
}
// use with care!
bool API::WriteEffect(const int32_t index, const t_effect_df40d & effect)
{
if(!d->effectsInited)
return false;
if(index >= d->p_effect->getSize())
return false;
// read pointer from vector at position
uint32_t temp = * (uint32_t *) d->p_effect->at (index);
// write effect to memory
g_pProcess->write(temp,sizeof(t_effect_df40d), (uint8_t *) &effect);
return true;
}
void API::FinishReadEffects()
{
if(d->p_effect)
{
delete d->p_effect;
d->p_effect = NULL;
}
d->effectsInited = false;
}
//TODO: maybe do construction reading differently - this could go slow with many of them.
// returns number of constructions, prepares a vector, returns total number of constructions

@ -166,6 +166,11 @@ namespace DFHack
bool ReadBuilding(const int32_t index, t_building & building);
void FinishReadBuildings();
bool InitReadEffects ( uint32_t & numeffects );
bool ReadEffect(const int32_t index, t_effect_df40d & effect);
bool WriteEffect(const int32_t index, const t_effect_df40d & effect);
void FinishReadEffects();
bool InitReadVegetation( uint32_t & numplants );
bool ReadVegetation(const int32_t index, t_tree_desc & shrubbery);
void FinishReadVegetation();

@ -103,7 +103,8 @@ bool SHMProcess::Private::SetAndWait (uint32_t state)
SHMCMD = state;
while (SHMCMD == state)
{
if(cnt == 10000)// check if the other process is still there, don't hammer the kernel too much.
// check if the other process is still there
if(cnt == 10000)
{
if(!AreLocksOk())
{
@ -135,7 +136,8 @@ bool SHMProcess::Private::SetAndWait (uint32_t state)
}
/*
Yeah. with no way to synchronize things (locks are slow, the OS doesn't give us enough control over scheduling)
Yeah. with no way to synchronize things (locks are slow, the OS doesn't give us
enough control over scheduling)
we end up with this silly thing
*/
bool SHMProcess::SetAndWait (uint32_t state)

@ -31,6 +31,28 @@ distribution.
namespace DFHack
{
template <int SIZE>
struct junk_fill
{
uint8_t data[SIZE];
/*
void Dump()
{
cout<<hex;
for (int i=0;i<SIZE;i++)
cout<<setw(2)<<i<<" ";
cout<<endl;
for (int i=0;i<SIZE;i++)
{
cout<<setw(2)<<(int)data[i]<<" ";
if ((i%32)==32-1)
cout<<endl;
}
cout<<endl;
}
*/
};
struct t_matgloss
{
char id[128]; //the id in the raws
@ -75,6 +97,37 @@ struct t_matglossPair
int16_t index;
};
// DF effects, by darius from the bay12 forum
enum EFFECT_TYPE
{
EFF_MIASMA=0,
EFF_WATER,
EFF_WATER2,
EFF_BLOOD,
EFF_DUST,
EFF_MAGMA,
EFF_SMOKE,
EFF_DRAGONFIRE,
EFF_FIRE,
EFF_WEBING,
EFF_BOILING, // uses matgloss
EFF_OCEANWAVE
};
struct t_effect_df40d //size 40
{
uint16_t type;
t_matglossPair material;
int16_t lifetime;
uint16_t x;
uint16_t y;
uint16_t z; //14
int16_t x_direction;
int16_t y_direction;
junk_fill <12> unk4;
uint8_t canCreateNew;//??
uint8_t isHidden;
};
// raw
struct t_construction_df40d
{

@ -1895,9 +1895,11 @@
</Entry>
<Entry version="v0.28.181.40d15" os="linux" id="40d15lin" base="40d14lin" rebase="0x0">
<String name="md5">4f55a1dcc326786271f221de23c425b5</String>
</Entry>
<Entry version="v0.28.181.40d16" os="linux" id="40d16lin" base="40d15lin" rebase="0x0">
<String name="md5">022b933926e08da49c6df8649295f2b7</String>
<Address name="effects_vector">0x0893F2D0</Address>
</Entry>
<Entry version="v0.28.181.40d17" os="linux" id="40d17lin" base="40d16lin">
<String name="md5">8f55a6250f2550e28535b79db43d5f1a</String>
@ -1930,6 +1932,7 @@
<Address name="x_count">0x08fa2d50</Address>
<Address name="y_count">0x08fa2d54</Address>
<Address name="z_count">0x08fa2d58</Address>
<Address name="effects_vector">0x08947438</Address>
</Entry>
<Entry version="v0.28.181.40d18" os="linux" id="40d18lin" base="40d17lin">
<String name="md5">777e7d674d8908042307994cb75250ff</String>
@ -1962,6 +1965,7 @@
<Address name="x_count">0x09049cf0</Address>
<Address name="y_count">0x09049cf4</Address>
<Address name="z_count">0x09049cf8</Address>
<Address name="effects_vector">0x089EE3D8</Address>
</Entry>
<Entry version="v0.28.181.40d19" os="linux" id="40d19lin" base="40d18lin">
<String name="md5">04c3ad13c657f59ba6fc135e156d721d</String>
@ -1994,6 +1998,7 @@
<Address name="x_count">0x09048d10</Address>
<Address name="y_count">0x09048d14</Address>
<Address name="z_count">0x09048d18</Address>
<Address name="effects_vector">0x089ED3F8</Address>
</Entry>
</MemoryDescriptors>
<!-- Windows logo by M$, spiderweb by jgs -->