I see, I don't come any further this way. And just poking the right values to StrPtr/StrPtrLen-position... an idea I never dared to try. Now I will- even if my computer explodes and sets the cat on fire
Printable View
I see, I don't come any further this way. And just poking the right values to StrPtr/StrPtrLen-position... an idea I never dared to try. Now I will- even if my computer explodes and sets the cat on fire
:DQuote:
Now I will- even if my computer explodes and sets the cat on fire
Don't worry ...
tommorow- in a sober condition- forgotten the troubles of the day before - with unstoppable powers released of thinCore an avalanche will go down the hill :)
Here is a simpler varptr test.
Code:
uses "oxygen"
'OXYGENBASIC SECTION
'===================
dim as string src
dim as long pGetVarPtr
dim as long pFinish
src="
'Derived from ThinCore header
! thinBasic_VariableGetInfoEX lib "thinCore.dll" (string SearchKey, sys *pMainType,*pSubType,*pIsArray,*pDataPtr,*pnElements,WhichLevel) as sys
'---Equates for variable Main Type
%MainType_IsNumber = 20&
%MainType_String = 30&
%MainType_IsString = %MainType_String
%MainType_Variant = 50&
%MainType_IsVariant = %MainType_Variant
%MainType_UDT = 60&
%MainType_IsUDT = %MainType_UDT
'---Equates for variable Sub Type
%SubType_Byte = 1&
%SubType_Integer = 2&
%SubType_Word = 3&
%SubType_DWord = 4&
%SubType_Long = 5&
%SubType_Quad = 6&
%SubType_Single = 7&
%SubType_Double = 8&
%SubType_Currency = 9&
%SubType_Ext = 10&
%SubType_AsciiZ = 25&
function GetVarPtr(bstring varname, optional sys n) as sys, link #pGetVarPtr
============================================================================
'
sys MainType, SubType, IsArray, DataPtr, nElements, WhichLevel
thinBasic_VariableGetInfoEX Varname, MainType, SubType, IsArray, DataPtr, nElements, WhichLevel
'print " MainType " MainType +
' " SubType " SubType +
' " IsArray " IsArray +
' " DataPtr " DataPtr +
' " nElements " nElements
if n=0 then n=1
if MainType=30 and n<=nElements then
bstring array at (DataPtr) 'thinBasic uses bstrings
return strptr array[n]
end if
end function
sub finish() link #pFinish
==========================
terminate
end sub
"
o2_basic src
if o2_error then
msgbox 0,o2_error
stop
else
o2_exec
end if
declare function GetVarPtr(byval v as string, optional byval n as dword ) as dword at pGetVarPtr
declare sub Finish() at pFinish
'MAIN THINBASIC SECTION
'======================
string a(3)
a(1)="Apples"
a(2)="Bananas"
dword p=GetVarPtr("a",2) 'pointer to Bananas
if p then msgbox 0,hex$(peek(byte,p)) '42
Finish
I have another "basic" question regarding oxygen:
Is there a limit of dimensions for an array - and how many would that be? Does the element-order of 2- and 3-dimensional arrays in oxygen match the element-order in tB?
I wonder if it were possible to calculate the 1-dimensional index of some multidimensional element a lot faster if the calculation was compiled. For full powers it should probably be done in assembler - but I don't even get the stuff in o2-basic together see below - mostly because I'm missing some simple methods as peek/poke and I don't know how to read out that Dword in front of a bstring (which tells the length of the string without creating a temporary one as "Len" does).
I'm convinced such low-level-often-needed calculations like the position/index of a variable should not be done by basic itself since it might be needed a few times per codeline.
I think what I wrote here is a total mess - it does not run and I don't know why- no matter what I change- thereafter comes another Error and it's all blind trying out. I would not use a function as len here usually but I don't know any better. Script does not run anyway - it's like driving a fully loaded truck with broken mirrors backwards pushing the throttle down- no matter what comes.Code:Uses "console", "oxygen"
Long pGetIndex
Long pFinish
O2_Basic RawText
Function GetIndex( bString Element, bString Bounds) As DWord, link #pGetIndex
If Len(Element) <> Len(Bounds)
Return 0
Else
If Len(Element) < 8 Then Return 0
If Len(Bounds) < 8 Then Return 0
EndIf
DWord i, position, numElements
DWord numDims = Len(Element)/SizeOf(DWord)
Dim As DWord vElement[numDims] At StrPtr(Element)
Dim As DWord vBounds[numDims] At StrPtr(Bounds)
For i = 1 To numDims
If vElement[i] < 1 Or vElement[i] > vBounds[i] Then Return 0
If vBounds[i] < 2 Then Return 0
Next
numElements = vBounds[1]
For i = 2 To numDims
numElements = numElements * vBounds[i]
Next
For i = 1 To numDims - 1
numElements = numElements/vBounds[i]
position = position + (vElement[i]-1) * numElements
Next
Function = position + vElement[numDims]
End Function
'-------------------------
Sub Finish() link #pFinish
terminate
End Sub
End RawText
If O2_Error <> "" Then
PrintL "Can not run - Error within o2-script:" + $CRLF
PrintL O2_Error
WaitKey
Stop
Else
' can run
O2_Exec
End If
'---------------------------------------------------------------
' TB_section
Declare Function GetIndex( ByVal String, ByVal String) As DWord At pGetIndex
' test:
PrintL "search Element 3,4,5 in bounds of 4,5,6"
PrintL Str$( GetIndex MKDWD$(3,4,5), MKDWD$(4,5,6) )
WaitKey
Finish()
maybe I should add: the link posted above leads to a commented tB-version of this function - just in case you don't understand what this is supposed to do if it would work - because it's a little rare described here
The order of dimensions for thinBasic is smallest-stride-first aka "column-major". This is the same as PowerBasic but the opposite to C and FreeBasic
OxygenBasic sidesteps this issue by supporting single dimension arrays only. So the multidimensional index has to be calculated. The downside is inconvenience, but the upside is flexibility.
Creating a pointer for an indexed element is pretty easy and certainly more efficient:
Example
uses "oxygen"
type pixelrgba
r as byte
g as byte
b as byte
a as byte
end type
dim pix(640,480) as pixelrgba
dim as long pFill,pFinish
dim as string src=rawtext
type pixel byte r,g,b,a
sub fill(pixel*p,sys nx,ny,margin) link #pFill
'filling pixel block with opaque red
nx-=margin
ny-=margin
indexbase 0
sys x,y
pixel *q
for y=margin to <ny
@q=@p[y*640+margin]
for x=margin to <nx
q.a=255
q.r=250
@q+=sizeof pixel
next
next
end sub
sub finish() link #pFinish
terminate
end sub
end rawtext
o2_basic src
if len(o2_error) then
msgbox 0,o2_error
stop
else
o2_exec
end if
declare sub fillpix(pix as pixelrgba, byval x as long, byval y as long, byval margin as long) at pFill
declare sub finish() at pFinish
fillpix(pix(1,1),640,480,100)
finish
msgbox 0,pix(200,200).r '250
I don't understand the example. Is it supposed to mean Pixel is a replacement-keyword/substitute for two-dimensional arrays in oxygen? And why is it in oxygen part just fill while declared as fillpix from tB? Is it supposed to prove that name of the function can differ from oxygen and tb-version? mainly parameters and shared position matter?
And how does
work? it makes no sense to think "smaller than" since it would stop at 0 already - does it mean "For y = margin To (ny-1)" or to go the absolute value of y here = 480 steps?Code:For y=margin To <ny
My example is only an illustration.
Iteration:
for i=0 to <e
is more efficient than
for i=0 to e-1
Hi John,
I think Charles it already neatly summed up in this post. It is just that simple.
Petr