Dafyd a écritEt ben... plus de codeurs sur ce forum ?
Si, si !
Un exemple en C89 (toolkit MSVC, Win32 x86, Pentium II ou ultérieur requis car j'aime prendre en charge aussi les vieux coucous sous Windows XP) (j'ai pas tout écrit, c'est un fork) :
Windows Multimedia CD Audio OGG player wrapper, un wrapper pour le sous-ensemble de l'API WinMM (API héritée de l'ère Windows 3.X/9.X pour le multimédia dans Windows) concernant la lecture des musiques CD à l'aide du
périphérique MCI pour les CD audio.
Permet d'avoir les musiques CD sans le CD, et de corriger souvent l'usage de l'API WinMM (le jeu ne prévoyait pas la répétition des musiques, par exemple. Ou il mettait le volume du son à 0 donc pas de musique. Ou il ne détecte pas de CD à l'aide du vrai WinMM, et n'envoie pas de commandes pour lire la musique... Bon là je modifie le comportement de l'exe du jeu avec OllyDbg pour qu'il passe outre, et pas le wrapper).
Un des derniers développements fut la prise en charge de
mciSendStringA (la version ANSI et basé sur des chaînes de caractères de
mciSendCommand). Au menu : reconnaissance de tokens, parsing, le tout avec les version sécurisées de
strtok et consorts. Bon c'est une adaptation/modification d'un patch existant, mais ça a permis de prendre en charge les rares jeux utilisant mciSendStringA, tel que le port PC de
The House of the Dead.
Ça a l'air plus suivi que les autres développements (tous arrêtés ou presque) de Ogg-Winmm sur GitHub, et ça c'est cool.
* Une star (surveillance ? Je sais toujours pas trop ce que c'est !) par juanitogan, l'auteur de plein de
fan-patchs super avancées sur des jeux Sierra (de la rétro-ingénierie de dingue)
* Un premier fork de mon fork il y a quelques jours (identique pour le moment)
* Une demande de support pour le jeu DOS/Windows (deux versions sur le CD, comme ça se faisait souvent à l'époque)
Ignition reçue à l'instant par mail. On dirait un autre cas rare d'un jeu développé par des gens qui se haïssent (ils utilisent mciSendString plutôt que son équivalent "binaire" mciSendCommand)
Autre exemple en Delphi 1 (un fork là aussi) :
RUNEXITW
Contexte :
Quand on automatise un jeu Windows 3 (qui peut être 16 bit, ou 32 bit à l'aide de
Win32s), on veut pouvoir 1.le lancer, 2.Quitter Windows dès que jeu a fini (ce qui ferme DOSBox). Or, pas mal de jeux utilise un exécutable qui ne fait que lancer un autre exécutable avant de quitter. Il faut alors changer de stratégie : 1.Lancer l'exe, 2.Chercher une fenêtre, 3.Attendre que la fenêtre ne soit plus avant de quitter Windows.
Bon rien de super compliqué, à part se taper Delphi 1, l' "IDE" qui va avec, le tout dans DOSBox, et le peu de l'API Win16 auquel on a accès pour atteindre l'objectif (seule route : D'abord ShellExecute, ensuite WindowFromPoint, IsWIndow, ExitWindows, et puis c'est tout)
Dernier exemple (Win32s, C89, Microsoft VIsual C++ 4.1 de juin 1996) :
J'avais appelé ce projet "
RUNCOLD". 30 lignes de code tout mouillé, mais chaque ligne n'est pas là sans raison. C'est intégré à la version automatique de
Donald In Cold Shadow, apparue hier avec la fiche.
Adapté quelque peu plus tard pour la version automatique de
The Amazon Trail
En gros :
- J'avais besoin que le jeu s'exécute dès le départ en plein-écran. Impossible de le modifier avec OllyDbg, car le jeu utilise une bibliothèque qui utilise des API non-documentées du kernel Windows 3.X/9.X (le jeu est compatible Windows 3.X et 95/98 et cible ces deux versions de Windows) pour remplacer entièrement
GDI, chose qui d'ailleurs ne fonctionne pas sur d'autres Windows. Enfin, modifier le jeu pour le mettre en plein-écran via ce biais était pas impossible, mais ça plantait...
- On est en 32 bit car j'avais besoin d'utiliser PostMessageA, et même si sous Windows 3.X tout se passe dans le même espace d'adressage, ça ne permet pas d'aller poster un message sur la boucle des appels d'une fenêtre Win32 depuis une application Win16. Donc impossible d'adapter RUNEXITW. Apparemment, le
thunking ça ne marche que dans un sens (code 32 bit vers code 16 bit), ou quelque chose comme ça. En tout cas, rien n'y faisait.
- On s'exécute là aussi dans DOSBox + Windows 3.11, mais on est 32 bit grâce à Win32s
- Microsoft Visual C++ 4.1 (même pas l'antédiluvien MSVC++ 6 !) est le dernier IDE de MS à prendre en charge Win32s. Fonctionne toujours parfaitement sous Windows 10 ! Pour la gestion des sources (perdues depuis), j'utilisais tout de même git.
- Processus du programme :
* CreateProcessA (avec chemin en dur, car dans l'environnement émulé, ce sera toujours C:\DISNEY\CLDSHADW\CLDSHADW.EXE le chemin. Gestion des strings en C évité. :p )
* WaitForInputIdle (on attend que la fenêtre existe, et soit prête à recevoir des messages)
* FindWindow (recherche de la fenêtre du jeu à l'aide de sa
classe spécifique. Pas moyen d'avoir la mauvaise fenêtre, dans l'environnement émulé, à part le gestionnaire de programmes, seul le jeu a une fenêtre. Nom de la classe définie par le jeu découverte grâce à OllyDbg)
* SetForegroundWindow (on la met au premier plan)
* SetActiveWindow (pour pouvoir la rendre active)
* PostMessageA (pour pouvoir lui envoyer un message, simulant l'usage de l'entrée Fullscreen du menu Screen). Cet entrée porte un ID. Il est interne, mais a été découvert grâce à
Resource Hacker, le dialogue décrivant les menus de la fenêtre étant une ressource de l'exécutable)
* On attend que la fenêtre n'existe plus avant de quitter (polling avec FindWindow + Sleep. Il est recommandé d’utiliser plutôt WaitForSingleObject, mais ça n'a jamais voulu fonctionner).
Pour déboguer ça, il faut lancer DOSBox, Windows 3.11, et lancer notre programme depuis DOSBox. C'est pas instantané, et la moindre erreur résulte en une General Protection Fault ou autre message inexploitable. 😃
Alors y'a une modif de l'exe du jeu sur Old-Games.Ru pour qu'il utilise autrement
WinDirect (la bibliothèque qui remplace GDI) et s'exécute nativement. Mais on perd le mode plein-écran, et le jeu s'exécute toujours par défaut dans une toute petite fenêtre en 320x200. Au mieux en 640x400 en allant dans le menu Screen. Sur un écran HD, c'est pas très lisible.
En gardant DOSBox, on garde la compatibilité avec les manettes modernes (important pour un jeu de plateformes), la possibilité d'utiliser des scalers (HQ2X, HQ3X, Super2xSAI ...), la pérennité de la solution quel que soit la variante de Windows, et le mode plein-écran. On peut aussi utiliser une variante de DOSBox pour Linux, OS/2, ou autre. Et WinDirect peut toujours remplacer GDI avec ses appels à des fonctions non-documentées du kernel Windows de l'ère 16 bit s'il veut.
Le jeu est maintenant en plein-écran dans l'émulateur, comme les versions SNES ou Megadrive, au lieu d'être dans une fenêtre en 320x200 dans la fenêtre par défaut en 640x480 de DOSBox. Non mais oh ! Et les commits sur le SVN de DOSBox évoque la prise en charge des écrans HiDPI...
Le mode plein-écran est aussi le seul mode du jeu où le scrolling est parfait (pas de déchirures lors des mouvements). Là encore, comme sur les versions console. Et au contraire des versions console, le port PC bénéficie de musiques CD.
Enfin, tout ça, c'est pour les versions automatiques d'Abandonware France, auxquelles je participe beaucoup depuis des années.
Rien de super compliqué (j'en suis pas encore à écrire mon propre wrapper DirectDraw/Glide/OpenGl/Direct3D - et heureusement pour mes cheveux ! -, pour ça je m'appuie sur ddrawCompat ou dgVoodoo2, voire l'Application Compatibility Toolkit qui permet d'activer des
shims avancées du genre ForceDirectDrawEmulation), mais je m'amuse beaucoup.
Et sinon, DOSBox v0.75 va sortir ! (la v0.74 a 8 ans déjà !) \o/
Voilà, je retourne dans ma grotte.