Page 1 of 1

I must be doing something wrong with PokeB

Posted: Tue Mar 02, 2004 9:09 pm
by morduun
I'm at wit's end -- not saying much, I know, but still, it's as far as my wit can take me. The following code works if I've commented out the PokeB line near the end (clearly marked with the rem statement), but if I put the PokeB back in the whole thing siezes terribly -- ruining inner loop counts, thrashing array values and generally mucking up the works.

I'm fairly certain I'm doing something stupidly wrong, so if one of you folks were feeling charitable and could point me in the right direction I'd be much obliged.

Lastly -- yes, it's an awkward way of calling this procedure, but that's because DLL interface I need to use (Blitz's ugly CallDLL, for those interested) specifies this interface -- so while there may be better means by which to do the interface, that's the one I'm stuck with.

Thanks in advance for having a look.

Code: Select all

; 'in' is 3 bytes of info
;   byte 0 = x dimension requirement
;   byte 1 = y dimension requirement
;   byte 2 = level being constructed
;   am considering byte 3+ to be a custom "string".
;
; out is pre-sized to meet the x and y dimensions -- fill it up at the end.
Procedure CreateMap(*in, in_size, *out, out_size)

; the in DLL gives the routine x dimension, y dimension and level being created.
  xSize.b = PeekB(*in)
  ySize.b = PeekB(*in + 1)
  level.b = PeekB(*in + 2)
  
  ; quick sanity checker to make sure we're getting what we need in the outbank
  totalSize = xSize * ySize
  If totalSize > out_size
    MessageRequester("Map Data Error", "The map bank size is insufficient for the level specified.", #PB_MessageRequester_Ok)
    End
  EndIf
  
  ; now you just do all your nifty keen custom map stuff
  ; since this is just an example, we make one massive room with no walls.
  Dim map$(xSize-1, ySize-1)

  For col = 0 To xsize - 1
    For row = 0 To ysize - 1
      map$(col, row) = ","
    Next
  Next
  
  ; now load up the out bank with the ascii code of the map you've created before
  ; you drop out of the procedure.

  ; address offset starts at 0
  address.l = 0
  
  ; cycling through each row, and then each column per row
  For row = 0 To (ySize - 1)
    For col = 0 To (xSize - 1)
    
      ; grab the ascii code of the character occupying that spot on the map
      char.b = Asc(map$(col, row))
      
      ; if we've somehow screwed up, crash out
      If address > totalsize
        MessageRequester("Map Data Error", "Whewps, bad mojo here.", #PB_MessageRequester_Ok)
        End
      EndIf
      
      ; add the character to the line to be displayed
      myLine$ = myLine$ + Chr(char)
      
      ; poke the character to the out bank
      ; THIS IS THE OFFENDING BIT
      ; unREM this line to see it crash beautifully.
      PokeB(*out + address, char)
      
      ; increment the offset by one
      address = address + 1
    Next
    myLine$ = myLine$ + chr$(13)
  Next
  
  MessageRequester("BLANKMAP", myLine$, #PB_MessageRequester_Ok)
  
EndProcedure

myInMem = AllocateMemory(1, 3)
myOutMem = AllocateMemory(2, 80*24)
PokeB(@myInMem, 80)
PokeB(@myInMem + 1, 24)
PokeB(@myInMem + 2, 2)
CreateMap(@myInMem, 3, @myOutMem, 80*24)
End
[/code]

Posted: Tue Mar 02, 2004 10:06 pm
by LarsG
Have you tried using longs for the x,y and level variables?!?
I haven't studied your code (or even ran it), but it looks like a lot of "byte'ing around".. lol
I just though that it may be some addressing that messes it up?!?

Posted: Tue Mar 02, 2004 10:19 pm
by morduun
Ehrm... thanks for the reply, but that's definitely not the problem here unless I'm =really= missing something.

Posted: Tue Mar 02, 2004 10:21 pm
by LarsG
never mind my rambling.. lol
but can you do with return the memory address value of the "bank"?

I did this (don't know if helps you, but hey.. I tried.. lol)...

Code: Select all

Global myLine$

; 'in' is 3 bytes of info 
;   byte 0 = x dimension requirement 
;   byte 1 = y dimension requirement 
;   byte 2 = level being constructed 
;   am considering byte 3+ to be a custom "string". 
; 
; out is pre-sized to meet the x and y dimensions -- fill it up at the end. 
Procedure CreateMap(*in, in_size, out_size) 

; the in DLL gives the routine x dimension, y dimension and level being created. 
  xSize.b = PeekB(*in) 
  ySize.b = PeekB(*in + 1) 
  level.b = PeekB(*in + 2) 
  
  ; quick sanity checker to make sure we're getting what we need in the outbank 
  totalSize = xSize * ySize 
  If totalSize > out_size 
    MessageRequester("Map Data Error", "The map bank size is insufficient for the level specified.", #PB_MessageRequester_Ok) 
    End 
  EndIf 
  
  ; now you just do all your nifty keen custom map stuff 
  ; since this is just an example, we make one massive room with no walls. 
  Dim map$(xSize-1, ySize-1) 

  For col = 0 To xsize - 1 
    For row = 0 To ysize - 1 
      map$(col, row) = "," 
    Next 
  Next 
  
  outmem = AllocateMemory(2,out_size)
  
  ; now load up the out bank with the ascii code of the map you've created before 
  ; you drop out of the procedure. 

  ; address offset starts at 0 
  address.b = 0 
  
  ; cycling through each row, and then each column per row 
  For row = 0 To (ySize - 1) 
    For col = 0 To (xSize - 1) 
    
      ; grab the ascii code of the character occupying that spot on the map 
      char.b = Asc(map$(col, row)) 
      
      ; if we've somehow screwed up, crash out 
      If address > totalsize 
        MessageRequester("Map Data Error", "Whewps, bad mojo here.", #PB_MessageRequester_Ok) 
        End 
      EndIf 
      
      ; add the character to the line to be displayed 
      myLine$ = myLine$ + Chr(char) 
      
      ; poke the character to the out bank 
      ; THIS IS THE OFFENDING BIT 
      ; unREM this line to see it crash beautifully. 
      PokeB(outmem + address, char) 
      
      ; increment the offset by one 
      address = address + 1
    Next 
    myLine$ = myLine$ + chr$(13) 
  Next 
  
  
  ProcedureReturn @outmem

EndProcedure 

myInMem = AllocateMemory(1, 3) 
;myOutMem = AllocateMemory(2, 80*24) 
PokeB(@myInMem, 80) 
PokeB(@myInMem + 1, 24) 
PokeB(@myInMem + 2, 2) 
memaddress = CreateMap(@myInMem, 3, 80*24)

MessageRequester("BLANKMAP", myLine$ + Chr(13)+Chr(13) + "@: " + Str(memaddress) , #PB_MessageRequester_Ok) 

End

Posted: Tue Mar 02, 2004 10:31 pm
by morduun
I can't modify the interface -- as I mentioned, this is the only way to interface with CallDLL, so the interface itself is non-negotiable.

Seriously, PokeB can't be the problem here, can it? I've double-checked the *out addresses after creation, after being passed to the procecure and just prior to modification and they're all the same physical address -- but using that PokeB in that loop causes a GPF -- not even a Pure error. Am I somehow munging the *out address, or maybe overrunning the buffer somehow?

Posted: Tue Mar 02, 2004 10:36 pm
by LarsG
The only thing I really did was to move the allocation stuff to inside the procedure... :roll:

Posted: Tue Mar 02, 2004 10:36 pm
by morduun
Yep, I know -- and I can't do that. The allocation has to happen outside the procedure.

Posted: Tue Mar 02, 2004 10:55 pm
by LarsG
Try removing the "@" at the memory pointers..
They are already containing the address for the allocated memory...

Posted: Tue Mar 02, 2004 11:09 pm
by freedimension
Yep, it seems you haven't understood the pointer stuff so far.
Dig deeper into that, I think the following code could help you with that:

Code: Select all

; 'in' is 3 bytes of info 
;   byte 0 = x dimension requirement 
;   byte 1 = y dimension requirement 
;   byte 2 = level being constructed 
;   am considering byte 3+ to be a custom "string". 
; 
; out is pre-sized to meet the x and y dimensions -- fill it up at the end. 
Procedure CreateMap(in, in_size, out, out_size) 
  
  ; the in DLL gives the routine x dimension, y dimension and level being created. 
  xSize.b = PeekB(in) 
  ySize.b = PeekB(in + 1) 
  level.b = PeekB(in + 2) 
  
  ; quick sanity checker to make sure we're getting what we need in the outbank 
  totalSize = xSize * ySize 
  If totalSize > out_size 
    MessageRequester("Map Data Error", "The map bank size is insufficient for the level specified.", #PB_MessageRequester_Ok) 
    End 
  EndIf 
  
  ; now you just do all your nifty keen custom map stuff 
  ; since this is just an example, we make one massive room with no walls. 
  Dim map$(xSize-1, ySize-1) 
  
  For col = 0 To xSize - 1 
    For row = 0 To ySize - 1 
      map$(col, row) = "," 
    Next 
  Next 
  
  ; now load up the out bank with the ascii code of the map you've created before 
  ; you drop out of the procedure. 
  
  ; address offset starts at 0 
  address.l = 0 
  
  ; cycling through each row, and then each column per row 
  For row = 0 To (ySize - 1) 
    For col = 0 To (xSize - 1) 
      
      ; grab the ascii code of the character occupying that spot on the map 
      char.b = Asc(map$(col, row)) 
      
      ; if we've somehow screwed up, crash out 
      If address > totalSize 
        MessageRequester("Map Data Error", "Whewps, bad mojo here.", #PB_MessageRequester_Ok) 
        End 
      EndIf 
      
      ; add the character to the line to be displayed 
      myLine$ = myLine$ + Chr(char) 
      
      ; poke the character to the out bank 
      ; THIS IS THE OFFENDING BIT 
      ; unREM this line to see it crash beautifully. 
      PokeB(out + address, char) 
      
      ; increment the offset by one 
      address = address + 1 
    Next 
    myLine$ = myLine$ + Chr$(13) 
  Next 
  
  MessageRequester("BLANKMAP", myLine$, #PB_MessageRequester_Ok) 
  
EndProcedure 

myInMem = AllocateMemory(1, 3) 
myOutMem = AllocateMemory(2, 80*24) 
PokeB(myInMem, 80) 
PokeB(myInMem + 1, 24) 
PokeB(myInMem + 2, 2) 
CreateMap(myInMem, 3, myOutMem, 80*24) 
End

Posted: Tue Mar 02, 2004 11:39 pm
by AlGonzalez
I believe AllocateMemory already returns a pointer to the allocated memory.
So passing myOutMem with @ is not necessary.

In other words, instead of passing the pointer to the allocated memory, I think you are passing a pointer to the memory address of the variable that holds the memory address of the allocated memory. 8O

Of course I am very new to PureBasic so take anything I say with a big grain of salt :lol:

HTH

Posted: Wed Mar 03, 2004 1:05 pm
by morduun
Ahhh now that's helped a bit. Thanks for helping to get the right syntax through my thick skull to Lars, freedimension and Al. Unfortunately I've still got problems using the routine as a DLL, but I'm not at all convinced that's Pure's fault, so it's time to do some more tedious line-by-line debugging. Thanks much for all the help though!