• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
fir

calling function pointer without typedef

14 posts in this topic

Once time ago I was using dynamic dll linking ,

Here you obtain a function pointer by name,

You should also typedef this pointer but I was

lazy (those typedefs can be complex ) so i tried

to call it without typedef, something like

 

FARPROC  SomeImportedFunction  = NULL; 

 

int x = SomeImportedFunction(1,2,3);

 

Has it (this way of using it) a chance to work?

(I think this is dangerous becouse compiler here has to guess 

how to pass arguments and this is not type checked in the case

of some omittions or misaligments, wrong arg sizes), but if doing carefully 

has this a chance to work, how to do it?

 

previously i was even unawara I can do this, I mean this way you can 

push any arguments configuration then call the pointer, I am not sure how this is working - does it asume SomeImportedFunction is cdecl or stdcall

or what?

 

(I am not really sure what FARPROC hides, used it becouse it was 

simplest not need to define any function pointedr typedef just using some)

 

 

 

 

0

Share this post


Link to post
Share on other sites

FARPROC is a typedef:

 

int (FAR WINAPI * FARPROC) ()

 

In C, an empty parameter list means "turn off all type checking and pass in whatever I supply". In C++ it means "This method takes no parameters". The C form just makes the assumption that the called function knows what state the stack is in in terms of values that are there. Its more a throwback to the sort of "portable assembler" philosophy of C.

 

Its not clever to do this though. Far better to cast to a pointer to function typedef that specifies the arguments so the compiler can check you are calling it correctly. If you stuff up, the function will trash all over the stack when it runs. 

1

Share this post


Link to post
Share on other sites

FARPROC is a typedef:

 

int (FAR WINAPI * FARPROC) ()

 

In C, an empty parameter list means "turn off all type checking and pass in whatever I supply". In C++ it means "This method takes no parameters". The C form just makes the assumption that the called function knows what state the stack is in in terms of values that are there. Its more a throwback to the sort of "portable assembler" philosophy of C.

 

Its not clever to do this though. Far better to cast to a pointer to function typedef that specifies the arguments so the compiler can check you are calling it correctly. If you stuff up, the function will trash all over the stack when it runs. 

 

I do not understand (some weak english)

 

Does this mean that this 

 

 

FARPROC  SomeImportedFunction  = NULL; 

//... obtaint pointer here from dll

int x = SomeImportedFunction(1,2,3);

 

will work in c but not in c++ or what ? (I usually wrote a c cod e but compile with basic c++ mode, and it seemed 'partially 

work' there probably i was passing some wrong size types,

not sure so some worked, some not)

 

ps 

 

if f() means any arg cann be called , like f(1) , f(1,2,3,4)

how to use it - wrote a definition for this, if args are unknown, i do not understand

Edited by fir
0

Share this post


Link to post
Share on other sites

Yes, it will work in C but not C++.

 

In C, a function with no arguments of the form f() can be passed any arguments at all and the compiler just ignores them in terms of checking. To define a C function that takes no arguments, you have to use the form f(void).

 

In C++ this changed and f() means no arguments. Calling a FARPROC pointer with arguments won't compile on a C++ compiler.

 

This implies that you, the programmer, are responsible for ensuring that the arguments you pass match whatever the function expects. It also means the compiler can't check that you are passing the correct arguments.

 

So in the case of loading functions from DLLs, it is far more sensible to create a typedef of a function with the correct arguments. You then only have to get this right in one place, when you cast the return from GetProcAddress, rather than get it right every time you call the resultant function.

Edited by Aardvajk
1

Share this post


Link to post
Share on other sites

If you remove all the winapi crap from the typedef you see that the function pointer FARPROC is defined as:

typedef int (*FARPROC)();

So it is indeed a pointer to a function which takes an indeterminate number of arguments. You can pass in anything you want, the compiler will set up the caller's stack accordingly, and the function will "read" the arguments passed off the stack (this could range from "explodes if you pass the wrong arguments" to "looks at the stack pointer to work out how many arguments were passed, varargs style"). In C, a function which takes exactly zero arguments should normally be written as foo(void).

 

