diff --git a/examples/attachtest.cpp b/examples/attachtest.cpp index 03ee928b4..5ead5a7a0 100644 --- a/examples/attachtest.cpp +++ b/examples/attachtest.cpp @@ -26,7 +26,7 @@ int main (void) cerr << e.what() << endl; return 1; } - +/* // attach/detach test cout << "Testing attach/detach" << endl; time(&start); @@ -62,7 +62,7 @@ int main (void) time_diff = difftime(end, start); cout << "attach tests done in " << time_diff << " seconds." << endl; - + */ cout << "Testing suspend/resume" << endl; DF.Attach(); time(&start); diff --git a/examples/veinlook.cpp b/examples/veinlook.cpp index 30c9bf212..9350bc331 100644 --- a/examples/veinlook.cpp +++ b/examples/veinlook.cpp @@ -275,9 +275,9 @@ main(int argc, char *argv[]) DFHack::t_designation designations[16][16]; uint8_t regionoffsets[16]; */ - mapblock40d Block; map materials; materials.clear(); + mapblock40d blocks[3][3]; vector stonetypes; vector< vector > layerassign; vector veinVector; @@ -338,13 +338,16 @@ main(int argc, char *argv[]) bool dirtybit = false; uint32_t blockaddr = 0; uint32_t blockaddr2 = 0; - // walk the map! + + // resume so we don't block DF while we wait for input + DF.Resume(); + for (;;) { dig = false; dump = false; digbit = false; - DF.Resume(); + int c = getch(); /* refresh, accept single keystroke of input */ clrscr(); /* process the command keystroke */ @@ -392,76 +395,85 @@ main(int argc, char *argv[]) cursorX = min(cursorX, x_max - 1); cursorY = min(cursorY, y_max - 1); - cursorZ = min(cursorZ, z_max - 1); - + cursorZ = min(cursorZ, z_max - 1); + + // clear data before we suspend + memset(blocks,0,sizeof(blocks)); + veinVector.clear(); + IceVeinVector.clear(); + dirtybit = 0; + + // Supend, read/write data DF.Suspend(); - for(int i = -1; i <= 1; i++) + for(int i = -1; i <= 1; i++) for(int j = -1; j <= 1; j++) { - for(int j = -1; j <= 1; j++) + 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); + + // extra processing of the block in the middle + if(i == 0 && j == 0) { - // read data - DF.ReadBlock40d(cursorX+i,cursorY+j,cursorZ, &Block); - /* - DF.ReadTileTypes(cursorX+i,cursorY+j,cursorZ, (uint16_t *) tiletypes); - DF.ReadDesignations(cursorX+i,cursorY+j,cursorZ, (uint32_t *) designations); - */ + // read veins + DF.ReadVeins(cursorX+i,cursorY+j,cursorZ,veinVector,IceVeinVector); - for(int x = 0; x < 16; x++) + // get pointer to block + blockaddr = DF.getBlockPtr(cursorX+i,cursorY+j,cursorZ); + blockaddr2 = Block->origin; + + // dig all veins and trees + if(dig) { - for(int y = 0; y < 16; y++) + for(int x = 0; x < 16; x++) for(int y = 0; y < 16; y++) { - if(dig) - { - TileClass tc = tileTypeTable[Block.tiletypes[x][y]].c; - TileMaterial tm = tileTypeTable[Block.tiletypes[x][y]].m; - if( tc == WALL && tm == VEIN || tc == TREE_OK || tc == TREE_DEAD) - { - Block.designaton[x][y].bits.dig = designation_default; - } - } - int color = COLOR_BLACK; - color = pickColor(Block.tiletypes[x][y]); - if(Block.designaton[x][y].bits.hidden) + TileClass tc = tileTypeTable[Block->tiletypes[x][y]].c; + TileMaterial tm = tileTypeTable[Block->tiletypes[x][y]].m; + if( tc == WALL && tm == VEIN || tc == TREE_OK || tc == TREE_DEAD) { - puttile(x+(i+1)*16,y+(j+1)*16,Block.tiletypes[x][y], color); - } - else - { - attron(A_STANDOUT); - puttile(x+(i+1)*16,y+(j+1)*16,Block.tiletypes[x][y], color); - attroff(A_STANDOUT); + Block->designaton[x][y].bits.dig = designation_default; } } + DF.WriteDesignations(cursorX+i,cursorY+j,cursorZ, (uint32_t *) Block->designaton); } - - if(i == 0 && j == 0) + // do a dump of the block data + if(dump) { - blockaddr = DF.getBlockPtr(cursorX+i,cursorY+j,cursorZ); - blockaddr2 = Block.origin; - if(dump) - { - hexdump(DF,blockaddr,0x1E00,filenum); - filenum++; - } - - if(dig) - DF.WriteDesignations(cursorX+i,cursorY+j,cursorZ, (uint32_t *) Block.designaton); - DF.ReadDirtyBit(cursorX+i,cursorY+j,cursorZ,dirtybit); - if(digbit) - { - dirtybit = !dirtybit; - DF.WriteDirtyBit(cursorX+i,cursorY+j,cursorZ,dirtybit); - } - veinVector.clear(); - IceVeinVector.clear(); - DF.ReadVeins(cursorX+i,cursorY+j,cursorZ,veinVector,IceVeinVector); - + hexdump(DF,blockaddr,0x1E00,filenum); + filenum++; + } + // read/write dirty bit of the block + DF.ReadDirtyBit(cursorX+i,cursorY+j,cursorZ,dirtybit); + if(digbit) + { + dirtybit = !dirtybit; + DF.WriteDirtyBit(cursorX+i,cursorY+j,cursorZ,dirtybit); } } } } + // Resume, print stuff to the terminal + DF.Resume(); + for(int i = -1; i <= 1; i++) for(int j = -1; j <= 1; j++) + { + mapblock40d * Block = &blocks[i+1][j+1]; + for(int x = 0; x < 16; x++) for(int y = 0; y < 16; y++) + { + int color = COLOR_BLACK; + color = pickColor(Block->tiletypes[x][y]); + if(Block->designaton[x][y].bits.hidden) + { + puttile(x+(i+1)*16,y+(j+1)*16,Block->tiletypes[x][y], color); + } + else + { + attron(A_STANDOUT); + puttile(x+(i+1)*16,y+(j+1)*16,Block->tiletypes[x][y], color); + attroff(A_STANDOUT); + } + } + } gotoxy(0,48); cprintf("arrow keys, PGUP, PGDN = navigate"); gotoxy(0,49); diff --git a/library/DFProcess-linux-SHM.cpp b/library/DFProcess-linux-SHM.cpp index 3ca1bdebc..2f224c8b4 100644 --- a/library/DFProcess-linux-SHM.cpp +++ b/library/DFProcess-linux-SHM.cpp @@ -429,20 +429,26 @@ bool SHMProcess::suspend() if(D_SHMCMD == CORE_RUN) { //fprintf(stderr,"%d invokes step\n",d->attachmentIdx); + /* // wait for the next window if(!d->SetAndWait(CORE_STEP)) { throw Error::SHMLockingError("if(!d->SetAndWait(CORE_STEP))"); } + */ + D_SHMCMD = CORE_STEP; } else { //fprintf(stderr,"%d invokes suspend\n",d->attachmentIdx); // lock now + /* if(!d->SetAndWait(CORE_SUSPEND)) { throw Error::SHMLockingError("if(!d->SetAndWait(CORE_SUSPEND))"); } + */ + D_SHMCMD = CORE_SUSPEND; } //fprintf(stderr,"waiting for lock\n"); // we wait for the server to give up our suspend lock (held by default) diff --git a/shmserver/mod-core.cpp b/shmserver/mod-core.cpp index 63622731d..5b032525e 100644 --- a/shmserver/mod-core.cpp +++ b/shmserver/mod-core.cpp @@ -202,7 +202,7 @@ DFPP_module InitCore(void) //core.set_command(CORE_RUN, FUNCTION, "Run!",AcquireSuspendLock,CORE_RUNNING); core.set_command(CORE_RUN, CANCELLATION, "Run!",0,CORE_RUNNING); core.set_command(CORE_STEP, CANCELLATION, "Suspend on next step",0,CORE_SUSPEND);// set command to CORE_SUSPEND, check next client - core.set_command(CORE_SUSPEND, FUNCTION, "Suspend", ReleaseSuspendLock , CORE_SUSPENDED); + core.set_command(CORE_SUSPEND, FUNCTION, "Suspend", ReleaseSuspendLock , CORE_SUSPENDED, LOCKING_LOCKS); core.set_command(CORE_SUSPENDED, CLIENT_WAIT, "Suspended"); core.set_command(CORE_ERROR, CANCELLATION, "Error"); @@ -298,13 +298,20 @@ void SHM_Act (void) } full_barrier */ + // set next state BEFORE we act on the command - good for locks + if(cmd.locking == LOCKING_LOCKS) + { + if(cmd.nextState != -1) SHMCMD = cmd.nextState; + } + if(cmd._function) { cmd._function(mod.modulestate); } full_barrier - if(cmd.nextState != -1) + // set next state AFTER we act on the command - good for busy waits + if(cmd.locking == LOCKING_BUSY) { /* char text [512]; @@ -313,7 +320,7 @@ void SHM_Act (void) sprintf(text2, "Server set %d\n",cmd.nextState); */ // FIXME: WHAT HAPPENS WHEN A 'NEXTSTATE' IS FROM A DIFFERENT MODULE THAN 'CORE'? Yeah. It doesn't work. - SHMCMD = cmd.nextState; + if(cmd.nextState != -1) SHMCMD = cmd.nextState; //MessageBox(0,text,text2, MB_OK); //fflush(stderr); // make sure this finds its way to the terminal! diff --git a/shmserver/shms.h b/shmserver/shms.h index 48fa2af5d..2b61cc283 100644 --- a/shmserver/shms.h +++ b/shmserver/shms.h @@ -31,6 +31,12 @@ #endif #endif +enum DFPP_Locking +{ + LOCKING_BUSY = 0, + LOCKING_LOCKS = 1 +}; + enum DFPP_CmdType { CANCELLATION, // we should jump out of the Act() @@ -44,6 +50,7 @@ struct DFPP_command DFPP_CmdType type:32; // force the enum to 32 bits for compatibility reasons std::string name; uint32_t nextState; + DFPP_Locking locking; }; struct DFPP_module @@ -62,12 +69,13 @@ struct DFPP_module modulestate = orig.modulestate; version = orig.version; } - inline void set_command(const unsigned int index, const DFPP_CmdType type, const char * name, void (*_function)(void *) = 0,uint32_t nextState = -1) + inline void set_command(const unsigned int index, const DFPP_CmdType type, const char * name, void (*_function)(void *) = 0,uint32_t nextState = -1, DFPP_Locking locking = LOCKING_BUSY) { commands[index].type = type; commands[index].name = name; commands[index]._function = _function; commands[index].nextState = nextState; + commands[index].locking = locking; } inline void reserve (unsigned int numcommands) {