project-navigation
Personal tools

Author Topic: Undefined Reference  (Read 14132 times)

Offline criusmac

  • Squad Leader
  • ****
  • Posts: 168
    • View Profile
Undefined Reference
« on: September 16, 2009, 01:17:35 am »
While I am compiling the game project (Specifically g_combat.c), I am getting undefined reference errors to all the code I added in the ufo project (Specifically cl_actor.c).

From what I understand, it can't find the object code, probably due to them being in different projects.

I realize I can probably solve this by moving these functions into g_combat.c, but I would rather keep them together since they really all deal with the actor. Is there another way to solve this?

Offline Destructavator

  • Combination Multiple Specialty Developer
  • Administrator
  • PHALANX Commander
  • *****
  • Posts: 1908
  • Creater of Scorchcrafter, knows the zarakites...
    • View Profile
Re: Undefined Reference
« Reply #1 on: September 16, 2009, 04:55:22 am »
Although I'm not an advanced coder, I'd suggest that you post some of your code in your posts, in-between the code tags - assuming you are using the default forum layout, this is done with the "pound" or "number sign" - " # " in the buttons above where you post (apologies if you already happen to know this).

Either that, or including your code files in an attachment to your post would likely help, re-naming them to .txt files.

Offline Mattn

  • Administrator
  • PHALANX Commander
  • *****
  • Posts: 4831
  • https://github.com/mgerhardy/vengi
    • View Profile
    • Vengi Voxel Tools
Re: Undefined Reference
« Reply #2 on: September 16, 2009, 08:41:20 am »
you can't add code from cl_actor.c into the g_* files - the g_* files will end in a shared object file (or dylib or dll) - the cl_* files are used to link the ufo binary itself, not the game.dylib.

Show us your patch and then we can say more and help you a little out

Offline criusmac

  • Squad Leader
  • ****
  • Posts: 168
    • View Profile
Re: Undefined Reference
« Reply #3 on: September 16, 2009, 02:37:33 pm »
Thank you for the help, you have solved my problem.

The solution is I have to transfer my new functions from cl_actor.c to g_combat.c.

It is unfortunate there wasn't a different solution, and the functions I'm creating must be spread apart, but such is the way it is written. I might as well rename the functions too, I'll update my todo list when I decide on the new names.

Offline Mattn

  • Administrator
  • PHALANX Commander
  • *****
  • Posts: 4831
  • https://github.com/mgerhardy/vengi
    • View Profile
    • Vengi Voxel Tools
Re: Undefined Reference
« Reply #4 on: September 16, 2009, 03:04:35 pm »
what are you working on? patches already available?

Offline criusmac

  • Squad Leader
  • ****
  • Posts: 168
    • View Profile
Re: Undefined Reference
« Reply #5 on: September 17, 2009, 05:53:14 pm »
There are no patches available for what I'm working on.

I am working on medikits.

Offline criusmac

  • Squad Leader
  • ****
  • Posts: 168
    • View Profile
Re: Undefined Reference
« Reply #6 on: September 17, 2009, 08:39:04 pm »
After moving all my functions to g_combat.c, I now get different undefined references:


-------------- Build: windows_debug in game ---------------

Compiling: ..\..\src\game\g_combat.c
Linking dynamic library: ..\..\base\game.dll
.objs\game\src\game\g_combat.o: In function `CL_ActorDamage':C:/cprogs/UFOAI-2.3-dev/src/game/g_combat.c:205: undefined reference to `LIST_AddPointer'
.objs\game\src\game\g_combat.o: In function `CL_ActorTreat':C:/cprogs/UFOAI-2.3-dev/src/game/g_combat.c:305: undefined reference to `LIST_GetByIdx'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 2 seconds)
0 errors, 0 warnings
 
So, I've run into the problem that prevents me from adding this code to either cl_actor.c and g_combat.c.

I doubt it'll help any, but here is all the code I'm trying to compile... It is untested, and probably very buggy though, but here it is anyways:

Code: [Select]
/**
 * @brief Damage the actor.
 * @param[in] target Who is injured
 * @param[in] damage How much damage is being inflicted
 */
