view buffer.c @ 184:c6ba9fe45910

Strip _c from filenames of current compiler
author Mike Pavone <pavone@retrodev.com>
date Wed, 27 Jul 2011 21:28:43 -0700
parents 76568becd6d6
children
line wrap: on
line source

#include "datum.h"
#include "vis_threading.h"
#include "structs.h"
#include <string.h>

//TODO: Make some kind of "notifier" lock that takes some kind of callback
//to be called when the lock becomes free

typedef struct
{
	int offset;
	char * buffer;
	int size;
	VIS_CRITICAL_SECTION(lock)
} fixed_buffer;
	
int vis_buffer_new(datum ** params, queue_entry * entry)
{
	int size = params[0]->c.integers.num_a;
	fixed_buffer * buf;
	release_ref(params[0]);
	params[0] = new_datum(BUILTIN_TYPE_BUFFER, 1, sizeof(fixed_buffer) + size, entry->instance->def->program);
	buf = params[0]->c.generic.data;
	buf->offset = 0;
	buf->buffer = ((char *)buf) + sizeof(fixed_buffer);
	buf->size = size;
	VIS_InitializeCriticalSection(buf->lock);
	return 0;
}

int vis_buffer_lock(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	VIS_EnterCriticalSection(buf->lock);
	return 0;
}

int vis_buffer_unlock(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	VIS_LeaveCriticalSection(buf->lock);
	return 0;
}

int vis_buffer_putbyte(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	char byte = params[1]->c.integers.num_a;
	release_ref(params[1]);
	if(buf->offset < buf->size)
	{
		buf->buffer[buf->offset++] = byte;
		params[1] = NULL;
	}
	else
	{
		params[1] = params[0];
		params[1] = NULL;
	}
	return 0;
}

int vis_buffer_writebyte(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	char byte = params[1]->c.integers.num_a;
	release_ref(params[1]);
	if(buf->offset < buf->size)
	{
		buf->buffer[buf->offset] = byte;
		params[1] = NULL;
	}
	else
	{
		params[1] = params[0];
		params[1] = NULL;
	}
	return 0;
}

int vis_buffer_putshort(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	short * wordbuf;
	short word = params[1]->c.integers.num_a;
	release_ref(params[1]);
	if(buf->offset < buf->size)
	{
		wordbuf = (short *)buf->buffer;
		wordbuf[buf->offset >> 1] = word;
		params[1] = NULL;
		buf->offset += 2;
	}
	else
	{
		params[1] = params[0];
		params[1] = NULL;
	}
	return 0;
}

int vis_buffer_writeshort(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	short * wordbuf;
	short word = params[1]->c.integers.num_a;
	release_ref(params[1]);
	if(buf->offset < buf->size)
	{
		wordbuf = (short *)buf->buffer;
		wordbuf[buf->offset >> 1] = word;
		params[1] = NULL;
	}
	else
	{
		params[1] = params[0];
		params[1] = NULL;
	}
	return 0;
}

int vis_buffer_putlong(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	long * longbuf;
	long lword = params[1]->c.integers.num_a;
	release_ref(params[1]);
	if(buf->offset < buf->size)
	{
		longbuf = (long *)buf->buffer;
		longbuf[buf->offset >> 2] = lword;
		params[1] = NULL;
		buf->offset += 4;
	}
	else
	{
		params[1] = params[0];
		params[1] = NULL;
	}
	return 0;
}

int vis_buffer_writelong(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	long * longbuf;
	long lword = params[1]->c.integers.num_a;
	release_ref(params[1]);
	if(buf->offset < buf->size)
	{
		longbuf = (long *)buf->buffer;
		longbuf[buf->offset >> 2] = lword;
		params[1] = NULL;
	}
	else
	{
		params[1] = params[0];
		params[1] = NULL;
	}
	return 0;
}

int vis_buffer_reset(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	buf->offset = 0;
	return 0;
}

#if defined(SEGA) | defined(NINTENDO_DS)
int vis_buffer_fromaddress(datum ** params, queue_entry * entry)
{
	char buffer;
	datum * out;
	int size = params[1]->c.integers.num_a;
	fixed_buffer * buf;
	release_ref(params[1]);
	out = new_datum(BUILTIN_TYPE_BUFFER, 1, sizeof(fixed_buffer), entry->instance->def->program);
	buf = out->c.generic.data;
	buf->offset = 0;
	buf->buffer = (char *)(params[0]->c.integers.num_a);
	buf->size = size;
	VIS_InitializeCriticalSection(buf->lock);
	release_ref(params[0]);
	params[0] = out;
	return 0;
}
#endif