Yes, but it's inefficient to extract those values or change them.
Here are a few alternatives:
a) Two arrays. One for your 'BoxPoints' array, and one for vertex's. The BoxPoints array holds a single number that holds the ID of the first vertex from the second array. The vertex array is built using a type that holds the x and y coords you require, but also a 'NextID' entry which identified the next vertex to use. If the NextID is set to -1, then there is no next vertex.
Here's an example that you can use as a guide - it was for a war strategy game of some type - A square grid, where each entry on the grid can hold an unlimited number of units:
type Tile_t
Head as integer
` Other tile information added as needed
endtype
type Unit_t
PrevUnit as integer
NextUnit as integer
TileX as integer
TileY as integer
` Other unit information added as needed
endtype
dim Tiles(4, 4) as Tile_t
dim FreeUnits() as integer
dim Units() as Unit_t
global FreeUnitCount as integer = -1
print "***Initialising***"
InitialiseTiles()
InitialiseUnits()
print ""
print "***Creating 4 units***"
UnitA = NewUnit()
UnitB = NewUnit()
UnitC = NewUnit()
UnitD = NewUnit()
print ""
print "***Adding all units to tile (0,0)***"
AddUnitToTile(UnitA, 0, 0)
AddUnitToTile(UnitB, 0, 0)
AddUnitToTile(UnitC, 0, 0)
AddUnitToTile(UnitD, 0, 0)
print ""
print "***Clearing all units from tile (0,0)"
ClearTileList(0, 0)
print ""
ShowTileList(0, 0)
print "The free list now contains "; FreeUnitCount+1; " items"
AddUnitToTile(UnitA, 0, 0)
AddUnitToTile(UnitB, 0, 0)
AddUnitToTile(UnitC, 0, 0)
AddUnitToTile(UnitD, 0, 0)
ShowTileList(0, 0)
FreeUnit(UnitC)
ShowTileList(0, 0)
wait key
end
function ShowTileList(TileX as integer, TileY as integer)
local Unit as integer
local TileCount as integer
` Get the pointer to the first in the list
Unit = Tiles( TileX, TileY ).Head
TileCount = 0
print "Tile "; TileX; "/"; TileY; " contains ";
` Repeat while the unit number is a valid unit
while Unit >= 0
inc TileCount
print Unit; " ";
` Get the next unit number
Unit = Units( Unit ).NextUnit
endwhile
if TileCount = 0
print "***nothing***"
else
print ""
endif
endfunction
function ClearTileList(TileX as integer, TileY as integer)
local Unit as integer
Unit = Tiles( TileX, TileY ).Head
while Unit >= 0
FreeUnit( Unit )
DeleteUnit( Unit )
Unit = Tiles( TileX, TileY ).Head
endwhile
endfunction
function AddUnitToTile(Unit as integer, TileX as integer, TileY as integer)
local NextUnit as integer
` If this unit has a tile coord, it needs removing from that tile first
if Units(Unit).TileX >= 0 then FreeUnit(Unit)
print "Adding unit "; Unit; " to tile "; TileX; "/"; TileY
` Get the top of the current list
NextUnit = Tiles( TileX, TileY ).Head
` Make this unit point to the old 'top' as the next, and none as the previous
Units(Unit).NextUnit = NextUnit
Units(Unit).PrevUnit = -1
` Make the old one point back to this one
if NextUnit <> -1
Units(NextUnit).PrevUnit = Unit
endif
` Make the tile point to this unit
Tiles(TileX, TileY).Head = Unit
` Store the tile coords
Units(Unit).TileX = TileX
Units(Unit).TileY = TileY
endfunction
function FreeUnit(Unit as integer)
local PrevUnit as integer = -1
local NextUnit as integer = -1
if Units(Unit).TileX < 0 then exitfunction
print "Removing unit "; Unit; " from tile "; Units(Unit).TileX; "/"; Units(Unit).TileY
PrevUnit = Units(Unit).PrevUnit
NextUnit = Units(Unit).NextUnit
` If not the end of the list, point the next unit back at the previous one
if NextUnit >= 0
Units(NextUnit).PrevUnit = PrevUnit
endif
` If not at the top of the list, point the previous unit to the next one
if PrevUnit >= 0
Units(PrevUnit).NextUnit = NextUnit
else
` If we are at the top of the list, make the tile point to the next unit
Tiles( Units(Unit).TileX, Units(Unit).TileY ).Head = NextUnit
endif
Units(Unit).TileX = -1
Units(Unit).TileY = -1
endfunction
function InitialiseTiles()
local i as integer
for i = 0 to array count( Tiles() )
Tiles(i).Head = -1
next i
endfunction
function InitialiseUnits()
` The units array is automatically has one item ... may change in future updates
` DeleteUnit(0)
endfunction
function NewUnit()
local NewItem as integer
` If the free list has something in, use the top one and decrease the counter
if FreeUnitCount >= 0
dec FreeUnitCount
NewItem = FreeUnits( FreeUnitCount )
print "Retrieved unit "; NewItem; " from the free list"
else
` Otherwise, extend the units array and return that item
array insert at bottom Units()
NewItem = array count( Units() )
print "Created a new unit "; NewItem
endif
` Initialise the new unit
Units(NewItem).PrevUnit = -1
Units(NewItem).NextUnit = -1
Units(NewItem).TileX = -1
Units(NewItem).TileY = -1
endfunction NewItem
function DeleteUnit(Unit as integer)
print "Adding unit "; Unit; " to the free list"
` Increase the free count
inc FreeUnitCount
` If the list is too small, enlarge it
if array count( FreeUnits() ) < FreeUnitCount then array insert at bottom FreeUnits()
` Store the unit in the free list at the top
FreeUnits( FreeUnitCount ) = Unit
endfunction
b) One array and some low-level mucking around. Your BoxPoints array holds counter for the number of vertex's it holds, and a memory address.
It's probably easier to show you that one:
type BoxPoints_t
VertexData as dword
VertexCount as dword
endtype
global dim BoxPoints(0) as BoxPoints_t
SetVertex(0, 0, 10, 10)
print GetVertexX(0, 0)
print GetVertexY(0, 0)
wait key
end
function SetVertex(BP as integer, V as integer, x as float, y as float)
local Addr as dword
if V < BoxPoints(BP).VertexCount
` Vertex is within allocated memory
Addr = BoxPoints(BP).VertexData
else
` Vertex is outside allocated memory
` Allocate a larger chunk
Addr = make memory( V * 8 + 8 )
fill memory Addr, 0, V * 8 + 8
` Copy the existing data into that memory
if BoxPoints(BP).VertexData
copy memory Addr, BoxPoints(BP).VertexData, BoxPoints(BP).VertexCount * 8
delete memory BoxPoints(BP).VertexData
endif
` Update the BoxPoints array with the new memory & size
BoxPoints(BP).VertexData = Addr
BoxPoints(BP).VertexCount = V + 1
endif
` Write the 2 floats to the correct place in memory
inc Addr, V * 8
poke float Addr, x
poke float Addr + 4, y
endfunction
function GetVertex(BP as integer, V as integer, Offset as integer)
local r as float
if V < BoxPoints(BP).VertexCount
` Vertex is within allocated memory
` Calculate address in memory and pass back the value held there
Addr = BoxPoints(BP).VertexData
inc Addr, V * 8
inc Addr, Offset * 4
r = peek float( Addr )
else
` Outside allocated memory, return default value
r = 0.0
endif
endfunction r
function GetVertexX(BP as integer, V as integer)
exitfunction GetVertex(BP, V, 0)
endfunction 0.0
function GetVertexY(BP as integer, V as integer)
exitfunction GetVertex(BP, V, 1)
endfunction 0.0
Both BoxPoints and vertex's start from 0. This code also requires the use of one of my utility plug-ins (low-level memory access). You could do it with memblocks instead, but you limit yourself to 255 BoxPoints (255 for actual storage, and 1 left for copying when expanding an existing memblock).