diff --git a/plugins/Dfusion/CMakeLists.txt b/plugins/Dfusion/CMakeLists.txt index 8ac2e79e9..c7f71c71c 100644 --- a/plugins/Dfusion/CMakeLists.txt +++ b/plugins/Dfusion/CMakeLists.txt @@ -13,3 +13,4 @@ DFHACK_PLUGIN(dfusion ${DFUSION_CPPS_ALL} ${DFUSION_HS} LINK_LIBRARIES lua) # installs into DF root install(DIRECTORY luafiles/ DESTINATION dfusion) +install(FILES ../../library/include/df/codegen.out.xml DESTINATION dfusion/patterns/) \ No newline at end of file diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp index b06a7d278..120e3fce6 100644 --- a/plugins/Dfusion/dfusion.cpp +++ b/plugins/Dfusion/dfusion.cpp @@ -31,8 +31,10 @@ uint64_t timeLast=0; DFHACK_PLUGIN("dfusion") -command_result dfusion (Core * c, vector & parameters); -command_result lua_run (Core * c, vector & parameters); +command_result dfusion (color_ostream &out, std::vector ¶meters); +command_result dfuse (color_ostream &out, std::vector ¶meters); +command_result lua_run (color_ostream &out, std::vector ¶meters); +command_result lua_run_file (color_ostream &out, std::vector ¶meters); DFhackCExport const char * plugin_name ( void ) { @@ -43,8 +45,8 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector { lua::state st=lua::glua::Get(); //maybe remake it to run automaticaly - lua::RegisterConsole(st,&c->con); - lua::RegisterProcess(st,c->p); + lua::RegisterConsole(st); + lua::RegisterProcess(st); lua::RegisterHexsearch(st); lua::RegisterMisc(st); lua::RegisterVersionInfo(st); @@ -59,9 +61,10 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector st.setglobal("WINDOWS"); #endif - commands.push_back(PluginCommand("dfusion","Init dfusion system. Use 'dfusion init' to run dfusion in init mode (not interactive).",dfusion)); - commands.push_back(PluginCommand("lua", "Run interactive interpreter. Use 'lua ' to run instead.",lua_run)); - + commands.push_back(PluginCommand("dfusion","Run dfusion system (interactive i.e. can input further commands).",dfusion,true)); + commands.push_back(PluginCommand("dfuse","Init dfusion system (not interactive).",dfuse,false)); + commands.push_back(PluginCommand("lua", "Run interactive interpreter. Use 'lua ' to run instead.",lua_run,true)); + commands.push_back(PluginCommand("runlua", "Run non-interactive interpreter. Use 'runlua ' to run .",lua_run_file,false)); mymutex=new tthread::mutex; return CR_OK; } @@ -93,9 +96,9 @@ DFhackCExport command_result plugin_onupdate_DISABLED ( Core * c ) } catch(lua::exception &e) { - c->con.printerr("Error OnTick:%s\n",e.what()); - c->con.printerr("%s\n",lua::DebugDump(lua::glua::Get()).c_str()); - c->con.msleep(1000); + c->getConsole().printerr("Error OnTick:%s\n",e.what()); + c->getConsole().printerr("%s\n",lua::DebugDump(lua::glua::Get()).c_str()); + c->getConsole().msleep(1000); } } s.settop(0); @@ -103,13 +106,15 @@ DFhackCExport command_result plugin_onupdate_DISABLED ( Core * c ) return CR_OK; } -void InterpreterLoop(Core* c) +void InterpreterLoop(color_ostream &out) { - Console &con=c->con; + DFHack::CommandHistory hist; lua::state s=lua::glua::Get(); string curline; - con.print("Type quit to exit interactive mode\n"); + out.print("Type quit to exit interactive mode\n"); + assert(out.is_console()); + Console &con = static_cast(out); con.lineedit(">>",curline,hist); while (curline!="quit") { @@ -122,18 +127,27 @@ void InterpreterLoop(Core* c) catch(lua::exception &e) { con.printerr("Error:%s\n",e.what()); - c->con.printerr("%s\n",lua::DebugDump(lua::glua::Get()).c_str()); + con.printerr("%s\n",lua::DebugDump(lua::glua::Get()).c_str()); s.settop(0); } con.lineedit(">>",curline,hist); } s.settop(0); } -command_result lua_run (Core * c, vector & parameters) +command_result lua_run_file (color_ostream &out, std::vector ¶meters) +{ + if(parameters.size()==0) + { + out.printerr("runlua without file to run!"); + return CR_FAILURE; + } + return lua_run(out,parameters); +} +command_result lua_run (color_ostream &out, std::vector ¶meters) { - Console &con=c->con; mymutex->lock(); lua::state s=lua::glua::Get(); + lua::SetConsole(s,out); if(parameters.size()>0) { try{ @@ -142,23 +156,21 @@ command_result lua_run (Core * c, vector & parameters) } catch(lua::exception &e) { - con.printerr("Error:%s\n",e.what()); - c->con.printerr("%s\n",lua::DebugDump(lua::glua::Get()).c_str()); + out.printerr("Error:%s\n",e.what()); + out.printerr("%s\n",lua::DebugDump(lua::glua::Get()).c_str()); } } else { - InterpreterLoop(c); + InterpreterLoop(out); } s.settop(0);// clean up mymutex->unlock(); return CR_OK; } -void RunDfusion(void *p) +void RunDfusion(color_ostream &out) { - Console &con=static_cast(p)->con; mymutex->lock(); - lua::state s=lua::glua::Get(); try{ s.getglobal("err"); @@ -169,26 +181,27 @@ void RunDfusion(void *p) } catch(lua::exception &e) { - con.printerr("Error:%s\n",e.what()); - con.printerr("%s\n",lua::DebugDump(lua::glua::Get()).c_str()); + out.printerr("Error:%s\n",e.what()); + out.printerr("%s\n",lua::DebugDump(lua::glua::Get()).c_str()); } s.settop(0);// clean up mymutex->unlock(); } -command_result dfusion (Core * c, vector & parameters) +command_result dfuse(color_ostream &out, std::vector ¶meters) { - if(parameters[0]=="init") - { - lua::state s=lua::glua::Get(); - s.push(1); - s.setglobal("INIT"); - } - else - { - lua::state s=lua::glua::Get(); - s.push(); - s.setglobal("INIT"); - } - RunDfusion(c); + lua::state s=lua::glua::Get(); + lua::SetConsole(s,out); + s.push(1); + s.setglobal("INIT"); + RunDfusion(out); + return CR_OK; +} +command_result dfusion (color_ostream &out, std::vector ¶meters) +{ + lua::state s=lua::glua::Get(); + lua::SetConsole(s,out); + s.push(); + s.setglobal("INIT"); + RunDfusion(out); return CR_OK; } diff --git a/plugins/Dfusion/include/lua_Console.h b/plugins/Dfusion/include/lua_Console.h index 2ced33645..227effa9f 100644 --- a/plugins/Dfusion/include/lua_Console.h +++ b/plugins/Dfusion/include/lua_Console.h @@ -6,8 +6,8 @@ namespace lua { -void RegisterConsole(lua::state &st, DFHack::Console *c); - +void RegisterConsole(lua::state &st); +void SetConsole(lua::state &st,DFHack::color_ostream& stream); } #endif \ No newline at end of file diff --git a/plugins/Dfusion/include/lua_Process.h b/plugins/Dfusion/include/lua_Process.h index e6639cfc8..3429c9518 100644 --- a/plugins/Dfusion/include/lua_Process.h +++ b/plugins/Dfusion/include/lua_Process.h @@ -8,6 +8,6 @@ namespace lua { -void RegisterProcess(lua::state &st,DFHack::Process *p); +void RegisterProcess(lua::state &st); } #endif \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/common.lua b/plugins/Dfusion/luafiles/common.lua index 4548acecf..2b706b7f7 100644 --- a/plugins/Dfusion/luafiles/common.lua +++ b/plugins/Dfusion/luafiles/common.lua @@ -19,9 +19,9 @@ function GetTextRegion() ranges__=Process.getMemRanges() --print("Ranges:"..#ranges__) for k,v in pairs(ranges__) do - --for k2,v2 in pairs(v) do - -- print(string.format("%d %s->%s",k,tostring(k2),tostring(v2))) - --end + for k2,v2 in pairs(v) do + --print(string.format("%d %s->%s",k,tostring(k2),tostring(v2))) + end --local num --flgs="" --if(v["read"])then flgs=flgs..'r' end diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua index 4e6ebc6cb..ef2d4d603 100644 --- a/plugins/Dfusion/luafiles/init.lua +++ b/plugins/Dfusion/luafiles/init.lua @@ -44,6 +44,8 @@ function mainmenu(t1) end dofile("dfusion/common.lua") dofile("dfusion/utils.lua") +types=nil +dofile("dfusion/xml_struct.lua") unlockDF() plugins={} table.insert(plugins,{"simple_embark","A simple embark dwarf count editor"}) diff --git a/plugins/Dfusion/luafiles/patterns/supplementary.xml b/plugins/Dfusion/luafiles/patterns/supplementary.xml new file mode 100644 index 000000000..e341a1368 --- /dev/null +++ b/plugins/Dfusion/luafiles/patterns/supplementary.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/xml_struct.lua b/plugins/Dfusion/luafiles/xml_struct.lua index 0a6b54138..5c2cb9b26 100644 --- a/plugins/Dfusion/luafiles/xml_struct.lua +++ b/plugins/Dfusion/luafiles/xml_struct.lua @@ -40,7 +40,7 @@ function parseTree(t) end function parseTreeGlobals(t) local glob={} - print("Parsing global-objects") + --print("Parsing global-objects") for k,v in ipairs(t) do if v.xarg~=nil and v.label=="ld:global-object" then local name=v.xarg["name"]; @@ -84,7 +84,7 @@ local df_meta={} function df_meta:__index(key) local addr=VersionInfo.getAddress(key) local vartype=rawget(df,"types")[key]; - if addr==nil then + if addr==0 then error("No such global address exist") elseif vartype==nil then error("No such global type exist") @@ -95,7 +95,7 @@ end function df_meta:__newindex(key,val) local addr=VersionInfo.getAddress(key) local vartype=rawget(df,"types")[key]; - if addr==nil then + if addr==0 then error("No such global address exist") elseif vartype==nil then error("No such global type exist") @@ -129,3 +129,26 @@ for k,v in pairs(labels) do end end end--]=] +function addressOf(var) + local addr=rawget(var,"ptr") + return addr +end +function printGlobals() + print("Globals:") + for k,v in pairs(rawget(df,"types")) do + print(k) + end +end +function printFields(object) + local tbl + if getmetatable(object)==xtypes["struct-type"].wrap then + tbl=rawget(object,"mtype") + elseif getmetatable(object)==xtypes["struct-type"] then + tbl=object + else + error("Not an class_type or a class_object") + end + for k,v in pairs(tbl.types) do + print(k) + end +end \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/xml_types.lua b/plugins/Dfusion/luafiles/xml_types.lua index b96e77b47..e1c870f24 100644 --- a/plugins/Dfusion/luafiles/xml_types.lua +++ b/plugins/Dfusion/luafiles/xml_types.lua @@ -1,13 +1,13 @@ function type_read(valtype,address) if valtype.issimple then - print("Simple read:"..tostring(valtype.ctype)) + --print("Simple read:"..tostring(valtype.ctype)) return engine.peek(address,valtype.ctype) else return valtype:makewrap(address) end end function type_write(valtype,address,val) - if altype.issimple then + if valtype.issimple then engine.poke(address,valtype.ctype,val) else engine.poke(address,DWORD,rawget(val,"ptr")) @@ -20,6 +20,15 @@ function first_of_type(node,labelname) end end end +function padAddress(curoff,sizetoadd) --return new offset to place things + --windows -> sizeof(x)==alignof(x) + if sizetoadd>8 then sizetoadd=8 end + if(math.mod(curoff,sizetoadd)==0) then + return curoff + else + return curoff+(sizetoadd-math.mod(curoff,sizetoadd)) + end +end xtypes={} -- list of all types prototypes (e.g. enum-type -> announcement_type) -- type must have new and makewrap (that makes a wrapper around ptr) local sarr={} @@ -27,13 +36,13 @@ sarr.__index=sarr function sarr.new(node) local o={} setmetatable(o,sarr) - print("Making array.") + --print("Making array.") o.count=tonumber(node.xarg.count) - print("got cound:"..o.count) + --print("got count:"..o.count) o.ctype=makeType(first_of_type(node,"ld:item")) o.size=o.count*o.ctype.size - print("got subtypesize:"..o.ctype.size) + --print("got subtypesize:"..o.ctype.size) return o end function sarr:makewrap(address) @@ -45,6 +54,9 @@ function sarr:makewrap(address) end sarr.wrap={} function sarr.wrap:__index(key) + if key=="size" then + return rawget(self,"mtype").count + end local num=tonumber(key) local mtype=rawget(self,"mtype") if num~=nil and num(lua_touserdata(st,-1)); + DFHack::color_ostream* c=static_cast(lua_touserdata(st,-1)); st.settop(t); return c; } @@ -13,7 +13,7 @@ static int lua_Console_print(lua_State *S) { lua::state st(S); int t=st.gettop(); - DFHack::Console* c=GetConsolePtr(st); + DFHack::color_ostream* c=GetConsolePtr(st); c->print("%s",st.as(t).c_str()); return 0; } @@ -22,7 +22,7 @@ static int lua_Console_printerr(lua_State *S) { lua::state st(S); int t=st.gettop(); - DFHack::Console* c=GetConsolePtr(st); + DFHack::color_ostream* c=GetConsolePtr(st); c->printerr("%s",st.as(t).c_str()); return 0; } @@ -30,69 +30,95 @@ static int lua_Console_printerr(lua_State *S) static int lua_Console_clear(lua_State *S) { lua::state st(S); - DFHack::Console* c=GetConsolePtr(st); + DFHack::color_ostream* c=GetConsolePtr(st); c->clear(); return 0; } static int lua_Console_gotoxy(lua_State *S) { lua::state st(S); - DFHack::Console* c=GetConsolePtr(st); - c->gotoxy(st.as(1,1),st.as(1,2)); + DFHack::color_ostream* c=GetConsolePtr(st); + if(c->is_console()) + { + DFHack::Console* con=static_cast(c); + con->gotoxy(st.as(1,1),st.as(1,2)); + } return 0; } static int lua_Console_color(lua_State *S) { lua::state st(S); - DFHack::Console* c=GetConsolePtr(st); + DFHack::color_ostream* c=GetConsolePtr(st); c->color( static_cast(st.as(-1,1)) ); return 0; } static int lua_Console_reset_color(lua_State *S) { lua::state st(S); - DFHack::Console* c=GetConsolePtr(st); + DFHack::color_ostream* c=GetConsolePtr(st); c->reset_color(); return 0; } static int lua_Console_cursor(lua_State *S) { lua::state st(S); - DFHack::Console* c=GetConsolePtr(st); - c->cursor(st.as(1)); + DFHack::color_ostream* c=GetConsolePtr(st); + if(c->is_console()) + { + DFHack::Console* con=static_cast(c); + con->cursor(st.as(1)); + } return 0; } static int lua_Console_msleep(lua_State *S) { lua::state st(S); - DFHack::Console* c=GetConsolePtr(st); - c->msleep(st.as(1)); + DFHack::color_ostream* c=GetConsolePtr(st); + if(c->is_console()) + { + DFHack::Console* con=static_cast(c); + con->msleep(st.as(1)); + } return 0; } static int lua_Console_get_columns(lua_State *S) { lua::state st(S); - DFHack::Console* c=GetConsolePtr(st); - st.push(c->get_columns()); + DFHack::color_ostream* c=GetConsolePtr(st); + if(c->is_console()) + { + DFHack::Console* con=static_cast(c); + st.push(con->get_columns()); + } return 1; } static int lua_Console_get_rows(lua_State *S) { lua::state st(S); - DFHack::Console* c=GetConsolePtr(st); - st.push(c->get_rows()); + DFHack::color_ostream* c=GetConsolePtr(st); + if(c->is_console()) + { + DFHack::Console* con=static_cast(c); + st.push(con->get_rows()); + } return 1; } static int lua_Console_lineedit(lua_State *S) { lua::state st(S); - DFHack::Console* c=GetConsolePtr(st); - string ret; - DFHack::CommandHistory hist; - int i=c->lineedit(st.as(1),ret,hist); - st.push(ret); - st.push(i); - return 2;// dunno if len is needed... + DFHack::color_ostream* c=GetConsolePtr(st); + if(c->is_console()) + { + DFHack::Console* con=static_cast(c); + string ret; + DFHack::CommandHistory hist; + int i=con->lineedit(st.as(1),ret,hist); + st.push(ret); + st.push(i); + return 2;// dunno if len is needed... + } + else + return 0; } const luaL_Reg lua_console_func[]= { @@ -109,7 +135,7 @@ const luaL_Reg lua_console_func[]= {"lineedit",lua_Console_lineedit}, {NULL,NULL} }; -void lua::RegisterConsole(lua::state &st, DFHack::Console *c) +void lua::RegisterConsole(lua::state &st) { st.getglobal("Console"); if(st.is()) @@ -118,10 +144,21 @@ void lua::RegisterConsole(lua::state &st, DFHack::Console *c) st.newtable(); } - st.pushlightuserdata(c); - st.setfield("__pointer"); - lua::RegFunctionsLocal(st, lua_console_func); //TODO add color consts st.setglobal("Console"); } +void lua::SetConsole(lua::state &st,DFHack::color_ostream& stream) +{ + int top=st.gettop(); + st.getglobal("Console"); + if(st.is()) + { + st.pop(); + st.newtable(); + } + + st.pushlightuserdata(&stream); + st.setfield("__pointer"); + st.settop(top); +} \ No newline at end of file diff --git a/plugins/Dfusion/src/lua_Process.cpp b/plugins/Dfusion/src/lua_Process.cpp index 6d2b3d877..19bf698d1 100644 --- a/plugins/Dfusion/src/lua_Process.cpp +++ b/plugins/Dfusion/src/lua_Process.cpp @@ -2,12 +2,7 @@ static DFHack::Process* GetProcessPtr(lua::state &st) { - int t=st.gettop(); - st.getglobal("Process"); - st.getfield("__pointer"); - DFHack::Process* c=static_cast(lua_touserdata(st,-1)); - st.settop(t); - return c; + return DFHack::Core::getInstance().p; } static int lua_Process_readDWord(lua_State *S) @@ -275,7 +270,7 @@ const luaL_Reg lua_process_func[]= {NULL,NULL} }; #undef PROC_FUNC -void lua::RegisterProcess(lua::state &st,DFHack::Process *p) +void lua::RegisterProcess(lua::state &st) { st.getglobal("Process"); if(st.is()) @@ -284,9 +279,6 @@ void lua::RegisterProcess(lua::state &st,DFHack::Process *p) st.newtable(); } - st.pushlightuserdata(p); - st.setfield("__pointer"); - lua::RegFunctionsLocal(st, lua_process_func); st.setglobal("Process");