mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-25 13:21:36 +00:00
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:
parent
88098ab5d3
commit
c877a06196
4 changed files with 229 additions and 8 deletions
120
plugins/memory.c
Normal file
120
plugins/memory.c
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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--;
|
||||
|
|
Loading…
Reference in a new issue