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

Contribuez Pascal Discussion :

Demo style "old-school"


Sujet :

Contribuez Pascal

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 30
    Points : 19
    Points
    19
    Par défaut Demo style "old-school"
    Bonsoir à tous

    tout d'abord je suis agréablement surpris de voir qu'il existe encore des gens utilisant l'environnement Borland pour programmer en Pascal.

    Même si évidemment ça ne sert plus à grand chose d'utiliser cet environnement, je ne peux l'oublier car il m'a fait connaître un vrai langage ... à l'époque j'avais commencé avec Turbo-Pascal 5.0 ...

    Donc je me propose de vous faire partager une petite démo que j'ai récemment fini, en Turbo-Pascal 7.0 ... n'utilisant pas la biblitothéque GRAPH.TPU car j'avais besoins de routines ciblées et rapides.

    Donc tous les calculs, sont faits en Pascal, j'utilise juste une routine assembleur pour la synchro. écran et pour allumer l'écran graphique ...

    juste l'unit CRT pour lire le clavier, sinon le reste c'est du Pascal pure puisque j'accéde directement à la mémoire vidéo.

    Voilà ... bon visionnage et bonne nostalgie

    http://membres.multimania.fr/powel/DOS_16_bits/NOST.EXE

  2. #2
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Super sympa, ca rappelle des très bons souvenirs !!

    Si tu en as envie, tu peux partager la source des ton (tes) programme(s) sur ce site

    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 30
    Points : 19
    Points
    19
    Par défaut
    Salut et merci pour ta réponse

    j'espère que ça a fait revivre de vieux souvenirs.

    Si ce topic suscite plus d'intérêt ça me fera plaisir de poster le source et de le partager avec vous histoire qu'on discute sur la manière plus optimale de faire telle ou telle chose.

  4. #4
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    HAAAA MY EYES!

    bien joué, une petite dentro bien sympa, dommage il manque un petit mod en fond histoire de.

    attention par contre, le texte semble défilé plus ou moins vite sur certaines machine ce qui donne mal au yeux au bout d'un moment ... trop de texte.

    faut la poster sur Pouet.net

    si tu veux y ajouter un petit mp3 style chiptune fait moi signe.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  5. #5
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    7 938
    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 938
    Points : 59 416
    Points
    59 416
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par powel Voir le message
    Si ce topic suscite plus d'intérêt ça me fera plaisir de poster le source et de le partager avec vous histoire qu'on discute sur la manière plus optimale de faire telle ou telle chose.
    Oh oui !
    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
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 30
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Dr.Who Voir le message
    HAAAA MY EYES!

    bien joué, une petite dentro bien sympa, dommage il manque un petit mod en fond histoire de.

    attention par contre, le texte semble défilé plus ou moins vite sur certaines machine ce qui donne mal au yeux au bout d'un moment ... trop de texte.

    faut la poster sur Pouet.net

    si tu veux y ajouter un petit mp3 style chiptune fait moi signe.
    Merci pour le qualificatif "Dentro", car il me semble qu'une Intro ne doit pas dépasser 64 K
    Merci bien d'avoir essayé sur plusieurs machines peux-tu me dire lesquelles étaient-ce ?

    Normalement le scroll text ainsi que tous les autres déplacement sont synchronisés avec la fin du balayage vertical, ce qui veut dire que les déplacements doivent être parfaits !... et ne doivent pas faire mal aux yeux. Mais ça veut dire que j'ai pas pris en compte toutes les différences des matériels existant

    Je viens de jeter un oeil sur Pouet.net, je vais la poster aussi la bas ... merci

    J'avais pensé à une musique en utilisant "sound" de Pascal ... mais tu me surprends, donc il est tout à fait facile d'implementer une musique en mp3 ou mod avec Turbo-Pascal Borland ? si t'as des bouts de codes utilisant le MP3 ou MOD je veux bien y jeter un oeil. Curieux de voir ça. Car je ne connais pas l'utilisation des ports concernant la carte son ... pour l'instant j'ai pas vraiment la foi pour revenir en arrière et améliorer la demo mais pourquoi pas dans une prochaine .... et l'algo. pour décompresser le MP3, s'il existe en Pascal, ça m'intéresse.

    Citation Envoyé par Alcatîz Voir le message
    Oh oui !
    Sinon pour discutailler bouts de ... code ... voici une des parties essentielles, l'affichage des "sprites" ...
    L'affichage d'une image sur l'écran consiste à copier les octets de l'image à partir d'une zone mémoire vers la mémoire de la carte graphique.
    Ensuite on affiche l'image sur l'endroit d'à côté et ainsi de suite on voit une image se déplacer, ce qui est je crois un Sprite.

    Je ne voulais pas de GRAPH.TPU pour l'affichage des images, pour plusieurs raisons :
    - beaucoup trop lent PutImage, ça aurai été impossible de réaliser cette DEMO.
    - le PutImage de GRAPH.TPU n'affiche pas du tout l'image, lorsque celle-ci ne déborde que d'un pixel en dehors de l'écran, et c'était pas acceptable pour ce que j'avais à faire
    - je voulais pas de fichier externe (GRAPH.TPU), et j'avais pas besoin de toutes ses fonctionnalités
    - je voulais un code éventuellement adaptable en Assembleur pour rester dans le ton d'une DEMO et l'utilisation des bibliothéques ne me plaisait pas

    Ils ont pourtant pensé à tout avec PutImage et GetImage, même l'utilisation de XOR, OR, etc ... mais l'explication de la lenteur vient probablement du fait qu'ils doivent appeler leur routine PutPixel ... ce qui est naturel, mais pas optimal. Voilà la structure d'une Image EGA qu'ils ont utilisé.

    Sans entrer dans les détails, une image EGA (16 couleurs) fonctionne en "BitPlan". Par exemple pour afficher une image de 640 x 350 x 16 couleurs, il faut fournir à la mémoire video de la carte graphique, 4 images monochromes d'une résolution de 640 x 350 pixels. J'entends par monochrome qu'un pixel ne peut prendre que deux états (Blanc ou Noir par exemple).
    La carte graphique va en interne "superposer" ces 4 images monochromes pour afficher à l'écran une image de 16 couleurs. Principe qu'utilise par exemple l'AMIGA.

    Le premier pixel de l'image monochrome BitPlan0, BitPlan1, BitPlan2 & BitPlan3 peuvent prendre 0 ou 1 donc en les associant on a par exemple :
    0101 ce qui donnera pour le premier pixel visible sur l'écran une couleur de valeur 5 en décimale. Donc 4 bits on a bien 16 couleurs possibles. Il en va de même pour tous les autres pixels.

    Voilà comment GRAPH.TPU stock ça dans la mémoire dynamique :
    la première rangée d'octets, c'est la première ligne du bitplan3 (exemple : une image de 640 pixels de large = 80 octets puisque 8 points monochromes par octet)
    la deuxième rangée d'octets, c'est la première ligne du bitplan2
    la troisieme rangée d'octets, c'est la première ligne de bitplan1
    la quatrieme rangée d'octets, c'est la première ligne du bitplan0

    la cinquieme rangée d'octers, c'est la deuxième ligne du bitplan3
    la sixieme rangée d'octers, c'est la deuxième ligne du bitplan2
    la septieme rangée d'octers, c'est la deuxième ligne du bitplan1
    la huitieme rangée d'octers, c'est la deuxième ligne du bitplan0

    etc ...

    Ce qui veut dire qu'ils fusionnent dans la mémoire de stockage de l'image, les 4 bits plans. Et comme GetImage requiert un pointeur, vous savez comme moi qu'on ne peut pas allouer plus de 65528 octets en un seul bloc.
    Donc cela limite une image 16 couleurs à environ 640 x 200 (64000 octets).

    Pour pouvoir utiliser le maximum de mémoire dynamique tout en restant compatible avec les fonctions de gestion mémoire fournis par l'UNIT SYSTEM, j'ai décidé de faire autrement.

    C'est simple, chaque BitPlan (de 0 à 3) se réserve son bloc mémoire dynamique. Autrement dit un BitPlan (donc une image monochrome), de 60 000 octets pourrai être de 800 x 600 x 2 couleurs. Et donc les 4 bitplans forment une image de 800 x 600 x 16 couleurs, stockable en mémoire dynamique.

    Donc sans être obligé de me refaire une gestion mémoire pour dépasser la limitation 64K, j'arrive en utilisant la spécificité du BitPlan à stocker par exemple un paysage de 800 x 600 x 16 couleurs.

    J'utilise aussi le côté objet de Pascal ; j'instancie une classe "Image16" ce qui me donne un objet dans lequel je stock l'image. Quand je veux afficher cet objet, j'écris simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    paysage.disp (0, 0);				 
    arbre.disp (30, 30); 
    montagne.disp (-50, 200);
    etc ...
    Voici donc la classe "Image16" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    const planMaxSize = 60000;
    var screenH, screenV : word;
     
    type
     Plan = array [0..planMaxSize-1] of byte;	
     
     Image16 = object			   	
      h, v : word;	
      bitmap : array [0..3] of ^Plan;       
      procedure disp (x, y : integer);	
     end;
    Les variables "screenH", "screenV" contiennent les dimensions actuelles de l'écran, car en EGA on peut passer aussi en 320 x 200.
    Le type "Plan" est comme je l'explique plus haut, un tableau de 60000 octets contenant un des 4 BitPlan d'une image 16 couleurs.
    "bitmap" est un tableau de 4 pointeurs. Chaque pointeur indique des données structurées façon "Plan".
    "Disp" affiche l'image en copiant depuis les données "Plan" vers la mémoire de la carte graphique EGA.

    Définition de la méthode "disp" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure Image16.disp (x, y : integer);		
     
    var x2, y2, h2, v2, source, target, srcStep, tarStep, i : word;
    begin
    x & y -> coordonnées de l'image. Type Integer volontairement choisi à la place de Word permettant à l'utilisateur de faire déborder l'image exemple : -30, -100
    x2 & y2 -> coordonnées de la zone mémoire qui différent de x et y lorsque l'image à afficher déborde de l'écran ; il est inutile de lire les octets qu'on affiche pas !
    h2 & v2 -> dimensions de la zone mémoire qui différent de h et v lorsque l'image à afficher déborde de l'écran ; il est inutile de lire les octets qu'on affiche pas !
    autrement dit x2, y2, h2, v2 existent en plus de x, y, h, v car il y a découpage de l'image en cas de débordement ... et oui c'est jamais simple la programmation bas niveau
    h2 contiendra le nombre d'octets d'une ligne découpée à copier
    v2 contiendra le nombre de lignes à copier en écartant les lignes invisibles

    source -> dans la zone mémoire où est stockée l'image, numéro du premier octet à lire
    target -> dans la zone mémoire de la carte graphique, numéro du premier octet à écrire
    srcStep -> lorsque l'on a fini de copier la première ligne de l'image, source est incrementée avec "srcStep"
    tarStep -> lorsque l'on a fini de copier la première ligne de l'image, target est incrementée avec "tarStep"
    n'oublions pas que srcStep et tarStep sont évidemmenent différents, car dans la zone source après une longueur de ligne, l'autre ligne se trouve juste après, alors que dans la zone graphique la ligne suivante se trouve (ScreenH / 8) octets après. Tout ça évite d'effectuer les mêmes multiplications entre chaque copie de ligne de l'image pour gratter du temps CPU.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (x >= screenH) or (y >= screenV) or (x + h < 1) or (y + v < 1) then exit;
    si l'image déborde totalement de l'écran, pas la peine de continuer plus loin puisqu'on affiche rien.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    h2 := screenH - x; if h2 > h then h2 := h;
    calcul de h2 : si screenH - x > largeur initiale de l'image alors pas de débordement et h2 = h sinon h2 prendra une plus petite valeure puisque découpage



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     v2 := screenV - y; if v2 > v then v2 := v;
    calcul de v2 : même principe que pour h2



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    x2 := 0; if x < 0 then begin x := -((abs(x + 1) shr 3 + 1) shl 3); dec (x2, x); inc (h2, x); x := 0; end;
    Calcul de x2. En cas de débordement horizontal gauche ; x := -((abs(x + 1) shr 3 + 1) shl 3); dec (x2, x); inc (h2, x); x := 0;
    il n'est donc utile de lire l'image dans la zone de stockage qu'à PARTIR DE l'ENDROIT VISIBLE d'où le x := - abs (x) <-- si x = - 30, on lit à partir du 30 ème pixel.
    dec (x2, x); comme x est négatif la decrementation se transforme en incrementation et x2 se trouve incrementé de 30. x = 0 car si l'image déborde à gauche, on commence par écrire les pixels à partir de 0.
    shr 3 est équivalent à div / 8 ... traduit en assembleur par un pur shr 3, donc gain de temps
    shl 3 est équivalent à mul * 8 ... traduit en assembleur par un pur shl 3, donc gain de temps


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    y2 := 0; if y < 0 then begin dec (y2, y); inc (v2, y); y := 0; end;
    calcul de y2. En cas de débordement vertical haut ; même procédé que pour x2.


    conversion pixels en octets exemple : 640 -> 80
    par exemple si l'utilisateur veut afficher une image à partir de la position -8 horizontale. Et bien inutile de lire le premier octet, puisqu'il est invisible
    1 octet = 8 points . D'où l'utilité de garder x2 et x et tous ces calculs ! il en va de même pour le vertical
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    srcStep := h       shr 3; source := x2 shr 3 + y2 * srcStep; 
    tarStep := screenH shr 3; target := x  shr 3 + y  * tarStep;
    OUF !... toutes les valeurs sont prêtes, il n'y a plus qu'à lancer la boucle qui copie les lignes. Cette boucle sera répété 4 fois pour les bitplans de 0 à 3 ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     for i := 0 to 3 do begin
      port [$3C5] := 1 shl i;
      rowsCopy (bitmap[i]^[source], mem[40960:target], srcStep, tarStep, h2, v2);
     end;
    end;
    port [$3C5] := 1 shl i;
    indique à la carte EGA quel BitPlan attaquer : 1, 2, 4, 8 pour dire 0, 1, 2, d'où le shl.


    "disp" utilise une procedure "rowsCopy" qui copie des rangées d'octets, directement utile pour l'affichage d'une image on remarque l'utilisation de "move" et aucune multiplication à l'intérieur de la boucle, afin de gratter du temps CPU
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    procedure rowsCopy (var source, target : array of byte; srcStep, tarStep, rowSize, rowNumber : word);
    var s, t : word;
    begin
     s := 0;
     t := 0;
     while (rowNumber > 0) do begin
      move (source[s], target[t], rowSize);
      inc (s, srcStep);
      inc (t, tarStep);
      dec (rowNumber);
     end;
    end;
    Il est clair qu'à le relecture de mon code, tout me parait compliqué et pourtant pour gérer les cas de débordement de l'image, ne copier que les octets utiles et qu'aucun calcul ne soit fait à l'intérieur des boucles pour un temps d'execution optimal ... il faut ce qu'il faut.

    En tous cas bravo si vous avez eu le courage de tout lire et si vous avez tout compris
    Fichiers attachés Fichiers attachés

  7. #7
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Très intéressant, je connaissais pas l'histoire du port [$3C5]... Vais jeter un oeil ce soir...
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  8. #8
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    ah oui c'est du TP haha
    alors a moins d'utiliser la lib Ogg ou lameMp3 ou même bass. pas moyen de faire autrement.
    ce qui du coups est moins simple.
    aprés y'a des petites lib pour lire les MOD et XM, sur torry's je crois.
    mais j'ai pas la motivation pour retourner sur ModPlug

    pour le PC : c'est un HP pavilion zv6000 en 60hz rR. pas une bete de course quoi.
    ou alors ce sont mes yeux qui n'ont pas supporter ... tout simplement.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 30
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par wormful_sickfoot Voir le message
    Très intéressant, je connaissais pas l'histoire du port [$3C5]... Vais jeter un oeil ce soir...
    oui mais attention il faut d'abord lui dire de passer en mode "X"
    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
    26
     
    asm
     mov ax, 16     { choix du mode EGA 640 x 350 x 16 }
     int 16
     port [$3C4] := 2; { passage en mode "X" pour pouvoir accéder aux bitplans }
     
     port [$3C5] := 1;
     
     { modification du bitplan 0 }
     
     port [$3C5] := 2;
     
     { modification du bitplan 1 }
     
     port [$3C5] := 4;
     
     { modification du bitplan 2 }
     
     port [$3C5] := 8;
     { modification du bitplan 3 }
     
     port [$3C5] := 15;
     { modification simultanément des bitplans 0, 1, 2 et 3 }
     { autrement dit les octets qu'on écrira ici apparaitront en blanc clair }
     { qui correspond à la couleur 15 de la couleur IBM PC ou EGA par défaut }
    end;

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 30
    Points : 19
    Points
    19
    Par défaut Changement URL
    Bonjour à tous,

    un an après je reviens avec un prétexte pour remonter le topic
    L'URL de la démo a changé :
    http://caltronik.pagesperso-orange.f...80286/NOST.EXE


Discussions similaires

  1. Conseils pour re-développer une application "old school"
    Par delphi5user dans le forum Delphi
    Réponses: 1
    Dernier message: 10/07/2006, 17h53
  2. [old-school] Les disquettes 5 pouces ¼...
    Par MasterOfChakhaL dans le forum Composants
    Réponses: 9
    Dernier message: 09/01/2006, 12h40

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