*
* Ein IFF-Bild mit Spezialeffekten ... Nummer 2
*
* created on 16/12/89 20:30:31 by Holger Gzella
*

                incdir "asm:"
                include "exec/exec_lib.i"
                include "graphics/graphics_lib.i"
                include "intuition/intuition_lib.i"
                include "misc/easystart.i"

                move.l  #0,offset               * Offset löschen

*
* Hier werden die beiden Libraries geöffnet: Graphics und Intuition
*

                lea     GfxName,a1              * Graphics öffnen
                moveq.l #0,d0
                CALLEXEC OpenLibrary
                move.l  d0,GfxBase

                lea     IntuiName,a1            * Intuition öffnen
                moveq.l #0,d0
                CALLEXEC OpenLibrary
                move.l  d0,IntuiBase

*
* Auch der Font sollte geöffnet werden ...
*

                move.l  GfxBase,a6
                lea     Font,a0                 * Font in a0 laden
                jsr     _LVOOpenFont(a6)        * und öffnen
                beq     IFFault                 * konnte nicht geöffnet
                                                * werden - schade!
                move.l  d0,FontBase             * Zeiger sichern

*
* Hier wird Speicher für die Copperlist geholt.
*

                move.l  #$10002,d1              * CHIP u. memClear
                moveq.l #12,d0                  * 12 Bytes
                CALLEXEC AllocMem               * allokieren!
                tst.l   d0                      * alles klar?
                beq     IFFault                 * nö!
                move.l  d0,CList                * Zeiger retten

*
* An dieser Stelle wird die Copperliste aufgebaut.
*

                lea     CopColors1,a4
                moveq.w #93,d7

CopperList:     move.w  d7,d2
                move.w  #20,d3
                bsr     CopWait

                move.w  #$180,d2
                move.w  (a4)+,d3
                bsr     CopMove

                addq.w  #1,d7
                cmp.w   #155,d7
                bne.s   CopperList

                move.w  #$180,d2
                move.w  #$000,d3
                bsr     CopMove

                lea     CopColors2,a4
                lea     CopColors3,a5
                move.w  #220,d7

CopperList2:    move.w  d7,d2
                move.w  #20,d3
                bsr     CopWait

                move.w  #$180,d2
                move.w  (a4)+,d3
                bsr     CopMove

                move.w  #$182,d2
                move.w  (a5)+,d3
                bsr     CopMove

                addq.w  #1,d7
                cmp.w   #230,d7
                bne.s   CopperList2

                move.w  #$180,d2
                move.w  #$000,d3
                bsr     CopMove

*
* An dieser Stelle wird der FORM-Chunk eingelesen und geprüft.
*

                move.l  #Buffer,d2              * Zwischenspeicher
                moveq.l #12,d3                  * 12 Bytes
                bsr     ReadSomething           * laden
                lea     Buffer,a2               * Adresse holen
                cmp.l   #"FORM",(a2)            * vergleichen
                bne     IFFault                 * kein FORM!!

                cmp.l   #"ILBM",8(a2)           * ILBM?
                bne     IFFault                 * Abbruch!

*
* Nun wird auf BMHD oder BHSM gecheckt.
*

ItsILBM:        move.l  #Buffer,d2              * nächsten Chunk
                moveq.l #8,d3                   * ein-
                bsr     ReadSomething           * laden
                lea     Buffer,a2               * Zwischenspeicher holen
                cmp.l   #"BMHD",(a2)            * BMHD?
                beq     ItsBMHD                 * ja!

                cmp.l   #"BHSM",(a2)            * BHSM?
                bne     IFFault                 * nein ... Abbruch!

                move.l  #Buffer,d2              * BHSM-Chunk
                moveq.l #2,d3                   * über-
                bsr     ReadSomething           * lesen

                bra.s   ItsILBM                 * BMHD weiter suchen!

ItsBMHD:        move.l  4(a2),d3                * BMHD-Chunk
                move.l  #BMHD,d2                * ein-
                bsr     ReadSomething           * lesen

                move.l  pageWidth,d0            * Breite u. Höhe nach d0
                move.l  bmhdWidth,d1
                tst.l   d0                      * überhaupt vorhanden?
                bne.s   PageDefined             * ja!

                move.l  d1,width                * Kompromiß!
                bra.s   ContPlanes

PageDefined:    move.l  d0,width

ContPlanes:     move.b  Planes,d0               * Anzahl Planes
                ext.w   d0                      * auf Word-Größe bringen
                move.w  d0,depth                * und speichern

