6 registered members (TipmyPip, Niels, dBc, Ed_Love, 3run, 1 invisible),
17,843
guests, and 5
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
[SOLVED] Struct pointer to skill
#456901
12/15/15 10:18
12/15/15 10:18
|
Joined: Jan 2006
Posts: 968
EpsiloN
OP
User
|
OP
User
Joined: Jan 2006
Posts: 968
|
I have a struct for weapons in my project. I'm initializing the first weapon:
WEAPONSTRUCT* glock = malloc(sizeof(WEAPONSTRUCT));
...
weaponsList[0] = &glock;
and I'm trying to save the pointer to a skill of the player entity.
if( weaponsList[0] ) {
player.weapon = weaponsList[0];
}
Later, I'm trying to get the handle of that weapon in another function for shooting:
WEAPONSTRUCT* currentWeapon;
while(me) {
if( my.weapon ) {
currentWeapon = my.weapon;
if( currentWeapon ) {
STRING* tmpstr1 = str_create("");
str_for_num( tmpstr1 , currentWeapon.bullet_speed );
draw_text( tmpstr1 , 10 , 10 , vector(255,255,255) );
...
weaponsList[10] is a var. I tried with weaponsList being a WEAPONSTRUCT* but it didn't work also (assigning it to player.weapon as "&weaponsList[0]" Can anyone tell me why its not working? I know I'm missing something in pointer knowledge, but I cant figure this out  ***EDIT*** Got it working by going back to weaponsList being a WEAPONSTRUCT* array and assigning the weaponsList[0] directly, without the reference operator & , it is automatically referenced/dereferenced by the engine, I guess?
Last edited by EpsiloN; 12/15/15 10:24.
|
|
|
Re: [SOLVED] Struct pointer to skill
[Re: EpsiloN]
#456905
12/15/15 11:35
12/15/15 11:35
|
Joined: Apr 2015
Posts: 20 Vietnam
Florastamine
Newbie
|
Newbie
Joined: Apr 2015
Posts: 20
Vietnam
|
it is automatically referenced/dereferenced by the engine, I guess? The engine automagically does this for you, as long as you don't have PRAGMA_POINTER enabled.
|
|
|
Re: [SOLVED] Struct pointer to skill
[Re: Florastamine]
#456907
12/15/15 12:29
12/15/15 12:29
|
Joined: Jan 2006
Posts: 968
EpsiloN
OP
User
|
OP
User
Joined: Jan 2006
Posts: 968
|
I think that's the perfect word for it  But, this does not work:
if( currentWeapon != my.weapon ) {
currentWeapon = my.weapon;
currentClip = currentWeapon.magazine_size;
}
It always resolves to True... I was able to go around the problem with using another pointer to hold "old" value and assign currentWeapon every frame with a check against this "old" value to reset the magazine_size on weapon change. Otherwise it gets assigned every frame, and I have the Unlimited ammo cheat on...  Any ideas?
|
|
|
Re: [SOLVED] Struct pointer to skill
[Re: EpsiloN]
#456909
12/15/15 14:26
12/15/15 14:26
|
Joined: Mar 2012
Posts: 927 cyberspace
Wjbender
User
|
User
Joined: Mar 2012
Posts: 927
cyberspace
|
simple cast back and forth should have worked..
Compulsive compiler
|
|
|
Re: [SOLVED] Struct pointer to skill
[Re: EpsiloN]
#456924
12/15/15 20:22
12/15/15 20:22
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
I will try to give some light... I have a struct for weapons in my project. I'm initializing the first weapon:
WEAPONSTRUCT* glock = malloc(sizeof(WEAPONSTRUCT));
...
weaponsList[0] = &glock;
'malloc' allocates some static memory and returns the first bytes address that is saved into the pointer. So there are two memory areas in play in your first code line: the allocated struct and the declared pointer. Your code references the pointer to the struct, not the struct itself. So the memory address that is saved into 'weaponList[0]' is the address of the pointer! Let's play a bit around this. Imagine the data is declared static (global):
typedef struct WEAPON
{
int ammo;
} WEAPON;
WEAPON weapon;
WEAPON *weaponPtr;
When you need a pointer to a global struct you need to reference it.
weaponPtr = &weapon; // save the address of the first byte of 'weapon' global struct
Your first code line does mostly the same of this code line, but the compiler has no name to identify the memory of the static struct (dynamically allocated).
weaponPtr = malloc ( sizeof(WEAPON) );
Building a list of weapons is managed same:
WEAPON weapon;
WEAPON *weaponPtrList[2];
weaponPtrList[0] = &weapon;
weaponPtrList[1] = malloc ( sizeof(WEAPON );
Notice that you could also declare a static array of weapons: and save pointers to them in the order you want:
WEAPON *playerWeaponPtrList[10];
playerWeaponPtrList[0] = &weaponList[8];
playerWeaponPtrList[1] = &weaponList[0];
...
// or cheaper
playerWeaponPtrList[0] = weaponList + 8; // When you increase a pointer by one, the compiler encreases the address saved into the pointer by the length of the pointer type
playerWeaponPtrList[1] = weaponList; // + 0 !!Notice that the array name with no index is a pointer to the first member of the array
...
Ok, enough about pointers. Lets talk about castings and comparisions. When you save a pointer into a skill, you are casting the type of the pointer from an integer to a fixed point variable. Their interpreted value of the same bit group is different depending on the type. A var uses last 10 bits for mantissa, so an int and a var with the same interpreted value are displaced 10 bits in the real memory. The problem comes when the compiler makes things easy and let you compare a var and an int throught their interpreted values instead of the bits of each own.
int i = 1; // all the bits are 0 but the last
var v = 1; // all the bits are 0 but the 11th
if ( i == v )
printf ( "equal!" );
...
int i = 1; // all the bits are 0 but the last
var v = *((var*)(&((int)1))); // all the bits are 0 but the last
if ( i != v )
printf ( "not equal!" );
v <<= 10; // displace the only positive bit (the last) to 11th position from the tail
if ( i == v )
printf ( "equal!" );
So when you need to compare a pointer and a pointer casted to a var (skill), you will need to cast back the skill in order to avoid any interpretation (as Wjbender pointed out).
WEAPON *weaponPtr = malloc ( sizeof(WEAPON) );
my->weapon = (var)weaponPtr;
if ( (WEAPON*)my->weapon == weaponPtr )
printf ( "same weapon" );
Hope it helps Salud!
|
|
|
Re: [SOLVED] Struct pointer to skill
[Re: txesmi]
#456932
12/15/15 21:43
12/15/15 21:43
|
Joined: Jan 2006
Posts: 968
EpsiloN
OP
User
|
OP
User
Joined: Jan 2006
Posts: 968
|
Yes, it helps  After reading those C++ tutorials last week, I tried static_cast<> now in SED and faced a slap. I tried casting to var "(var)glock", but I also got an error, dunno what went wrong, but seeing your reply and remembering I've seen this used before, makes me think I did something else wrong. It said, if I remember, I cant cast a struct to a fixed point...or something...  But, I also tried _VAR(glock), after again false memory, and it didn't work also. BUT! Let me give it another try tomorrow  And, let me see if I got this right (learned it enough?):
var v = *((var*)(&((int)1))); // all the bits are 0 but the last
You are casting a var literal into an int, dereferencing the address of an int, casting the address of an int to a var address and assigning the address to that address to an actual var (into v), right? I think I got something wrong... PS.: my weaponsList is a global array of WEAPONSTRUCT*s and I'm just initializing each weapon (malloc) in a function upon start and assigning it to a member of the global array. I'm doing it this way, instead with global structs, because my intention is to achieve a system that could create dynamically weapons later (based on a web database for example). I'm aiming for a Diablo style prefix/suffix random drops... But I haven't dealt with structs much yet...  Thanks for helping, by the way.
Last edited by EpsiloN; 12/15/15 21:44.
|
|
|
Re: [SOLVED] Struct pointer to skill
[Re: EpsiloN]
#456997
12/18/15 11:32
12/18/15 11:32
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
And, let me see if I got this right (learned it enough?):
var v = *((var*)(&((int)1))); // all the bits are 0 but the last
You are casting a var literal into an int, dereferencing the address of an int, casting the address of an int to a var address and assigning the address to that address to an actual var (into v), right? I think I got something wrong... Lets go ny parts  The literal is an integer already. I added the casting in order to avoid confusions. Integer literals are treated as integers and decimal numbers as var. It will need to add '.0' to an integer to force the compiler treat it as a var. I should have written:
int i = 1;
var v = *((var*)(&i));
|
|
|
Re: [SOLVED] Struct pointer to skill
[Re: txesmi]
#457001
12/18/15 15:38
12/18/15 15:38
|
Joined: Jan 2006
Posts: 968
EpsiloN
OP
User
|
OP
User
Joined: Jan 2006
Posts: 968
|
Oh, I thought, since the engine uses its own compiler, it treated literals as var instead of int (opposed to usual C++ compilers...) I wrote a long post asking further clarification on the syntax, but I really should read more on this stuff, instead of using you as a personal teacher  Thanks for the help, I'm starting to see things differently now, with many new possibilities opening up from the language using structs, passing references and, lets not forget the almighty send_data_to function that I haven't even used yet...  Next goal - custom collision for 1000's of enemies on screen 
Last edited by EpsiloN; 12/18/15 15:39.
|
|
|
Re: [SOLVED] Struct pointer to skill
[Re: txesmi]
#457480
01/19/16 12:26
01/19/16 12:26
|
Joined: Jan 2006
Posts: 968
EpsiloN
OP
User
|
OP
User
Joined: Jan 2006
Posts: 968
|
To anyone reading this post in the future, it means nothing to read a couple online tutorials. I understand what all this means, after just finishing the section on Pointers in K&R C book (second edition). Thanks to txesmi and Wjbender and Florastamine for their help. Now go read a book!  PS.: I really loved this one: char (*(*x[3])())[5] x: array[3] of pointer to function returning pointer to array[5] of char My brain almost melted here... Probably will read the Pointers section one more time... 
|
|
|
|