home *** CD-ROM | disk | FTP | other *** search
/ ftp.uni-stuttgart.de/pub/systems/acorn/ / Acorn.tar / Acorn / acornet / fun / mags / hl-01-93.arc / !HL-01_93_Text_Text40 < prev    next >
Text File  |  1993-03-24  |  15KB  |  331 lines

  1.  
  2.  
  3.  
  4. ÿÿÿÿÿÿÿÿÿÿ Tips'n'Trix ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
  5.  
  6.  
  7. - Von einem, der auszog, um das Scrollen zu lernen -
  8.  
  9.  
  10. Fⁿr schnelle Actiongames oder saubere Textausgaben ist sie einfach unerlΣ▀lich.
  11. Und auch in so manchem Demo kann man sie gut gebrauchen.
  12.  
  13.  
  14. Die Rede ist natⁿrlich von der ultimativen...
  15.  
  16.  
  17.                        ...Vertikalscroll-Routine !!! 
  18.  
  19.  
  20.  
  21. Herk÷mmliche Scrollroutinen gibt es wie Sand am Meer. Die gebrΣuchlichsten
  22. sind folgende:
  23.  
  24.  
  25.  1) Hardwarescrolling.
  26.  
  27.     Dies ist die Scrollmethode, die am allerwenigsten Rechenzeit beansprucht.
  28.     Das Scrollen erledigt hier nΣmlich der gute, alte Memorychip MemC(1a),
  29.     indem er ein wenig mit seinen drei beschreibbaren Videoregistern (Vinit,
  30.     Vstart und Vend) herumspielt.
  31.  
  32.     Vstart und Vend markieren dabei das gesamte screen memory. Vinit zeigt
  33.     auf die aktuelle Screen-Basisadresse; die Adresse also, ab der der MemC
  34.     den Bildschirmspeicher ausliest.
  35.  
  36.     M÷chte man nun den Bildschirm nach oben scrollen, erh÷ht man einfach den
  37.     Wert in Vinit um die jeweilige Zeilenbreite in Bytes (in Mode 15 wΣren
  38.     das also 640 Bytes). Im nΣchsten Framefly liest nun der MemC diesen 
  39.     modifizierten Wert aus Vinit aus und beginnt, das neue Bild aufzubauen.
  40.     Dieses erscheint um eine Zeile nach oben gescrollt, weil ja die erste
  41.     "Original"-Bildzeile geflissentlich vom MemC ⁿbergangen wird.
  42.     
  43.     Der MemC hat noch ein weiteres Videoregister, das allerdings vom User
  44.     weder gelesen noch beschrieben werden kann: Vptr.
  45.     Vptr zeigt auf das aktuelle quadword (4 W÷rter = 16 Bytes), das gerade vom
  46.     MemC ausgelesen und per DMA an den VidC weitergeleitet wird. Was passiert
  47.     nun, wenn Vptr den Wert von Vend (Ende des Bildschirmspeichers) erreicht ?
  48.     Irgendwas mu▀ ja passieren, denn sonst wⁿrde der MemC flei▀ig 
  49.     Speicherbereiche auslesen, die nix mit Video & Screen zu tun haben !!
  50.  
  51.     Des RΣtsels L÷sung liegt im Vstart-Register. Um es mit BASIC-Befehlen
  52.     auszudrⁿcken:
  53.  
  54.     ...
  55.  
  56.     Vptr=Vptr+16
  57.     IF Vptr>Vend THEN Vptr=Vstart
  58.  
  59.     So lΣuft das natⁿrlich in der RealitΣt nicht ab. WΣre ja noch sch÷ner, wenn
  60.     die Chips fortan in BASIC programmiert wΣren...
  61.     
  62.     Nun, es dⁿrfte jetzt jedem klar sein, da▀ Vptr beim ▄berschreiten des Vend-
  63.     Registers mit dem Inhalt von Vstart geladen wird. 
  64.     Dies bedeutet aber auch, da▀ Vptr den Bereich zwischen Vstart und Vend
  65.     nicht verlassen kann, sondern stΣndig dazwischen ZIRKULIERT. Deshalb
  66.     spricht man im Zusammenhang mit dem Screenmemory auch von einem ZIRKULAREN
  67.     Buffer.
  68.  
  69.     Um den ganzen Kram mit der Hardware zu synchronisieren, wird Vptr mit dem
  70.     Wert aus Vinit geladen, sobald der Elektronenstrahl das untere Ende des
  71.     angezeigten Bildes erreicht.
  72.  
  73.     Angenommen, wir befinden uns in Mode 15 bei einen Bildschirmspeicher der
  74.     Gr÷▀e 160K und erh÷hen Vinit in jedem Vsync um 640 Bytes, ergibt sich ein
  75.     superweiches Hardwarescrolling nach oben. Zur Veranschaulichung befindet
  76.     sich innerhalb der !Hardliner-Applikation im "Examples"-Verzeichnis ein
  77.     kleines Demoprogramm dazu.
  78.  
  79.  
  80.     Der Vorteil dieser Scrollmethode liegt also auf der Hand: Chipscrolling
  81.     verbraucht (fast) keine Prozessorzeit und erm÷glicht sogar in einem
  82.     hochaufl÷senden Modus wie z.B. Mode 28 noch Framerates von 50 oder 60
  83.     Hertz.
  84.     Es gibt aber auch einen gravierenden Nachteil: M÷chte man ⁿber der zu
  85.     scrollenden FlΣche noch etwas bewegen lassen (beispielsweise Sprites),
  86.     kann das ziemlich kompliziert werden, da ja bei jedem Scroll der GESAMTE
  87.     Bildschirm nach oben bewegt wird; also rutschen auch die Sprites beim
  88.     nΣchste Bildschirmaufbau nach oben. Au▀erdem wird der Hintergrund (also
  89.     die ScrollflΣche) nicht "upgedatet", soda▀ bewegte Sprites auf dem Screen
  90.     unsch÷ne Spuren hinterlassen. Letztlich kann man den Hardwarescroll nicht
  91.     - wie auf anderen Computersystemem - auf beliebige Bildschirmbereiche
  92.     beschrΣnken, gescrollt wird immer der gesamte Screen.
  93.     
  94.     Bis auf den letzten Einwand kann man natⁿrlich alle Negativ-Punkte durch
  95.     einigerma▀en geschickte Programmierung abwenden. Und wer beispielsweise
  96.     (wie ich) von einem CPC kommt, wird wissen, wie eifrig Hardscrolling dort
  97.     genutzt wird. Aber wird besitzen schlie▀lich alle einen Archimedes, und
  98.     auf einem solchen 32-Bitter sollte man versuchen, m÷glichst alles ⁿber die
  99.     Software zu erledigen.
  100.  
  101.     Wir kommen also zur nΣchsten Scrollm÷glichkeit, und die nennt sich...
  102.  
  103.  
  104.  
  105.  2.) Softwarescrolling.
  106.  
  107.  
  108.     Hier gibt es zwei verschiedene Scrollarten.
  109.  
  110.     Die erste bietet sich besonders dann an, wenn man nur einen Screen
  111.     reserviert hat. In einem Mode 13-Bild wⁿrde man dann mittels LDM/STM-
  112.     Kommandos die zweite Bildschirmzeile in die erste, die dritte in die
  113.     zweite, die vierte in die dritte, usw. kopieren. Das Resultat wΣre, da▀
  114.     der Bildschirm nach oben gescrollt wⁿrde. Hier gibt es jedoch den gleichen
  115.     Nachteil wie beim Hardwarescrolling: Alles, was sich auf dem Screen
  116.     befindet, wird nach oben geschoben, also auch Sprites, Lines, usw.
  117.     Allerdings kann man hier die ScrollflΣche nach eigenen Belieben bestimmen,
  118.     was eigentlich die Grundvoraussetzung fⁿr eine Scrollroutine ist.
  119.  
  120.  
  121.     Die zweite Softscroll-Variante bietet schon eher eine L÷sung unseres
  122.     Problems. Man arbeitet hier mit einem internen Buffer, der so gro▀
  123.     (manchmal etwas gr÷▀er) als die FlΣche ist, die gescrollt werden soll.
  124.  
  125.     Verschoben wird nur der Buffer, und zwar nach dem Schema, wie man den
  126.     Bildschirm mit der ersten Softscroll-Routine verschiebt. Nachdem man den
  127.     Buffer gescrollt hat, kann man ihn wie eine Grafik behandeln und per
  128.     LDM/STM auf den Bildschirm bringen.
  129.     Diese Routine ist sehr flexibel und programmiererfreundlich, hat aber einen
  130.     Σu▀erst st÷renden Nachteil: Sie kostet Unmengen an kostbarer Prozessorzeit:
  131.     Das Scrollen eines kompletten Mode 13-Screens kann durchaus 80-90% der
  132.     Leistung eines ARM2s ben÷tigen, was fⁿr den 50 Hertz-Fetischisten ganz
  133.     einfach nicht akzeptabel ist.
  134.  
  135.  
  136.     Um es noch einmal zusammenzufassen, hier die Vor- und Nachteile der bisher
  137.     vorgestellten Scrollroutinen:
  138.  
  139.  
  140.     Hardwarescrolling:  -zeitgⁿnstig (wenige Promille der Rechenzeit)
  141.                         -schwierig mit Sprites zu verbinden
  142.                         -gescrollt wird nur kompletter Screen
  143.  
  144.     dir. Softscrolling: -zeitgⁿnstig (2.5-2.7 Taktzyklen pro word)
  145.                         -gescrollt wird beliebiger Ausschnitt
  146.                         -schwierig mit Sprites zu verbinden
  147.  
  148.     indir. Softscrolling: -zeitintensiv (s.o. !!!)
  149.                         -spritefreundlich
  150.                         -gescrollt wird beliebiger Ausschnitt
  151.                         -beansprucht einen (manchmal gro▀en) Buffer 
  152.  
  153.  
  154.     Hm !
  155.  
  156.     Sinnvoll wΣre also eine Routine, die die Vorteile der bisherigen Routinen
  157.     vereint. Die Routine sollte also
  158.  
  159.     - schnell
  160.  
  161.     - flexibel
  162.  
  163.     - und spritefreundlich
  164.  
  165.     sein. Aber das sind ja gleich drei Dinge auf einmal ! Nein, nein, das geht
  166.     nun wirklich nicht...
  167.  
  168.  
  169.     DOCH !
  170.  
  171.     
  172.  
  173.     Und zwar mit dem...
  174.  
  175.  
  176.  3.) Zirkularen Softwarescroll.
  177.  
  178.  
  179.     H÷rt sich bombastisch an, ist aber im Grund ganz einfach.
  180.  
  181.     Die Idee dahinter ist nΣmlich, da▀ wir beim Scrollen gar nicht Scrollen.
  182.     Oder, mit anderen Worten: Das eigentliche Scrollen kostet nur sehr, sehr
  183.     wenige Taktzyklen. Bei einem vollstΣndigen Screenscroll handelt es sich
  184.     um vielleicht 500 oder 600 Zyklen, die aber kaum ins Gewicht fallen.
  185.     Der Haken an der Sache ist nur, da▀ wir die zu scrollende FlΣche in jedem
  186.     Frame neu auf den Bildschirm bringen mⁿssen. Bei gro▀en ScrollflΣchen
  187.     kann das recht arg werden; aber fⁿr normale Zwecke ist die Scrollroutine
  188.     einfach grandios ! Wie gesagt, sie verbraucht ungefΣhr genausoviel Zeit,
  189.     wie das Plotten einer gleichgro▀en FlΣche erfordern wⁿrde (plus die
  190.     erwΣhnten 500 Zyklen). Dafⁿr haben wir haben auch die Garantie, da▀ jede
  191.     beliebige Spriteroutine mit der Scrollroutine zusammenarbeitet, falls man
  192.     so etwas mal brauchen sollte.
  193.  
  194.  
  195.     Um die Routine zu verstehen, solltet Ihr Euch jetzt am besten in die Lage
  196.     des MemC versetzen. Stellt Euch vor, Ihr wΣrd eine Memorycontroller, der
  197.     tagein-tagaus nichts Besseres zu tun hat, als interne Register zu
  198.     verwalten !! Dann dⁿrfte das Folgende absolut kein Problem fⁿr Euch
  199.     darstellen...
  200.  
  201.  
  202.     Also:
  203.  
  204.  
  205.     Prinzipiell Σhnelt der zirkulare Softwarescroll (ZISS) dem oben
  206.     besprochenen Hardwarescrolling. Das Wort "Software" deutet es schon an:
  207.     Wir ben÷tigen diesmal einen internen Buffer. 
  208.  
  209.     Um alles etwas zu vereinfachen, m÷chte ich den ZISS anhand eines konkreten
  210.     Beispiels erlΣutern: Wir m÷chten einen Bereich scrollen, der so gro▀ wie
  211.     ein normaler Mode 13-Screen ist und aus lauter Spritebl÷cken (wie im
  212.     ArcAngels-Megademo) besteht. Die Spritebl÷cke haben die Gr÷▀e 32x32 Pixel.
  213.  
  214.     ZunΣchst legen wir im Memory einen Buffer an, der 320 Bytes breit und
  215.     (256+32)=288 Bytes lang, also 90 KByte gro▀ ist. In ihn passen der
  216.     komplette Bildschirm plus die nΣchste anzuzeigende Spriteblockzeile
  217.     (10 Sprites zu je 32x32 Pixel).
  218.     Der Bildschirm soll bei jedem Vsync um eine Zeile nach oben gescrollt
  219.     werden. Gleichzeitig soll unten eine Zeile eingefⁿgt werden, um eine
  220.     kontinuierliche Grafikbewegung zu simulieren.
  221.  
  222.     Wer beim Hardscroll gut aufgepa▀t hat, dem dⁿrften folgende Vereinbarungen
  223.     gut verstΣndlich sein:
  224.  
  225.     "start" bezeichnet die Startadresse des Buffers
  226.     "ende"  bezeichnet die Adresse des auf den Buffer folgenden Bytes
  227.     "offset" Σhnelt dem Vinit-Register im MemC. offset=0 gibt den Zustand zu
  228.             Beginn des Scrolls an. Nach zehn DurchlΣufen hat offset den
  229.             Wert 10x320(Bufferbreite)=3200, usw.
  230.     "length" gibt die LΣnge des Buffers an, hier also 90 KByte.
  231.  
  232.  
  233.     Schematisch hat die Routine folgenden Aufbau
  234.  
  235.  
  236.     ;.schleife
  237.     ;
  238.     ;Warte auf Vsync
  239.     ;
  240.     ;erh÷he offset um 320
  241.     ;wenn offset>=length, dann offset=offset-length
  242.     ;
  243.     ;fⁿge nach jeweils 32 Vsyncs 10 neue Sprites in den Buffer ein
  244.     ;
  245.     ;plotte den Buffer auf den Screen; als Bufferbeginn zΣhlt start+offset
  246.     ;
  247.     ;B schleife
  248.  
  249.  
  250.     
  251.     Das Wichtigste an der Routine dⁿrfte klar sein: offset wird bei jedem
  252.     Durchlauf um 320 erh÷ht. Sobald offset aber length ⁿberschreitet, wird
  253.     die Operation offset=offset-length durchgefⁿhrt, was quasi eine 
  254.     Zurⁿckstellung von offset auf den Ausgangszustand bedeutet.
  255.  
  256.     Herzstⁿck der Scrollroutine ist das Plotten. Wie man vielleicht schon
  257.     jetzt absehen kann, wird das mit "normalen" Mitteln nicht zu machen sein,
  258.     denn der Beginn des Buffers ergibt sich ja aus start+offset. Wⁿrde man
  259.     jetzt einfach 256 Bytezeilen linear aus dem Buffer in den Screen kopieren,
  260.     wΣre ein Gro▀teil der Ausgabe Grafikschrott.
  261.     Deshalb mu▀ man einen Ausweg finden. Und der ist simpel: Man fragt einfach
  262.     zu Beginn einer jeden Zeile ab, ob die nun auszulesende Adresse gr÷▀er
  263.     als ende ist. Wenn ja, kann man sicher sein, da▀ die Zeile keine Grafik
  264.     mehr enthΣlt, da man ja den Buffer bereits verlassen hat. In diesem Fall
  265.     setzt man die Leseadresse auf den Wert von start und macht ganz cool
  266.     weiter. Irgendwann hat man dann 256 Zeile kopiert und das Ende des
  267.     Screens erreicht.
  268.  
  269.     Wⁿrde man immer nur denselben Buffer durchscrollen lassen wollen, wΣre
  270.     die Arbeit jetzt schon getan. Das Bild wⁿrde bis in alle Ewigkeit oben
  271.     aus dem Screen heraus- und von unten wieder in den Screen hineinscrollen.
  272.     Aber wir wollen ja noch verschiedene Spritebl÷cke einbauen und machen
  273.     deshalb munter weiter.
  274.  
  275.     Wenn wir den Buffer im ungescrollten Zustand betrachten, befinden sich
  276.     unsere Spritebl÷cke ab start+256*320. An diese Adresse mⁿssen wir bei
  277.     Bedarf den Grafiknachschub hinplotten.
  278.     Dies ist bei Berⁿcksichtigung des Scroll-Offsets praktisch genau gleich.
  279.     Wir ermitteln zunΣchst, ob die Adresse start+offset+256*320 gr÷▀er als
  280.     ende ist, sich also au▀erhalb des Buffers befindet. Wenn ja, mⁿssen wir
  281.     von dieser Adresse nur noch length abziehen, und die Welt ist wieder in
  282.     Ordnung. Warum ?
  283.     Nun, unsere Plot-Routine wird wie ⁿblich beginnen, den Buffer ab
  284.     start+offset auszulesen. Sobald sie ende erreicht, wird sie auf den Wert
  285.     von start restauriert, von ihr wird also length abgezogen. Die erste
  286.     Zeile, die sie nicht mehr auf den Screen bringt, ist also genau die Zeile,
  287.     an die wir die Spritebl÷cke kopieren.
  288.  
  289.     Im nΣchsten Durchlauf ist offset um 320 gr÷▀er. Die letzte geplottete Zeile
  290.     entspricht dann der ersten "neuen" Grafikzeile.
  291.  
  292.     Beim Kopieren der neuen Spritebl÷cke in den Scrollbuffer mⁿssen wird
  293.     natⁿrlich genau wie beim Plotten verfahren: Zu Beginn einer jeden Zeile
  294.     wird geprⁿft, ob sich die Ablegeadresse noch innerhalb des Buffers
  295.     befindet. Wenn nicht, wird - wie ⁿblich - length angezogen.
  296.  
  297.     ---------------------------------------------------------------------------
  298.  
  299.     Das ist sie also schon, unsere ultimative Vertikalscroll-Routine. Man
  300.     k÷nnte sie im Nachhinein mit einer unbeweglichen Druckerrolle vergleichen.
  301.     Die OberflΣche dieser Walze wⁿrde dann unseren Scrollbuffer darstellen,
  302.     und der Beginn des Buffer wⁿrde quasi bis in alle Ewigkeit um die Walze
  303.     herumwandern. Die Position, an die wir die Sprites kopieren wⁿrden,
  304.     wΣre dem Bufferbeginn immer ein Stⁿck voraus (dieses "Stⁿck" entsprΣche
  305.     natⁿrlich der LΣnge des Buffers).
  306.  
  307.     Soweit ich wei▀, handelt es sich beim ZISS um die schnellste Scrollroutine
  308.     ⁿberhaupt. Mit gewissen EinschrΣnkungen kann man sie auch auf typische
  309.     Horizontalscroll-Probleme portieren; sie bietet sich beispielsweise bei
  310.     Sinusscrollern an.
  311.  
  312.     Damit das Ganze theoretische Gelabere ein bi▀chen verstΣndlicher wird,
  313.     befindet sich innerhalb der !Hardliner-Applikation im Verzeichnis
  314.     "Examples" ein kleines Beispiel zum ZISS. Schaut es Euch in Ruhe an !
  315.     Auch wenn sich momentan alles noch ein bi▀chen schwammig anh÷rt: ▄bung
  316.     macht den Meister...
  317.      
  318.  
  319.  
  320.                                                               - Tim Juretzky -
  321.  
  322.  
  323.  
  324. PS: Wollt Ihr wissen, warum diesmal ausgerechnet eine Scrollroutine durch-
  325.     gesprochen wurde ? Tja, dann schaut Euch mal den Textscroll an, den Ihr
  326.     da vor Euch seht ! Supersmooth, isn't it ? Waschechter ZISS, wⁿrde ich
  327.     sagen... Die Entwicklungsversionen des "Hardliners" hatten noch eine
  328.     andere Scrollroutine. Da diese aber ohne Ende ruckelte, zuckelte und
  329.     flackerte, mu▀te Abhilfe geschaffen werden. Das Ergebnis seht Ihr hier...
  330.     
  331.