*
* Jetzt wird erstmal die CMAP gesucht.
*

SearchCMAP:     move.l  #Buffer,d2              * CMAP-Chunk
                moveq.l #8,d3                   * ein-
                bsr     ReadSomething           * lesen
                lea     Buffer,a2               * ist es
                cmp.l   #"CMAP",(a2)            * CMAP?
                beq.s   ItsCMAP                 * es ist!

*
* Nun wird auf CAMG gecheckt.
*

                cmp.l   #"CAMG",(a2)            * ist es CAMG?
                bne     IFFault2                * nein - Fehler!
                moveq.l #4,d3                   * CAMG
                move.l  #Buffer,d2              * ein-
                bsr     ReadSomething           * lesen
                lea     Buffer,a0               * und ViewModes
                move.l  2(a0),viewModes         * speichern

                bra     SearchCMAP              * weiter suchen

*
* Der CMAP-Chunk wurde gefunden. Nun werden die Farben gelesen.
*

ItsCMAP:        move.l  4(a2),d3                * Länge laden
                move.l  d3,d5                   * und retten
                divu    #3,d5                   * durch 3 = Farbanzahl
                subq    #1,d5                   * weniger 1

                move.l  #Colors,d2              * Farben
                bsr     ReadSomething           * einlesen

*
* An dieser Stelle wird der BODY-Chunk gesucht.
*

SearchBODY:     move.l  #Buffer,d2              * nächsten Chunk
                moveq.l #4,d3                   * ein-
                bsr     ReadSomething           * lesen
                cmp.l   #"BODY",Buffer          * ist es BODY?
                beq     FoundBODY               * ja, es ist!

*
* Jetzt werden andere Chunks überlesen oder ausgewertet.
*

SearchOther:    cmp.l   #"CRNG",Buffer          * ist es CRNG?
                bne     NoCRNG                  * nein!
                moveq.l #12,d3                  * CRNG
                move.l  #Buffer,d2              * über-
                bsr     ReadSomething           * lesen

                bra.s   SearchBODY              * Suche fortsetzen

NoCRNG:         cmp.l   #"DPPS",Buffer          * ist es DPPS?
                bne.s   NoDPPS                  * nein!
                move.l  #114,d3                 * DPPS
                move.l  #Buffer,d2              * interessiert uns
                bsr     ReadSomething           * nicht!

                bra.s   SearchBODY              * Suche fortsetzen

NoDPPS:         cmp.l   #"DPPV",Buffer          * ist es DPPV?
                bne.s   NoDPPV                  * nein, nein!
                move.l  #108,d3                 * DPPV
                move.l  #Buffer,d2              * interessiert uns
                bsr     ReadSomething           * noch weniger!

                bra.s   SearchBODY              * Suche fortsetzen

NoDPPV          cmp.l   #"CAMG",Buffer          * ist hier wenigstens CAMG?
                bne.s   NoCAMG                  * nein!
                moveq.l #8,d3                   * CAMG
                move.l  #Buffer,d2              * interessiert uns
                bsr     ReadSomething           * schon mehr!
                lea     Buffer,a0               * ViewModes
                move.w  6(a0),viewModes         * speichern

                bra     SearchBODY              * weiter

NoCAMG:         cmp.l   #"CCRT",Buffer          * ist es CCRT?
                bne.s   NoCCRT                  * nein - weiter!
                moveq.l #18,d3                  * CCRT
                move.l  #Buffer,d2              * über-
                bsr     ReadSomething           * lesen.

NoCCRT:         moveq.l #4,d3                   * scheint
                move.l  #Buffer,d2              * irgendsoein
                bsr     ReadSomething           * privater
                move.l  Buffer,d3               * Chunk zu sein,
                move.l  #Buffer,d2              * der uns
                bsr     ReadSomething           * nichts angeht.

                bra     SearchBODY              * weiter mit der Suche

*
* Der BODY-Chunk wurde gefunden!
*

FoundBODY:      move.l  GfxBase,a6              * GfxBase laden

*
* Erstmal müssen wir eine eigene BitMap initialisieren ...
*

                lea     BitMapStruc,a0          * leere BitMap-Struktur
                move.w  depth,d0                * Anzahl Planes
                move.w  bmhdWidth,d1            * Breite
                move.w  bmhdHeight,d2           * Höhe
                jsr     _LVOInitBitMap(a6)      * und initialisieren!

