IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Turbo Pascal Discussion :

[TP]Optimiser le rafraîchissement de l'écran en mode texte?


Sujet :

Turbo Pascal

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2004
    Messages : 5
    Points : 1
    Points
    1
    Par défaut [TP]Optimiser le rafraîchissement de l'écran en mode texte?
    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;

  2. #2
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2004
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Finalement, en cherchant ces dernières heures, j'ai presque résolu mon problème et j'ai réussi à supprimer ces rafraîchissements intempestifs.

    Si quelqu'un sait comment intégrer l'image de fond dans la résolution 80*50, pourrait-il me l'expliquer? J'imagine que ce n'est pas très compliqué et qu'il suffit de modifier quelque peu la procédure "draw_picture".

    Voilà, un grand merci...

  3. #3
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    7 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2003
    Messages : 7 944
    Points : 59 430
    Points
    59 430
    Billets dans le blog
    2
    Par défaut
    Bonjour !

    Pour passer en mode 80*50, tu dois sélectionner une matrice de caractères 8*8 à l'aide de la sous-fonction 12h de la fonction 11h de l'interruption 10h.

    L'adressage d'un caractère particuler en RAM vidéo n'est pas plus compliqué qu'en mode 80*25. Où se situe ton problème ?
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
    La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]

  4. #4
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2004
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    "L'adressage d'un caractère particuler en RAM vidéo n'est pas plus compliqué qu'en mode 80*25. Où se situe ton problème ?"

    Ne sachant pas comment marche l'adressage direct, quand je passe en mode 80*50, mon image de fond n'est affichée quand dans la moitié supérieure de l'écran et il n'y a rien dans la moitié inférieure. J'ai bien essayé de faire quelques changements au code trouvé dans SWAG (qui marche très bien pour le 80*25), mais je n'arrive à rien (ce qui est un peu normal puisque je ne sais pas comment ça marche!).

    Voici le code source de SWAG qui marche très bien pour le mode 80*25:

    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);

    Que faut-il changer pour ça marche correctement en 80*50? Et pourquoi faut-il la condition Odd(i) pour afficher la couleur?

    Un grand merci, en tout cas! Je vais essayer de comprendre cette histoire d'interruption (une notion qui manque malheureusement à ma connaissance).

  5. #5
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    7 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2003
    Messages : 7 944
    Points : 59 430
    Points
    59 430
    Billets dans le blog
    2
    Par défaut
    Dans la RAM vidéo, les caractères sont codés sur 2 octets : un pour le code ASCII et l'autre pour l'attribut.
    Les attributs se trouvant aux adresses impaires, cela explique le test Odd().

    En mode 80*50, ta boucle ne doit pas s'arrêter à 4000 itérations mais doit aller jusqu'à 8000 (vu qu'il y a deux fois plus de caractères sur 50 lignes que sur 25) ! Cela explique que tu n'as qu'un demi-écran.
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
    La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]

  6. #6
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2004
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    >Les attributs se trouvant aux adresses impaires, cela explique le test Odd().

    Ok, merci!

    >En mode 80*50, ta boucle ne doit pas s'arrêter à 4000 itérations mais doit >aller jusqu'à 8000

    Etrange, il me semblait que j'avais essayé ça, mais que ça n'avait pas marché. J'ai sûrement dû faire une autre erreur. Je réessaierai en faisant plus attention! [/quote]

  7. #7
    Membre expert
    Avatar de Eric Sigoillot
    Inscrit en
    Mars 2002
    Messages
    1 212
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 212
    Points : 3 369
    Points
    3 369
    Par défaut
    Tu devrais utiliser un tableau en absolute, ça te simplifierait la vie...

    Fait comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    type
      TScreenChar = record
        Ch: Char;
        Color: Byte;
      end;
     
      TScreen: array[1..50, 1..80] of TScreenChar;
     
    var
      Screen: TScreen absolute $B800:$0000;
    Comme ça, tu peux accéder directement à l'écran, et sans te casser la tête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Screen[5, 5].Ch := 'A';
    A noter que la mémoire vidéo est plus large que ce que tu peux apercevoir à l'écran. Donc une solution pourrait consister à écrire en mémoire sur une écran "caché" (après les 8000 octets visibles) puis à le recopier rapidement en affichage visible dans les 8000 premiers octets avec Move.

    A+
    Règles du forum
    F.A.Q Pascal

    Pour me joindre (aucune question technique, merci)

  8. #8
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2004
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Merci beaucoup pour ces explications! C'est en effet beaucoup plus simple...

  9. #9
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    7 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2003
    Messages : 7 944
    Points : 59 430
    Points
    59 430
    Billets dans le blog
    2
    Par défaut
    Et pour poursuivre l'idée de HDD34, tu peux jouer avec plusieurs pages d'écran et commuter entre elles.
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
    La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]

Discussions similaires

  1. Optimisation de votre SGBDR et de vos requêtes...
    Par SQLpro dans le forum Langage SQL
    Réponses: 35
    Dernier message: 11/01/2013, 11h49
  2. Réponses: 0
    Dernier message: 02/04/2010, 09h09
  3. [VB6] [BDD] Optimisation de l'accès aux données
    Par LadyArwen dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 30/01/2003, 13h27
  4. [langage]Problème de temps de lecture, optimisation
    Par And_the_problem_is dans le forum Langage
    Réponses: 2
    Dernier message: 08/01/2003, 08h47
  5. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    Réponses: 2
    Dernier message: 11/06/2002, 10h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo