1 registered members (AndrewAMD),
1,248
guests, and 6
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
dynamic array handling helpers
#456671
12/03/15 09:21
12/03/15 09:21
|
Joined: Mar 2011
Posts: 3,150 Budapest
sivan
OP
Expert
|
OP
Expert
Joined: Mar 2011
Posts: 3,150
Budapest
|
Hi folks, I nearly forgot to share this little dynamic array helper script I made for myself, and an additional demo showing how to use it. You can find comments at nearly all of the demo lines, and the MBarray.h contains detailed descriptions and examples for each function. Nothing complex, it just helps a bit the basic array operations, with a few safety checks. Everything is tested, but not stupid safe, so normally cannot harm your computer. - create an array - create an array and fill with default value - resize array (both increase and decrease) - add new element - free an existing array - pseudo 2d array rotation (1d with 2d conversions) - pseudo 3d array rotation (1d with 3d conversions) Just create 3 script files with the given names to get the demo (Arraytest.c) work. If you have any idea what to add, please tell me. Arraytest.c
/////////////////////////////////////
// includes
// engine
#include <acknex.h> // A8 game engine
//#include <default.c> // do not include in this demo, key_esc is used in main loop, and default.c would override it
//#include <windows.h> // to access GetTickCount for precision timer
//#include <strio.c> // Win API I/O functions - needed by file handling functions used in wmb compilation
// array helper scripts
#include "MBarray.h"
#include "MBarray.c"
/////////////////////////////////////
// defines
/////////////////////////////////////
// variables
char* char_array = NULL;
int char_array_length = 0;
short* short_array = NULL;
int short_array_length = 0;
int* int_array = NULL;
int int_array_length = 0;
var* var_array = NULL;
int var_array_length = 0;
VECTOR* vec_array = NULL;
int vec_array_length = 0;
typedef struct TEST_STRUCT
{
var variable_var;
int variable_int;
VECTOR variable_vec;
} TEST_STRUCT;
TEST_STRUCT* struct_array = NULL;
int struct_array_length = 0;
/////////////////////////////////////
// functions
void main();
// show array content - function overloading does not work in lite-c, similarly to C
void ShowArrayElements_char(char* inarray, int arraylength, var posx, var posy);
void ShowArrayElements_short(short* inarray, int arraylength, var posx, var posy);
void ShowArrayElements_int(int* inarray, int arraylength, var posx, var posy);
void ShowArrayElements_var(var* inarray, int arraylength, var posx, var posy);
void ShowArrayElements_vec(VECTOR* inarray, int arraylength, var posx, var posy);
void ShowArrayElements_struct(TEST_STRUCT* inarray, int arraylength, var posx, var posy);
/////////////////////////////////////
// code
void main()
{
//------------------------------------------------------------------------
// default array length
int newlength = 10;
//------------------------------------------------------------------------
// initialize arrays
//------------------------------------
// char array
char_array = array_new(sizeof(char), &char_array_length, newlength); // default value 0
char_array[0] = 100; // 8th element is set to 100
array_fill_char(&char_array[8], 2, 10); // 9-10 elements are set to 10
array_fillbytes(&char_array[2], sizeof(char), 3, 1); // 3-5 elements are set to 1, by using void* as fnction parameter, and defining element size
//------------------------------------
// short array
short_array = array_new(sizeof(short), &short_array_length, newlength, 255); // default value 65535
short_array[0] = 10000; // 10th element is set to 10000
array_fill_short(&short_array[8], 2, 10); // 9-10 elements are set to 10
array_fillbytes(&short_array[2], sizeof(short), 3, 1); // all bytes of 3-5 elements are set to 1 = 257, by using void* as fnction parameter, and defining element size
short temp_short = 5000; // temp value to be used for array elements
short_array = array_add(short_array, sizeof(short), &short_array_length, 2, &temp_short); // add new elements
//------------------------------------
// int array
int_array = array_new(sizeof(int), &int_array_length, newlength); // default value 0
array_fill_int(int_array, int_array_length, 111); // all elements are set to 111 - not per byte setting, thus any value works within integer range
int_array[7] = 100000; // 8th element is set to 100000
array_fill_int(&int_array[2], 3, 100); // 3-5 elements are set to 100 - not per byte setting, thus any value works within integer range
//------------------------------------
// var array
var_array = array_new(sizeof(var), &var_array_length, newlength); // default value 0
array_fill_var(var_array, var_array_length, 123.456); // all elements are set to 100 - not per byte setting, thus any value works within integer range
var_array = array_resize(var_array, sizeof(var), &var_array_length, var_array_length-2); // decrease size by popping last 2 elements
var temp_var = 100.001;
array_fill(&var_array[2], sizeof(var), 2, &temp_var); // 3-4 element set to temp_var, by using void* as fnction parameter, and defining element size
//------------------------------------
// VECTOR array
vec_array = array_new(sizeof(VECTOR), &vec_array_length, newlength); // default value 0,0,0
VECTOR temp_vec; // temp VECTOR to be used for array elements
temp_vec.x = 1.1;
temp_vec.y = 2.2;
temp_vec.z = 3.3;
array_fill_vec(vec_array, vec_array_length, &temp_vec); // set all elements to new element value, by using a loop, thus slower than fillbytes
array_fillbytes(&vec_array[2], sizeof(VECTOR), 3, 0); // set all bytes of any type or struct
// in case of int, var, or VECTOR, only zero is opractical to be used with fillbytes
array_fill(&vec_array[7], sizeof(VECTOR), 2, vector(1, 2, 3)); // 8-9 element is set to 1,2,3, by using void* as fnction parameter, and defining element size
temp_vec.x = 4;
temp_vec.y = 5;
temp_vec.z = 6;
vec_array = array_add(vec_array, sizeof(VECTOR), &vec_array_length, 2, &temp_vec); // add new elements
//------------------------------------
// struct array
struct_array = array_new(sizeof(TEST_STRUCT), &struct_array_length, 5);
struct_array[3].variable_var = 123.456; // set 4th struct array element parameters directly
struct_array[3].variable_int = 100000;
vec_set(struct_array[3].variable_vec, vector(1.1,2.2,3.3));
TEST_STRUCT temp_struct; // temp struct to be used for array elements
temp_struct.variable_var = 111.111;
temp_struct.variable_int = 111111;
vec_set(temp_struct.variable_vec, vector(1.111,2.222,3.333));
struct_array = array_add(struct_array, sizeof(TEST_STRUCT), &struct_array_length, 5, &temp_struct); // add new elements
//------------------------------------------------------------------------
// display results
while(1)
{
draw_text("char*", 50, 25, COLOR_WHITE);
draw_text("short*", 150, 25, COLOR_BLUE);
draw_text("int*", 250, 25, COLOR_RED);
draw_text("var*", 350, 25, COLOR_GREEN);
draw_text("VECTOR*", 450, 25, vector(255, 255, 0));
draw_text("struct*", 50, 300, vector(0, 255, 255));
draw_text("var", 50, 325, vector(0, 255, 255));
draw_text("int", 150, 325, vector(0, 255, 255));
draw_text("VECTOR", 250, 325, vector(0, 255, 255));
ShowArrayElements_char(char_array, char_array_length, 50, 50);
ShowArrayElements_short(short_array, short_array_length, 150, 50);
ShowArrayElements_int(int_array, int_array_length, 250, 50);
ShowArrayElements_var(var_array, var_array_length, 350, 50);
ShowArrayElements_vec(vec_array, vec_array_length, 450, 50);
ShowArrayElements_struct(struct_array, struct_array_length, 50, 350);
if (key_esc) break;
wait(1);
}
//------------------------------------------------------------------------
// free memory
array_destroy( char_array );
array_destroy( short_array );
array_destroy( int_array );
array_destroy( var_array );
array_destroy( vec_array );
array_destroy( struct_array );
//------------------------------------------------------------------------
// wait(-3);
sys_exit(NULL);
}
/////////////////////////////////////
// show array content
void ShowArrayElements_char(char* inarray, int arraylength, var posx, var posy)
{
if (!inarray) return;
int i;
for (i=0; i<arraylength; ++i)
{
draw_text( str_for_int(NULL, (int)inarray[i]), posx, posy + i*20, COLOR_WHITE );
}
}
void ShowArrayElements_short(short* inarray, int arraylength, var posx, var posy)
{
if (!inarray) return;
int i;
for (i=0; i<arraylength; ++i)
{
draw_text( str_for_int(NULL, (int)inarray[i]), posx, posy + i*20, COLOR_BLUE );
}
}
void ShowArrayElements_int(int* inarray, int arraylength, var posx, var posy)
{
if (!inarray) return;
int i;
for (i=0; i<arraylength; ++i)
{
draw_text( str_for_int(NULL, inarray[i]), posx, posy + i*20, COLOR_RED );
}
}
void ShowArrayElements_var(var* inarray, int arraylength, var posx, var posy)
{
if (!inarray) return;
int i;
for (i=0; i<arraylength; ++i)
{
draw_text( str_for_num(NULL, inarray[i]), posx, posy + i*20, COLOR_GREEN );
}
}
void ShowArrayElements_vec(VECTOR* inarray, int arraylength, var posx, var posy)
{
if (!inarray) return;
int i;
for (i=0; i<arraylength; ++i)
{
draw_text( str_for_num(NULL, inarray[i].x), posx, posy + i*20, vector(255, 255, 0) );
draw_text( str_for_num(NULL, inarray[i].y), posx + 50, posy + i*20, vector(255, 255, 0) );
draw_text( str_for_num(NULL, inarray[i].z), posx + 100, posy + i*20, vector(255, 255, 0) );
}
}
void ShowArrayElements_struct(TEST_STRUCT* inarray, int arraylength, var posx, var posy)
{
if (!inarray) return;
int i;
for (i=0; i<arraylength; ++i)
{
draw_text( str_for_num(NULL, inarray[i].variable_var), posx, posy + i*20, vector(0, 255, 255) );
draw_text( str_for_num(NULL, inarray[i].variable_int), posx + 100, posy + i*20, vector(0, 255, 255) );
draw_text( str_for_num(NULL, inarray[i].variable_vec.x), posx + 200, posy + i*20, vector(0, 255, 255) );
draw_text( str_for_num(NULL, inarray[i].variable_vec.y), posx + 300, posy + i*20, vector(0, 255, 255) );
draw_text( str_for_num(NULL, inarray[i].variable_vec.z), posx + 400, posy + i*20, vector(0, 255, 255) );
}
}
/////////////////////////////////////
MBArray.h
#ifndef MBarray_h
#define MBarray_h
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
// macros
#define new(structtype) sys_malloc(sizeof(structtype))
#define new_array(structtype, length) sys_malloc(length * sizeof(structtype))
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
// functions
//////////////////////////////////////////////////////////////////////////////////////
/*
array operations
requirements:
- the array (initially set to NULL),
- an int variable storing array length (optional)
if structs contain inner dynamic arrays, they should be separately allocated and freed!
*/
/*
allocate memory of a new array with the given number of elements,
initializes all bytes to zero
(initially MyArray should be NULL)
(arraylength can be NULL)
returns the array, sets arraylength (optional, if not NULL)
example-1 : MYARRAYTYPE* MyArray = array_new( sizeof(MYARRAYTYPE), NULL, 10 );
example-2 : int MyArrayLength = 10;
MYARRAYTYPE* MyArray = array_new( sizeof(MYARRAYTYPE), NULL, MyArrayLength );
example-3 : int MyArrayLength = 0;
MYARRAYTYPE* MyArray = array_new( sizeof(MYARRAYTYPE), &MyArrayLength, 10 );
(now MyArrayLength is set to 10)
*/
void* array_new(int elementsize, int* arraylength, int newelementscount);
/*
same as array_new() but initializes all bytes to (char)defaultvalue (instead of zero)
returns the array, sets arraylength (optional, if not NULL)
example-1 : MyArray = array_new( sizeof(MYARRAYTYPE), NULL, 10, 255 );
example-2 : int MyArrayLength;
MYARRAYTYPE* MyArray = array_new( sizeof(MYARRAYTYPE), &MyArrayLength, 10, 255 );
*/
void* array_new(int elementsize, int* arraylength, int newelementscount, int defaultvalue);
/*
fill an array with the given value,
also can be used to fill part of an array,
by giving pointer to the starting element,
and defining a few element length as arraylength (must not exceed real arraylength)
example : array_fill( MyArray, MyArrayLength, 10 );
*/
void array_fill_char(char* arrayin, int arraylength, char elementvalue); // loop and =
void array_fill_short(short* arrayin, int arraylength, short elementvalue); // loop and =
void array_fill_int(int* arrayin, int arraylength, int elementvalue); // loop and =
void array_fill_var(var* arrayin, int arraylength, var elementvalue); // loop and =
void array_fill_vec(VECTOR* arrayin, int arraylength, VECTOR* elementvalue); // loop and memcpy
/*
same as array_fill_xxx, but okay for any type, using a locally created element,
example : short NewElement = 10;
array_fill( MyArray, sizeof(short), MyArrayLength, &NewElement );
*/
void array_fill(void* arrayin, int elementsize, int arraylength, void* elementvalue); // loop and memcpy, for any types or structs
/*
fills all bytes of the array with the given char value,
example : array_fillbytes( MyArray, sizeof(int), MyArrayLength, (char)10 );
*/
void array_fillbytes(void* arrayin, int elementsize, int arraylength, char bytevalue); // memset, for any types or structs
/*
increase or decrease array size,
reallocate memory of an existing array to the new size,
if length is increased, all bytes of new elements are set to zero
returns the array, sets arraylength (must not be NULL!)
example : MyArray = array_resize( MyArray, sizeof(MYARRAYTYPE), &MyArrayLength, 10 );
*/
void* array_resize(void* arrayin, int elementsize, int* arraylength, int newsize);
/*
increase or decrease array size,
reallocate memory of an existing array with a given number of new elements,
fill new elements with default value given by one locally created element,
or decrease array length if newelementscount is negative
returns the array, sets arraylength (must not be NULL!)
example : short newelement = 10;
MyArray = array_add( MyArray, sizeof(short), &MyArrayLength, 3, &newelement );
*/
void* array_add(void* arrayin, int elementsize, int* arraylength, int newelementscount, void* newelement);
/*
free array memory, set it to NULL for future usage,
and set the corresponding length to zero if given
example : array_destroy( MyArray, &MyArrayLength );
*/
void array_destroy(void* arrayin);
void array_destroy(void* arrayin, int* arraylength);
void array_destroy2(void** arrayin);
void array_destroy2(void** arrayin, int* arraylength);
//////////////////////////////////////////////////////////////////////////////////////
// pseudo 2D array operations
// elements are supposed to be organized similarly to coordinates, (X=0;Y=0) element is the bottom left one
// helpers
int array2d_getx(int sizex, int sizey, int abspos);
int array2d_gety(int sizex, int sizey, int abspos);
int array2d_getabs(int sizex, int sizey, int posx, int posy);
/*
reposition array elements as it would be rotated as a 2D matrix
to the given direction (angle/45), assuming currently looking towards 0
returns the new array
example : int* MyArray is the existing array to be rotated
int MyRotateArrayLength = MyArrayLength;
int MyRotateSizeX = MySizeX;
int MyRotateSizeY = MySizeY;
MYARRAYTYPE* MyRotatedArray = array2d_rotate( MyArray, sizeof(MYARRAYTYPE), &MyRotateArrayLength, 2, &MyRotateSizeX, &MyRotateSizeY );
(direction 2 means rotation by 90 degrees)
(no diagonal rotation supported i.e. 1,3,5,7)
*/
void* array2d_rotate(void* arrayin, int elementsize, int* arraylength, int direction, int* sizex, int* sizey);
//////////////////////////////////////////////////////////////////////////////////////
// pseudo 3D array operations
// the first X*Y elements corresponds to Z=0
// helpers
int array3d_getx(int sizex, int sizey, int sizez, int abspos);
int array3d_gety(int sizex, int sizey, int sizez, int abspos);
int array3d_getabs(int sizex, int sizey, int posx, int posy, int posz);
/*
same as array2d_rotate() but supports 3D arrays organized level by level
*/
void* array3d_rotate(void* arrayin, int elementsize, int* arraylength, int direction, int* sizex, int* sizey);
//////////////////////////////////////////////////////////////////////////////////////
#endif
MBArray.c
#ifndef MBarray_c
#define MBarray_c
///////////////////////////////////////////////////////////////////////////////////////////
// array helpers
void* array_new(int elementsize, int* arraylength, int newelementscount)
{
if (elementsize <= 0) return NULL;
if (newelementscount <= 0) return NULL;
int newsize = newelementscount; // cannot be smaller than 0
void* arrayout = (void*)sys_malloc(elementsize * newsize);
if (!arrayout)
{
// printf( "array_new error!" ); // error
return NULL;
}
else
{
// memset(arrayout, (char)0, elementsize * newsize); // set everything to 0, char based! - not essential, sys_malloc sets them to 0
if (arraylength)
{
*arraylength = newelementscount;
}
}
return(arrayout);
}
void* array_new(int elementsize, int* arraylength, int newelementscount, int defaultvalue)
{
if (elementsize <= 0) return NULL;
if (newelementscount <= 0) return NULL;
int newsize = newelementscount; // cannot be smaller than 0
void* arrayout = (void*)sys_malloc(elementsize * newsize);
if (!arrayout)
{
// printf( "array_new with default byte value error!" );
return NULL;
}
else
{
memset(arrayout, (char)defaultvalue, elementsize * newsize); // set everything to defaultvalue, char based!
if (arraylength)
{
*arraylength = newelementscount;
}
}
return(arrayout);
}
//////////////////////////////////////////////////////////////////////////////////////
void array_fill_char(char* arrayin, int arraylength, char elementvalue)
{
if (!arrayin) return;
if (arraylength <= 0) return;
int i;
for(i=0; i<arraylength; ++i)
{
arrayin[i] = elementvalue;
}
}
void array_fill_short(short* arrayin, int arraylength, short elementvalue)
{
if (!arrayin) return;
if (arraylength <= 0) return;
int i;
for(i=0; i<arraylength; ++i)
{
arrayin[i] = elementvalue;
}
}
void array_fill_int(int* arrayin, int arraylength, int elementvalue)
{
if (!arrayin) return;
if (arraylength <= 0) return;
int i;
for(i=0; i<arraylength; ++i)
{
arrayin[i] = elementvalue;
}
}
void array_fill_var(var* arrayin, int arraylength, var elementvalue)
{
if (!arrayin) return;
if (arraylength <= 0) return;
int i;
for(i=0; i<arraylength; ++i)
{
arrayin[i] = elementvalue;
}
}
void array_fill_vec(VECTOR* arrayin, int arraylength, VECTOR* elementvalue)
{
if (!arrayin) return;
if (arraylength <= 0) return;
if (!elementvalue) return;
int i;
for(i=0; i<arraylength; ++i)
{
memcpy( &arrayin[i] , elementvalue , sizeof(VECTOR) );
// memcpy( arrayin + i * sizeof(VECTOR) , elementvalue , sizeof(VECTOR) ); // not working...
}
}
//////////////////////////////////////////////////////////////////////////////////////
void array_fill(void* arrayin, int elementsize, int arraylength, void* elementvalue)
{
if (!arrayin) return;
if (arraylength <= 0) return;
if (!elementvalue) return;
int i;
for(i=0; i<arraylength; ++i)
{
char* j = (char*)arrayin + i * elementsize; // char* casting is required!
memcpy( j , elementvalue , elementsize );
}
}
//////////////////////////////////////////////////////////////////////////////////////
void array_fillbytes(void* arrayin, int elementsize, int arraylength, char bytevalue)
{
if (!arrayin) return;
if (arraylength <= 0) return;
memset(arrayin, bytevalue, elementsize * arraylength);
}
//////////////////////////////////////////////////////////////////////////////////////
void* array_resize(void* arrayin, int elementsize, int* arraylength, int newsize)
{
//--------------------------------------------------------------
if (!arrayin) return arrayin;
if (elementsize <= 0) return arrayin;
if (!arraylength) return arrayin;
//--------------------------------------------------------------
int oldsize = *arraylength;
//--------------------------------------------------------------
if (newsize <= 0) return arrayin;
if (newsize == oldsize) return arrayin;
//--------------------------------------------------------------
int sizetocopy = 0;
if (newsize > oldsize)
{
sizetocopy = oldsize;
}
else
{
sizetocopy = newsize;
}
//--------------------------------------------------------------
void* arrayout = (void*)sys_malloc(elementsize * newsize);
//--------------------------------------------------------------
if (!arrayout)
{
// printf( "array_resize error!" );
return arrayin;
}
else
{
memcpy( arrayout, arrayin, sizetocopy * elementsize); // copy old content
*arraylength = newsize; // set array length
}
//--------------------------------------------------------------
sys_free(arrayin);
arrayin = NULL;
return arrayout;
//--------------------------------------------------------------
}
void* array_add(void* arrayin, int elementsize, int* arraylength, int newelementscount, void* newelement)
{
//--------------------------------------------------------------
if (!arrayin) return arrayin;
if (elementsize <= 0) return arrayin;
if (!arraylength) return arrayin;
//--------------------------------------------------------------
int oldsize = *arraylength;
int newsize = *arraylength + newelementscount; // can be smaller than arraylength!
//--------------------------------------------------------------
if (newsize <= 0) return arrayin;
if (newsize == oldsize) return arrayin;
//--------------------------------------------------------------
int sizetocopy = 0;
if (newsize > oldsize)
{
sizetocopy = oldsize;
}
else
{
sizetocopy = newsize;
}
//--------------------------------------------------------------
void* arrayout = (void*)sys_malloc(elementsize * newsize);
//--------------------------------------------------------------
if (!arrayout)
{
// printf( "array_add error!" );
return arrayin;
}
else
{
memcpy( arrayout, arrayin, sizetocopy * elementsize); // copy old content
if (newelementscount > 0) // add new content if needed
{
if (newelement)
{
int i;
for(i=0; i<newelementscount; ++i)
{
char* j = (char*)arrayout + oldsize * elementsize + i * elementsize; // char* casting is required!
memcpy( j , newelement , elementsize );
}
}
// else
// {
// memset( &arrayout[oldsize], (char)0, elementsize * abs(newsize-oldsize)); // set all bytes of new elements to 0, char based! - not essential, sys_malloc sets them to 0
// }
}
*arraylength += newelementscount; // increase array length
}
//--------------------------------------------------------------
sys_free(arrayin);
arrayin = NULL;
return arrayout;
//--------------------------------------------------------------
}
//////////////////////////////////////////////////////////////////////////////////////
void array_destroy(void* arrayin)
{
if (arrayin)
{
sys_free(arrayin);
arrayin = NULL;
}
}
void array_destroy(void* arrayin, int* arraylength)
{
if (arrayin)
{
sys_free(arrayin);
arrayin = NULL;
}
if (arraylength)
{
*arraylength = 0;
}
}
void array_destroy2(void** arrayin)
{
if (*arrayin)
{
sys_free(*arrayin);
*arrayin = NULL;
}
}
void array_destroy2(void** arrayin, int* arraylength)
{
if (*arrayin)
{
sys_free(*arrayin);
*arrayin = NULL;
}
if (arraylength)
{
*arraylength = 0;
}
}
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
// 2D array helpers
int array2d_getx(int sizex, int sizey, int abspos)
{
return abspos % sizex;
}
int array2d_gety(int sizex, int sizey, int abspos)
{
return integer(abspos / sizex);
}
int array2d_getabs(int sizex, int sizey, int posx, int posy)
{
return posx + posy * sizex;
}
//////////////////////////////////////////////////////////////////////////////////////
// 2D array operations
void* array2d_rotate(void* arrayin, int elementsize, int* arraylength, int direction, int* sizex, int* sizey)
{
sys_marker("sro");
//--------------------------------
// convert to 1..7 range - for safety
while (direction < 0)
{
direction = direction + 8;
}
while (direction > 7)
{
direction = direction - 8;
}
if (direction == 0) return arrayin;
//--------------------------------
// store original values
int old_sizex = *sizex;
int old_sizey = *sizey;
int old_size = old_sizex * old_sizey;
int old_arraylength = *arraylength;
//--------------------------------
// temp array parameters
void* temp_array = NULL;
int temp_arraylength = 0; // actual array length is 0, will be set to temp_size by array_new()
int temp_sizex = old_sizex;
int temp_sizey = old_sizey;
//--------------------------------
// rotation area
// cardinal / diagonal
if (direction % 2 > 0)
{
return arrayin; // currently not supported
}
// swap x-y if rotated by 90 or 270 degree
if ((direction == 2) || (direction == 6))
{
temp_sizex = old_sizey;
temp_sizey = old_sizex;
}
int temp_size = old_arraylength;
//--------------------------------
// temp array
temp_array = array_new( elementsize, &temp_arraylength, temp_size );
//--------------------------------
if (!temp_array)
{
// printf("temp_array == NULL !!!");
return arrayin;
}
if (temp_arraylength <= 0)
{
// printf("temp_arraylength <= 0 !!!");
return arrayin;
}
//--------------------------------
// valid rotation
int i; // x
int j; // y
int k = 0; // abs
// cardinal directions : k counts in new array, i-j loops through old array positions, thus old_sizex-y needed to be used!
if (direction == 0) // 0°
{
for (j=0; j<old_sizey; ++j)
{
for (i=0; i<old_sizex; ++i)
{
int temp = array2d_getabs(old_sizex, old_sizey, i, j);
// temp_array[k] = arrayin[temp]; // wrong, void size cannot be determined
// memcpy( &temp_array[k] , &arrayin[temp] , elementsize ); // copy new values - wrong
char* newaddress = (char*)temp_array + k * elementsize; // char* casting is required!
char* oldaddress = (char*)arrayin + temp * elementsize; // char* casting is required!
memcpy( newaddress , oldaddress , elementsize );
++k;
}
}
}
else if (direction == 2) // 90°
{
for (i=0; i<old_sizex; ++i)
{
for (j=0; j<old_sizey; ++j)
{
int temp = array2d_getabs(old_sizex, old_sizey, i, old_sizey-1-j);
char* newaddress = (char*)temp_array + k * elementsize; // char* casting is required!
char* oldaddress = (char*)arrayin + temp * elementsize; // char* casting is required!
memcpy( newaddress , oldaddress , elementsize );
++k;
}
}
}
else if (direction == 4) // 180°
{
for (j=0; j<old_sizey; ++j)
{
for (i=0; i<old_sizex; ++i)
{
int temp = array2d_getabs(old_sizex, old_sizey, old_sizex-1-i, old_sizey-1-j);
char* newaddress = (char*)temp_array + k * elementsize; // char* casting is required!
char* oldaddress = (char*)arrayin + temp * elementsize; // char* casting is required!
memcpy( newaddress , oldaddress , elementsize );
++k;
}
}
}
else if (direction == 6) // 270°
{
for (i=0; i<old_sizex; ++i)
{
for (j=0; j<old_sizey; ++j)
{
int temp = array2d_getabs(old_sizex, old_sizey, old_sizex-1-i, j);
char* newaddress = (char*)temp_array + k * elementsize; // char* casting is required!
char* oldaddress = (char*)arrayin + temp * elementsize; // char* casting is required!
memcpy( newaddress , oldaddress , elementsize );
++k;
}
}
}
//--------------------------------
// set parameters if were modified
if (arraylength)
{
*arraylength = temp_arraylength;
}
*sizex = temp_sizex;
*sizey = temp_sizey;
//--------------------------------
sys_free(arrayin);
arrayin = NULL;
sys_marker(NULL);
return temp_array;
}
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
// 3D array helpers
int array3d_getx(int sizex, int sizey, int sizez, int abspos)
{
return (abspos % (sizex * sizey)) % sizex;
}
int array3d_gety(int sizex, int sizey, int sizez, int abspos)
{
return (integer((abspos % (sizex * sizey)) / sizex));
}
int array3d_getabs(int sizex, int sizey, int posx, int posy, int posz)
{
return (posx + posy * sizex) + (sizex * sizey * posz);
}
//////////////////////////////////////////////////////////////////////////////////////
// 3D array operations
void* array3d_rotate(void* arrayin, int elementsize, int* arraylength, int direction, int* sizex, int* sizey)
{
sys_marker("sro");
//--------------------------------
// convert to 1..7 range - for safety
while (direction < 0)
{
direction = direction + 8;
}
while (direction > 7)
{
direction = direction - 8;
}
// if (direction == 0) return arrayin;
//--------------------------------
// store original values
int old_sizex = *sizex;
int old_sizey = *sizey;
int old_size = old_sizex * old_sizey;
int old_arraylength = *arraylength;
int old_sizez = old_arraylength / old_size;
//--------------------------------
// temp array parameters
void* temp_array = NULL;
int temp_arraylength = 0; // actual array length is 0, will be set to temp_size by array_new()
int temp_sizex = old_sizex;
int temp_sizey = old_sizey;
//--------------------------------
// rotation area
// cardinal / diagonal
if (direction % 2 > 0)
{
return arrayin; // currently not supported
}
// swap x-y if rotated by 90 or 270 degree
if ((direction == 2) || (direction == 6))
{
temp_sizex = old_sizey;
temp_sizey = old_sizex;
}
int temp_size = old_arraylength;
//--------------------------------
// temp array
temp_array = array_new( elementsize, &temp_arraylength, temp_size );
// same as
// temp_arraylength = temp_size;
// void* temp_array = (void*)sys_malloc(elementsize * temp_size);
//--------------------------------
if (!temp_array)
{
// printf("temp_array == NULL !!!");
return arrayin;
}
if (temp_arraylength <= 0)
{
// printf("temp_arraylength <= 0 !!!");
return arrayin;
}
//--------------------------------
// valid rotation
int i; // x
int j; // y
int k = 0; // abs
int m; // z
// cardinal directions : k counts in new array, i-j loops through old array positions, thus old_sizex-y needed to be used!
if (direction == 0) // 0°
{
for (m=0; m<old_sizez; ++m)
{
for (j=0; j<old_sizey; ++j)
{
for (i=0; i<old_sizex; ++i)
{
int temp = array3d_getabs(old_sizex, old_sizey, i, j, m);
// temp_array[k] = arrayin[temp]; // wrong, void size cannot be determined
// memcpy( &temp_array[k] , &arrayin[temp] , elementsize ); // copy new values - wrong
char* newaddress = (char*)temp_array + k * elementsize; // char* casting is required!
char* oldaddress = (char*)arrayin + temp * elementsize; // char* casting is required!
memcpy( newaddress , oldaddress , elementsize );
++k;
}
}
}
}
else if (direction == 2) // 90°
{
for (m=0; m<old_sizez; ++m)
{
for (i=0; i<old_sizex; ++i)
{
for (j=0; j<old_sizey; ++j)
{
int temp = array3d_getabs(old_sizex, old_sizey, i, old_sizey-1-j, m);
char* newaddress = (char*)temp_array + k * elementsize; // char* casting is required!
char* oldaddress = (char*)arrayin + temp * elementsize; // char* casting is required!
memcpy( newaddress , oldaddress , elementsize );
++k;
}
}
}
}
else if (direction == 4) // 180°
{
for (m=0; m<old_sizez; ++m)
{
for (j=0; j<old_sizey; ++j)
{
for (i=0; i<old_sizex; ++i)
{
int temp = array3d_getabs(old_sizex, old_sizey, old_sizex-1-i, old_sizey-1-j, m);
char* newaddress = (char*)temp_array + k * elementsize; // char* casting is required!
char* oldaddress = (char*)arrayin + temp * elementsize; // char* casting is required!
memcpy( newaddress , oldaddress , elementsize );
++k;
}
}
}
}
else if (direction == 6) // 270°
{
for (m=0; m<old_sizez; ++m)
{
for (i=0; i<old_sizex; ++i)
{
for (j=0; j<old_sizey; ++j)
{
int temp = array3d_getabs(old_sizex, old_sizey, old_sizex-1-i, j, m);
char* newaddress = (char*)temp_array + k * elementsize; // char* casting is required!
char* oldaddress = (char*)arrayin + temp * elementsize; // char* casting is required!
memcpy( newaddress , oldaddress , elementsize );
++k;
}
}
}
}
//--------------------------------
// set parameters if were modified
if (arraylength)
{
*arraylength = temp_arraylength;
}
*sizex = temp_sizex;
*sizey = temp_sizey;
//--------------------------------
sys_free(arrayin);
arrayin = NULL;
sys_marker(NULL);
return temp_array;
}
//////////////////////////////////////////////////////////////////////////////////////
#endif
|
|
|
|