At least, that is the case in C. As Aardvajk said, C++ deprecates the unspecified argument syntax, so that foo() is effectively equivalent to foo(void), in other words, you will not be able to call the function through the function pointer (or otherwise) with any arguments specified, and your snippet should not work. If it does, it means your C++ compiler is operating in some "C compatibility mode", or that it is simply broken. So for C++ you would presumably need to rewrite the function declaration to explicitly indicate the arguments, or use varargs syntax, and you would probably want to write an idiomatic C++ wrapper on top of it using std::bind or whatever (I don't really know a lot of C++, just saying you would typically write more high level code for this stuff).

 

So, to answer your question in plain english:

 

 

 


FARPROC  SomeImportedFunction  = NULL; 
//... obtaint pointer here from dll
int x = SomeImportedFunction(1,2,3);
 
will work in c but not in c++ or what ? (I usually wrote a c cod e but compile with basic c++ mode, and it seemed 'partially 
work' there probably i was passing some wrong size types,
not sure so some worked, some not)

 

Yes, it will not work in C++. If it work on your compiler, then you're not compiling C++ but C or some hybrid thereof.

 

 

 


if f() means any arg cann be called , like f(1) , f(1,2,3,4)
how to use it - wrote a definition for this, if args are unknown, i do not understand

 

You as a programmer are supposed to know how to call it. The compiler doesn't know nor care whether the arguments are right or wrong if it's not given a function signature, it will push the arguments into registers/onto the stack following whatever calling convention is in use and will then call the function. If the function can read the arguments (= same calling convention and expected number/format of arguments) then it will work. If not, your program will probably segfault inside the function, or, for some calling conventions, corrupt the stack. This syntax was designed to be very, very close to assembly level, if you don't understand how function calls happen in assembly then you will probably not understand how these types of functions work and why they are relevant. And if you do a lot of C and especially a lot of low-level interop (which it seems you do, seeing your recent posts on static lib compatibility) it would definitely not hurt to take a look.

1

Share this post


Link to post
Share on other sites

FARPROC is a typedef:

 

int (FAR WINAPI * FARPROC) ()

 

In C, an empty parameter list means "turn off all type checking and pass in whatever I supply". In C++ it means "This method takes no parameters". The C form just makes the assumption that the called function knows what state the stack is in in terms of values that are there. Its more a throwback to the sort of "portable assembler" philosophy of C.

 

Its not clever to do this though. Far better to cast to a pointer to function typedef that specifies the arguments so the compiler can check you are calling it correctly. If you stuff up, the function will trash all over the stack when it runs. 

alright, tnx, i agrre typedef is far better (I got silent runtime errors indeed), still I am curious; 

Some typedefs were hard to obtain as far as i weakly remember ... Does mayby anyone know - If you have a dll

and a header to it , it contains header declarations of functions

... - is there a process of turning this declarations into needed typedefs an easy task, like

 

int foo();     ->     typedef int (*p_foo) ();

 

or there I can meet some pitfalls or obstacles I'm vaguelly afraid of?

0

Share this post


Link to post
Share on other sites

So, to answer your question in plain english:

 

 

ok, i understand

 

 

Yes, it will not work in C++. If it work on your compiler, then you're not compiling C++ but C or some hybrid thereof.

 

 

 

could be i always use c in c++ compiling mode but this was

a small pice and maybe i overlooked to set cpp mode

 

 


"You as a programmer are supposed to know how to call it. The compiler doesn't know nor care whether the arguments are right or wrong if it's not given a function signature, it will push the arguments into registers/onto the stack following whatever calling convention is in use and will then call the function. If the function can read the arguments (= same calling convention and expected number/format of arguments) then it will work. If not, your program will probably segfault inside the function, or, for some calling conventions, corrupt the stack. This syntax was designed to be very, very close to assembly level, if you don't understand how function calls happen in assembly then you will probably not understand how these types of functions work and why they are relevant. And if you do a lot of C and especially a lot of low-level interop (which it seems you do, seeing your recent posts on static lib compatibility) it would definitely not hurt to take a look."

 

i meant if i declare 

 

int f();

 

how can i use then to use it one time to call like f(1,2)

or other time to call it f(1,2,3)

 

I can call it any way i like but in definition there is no arguments so how do i then acces to this 1,2 or 1,2,3 values

0

Share this post


Link to post
Share on other sites

Function typedefs look scary but they are easy enough. Just write it like a function, then put parentheses around the name and put a start in front of the name, then remove parameter names.

 

double name(int i, const std::string &s);

 

typedef double (*name)(int, const std::string&);

1

Share this post


Link to post
Share on other sites

I can call it any way i like but in definition there is no arguments so how do i then acces to this 1,2 or 1,2,3 values

 

A function would need to do some kind of interogation of the stack to figure out what had been pushed onto the stack prior to the call. Its not possible to do this in standard C and is not a common activity these days.

 

In the bad old days of C, people were used to working in assembly where they would manage their own stacks, so it was probably far more common back then to mess about with the stack directly in C. There's never really a good reason for that sort of thing in 2014, outside of very niche areas like embedded systems.

 

Templates, function overloading and inlining in C++ have pretty much removed any need for varadic functions. In C you have the va_args and ellipses system if you really need to mess about.

Edited by Aardvajk
1

Share this post


Link to post
Share on other sites

Here's a real world example from Caveman 3.0....

 

first, the typedefs....

 

//#################################### TYPEDEFS #####################################################
 
 
 
typedef void functiontype1();
 
typedef void functiontype2(int);
 
//#################################### END TYPEDEFS #####################################################
1

Share this post


Link to post
Share on other sites

well, once again the editor is clipping everything after the first "open square bracket, slash, 'code', closed square bracket".

 

guess i'll have to post the reply in sections...

 

 

 
Second, declare your function variables....
 

// action types
struct actionrec
{
char msg[100];
int energy,water_disease,bath_disease;
functiontype1 *proceedure;
int numskills,numparts,numtools,skill[10],xp[10],part[10],partqty[10],tool[10],toolqty[10];
requirementsrec r;
};    

actionrec action[maxactions];        // the actions database
 

 

 

 
 
0

Share this post


Link to post
Share on other sites
Third, forward declaration of the function variables  (you may or may not need forward declarations,depending on the order in which things appear in the source file..... 
 
 
//################################################# ACTIONS ###################################################
 
// forward declarations of action routines for init actions database
void drinkliquid();
void _make_object();
void sleep();
void rest();
void bathe();
void restandheal();
void makefire();
void eatfood();                              //   GENERIC      31 foods
void research_skill();                   //   GENERIC      45 skills
void cook_food();                           //   GENERIC      35 cooked foods / liquids
void find_object();                         //   GENERIC    everything you can find
void addwood2fire();
void play_with_fire();
void make_shelter();                        //   GENERIC      6 types of shelters
void demolish_shelter();
void entershelter();
void move();
void inspect_shelter();
void repair_shelter();
void butcher_animal();
void getbone_animal();
void gettrinkets_animal();
void sacrifice_animal();
void skin_animal();
void leaveshelter();
void bathewaterskin();
void forrage();
void fill_waterskins_rain();
void train();                               //   GENERIC      52 types of weapons
void stargaze();     
void fill_waterskins();
void swim();
void make_bedding();   
void climbtree();
void climbdownfromtree();
void makebedshelter();
void checkbedding();
void fixbedding();
void dance();
void playdrum();
void playflute();
void sing();
void telljoke();
void tellstory();
void fish();
void capture_animal();
void free_animal();
void tame_animal();
void watchclouds();
void fix_object();
void get_tendon_animal();
void make_storepit();
void inspect_storepit();
void repair_storepit();
//void examine_monolith();
void entercave();
void leavecave();
void searchbody();
void learn_from_caveman();
void teach_caveman();
void listen2story();
void teach_bandmember();
void telljokeclan();
void tellstoryclan();
void listen2joke();
void entercavern();
void leavecavern();
void buildpermshel();
void inspectpermshel();
void repairpermshel();
void demolishpermshel();
//void clearrubble();
void make_raft();
void learn_sailing();
void board_raft();
void check_raft();
void repair_raft();
void paddle();
void move_raft();
void disembark();
void pray();
void prayfire();
void poison_wpn();
void apply_camo();
void use_lodestone();
void putoutfire();
void kill_captured();
void make_object2();   // uses reqts rec
void check_trap();
void check_weather();
void check_fire();
void demolish_landmark();
void demolish_bedding();
void inspect_trap();
void repair_world_object();
void demolish_trap();
void inspect_landmark();
void repair_trap();
void daydream();
void talk2friendly();
void talk2bandmember();
void listen2bandmember();
 
0

Share this post


Link to post
Share on other sites
Fourth, assign the functions to the function varaibles.....
 
 
 
void init_actions_database()
{
ZeroMemory(action,sizeof(actionrec)*maxactions);
 
action[DONOTHING].energy=1;
 
strcpy_s(action[DRINK].msg,100,"Drinking...");
action[DRINK].proceedure=drinkliquid;
action[DRINK].water_disease=1;
 
strcpy_s(action[MAKEOBJ].msg,100,"Making object...");
action[MAKEOBJ].proceedure=_make_object;
 
action[SLEEP].energy=1;
strcpy_s(action[SLEEP].msg,100,"Sleeping...");
action[SLEEP].proceedure=sleep;
 
action[REST].energy=1;
action[REST].proceedure=rest;
strcpy_s(action[REST].msg,100,"Resting...");
 
action[BATHE].bath_disease=1;
action[BATHE].proceedure=bathe;
strcpy_s(action[BATHE].msg,100,"Bathing...");
 
action[RESTHEAL].energy=1;
action[RESTHEAL].proceedure=restandheal;
strcpy_s(action[RESTHEAL].msg,100,"Resting and healing...");
 
 
 
action[MAKEFIRE].proceedure=makefire;
strcpy_s(action[MAKEFIRE].msg,100,"Making fire...");
action[MAKEFIRE].numskills=1;
action[MAKEFIRE].skill[0]=FIREMAKING;
action[MAKEFIRE].xp[0]=50;
action[MAKEFIRE].numparts=2;
action[MAKEFIRE].part[0]=WOOD;
action[MAKEFIRE].part[1]=TINDER;
action[MAKEFIRE].partqty[0]=2;
action[MAKEFIRE].partqty[1]=1;
action[MAKEFIRE].numtools=1;
action[MAKEFIRE].tool[0]=FIRESTICKS;
action[MAKEFIRE].toolqty[0]=1;
 
action[EAT].proceedure=eatfood;
strcpy_s(action[EAT].msg,100,"Eating food...");
 
action[LEARN].proceedure=research_skill;
 
action[COOK].proceedure=cook_food;
strcpy_s(action[COOK].msg,100,"Cooking food...");
 
action[FIND].proceedure=find_object;
strcpy_s(action[FIND].msg,100,"Searching for object...");
 
action[ADDWOOD].proceedure=addwood2fire;
strcpy_s(action[ADDWOOD].msg,100,"Adding wood to fire...");
action[ADDWOOD].numparts=1;
action[ADDWOOD].part[0]=WOOD;
action[ADDWOOD].partqty[0]=2;
action[ADDWOOD].r.time=900;
action[ADDWOOD].r.chance=10000;
action[ADDWOOD].r.numparts=1;
action[ADDWOOD].r.part[0]=WOOD;
action[ADDWOOD].r.partqty[0]=2;
 
 
action[PLAYWITHFIRE].proceedure=play_with_fire;
strcpy_s(action[PLAYWITHFIRE].msg,100,"Playing with fire...");
 
action[MAKESHELTER].proceedure=make_shelter;
strcpy_s(action[MAKESHELTER].msg,100,"Making shelter...");
 
action[DEMOLISHSHELTER].proceedure=demolish_shelter;
strcpy_s(action[DEMOLISHSHELTER].msg,100,"Demolishing shelter...");
 
action[ENTERSHELTER].proceedure=entershelter;
strcpy_s(action[ENTERSHELTER].msg,100,"Entering shelter...");
 
action[MOVE].proceedure=move;
strcpy_s(action[MOVE].msg,100,"Traveling to new location...");
 
action[INSPECTSHELTER].proceedure=inspect_shelter;
strcpy_s(action[INSPECTSHELTER].msg,100,"Inspecting shelter...");
 
action[REPAIRSHELTER].proceedure=repair_shelter;
strcpy_s(action[REPAIRSHELTER].msg,100,"Repairing shelter...");
 
action[BUTCHER].proceedure=butcher_animal;
strcpy_s(action[BUTCHER].msg,100,"Butchering animal...");
 
action[DEBONE].proceedure=getbone_animal;
strcpy_s(action[DEBONE].msg,100,"Getting bone from animal...");
 
action[GETTRINKETS].proceedure=gettrinkets_animal;
strcpy_s(action[GETTRINKETS].msg,100,"Getting trinkets from animal...");
 
action[SACRIFICE].proceedure=sacrifice_animal;
strcpy_s(action[SACRIFICE].msg,100,"Sacrificing animal...");
 
action[SKIN].proceedure=skin_animal;
strcpy_s(action[SKIN].msg,100,"Skinning animal...");
 
action[LEAVESHELTER].proceedure=leaveshelter;
strcpy_s(action[LEAVESHELTER].msg,100,"Leaving shelter...");
 
action[BATHEWATERSKIN].proceedure=bathewaterskin;
strcpy_s(action[BATHEWATERSKIN].msg,100,"Bathing from waterskins...");
action[BATHEWATERSKIN].numparts=1;
action[BATHEWATERSKIN].part[0]=WATER;
action[BATHEWATERSKIN].partqty[0]=1;
action[BATHEWATERSKIN].numtools=1;
action[BATHEWATERSKIN].tool[0]=WATERSKIN;
action[BATHEWATERSKIN].toolqty[0]=1;
 
action[FORRAGE].proceedure=forrage;
strcpy_s(action[FORRAGE].msg,100,"Forraging for food...");
 
action[FILLWATERSKINRAIN].proceedure=fill_waterskins_rain;
strcpy_s(action[FILLWATERSKINRAIN].msg,100,"Filling waterskins with rainwater...");
 
action[TRAIN].proceedure=train;
 
strcpy_s(action[STARGAZE].msg,100,"Stargazing...");
action[STARGAZE].proceedure=stargaze;
 
action[FILLWATERSKIN].proceedure=fill_waterskins;
strcpy_s(action[FILLWATERSKIN].msg,100,"Filling waterskins...");
 
action[SWIM].proceedure=swim;
strcpy_s(action[SWIM].msg,100,"Swimming...");
 
action[MAKEBEDDING].proceedure=make_bedding;
strcpy_s(action[MAKEBEDDING].msg,100,"Making bedding...");
 
action[CLIMBTREE].proceedure=climbtree;
strcpy_s(action[CLIMBTREE].msg,100,"Climbing tree...");
 
action[CLIMBDOWN].proceedure=climbdownfromtree;
strcpy_s(action[CLIMBDOWN].msg,100,"Climbing down from tree...");
 
action[MAKEBEDSHELTER].proceedure=makebedshelter;
strcpy_s(action[MAKEBEDSHELTER].msg,100,"Making bedding in shelter...");
 
 
strcpy_s(action[CHECKBEDDING].msg,100,"Checking bedding condition...");
action[CHECKBEDDING].proceedure=checkbedding;
 
strcpy_s(action[FIXBEDDING].msg,100,"Repairing bedding...");
action[FIXBEDDING].proceedure=fixbedding;
 
strcpy_s(action[DANCE].msg,100,"Dancing...");
action[DANCE].proceedure=dance;
 
strcpy_s(action[PLAYDRUM].msg,100,"Playing drums...");
action[PLAYDRUM].proceedure=playdrum;
 
strcpy_s(action[PLAYFLUTE].msg,100,"Playing flute...");
action[PLAYFLUTE].proceedure=playflute;
 
strcpy_s(action[SING_ACTION].msg,100,"Singing...");
action[SING_ACTION].proceedure=sing;
 
strcpy_s(action[TELLJOKE].msg,100,"Telling joke...");
action[TELLJOKE].proceedure=telljoke;
 
strcpy_s(action[TELLSTORY].msg,100,"Telling story...");
action[TELLSTORY].proceedure=tellstory;
 
action[FISH].proceedure=fish;
 
strcpy_s(action[CAPTUREANIMAL].msg,100,"Capturing animal...");
action[CAPTUREANIMAL].proceedure=capture_animal;
 
strcpy_s(action[FREEANIMAL].msg,100,"Freeing animal...");
action[FREEANIMAL].proceedure=free_animal;
 
strcpy_s(action[TAMEANIMAL].msg,100,"Taming animal...");
action[TAMEANIMAL].proceedure=tame_animal;
 
 
strcpy_s(action[WATCHCLOUDS].msg,100,"Watching clouds...");
action[WATCHCLOUDS].proceedure=watchclouds;
 
strcpy_s(action[FIXOBJECT].msg,100,"Fixing object...");
action[FIXOBJECT].proceedure=fix_object;
 
strcpy_s(action[GETTENDON].msg,100,"Getting tendon from animal...");
action[GETTENDON].proceedure=get_tendon_animal;
action[GETTENDON].numtools=1;
action[GETTENDON].tool[0]=STONEKNIFE;
action[GETTENDON].toolqty[0]=1;
 
strcpy_s(action[MAKESTOREPIT].msg,100,"Building storage pit...");
action[MAKESTOREPIT].proceedure=make_storepit;
 
strcpy_s(action[INSPECTSTOREPIT].msg,100,"Inspecting storage pit...");
action[INSPECTSTOREPIT].proceedure=inspect_storepit;
 
strcpy_s(action[REPAIRSTOREPIT].msg,100,"Repairing storage pit...");
action[REPAIRSTOREPIT].proceedure=repair_storepit;
 
strcpy_s(action[EXAMINEMONOLITH].msg,100,"Examinimg monolith...");
//action[EXAMINEMONOLITH].proceedure=examine_monolith;
 
 
strcpy_s(action[ENTERCAVE].msg,100,"Entering cave...");
action[ENTERCAVE].proceedure=entercave;
 
 
strcpy_s(action[LEAVECAVE].msg,100,"Leaving cave...");
action[LEAVECAVE].proceedure=leavecave;
 
 
strcpy_s(action[SEARCHBODY].msg,100,"Searching body...");
action[SEARCHBODY].proceedure=searchbody;
 
 
strcpy_s(action[LEARNFROMCAVEMAN].msg,100,"Learning from caveman...");
action[LEARNFROMCAVEMAN].proceedure=learn_from_caveman;
 
strcpy_s(action[TEACHCAVEMAN].msg,100,"Teaching caveman...");
action[TEACHCAVEMAN].proceedure=teach_caveman;
 
strcpy_s(action[LISTEN2STORY].msg,100,"Listening to story...");
action[LISTEN2STORY].proceedure=listen2story;
 
strcpy_s(action[TEACHBANDMEMBER].msg,100,"Teaching bandmember...");
action[TEACHBANDMEMBER].proceedure=teach_bandmember;
 
strcpy_s(action[TELLJOKECLAN].msg,100,"Telling joke to bandmember...");
action[TELLJOKECLAN].proceedure=telljokeclan;
 
strcpy_s(action[TELLSTORYCLAN].msg,100,"Telling story to bandmember...");
action[TELLSTORYCLAN].proceedure=tellstoryclan;
 
strcpy_s(action[LISTEN2JOKE].msg,100,"Listening to joke...");
action[LISTEN2JOKE].proceedure=listen2joke;
 
 
 
strcpy_s(action[ENTERCAVERN].msg,100,"Entering cavern...");
action[ENTERCAVERN].proceedure=entercavern;
 
strcpy_s(action[LEAVECAVERN].msg,100,"Leaving cavern...");
action[LEAVECAVERN].proceedure=leavecavern;
 
 
strcpy_s(action[BUILDPERMSHEL].msg,100,"Building permenant shelter...");
action[BUILDPERMSHEL].proceedure=buildpermshel;
 
strcpy_s(action[INSPECTPERMSHEL].msg,100,"Inspecting permenant shelter...");
action[INSPECTPERMSHEL].proceedure=inspectpermshel;
 
 
strcpy_s(action[REPAIRPERMSHEL].msg,100,"Repairing permenant shelter...");
action[REPAIRPERMSHEL].proceedure=repairpermshel;
 
 
 
strcpy_s(action[DEMOLISHPERMSHEL].msg,100,"Demolishing permenant shelter...");
action[DEMOLISHPERMSHEL].proceedure=demolishpermshel;
 
 
strcpy_s(action[CLEARRUBBLE].msg,100,"Clearing rubble...");
action[CLEARRUBBLE].proceedure=NULL;
 
strcpy_s(action[MAKERAFT].msg,100,"Making raft...");
action[MAKERAFT].proceedure=make_raft;
 
 
strcpy_s(action[LEARNSAILING].msg,100,"Learning sailing...");
action[LEARNSAILING].proceedure=learn_sailing;
 
strcpy_s(action[BOARDRAFT].msg,100,"Boarding raft...");
action[BOARDRAFT].proceedure=board_raft;
 
strcpy_s(action[INSPECTRAFT].msg,100,"Checking raft...");
action[INSPECTRAFT].proceedure=check_raft;
 
strcpy_s(action[REPAIRRAFT].msg,100,"Repairing raft...");
action[REPAIRRAFT].proceedure=repair_raft;
 
strcpy_s(action[PADDLE].msg,100,"Paddling...");
action[PADDLE].proceedure=paddle;
 
strcpy_s(action[MOVERAFT].msg,100,"Moving on raft...");
action[MOVERAFT].proceedure=move_raft;
 
 
strcpy_s(action[DISEMBARK].msg,100,"Disembarking...");
action[DISEMBARK].proceedure=disembark;
 
strcpy_s(action[PRAY].msg,100,"Making sacrifice...");
action[PRAY].proceedure=pray;
 
 
action[PRAYFIRE].proceedure=prayfire;
strcpy_s(action[PRAYFIRE].msg,100,"Making sacrificial fire...");
action[PRAYFIRE].numskills=1;
action[PRAYFIRE].skill[0]=FIREMAKING;
action[PRAYFIRE].xp[0]=50;
action[PRAYFIRE].numparts=2;
action[PRAYFIRE].part[0]=WOOD;
action[PRAYFIRE].part[1]=TINDER;
action[PRAYFIRE].partqty[0]=2;
action[PRAYFIRE].partqty[1]=1;
action[PRAYFIRE].numtools=1;
action[PRAYFIRE].tool[0]=FIRESTICKS;
action[PRAYFIRE].toolqty[0]=1;
 
action[POISONWPN].proceedure=poison_wpn;
strcpy_s(action[POISONWPN].msg,100,"Poisoning weapon...");
 
action[APPLYCAMO].proceedure=apply_camo;
strcpy_s(action[APPLYCAMO].msg,100,"Applying camoflage...");
action[APPLYCAMO].r.numskills=1;
action[APPLYCAMO].r.skill[0]=CAMOFLAGE;
action[APPLYCAMO].r.xp[0]=50;
action[APPLYCAMO].r.numparts=1;
action[APPLYCAMO].r.part[0]=CORDAGE;
action[APPLYCAMO].r.partqty[0]=1;
action[APPLYCAMO].r.numtools=1;
action[APPLYCAMO].r.tool[0]=STONEKNIFE;
action[APPLYCAMO].r.toolqty[0]=1;
 
 
 
 
 
 
action[USELODESTONE].proceedure=use_lodestone;
strcpy_s(action[USELODESTONE].msg,100,"Using lodestone...");
action[USELODESTONE].r.numskills=1;
action[USELODESTONE].r.skill[0]=NAVIGATION;
action[USELODESTONE].r.xp[0]=500;
action[USELODESTONE].r.numparts=1;
action[USELODESTONE].r.part[0]=WATER;
action[USELODESTONE].r.partqty[0]=10;
action[USELODESTONE].r.numtools=3;
action[USELODESTONE].r.tool[0]=LODESTONE;
action[USELODESTONE].r.tool[1]=CLAYPOT;
action[USELODESTONE].r.tool[2]=WOOD;
action[USELODESTONE].r.toolqty[0]=1;
action[USELODESTONE].r.toolqty[1]=1;
action[USELODESTONE].r.toolqty[2]=1;
action[USELODESTONE].r.time=4500;
action[USELODESTONE].r.chance=7500;
action[USELODESTONE].r.numbonusskills=1;
action[USELODESTONE].r.bonusskill[0]=NAVIGATION;
action[USELODESTONE].r.numboostedskills=1;
action[USELODESTONE].r.boostedskill[0]=NAVIGATION;
 
 
 
 
 
action[PUTOUTFIRE].proceedure=putoutfire;
strcpy_s(action[PUTOUTFIRE].msg,100,"Putting out fire...");
 
action[KILLCAPTURED].proceedure=kill_captured;
strcpy_s(action[KILLCAPTURED].msg,100,"Killing animal...");
 
 
 
 
strcpy_s(action[MAKEOBJ2].msg,100,"Making object...");
action[MAKEOBJ2].proceedure=make_object2;
 
 
strcpy_s(action[CHECKTRAP].msg,100,"Checking trap...");
action[CHECKTRAP].proceedure=check_trap;
action[CHECKTRAP].r.chance=10000;
action[CHECKTRAP].r.time=50;
 
 
strcpy_s(action[CHECKWEATHER].msg,100,"Checking weather...");
action[CHECKWEATHER].proceedure=check_weather;
action[CHECKWEATHER].r.chance=10000;
action[CHECKWEATHER].r.time=50;
 
 
strcpy_s(action[CHECKFIRE].msg,100,"Checking fire...");
action[CHECKFIRE].proceedure=check_fire;
action[CHECKFIRE].r.chance=10000;
action[CHECKFIRE].r.time=50;
 
strcpy_s(action[DEMOLISH_LANDMARK].msg,100,"Demolishing landmark...");
action[DEMOLISH_LANDMARK].proceedure=demolish_landmark;
action[DEMOLISH_LANDMARK].r.chance=10000;
action[DEMOLISH_LANDMARK].r.time=13500;
 
strcpy_s(action[DEMOLISH_BEDDING].msg,100,"Demolishing bedding...");
action[DEMOLISH_BEDDING].proceedure=demolish_bedding;
action[DEMOLISH_BEDDING].r.chance=10000;
action[DEMOLISH_BEDDING].r.time=4500;
 
strcpy_s(action[INSPECT_TRAP].msg,100,"Inspecting trap...");
action[INSPECT_TRAP].proceedure=inspect_trap;
action[INSPECT_TRAP].r.chance=10000;
action[INSPECT_TRAP].r.time=4500;
 
strcpy_s(action[REPAIR_WORLDOBJ].msg,100,"Repairing object...");
action[REPAIR_WORLDOBJ].proceedure=repair_world_object;
action[REPAIR_WORLDOBJ].r.chance=10000;
action[REPAIR_WORLDOBJ].r.time=4500;
 
strcpy_s(action[DEMOLISH_TRAP].msg,100,"Demolishing trap...");
action[DEMOLISH_TRAP].proceedure=demolish_trap;
action[DEMOLISH_TRAP].r.chance=10000;
action[DEMOLISH_TRAP].r.time=4500;
 
strcpy_s(action[INSPECT_LANDMARK].msg,100,"Inspecting landmark...");
action[INSPECT_LANDMARK].proceedure=inspect_landmark;
action[INSPECT_LANDMARK].r.chance=10000;
action[INSPECT_LANDMARK].r.time=4500;
 
strcpy_s(action[REPAIR_TRAP].msg,100,"Repairing trap...");
action[REPAIR_TRAP].proceedure=repair_trap;
action[REPAIR_TRAP].r.chance=10000;
action[REPAIR_TRAP].r.time=4500;
 
strcpy_s(action[DAYDREAM].msg,100,"Daydreaming...");
action[DAYDREAM].proceedure=daydream;
 
strcpy_s(action[TALK2FRIENDLY].msg,100,"Talking to friendly caveman...");
action[TALK2FRIENDLY].proceedure=talk2friendly;
 
strcpy_s(action[TALK2BANDMEMBER].msg,100,"Talking to band member...");
action[TALK2BANDMEMBER].proceedure=talk2bandmember;
 
strcpy_s(action[LISTEN2BANDMEMBER].msg,100,"Listening to band member...");
action[LISTEN2BANDMEMBER].proceedure=listen2bandmember;
 
 
 
 
 
 
 
 
}
 
 
 
0

Share this post


Link to post
Share on other sites
Finally, call the function variable. This is the slick part. Instead of a huge switch on action_type, you just do:
 
void doactionmodeB(int cm1)
{
int a;
a=7+cm[cm1].mood/13;
if (frame<=a) action[cm[cm1].current_action].proceedure();
}
 
Note that working with DLLs, you may need to pay particular attention to calling conventions ( IE cdecel vs fastcall etc.).
 
 
 
0

Share this post


Link to post
Share on other sites

Any reason you initialize a fixed size array with ZeroMemory? Usually you just do "array = {0};", it's cleaner, portable, and doesn't invoke a function that is possibly not even built-in on some compilers (I take it maxactions is known at compile-time). If the indices into the array are also known at compile time, the compiler may even decide zeroing the array is unnecessary and skip it altogether after doing some static analysis (though I doubt that, admittedly, but just saying that would probably never be possible with a call to ZeroMemory bang in the middle of the function).

1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0