From 33bb7c3f72dcc6d3d6c1f23799976181ac1969da Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Fri, 10 Jun 2011 01:48:46 +0400 Subject: DREAMWEB: fixed memory deallocation --- engines/dreamweb/dreamweb.cpp | 15 ++++++++------ engines/dreamweb/runtime.h | 46 ++++++++++++++++++++++++++++++++----------- 2 files changed, 43 insertions(+), 18 deletions(-) (limited to 'engines/dreamweb') diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp index 3493e5d1e0..65cd2a0c43 100644 --- a/engines/dreamweb/dreamweb.cpp +++ b/engines/dreamweb/dreamweb.cpp @@ -318,7 +318,8 @@ void allocatemem(Context &context) { } void deallocatemem(Context &context) { - ::error("deallocatemem"); + debug(1, "deallocating segment %04x", (uint16)context.es); + context.deallocateSegment(context.es); } void removeemm(Context &context) { @@ -400,16 +401,18 @@ void setsoundoff(Context &context) { warning("setsoundoff: STUB"); } - -void loadsecondsample(Context &context) { - ::error("loadsecondsample"); -} +void readheader(Context &context); void loadsample(Context &context) { warning("loadsample: STUB"); openfile(context); closefile(context); - //readheader(context); //add exports to tasm recompiler +} + +void loadsecondsample(Context &context) { + warning("loadsecondsample: STUB"); + openfile(context); + closefile(context); } void loadspeech(Context &context) { diff --git a/engines/dreamweb/runtime.h b/engines/dreamweb/runtime.h index 45882a266d..0e106b9916 100644 --- a/engines/dreamweb/runtime.h +++ b/engines/dreamweb/runtime.h @@ -6,6 +6,8 @@ #include "common/array.h" #include "common/debug.h" #include "common/hashmap.h" +#include "common/list.h" +#include "common/ptr.h" namespace dreamgen { @@ -111,15 +113,17 @@ struct Segment { } }; +typedef Common::SharedPtr SegmentPtr; + class Context; class SegmentRef { - Context *_context; - uint16 _value; - Segment *_segment; + Context *_context; + uint16 _value; + SegmentPtr _segment; public: - SegmentRef(Context *ctx, uint16 value = 0, Segment *segment = 0): _context(ctx), _value(value), _segment(segment) { + SegmentRef(Context *ctx, uint16 value = 0, SegmentPtr segment = SegmentPtr()): _context(ctx), _value(value), _segment(segment) { } inline void reset(uint16 value); @@ -188,8 +192,11 @@ struct Flags { }; class Context { - typedef Common::HashMap SegmentMap; + typedef Common::HashMap SegmentMap; SegmentMap _segments; + + typedef Common::List FreeSegmentList; + FreeSegmentList _freeSegments; public: enum { kDefaultDataSegment = 0x1000, kVideoSegment = 0xa000 }; @@ -210,8 +217,9 @@ public: inline Context(): al(ax), ah(ax), bl(bx), bh(bx), cl(cx), ch(cx), dl(dx), dh(dx), cs(this), ds(this), es(this), data(this), video(this) { - _segments[kDefaultDataSegment] = Segment(); - _segments[kVideoSegment].data.resize(0x10000); + _segments[kDefaultDataSegment] = SegmentPtr(new Segment()); + _segments[kVideoSegment] = SegmentPtr(new Segment()); + _segments[kVideoSegment]->data.resize(0x10000); cs.reset(kDefaultDataSegment); ds.reset(kDefaultDataSegment); @@ -223,15 +231,29 @@ public: SegmentRef getSegment(uint16 value) { SegmentMap::iterator i = _segments.find(value); assert(i != _segments.end()); - return SegmentRef(this, value, &i->_value); + return SegmentRef(this, value, i->_value); } SegmentRef allocateSegment(uint size) { - unsigned id = kDefaultDataSegment + _segments.size(); + unsigned id; + if (_freeSegments.empty()) + id = kDefaultDataSegment + _segments.size(); + else { + id = _freeSegments.front(); + _freeSegments.pop_front(); + } assert(!_segments.contains(id)); - Segment &seg = _segments[id]; - seg.data.resize(size); - return SegmentRef(this, id, &seg); + SegmentPtr seg(new Segment()); + seg->data.resize(size); + _segments[id] = seg; + return SegmentRef(this, id, seg); + } + + void deallocateSegment(uint16 id) { + SegmentMap::iterator i = _segments.find(id); + assert(i != _segments.end()); + _segments.erase(i); + _freeSegments.push_back(id); } inline void _cmp(uint8 a, uint8 b) { -- cgit v1.2.3