Je suis à la recherche de quelqu'un qui pourrait m'aider sur un programme de jeu que j'ai "récupéré".
Je précise que ce jeu est un abandonware (fermeture définitive du jeu en 2013), cependant, même si le code est disponible sur internet, rien ne me prouve à ce jours que l'éditeur est abandonné les droits, je ne le partagerais donc pas les sources sur un forum (uniquement fourniture du lien internet en communication privé).
Je précise qu'il n'y a bien-sûr aucun intérêt ni financier, ni business ni autre uniquement de la culture personnel sur ce mini-projet personnel (je suis fan de casse-tête).
Je souhaites juste que quelqu'un m'aide à comprendre les étapes qui se déroulent dans le code lorsque j'appui sur la touche saut "JUMP" et lorsque le joueur monte sur une monture.
je ne comprend pas bien le déroulement de ces processus dans le code.
Si quelqu'un souhaite m'aider, nous discuterons en privé pour m'expliquer.
Merci à vous.
Et un grand merci pour ce site de très bonne qualité.
Je vous laisse détruire ce post, si vous estimez qu'il n'est pas conforme à vos souhaits.
Si tu nous disais déjà de quel jeu il s'agit, que nous puissions faire nos propres recherches, et, le cas échéant, confirmer ou infirmer tes propres déductions ? Ce serait déjà pas mal, tu ne crois pas ?
D'un autre coté, sans le code et sans même savoir de quel jeu on parle ici, il va sans doute être très difficile de t'aider en quoi que ce soit, car on vient d'entrer dans une période (qui est prévue pour durer 365 jours) pendant laquelle toutes les boules de crystal vont fonctionner de manière erratique (une question d'ondes envoyées par le soleil, ou quelque chose du genre)
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Merci à vous deux pour vos réponses. Ne connaissant pas parfaitement les règles du forum, j'avais effectivement volontairement limité les informations.
Le jeu s'appelle : RAIDERZ (il me semble que le "moteur" est commun à d'autre jeu du même éditeur).
Vous pouvez trouver facilement les sources de ce vieux jeu sur internet, notamment sur les sites d'émulation. Je vous conseille un site français plutôt "funky" (mes sources viennent de là-bas).
Concernant ta question Fvirtman, j'avoue ne pas savoir comment faire avec ce type de source, car l’exécutable une fois compilé doit être lancé avec des instructions derrières via un .bat ou en shell.
Je me permet de remonter le sujet, car je suis vraiment coincé.
Si quelqu'un pouvait me dire comment lancer (en mode pas à pas) l'application dans Visual studio en ajoutant des instructions (comme dans un bat ou par shell).
Je suis désolé, je n'ai vraiment pas un bon niveau, mais je voudrais comprendre :
Ceci est bien une fonction ==> bool XMyActionJump::OnSpecialAction(SPECIAL_ACTION_COMMAND nSpecialActionCommand)
Si, oui, donc logiquement, elle devrait être appelé à quelque part dans le programme (vu que dans les log elle apparait), malheureseument impossible de trouver à quel endroit elle est appelée.
Pour le message du 14 mars, vous essayez de lancer le débuggeur sur un projet de type "librairie" et non un projet exécutable.
C'est possible mais cela demande quelques réglages. (et je viens de relire les messages, l'utilisation d'un bat de pré-lancement complique un peu les choses, il faudrait nous le fournir, si besoin)
C'est Ok pour le débugging ?
>Ceci est bien une fonction
C'est une question ou une affirmation ?
Si c'est une question, c'est fonction de ce qu'il y a "autour".(et on parle vraisemblablement d'une DEFINITION de fonction, pas d'une déclaration ou d'un appel de cette même fonction)
>malheureseument impossible de trouver à quel endroit elle est appelée.
Si vous avez réussi à compiler le projet, voir toute la solution, sous VS, vous disposez d'un menu contextuel "Rechercher toutes les références" ou encore "Afficher la hiérarchie d'appels" quand vous sélectionnez le nom de la méthode.
Ce n'est pas 100% sûr mais ça fonctionne plutôt bien sur du code pas trop complexe/exotique.
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
Ceci est bien une fonction ==> bool XMyActionJump::OnSpecialAction(SPECIAL_ACTION_COMMAND nSpecialActionCommand)
Oui, c'est ce que l'on appelle la "signature" d'une fonction. C'est, pour faire simple, ce qui permet au compilateur de savoir qu'une fonction existe et de s'assurer -- lorsqu'on essaye d'appeler cette fonction -- qu'on lui transmet les bons paramètres et, le cas échéant, que l'on récupère la valeur renvoyée par la fonction dans une donnée du type correct.
Pour te permettre de comprendre, ce prototype prend normalement la forme de
<Type_de_retour> [<nom_de_classe> ::] <nom_de_fonction> ([<liste_paramètres>])
^
|
"opérateur de portée"
(Ce qui est entre crochets [ et ] peut ne pas apparaître, mais est obligatoire dans le cas présent)
Voyons à quoi tout cela correspond
Le type_de_retour permet au compilateur de savoir quel sera le type de la donnée renvoyée par la fonction une fois qu'elle aura terminé son travail. Dans le cas présent, la fonction va renvoyer un booléen: une donnée qui ne peut prendre que deux valeurs différentes true ("vrai") et false ("faux")
[<nom_de_la_classe>::] permet au compilateur que l'on va parler de "quelque chose" (une fonction, en l'occurrence) qui ne peut être utilisé qu'au travers d'une classe bien particulière. Dans le cas présent, la fonction (et surtout la logique qu'elle décrit) est destinée à être utilisée au travers d'une classe nommée XMyActionJump
<nom_de_la_fonction> permet au compilateur d'identifier sans l'ombre d'un doute la fonction parmi toutes les autres fonctions qui existent (au niveau de la classe XMyAcionJump, dans le cas présent). Dans notre cas, il s'agit de la fonction appelée OnSpecialAction.
Enfin, <liste_des_paramètres> (qui se trouve forcément entre deux parenthèses ( et ), si elle existe ) permet de transmettre les données dont la fonction a besoin pour travailler mais qu'elle est incapable de définir par elle-même. On désigne les paramètres (je simplifie) en précisant
le type de donnée qui sera utilisé comme paramètre. Dans le cas présent il s'agit d'un SPECIAL_ACTION_COMMAND
un "cv qualifier" éventuel (absent dans le cas présent), qui peut être le mot clé const ou le mot clé volatile (ou rien)
un "memory access qualifier" (absent dans le cas présent), qui peut prendre la forme d'une étoile '*' pour représenter un pointeur, d'une esperluette '&' pour représenter une référence ou rien pour représenter un passage par valeur
un nom permettant d'identifier le paramètre parmi toutes les données accessibles à la fonction. Dans le cas présent, le paramètre est nommé nSpecialActionCommand
s'il y a plusieurs paramètres à transmettre, on les sépare par une virgule ';' et on recommence en (1) avec le type du paramètre suivant
On dispose donc de toutes les informations qui nous permettent (ainsi qu'au compilateur, d'ailleurs) de nous faire une idée bien précise du concept dans lequel cette fonction sera utilisée, et, mieux encore, de nous faire une idée précise de l'usage auquel elle est destinée; du moins, si on connaît ne serait-ce qu'un tout petit peu l'anglais
Car le nom de la classe (XActionJump) évoque clairement le fait que le joueur est occupé à sauter (le terme jump nous l'évoque), alors que le nom de la fonction (OnSpeialAction) évoque clairement que le joueur tente d'utiliser son action spéciale.
Autrement dit, nous sommes occupés à définir la logique qui devra être suivie si le joueur souhaite lancer son "action spéciale" alors qu'il est déjà occupé à sauter. Et, comme on ignore -- au moment d'écrire le code -- quelle pourra être cette action spéciale (ni même si le joueur dispose effectivement d'une action spéciale, d'ailleurs), on transmet l'action qui devra être effectuée sous forme de paramètre.
Avoue que l'on commence déjà à y voir plus clair, non ?
Maintenant, je n'ai toujours pas regardé le code de ce jeu en particulier, et pourtant, comme je sais vaguement comment ils fonctionnent généralement, et que le code respecte des conventions de nommages relativement classiques, je peux assez facilement faire quelque suppositions.
Par exemple, parce que le type du paramètre est écrit sous la forme de SPECIAL_ACTION_COMMAND, on peut raisonnablement penser qu'il s'agit d'un symbole permettant de représenter plus facilement ce que l'on appelle un "pointeur de fonction" (ou "callback" en anglais).
De même, on peut raisonnablement penser que la classe XMyActionJump représente en réalité un état particulier du joueur à un moment donné du jeu, et qu'elle intervient donc dans une hiérarchie de classes, permettant de représenter l'ensemble des états dans lequel le joueur peut se trouver (à un instant donné du jeu) comme -- par exemple -- le fait d'être mort, d'être couché, de marcher ou de courir, de sauter, d'attaquer, d'attendre une instruction, j'en passe, et sans doute de meilleures.
En outre, on peut raisonnablement penser que le joueur peut vouloir (essayer d') exécuter son action spéciale dans n'importe lequel des états, et donc, qu'il existe une implémentation (comprend: le fait de définir la logique qui doit être utilisée) de la fonction OnSpecialActioin dans chaque classe représentant les différents états que j'ai cités.
De plus, le fait que cette fonction renvoie un booléen (une donnée qui ne peut prendre que les valeur "vrai" et "faux") semble indiquer que l'appel de la fonction sera systématiquement suivi d'un test permettant de savoir si elle a été correctement exécutée ou non.
Tout cela me laisse à penser que l'on devrait donc trouver -- mais sans doute à un seul endroit du code -- un code proche de
Il se pourrait aussi qu'il se retrouve plutôt sous une forme proche de
case <un_nom_quelconque>:
return OnSpecialAction(<un_autre_nom>);
(où <un_nom_quelconque> et <un_autre_nom> peuvent correspondre strictement à n'importe quoi).
Au final, si tu veux trouver l'endroit (ou les endroits, mais je doute qu'il y en ai beaucoup) où cette fonction sera appelée, l'idéal est de simplement rechercher le terme OnSpecialAction( en sachant que la plupart des éléments que tu trouveras seront sans doute des signatures (bool <un_nom>::OnSpecialAction(SPECIAL_ACTION_COMMAND nSpecialActionCommand) voir des déclarations dans les différentes classes (virtual bool OnSpecialAction(SPECIAL_ACTION_COMMAND nSpecialActionCommand) ), et que ces éléments là ne t'intéressent a priori pas
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Dans un premier temps je souhaiterais vous dire un grand merci, merci, merci pour votre temps et toutes ces explications si précieuses.
Concernant la question de bacelar, vous trouverez ci-dessous le .bat (j'ai essayé de le supprimant en modifiant le début du code pour pouvoir lancer directement l'executable ==> Ce qui devait me permettre de lancer le mode debug, mais malheureusement je n'y arrive pas)
"START .\GameApp.exe 127.0.0.1"
Voici le début du code au cas ou vous pourriez m'expliquer les modifications à faire pour supprimer cette étape :
Si j'ai bien lu, je penses qu'il faut modifier cette partie la (le "cmdline"), mais j'ai pas réussi :
// Create application
XGameApp* g_pApp = new XGameApp();
g_pApp->Init(cmdline);
int ret = g_pApp->Run();
if (!ret)
Concernant la problématique sur le debug, la j'avoue que je ne suis pas assez avancer pour savoir comment modifier les paramètres de VS pour lancer à partir de l’exécutable, si vous avez l'explication ou un tuto, je suis preneur, svp.
koala01, un grand merci pour le détail de tes explications, je comprends effectivement beaucoup mieux, j'ai effectué la recherche et trouvé exactement ce que tu avais noté (tu es très fort), ce qui m'a permis de comprendre un peu mieux le code, mais malheureusement j'ai toujours un bug dans ma compréhension des commandes.
En utilisant toutes vos réponses + les tutos d'openclassrooms, j'ai trouvé la source du problème, mais impossible de le résoudre.
Lorsque le player effectue un saut sans avoir de monture, il passe par la dans le code :
bool XModuleMyControl::_UpdateMyMovement(float fDelta, XModuleEntity* pModuleEntity, vec3& vDir)
... (je vous mets pas tout le début de code qui ne semble pas servir pour cette problematique)
const int nActionFSMStateID = GetCurrentActionStateID(); // La constante qui pose probleme nActionFSMStateID
const XMovableFactor& movableFactor = m_pModuleMovable->GetMovableFactor();
if (nActionFSMStateID != ACTION_STATE_IDLE &&
nActionFSMStateID != ACTION_STATE_CHANGE_STANCE &&
nActionFSMStateID != ACTION_STATE_WEAPON_CHANGE)
... (si le if est OK, le player peut avancer pendant le saut, sinon non)
Si j'édite la fonction GetCurrentActionStateID(), ci-dessous le détail :
Si le player n'a pas de monture (fonction void XPlayer::SetRide( int nRideID )), aucun problème nActionFSMStateID est différent donc il peut sauter en avant, par contre dès qu'il a une monture nActionFSMStateID est toujours égale à ACTION_STATE_IDLE (soit 0) ce qui ne devrait pas être le cas, j'imagine, pour pouvoir utiliser les commandes mouvement en plein saut
En remontant un peu plus loin, j'ai découvert que la source de la problématique était ici :
GetCurrentStateID()
int GetCurrentStateID()
{
if (m_pCurrentState)
{
return m_pCurrentState->GetID();
}
return -1;
}
Mais la encore je me heurte à un problème sur cette ligne :
return m_pCurrentState->GetID();
Quand je clique droit sur GetID() et que je fais "aperçu de la définition", je me retrouve avec une liste incroyable de possibilité (différent choix sur différent fichier) pour cette fonction/valeur :
virtual int GetID() { return CUTSCENEPLAYER_ACTION_STATE_NA; }
virtual int GetID() { return CUTSCENEPLAYER_ACTION_STATE_NONE; }
virtual int GetID() { return CUTSCENEPLAYER_ACTION_STATE_TALENT; }
int GetID() { return ACTION_STATE_SHOOT_ARROW; }
int GetID() { return ACTION_STATE_CHANGE_CHANNEL; }
etc...
Visiblement en fonction d'une info (je ne sais ni ou ni comment, ni laquelle), il prend une valeur ou une autre.
Pouvez-vous m’éclairer, si cela ne vous embêtes pas trop, de vos lanternes, svp ?
Encore merci à vous
- Edité par TestuffTestuffi1 29 mars 2020 à 15:53:52
>ci-dessous le .bat (j'ai essayé de le supprimant en modifiant le début du code
C'est pas très clair. Vous avez modifié le début du bat ou du code source de l'exécutable ?
Il nous faudrait tout le code du BAT "original" pour voir s'il y a des particularités dans celui-ci.
Le code source montre que le programme doit toujours être lancé avec des paramètres en ligne de commande.
La ligne de commande "START ..." indique qu'il faut ajouter au nom de l'exécutable, un paramètre indiquant une adresse IP. Vraisemblablement l'adresse IP du serveur s'il s'agit d'un jeu "Online".
"127.0.0.1" est un alias vers l'adresse IP de la machine locale, c'est donc que le programme (ici le client) cherche le serveur sur la même machine que lui.
Elle indique aussi qu'il faut que le dossier de travail soit celui contenant le fichier GameApp.exe.
Cela permet de configurer votre environnement pour déboguer dans Visual Studio (sous réserve que les parties du fichier bat que vous ne nous avez pas fourni n'est rien très spécial).
Le plus simple, c'est de prendre comme projet pour le débuguing, celui qui génère GameApp.exe.
Une fois trouvé dans l'explorateur de solution, faite un clic droit dessus et sélectionner "Définir comme projet de démarrage" dans le menu contextuel.
Refaites un clic droit sur le même projet et sélectionnez "Propriétés" dans le menu contextuel. Une boite de dialogue pour configurer votre projet s'ouvrira.
Comme les modifications sont valides dans toutes les configurations, sélectionnez "Toutes les configurations" dans la liste déroulante "Configuration" en haut à gauche de cette boite de dialogue.
Dans l'arborescence à gauche de la boite de dialogue, sélectionnez le nœud "Propriétés de Configuration"/"Débugage". Cela affichera un certain nombre de propriétés dans la partie "centre+droite" de la boite de dialogue.
Normalement, dans la propriété "Commande", il y a "$(TargetPath)". Si c'est le cas, ne touchez à rien, sinon mettez cette valeur (mais si vous avez un doute sur le projet sélectionnez dans l'explorateur, postez-nous la valeur actuelle).
Normalement, dans la propriété "Arguments de la ligne de commande", il n'y a rien. Mettez dans cette propriété "127.0.0.1".
Normalement, dans la propriété "Répertoire de travail", il y a "$(ProjectDir)". Remplacez cette valeur par "$(OutDir)". Cette modification peut entrainer quelques autres problèmes mais facilement corrigeables.
Une fois ces modifications faites, la touche "F5" démarrera automatiquement une session de débuguage de votre exécutable.
Mais avant de lancer la session de débugging, utilisez la touche "F9" après avoir sélectionné la ligne où vous voulez que votre programme s'interrompt.
>vous pourriez m'expliquer les modifications à faire pour supprimer cette étape :
Vous n'avez aucune modification à faire. Le code est assez bien fait pour ne pas avoir à le changer pour le déboguer dans VS.
Le code sent un peu la naphtaline avec des trucs pas très élégants, mais c'est généralement des trucs assez "simple" à comprendre.
Le "virtual int ..." montre que GetID est très vraisemblablement une méthode virtuelle (comme on ne sait de quelles classes il s'agit dans votre message, on peut pas en être sûr). En gros, c'est juste que la méthode qui sera effectivement appelée est fonction du "vrai" type de l'objet et non en fonction du type déclaré de la variable le "contenant".
Donc, la méthode qui sera appelée est fonction du type de la variable contenue dans "m_pCurrentState". C'est là où l'utilisation d'un débogueur prend tout son intérêt.
Après, le type de "m_pCurrentState" doit avoir une certaine logique en fonction du comportement que l'on souhaite avoir dans l'état "courant".
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
Je suis désolé, j'ai encore une question bête mais est-il possible de voir la fenêtre de l’exécutable s'animer en mode pas à pas débogage (un peu comme du PHP ou du VB), afin de voir exactement le chemin pour chaque animation, svp ?
Dans mon cas actuellement pendant les avancées pas à pas la fenêtre exécutable est figées.
Pour ce genre de débugging de programme graphique, je vous conseille chaudement d'avoir 2 écrans, l'un avec le programme en cours de débugging et l'autre avec le débogueur.
Le débugging pas à pas du C++ est tout à fait comparable à celui du VB(6? ou .NET?, VBA c'est spécial) et très vraisemblablement du PHP.
Pouvez-vous être plus précis ?
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
J'utilise bien deux écrans, cependant la fenêtre "programme" ne s'anime pas qu'en j'avance en pas à pas, elle reste figée. Lorsque je relance le programme après un point d'arrêt à ce moment là, la fenêtre s'anime à nouveau.
Exemple : si je lance un saut dans la fenêtre programme, je mets un point d'arrêt au début du saut et à la fin. Entre les deux point d'arrêt il ne se passe rien (en terme d'animation) et après le dernier point d'arrêt le "joueur" apparaît sur la fenêtre programme directement à son point de chute sans avoir présenter l'animation. Hors en mode normal, on le voit sauter.
C'est normal, quand tu exécute en pas à pas, les instructions sont exécutées une par une, or le rafraichissement de l'écran est une instruction (un paquet en fait, mais passons). Tant que tu n'exécutes pas l'instruction de rafraichissement de l'écran, l'image est figée. La structure d'un programme graphique est grosso modo toujours celle-ci:
while(!quit())
{
compute();
display();
}
Si tu regardes ce code minimal, la fonction compute prépare la prochaine apparence de la fenêtre, et la fonction display affiche cette nouvelle image. donc tant que tu n'exécute pas display, ta fenêtre est figée.
Je tenais à tous vous remercier, j'ai beaucoup appris et j'apprend encore beaucoup en parcourant le code. Pour le moment j'avance à mon rythme, mais cela semble assez logique :-).
Encore un grand merci.
NB : Si par hasard certain d'entre vous, qui semble bien connaitre le montage de ce type de code, pouvez m'aiguiller sur l'endroit je peux trouver la gestion des animations. Je veux dire le "morceau" code qui lie le choix d'un fichier animation avec ce qu'il doit mettre à l'écran (pas sûr que je sois très clair, désolé)
Si c'est fait en POO, il y a des chances qu'il existe tout un jeu de classe avec "Animation" dans leur nom qui doivent gérer tout ou partie du bignou.
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
Besoin d'aide sur une programmation existante
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html