/* * PSX-Tools Bundle Pack * Copyright (C) 2002-2005 Nicolas "Pixel" Noble * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: binwriter.cpp,v 1.1 2005-12-02 11:28:27 pixel Exp $ */ #include #include void BinWriter::merge(void) { Section * iter, * sub_iter; std::vector
merged; std::vector
to_merge; std::vector
::iterator i; bool is_in, did_merge, pure_bss, is_before_us; Uint32 base, real_size, whole_size, end_address, sub_size; for (iter = Section::GetFirst(); iter; iter = iter->GetNext()) { is_in = false; for (i = merged.begin(); i != merged.end(); i++) { if (*i == iter) { is_in = true; break; } } if (is_in) continue; merged.push_back(iter); to_merge.clear(); if (!iter->is_bss()) { to_merge.push_back(iter); } base = iter->get_offset(); if (iter->is_bss()) { real_size = 0; whole_size = iter->get_size(); pure_bss = true; } else { real_size = whole_size = iter->get_size(); pure_bss = false; } end_address = base + whole_size; #if 0 do { did_merge = false; is_before_us = true; for (sub_iter = Section::GetFirst(); sub_iter; iter = sub_iter->GetNext()) { is_in = false; if (sub_iter == iter) { is_before_us = false; continue; } for (i = merged.begin(); i != merged.end(); i++) { if (*i == sub_iter) { is_in = true; break; } } if (is_in) continue; // ***** CHECK AND/OR REWRITE THAT FUCKING CRAP ***** if (base >= sub_iter->get_offset()) { // The current sub-iter is below our base if (base > sub_iter->get_end_offset()) { // but it doesn't reach it... next! continue; } if ((base == sub_iter->get_end_offset()) && sub_iter->is_bss() && !pure_bss) { // they do not overlap, we are not a bss, and it's a bss. Skip! continue; } sub_size = base - sub_iter->get_offset(); if (sub_iter->is_bss() && !pure_bss) { // Worst case: it's overlapping, we're not a bss, and it's a bss... // We'll have to transform it into plain memory. if ((base + whole_size) < sub_iter->get_end_offset()) { // it's so big it goes beyond our end... let's extend our bss size then. whole_size = sub_iter->get_size(); end_address = sub_iter->get_end_offset(); } else { whole_size += sub_size; } base = sub_iter->get_offset(); real_size += sub_size; did_merge = true; merged.push_back(sub_iter); continue; } if (pure_bss && !sub_iter->is_bss()) { // we're a bss, and this is not. Let's transform ourselves. pure_bss = false; base = sub_iter->get_offset(); real_size = sub_iter->get_size(); if ((base + whole_size) < sub_iter->get_end_offset()) { // it's so big we don't have any bss anymore. whole_size = real_size; end_address = sub_iter->get_end_offset(); } else { whole_size += sub_size; } if (is_before_us) { to_merge.insert(to_merge.begin(), sub_iter); } else { to_merge.push_back(sub_iter); } did_merge = true; merged.push_back(sub_iter); continue; } if (pure_bss && sub_iter->is_bss()) { // we're both bss. if ((base + whole_size) < sub_iter->get_end_offset()) { // it's so big we are somewhat absorbed here. whole_size = real_size; end_address = sub_iter->get_end_offset(); } else { whole_size += sub_size; } base = sub_iter->get_offset(); did_merge = true; merged.push_back(sub_iter); continue; } if (!pure_bss && !sub_iter->is_bss()) { // we both have data if ((base + whole_size) < sub_iter->get_end_offset()) { // it's so big we are somewhat absorbed here. whole_size = real_size; end_address = sub_iter->get_end_offset(); } else { whole_size += sub_size; } base = sub_iter->get_offset(); real_size += sub_size; if (is_before_us) { to_merge.insert(to_merge.begin(), sub_iter); } else { to_merge.push_back(sub_iter); } } // lots of other conditions here... } else { // even more conditions here... } } } while (did_merge); #endif struct SectionOut so; if (!pure_bss) so.data = (char *) malloc(real_size); else so.data = NULL; so.base = base; so.real_size = real_size; so.whole_size = whole_size; for (i = to_merge.begin(); i != to_merge.end(); i++) { memcpy(so.data + (*i)->get_offset() - base, (*i)->get_bytes(), (*i)->get_size()); } sections.push_back(so); } } // Hubbold Roger - network latency.