void CL_ActorDamage (edict_t *target, const int damage)
{
wound_t *newWound;
int randomValue;

/**< Sanity check, don't add a wound if no damage was done. */
if(damage <= 0)
return;

newWound = malloc(sizeof(wound_t));
/**< First determine where the wound is */
randomValue = rand() % (WOUND_HEAD_PROBABILITY + WOUND_CHEST_PROBABILITY + WOUND_ARMS_PROBABILITY + WOUND_LEGS_PROBABILITY);
if(randomValue < WOUND_HEAD_PROBABILITY)
newWound->location = WOUND_HEAD;
else if(randomValue < WOUND_HEAD_PROBABILITY + WOUND_CHEST_PROBABILITY)
newWound->location = WOUND_CHEST;
else if(randomValue < WOUND_HEAD_PROBABILITY + WOUND_CHEST_PROBABILITY + WOUND_ARMS_PROBABILITY)
newWound->location = WOUND_ARMS;
else if(randomValue < WOUND_HEAD_PROBABILITY + WOUND_CHEST_PROBABILITY + WOUND_ARMS_PROBABILITY + WOUND_LEGS_PROBABILITY)
newWound->location = WOUND_LEGS;
else /**< This should *never* happen, put out an error or something */
newWound->location %= WOUND_LEGS; /**< WOUND_LEGS is probably the highest enum value, so % by it. */

/**< Next determine if it is a wound */
if(damage < WOUND_MINIMUM_DAMAGE) {
newWound->affectSkill = 0;
newWound->treated = 1;
} else {
newWound->affectSkill = 1;
newWound->treated = 0;
}

/**< Finally set the damage of the wound */
newWound->value = damage;

/**< The wound is created, just add it to the target now */
LIST_AddPointer(&target->chr.wounds, newWound);
/**< Subtract the damage from the current hit points. */
target->HP -= damage;
}

int CL_ActorAccuracyDecreaseByWounds (edict_t *target)
{
linkedList_t *woundList;
wound_t *wound;
int armWounds = 0, headWounds = 0, returnValue = 0;

/**< Calculate Arm Wounds */
woundList = target->chr.wounds;
while (woundList) {
wound = (wound_t *)woundList->data;
if ((wound->location == WOUND_ARMS) && wound->affectSkill) {
if (wound->treated)
armWounds += wound->value / 2;
else
armWounds += wound->value;
}
woundList = woundList->next;
}
/**< TODO: Value of all arm wounds is now stored in armWounds, do something with it here. */

/**< Calculate Head Wounds */
woundList = target->chr.wounds;
while (woundList) {
wound = (wound_t *)woundList->data;
if ((wound->location == WOUND_HEAD) && wound->affectSkill) {
if (wound->treated)
headWounds += wound->value / 2;
else
headWounds += wound->value;
}
woundList = woundList->next;
}
/**< TODO: Value of all head wounds is now stored in headWounds, do something with it here. */

return returnValue;
}

int CL_ActorShootTUIncreaseByWounds (edict_t *target)
{
linkedList_t *woundList;
wound_t *wound;
int armWounds = 0, returnValue = 0;

/**< Calculate Arm Wounds */
woundList = target->chr.wounds;
while (woundList) {
wound = (wound_t *)woundList->data;
if ((wound->location == WOUND_ARMS) && wound->affectSkill) {
if (wound->treated)
armWounds += wound->value / 2;
else
armWounds += wound->value;
}
woundList = woundList->next;
}
/**< TODO: Value of all arm wounds is now stored in armWounds, do something with it here. */

return returnValue;
}

/**
 * @brief Treat the actor.
 * @param[in] target Who is treated
 * @param[in] damage /1000=type of healing, %1000 = amount of healing.
 */
void CL_ActorTreat (edict_t *target, const int damage)
{
int type, value, index, amount, woundNumber;
linkedList_t *woundList;
wound_t *treatWound;

type = damage / 1000;
value = damage % 1000;

/**< Sanity check on 'value' here if wanted. *
* I am leaving it out in case we want to subtract morale or something. */
if (type < 0)
type = -type;

if ( type == HEAL ) {
/**< First we locate the worst wound on the person being treated */
index = 0;
amount = 0;
woundNumber = 0;
woundList = target->chr.wounds;
while (woundList) {
treatWound = (wound_t *)woundList->data;
if ((!treatWound->treated) && (treatWound->value > amount)) {
    amount = treatWound->value;
    woundNumber = index;
}
index++;
woundList = woundList->next;
}
woundList = target->chr.wounds;
treatWound = (wound_t *)LIST_GetByIdx(woundList, woundNumber);
/**< Heal the wound a bit. We will simply subtract 10% of the wound from itself. */
treatWound->value -= treatWound->value / 10;
treatWound->treated = 1;
target->HP += treatWound->value / 10;
} else if (type == MORALE) {
target->morale -= value;
target->morale = min (target->morale, 100);
target->morale = max (target->morale, 0);
} else if (type == STUN) {
target->STUN -= value;
target->STUN = min (target->STUN, 255);
target->STUN = max (target->STUN, 0);
} else {

}
}
« Last Edit: September 17, 2009, 08:45:26 pm by criusmac »

