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) IF(UNIX)
# veinlook - look at the map... sort of # veinlook - look at the map... sort of
ADD_EXECUTABLE(dfveinlook veinlook.cpp) ADD_EXECUTABLE(dfveinlook veinlook.cpp)
TARGET_LINK_LIBRARIES(dfveinlook dfhack ncurses) TARGET_LINK_LIBRARIES(dfveinlook dfhack ncursesw)
ENDIF(UNIX) ENDIF(UNIX)
# renamer - change the custom names and professions of creatures, sends keys to df directly # renamer - change the custom names and professions of creatures, sends keys to df directly

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

@ -124,6 +124,7 @@ public:
bool constructionsInited; bool constructionsInited;
bool buildingsInited; bool buildingsInited;
bool effectsInited;
bool vegetationInited; bool vegetationInited;
bool creaturesInited; bool creaturesInited;
bool cursorWindowInited; bool cursorWindowInited;
@ -141,6 +142,7 @@ public:
DfVector *p_cre; DfVector *p_cre;
DfVector *p_cons; DfVector *p_cons;
DfVector *p_bld; DfVector *p_bld;
DfVector *p_effect;
DfVector *p_veg; DfVector *p_veg;
DfVector *p_itm; DfVector *p_itm;
DfVector *p_notes; DfVector *p_notes;
@ -174,12 +176,15 @@ API::API (const string path_to_xml)
d->constructionsInited = false; d->constructionsInited = false;
d->creaturesInited = false; d->creaturesInited = false;
d->buildingsInited = false; d->buildingsInited = false;
d->effectsInited = false;
d->vegetationInited = false; d->vegetationInited = false;
d->cursorWindowInited = false; d->cursorWindowInited = false;
d->viewSizeInited = false; d->viewSizeInited = false;
d->itemsInited = false; d->itemsInited = false;
d->notesInited = false; d->notesInited = false;
d->hotkeyInited = false; d->hotkeyInited = false;
d->namesInited = false;
d->nameTablesInited = false;
d->pm = NULL; d->pm = NULL;
d->shm_start = 0; d->shm_start = 0;
d->maps_module = 0; d->maps_module = 0;
@ -854,6 +859,55 @@ void API::FinishReadBuildings()
d->buildingsInited = false; 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. //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 // returns number of constructions, prepares a vector, returns total number of constructions

@ -165,6 +165,11 @@ namespace DFHack
bool InitReadBuildings ( uint32_t & numbuildings ); bool InitReadBuildings ( uint32_t & numbuildings );
bool ReadBuilding(const int32_t index, t_building & building); bool ReadBuilding(const int32_t index, t_building & building);
void FinishReadBuildings(); 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 InitReadVegetation( uint32_t & numplants );
bool ReadVegetation(const int32_t index, t_tree_desc & shrubbery); bool ReadVegetation(const int32_t index, t_tree_desc & shrubbery);

@ -103,7 +103,8 @@ bool SHMProcess::Private::SetAndWait (uint32_t state)
SHMCMD = state; SHMCMD = state;
while (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()) 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 we end up with this silly thing
*/ */
bool SHMProcess::SetAndWait (uint32_t state) bool SHMProcess::SetAndWait (uint32_t state)

@ -31,6 +31,28 @@ distribution.
namespace DFHack 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 struct t_matgloss
{ {
char id[128]; //the id in the raws char id[128]; //the id in the raws
@ -75,6 +97,37 @@ struct t_matglossPair
int16_t index; 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 // raw
struct t_construction_df40d struct t_construction_df40d
{ {

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