From 5aa1877beffa71a2cc712a85b74a788e22a924e2 Mon Sep 17 00:00:00 2001 From: Julien Date: Sun, 5 Jun 2011 05:01:39 +0800 Subject: TEENAGENT: Allocate large buffers on the heap instead of the stack --- engines/teenagent/resources.cpp | 11 +++- engines/teenagent/teenagent.cpp | 129 +++++++++++++++++++++++++++++++--------- 2 files changed, 111 insertions(+), 29 deletions(-) diff --git a/engines/teenagent/resources.cpp b/engines/teenagent/resources.cpp index 9e69383215..597ca670c0 100644 --- a/engines/teenagent/resources.cpp +++ b/engines/teenagent/resources.cpp @@ -106,13 +106,20 @@ void Resources::loadOff(Graphics::Surface &surface, byte *palette, int id) { error("invalid background %d", id); return; } - byte buf[64768]; - off.read(id, buf, sizeof(buf)); + + const uint bufferSize = 64768; + byte *buf = (byte *)malloc(bufferSize); + if (!buf) + error("[Resources::loadOff] Cannot allocate buffer"); + + off.read(id, buf, bufferSize); byte *src = buf; byte *dst = (byte *)surface.pixels; memcpy(dst, src, 64000); memcpy(palette, buf + 64000, 768); + + free(buf); } Common::SeekableReadStream *Resources::loadLan(uint32 id) const { diff --git a/engines/teenagent/teenagent.cpp b/engines/teenagent/teenagent.cpp index 724f75be2f..0289b994e6 100644 --- a/engines/teenagent/teenagent.cpp +++ b/engines/teenagent/teenagent.cpp @@ -216,14 +216,22 @@ Common::Error TeenAgentEngine::loadGameState(int slot) { Resources *res = Resources::instance(); - assert(res->dseg.size() >= 0x6478 + 0x777a); - char data[0x777a]; + const uint dataSize = 0x777a; + assert(res->dseg.size() >= 0x6478 + dataSize); + + char *data = (char *)malloc(dataSize); + if (!data) + error("[TeenAgentEngine::loadGameState] Cannot allocate buffer"); + in->seek(0); - if (in->read(data, 0x777a) != 0x777a) { + if (in->read(data, dataSize) != dataSize) { + free(data); return Common::kReadingFailed; } - memcpy(res->dseg.ptr(0x6478), data, sizeof(data)); + memcpy(res->dseg.ptr(0x6478), data, dataSize); + + free(data); scene->clear(); inventory->activate(false); @@ -290,17 +298,32 @@ bool TeenAgentEngine::showCDLogo() { if (!cdlogo.exists("cdlogo.res") || !cdlogo.open("cdlogo.res")) return true; - byte bg[0xfa00]; - byte palette[3*256]; + const uint bgSize = 0xfa00; + const uint paletteSize = 3 * 256; + + byte *bg = (byte *)malloc(bgSize); + if (!bg) + error("[TeenAgentEngine::showCDLogo] Cannot allocate background buffer"); + + byte *palette = (byte *)malloc(paletteSize); + if (!palette) { + free(bg); + error("[TeenAgentEngine::showCDLogo] Cannot allocate palette buffer"); + } + + cdlogo.read(bg, bgSize); + cdlogo.read(palette, paletteSize); - cdlogo.read(bg, sizeof(bg)); - cdlogo.read(palette, sizeof(palette)); - for (uint c = 0; c < 3*256; ++c) + for (uint c = 0; c < paletteSize; ++c) palette[c] *= 4; + _system->getPaletteManager()->setPalette(palette, 0, 0x100); _system->copyRectToScreen(bg, 320, 0, 0, 320, 200); _system->updateScreen(); + free(bg); + free(palette); + for(uint i = 0; i < 20; ++i) { int r = skipEvents(); if (r != 0) @@ -317,43 +340,66 @@ bool TeenAgentEngine::showLogo() { if (!logo.open("unlogic.res")) return true; - byte bg[0xfa00]; - byte palette[3*256]; - Common::ScopedPtr frame(logo.getStream(1)); if (!frame) return true; - frame->read(bg, sizeof(bg)); - frame->read(palette, sizeof(palette)); - for (uint c = 0; c < 3*256; ++c) + const uint bgSize = 0xfa00; + const uint paletteSize = 3 * 256; + + byte *bg = (byte *)malloc(bgSize); + if (!bg) + error("[TeenAgentEngine::showLogo] Cannot allocate background buffer"); + + byte *palette = (byte *)malloc(paletteSize); + if (!palette) { + free(bg); + error("[TeenAgentEngine::showLogo] Cannot allocate palette buffer"); + } + + frame->read(bg, bgSize); + frame->read(palette, paletteSize); + + for (uint c = 0; c < paletteSize; ++c) palette[c] *= 4; + _system->getPaletteManager()->setPalette(palette, 0, 0x100); + free(palette); + uint n = logo.fileCount(); for(uint f = 0; f < 4; ++f) for(uint i = 2; i <= n; ++i) { { int r = skipEvents(); - if (r != 0) + if (r != 0) { + free(bg); return r > 0? true: false; + } } _system->copyRectToScreen(bg, 320, 0, 0, 320, 200); frame.reset(logo.getStream(i)); - if (!frame) + if (!frame) { + free(bg); return true; + } Surface s; s.load(frame, Surface::kTypeOns); - if (s.empty()) + if (s.empty()) { + free(bg); return true; + } _system->copyRectToScreen((const byte *)s.pixels, s.w, s.x, s.y, s.w, s.h); _system->updateScreen(); _system->delayMillis(100); } + + free(bg); + return true; } @@ -364,29 +410,53 @@ bool TeenAgentEngine::showMetropolis() { FilePack varia; varia.open("varia.res"); - byte palette[3*256]; + const uint paletteSize = 3 * 256; + byte *palette = (byte *)malloc(paletteSize); + if (!palette) + error("[TeenAgentEngine::showMetropolis] Cannot allocate palette buffer"); + { Common::ScopedPtr s(varia.getStream(5)); - s->read(palette, sizeof(palette)); - for (uint c = 0; c < 3*256; ++c) + s->read(palette, paletteSize); + for (uint c = 0; c < paletteSize; ++c) palette[c] *= 4; } _system->getPaletteManager()->setPalette(palette, 0, 0x100); - byte varia_6[21760], varia_9[18302]; - varia.read(6, varia_6, sizeof(varia_6)); - varia.read(9, varia_9, sizeof(varia_9)); + free(palette); - byte colors[56 * 160 * 2]; - memset(colors, 0, sizeof(colors)); + const uint varia6Size = 21760; + const uint varia9Size = 18302; + byte *varia_6 = (byte *)malloc(varia6Size); + byte *varia_9 = (byte *)malloc(varia9Size); + if (!varia_6 || !varia_9) { + free(varia_6); + free(varia_9); + + error("[TeenAgentEngine::showMetropolis] Cannot allocate buffer"); + } + + varia.read(6, varia_6, varia6Size); + varia.read(9, varia_9, varia9Size); + + const uint colorsSize = 56 * 160 * 2; + byte *colors = (byte *)malloc(colorsSize); + if (!colors) + error("[TeenAgentEngine::showMetropolis] Cannot allocate colors buffer"); + + memset(colors, 0, colorsSize); int logo_y = -56; for(uint f = 0; f < 300; ++f) { { int r = skipEvents(); - if (r != 0) + if (r != 0) { + free(varia_6); + free(varia_9); + free(colors); return r > 0? true: false; + } } Graphics::Surface *surface = _system->lockScreen(); @@ -441,6 +511,11 @@ bool TeenAgentEngine::showMetropolis() { _system->updateScreen(); _system->delayMillis(100); } + + free(varia_6); + free(varia_9); + free(colors); + return true; } -- cgit v1.2.3