void getexp(int r0, int c0, int rn, int cn, int fd) { struct ent **pp; struct ent *p; int r, c; for (r = r0; r <= rn; r++) { for (c = c0, pp = ATBL(tbl, r, c); c <= cn; pp++, c++) { *line = '\0'; p = *pp; if (p && p->expr) { linelim = 0; decompile(p->expr, 0); /* set line to expr */ line[linelim] = '\0'; if (*line == '?') *line = '\0'; } if (c < cn) strcat(line, "\t"); else strcat(line, "\n"); write(fd, line, strlen(line)); if (brokenpipe) { linelim = -1; return; } } } linelim = -1; }
int main(int argc, char *argv[]) { int filename_pos = 1; if (argc != filename_pos + 1) { fprintf(stderr, "Usage: delua file.lua\n"); exit(1); } char *filename = argv[filename_pos]; FILE *f = fopen(filename, "rb"); if (f == NULL) { perror(filename); exit(1); } lua_open(); ZIO z; luaZ_Fopen(&z, f, filename); TProtoFunc *tf = luaU_undump1(&z); fclose(f); if (tf == NULL) { fprintf(stderr, "%s isn't a valid lua script\n", filename); exit(1); } decompile(std::cout, tf, "", NULL, 0); lua_close(); return 0; }
void print(std::ostream &os) const { os << "function("; for (int i = 0; i < tf->code[1]; i++) { os << localname(tf, i); if (i + 1 < tf->code[1]) os << ", "; } os << ") -- line " << tf->lineDefined << std::endl; decompile(os, tf, indent_str + std::string(4, ' '), upvals, num_upvals); os << indent_str << "end"; }
void ncode(unsigned char *start, unsigned char *finish, unsigned int address, char is_32bit) { int all = finish - start; /* Number of bytes to disassemble */ pc = 0; instbuf = start; do_size = 1; /* Always output sizes */ while(pc < all) { inst_offset = address + pc; fprintf(listfp, "%05X ", inst_offset); addrsize = opsize = (is_32bit ? 32 : 16); decompile(); } fputc('\n', listfp); }
void write_colors(FILE *f, int indent) { int i, c = 0; for (i = 0; i < 8; i++) { if (cpairs[i] && cpairs[i]->expr) { sprintf(line, "color %d = ", i + 1); linelim = strlen(line); decompile(cpairs[i]->expr, 0); line[linelim] = '\0'; fprintf(f, "%*s%s\n", indent, "", line); if (brokenpipe) return; c++; } } if (indent && c) fprintf(f, "\n"); }
int main(int argc, char *argv[]) { parse_options(argc, argv); rdef_set_flags(sFlags); if (sDecompile) decompile(); else compile(); rdef_free_input_files(); rdef_free_include_dirs(); if (rdef_err != B_OK) report_error(); return EXIT_SUCCESS; }
bool idaapi dump_funcs_ctree(void *ud, qstring &crypto_prefix) { logmsg(DEBUG, "dump_funcs_ctree entered\n"); std::map<ea_t, ctree_dump_line> data_to_dump; // enumerate through all the functions in the idb file bool heuristic_flag; size_t count = 0, heur_count = 0, crypto_count = 0; size_t total_func_qty = get_func_qty(); for (size_t i = 0 ; i < total_func_qty ; i ++) { heuristic_flag = 0; func_t *function = getn_func(i); if (function != NULL) { bool crypto_flag = func_name_has_prefix(crypto_prefix, function->startEA); // skip libs that are not marked as crypto if ( ((function->flags & FUNC_LIB) != 0) && !crypto_flag ) continue; // From this point on, we have a function outside of lib or a crypto one // Ignore functions less than MIN_FUNC_SIZE_DUMP bytes if ( ((function->endEA - function->startEA) < MIN_FUNC_SIZE_DUMP) && !crypto_flag ) continue; // If function is bigger than MIN_HEURISTIC_FUNC_SIZE_DUMP, mark as being triggered by the heuristic if (function->endEA - function->startEA > MIN_HEURISTIC_FUNC_SIZE_DUMP) heuristic_flag = 1; // dump up to N_CRYPTO_FUNCS_TO_DUMP crypto functions // dump up to N_HEUR_FUNCS_TO_DUMP heuristic functions // at least N_FUNCS_TO_DUMP functions will be dumped if ((count < N_FUNCS_TO_DUMP) || (crypto_flag && (crypto_count < N_CRYPTO_FUNCS_TO_DUMP)) || (heuristic_flag && (heur_count < N_HEUR_FUNCS_TO_DUMP))) { hexrays_failure_t hf; cfuncptr_t cfunc = decompile(function, &hf); logmsg(DEBUG, "\nafter decompile()\n"); if (cfunc != NULL) { ctree_dumper_t ctree_dumper; ctree_dumper.apply_to(&cfunc->body, NULL); ctree_dump_line func_dump; func_dump.ctree_dump = ctree_dumper.ctree_dump; func_dump.ctree_for_hash = ctree_dumper.ctree_for_hash; func_dump.func_depth = -1; func_dump.func_start = function->startEA; func_dump.func_end = function->endEA; qstring func_name; if (get_func_name2(&func_name, function->startEA) != 0) { if (func_name.length() > 0) { func_dump.func_name = func_name; } } func_parent_iterator_t fpi(function); for (ea_t addr = get_first_cref_to(function->startEA); addr != BADADDR; addr = get_next_cref_to(function->startEA, addr)) { func_t *referer = get_func(addr); if (referer != NULL) { func_dump.referres.push_back(referer->startEA); } } func_dump.heuristic_flag = heuristic_flag; // 0 or 1 depending on code above if (heuristic_flag) heur_count++; if (crypto_flag) crypto_count++; count++; data_to_dump[function->startEA] = func_dump; } } } } dump_ctrees_in_file(data_to_dump, crypto_prefix); return true; }
void CScriptEdit::OnLoadex() { char BASED_CODE *szFilter; CString m_text; CString fpath; int fhandle; int res; char *pos; res=OFN_FILEMUSTEXIST|OFN_ENABLESIZING|OFN_EXPLORER; if(readonly) res|=OFN_READONLY; szFilter=szFilterb; CMyFileDialog m_getfiledlg(TRUE, m_bcs?"bcs":"baf", m_bcs ? makeitemname(".bcs",0): makeitemname(".baf",1), res, szFilter); m_getfiledlg.m_ofn.nFilterIndex = m_bcs+1; if( m_getfiledlg.DoModal() == IDOK ) { filepath = fpath = m_getfiledlg.GetPathName(); if(checkfile(fpath,"SC") ) { m_bcs=1; res=decompile(filepath, m_getfiledlg.GetFileTitle()); //decompile first if(res) { MessageBox("Cannot decompile file: "+fpath+"!","Error",MB_OK); return; } lastopenedoverride=fpath.Left(filepath.ReverseFind('\\')); } else { //remember the path when opening a script source m_bcs=0; lastopenedscript=fpath.Left(filepath.ReverseFind('\\')); } fhandle=open(filepath, O_RDONLY|O_BINARY); if(fhandle<1) { MessageBox("Cannot open file!","Error",MB_OK); return; } readonly=m_getfiledlg.GetReadOnlyPref(); res=filelength(fhandle); if(res>=0) { pos=m_text.GetBufferSetLength(res); if(pos) { if(read(fhandle,pos,res)!=res) res=-9; else res=0; } else res=-9; } m_text.ReleaseBuffer(); close(fhandle); m_text_control.SetWindowText(m_text); switch(res) { case 0: if((m_bcs==1) && (editflg&REMBAF) ) {//removing decompiled baf unlink(filepath); } itemname=m_getfiledlg.GetFileTitle(); itemname.MakeUpper(); break; case -9: //special error: cannot read decompiled script MessageBox("Cannot read script!","Error",MB_OK); default: //that error was already handled elsewhere OnNew(); return; } } UpdateData(UD_DISPLAY); the_script.m_changed=false; CheckScript(WHOLE_CHECK|FORCED_CHECK); RefreshDialog(); }
void CScriptEdit::OnLoad() { CString filepath; CString m_text; int fhandle; int res; char *pos; pickerdlg.m_restype=REF_BCS; pickerdlg.m_picked=itemname; res=pickerdlg.DoModal(); if(res==IDOK) { filepath=pickerdlg.m_picked+".bcs"; itemname=pickerdlg.m_picked; m_bcs=1; res=decompile(filepath, itemname); //this will decompile the bcs if(res) { MessageBox("Cannot decompile file!","Error",MB_OK); } else { fhandle=open(filepath, O_RDONLY|O_BINARY); if(!fhandle) { MessageBox("Cannot open file!","Error",MB_OK); res=-1; } if(!res) {//fhandle will always get initialized if res was 0 res=filelength(fhandle); if(res>=0) { pos=m_text.GetBufferSetLength(res); if(pos) { if(read(fhandle,pos,res)!=res) res=-1; else res=0; } else res=-1; m_text.ReleaseBuffer(); m_text_control.SetWindowText(m_text); } close(fhandle); } } switch(res) { case 0: if((m_bcs==1) && (editflg&REMBAF) ) {//removing decompiled baf unlink(filepath); } break; default: MessageBox("Cannot read script!","Error",MB_OK); OnNew(); return; } } UpdateData(UD_DISPLAY); the_script.m_changed=false; CheckScript(WHOLE_CHECK|FORCED_CHECK); RefreshDialog(); }
bool idaapi extract_all_types(void *ud) { logmsg(DEBUG, "extract_types()\n"); // find vtables in the binary search_objects(false); qvector <VTBL_info_t>::iterator vtbl_iter; std::map<ea_t, VTBL_info_t> vtbl_map; for (vtbl_iter = vtbl_t_list.begin(); vtbl_iter != vtbl_t_list.end(); vtbl_iter++) vtbl_map[(*vtbl_iter).ea_begin] = (*vtbl_iter); int file_id = create_open_file("types.txt"); if (file_id == -1) { logmsg(ERROR, "Failed to open file for dumping types.txt\r\n"); return false; } int struct_no = 0; for (vtbl_iter = vtbl_t_list.begin(); vtbl_iter != vtbl_t_list.end(); vtbl_iter++) { qstring info_msg; info_msg.cat_sprnt("Processing vtable %s\n", (*vtbl_iter).vtbl_name.c_str()); logmsg(DEBUG, info_msg.c_str()); qstring type_name; type_name.sprnt("struc_2_%d", struct_no); ea_t cur_vt_ea = (*vtbl_iter).ea_begin; int struct_subno = 0; qvector <qstring> types_to_merge; for (ea_t addr = get_first_dref_to(cur_vt_ea); addr != BADADDR; addr = get_next_dref_to(cur_vt_ea, addr)) { qstring name; if (get_func_name(&name, addr) <= 0) continue; qstring info_msg1; info_msg1.cat_sprnt("\t%s\n", name.c_str()); logmsg(DEBUG, info_msg1.c_str()); func_t *pfn = get_func(addr); if (!pfn) continue; hexrays_failure_t hf; cfuncptr_t cfunc = decompile(pfn, &hf); if (cfunc != NULL) { qstring var_name; info_msg.clear(); if (find_var(cfunc, (*vtbl_iter).vtbl_name, var_name)) { info_msg.cat_sprnt(" : %s\n", var_name.c_str()); logmsg(DEBUG, info_msg.c_str()); qstring sub_type_name = type_name; sub_type_name.cat_sprnt("_%d", struct_subno); struct_subno++; if (reconstruct_type(cfunc, var_name, sub_type_name)) { if (check_subtype((*vtbl_iter), sub_type_name)) { types_to_merge.push_back(sub_type_name); } } } else { info_msg.cat_sprnt(" : none\n"); logmsg(DEBUG, info_msg.c_str()); } } } struct_no++; merge_types(types_to_merge, type_name); dump_type_info(file_id, (*vtbl_iter), type_name, vtbl_map); } qclose(file_id); return true; }
void PGRAPH::Begin(Primitive primitive) { // Set surface setSurface(); // Set viewport gfx::Viewport viewportRect = { viewport.x, viewport.y, viewport.width, viewport.height, 0.0f, 1.0f }; gfx::Rectangle scissorRect = { scissor.x, scissor.y, scissor.width, scissor.height }; cmdBuffer->cmdSetViewports(1, &viewportRect); cmdBuffer->cmdSetScissors(1, &scissorRect); // Hashing auto vpData = &vpe.data[vpe.start]; auto vpHash = HashVertexProgram(vpData); auto fpData = memory->ptr<rsx_fp_instruction_t>((fp_location ? rsx->get_ea(0x0) : 0xC0000000) + fp_offset); auto fpHash = HashFragmentProgram(fpData); auto pipelineHash = hashStruct(pipeline) ^ vpHash ^ fpHash; if (cachePipeline.find(pipelineHash) == cachePipeline.end()) { const auto& p = pipeline; if (cacheVP.find(vpHash) == cacheVP.end()) { auto vp = std::make_unique<RSXVertexProgram>(); vp->decompile(vpData); vp->compile(graphics.get()); cacheVP[vpHash] = std::move(vp); } if (cacheFP.find(fpHash) == cacheFP.end()) { auto fp = std::make_unique<RSXFragmentProgram>(); fp->decompile(fpData); fp->compile(graphics.get()); cacheFP[fpHash] = std::move(fp); } gfx::PipelineDesc pipelineDesc = {}; pipelineDesc.formatDSV = convertFormat(surface.depthFormat); pipelineDesc.numCBVs = 2; pipelineDesc.numSRVs = RSX_MAX_TEXTURES; pipelineDesc.vs = cacheVP[vpHash]->shader; pipelineDesc.ps = cacheFP[fpHash]->shader; pipelineDesc.rsState.fillMode = gfx::FILL_MODE_SOLID; pipelineDesc.rsState.cullMode = p.cull_face_enable ? convertCullMode(p.cull_mode) : gfx::CULL_MODE_NONE; pipelineDesc.rsState.frontCounterClockwise = convertFrontFace(p.front_face); pipelineDesc.rsState.depthEnable = p.depth_test_enable; pipelineDesc.rsState.depthWriteMask = p.depth_mask ? gfx::DEPTH_WRITE_MASK_ALL : gfx::DEPTH_WRITE_MASK_ZERO; pipelineDesc.rsState.depthFunc = convertCompareFunc(p.depth_func); pipelineDesc.rsState.stencilEnable = p.stencil_test_enable; pipelineDesc.rsState.stencilReadMask = p.stencil_func_mask; pipelineDesc.rsState.stencilWriteMask = p.stencil_mask; pipelineDesc.rsState.frontFace.stencilOpFail = convertStencilOp(p.stencil_op_fail); pipelineDesc.rsState.frontFace.stencilOpZFail = convertStencilOp(p.stencil_op_zfail); pipelineDesc.rsState.frontFace.stencilOpPass = convertStencilOp(p.stencil_op_zpass); pipelineDesc.rsState.frontFace.stencilFunc = convertCompareFunc(p.stencil_func); if (p.two_sided_stencil_test_enable) { pipelineDesc.rsState.backFace.stencilOpFail = convertStencilOp(p.stencil_op_fail); pipelineDesc.rsState.backFace.stencilOpZFail = convertStencilOp(p.stencil_op_zfail); pipelineDesc.rsState.backFace.stencilOpPass = convertStencilOp(p.stencil_op_zpass); pipelineDesc.rsState.backFace.stencilFunc = convertCompareFunc(p.stencil_func); } else { pipelineDesc.rsState.backFace.stencilOpFail = convertStencilOp(p.back_stencil_op_fail); pipelineDesc.rsState.backFace.stencilOpZFail = convertStencilOp(p.back_stencil_op_zfail); pipelineDesc.rsState.backFace.stencilOpPass = convertStencilOp(p.back_stencil_op_zpass); pipelineDesc.rsState.backFace.stencilFunc = convertCompareFunc(p.back_stencil_func); } pipelineDesc.cbState.colorTarget[0].enableBlend = p.blend_enable; pipelineDesc.cbState.colorTarget[0].enableLogicOp = p.logic_op_enable; pipelineDesc.cbState.colorTarget[0].blendOp = convertBlendOp(p.blend_equation_rgb); pipelineDesc.cbState.colorTarget[0].blendOpAlpha = convertBlendOp(p.blend_equation_alpha); pipelineDesc.cbState.colorTarget[0].srcBlend = convertBlend(p.blend_sfactor_rgb); pipelineDesc.cbState.colorTarget[0].destBlend = convertBlend(p.blend_dfactor_rgb); pipelineDesc.cbState.colorTarget[0].srcBlendAlpha = convertBlend(p.blend_sfactor_alpha); pipelineDesc.cbState.colorTarget[0].destBlendAlpha = convertBlend(p.blend_dfactor_alpha); pipelineDesc.cbState.colorTarget[0].colorWriteMask = convertColorMask(p.color_mask); pipelineDesc.cbState.colorTarget[0].logicOp = convertLogicOp(p.logic_op); pipelineDesc.iaState.topology = convertPrimitiveTopology(primitive); for (U32 index = 0; index < RSX_MAX_VERTEX_INPUTS; index++) { const auto& attr = vpe.attr[index]; if (!attr.size) { continue; } gfx::Format format = convertVertexFormat(attr.type, attr.size); U32 stride = attr.stride; pipelineDesc.iaState.inputLayout.push_back({ index, format, index, 0, stride, 0, gfx::INPUT_CLASSIFICATION_PER_VERTEX, 0 } ); } for (U32 i = 0; i < RSX_MAX_TEXTURES; i++) { gfx::Sampler sampler = {}; sampler.filter = gfx::FILTER_MIN_MAG_MIP_LINEAR; sampler.addressU = gfx::TEXTURE_ADDRESS_MIRROR; sampler.addressV = gfx::TEXTURE_ADDRESS_MIRROR; sampler.addressW = gfx::TEXTURE_ADDRESS_MIRROR; pipelineDesc.samplers.push_back(sampler); } cachePipeline[pipelineHash] = std::unique_ptr<gfx::Pipeline>(graphics->createPipeline(pipelineDesc)); } heapResources->reset(); heapResources->pushVertexBuffer(vpeConstantMemory); heapResources->pushVertexBuffer(vtxTransform); // Upload VPE constants if necessary void* constantsPtr = vpeConstantMemory->map(); memcpy(constantsPtr, &vpe.constant, sizeof(vpe.constant)); vpeConstantMemory->unmap(); // Upload vertex transform matrix if necessary if (vertex_transform_dirty) { V128* transformPtr = reinterpret_cast<V128*>(vtxTransform->map()); memset(transformPtr, 0, 4 * sizeof(V128)); F32 half_cliph = surface.width / 2.0f; F32 half_clipv = surface.height / 2.0f; transformPtr[0].f32[0] = (viewport_scale.f32[0] / half_cliph); transformPtr[1].f32[1] = (viewport_scale.f32[1] / half_clipv); transformPtr[2].f32[2] = (viewport_scale.f32[2]); transformPtr[0].f32[3] = (viewport_offset.f32[0] - half_cliph) / half_cliph; transformPtr[1].f32[3] = (viewport_offset.f32[1] - half_clipv) / half_clipv; transformPtr[2].f32[3] = (viewport_offset.f32[2]); transformPtr[3].f32[3] = 1.0f; vtxTransform->unmap(); } // Set textures for (U32 i = 0; i < RSX_MAX_TEXTURES; i++) { const auto& tex = texture[i]; // Dummy texture if (!tex.enable) { gfx::TextureDesc texDesc = {}; texDesc.width = 2; texDesc.height = 2; texDesc.format = gfx::FORMAT_R8G8B8A8_UNORM; texDesc.mipmapLevels = 1; texDesc.swizzle = TEXTURE_SWIZZLE_ENCODE( gfx::TEXTURE_SWIZZLE_VALUE_0, gfx::TEXTURE_SWIZZLE_VALUE_0, gfx::TEXTURE_SWIZZLE_VALUE_0, gfx::TEXTURE_SWIZZLE_VALUE_0 ); gfx::Texture* texDescriptor = graphics->createTexture(texDesc); heapResources->pushTexture(texDescriptor); } // Upload real texture else { auto texFormat = static_cast<TextureFormat>(tex.format & ~RSX_TEXTURE_LN & ~RSX_TEXTURE_UN); gfx::TextureDesc texDesc = {}; texDesc.data = memory->ptr<Byte>((tex.location ? rsx->get_ea(0x0) : 0xC0000000) + tex.offset); texDesc.size = tex.width * tex.height; texDesc.width = tex.width; texDesc.height = tex.height; texDesc.format = convertTextureFormat(texFormat); texDesc.mipmapLevels = tex.mipmap; texDesc.swizzle = convertTextureSwizzle(texFormat); switch (texFormat) { case RSX_TEXTURE_B8: texDesc.size *= 1; break; case RSX_TEXTURE_A1R5G5B5: texDesc.size *= 2; break; case RSX_TEXTURE_A4R4G4B4: texDesc.size *= 2; break; case RSX_TEXTURE_R5G6B5: texDesc.size *= 2; break; case RSX_TEXTURE_A8R8G8B8: texDesc.size *= 4; break; default: assert_always("Unimplemented"); } gfx::Texture* texDescriptor = graphics->createTexture(texDesc); heapResources->pushTexture(texDescriptor); } } cmdBuffer->cmdBindPipeline(cachePipeline[pipelineHash].get()); cmdBuffer->cmdSetHeaps({ heapResources }); cmdBuffer->cmdSetDescriptor(0, heapResources, 0); cmdBuffer->cmdSetDescriptor(1, heapResources, 2); cmdBuffer->cmdSetPrimitiveTopology(convertPrimitiveTopology(primitive)); }
int main(int argc, char **argv) { int i; int start_flag = 0; wadfile_t *wf; char *s; char *program; char *wadfile = NULL; /* save program name for usage() */ program = *argv; printf("%s version %s\n\n", program, VERSION); /* process options */ while ((--argc > 0) && (**++argv == '-')) { for (s = *argv+1; *s != '\0'; s++) { switch (*s) { case 'p': preserve_case++; break; case 'c': argc--; argv++; if (!strcmp(*argv, "doom")) palette = doom_rgb; else if (!strcmp(*argv, "heretic")) palette = heretic_rgb; else if (!strcmp(*argv, "hexen")) palette = hexen_rgb; else if (!strcmp(*argv, "strife")) palette = strife_rgb; else usage(program, NULL); break; default: usage(program, --s); } } } /* have one argument left? */ if (argc == 0) wadfile = fw_find_iwad(); else if (argc == 1) wadfile = fw_find_wad(*argv); else usage(program, NULL); if(!wadfile) { fprintf(stderr, "Couldn't find WAD file\n"); exit(2); } /* open WAD file */ wf = open_wad(wadfile); /* just make flats directory, ignore errors, deal with it later */ #ifdef __MINGW32__ mkdir("flats"); #else mkdir("flats", 0777); #endif /* loop over all lumps and look for the flats */ for (i = 0; i < wf->wh.numlumps; i++) { /* start processing after F_START */ if (!lump_name_cmp(wf->lp->lumps[i]->name, "F_START")) { if (start_flag) continue; start_flag = 1; printf("found F_START, start decompiling flats\n"); continue; /* also accept FF_START */ } else if (!lump_name_cmp(wf->lp->lumps[i]->name, "FF_START")) { if (start_flag) continue; start_flag = 1; printf("found FF_START, start decompiling flats\n"); continue; } else if (!lump_name_cmp(wf->lp->lumps[i]->name, "F_END")) { start_flag = 0; printf("found F_END, done\n"); break; } else if (!lump_name_cmp(wf->lp->lumps[i]->name, "FF_END")) { start_flag = 0; printf("found FF_END, done\n"); break; } else { if (start_flag && (wf->lp->lumps[i]->size == 4096 || wf->lp->lumps[i]->size == 4160 || wf->lp->lumps[i]->size == 8192)) { decompile(wf, i); } } } /* done */ close_wad(wf); return 0; }
int main(int argc, char **argv) { char *program; char *s; char *wadfile; wadfile_t *wf; int i; int start_flag = 0; /* save program name for usage() */ program = *argv; printf("%s version %s\n\n", program, VERSION); /* process options */ while ((--argc > 0) && (**++argv == '-')) { for (s = *argv+1; *s != '\0'; s++) { switch (*s) { case 'c': argc--; argv++; if (!strcmp(*argv, "doom")) palette = doom_rgb; else if (!strcmp(*argv, "heretic")) palette = heretic_rgb; else if (!strcmp(*argv, "hexen")) palette = hexen_rgb; else if (!strcmp(*argv, "strife")) palette = strife_rgb; else usage(program, NULL); break; case 'p': preserve_case++; break; case 'w': argc--; argv++; wildcard = *argv; { char *p; for (p = wildcard; *p != '\0'; p++) *p = toupper(*((unsigned char *) p)); } break; default: usage(program, --s); } } } /* have one argument left? */ if (argc == 1) wadfile = fw_find_wad(*argv); else if(argc == 0) wadfile = fw_find_iwad(); else usage(program, NULL); if(!wadfile) { fprintf(stderr, "Couldn't find WAD file\n"); exit(2); } /* open WAD file */ wf = open_wad(wadfile); /* * make sprites directory, ignore errors, we'll handle that later * when we try to write the graphics files into it */ #ifdef __MINGW32__ mkdir("sprites"); #else mkdir("sprites", 0777); #endif /* loop over all lumps and look for the sprites */ for (i = 0; i < wf->wh.numlumps; i++) { /* start processing after S_START */ if (!start_flag && !lump_name_cmp(wf->lp->lumps[i]->name, "S_START")) { start_flag = 1; printf("found S_START, start decompiling sprites\n"); continue; } else if (!start_flag && !lump_name_cmp(wf->lp->lumps[i]->name, "SS_START")) { start_flag = 1; printf("found SS_START, start decompiling sprites\n"); continue; } else if (start_flag && !lump_name_cmp(wf->lp->lumps[i]->name, "S_END")) { start_flag = 0; printf("found S_END, done\n"); break; } else { if (start_flag) { char name[9]; size_t n; for (n = 0; n < 8; n++) { name[n] = toupper(wf->lp->lumps[i]->name[n]); } name[n] = '\0'; if (wildcard != NULL && fnmatch(wildcard, name, 0) != 0) continue; decompile(wf, i); } } } /* print number of errors (for Windows) */ printf("\n\nNumber of write errors: %d\n", errors); /* clean up and done */ close_wad(wf); return 0; }
void decompile(ast_t *root) { if (root !=0) { switch(root->type) { /* ROOT NODE */ case AST_PROGRAM_INI: decompile(root->son[0]); break; /* ROOT NODE */ case AST_PROGRAM: decompile(root->son[0]); decompile(root->son[1]); break; /* COMMANDS */ case AST_CMD_LIST: decompile(root->son[0]); if(root->son[1]!=0) fprintf(outputFile,";\n"); decompile(root->son[1]); break; /* BLOCK */ case AST_BLOCK: fprintf(outputFile,"{\n"); decompile(root->son[0]); fprintf(outputFile,"}"); break; /* DATA TYPE */ case AST_WORD: fprintf(outputFile,"word "); break; case AST_BYTE: fprintf(outputFile,"byte "); break; case AST_BOOL: fprintf(outputFile,"bool "); break; case AST_SYMBOL: fprintf(outputFile,"%s",root->symbol->text); decompile(root->son[0]); break; /* ARIM OPERATIONS */ case AST_ADD: decompile(root->son[0]); fprintf(outputFile," + "); decompile(root->son[1]); break; case AST_SUB: decompile(root->son[0]); fprintf(outputFile," - "); decompile(root->son[1]); break; case AST_MUL: decompile(root->son[0]); fprintf(outputFile," * "); decompile(root->son[1]); break; case AST_DIV: decompile(root->son[0]); fprintf(outputFile," / "); decompile(root->son[1]); break; /* LOGICAL OPERATIONS*/ case AST_GREATER: decompile(root->son[0]); fprintf(outputFile," > "); decompile(root->son[1]); break; case AST_LESS: decompile(root->son[0]); fprintf(outputFile," < "); decompile(root->son[1]); break; case AST_AND: decompile(root->son[0]); fprintf(outputFile," && "); decompile(root->son[1]); break; case AST_OR: decompile(root->son[0]); fprintf(outputFile," || "); decompile(root->son[1]); case AST_LE: decompile(root->son[0]); fprintf(outputFile," <= "); decompile(root->son[1]); break; case AST_GE: decompile(root->son[0]); fprintf(outputFile," >= "); decompile(root->son[1]); break; case AST_EQ: decompile(root->son[0]); fprintf(outputFile," == "); decompile(root->son[1]); break; case AST_NE: decompile(root->son[0]); fprintf(outputFile," != "); decompile(root->son[1]); break; case AST_INV_EXPR: decompile(root->son[0]); fprintf(outputFile,"("); decompile(root->son[1]); fprintf(outputFile,")"); break; case AST_BOOLEAN_INV: fprintf(outputFile,"!"); break; case AST_ARIT_INV: fprintf(outputFile,"-"); break; /* I/O */ case AST_IN: fprintf(outputFile,"input "); fprintf(outputFile,"%s",root->symbol->text); decompile(root->son[1]); break; case AST_OUT: fprintf(outputFile,"output "); decompile(root->son[0]); break; case AST_OUT_ARG: if(root->symbol !=0) fprintf(outputFile,"%s",root->symbol->text); decompile(root->son[0]); if(root->son[1]!=0) fprintf(outputFile,","); decompile(root->son[1]); break; case AST_OUT_ARG_STR: if(root->symbol !=0) fprintf(outputFile,"%s",root->symbol->text); decompile(root->son[0]); if(root->son[1]!=0) fprintf(outputFile,","); decompile(root->son[1]); break; /* EXPRESSION */ case AST_PAR_EXPR: fprintf(outputFile,"("); decompile(root->son[1]); fprintf(outputFile,")"); break; /* FLUX CONTROL */ case AST_IF: fprintf(outputFile,"if ("); decompile(root->son[0]); fprintf(outputFile,") "); decompile(root->son[1]); decompile(root->son[2]); break; case AST_CMD_THEN: fprintf(outputFile,"then "); break; case AST_CMD_ELSE: fprintf(outputFile,"else "); break; case AST_CMD_LOOP: fprintf(outputFile,"loop "); break; /* DECLARATIONS */ case AST_DEC: decompile(root->son[0]); decompile(root->son[1]); fprintf(outputFile,";\n"); break; case AST_DECL: decompile(root->son[0]); decompile(root->son[1]); fprintf(outputFile,";\n"); break; case AST_FUN_DEF: decompile(root->son[0]); fprintf(outputFile,"%s (",root->symbol->text); decompile(root->son[1]); fprintf(outputFile,")"); fprintf(outputFile,"\n"); decompile(root->son[2]); break; case AST_NDEC: decompile(root->son[0]); fprintf(outputFile,"%s:",root->symbol->text); decompile(root->son[1]); break; case AST_POINTER_DEC: decompile(root->son[0]); fprintf(outputFile,"$%s:",root->symbol->text); decompile(root->son[1]); break; case AST_ARRAY_DEC: decompile(root->son[0]); fprintf(outputFile,"%s[",root->symbol->text); decompile(root->son[1]); fprintf(outputFile,"]"); if(root->son[2] !=0) fprintf(outputFile,":"); decompile(root->son[2]); break; case AST_INDEX: fprintf(outputFile,"["); decompile(root->son[0]); fprintf(outputFile,"]"); break; /* POINTERS */ case AST_POINTER: fprintf(outputFile,"$%s",root->symbol->text); break; case AST_POINTER_ADDR: fprintf(outputFile,"&%s",root->symbol->text); break; /* FUNCTIONS AND PARAMETERS */ case AST_PARAM: decompile(root->son[0]); fprintf(outputFile,"%s",root->symbol->text); if(root->son[1] !=0) fprintf(outputFile,","); decompile(root->son[1]); break; case AST_PASS_PARAM: decompile(root->son[0]); if(root->son[1]!=0) fprintf(outputFile,","); decompile(root->son[1]); break; case AST_PARAM_REF: fprintf(outputFile,"$"); decompile(root->son[0]); if(root->son[1]!=0) fprintf(outputFile,","); decompile(root->son[1]); break; case AST_FUNC_CALL: fprintf(outputFile,"%s",root->symbol->text); fprintf(outputFile,"("); decompile(root->son[0]); fprintf(outputFile,")"); break; case AST_RETURN: fprintf(outputFile,"return "); decompile(root->son[0]); break; /* ATRIBUITIONS */ case AST_ATRR: decompile(root->son[0]); fprintf(outputFile," = "); decompile(root->son[1]); break; case AST_ATRR_LIT: decompile(root->son[0]); if(root->son[1])fprintf(outputFile," "); decompile(root->son[1]); break; /* DEFAULT ACTION */ default: printf("END"); break; } } }
int main(int argc, char **argv) { int rc = 0; /* Exit code */ char *s; listitem_t *wadlist; /* Linked list of open wads */ char *iwad = NULL; /* Filename of the iwad (or NULL) */ void *pnames; /* The contents of the PNAMES lump */ void *texture1; /* The contents of the TEXTURE1 lump */ void *texture2; /* The contents of the TEXTURE2 lump */ printf("%s version %s\n\n", program, VERSION); /* process options */ while ((--argc > 0) && (**++argv == '-')) { for (s = *argv+1; *s != '\0'; s++) { switch (*s) { case 'c': argc--; argv++; if (!strcmp(*argv, "doom")) palette = doom_rgb; else if (!strcmp(*argv, "heretic")) palette = heretic_rgb; else if (!strcmp(*argv, "hexen")) palette = hexen_rgb; else if (!strcmp(*argv, "strife")) palette = strife_rgb; else usage(NULL); break; case 'i': argc--; argv++; iwad = *argv; break; case 'm': mpatch_policy = OIT_IF_ALL; break; case 'M': mpatch_policy = OIT_ALWAYS; break; case 'n': extract = 0; break; case 'p': preserve_case++; break; case 't': tflag++; break; case 'w': argc--; argv++; wildcard = *argv; { char *p; for (p = wildcard; *p != '\0'; p++) *p = toupper(*((unsigned char *) p)); } break; default: usage(--s); } } } if (argc == 0 && iwad == NULL) { err("No wad given"); exit(1); } /* build list of wads, last pwad first, iwad last */ wadlist = NULL; if (iwad != NULL) { wadlist = malloc(sizeof *wadlist); if (wadlist == NULL) { err("Not enough memory"); exit(1); } wadlist->name = iwad; wadlist->wf = open_wad(iwad); wadlist->next = NULL; } for (; argc > 0; argv++, argc--) { listitem_t *newitem = malloc(sizeof *newitem); if (newitem == NULL) { err("Not enough memory"); exit(1); } /* insert at the beginning of the list */ newitem->name = *argv; newitem->wf = open_wad(*argv); newitem->next = wadlist; wadlist = newitem; } /* locate PNAMES, TEXTURE1 and TEXTURE2 */ pnames = NULL; texture1 = NULL; texture2 = NULL; { listitem_t *wad; for (wad = wadlist; wad != NULL; wad = wad->next) { if (pnames == NULL) pnames = get_lump_by_name(wad->wf, "PNAMES"); if (texture1 == NULL) texture1 = get_lump_by_name(wad->wf, "TEXTURE1"); if (texture2 == NULL) texture2 = get_lump_by_name(wad->wf, "TEXTURE2"); } } if (pnames == NULL) { err("No PNAMES lump found"); exit(1); } if (texture1 == NULL) { err("No TEXTURE1 lump found"); exit(1); } /* * make textures directory, ignore errors, we'll handle that later * when we try to write the graphics files into it */ if (extract || tflag) mkdir("textures", 0777); /* decompile the textures */ printf("Got TEXTURE1 lump, decompiling...\n"); { int r = decompile(wadlist, "TEXTURE1", texture1, pnames); if (r > rc) rc = r; if (texture2 != NULL) { printf("Got TEXTURE2 lump, decompiling...\n"); r = decompile(wadlist, "TEXTURE2", texture2, pnames); if (r > rc) rc = r; } } /* clean up and done */ if (pnames != NULL) free(pnames); if (texture1 != NULL) free(texture1); if (texture2 != NULL) free(texture2); { listitem_t *wad, *next; for (wad = wadlist; wad != NULL;) { next = wad->next; if (wad->wf != NULL) close_wad(wad->wf); free(wad); wad = next; } } if (img_buf != NULL) free(img_buf); return rc; }