Offline Mattn

  • Administrator
  • PHALANX Commander
  • *****
  • Posts: 4831
  • https://github.com/mgerhardy/vengi
    • View Profile
    • Vengi Voxel Tools
Re: Undefined Reference
« Reply #7 on: September 17, 2009, 09:20:58 pm »
you can't use the linked list directly. it is using memory pools that are not available in the game lib - keep in mind that the stuff below src/game/ will end in a dll - you can use most of the stuff from src/shared - but very little other stuff.

also please move your code into g_actor.c and change the prefix from CL_Actor* to G_Actor*

be a little bit more verbose on your comments please - describe exactly what each function is supposed to do.

the game lib is using callbacks for e.g. cvars and commands to access the server context (where the game lib is running at) see sv_game.c SV_InitGameProgs

but adding more function callbacks there is only accepted if no other choice is left. so maybe just make wound_t a linked list like this:

Code: [Select]
typedef struct wound_s {
[......]
[......]
struct wound_s *next;
} wound_t;

last but not least - please beware our coding guidelines ;)

Offline criusmac

  • Squad Leader
  • ****
  • Posts: 168
    • View Profile
Re: Undefined Reference
« Reply #8 on: September 17, 2009, 09:38:29 pm »
also please move your code into g_actor.c and change the prefix from CL_Actor* to G_Actor*

Yes, as stated before, once I figure out where the code is going, I will change the function names.

Quote
be a little bit more verbose on your comments please - describe exactly what each function is supposed to do.

Yes, as stated before, this code is *NOT* done, and will not be commented properly until it does exactly what I want. The number of times I've had to change this code already has made many comments vanish.

Quote
the game lib is using callbacks for e.g. cvars and commands to access the server context (where the game lib is running at) see sv_game.c SV_InitGameProgs

but adding more function callbacks there is only accepted if no other choice is left. so maybe just make wound_t a linked list like this:

Code: [Select]
typedef struct wound_s {
[......]
[......]
struct wound_s *next;
} wound_t;

So, you are suggesting that I create linkedList_t by copying all the functionality to the dll? I'm not sure exactly what you are suggesting.

Quote
last but not least - please beware our coding guidelines ;)

As stated before, I will finalize the code once I have written it. I will not beautify my code until it is complete since it takes so much time to do so, and it keeps changing due to various problems, such as this. This is actually what I figured might be said, which is why I originally didn't want to supply any code.
« Last Edit: September 17, 2009, 09:57:13 pm by criusmac »

Offline criusmac

  • Squad Leader
  • ****
  • Posts: 168
    • View Profile
Re: Undefined Reference
« Reply #9 on: September 17, 2009, 09:56:23 pm »
I am probably over reacting, but it is how I feel, so I will leave it as was... (This attitude of mine always seems to get me into trouble)

Right now, as far as I can tell, the problem you are stating Mattn (aside from the comments on how poorly written my code in progress is) is that the dll is not using the same heap manager as the rest of the code. If this is the case, even if I create my own linked list in the dll, it will run into the same problem.

From what I understand, the code should have been written so that only one module is handling all the allocations and the frees. Any allocations in the dll should have already been using the same allocator.. If this is the case, there shouldn't be any problem using the existing linked list code in the dll. If this is not the case, there are going to be a lot of other problems in the dll code if it does any sort of memory allocations at all... Even if I create my own linked list to do so.

So, right now, the way I see it... I can't continue properly, since the suggestion given and the reason given by you are conflicting with each other.

IE: If different memory pools are being used, then I can't create my own linked list to get around it anyways. My code absolutely *must* be able to transfer the memory contents between the dll portion and the rest of the code since wounds need to be handled in combat, and hospitals, and save files, and etc. Is what I'm trying to do impossible due to this?

Offline geever

  • Project Coder
  • PHALANX Commander
  • ***
  • Posts: 2561
    • View Profile
