204 lines
4.0 KiB
C++
204 lines
4.0 KiB
C++
|
|
#include "bbbank.hpp"
|
|
#include "bbstream.hpp"
|
|
#include "std.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 set<bbBank*> bank_set;
|
|
|
|
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");
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|