Custom arrays using banks

Blitz3D Forums/Blitz3D Programming/Custom arrays using banks

Jams(Posted 2005) [#1]
I'm trying to make a custom kind of array using banks, but i'm having all kinds of trouble. I have absolutely no idea why this doesn't work:

Type array
	Field BankHND%
	Field Dim1%, Dim2%, Dim3%, Dim4%, Dim5%
End Type

Function array__Create.array( nDim1%, nDim2%=0, nDim3%=0, nDim4%=0, nDim5%=0 )
					Local nArray.array = New array
					nArray \ Dim1% = nDim1
					nArray \ Dim2% = nDim2
					nArray \ Dim3% = nDim3
					nArray \ Dim4% = nDim4
					nArray \ Dim5% = nDim5
					nArray \ BankHND% = array__CreateBank( nArray )
					Return nArray
End Function

Function array__CreateBank%( tArray.array )
					Local nSize% = tArray \ Dim1
					If tArray \ Dim2 Then nSize = nSize * tArray \ Dim2
					If tArray \ Dim3 Then nSize = nSize * tArray \ Dim3
					If tArray \ Dim4 Then nSize = nSize * tArray \ Dim4
					If tArray \ Dim5 Then nSize = nSize * tArray \ Dim5
					Return CreateBank( nSize * 4 )
End Function

Function array__WriteVal%( tArray.array, nValue%, nDim1%, nDim2%=0, nDim3%=0, nDim4%=0, nDim5%=0 )
					If nDim1 > tArray \ Dim1 Then Return
					If nDim2 > tArray \ Dim2 Then Return
					If nDim3 > tArray \ Dim3 Then Return
					If nDim4 > tArray \ Dim4 Then Return
					If nDim5 > tArray \ Dim5 Then Return

					Local nOffset% = nDim1
					If nDim1% Then nOffset = nOffset * nDim1
					If nDim2% Then nOffset = nOffset * nDim2
					If nDim3% Then nOffset = nOffset * nDim3
					If nDim4% Then nOffset = nOffset * nDim4
					If nDim5% Then nOffset = nOffset * nDim5

					PokeInt( tArray \ BankHND%, nOffset * 4, nValue )
End Function

Function array__ReadVal%( tArray.array, nDim1%, nDim2%=0, nDim3%=0, nDim4%=0, nDim5%=0 )
					If nDim1 > tArray \ Dim1 Then Return
					If nDim2 > tArray \ Dim2 Then Return
					If nDim3 > tArray \ Dim3 Then Return
					If nDim4 > tArray \ Dim4 Then Return
					If nDim5 > tArray \ Dim5 Then Return

					Local nOffset% = nDim1
					If nDim1% Then nOffset = nOffset * nDim1
					If nDim2% Then nOffset = nOffset * nDim2
					If nDim3% Then nOffset = nOffset * nDim3
					If nDim4% Then nOffset = nOffset * nDim4
					If nDim5% Then nOffset = nOffset * nDim5

					Return PeekInt( tArray \ BankHND%, nOffset * 4 )
End Function


;testing
Local ArraySize=4
Local nArray.array = array__Create( ArraySize, ArraySize )

For x = 1 To ArraySize
For y = 1 To ArraySize
	array__WriteVal( nArray, x, y, 10 )
Next
Next

For x = 1 To ArraySize
For y = 1 To ArraySize
	Print Str$( array__ReadVal( nArray, x, y ) )
Next
Next
WaitKey:End


Instead of getting '10' across the board, it's coming up with either 0 or some other much larger number... I think it might be a problem when calculating the offset for reading / writing... i'm not sure. Hopefully some guru out there can help me!


octothorpe(Posted 2005) [#2]
Firstly, you're calling your function with the wrong arguments. "value" is the second argument.

array__WriteVal( nArray, 10, x, y )


Secondly, your math is all wrong. Your nOffset calculation should look like this:

	Local nOffset% = nDim1-1
	If tArray\Dim2 > 0 Then nOffset = nOffset + (nDim2-1) * tArray\Dim1
	If tArray\Dim3 > 0 Then nOffset = nOffset + (nDim3-1) * tArray\Dim2
	If tArray\Dim4 > 0 Then nOffset = nOffset + (nDim4-1) * tArray\Dim3
	If tArray\Dim5 > 0 Then nOffset = nOffset + (nDim5-1) * tArray\Dim4


Lastly, you might find this simpler if you use a value of "1" to represent unused dimensions. Thinking of arrays as starting at 0 instead of 1 might make things even simpler.


octothorpe(Posted 2005) [#3]
Sorry, couldn't resist:

Type array
	Field BankHND%
	Field Dim1%, Dim2%, Dim3%, Dim4%, Dim5%
End Type

Function array__Create.array( nDim1%, nDim2%=1, nDim3%=1, nDim4%=1, nDim5%=1 )
	Local nArray.array = New array
	nArray \ Dim1% = nDim1
	nArray \ Dim2% = nDim2
	nArray \ Dim3% = nDim3
	nArray \ Dim4% = nDim4
	nArray \ Dim5% = nDim5
	nArray \ BankHND% = CreateBank( 4 * (nDim1 * nDim2 * nDim3 * nDim4 * nDim5) )
	Return nArray
End Function

Function array__GetOffset( tArray.array, nDim1%, nDim2%, nDim3%, nDim4%, nDim5% )
	If nDim1 >= tArray \ Dim1 Then RuntimeError("out of bounds!")
	If nDim2 >= tArray \ Dim2 Then RuntimeError("out of bounds!")
	If nDim3 >= tArray \ Dim3 Then RuntimeError("out of bounds!")
	If nDim4 >= tArray \ Dim4 Then RuntimeError("out of bounds!")
	If nDim5 >= tArray \ Dim5 Then RuntimeError("out of bounds!")

	Local nOffset% = nDim1
	nOffset = nOffset + nDim2 * tArray\Dim1
	nOffset = nOffset + nDim3 * tArray\Dim2
	nOffset = nOffset + nDim4 * tArray\Dim3
	nOffset = nOffset + nDim5 * tArray\Dim4

	Return nOffset
End Function

Function array__WriteVal%( tArray.array, nValue%, nDim1%, nDim2%=0, nDim3%=0, nDim4%=0, nDim5%=0 )
	Local nOffset% = array__GetOffset( tArray, nDim1, nDim2, nDim3, nDim4, nDim5 )
	PokeInt( tArray \ BankHND%, nOffset * 4, nValue )
End Function

Function array__ReadVal%( tArray.array, nDim1%, nDim2%=0, nDim3%=0, nDim4%=0, nDim5%=0 )
	Local nOffset% = array__GetOffset( tArray, nDim1, nDim2, nDim3, nDim4, nDim5 )
	Return PeekInt( tArray \ BankHND%, nOffset * 4 )
End Function


;testing
Local ArraySize=4
Local nArray.array = array__Create( ArraySize, ArraySize )

For x = 0 To ArraySize-1
For y = 0 To ArraySize-1
	array__WriteVal( nArray, 10, x, y )
Next
Next

For x = 0 To ArraySize-1
For y = 0 To ArraySize-1
	Print Str$( array__ReadVal( nArray, x, y ) )
Next
Next
WaitKey:End



Jams(Posted 2005) [#4]
Thankyou very much octothorpe!! Your help is appreciated!!


octothorpe(Posted 2005) [#5]
No problem. Glad I could help! :)