I must be doing something wrong with PokeB

Everything else that doesn't fall into one of the other PB categories.
morduun
New User
New User
Posts: 8
Joined: Sat May 24, 2003 6:16 am
Location: NJ, USA
Contact:

I must be doing something wrong with PokeB

Post 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]
LarsG
Enthusiast
Enthusiast
Posts: 713
Joined: Mon Jun 02, 2003 1:06 pm
Location: Norway
Contact:

Post 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?!?

AMD Athlon XP2400, 512 MB RAM, Hercules 3D Prophet 9600 256MB RAM, WinXP
PIII 800MHz, 320 MB RAM, Nvidia Riva Tnt 2 Mach 64 (32MB), WinXP + Linux
17" iMac, 1.8 GHz G5, 512 MB DDR-RAM, 80 GB HD, 64 MB Geforce FX 5200, SuperDrive, OSX
morduun
New User
New User
Posts: 8
Joined: Sat May 24, 2003 6:16 am
Location: NJ, USA
Contact:

Post by morduun »

Ehrm... thanks for the reply, but that's definitely not the problem here unless I'm =really= missing something.
LarsG
Enthusiast
Enthusiast
Posts: 713
Joined: Mon Jun 02, 2003 1:06 pm
Location: Norway
Contact:

Post 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

AMD Athlon XP2400, 512 MB RAM, Hercules 3D Prophet 9600 256MB RAM, WinXP
PIII 800MHz, 320 MB RAM, Nvidia Riva Tnt 2 Mach 64 (32MB), WinXP + Linux
17" iMac, 1.8 GHz G5, 512 MB DDR-RAM, 80 GB HD, 64 MB Geforce FX 5200, SuperDrive, OSX
morduun
New User
New User
Posts: 8
Joined: Sat May 24, 2003 6:16 am
Location: NJ, USA
Contact:

Post 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?
LarsG
Enthusiast
Enthusiast
Posts: 713
Joined: Mon Jun 02, 2003 1:06 pm
Location: Norway
Contact:

Post by LarsG »

The only thing I really did was to move the allocation stuff to inside the procedure... :roll:

AMD Athlon XP2400, 512 MB RAM, Hercules 3D Prophet 9600 256MB RAM, WinXP
PIII 800MHz, 320 MB RAM, Nvidia Riva Tnt 2 Mach 64 (32MB), WinXP + Linux
17" iMac, 1.8 GHz G5, 512 MB DDR-RAM, 80 GB HD, 64 MB Geforce FX 5200, SuperDrive, OSX
morduun
New User
New User
Posts: 8
Joined: Sat May 24, 2003 6:16 am
Location: NJ, USA
Contact:

Post by morduun »

Yep, I know -- and I can't do that. The allocation has to happen outside the procedure.
LarsG
Enthusiast
Enthusiast
Posts: 713
Joined: Mon Jun 02, 2003 1:06 pm
Location: Norway
Contact:

Post by LarsG »

Try removing the "@" at the memory pointers..
They are already containing the address for the allocated memory...

AMD Athlon XP2400, 512 MB RAM, Hercules 3D Prophet 9600 256MB RAM, WinXP
PIII 800MHz, 320 MB RAM, Nvidia Riva Tnt 2 Mach 64 (32MB), WinXP + Linux
17" iMac, 1.8 GHz G5, 512 MB DDR-RAM, 80 GB HD, 64 MB Geforce FX 5200, SuperDrive, OSX
freedimension
Enthusiast
Enthusiast
Posts: 613
Joined: Tue May 06, 2003 2:50 pm
Location: Germany
Contact:

Post 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
AlGonzalez
User
User
Posts: 53
Joined: Sun Feb 15, 2004 6:04 am
Location: Easley, SC, USA

Post 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
morduun
New User
New User
Posts: 8
Joined: Sat May 24, 2003 6:16 am
Location: NJ, USA
Contact:

Post 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!
Post Reply