*
* Als nächstes müssen wir die Planes allokieren. Damit's
* professioneller aussieht, löschen wir sie gleich mit BltClear.
*

                move.w  depth,d4                * Anzahl Planes
                lsl.w   #2,d4                   * mal 4

                lea     PlaneTable,a3           * Planetabelle holen
                moveq.w #0,d3                   * d3 löschen

AllocThem:      move.w  bmhdWidth,d0            * Breite
                move.w  bmhdHeight,d1           * und Höhe
                jsr     _LVOAllocRaster(a6)     * Plane bereitstellen!
                tst.l   d0                      * hat's geklappt?
                beq     IFFault                 * nein; schade!
                move.l  d0,0(a3,d3.w)           * Zeiger retten
                move.l  d0,a1
                move.w  bmhdWidth,d0            * Breite nach d0
                lsr.w   #3,d0                   * durch 8 teilen
                mulu.w  bmhdHeight,d0           * mit Höhe multiplizieren
                moveq.l #0,d1                   * Flag: normal
                jsr     _LVOBltClear(a6)        * Plane löschen
                add.w   #4,d3                   * Zähler erhöhen
                cmp.w   d3,d4                   * fertig?
                bne     AllocThem               * nein ... weiter!

*
* Jetzt wird anhand der Höhe auf Overscan geprüft.
*

                move.l  IntuiBase,a6            * IntuiBase laden
                jsr     _LVOViewAddress(a6)     * View holen
                move.l  d0,a0                   * und nach a0 schieben
                move.w  12(a0),oldY             * alte Offsets retten
                move.w  14(a0),oldX

                move.l  #pageWidth,a1           * Displaybreite laden
                cmp.w   #256,2(a1)              * größer als 256?
                ble.s   OpenIt                  * kein Overscan!

                cmp.w   #512,2(a1)              * kleiner als 512?
                ble.s   OpenIt                  * kein Overscan!

                move.w  #30,12(a0)              * dyOffset verändern
                move.w  #112,14(a0)             * dxOffset verändern
                jsr     _LVORethinkDisplay(a6)  * Display erneuern

OpenIt:         lea     ScreenDefs,a0           * Screen öffnen
                jsr     _LVOOpenScreen(a6)
                tst.l   d0
                beq     IFFault

                move.l  d0,Screen
                move.l  d0,a0
                lea     $2c(a0),a0
                move.l  a0,ViewPort             * ViewPort retten
                move.l  Screen,a0
                lea     $b8(a0),a0
                lea     8(a0),a0
                move.l  a0,a5                   * Plane-Tabelle holen

*
* Jetzt werden erstmal die Farben umgewandelt!
*

CompColors:     move.l  GfxBase,a6
                lea     Colors,a3               * Farbtabelle holen
                moveq.w #0,d6                   * bei Farbe 0 anfangen!

ColLoop:        move.b  (a3)+,d1                * Rotkomponente holen
                lsr.b   #4,d1                   * durch 16 teilen
                move.b  (a3)+,d2                * Grünkomponente holen
                lsr.b   #4,d2                   * durch 16 teilen
                move.b  (a3)+,d3                * Blaukomponente holen
                lsr.b   #4,d3                   * durch 16 teilen
                move.l  ViewPort,a0             * ViewPort holen
                move.w  d6,d0                   * Nummer holen
                jsr     _LVOSetRGB4(a6)         * Farbe setzen!

                addq.w  #1,d6                   * Nummer erhöhen
                dbra    d5,ColLoop              * bis zum Ende!

*
* Nun beginnt das Lesen der eigentlichen Daten.
*

ReadThem:       move.l  #Buffer,d2              * Chunk-Länge
                move.l  #4,d3                   * über-
                bsr     ReadSomething           * lesen

                move.l  #Buffer,d2              * die ersten
                move.l  #1024,d3                * 1024 Bytes
                bsr     ReadSomething           * einlesen

                move.w  height,numLines         * Höhe = Anzahl Zeilen
                move.w  height,d5               * nach d5
                move.w  width,d3                * Breite nach d3
                lsr.w   #3,d3                   * durch 8 = Bytes/Zeile
                move.l  a5,a3                   * Plane-Zeiger nach a3
                move.l  #Buffer,a2              * Zwischenspeicher nach a2
                move.w  depth,d4                * Anzahl Planes nach d4

                cmp.b   #1,Comp                 * gepackt?
                bne     NotPacked               * nein ... schön!

*
* Ab hier steht die Routine, die einen gepackten BODY-
* Chunk einliest und anzeigt.
*

                moveq.l #0,d1                   * erstmal d1 löschen
                moveq.l #0,d5                   * Zeilenzähler löschen
