Bonjour,
Pour m'amuser, je développe depuis quelques années un cheater sous DOS en mode texte. Le programme se compose principalement d'une liste de jeux ou du texte que l'utilisateur fait défiler. J'utilisais les fonctions de base de Turbo Pascal (version 7) pour écrire et rafraîchir l'écran ("write" et "clrscr"). Celles-ci étaient suffisantes jusqu'à ce que je veuille implémenter une nouvelle fonction: avoir en fond d'écran, non pas une seule couleur, mais une image composée par différentes couleurs.
J'ai implémenté la fonction, mais le rafraîchissement de l'écran est devenu beaucoup trop lent avec les fonctions de base. J'ai pu très légèrement amélioré le problème en écrivant directement dans la mémoire vidéo grâce à un algorithme trouvé dans la base de données SWAG, mais c'est très loin d'être satisfaisant. Ne connaissant pas du tout le fonctionnement de l'adressage direct en mémoire pour utiliser l'écran, je ne sais pas quoi faire (pour l'instant, j'essaye de me débrouiller comme je peux).
Le fonctionnement de mon programme lié au rafraîchissement est très simple et est certainement la base de ce problème: l'écran s'affiche et attend une action de l'utilisateur. Une fois celle-ci reçue, le programme la traite, puis réaffiche la partie de l'écran qui a été modifiée (généralement presque tout l'écran).
J'imagine que plutôt que de réafficher à chaque fois presque tout l'écran, je ne devrais réafficher que ce qui a été modifié (en capturant et restaurant la partie de l'écran en question?), mais cela me semble bien compliqué.
J'ai mis le programme (exécutable) ici pour que vous puissiez vous rendre compte de ce que ça donne:
http://users.skynet.be/fa224292/tuc.zip
(Attention, je n'ai copié que le nécessaire! Les données du programme sont absentes sur ce lien). Remarque: vu que je suis en train de modifier le code source d'affichage du programme, tout n'est pas encore réglé et le menu Painter déconne un peu beaucoup pour l'instant...
Pour activer/désactiver le "mode image", faire SHIFT+TAB.
Brièvement, pour comprendre ce qui se passe:
- affichage de tout l'écran;
- le programme dessine l'image de fond;
- l'utilisateur appuie sur la flèche du bas pour descendre dans la liste;
- le programme réaffiche _toute_ la liste (bien que seulement deux lignes aient été modifiées par l'action de l'utilisateur);
- le programme dessine l'image de fond;
- etc.
Une chose que j'ai remarqué: quand j'affiche l'image de fond et que j'essaie de savoir la couleur de l'écran en x,y celle-ci ne correspond jamais à la couleur visible à l'écran, mais à la couleur par défaut du fond d'écran. Exemple: en position x/y (25,18), la couleur affichée est "vert" et la couleur renvoyée est "bleu" (= la couleur par défaut de l'écran).
La solution idéale la plus simple serait peut-être qu'une fois l'image de fond affichée, le programme puisse écrire des caractères sans changer la couleur de fond d'écran (ce que je n'arrive pas à faire puisqu'ici, chaque caractère est écrit sur fond bleu qui est la couleur par défaut).
Voilà, j'espère avoir été plus ou moins clair et quelqu'un pourra m'aider d'une façon ou d'une autre.
Un grand merci pour votre patience et votre temps!
Ponytear
PS: Ci-après, la fonction "fastwrite" de SWAG que j'utilise (pour l'instant) pour afficher le texte à l'écran et la fonction "draw_picture" que j'utilise pour afficher l'image de fond (basée sur SWAG aussi).
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 procedure fastwrite(x, y, f, b: byte; s : STRING); { Does a direct video write -- extremely fast. X, Y = screen location of first byte; S = string to display; F = foreground color; B = background color. } type videolocation=record { the layout of a two-byte video location } videodata: char; { character displayed } videoattribute: byte; { attributes } end; var cnter: byte; videosegment: word; { the location of video memory } monosystem: boolean; { mono vs. color } vidptr: ^videolocation; { pointer to video locations } Begin videosegment := $b800; vidptr:=ptr(videosegment,2*(80*(y-1)+(x-1))); for cnter:=1 to length(s) do Begin vidptr^.videoattribute:=(b shl 4)+f; vidptr^.videodata:=s[cnter]; { put character at location } inc(vidptr); { go to next video location } End; End;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 procedure draw_picture; {remarque: picture[] est le tableau qui contient mon image} var i:word; Begin for i:=0 to 3999 do If Odd(i) then Mem[$b800:i]:=(Mem[$b800:i] and 15) or ((picture[i] and 15) shl 4); End;
Partager