Re: Undefined Reference
« Reply #10 on: September 17, 2009, 10:04:43 pm »
IE: If different memory pools are being used, then I can't create my own linked list to get around it anyways. My code absolutely *must* be able to transfer the memory contents between the dll portion and the rest of the code since wounds need to be handled in combat, and hospitals, and save files, and etc. Is what I'm trying to do impossible due to this?

I don't know this (dll) part but did you check how character data shared? There is a communication in both directions (client->game, game->client) for sure...

-geever

Offline criusmac

  • Squad Leader
  • ****
  • Posts: 168
    • View Profile
Re: Undefined Reference
« Reply #11 on: September 17, 2009, 10:15:02 pm »
Sort of. The character data appears to be stored in character_t create in inv_shared.h. This already has a linked list built into it via teamDef_t, and so I included my linked list into character_t's data structure. The teamDef_t data structure appeared to be used in both the g_ and cp_ places, but I didn't pay attention to where its memory is allocated. Now that I look, it appears the memory is allocated only in the cp_ code.

Unfortunately, I can't do that the same way since memory has to be allocated and deallocated with regards to my linked list in both the g_ code, and the cp_ code.

For example:
Every time a wound is created I need to allocate in the g_ code since it happens in combat.
Every time a wound is healed, I need to deallocate in the cp_ code since it happens outside of combat.

*Edit*
I don't know this (dll) part but did you check how character data shared? There is a communication in both directions (client->game, game->client) for sure...

-geever

On second thought, I am unsure of what you are asking. It appears you are asking if I realize that the dll and non dll portions of the game can share data.. This is, at its surface an odd question since anyone can't avoid knowing that dlls share data with application code... So, you must be asking something else.. Are you asking if I've look at how memory is allocated between the client and the game? No, I never did. I did not even realize the game project was a dll since I don't know how to see that in code blocks.

I was unable to find g_actor.c in my current project, so I imagine I have to download everything again. From rereading Mattn's comments, it *sounds* like I need to move my code out of g_combat.c, and put it into inv_shared.c, which is in the src/shared, and go from there.
« Last Edit: September 17, 2009, 10:31:47 pm by criusmac »

Offline Duke

  • Administrator
  • PHALANX veteran
  • *****
  • Posts: 1037
    • View Profile
Re: Undefined Reference
« Reply #12 on: September 17, 2009, 10:53:17 pm »
I was unable to find g_actor.c in my current project,
In C:B, 'game' project, it's pretty much the first source you see if you open the 'sources' folder.
No need to re-download...

Offline criusmac

  • Squad Leader
  • ****
  • Posts: 168
    • View Profile
Re: Undefined Reference
« Reply #13 on: September 17, 2009, 11:11:12 pm »
It is pretty obvious that I can't do a malloc in a dll and get away with it now that I know it's a dll.

Obviously, being a dll, it has to be used by multiple pieces of software. Doing a dir indicates:
ufo.exe
ufo2map.exe
ufo_ded.exe

so, probably between a couple of those at least. I have never known another reason to use a dll myself, other than to share code between software...

Looking at ufo2map.exe, it looks like some sort of map editor, maybe it has something to do with radiant.
ufo.exe is the game, so that needs the dll.
ufo_ded.exe looks like a server or something. It appears to have connections to the game library as well. inv_shared.c is here, so it appears that inv_shared is purely exe code, and not available in the dll. Putting my code in it won't help at all. Hmmm...

Ok, my code absolutely has to be called during combat, and that appears to all take place in the dll. The memory for this has to be used outside of combat... so I really should allocate everything outside of the dll. Oops, I shouldn't keep thinking out loud. I'm making too much noise.


Reply posted while typing, so...
dir *g_actor* /s
was done before, and it showed no files found.
Looking at the game project indicates the first file is g_ai.c, not g_actor.c, and so I don't have the same project.
Since my last download before I started work was:
07/31/2009  11:40 AM       620,577,731 ufoai-2.3-dev-win32-25511.exe

Best I can assume is this g_actor.c did not exist when I did the download about a month ago. Does anyone have a small patch file for the changes since 25511? I don't have the bandwidth to download 600+ megs for about 20 days. (Until the eighth of October, my billing date)

Offline criusmac

  • Squad Leader
  • ****
  • Posts: 168
    • View Profile
Re: Undefined Reference
« Reply #14 on: September 17, 2009, 11:24:45 pm »
I guess it is wrong of me to expect help with my code the way it is. I have already started to beautify it to the coding standards in place. I expect it to take about 3-5 hours to complete, but I will post it when done.