UnpackLine:     moveq.l #0,d6                   * Bitplanezähler löschen

UnpackPlane:    move.w  d3,d0                   * Bytes/Zeile
                mulu    d5,d0                   * mal Höhe
                move.l  d0,a5                   * nach a5
                asl     #2,d6                   * mal 4 (wg. Longword)
                add.l   0(a3,d6.w),a5           * zur aktuellen
                                                * Position der aktuellen
                                                * Bitplane addieren
                asr     #2,d6                   * durch 4 (normal)

                move.l  a5,a6                   * nach a6
                add.w   d3,a6                   * plus Bytes/Zeile

*
* Jetzt wird geprüft, ob das Byte kleiner als 128 ist.
*

CheckPacked:    bsr     ReadOneByte             * nächste Byte lesen
                cmp.b   #128,d0                 * ist es
                bhi.s   GoOn                    * größer als 128?
                beq.s   CheckFinished           * wenn gleich 128, wird
                                                * keine Operation
                                                * durchgeführt.

*
* Das Byte zeigt an, daß ungleiche Bytes folgen. Diese
* werden nun alle in die entsprechende Plane geschrieben.
*

                move.b  d0,d7                   * als Zähler
FinishLine:     bsr     ReadOneByte             * nächste Byte lesen
                move.b  d0,(a5)                 * ab in die Plane
                addq.l  #1,a5                   * Planeposition + 1
                subq.b  #1,d7                   * Zähler dekrementieren
                bpl.s   FinishLine              * solange, bis Zähler 0
                bra.s   CheckFinished           * weiter

*
* Hierhin wird gesprungen, wenn erkannt wurde, daß die
* folgenden Bytes gleich sind.
*

GoOn:           move.b  d0,d7                   * Zähler setzen
                bsr     ReadOneByte             * nächste Byte lesen
StoreByte:      move.b  d0,(a5)                 * in die Plane
                addq.l  #1,a5                   * Planeposition + 1
                addq.b  #1,d7                   * Zähler erhöhen
                cmp.b   #1,d7                   * ist Zähler 1?
                bne.s   StoreByte               * nein ... wiederholen

CheckFinished:  cmp.l   a5,a6                   * fertig?
                bhi.s   CheckPacked             * nein ... weiter mit
                                                * dem Lesen einzelner
                                                * Bytes

                addq    #1,d6                   * Planezähler erhöhen
                                                * (nächste Plane)
                cmp     d4,d6                   * Zeilenende erreicht?
                bne.s   UnpackPlane             * nein - weiter

                cmp.b   #1,Mask                 * Maske definiert?
                bne.s   GoOnLoop                * nein - weiter

*
* Hier steht im Prinzip der gleiche Code wie oben,
* nur werden die Bytes der Maske nirgendwohin gespeichert.
*

                move.l  #0,a5                   * Planeposition löschen

CheckPacked2:   bsr     ReadOneByte             * nächste Byte lesen
                cmp.b   #128,d0                 * 128?
                bhi.s   GoOn2                   * nein, größer!
                beq.s   CheckFinished2          * gleich 128 - heißt
                                                * keine Operation!

*
* Es folgen unterschiedliche Bytes.
*

                move.b  d0,d7                   * Zähler setzen
FinishLine2:    bsr     ReadOneByte             * nächste Byte lesen
                addq.l  #1,a5                   * Planeposition + 1
                subq.b  #1,d7                   * Zähler - 1
                bpl.s   FinishLine2             * noch nicht 0?
                bra.s   CheckFinished2          * weiter!

*
* Es folgen gleiche Bytes. Diese werden sozusagen ins
* Nichts geschrieben, aber so täuschend echt, daß es
* scheint, sie würden in irgendwelche Bitplanes geschrieben.
*

GoOn2:          move.b  d0,d7                   * Zähler setzen
                bsr     ReadOneByte             * nächste Byte lesen
StoreByte2:     addq.l  #1,a5                   * Position erhöhen
                addq.b  #1,d7                   * Zähler erhöhen
                cmp.b   #1,d7                   * ist schon 1?
                bne     StoreByte2              * nein ... weiter

CheckFinished2: cmp.l   a5,d3                   * Plane fertig?
                bhi.s   CheckPacked2            * nein ... weiter

GoOnLoop:       addq    #1,d5                   * Zeilenzähler erhöhen
                                                * (nächste Zeile)
                lea     numLines,a0             * Anzahl Zeilen laden
                cmp     (a0),d5                 * fertig (also war dies
                                                * die letzte Zeile)?
                bne     UnpackLine              * nein - weiterladen

                bra.s   ScrollStuff             * weiter

