The MASM Forum

General => The Campus => Topic started by: fluffywaffles on March 08, 2016, 09:45:13 AM

Title: Instantiating pointers in structs doesn't seem to work
Post by: fluffywaffles on March 08, 2016, 09:45:13 AM
So I have a Struct that looks like this for a game:


Animation STRUCT
  current_frame BYTE ?
  frame_count   BYTE ?
  frame_size      BYTE ?
  ALIGN DWORD
  frame_ptr       DWORD ?
Animation ENDS


And I initialize an Animation like so:


FighterAnimation Animation { 0, 3, SIZEOF BITMAP, OFFSET  fighter_bmp_000 }


However, FighterAnimation.frame_ptr is not defined as the address of the 0th fighter bitmap. If I try to access it, it turns out to be 0.

I can fix it by doing the following, later in the code:


mov FighterAnimation.frame_ptr, OFFSET fighter_bmp_000


Is it not possible to initialize a pointer inside of a struct without manually "mov" ing the pointer into place? This error confused me for quite some time until I tried manually mov-ing/setting the right value.
Title: Re: Instantiating pointers in structs doesn't seem to work
Post by: fearless on March 08, 2016, 11:09:44 AM
FighterAnimation        Animation {0, 3, SIZEOF BITMAP, dword ptr fighter_bmp_000} maybe?
Title: Re: Instantiating pointers in structs doesn't seem to work
Post by: rrr314159 on March 08, 2016, 11:23:16 AM
Such initialization works if fighter_bmp_000 is defined in a data statement, so that the address is assigned at compile-time, something like this:

.data
    fighter_bmp_000 db 10 dup(0)  ; of course your bmp is not 10 zero's this is just an example
.code


Not sure how you must have defined it; as a resource maybe? Anyway, apparently, its address is not assigned until run-time.

p.s. I can't see how fearless's suggestion would work. If you need further elucidation post your defn of fighter_bmp_000 (my crystal ball is at the shop for repairs :biggrin: )
Title: Re: Instantiating pointers in structs doesn't seem to work
Post by: fluffywaffles on March 08, 2016, 12:33:28 PM
fighter_bmp_000 is an instance of BITMAP, which looks like:


BITMAP STRUCT
  dwWidth DWORD ?
  dwHeight DWORD ?
  bTransparent BYTE ?
                      BYTE 3 DUP(?)
  lpBytes DWORD ?
BITMAP ENDS


Like I said, I don't have any trouble whatsoever when I manually mov the offset into my Animation instance - it's just when I try to initialize that it doesn't work. The fighter_bmp_000 bitmap is included before the FighterAnimation is defined, like so:


... ; stuff

.data

... ; more stuff

include sprites\fighter_bmp_000.asm ; defines fighter_bmp_000

FighterAnimation Animation { 0, 3, SIZEOF BITMAP, OFFSET fighter_bmp_000 }

... ; etc


If I don't later, in the .code segment, write


mov FighterAnimation.frame_ptr, OFFSET fighter_bmp_000


then it doesn't work correctly. But so long as I do manually set the frame_ptr, it works. It's weird. Maybe because I'm include-ing the bitmap the OFFSET doesn't work? That doesn't really make sense, though, seeing as it works if it is done later in the .code segment.
Title: Re: Instantiating pointers in structs doesn't seem to work
Post by: qWord on March 08, 2016, 01:00:49 PM
Maybe the pointer is overwritten at runtime?
Otherwise, reduce your code to an short example that shows the odd behavior and attach it.
Title: Re: Instantiating pointers in structs doesn't seem to work
Post by: jj2007 on March 08, 2016, 01:30:36 PM
This works fine:
include \masm32\include\masm32rt.inc

Animation STRUCT
  current_frame BYTE ?
  frame_count   BYTE ?
  frame_size      BYTE ?
  ALIGN DWORD
  frame_ptr       DWORD ?
Animation ENDS

.data
fighter_bmp_000 BITMAP {}
FighterAnimation Animation { 0, 3, SIZEOF BITMAP, fighter_bmp_000 }

.code
start:
  print hex$(FighterAnimation.frame_ptr)
  exit
end start


As qWord wrote, try to isolate the problem and post your full code here.
Title: Re: Instantiating pointers in structs doesn't seem to work
Post by: fluffywaffles on March 08, 2016, 10:07:23 PM
I discovered what my problem was.

I am nesting the FighterAnimation struct in a larger Fighter struct, that has a definition like


AnimatedCharacter STRUCT
  Position Point <>
  Velocity Point <>
  Acceleration Point <>
  Collider Rect <>
  Anim Animation <>
AnimatedCharacter ENDS


And, thinking I was being witty, I did something along the lines of


Fighter AnimatedCharacter {}
FighterPosition Position { 0, 0 }
...
FighterAnimation Animation { 0, 3, SIZEOF BITMAP, OFFSET fighter_bmp_000 }


Which, of course, assembles just fine. I thought, because of the in-order memory placement of initialized data, that when I then went to do something like


.if Fighter.Anim.frame_ptr == OFFSET fighter_bmp_000
  invoke DrawStr, OFFSET msg, 0, 0, 0c3h
.endif


I would get a nice message about how these things were equal.

MASM is apparently smarter with its Structs than that. Instead, I was allocating 2 of each struct, one outside and one inside of Fighter, and then referencing the blank ones inside of Fighter. *facepalm*

Anyway, I'm glad I figured it out, and thanks to everyone who helped!
Title: Re: Instantiating pointers in structs doesn't seem to work
Post by: jj2007 on March 08, 2016, 10:36:24 PM
Quote from: fluffywaffles on March 08, 2016, 10:07:23 PMAnyway, I'm glad I figured it out, and thanks to everyone who helped!

Our pleasure - and welcome to the forum :icon14: