scummvm/sword2/memory.h
Torbjörn Andersson 3d012651fd The script engine frequently needs to pass pointers to various structures
etc. to the different opcodes. Until now it has done so by casting the
pointer to an int32 (opcode parameters are represented as arrays of int32)
and then the opcode function casts it back to whatever pointer it needs.

At least in C there is no guarantee that a pointer can be represented as an
integer type (though apparently C99 may define such a type), so this has
struck me as unsafe ever since I first noticed it.

However, since all such pointers appear to point to the memory block owned
by the memory manager, we can easily convert them to integers by treating
them as offsets into the memory block. So that's what I have done. I hope I
caught all the occurences in the opcode functions, or we're going to have
some pretty interesting regressions on our hands...

svn-id: r11241
2003-11-10 07:52:15 +00:00

116 lines
2.9 KiB
C++

/* Copyright (C) 1994-2003 Revolution Software Ltd
*
* 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.
*
* $Header$
*/
#ifndef MEMORY_H
#define MEMORY_H
namespace Sword2 {
typedef struct {
uint32 state;
uint32 age; // *not used*
uint32 size;
int32 parent; // who is before us
int32 child; // who is after us
// id of a position in the _resList or some other unique id - for the
// visual display only
uint32 uid;
uint8 *ad;
} mem;
enum {
MEM_null = 0, // null
MEM_free = 1,
MEM_locked = 2,
MEM_float = 3
};
//---------------------------------------
// MEMORY BLOCKS
#define MAX_mem_blocks 999
// maintain at a good 50% higher than the
// highest recorded value from the on-screen info
//---------------------------------------
enum {
UID_memman = 0xffffffff,
UID_NULL = 0xfffffffe, // FREE
UID_font = 0xfffffffd,
UID_temp = 0xfffffffc,
UID_decompression_buffer = 0xfffffffb,
UID_shrink_buffer = 0xfffffffa,
UID_con_sprite = 0xfffffff9,
UID_text_sprite = 0xfffffff8,
UID_walk_anim = 0xfffffff7,
UID_savegame_buffer = 0xfffffff6,
UID_restoregame_buffer = 0xfffffff5
};
class MemoryManager {
private:
// Address of init malloc to be freed later
uint8 *_freeMemman;
uint32 _totalFreeMemory;
uint32 _totalBlocks;
// Start position of the defragger as indicated by its sister,
// VirtualDefrag.
int32 _suggestedStart;
mem *lowLevelAlloc(uint32 size, uint32 type, uint32 unique_id);
int32 defragMemory(uint32 req_size);
// Used to determine if the required size can be obtained if the
// defragger is allowed to run.
int32 virtualDefrag(uint32 size);
// Debugging functions
void debugMemory(void);
const char *fetchOwner(uint32 uid);
public:
// List of defined memory handles - each representing a block of memory
mem _memList[MAX_mem_blocks];
uint32 _baseMemBlock;
MemoryManager(void);
~MemoryManager(void);
int32 ptrToInt(const uint8 *p);
uint8 *intToPtr(int32 n);
mem *allocMemory(uint32 size, uint32 type, uint32 unique_id);
void freeMemory(mem *block);
void floatMemory(mem *block);
void lockMemory(mem *block);
// Debugging function
void displayMemory(void);
void memoryString(char *string);
};
extern MemoryManager *memory;
} // End of namespace Sword2
#endif