*
* Dies ist die Laderoutine für ungepackte IFF-Bilder.
*

NotPacked:      moveq.l #0,d1                   * d1 löschen
                moveq.l #0,d5                   * Zeilenzähler löschen
NUnpackLine:    moveq.l #0,d6                   * Planezähler löschen

NUnpackPlane:   move.w  d3,d0                   * Bytes/Zeile nach d0
                mulu    d5,d0                   * mal Höhe
                move.l  d0,a5                   * = Position
                asl     #2,d6                   * mal 4 (wg. Longword-
                                                * Adressierung
                add.l   0(a3,d6.w),a5           * zur aktuellen
                                                * Position der aktuellen
                                                * Bitplane addieren
                asr     #2,d6                   * wieder normalisieren

                move.l  a5,a6                   * nach a6
                add.w   d3,a6                   * + Bytes/Zeile

*
* Nun werden alles Bytes einer Plane eingelesen und
* an die entsprechende Stelle im Speicher kopiert.
*

                move.w  d3,d7                   * Zähler setzen
                subq    #1,d7                   * weniger 1 (wg. DBRA)
loop:           bsr     ReadOneByte             * nächste Byte lesen
                move.b  d0,(a5)                 * in die Bitplane
                addq    #1,a5                   * Planeposition + 1
                dbra    d7,loop                 * wiederholen, bis fertig

                addq    #1,d6                   * Planezähler erhöhen
                cmp     d4,d6                   * alle Planes durch?
                bne.s   NUnpackPlane            * nein - also weiter!

                cmp.b   #1,Mask                 * Maske definiert?
                bne.s   GoOnNUnpacking          * nein - weiter!

*
* Und wieder das gleiche wie oben, nur wird das, was die
* Leseroutine einladen, überhaupt nicht berücksichtigt
* (so geht's also auch).
*

                move.w  d3,d7                   * Bytes/Zeile als Zähler
                subq    #1,d7                   * - 1 (wegen DBRA)
loop2:          bsr     ReadOneByte             * nächste Byte lesen
                addq    #1,a5                   * Planeposition + 1
                dbra    d7,loop2                * bis fertig!

GoOnNUnpacking: addq    #1,d5                   * Zeilenzähler erhöhen
                lea     numLines,a0             * Anzahl Zeilen laden
                cmp     (a0),d5                 * sind wir fertig?
                bne.s   NUnpackLine             * nein, sind wir nicht!

*
* Hier steht die Routine für unsere Laufschrift ...
*

ScrollStuff:    move.l  #10000,d2               * auf (256;10000) warten:
                move.l  #256,d3                 * unmögliche Position, heißt
                bsr     CopWait                 * Ende der Liste!

                move.l  IntuiBase,a6
                move.l  ViewPort,a0             * und die
                move.l  CList,a1                * Copperlist
                move.l  a1,20(a0)               * einbinden

                jsr     _LVORethinkDisplay(a6)  * Display erneuern!

                moveq.l #0,d0                   * Scrollzähler löschen
                lea     Text,a4                 * Scrolltext nach a4

ScrollIt:       and.l   #$7,d0                  * sind alle 8 Pixel dieses
                                                * Buchstabens dargestellt?
                bne.s   ScrollOn                * nein ... weiterscrollen

*
* Dieser Abschnitt setzt den Font-Daten-Zeiger
* auf die letzte Zeile des Fonts.
*

                move.l  FontBase,a0             * Font-Basis holen
                move.l  34(a0),a3               * Zeiger auf Font-Daten
                move.w  38(a0),d4               * Modulo des Fonts
                move.w  d4,d5
                mulu    #7,d4                   * mal die Höhe des Fonts
                add.l   d4,a3                   * Zeiger auf dieetzte Zeile
                                                * der Font-Daten richten

*
* Hier wird der nächste, "hereinzuscrollende"
* Buchstabe aus dem Textstring geholt.
*

                moveq.l #0,d1

                move.b  (a4)+,d1                * nächsten Buchstaben laden
                bne.s   NotTheLast              * sollte dieser kein Nullbyte
                                                * sein, wird gescrollt, an-
                                                * sonsten der erste Buchstabe
                                                * geladen!

                lea     Text,a4                 * Textadresse laden
                move.b  (a4)+,d1                * Buchstaben holen

NotTheLast:     cmp.b   #127,d1                 * Sonderzeichen???
                bls.s   NoSpecialChar           * nein, alles bestens!

*
* Falls im Text ein Sonderzeichen (z.B. ein Umlaut)
* vorkommt, muß dessen ASCII-Code um 32 herunter-
* gerechnet werden, da die Zeichen mit den Codes
* 128 bis 159 ($80 bis $9f) im "topaz"-Datenblock
* nicht definiert sind. Da Sonderzeichen ASCII-Codes
* von größer als 128 haben, müssen die nicht defi-
* nierten Zeichen übersprungen werden.
*

                sub.b   #32,d1                  * $80-$9f überspringen

*
* Auch die ASCII-Codes $00-$1f (0-31) sind nicht
* im "topaz.font"-Datenblock definiert (aus be-
* greiflichen Gründen - sie sind nicht darstellbar!).
* Somit hat JEDES darstellbare Zeichen einen ASCII-Code
* von 32 oder darüber und muß um 32 Codes herunter-
* gerechnet werden.
*

NoSpecialChar:  sub.b   #32,d1                  * $00-$1f überspringen

                add.l   d1,a3                   * Zeiger korrekt setzen

ScrollOn:       move.l  Screen,a0
                move.l  192(a0),a0
                add.l   #229*40,a0              * Position (Zeile 229) setzen
                moveq.l #7,d1                   * 8 Zeilen scrollen

                move.l  a3,a5                   * Zeiger retten

*
* Für ein fließendes Scrolling ist es wichtig, zu warten, bis
* der Elektronenstrahl die richtige Position erreicht hat.
*

BeamSyncLoop:   move.l  $DFF004,d3              * Rasterstrahl-Position
                and.l   #$1ff00,d3              * nur vertikale Position
                cmp.l   #$08000,d3              * richtige Zeile (#128)?
                bne.s   BeamSyncLoop            * nein!

*
* Hier beginnt das eigentliche Scrolling.
*

                add.b   #$8,d0                  * Scrollzähler auf Word-
                                                * größe bringen

ScrollPlane:    moveq.l #19,d3                  * 20 Words auf einen Schlag
                moveq   #0,d2                   * welches Bit?
                move.b  (a5),d2                 * entsprechende Daten holen
                sub.l   d5,a5                   * Zeiger zurücksetzen

                roxl.w  #1,d2                   * und Daten des aktuellen
                roxl.w  d0,d2                   * Zeichens ermitteln

ScrollWord:     roxl.w  -(a0)                   * Word nach links schieben
                                                * (probieren Sie mal
                                                * ROXR.W (A0)+!)

                dbra    d3,ScrollWord           * bis alle 8 Zeilen ver-
                                                * schoben sind!

                dbra    d1,ScrollPlane          * bis die gesamte Plane,
                                                * bzw. deren Inhalt, ver-
                                                * schoben ist!

*
* An dieser Stelle wird etwas gewartet ...
*

GetActTime:     move.b  $bfea01,d2              * Highbyte der Zeit lesen
                lsl.l   #8,d2                   * mal 256
                move.b  $bfe901,d2              * Midbyte der Zeit lesen
                lsl.l   #8,d2                   * mal 256
                move.b  $bfe801,d2              * Lobyte der Zeit lesen

*
* Dieser Abschnitt wird solange wiederholt, bis die
* verstrichene Zeit 1/50stel Sekunde beträgt.
*

WaitTime:       move.b  $bfea01,d3
                lsl.l   #8,d3
                move.b  $bfe901,d3
                lsl.l   #8,d3
                move.b  $bfe801,d3

                move.l  d3,d7                   * neue Zeit retten
                sub.l   d2,d7                   * subtrahieren
                cmp.b   #1,d7                   * 1/50stel Sek. Differenz?
                blt.s   WaitTime                * nein!

                addq    #1,d0                   * nächstes Zeichen

Mouse:          btst.b  #6,$bfe001              * Maustaste gedrückt?
                bne     ScrollIt                * nein ... weiterscrollen

*
* Das ist nun das Ende.
*

IFFault2:       move.l  IntuiBase,a6
                jsr     _LVOViewAddress(a6)     * alte Offsets holen
                move.l  d0,a0
                move.w  oldY,12(a0)
                move.w  oldX,14(a0)
                jsr     _LVORethinkDisplay(a6)

                move.l  Screen,a0               * Screen schließen
                jsr     _LVOCloseScreen(a6)

                move.l  GfxBase,a6              * GfxBase laden

                move.w  depth,d4                * Anzahl Planes
                lsl.w   #2,d4                   * mal 4

                lea     PlaneTable,a3           * Planetabelle holen
                moveq.w #0,d3                   * d3 löschen

FreeThem:       move.l  0(a3,d3.w),a1           * Zeiger nach a1
                move.w  bmhdWidth,d0            * Breite nach d0
                lsr.w   #3,d0                   * durch 8 teilen
                mulu.w  bmhdHeight,d0           * mit Höhe multiplizieren
                moveq.l #0,d1                   * Flag: normal
                jsr     _LVOBltClear(a6)        * Plane löschen

                move.w  bmhdWidth,d0            * Breite
                move.w  bmhdHeight,d1           * und Höhe
                move.l  0(a3,d3.w),a0           * Zeiger holen
                jsr     _LVOFreeRaster(a6)      * Plane freigeben!
                add.w   #4,d3                   * d3 erhöhen
                cmp.w   d3,d4                   * fertig?
                bne     FreeThem                * nein ... weiter!

                move.l  GfxBase,a6              * Font schließen
                move.l  FontBase,a1
                jsr     _LVOCloseFont(a6)

IFFault:        move.l  IntuiBase,a1            * Libraries schließen
                CALLEXEC CloseLibrary

                move.l  GfxBase,a1
                CALLEXEC CloseLibrary

                moveq.l #0,d0                   * und Ende!
                rts

*
* Hier stehen die Unterroutinen zum Lesen ...
*

*
* Diese Routine list ein einen ganzen Schwall Bytes direkt
* aus dem Speicher. Die Länge wird in d3 übergeben, ein Zeiger
* auf den entsprechenden Zwischenspeicher muß in d1 stehen.
*

ReadSomething:  movem.l a0/a1,-(SP)             * Register sichern
                move.l  d3,d0                   * Länge nach d0
                subq.l  #1,d0                   * -1 (wegen DBRA)
                move.l  d2,a1                   * Ziel nach a1
                lea     picture,a0              * Quelladresse holen
                add.l   offset,a0               * + Offset
copy:           move.b  (a0)+,(a1)+             * Byte kopieren
                dbra    d0,copy                 * bis fertig
                add.l   d3,offset               * Offset richten
                movem.l (SP)+,a0/a1             * Register holen
                rts                             * und zurück

*
* Die Routine ReadOneByte liest ein einzelnes Byte,
* berücksichtigt aber die Zwischenspeicherung. Ein Zeiger auf
* den Zwischenspeicher muß in a2 stehen. Das geholte Byte
* steht dann in d0.
*

ReadOneByte:    move.b  0(a2,d1.w),d0           * Byte holen und in
                                                * d0 zurückgeben.
                addq.w  #1,d1                   * Länge erhöhen
                cmp.w   #1024,d1                * ist wieder ein ganzer
                                                * Schub fällig?
                bne.s   NotReadyYet             * nein, noch(!) nicht ...

                movem.l d0/d2/d3/a6,-(SP)       * das Nötigste auf den Stack
                move.l  a2,d2                   * Zwischenspeicher setzen
                move.l  #1024,d3                * Länge: 1 Kbyte
                bsr     ReadSomething           * lesen
                movem.l (SP)+,d0/d2/d3/a6       * vom Stack holen
                moveq   #0,d1                   * Länge löschen
NotReadyYet:    rts                             * zurück.


*
* Unterprogramme für die Copperlist ...
*

*
* Diese Routine entspricht etwa CWAIT aus GfxMacros.
* Übergeben werden müssen:
*
* D2 - y-Koordinate der Position, auf die gewartet werden soll.
* D3 - x-Koordinate der Position, auf die gewartet werden soll.
*

CopWait:        move.l  d2,d0                   * y-Koordinate und
                move.l  d3,d1                   * x-Koordinate sowie
                move.l  CList,a1                * Copperlist-Zeiger setzen!
                move.l  GfxBase,a6              * CWait
                jsr     _LVOCWait(a6)           * aufrufen!
                move.l  CList,a1                * CBump
                move.l  GfxBase,a6              * auf-
                jsr     _LVOCBump(a6)           * rufen
                rts                             * und zurück!

*
* Hier steht eine Art Äquivalent zu CMOVE.
* Diese Parameter werden benötigt:
*
* D0 - Offset des Hardware-Registers von $DFF000.
* D1 - Wert, den das Register erhalten soll.
*

CopMove:        move.l  d2,d0                   * Offset,
                move.l  d3,d1                   * Wert und
                move.l  CList,a1                * Zeiger setzen,
                move.l  GfxBase,a6              * dann
                jsr     _LVOCMove(a6)           * CMove und
                move.l  CList,a1                * darauf
                move.l  GfxBase,a6              * CBump
                jsr     _LVOCBump(a6)           * aufrufen!
                rts                             * zurück!

*
* Dies ist der Datenteil ...
*

*
* Hier steht die Definition eines Screens (NewScreen), der im
* Laufe des Programms initialisiert wird.
*

 even
ScreenDefs:
leftEdge:       dc.w    0
topEdge:        dc.w    0
width:          dc.w    0
height:         dc.w    0
depth:          dc.w    0
detailPen:      dc.b    1
blockPen:       dc.b    0
viewModes:      dc.w    0
type:           dc.w    $4F                     * customScreen und
                                                * customBitMap
font:           dc.l    0
defaultTitle:   dc.l    0
gadgets:        dc.l    0
customBitMap:   dc.l    BitMapStruc             * BitMap-Struktur

*
* Der Text ...
*

Text:           dc.b    "Ein weiteres Beispiel dafür, "
                dc.b    "wie man Demos mit gewissen Ex"
                dc.b    "tras erstellen kann!         "
                dc.b    "                             ",0

*
* Einige Systemkonstanten.
*

GfxName:        dc.b    "graphics.library",0
 even
IntuiName:      dc.b    "intuition.library",0
 even

Font:           dc.l FontName                   * TextAttr-Struktur
                dc.b 0,8,0,1                    * topaz80, normal und ROMFONT

FontName:       dc.b "topaz.font",0             * Name des Fonts

FontBase:       dc.l 0                          * Zeiger auf Font

*
* Hier wird Platz für eine BitMap-Struktur und Planes gelassen.
*

 even
BitMapStruc:    ds.b    8
PlaneTable:     ds.l    6

*
* Einige private (unsere!) Zeiger.
*

GfxBase:        dc.l    0
IntuiBase:      dc.l    0
ViewPort:       dc.l    0
Screen:         dc.l    0
CList:          dc.l    0

*
* Platz für den BMHD-Chunk, der hierhin kommt.
*

BMHD:
bmhdWidth:      dc.w    0
bmhdHeight:     dc.w    0,0,0
Planes:         dc.b    0
Mask:           dc.b    0
Comp:           dc.b    0,0
                dc.w    0,0
pageWidth:      dc.w    0
pageHeight:     dc.w    0

*
* Eigene Parameter ...
*

oldX:           dc.w    0                       * alter dxOffset
oldY:           dc.w    0                       * alter dyOffset
numLines:       dc.w    0                       * Anzahl Zeilen
offset:         dc.l    0                       * Offset für's
                                                * Laden aus dem Speicher

*
* Hier ist genug Platz für den CMAP-Chunk.
*

Colors:         ds.b    96

*
* Und das ist ein Zwischenspeicher für das zwischengespeicherte
* Einlesen von Bytes (siehe ReadOneByte).
*

Buffer:         ds.b    1024

*
* Hier stehen die Daten des Bildes. Sie können diesen Namen
* nach Ihren eigenen Wünschen (je nachdem, welches Bild geladen
* werden soll) abändern, nur müssen Sie dann das Programm neu
* assemblieren.
*

picture:        incbin  "GrafikProgs2:kap_22/Intro2.IFF"

*
* An dieser Stelle stehen die Farben für den Verlauf ...
*

CopColors1:     dc.w    $000,$001,$002,$003,$004,$005,$006,$007
                dc.w    $008,$009,$00A,$00B,$00C,$00D,$00E,$00F
                dc.w    $01F,$02F,$03F,$04F,$05F,$06F,$07F,$08F
                dc.w    $09F,$0AF,$0BF,$0CF,$0DF,$0EF,$0FF,$0FF
                dc.w    $0EF,$0DF,$0CF,$0BF,$0AF,$09F,$08F,$07F
                dc.w    $06F,$05F,$04F,$03F,$02F,$01F,$00F,$00E
                dc.w    $00D,$00C,$00B,$00A,$009,$008,$007,$006
                dc.w    $005,$004,$003,$002,$001,$000

CopColors3:     dc.w    $00F,$03F,$06F,$09F,$0CF
                dc.w    $0CF,$09F,$06F,$03F,$00F

CopColors2:     dc.w    $F00,$F30,$F60,$F90,$FC0
                dc.w    $FC0,$F90,$F60,$F30,$F00

*
* Das war's dann auch.
*

                END

