If you have comments or questions concerning this source file, discuss them in the forum.
/*
Copyright (c) 2002 Nicolai Haehnle
See the license.txt for details. If that file was not included in the
source distributions, please email <prefect@rtts.org>
*/
// lib_main.cpp - misc functions
#include "library.h"
/*
==============
SwapShort
==============
*/
short SwapShort(short x)
{
short s;
((byte *)&s)[0] = ((byte *)&x)[1];
((byte *)&s)[1] = ((byte *)&x)[0];
return s;
}
/*
==============
SwapInt
==============
*/
int SwapInt(int x)
{
int s;
((byte *)&s)[0] = ((byte *)&x)[3];
((byte *)&s)[1] = ((byte *)&x)[2];
((byte *)&s)[2] = ((byte *)&x)[1];
((byte *)&s)[3] = ((byte *)&x)[0];
return s;
}
/*
==============
SwapFloat
==============
*/
float SwapFloat(float x)
{
float s;
((byte *)&s)[0] = ((byte *)&x)[3];
((byte *)&s)[1] = ((byte *)&x)[2];
((byte *)&s)[2] = ((byte *)&x)[1];
((byte *)&s)[3] = ((byte *)&x)[0];
return s;
}
/*
==============
memnchr
Search the first occurence of a character other than c
==============
*/
void *memnchr(const void *buf, int c, int bytes)
{
while(bytes--) {
if (*(byte *)buf != (byte)c)
return (void *)buf;
buf = (const char *)buf + 1;
}
return 0;
}
/*
==============================================================================
LError IMPLEMENTATION
==============================================================================
*/
/*
==============
LError::LError
Format the error message into the buffer
==============
*/
LError::LError(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
vsnprintf(m_szMessage, sizeof(m_szMessage), fmt, va);
va_end(va);
m_iSeverity = ERR_FATAL;
}
LError::LError(int iSeverity, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
vsnprintf(m_szMessage, sizeof(m_szMessage), fmt, va);
va_end(va);
m_iSeverity = iSeverity;
}
/*
==============================================================================
MISCELLANEOUS LIBRARY FUNCTIONS
==============================================================================
*/
/*
==============
xstrcpy
Buffer overflow safe strcpy
==============
*/
void xstrcpy(char *dest, int size, const char *src)
{
while(size > 1 && *src) {
*dest++ = *src++;
size--;
}
*dest = 0;
}
/*
==============
xstrcat
Buffer overflow safe strcat
==============
*/
void xstrcat(char *dest, int size, const char *src)
{
while(*dest) {
dest++;
size--;
}
if (size <= 1)
return;
while(*src) {
if (!--size)
break;
*dest++ = *src++;
}
*dest = 0;
}
/*
==============
L_Tokenize
Destructive tokenizer, splits at whitespaces including newlines.
Tokens can be surrounded by quotation marks.
==============
*/
int L_Tokenize(char **tokv, int max_tokc, char *string)
{
int tokc = 0;
while(*string) {
string += strspn(string, " \t\n");
if (!*string)
break;
if (*string != '"') {
tokv[tokc++] = string;
if (tokc >= max_tokc)
break;
string += strcspn(string, " \t\n");
} else {
tokv[tokc++] = ++string; // skip the '"'
if (tokc >= max_tokc)
break;
string += strcspn(string, "\"");
}
if (!*string)
break;
*string++ = 0;
}
return tokc;
}
/*
==============
BitMaskSect
Perform bitmask intersection.
Returns 0 if the masks don't intersect.
==============
*/
int BitMaskSect(byte *mask0, int w0, int h0, byte *mask1, int w1, int h1,
int dx, int dy)
{
int bytes0, bytes1;
int x0, y0, x1, y1, w, h;
int x, y;
byte *p0, *p1;
byte bit0, bit1;
// determine the rectangle of intersection
if (dx >= 0) {
x0 = dx;
x1 = 0;
} else {
x0 = 0;
x1 = -dx;
}
if (x0 >= w0 || x1 >= w1)
return 0;
w = w0 - x0;
if (w1 - x1 < w)
w = w1 - x1;
if (w <= 0)
return 0;
if (dy >= 0) {
y0 = dy;
y1 = 0;
} else {
y0 = 0;
y1 = -dy;
}
if (y0 >= h0 || y1 >= h1)
return 0;
h = h0 - y0;
if (h1 - y1 < h)
h = h1 - y1;
if (h <= 0)
return 0;
// now trace the masks line by line, bit by bit (should use byteops and
// shifts for performance.. oh well)
bytes0 = (w0 + 7) / 8;
bytes1 = (w1 + 7) / 8;
for(y = 0; y < h; y++) {
p0 = mask0 + (y0 + y) * bytes0;
p0 += x0 >> 3;
bit0 = 1 << (x0 & 7);
p1 = mask1 + (y1 + y) * bytes1;
p1 += x1 >> 3;
bit1 = 1 << (x1 & 7);
for(x = 0; x < w; x++) {
if ((*p0 & bit0) && (*p1 & bit1))
return 1;
bit0 <<= 1;
if (!bit0) {
p0++;
bit0 = 1;
}
bit1 <<= 1;
if (!bit1) {
p1++;
bit1 = 1;
}
}
}
return 0;
}