Files
BlitzNext/Runtime/lib/bbbank.cpp
T
Michael Fabian 'Xaymar' Dirks 09be5488e1 runtime/lib: C++ify
2019-01-18 21:26:57 +01:00

207 lines
4.0 KiB
C++

#include "bbbank.hpp"
#include <set>
#include "bbstream.hpp"
struct bbBank {
char* data;
int size, capacity;
bbBank(int sz) : size(sz)
{
capacity = (size + 15) & ~15;
data = new char[capacity];
memset(data, 0, size);
}
virtual ~bbBank()
{
delete[] data;
}
void resize(int n)
{
if (n > size) {
if (n > capacity) {
capacity = capacity * 3 / 2;
if (n > capacity)
capacity = n;
capacity = (capacity + 15) & ~15;
char* p = new char[capacity];
memcpy(p, data, size);
delete[] data;
data = p;
} else
memset(data + size, 0, n - size);
}
size = n;
}
};
static std::set<bbBank*> bank_set;
#ifdef _DEBUG
static inline void debugBank(bbBank* b)
{
if (debug) {
if (!bank_set.count(b))
ThrowRuntimeException("bbBank does not exist");
}
}
static inline void debugBank(bbBank* b, int offset)
{
if (debug) {
debugBank(b);
if (offset >= b->size)
ThrowRuntimeException("Offset out of range");
}
}
#else
#define debugBank
#endif
bbBank* bbCreateBank(int size)
{
bbBank* b = new bbBank(size);
bank_set.insert(b);
return b;
}
void bbFreeBank(bbBank* b)
{
if (bank_set.erase(b))
delete b;
}
int bbBankSize(bbBank* b)
{
debugBank(b);
return b->size;
}
void bbResizeBank(bbBank* b, int size)
{
debugBank(b);
b->resize(size);
}
void bbCopyBank(bbBank* src, int src_p, bbBank* dest, int dest_p, int count)
{
if (debug) {
debugBank(src, src_p + count - 1);
debugBank(dest, dest_p + count - 1);
}
memmove(dest->data + dest_p, src->data + src_p, count);
}
int bbPeekByte(bbBank* b, int offset)
{
debugBank(b, offset);
return *(unsigned char*)(b->data + offset);
}
int bbPeekShort(bbBank* b, int offset)
{
debugBank(b, offset + 1);
return *(unsigned short*)(b->data + offset);
}
int bbPeekInt(bbBank* b, int offset)
{
debugBank(b, offset + 3);
return *(int*)(b->data + offset);
}
float bbPeekFloat(bbBank* b, int offset)
{
debugBank(b, offset + 3);
return *(float*)(b->data + offset);
}
void bbPokeByte(bbBank* b, int offset, int value)
{
debugBank(b, offset);
*(char*)(b->data + offset) = value;
}
void bbPokeShort(bbBank* b, int offset, int value)
{
debugBank(b, offset);
*(unsigned short*)(b->data + offset) = value;
}
void bbPokeInt(bbBank* b, int offset, int value)
{
debugBank(b, offset);
*(int*)(b->data + offset) = value;
}
void bbPokeFloat(bbBank* b, int offset, float value)
{
debugBank(b, offset);
*(float*)(b->data + offset) = value;
}
int bbReadBytes(bbBank* b, bbStream* s, int offset, int count)
{
if (debug) {
debugBank(b, offset + count - 1);
debugStream(s);
}
return s->read(b->data + offset, count);
}
int bbWriteBytes(bbBank* b, bbStream* s, int offset, int count)
{
if (debug) {
debugBank(b, offset + count - 1);
debugStream(s);
}
return s->write(b->data + offset, count);
}
int bbCallDLL(BBStr* dll, BBStr* fun, bbBank* in, bbBank* out)
{
if (debug) {
if (in)
debugBank(in);
if (out)
debugBank(out);
}
int t =
gx_runtime->callDll(*dll, *fun, in ? in->data : 0, in ? in->size : 0, out ? out->data : 0, out ? out->size : 0);
delete dll;
delete fun;
return t;
}
bool bank_create()
{
return true;
}
bool bank_destroy()
{
while (bank_set.size())
bbFreeBank(*bank_set.begin());
return true;
}
void bank_link(void (*rtSym)(const char*, void*))
{
rtSym("%CreateBank%size=0", bbCreateBank);
rtSym("FreeBank%bank", bbFreeBank);
rtSym("%BankSize%bank", bbBankSize);
rtSym("ResizeBank%bank%size", bbResizeBank);
rtSym("CopyBank%src_bank%src_offset%dest_bank%dest_offset%count", bbCopyBank);
rtSym("%PeekByte%bank%offset", bbPeekByte);
rtSym("%PeekShort%bank%offset", bbPeekShort);
rtSym("%PeekInt%bank%offset", bbPeekInt);
rtSym("#PeekFloat%bank%offset", bbPeekFloat);
rtSym("PokeByte%bank%offset%value", bbPokeByte);
rtSym("PokeShort%bank%offset%value", bbPokeShort);
rtSym("PokeInt%bank%offset%value", bbPokeInt);
rtSym("PokeFloat%bank%offset#value", bbPokeFloat);
rtSym("%ReadBytes%bank%file%offset%count", bbReadBytes);
rtSym("%WriteBytes%bank%file%offset%count", bbWriteBytes);
rtSym("%CallDLL$dll_name$func_name%in_bank=0%out_bank=0", bbCallDLL);
}