Hello...
I'm not sure if something like this has been posted before, but I couldn't find anything apart from tons of "Is it possible to make Arrays in Types??"-Threads.
Today I wrote some functions to create something like "virtual static arrays" or so, so arrays with fixed size, atm. just for integer-values. It is of course slower than the dbp-array-commands. Without debugging it is ~4 times slower (With debugging ~15 times slower, but release-versions usually shouldn't need debugging-stuff like this..), so needs e.g. 40ms instead of 10 for a million array-changes, but it's still much faster than using strings.
I'm not sure if it's faster than using another array for additional information, which was what I have done always before, but at least it should be much easier.
Before I post the functions a small description how it works:
You can create an array with "va_MakeArray(Element_Count)". The function will use free memory to store elements 0 to Element_Count as integers (so in fact (Elemnent_Count+1)*4 bytes). Also the function returns a handle which represents the array you just created. So the biggest difference from DBP-Arrays is, that they don't have a name, but an ID.
You can change an array-element by using "va_Set(ArrayID,Element,Value)". Use "va_Value(ArrayID,Element)" to get an array-value.
Arrays can be deleted with "va_DeleteArray(ArrayID)".
After an array is created it's values aren't changed, so they seem very random. To change that use va_ClearArray(ArrayID), which sets all values to 0, or va_FillArray(ArrayID,Value), which overwrites all elements with 'Value'.
Functions:
rem Are the functions to slow? If it's not already the case, write a 'rem' for the debug-lines inside va_Value and va_Set!
function va_start()
global va_ArrayCount as integer
dim va_Array(0) as va_ArrayType
rem Store
global va_Store as integer
endfunction
type va_ArrayType
exist as boolean
pos1 as dword
pos2 as dword
length as dword
lengthbytes as dword
`ByteSize as dword
endtype
function va_MakeArray(Length)
rem 0..Length -> inc
inc Length
rem Master-Array
ID = va_iNewArray()
rem Created Array
bLength = Length*4 `Integer -> 4 bytes each
va_Array(ID).pos1 = make memory(bLength)
va_Array(ID).pos2 = va_Array(ID).pos1 + bLength-1
va_Array(ID).Length = Length
va_Array(ID).LengthBytes = bLength
`va_Array(ID).ByteSize = 4
endfunction ID
function va_DeleteArray(ID)
va_Array(ID).exist = 0
endfunction
function va_ClearArray(ID)
for p = va_Array(ID).pos1 to va_Array(ID).pos2 step 4 `va_Array(ID).ByteSize
va_Store = p
*va_Store = 0
next p
endfunction
function va_FillArray(ID,v)
for p = va_Array(ID).pos1 to va_Array(ID).pos2 step 4 `va_Array(ID).ByteSize
va_Store = p
*va_Store = v
next p
endfunction
function va_Value(ID,Position)
rem ***DEBUG***
if va_Array(ID).exist = 0 then exit prompt "Array Error: Array " + str$(ID) + " does not exist!", "Array-Error" : end
if Position > va_Array(ID).Length or Position < 0 then exit prompt "Memory Error: Element " + str$(Position) + " outside Array-"+str$(ID)+" range!", "Array-Error" : end
rem End of debug
va_Store = va_Array(ID).pos1 + 4*position `va_Array(ID).ByteSize*position
v = *va_Store
endfunction v
function va_Set(ID,Position,V)
rem ***DEBUG***
if va_Array(ID).exist = 0 then exit prompt "Array Error: Array " + str$(ID) + " does not exist!", "Array-Error" : end
if Position > va_Array(ID).Length or Position < 0 then exit prompt "Memory Error: Element " + str$(Position) + " outside Array-"+str$(ID)+" range!", "Array-Error" : end
rem End of debug
va_Store = va_Array(ID).pos1 + 4*position `va_Array(ID).ByteSize*position
*va_Store = V
endfunction
function va_iNewArray()
rem Search for existing
ID = 0
for a = 1 to va_ArrayCount
if va_Array(a).exist = 0 then va_Array(a).exist = 1 : found = 1 : ID = a : exit
next a
if ID = 0
inc va_ArrayCount
array insert at bottom va_Array(0)
ID = va_ArrayCount
va_Array(ID).exist = 1
endif
endfunction ID
Small example:
va_start()
rem Make some arrays
dim Element(4)
for a = 1 to 4
print "Array ",a,":"
Element(1) = va_MakeArray(20)
print "Array created (",Element(1),")"
next a
wait key
print "Setting to 0"
for a = 1 to 4
va_FillArray(a,7)
next a
print "Setting values..."
for v = 0 to 20
print "A1(",v,") = ", va_Value(1,v)
va_Set(1,v, 100-rnd(200))
print "New A1(",v,") = ", va_Value(1,v)
next v
wait key
print
print "Repeating output"
for v = 0 to 20
print "A1(",v,") = ", va_Value(1,v)
next v
wait key
end
Comments appreciated.. have fun.
Btw.. you might use it in your project, would be kind if you mentioned my name, but you don't have to.. were just 10 minutes of work.
Edit: I didn't post an example of 'Arrays in types', but will do as soon as I've written one.
Edit2: Here's the new example. It doesn't really do anything useful but shows how the method works.
sync on
sync rate 0
va_start()
type UnitType
Life as integer
Team as byte
Object as integer
Weapons as dword `Pointer to Weapon-Array
WeaponSelected as integer
endtype
dim Unit(10) as UnitType
for u = 1 to 10
Unit(u).Life = 100
Unit(u).Team = 1 + rnd(1)
Unit(u).Object = u
a = va_MakeArray(5)
Unit(u).Weapons = a
rem Weapons
for w = 0 to 5
rem Set weapon-ID
va_Set(a,w,w+1)
next w
next u
do
cls
for u = 1 to 10
Unit(u).WeaponSelected = rnd(5)
print "Unit ", u, " Weapon-ID: ", va_Value(Unit(u).Weapons,Unit(u).WeaponSelected)
next u
sync
loop