An update.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1597 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2005-11-27 01:12:16 +00:00
parent 88098ab5d3
commit c877a06196
4 changed files with 229 additions and 8 deletions

120
plugins/memory.c Normal file
View file

@ -0,0 +1,120 @@
//a qvm compatable malloc/free interface
//This is seperate from qvm_api.c because this has a chunk of memory that simply isn't needed in all plugins.
#include "plugin.h"
struct memhead_s
{
int size;
int isfree;
struct memhead_s *next;
struct memhead_s *prev;
};
#ifndef MEMSIZE
#define MEMSIZE 1024*64 //64kb
#endif
static struct memhead_s *head;
static char memory[MEMSIZE];
//we create two dummies at the start and end
//these will never be freed
//we then have dynamic allocation in the middle.
//sizes include the headers
void *malloc(int size)
{
struct memhead_s *lasthead;
if (size <= 0)
return NULL;
size = ((size+4) & 3) + sizeof(struct memhead_s); //round up
if (!head)
{ //first call
struct memhead_s *last;
struct memhead_s *middle;
struct memhead_s *first;
first = (struct memhead_s*)memory;
last= (struct memhead_s*)((char*)memory - sizeof(struct memhead_s));
first->size = last->size = sizeof(struct memhead_s);
first->isfree = last->isfree = false;
middle = (struct memhead_s*)((char*)first+first->size);
middle->size = sizeof(memory) - sizeof(struct memhead_s)*3;
middle->isfree = true;
last->next = first;
last->prev = middle;
first->next = middle;
first->prev = last;
middle->next = last;
middle->prev = first;
head = middle;
}
lasthead = head;
do
{
if (head->isfree)
if (head->size >= size)
{
if (head->size > size + sizeof(struct memhead_s)+1)
{ //split
struct memhead_s *split;
split = (struct memhead_s*)((char*)head + size);
split->size = head->size - size;
head->size = size;
split->next = head->next;
split->prev = head;
head->next = split;
split->next->prev = split;
split->isfree = true;
head->isfree = false;
}
else
{ //no point in splitting
head->isfree = false;
}
return (char*)head + sizeof(struct memhead_s);
}
head = head->next;
} while (lasthead != head);
return NULL;
}
static struct memhead_s *mergeblock(struct memhead_s *b1, struct memhead_s *b2)
{
//b1 and b2 must be in logical order
b1->next = b2->next;
b2->next->prev = b1;
b1->size += b2->size;
return b1;
}
void free(void *mem)
{ //the foot hopefully isn't going to be freed
struct memhead_s *block;
block = (struct memhead_s*)((char*)mem - sizeof(struct memhead_s));
if (block->isfree)
Sys_Error("(plugin) Double free\n");
block->isfree = true;
if (block->prev->isfree)
{ //merge previous with this
block = mergeblock(block->prev, block);
}
if (block->next)
{ //merge next with this
block = mergeblock(block, block->next);
}
}

View file

