aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorWon Star2006-06-29 05:15:45 +0000
committerWon Star2006-06-29 05:15:45 +0000
commit3a020e787617d9ae5004ffbd496b95a6d67e9ca2 (patch)
tree76b5f601adf34b73880307543481f264232570f4 /backends
parentfa4aa40b7b2bf0240b0c6e8116be4f87bdcb4cf0 (diff)
downloadscummvm-rg350-3a020e787617d9ae5004ffbd496b95a6d67e9ca2.tar.gz
scummvm-rg350-3a020e787617d9ae5004ffbd496b95a6d67e9ca2.tar.bz2
scummvm-rg350-3a020e787617d9ae5004ffbd496b95a6d67e9ca2.zip
Add custom memory management code. malloc() for small allocs became much faster and startup time in the GP32 is now 10~30 secs depend on clock speed.
svn-id: r23338
Diffstat (limited to 'backends')
-rw-r--r--backends/gp32/Makefile1
-rw-r--r--backends/gp32/gp32_main.cpp6
-rw-r--r--backends/gp32/gp32_osys.h86
-rw-r--r--backends/gp32/gp32std.cpp107
-rw-r--r--backends/gp32/gp32std.h6
-rw-r--r--backends/gp32/gp32std_memory.cpp304
-rw-r--r--backends/gp32/gp32std_memory.h35
-rw-r--r--backends/gp32/portdefs.h1
8 files changed, 391 insertions, 155 deletions
diff --git a/backends/gp32/Makefile b/backends/gp32/Makefile
index 144ce36221..d61e8cb295 100644
--- a/backends/gp32/Makefile
+++ b/backends/gp32/Makefile
@@ -126,6 +126,7 @@ OBJS += backends/gp32/gp32std.o \
backends/gp32/gp32std_file.o \
backends/gp32/gp32std_grap.o \
backends/gp32/gp32std_input.o \
+ backends/gp32/gp32std_memory.o \
backends/gp32/gp32std_sound.o \
#backends/gp32/dmaaudio_asm.o \
#backends/gp32/dmaaudio.o \
diff --git a/backends/gp32/gp32_main.cpp b/backends/gp32/gp32_main.cpp
index b05117edc1..2175141f2e 100644
--- a/backends/gp32/gp32_main.cpp
+++ b/backends/gp32/gp32_main.cpp
@@ -38,6 +38,9 @@
GlobalVars g_vars;
void init() {
+ extern void memChunkInit();
+ memChunkInit();
+
gp_setCpuSpeed(40); // Default CPU Speed
GpGraphicModeSet(16, NULL);
@@ -78,6 +81,9 @@ void GpMain(void *arg) {
// Invoke the actual ScummVM main entry point:
//int res = scummvm_main(argc, argv);
int res = scummvm_main(1, NULL);
+
+ extern void memChunkDeinit();
+ memChunkDeinit();
g_system->quit(); // TODO: Consider removing / replacing this!
//return res;
diff --git a/backends/gp32/gp32_osys.h b/backends/gp32/gp32_osys.h
index 0833577bc2..2986263424 100644
--- a/backends/gp32/gp32_osys.h
+++ b/backends/gp32/gp32_osys.h
@@ -85,62 +85,62 @@ protected:
public:
OSystem_GP32();
- virtual ~OSystem_GP32();
-
- virtual bool hasFeature(Feature f);
- virtual void setFeatureState(Feature f, bool enable);
- virtual bool getFeatureState(Feature f);
- virtual const GraphicsMode *getSupportedGraphicsModes() const;
- virtual int getDefaultGraphicsMode() const;
- virtual bool setGraphicsMode(int mode);
+ ~OSystem_GP32();
+
+ bool hasFeature(Feature f);
+ void setFeatureState(Feature f, bool enable);
+ bool getFeatureState(Feature f);
+ const GraphicsMode *getSupportedGraphicsModes() const;
+ int getDefaultGraphicsMode() const;
+ bool setGraphicsMode(int mode);
bool setGraphicsMode(const char *name);
- virtual int getGraphicsMode() const;
- virtual void initSize(uint width, uint height);
- virtual int16 getHeight();
- virtual int16 getWidth();
- virtual void setPalette(const byte *colors, uint start, uint num);
- virtual void grabPalette(byte *colors, uint start, uint num);
+ int getGraphicsMode() const;
+ void initSize(uint width, uint height);
+ int16 getHeight();
+ int16 getWidth();
+ void setPalette(const byte *colors, uint start, uint num);
+ void grabPalette(byte *colors, uint start, uint num);
- virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
- virtual void updateScreen();
- virtual void setShakePos(int shakeOffset);
+ void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
+ void updateScreen();
+ void setShakePos(int shakeOffset);
- virtual void showOverlay();
- virtual void hideOverlay();
- virtual void clearOverlay();
- virtual void grabOverlay(OverlayColor *buf, int pitch);
- virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
- virtual int16 getOverlayHeight();
- virtual int16 getOverlayWidth();
+ void showOverlay();
+ void hideOverlay();
+ void clearOverlay();
+ void grabOverlay(OverlayColor *buf, int pitch);
+ void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
+ int16 getOverlayHeight();
+ int16 getOverlayWidth();
- virtual OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b);
- virtual void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b);
+ OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b);
+ void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b);
- virtual bool showMouse(bool visible);
+ bool showMouse(bool visible);
- virtual void warpMouse(int x, int y);
- virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1);
+ void warpMouse(int x, int y);
+ void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1);
- virtual bool pollEvent(Event &event);
- virtual uint32 getMillis();
- virtual void delayMillis(uint msecs);
+ bool pollEvent(Event &event);
+ uint32 getMillis();
+ void delayMillis(uint msecs);
- virtual void setTimerCallback(TimerProc callback, int interval);
+ void setTimerCallback(TimerProc callback, int interval);
- virtual MutexRef createMutex(void);
- virtual void lockMutex(MutexRef mutex);
- virtual void unlockMutex(MutexRef mutex);
- virtual void deleteMutex(MutexRef mutex);
+ MutexRef createMutex(void);
+ void lockMutex(MutexRef mutex);
+ void unlockMutex(MutexRef mutex);
+ void deleteMutex(MutexRef mutex);
- virtual bool setSoundCallback(SoundProc proc, void *param);
- virtual void clearSoundCallback();
- virtual int getOutputSampleRate() const;
+ bool setSoundCallback(SoundProc proc, void *param);
+ void clearSoundCallback();
+ int getOutputSampleRate() const;
- virtual void quit();
+ void quit();
- virtual void setWindowCaption(const char *caption);
+ void setWindowCaption(const char *caption);
- virtual void displayMessageOnOSD(const char *msg);
+ void displayMessageOnOSD(const char *msg);
void fillMouseEvent(Event &event, int x, int y);
void handleKbdMouse();
diff --git a/backends/gp32/gp32std.cpp b/backends/gp32/gp32std.cpp
index 2e3cbea6cc..d6befb1367 100644
--- a/backends/gp32/gp32std.cpp
+++ b/backends/gp32/gp32std.cpp
@@ -33,6 +33,7 @@
#include "backends/gp32/gp32std.h"
#include "backends/gp32/gp32std_grap.h"
+#include "backends/gp32/gp32std_memory.h"
#define DEBUG_MAX 5
char debline[DEBUG_MAX][256];
@@ -65,112 +66,6 @@ void _dprintf(const char *s, ...) {
// gp_delay(100);
}
-/////////////////////
-//Memory management
-#undef memcpy
-#undef memset
-void *gp_memcpy(void *dst, const void *src, size_t count) {
- return memcpy(dst, src, count);
-}
-
-void *gp_memset(void *dst, int val, size_t count) {
- return memset(dst, val, count);
-}
-
-void *gp_malloc(size_t size) {
- uint32 np;
- uint32 *up;
-
- np = (uint32) gm_malloc(size + sizeof(uint32));
-
- if (np) {
- up = (uint32 *) np;
- *up = 0x1234;
- return (void *)(np + sizeof(uint32));
- }
-
- return NULL;
-}
-
-void *gp_calloc(size_t nitems, size_t size) {
- void *p = gp_malloc(nitems * size); //gpcalloc doesnt clear?
-
- gp_memset(p, 0, nitems * size);
-
-// if (*(uint8 *)p != 0)
-// warning("%s: calloc doesn't clear", __FUNCTION__); //fixme: was error
-
- return p;
-}
-
-void gp_free(void *block) {
- uint32 np;
- uint32 *up;
-
- if (!block) {
- return;
- }
-
- np = ((uint32) block) - sizeof(uint32);
- up = (uint32 *) np;
- if (*up == 0x4321) {
- warning("%s: double deallocation", __FUNCTION__);
- return;
- }
-
- if (*up != 0x1234) {
- warning("%s: corrupt block", __FUNCTION__);
- return;
- }
- *up = 0x4321;
-
- gm_free(up);
-}
-
-//////////////////////////////////////////////////
-// GP32 stuff
-//////////////////////////////////////////////////
-static char usedMemStr[16];
-int gUsedMem = 1024 * 1024;
-
-//#define CLEAN_MEMORY_WITH_0xE7
-#define CHECK_USED_MEMORY
-#define CHECK_NEW_TIME
-
-void *operator new(size_t size) {
-#if defined(CHECK_NEW_TIME)
- static int ftick;
- ftick = GpTickCountGet();
-#endif
-// printf("BP:operator new(%d)", size);
- void *ptr = gp_malloc(size);
-
-#if defined(CLEAN_MEMORY_WITH_0xE7)
- if(ptr != NULL) {
- gp_memset(ptr, 0xE7, size);
- }
-#endif
-#if defined(CHECK_USED_MEMORY)
- // Check free memory.
- gUsedMem = ((int)(ptr) + size) - 0xc000000;
-
- sprintf(usedMemStr, "%8d", gUsedMem);
- gp_fillRect(frameBuffer1, 0, 0, 64, 12, 0);
- gp_textOut(frameBuffer1, 0, 0, usedMemStr, 0xfffff);
-#endif
-#if defined(CHECK_NEW_TIME)
- sprintf(usedMemStr, "%2d", GpTickCountGet() - ftick);
- gp_fillRect(frameBuffer1, 72, 0, 24, 12, 0);
- gp_textOut(frameBuffer1, 72, 0, usedMemStr, 0xfffff);
-#endif
- return ptr;
-}
-
-void operator delete(void *ptr) {
-// printf("operator delete(%x)", ptr);
- gp_free(ptr);
-}
-
////////////////////
//String functions
char *gp_strcpy(char *dst, const char *src) {
diff --git a/backends/gp32/gp32std.h b/backends/gp32/gp32std.h
index 327860c489..0abe4f0b89 100644
--- a/backends/gp32/gp32std.h
+++ b/backends/gp32/gp32std.h
@@ -47,12 +47,6 @@ extern int gp_strcasecmp(const char *dst, const char *src);
extern int gp_strncasecmp(const char *dst, const char *src, size_t count);
extern void gp_sprintf(char *str, const char *fmt, ...);
-extern void * gp_memcpy(void *dst, const void *src, size_t count);
-extern void * gp_memset(void *dst, int val, size_t count);
-extern void * gp_malloc(size_t size);
-extern void * gp_calloc(size_t nitems, size_t size);
-extern void gp_free(void *block);
-
extern void gp_setCpuSpeed(int freq);
extern int gp_printf(const char *fmt, ...);
extern void gp_delay(unsigned long msecs);
diff --git a/backends/gp32/gp32std_memory.cpp b/backends/gp32/gp32std_memory.cpp
new file mode 100644
index 0000000000..0fb54a5d9a
--- /dev/null
+++ b/backends/gp32/gp32std_memory.cpp
@@ -0,0 +1,304 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ * Copyright (C) 2006 Won Star - GP32 Backend
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "stdafx.h"
+#include "common/scummsys.h"
+//#include "graphics/scaler.h"
+#include "common/system.h"
+#include "backends/intern.h"
+
+#include "base/engine.h"
+
+#include "backends/gp32/gp32std.h"
+#include "backends/gp32/gp32std_grap.h"
+#include "backends/gp32/gp32std_memory.h"
+
+/////////////////////
+//Memory management
+
+#define USER_MEMORY_SIZE (256 * 1024)
+#define USER_BLOCK_SIZE 24
+#define NUM_BLOCK (USER_MEMORY_SIZE / USER_BLOCK_SIZE)
+// use fixed block size for small allocations
+// consumes about 128k for block array
+// consumes 256k for user memory
+
+class MemBlock {
+protected:
+ static byte *userMem;
+// static size_t allocSize;
+// static MemBlock *head;
+ static int numBlock;
+ static int prevBlock;
+
+ // Linked list is slow for this task. :)
+ static MemBlock block[NUM_BLOCK];
+
+ byte *block;
+ size_t size;
+
+// MemBlock *next;
+
+ int used;
+
+public:
+ static void init();
+ static void deinit();
+
+ static void *addBlock(size_t size);
+ static void deleteBlock(void *block);
+};
+
+byte *MemBlock::userMem = NULL;
+//MemBlock *MemBlock::head = NULL;
+//size_t MemBlock::allocSize = 0;
+int MemBlock::numBlock = 0;
+int MemBlock::prevBlock = 0;
+MemBlock MemBlock::block[NUM_BLOCK];
+
+void MemBlock::init()
+{
+ userMem = (byte *)gm_malloc(USER_MEMORY_SIZE + USER_BLOCK_SIZE);
+ if (!userMem) {
+ //error
+ }
+}
+
+void MemBlock::deinit()
+{
+ if (!userMem) {
+ //error
+ }
+ gm_free(userMem);
+ userMem = NULL;
+}
+
+void *MemBlock::addBlock(size_t size)
+{
+ int i;
+
+ // some optimizaion with loop
+ for (i = prevBlock; i < NUM_BLOCK; i++) {
+ if (!block[i].used) {
+ break;
+ }
+ }
+ if(i == NUM_BLOCK) {
+ for (i = 0; i < prevBlock; i++) {
+ if (!block[i].used) {
+ break;
+ }
+ }
+ if(i == prevBlock)
+ return NULL;
+ }
+
+ byte *ptr = userMem + (i * USER_BLOCK_SIZE);
+
+ block[i].size = size;
+ block[i].block = ptr;
+ block[i].used = 1;
+
+ prevBlock = i;
+
+ return (void *) ptr;
+}
+
+void MemBlock::deleteBlock(void *block)
+{
+ uint32 np = (uint32) block - (uint32) userMem;
+
+ if ((np / USER_BLOCK_SIZE) * USER_BLOCK_SIZE != np) {
+ gm_free(block);
+// warning("wrong block! (%d / %d)", (np / USER_BLOCK_SIZE) * USER_BLOCK_SIZE, np);
+ }
+ int i = np / USER_BLOCK_SIZE;
+ if (i > NUM_BLOCK) {
+ gm_free(block);
+ return;
+ }
+ block[i].used = 0;
+
+/*
+ int i = 0;
+ for (i = 0; i < NUM_BLOCK; i++) {
+ if (block[i].block == block)
+ break;
+ }
+ if (i == NUM_BLOCK) {
+ gm_free(block); //fixme?
+ //warning("wrong block! %x", (uint32)block - (uint32)userMem);
+ } else {
+ GPDEBUG("deleteing block %d", i);
+ block[i].used = 0;
+ }*/
+}
+
+// HACK not to include struct MemBlock
+void memBlockInit()
+{
+ MemBlock::init();
+}
+
+void memBlockDeinit()
+{
+ MemBlock::deinit();
+}
+
+#undef memcpy
+#undef memset
+void *gp_memcpy(void *dst, const void *src, size_t count) {
+ return memcpy(dst, src, count);
+}
+
+void *gp_memset(void *dst, int val, size_t count) {
+ return memset(dst, val, count);
+}
+
+#define MALLOC_MASK 0xAB800000
+
+void *gp_malloc(size_t size) {
+ uint32 np;
+ uint32 *up;
+
+ // size + 8 bytes : stores block size
+ int allocSize = size + sizeof(uint32) + sizeof(uint32);
+ if (allocSize <= USER_BLOCK_SIZE) {
+ np = (uint32) MemBlock::addBlock(allocSize);
+ if (!np) {
+// GPDEBUG("falling back to gm_malloc");
+ np = (uint32) gm_malloc(allocSize);
+ }
+ } else {
+ np = (uint32) gm_malloc(allocSize);
+ }
+
+ if (np) {
+ up = (uint32 *)np;
+ *up = size | MALLOC_MASK; // mem size: up to 8mb
+ up = (uint32 *)(np + size + sizeof(uint32));
+ *up = 0x1234; // catches oob acess
+ return (void *)(np + sizeof(uint32));
+ }
+
+ return NULL;
+}
+
+void gp_free(void *block) {
+ uint32 np;
+ uint32 *up;
+
+ if (!block) {
+ return;
+ }
+
+ np = ((uint32) block) - sizeof(uint32);
+ up = (uint32 *) np;
+ if (*up == 0x43210900) {
+ warning("%s: double deallocation", __FUNCTION__);
+ return;
+ }
+
+ if (*up & MALLOC_MASK != MALLOC_MASK) {
+ warning("%s: corrupt block", __FUNCTION__);
+ return;
+ }
+
+ int blockSize = (*up & 0x7fffff);
+ up = (uint32 *)(np + blockSize + sizeof(uint32));
+ if (*up != 0x1234) {
+ warning("gp_free: corrupt block - OOB access", __FUNCTION__);
+ return;
+ }
+
+ *up = 0x43210900;
+ np = ((uint32) block) - sizeof(uint32);
+ up = (uint32 *) np;
+
+ if (blockSize + 8 <= USER_BLOCK_SIZE) {
+ MemBlock::deleteBlock(up);
+ } else {
+ gm_free(up);
+ }
+}
+
+void *gp_calloc(size_t nitems, size_t size) {
+ void *p = gp_malloc(nitems * size); //gpcalloc doesnt clear?
+
+ gp_memset(p, 0, nitems * size);
+
+// if (*(uint8 *)p != 0)
+// warning("%s: calloc doesn't clear", __FUNCTION__); //fixme: was error
+
+ return p;
+}
+
+//////////////////////////////////////////////////
+// GP32 stuff
+//////////////////////////////////////////////////
+static char usedMemStr[16];
+int gUsedMem = 1024 * 1024;
+
+//#define CLEAN_MEMORY_WITH_0xE7
+#define CHECK_USED_MEMORY
+//#define CHECK_NEW_TIME
+//#define CHECK_NEW_SIZE
+
+void *operator new(size_t size) {
+#if defined(CHECK_NEW_TIME)
+ static int ftick;
+ ftick = GpTickCountGet();
+#endif
+// printf("BP:operator new(%d)", size);
+ void *ptr = gp_malloc(size);
+
+#if defined(CLEAN_MEMORY_WITH_0xE7)
+ if(ptr != NULL) {
+ gp_memset(ptr, 0xE7, size);
+ }
+#endif
+#if defined(CHECK_USED_MEMORY)
+ // Check free memory.
+ gUsedMem = ((int)(ptr) + size) - 0xc000000;
+
+ sprintf(usedMemStr, "%8d", gUsedMem);
+ gp_fillRect(frameBuffer1, 0, 0, 64, 12, 0);
+ gp_textOut(frameBuffer1, 0, 0, usedMemStr, 0xfffff);
+#endif
+#if defined(CHECK_NEW_TIME)
+ sprintf(usedMemStr, "%2d", GpTickCountGet() - ftick);
+ gp_fillRect(frameBuffer1, 72, 0, 24, 12, 0);
+ gp_textOut(frameBuffer1, 72, 0, usedMemStr, 0xfffff);
+#endif
+#if defined(CHECK_NEW_SIZE)
+ sprintf(usedMemStr, "%8d", size);
+ gp_fillRect(frameBuffer1, 108, 0, 64, 12, 0);
+ gp_textOut(frameBuffer1, 108, 0, usedMemStr, 0xfffff);
+#endif
+ return ptr;
+}
+
+void operator delete(void *ptr) {
+// printf("operator delete(%x)", ptr);
+ gp_free(ptr);
+}
diff --git a/backends/gp32/gp32std_memory.h b/backends/gp32/gp32std_memory.h
new file mode 100644
index 0000000000..ea89b6ecb9
--- /dev/null
+++ b/backends/gp32/gp32std_memory.h
@@ -0,0 +1,35 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2006 The ScummVM project
+ * Copyright (C) 2002 Ph0x - GP32 Backend
+ * Copyright (C) 2003/2004 DJWillis - GP32 Backend
+ * Copyright (C) 2005 Won Star - GP32 Backend
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __GP32STD_MEMORY_H
+#define __GP32STD_MEMORY_H
+
+extern void * gp_memcpy(void *dst, const void *src, size_t count);
+extern void * gp_memset(void *dst, int val, size_t count);
+extern void * gp_malloc(size_t size);
+extern void * gp_calloc(size_t nitems, size_t size);
+extern void gp_free(void *block);
+
+#endif
diff --git a/backends/gp32/portdefs.h b/backends/gp32/portdefs.h
index a56658ed76..7269f105e6 100644
--- a/backends/gp32/portdefs.h
+++ b/backends/gp32/portdefs.h
@@ -36,6 +36,7 @@
#include "gp32std.h"
#include "gp32std_file.h"
+#include "gp32std_memory.h"
#undef byte