@ -73,7 +73,10 @@ BUILTIN(void, Cmd_Args, (char *buffer, int bufsize)); //abort the entire engine.
BUILTIN(void, Cmd_Argv, (int argnum, char *buffer, int bufsize)); //abort the entire engine.
#undef ARGNAMES
#define ARGNAMES
BUILTIN(void, Cmd_Argc, (void)); //abort the entire engine.
BUILTINR(int, Cmd_Argc, (void)); //abort the entire engine.
#undef ARGNAMES
#define ARGNAMES ,msg
BUILTIN(void, Cmd_TokenizeString, (char *msg)); //abort the entire engine.
#undef ARGNAMES
#define ARGNAMES ,text,insert
@ -96,7 +99,7 @@ BUILTINR(float, Cvar_GetFloat, (char *name));
BUILTINR(qhandle_t, Cvar_Register, (char *name, char *defaultval, int flags, char *grouphint));
#undef ARGNAMES
#define ARGNAMES ,handle,modificationcount,stringv,floatv
BUILTINR(int, Cvar_Update, (qhandle_t handle, int modificationcount, char *stringv, float *floatv)); //stringv is 256 chars long, don't expect this function to do anything if modification count is unchanged.
BUILTINR(int, Cvar_Update, (qhandle_t handle, int *modificationcount, char *stringv, float *floatv)); //stringv is 256 chars long, don't expect this function to do anything if modification count is unchanged.
#undef ARGNAMES
#define ARGNAMES ,pnum,stats,maxstats
@ -129,6 +132,10 @@ BUILTIN(void, Draw_Colour3f, (float r, float g, float b));
BUILTIN(void, Draw_Colour4f, (float r, float g, float b, float a));
#undef ARGNAMES
#define ARGNAMES ,s
BUILTIN(void, SCR_CenterPrint, (char *s));
#undef ARGNAMES
#define ARGNAMES ,src,srcwidth,srcheight,x,y,width,height
BUILTIN(void, Media_ShowFrameRGBA_32, (void *src, int srcwidth, int srcheight, int x, int y, int width, int height));
#undef ARGNAMES
@ -167,6 +174,9 @@ BUILTIN(void, memcpy, (void *out, void *in, int len));
#define ARGNAMES ,out,in,len
BUILTIN(void, memset, (void *out, int in, int len));
#undef ARGNAMES
#define ARGNAMES ,out,in,len
BUILTIN(void, memmove, (void *out, void *in, int len));
#undef ARGNAMES
#endif
char *va(char *format, ...) //Identical in function to the one in Quake, though I can assure you that I wrote it...
@ -208,6 +218,7 @@ void Plug_InitStandardBuiltins(void)
{
#ifdef Q3_VM
CHECKBUILTIN(memcpy);
CHECKBUILTIN(memmove);
CHECKBUILTIN(memset);
#endif
@ -253,6 +264,7 @@ void Plug_InitStandardBuiltins(void)
CHECKBUILTIN(Draw_Colourp);
CHECKBUILTIN(Draw_Colour3f);
CHECKBUILTIN(Draw_Colour4f);
CHECKBUILTIN(SCR_CenterPrint);
CHECKBUILTIN(Media_ShowFrameRGBA_32);

View file

@ -17,6 +17,12 @@ typedef char *va_list;
#define va_end(va) (va = NULL)
#define NULL (void*)0
void *malloc(int size);
void free(void *mem);
char *strstr(char *str, const char *sub);
void strlcpy(char *d, const char *s, int n);
#else
#include <string.h>
@ -35,10 +41,16 @@ typedef char *va_list;
#endif
extern int (*plugin_syscall)( int arg, ... );
#ifdef _WIN32
void strlcpy(char *d, const char *s, int n);
int snprintf(char *buffer, int maxlen, char *format, ...);
#endif
#endif
typedef enum {false, true} qboolean;
typedef void *qhandle_t;
typedef float vec3_t[3];
@ -53,15 +65,16 @@ EBUILTIN(unsigned int, Sys_Milliseconds, ());
EBUILTIN(void, Cmd_AddCommand, (char *buffer)); //abort the entire engine.
EBUILTIN(void, Cmd_Args, (char *buffer, int bufsize)); //abort the entire engine.
EBUILTIN(void, Cmd_Argv, (int argnum, char *buffer, int bufsize)); //abort the entire engine.
EBUILTIN(void, Cmd_Argc, (void)); //abort the entire engine.
EBUILTIN(int, Cmd_Argc, (void)); //abort the entire engine.
EBUILTIN(void, Cmd_AddText, (char *text, qboolean insert));
EBUILTIN(void, Cmd_Tokenize, (char *msg)); //abort the entire engine.
EBUILTIN(void, Cvar_SetString, (char *name, char *value));
EBUILTIN(void, Cvar_SetFloat, (char *name, float value));
EBUILTIN(qboolean, Cvar_GetString, (char *name, char *retstring, int sizeofretstring));
EBUILTIN(float, Cvar_GetFloat, (char *name));
EBUILTIN(qhandle_t, Cvar_Register, (char *name, char *defaultval, int flags, char *grouphint));
EBUILTIN(int, Cvar_Update, (qhandle_t handle, int modificationcount, char *stringv, float *floatv)); //stringv is 256 chars long, don't expect this function to do anything if modification count is unchanged.
EBUILTIN(int, Cvar_Update, (qhandle_t handle, int *modificationcount, char *stringv, float *floatv)); //stringv is 256 chars long, don't expect this function to do anything if modification count is unchanged.
EBUILTIN(void, LocalSound, (char *soundname));
EBUILTIN(void, CL_GetStats, (int pnum, unsigned int *stats, int maxstats));
@ -79,6 +92,7 @@ EBUILTIN(void, Draw_Character, (int x, int y, unsigned int characture));
EBUILTIN(void, Draw_Colourp, (int palcol));
EBUILTIN(void, Draw_Colour3f, (float r, float g, float b));
EBUILTIN(void, Draw_Colour4f, (float r, float g, float b, float a));
EBUILTIN(void, SCR_CenterPrint, (char *s));
EBUILTIN(int, Net_TCPConnect, (char *ip, int port));
EBUILTIN(int, Net_TCPListen, (char *ip, int port, int maxcount));
@ -87,6 +101,8 @@ EBUILTIN(int, Net_Recv, (int socket, void *buffer, int len));
EBUILTIN(int, Net_Send, (int socket, void *buffer, int len));
EBUILTIN(void, Net_Close, (int socket));
#define N_WOULDBLOCK -1
#define NET_CLIENTPORT -1
#define NET_SERVERPORT -2

View file

@ -244,7 +244,7 @@ int strlen(const char *s)
return len;
}
int strncmp (char *s1, char *s2, int count)
int strncmp (const char *s1, const char *s2, int count)
{
while (1)
{
@ -261,7 +261,7 @@ int strncmp (char *s1, char *s2, int count)
return -1;
}
int strcmp(char *s1, char *s2)
int strcmp(const char *s1, const char *s2)
{
while(*s1)
{
@ -275,7 +275,7 @@ int strcmp(char *s1, char *s2)
return 0;
}
char *strstr(char *str, char *sub)
char *strstr(char *str, const char *sub)
{
char *p;
char *p2;
@ -295,9 +295,82 @@ char *strstr(char *str, char *sub)
return NULL;
}
char *strchr(char *str, char sub)
{
char *p;
char *p2;
while(*str)
{
if (*str == sub)
return str;
str++;
}
return NULL;
}
int atoi(char *str)
{
int sign;
int num;
int base = 10;
while(*(unsigned char*)str < ' ' && *str)
str++;
if (*str == '-')
{
sign = -1;
str++;
}
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
{
base = 16;
str += 2;
}
while(1)
{
if (*str >= '0' && *str <= '9')
num = num*base + (*str - '0');
else if (*str >= 'a' && *str <= 'a'+base-10)
num = num*base + (*str - 'a')+10;
else if (*str >= 'A' && *str <= 'A'+base-10)
num = num*base + (*str - 'A')+10;
else break; //bad char
}
return num*sign;
}
void strcpy(char *d, const char *s)
{
while (*s)
{
*d++ = *s++;
}
*d='\0';
}
static long randx = 1;
void srand(unsigned int x)
{
randx = x;
}
int getseed(void)
{
return randx;
}
int rand(void)
{
return(((randx = randx*1103515245 + 12345)>>16) & 077777);
}
#endif
void Q_strncpyz(char *d, const char *s, int n)
void strlcpy(char *d, const char *s, int n)
{
int i;
n--;