home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / grafix / boards / a2410src.lha / Public / Source / gfx.c < prev    next >
Encoding:
Text File  |  1995-02-19  |  76.9 KB  |  2,355 lines

  1. /* 
  2.     File : gfx.c
  3.     Date : 7.10.1994
  4.     Author : Jürgen Schober
  5.  
  6.     Description :
  7.         TIGA Graphics.library module 
  8.         This is the basic low level graphics code I use for the WB Emulation
  9.         on the A2410 TIGA !
  10.  
  11.         Uses my_macros instead of a2410/dev_macros.
  12.         do not link with a2410.lib !
  13.  
  14.     ©1994/95 Jürgen Schober
  15.  
  16. --------------------------------------------------------------------------------------------------------
  17.  
  18.     BASIC NOTES : 
  19.  
  20.     sorry, I made my notes in german...I will translate it if I have time sometimes ...
  21.     If somebody wanna do - just do it :-)
  22.     I will use english for further notes ... I swear !
  23.  
  24.     LibBasics :
  25.  
  26.     Jede Funktion enthält als erste Funktion ein Makro, das einige 
  27.     a2410.device setups vornimmt und die library auf <BUSY> setzt.
  28.     Am Ende wird <BUSY> wieder gelöscht.
  29.     Jede Funktion ruft danach (in einer Schleife) ClipIt auf. 
  30.     ClipIt() baut die Clipping-Rechtecke auf.
  31.     Danach wird der Zeichenmodus mittels DwMode() gesetzt und
  32.     schließlich die Graphikoperation ausgeführt.
  33.  
  34.     7.10.94 :
  35.  
  36.     Erste Arbeiten an der Draw()-Funktion.
  37.     Untersuchungen über clipping. Im Layer->ClipRect steht das erste ClipRect,
  38.     in ClipRect->bounds die Clipping-Grenzen. ClipRect->Next zeigt auf das 
  39.     nächste Clipping-Rechteck. Wenn ClipRect->prev == 0, dann nicht mehr 
  40.     clippen (?). Erste Implemetation von ClipLine(), jedoch in dieser Form
  41.     nicht brauchbar. ClipLine() muß, falls die Linie ganz im ClipRect gezeichnet
  42.     werden kann, das clipping unterbrechen ! Der Parameter <struct Layer> sollte
  43.     gegen <struct ClipRect> ausgetauscht werden. Die x/y-Offsets müssen in
  44.     Draw() dazuaddiert werden ! (noch nicht eingebaut !)
  45.  
  46.     Noch nicht kompilieren !
  47.  
  48.     8.10.94
  49.  
  50.     Clipping geändert. Zum Clippen wird set_clip_rect() verwendet. Dadurch läßt sich 
  51.     eine globale Funktion <ClipIt()> zum clippen _aller_ Graphikoperationen einsetzen.
  52.     (Auch Bitmaps, Füllfunktionen, Areafunktionen ...)
  53.     Kompiliert und getestet ! Funktioniert teilweise. Wenn ein Fenster im Vordergrund 
  54.     aktiviert wird, kann es passieren, daß die Cliprects nicht mehr stimmen (?).
  55.     DwMode() zum Setzten der DrawModes wurde aus der gsp_gfx.library, RectFill() übernommen.
  56.     Muß eventuell korrigiert werden !
  57.  
  58.  
  59.     12.10.94
  60.  
  61.     Außer Matura gemacht und durchgeflogen (Ärger) hab' ich noch das Clipping fertig.
  62.     Die ClipRects des aktuellen RastPort bzw. Layer werden durch ClipRect->lobs gekennzeichnet.
  63.     Ist lobs == NULL, gehoert das Rectangle zum aktuellen Window, lobs !=NULL -> anderes Fenster.
  64.     Funktioniert bis jetzt. Ich weiß allerdings nicht, was mit der Linie passiert, die hinter einem
  65.     Fenster gezeichnet wird. Müßte eigentlich in eine temporäre Bitmap gezeichnet werden, .. ???
  66.  
  67.     Ach ja, und RectFill() wurde schon am 8.10.94 aus der gsp_gfx.library geholt !
  68.     (Mein line-clipping macht aber keine Fehler, im Gegensatz zur Picasso !)
  69.  
  70.     13.10.94
  71.  
  72.     SetFont() / Text() aus der gsp_gfx.library übernommen. Neu ist, das SetFont() jetzt lokal 
  73.     InstallFont() aufruft um einen Zeichensatz auf die 2410 zu kopieren. Beim Öffnen der Lib wird
  74.     InstallFont() aufgerufen und topaz 8 als "ROM"-Font installiert. Default ist nun topaz 8.
  75.     Text() sollte eigentlich so funktionieren. Ich hab' da eine Bitmap auf der Tiga-Seite installiert,
  76.     aus der ich mit bit_blt() die einzelnen Zeichen rausschneide. Leider muß ich das für jeden 
  77.     Buchstaben einzeln machen. Dadurch wirds natürlich (relativ) langsam. (Sonst müßte ich den
  78.     ganze Text() Algorithmus auf die TIGA portieren - aber wie ???).
  79.  
  80.     SetFont() muß noch mal überarbeitet werden. Beim Umkopieren in die Cachebitmap wird keine 
  81.     Aussparung für das Zeichenkerning vorgenommen. Das ist ein bißchen aufwendig und dazu hab'
  82.     ich jetzt keine Lust.
  83.  
  84.     17.10.94
  85.  
  86.     FuncEntry und FuncExit durch LockLib() und UnlockLib() ausgetauscht. Locking-Mechanismus mit
  87.     Semaphoren realisiert. Semaphoren dürften funktionieren (kann ich nicht real testen, aber ich
  88.     habe meine Line-Routine gegen Draw ausgetauscht, und da ist es gelaufen). Das Problem liegt
  89.     jetzt anscheinend am FindTask(NULL); das ist die Methode, wie das device den aktuellen Task
  90.     findet. Bei einem zweiten Task -> crash !
  91.  
  92.     18.10.94
  93.  
  94.     LockLib()/UnlockLib() funktioniert jetzt ! Wurde mit SignalSemaphoren verwirklicht.
  95.     ObtainSemaphoreShared() hat nicht funktioniert, ObtainSemaphore funktioniert.
  96.     LockLayerRom() benutzt auch Semaphoren, kann sein, daß ich da in der Verschachtelung einen
  97.     Fehler gehabt habe'. (?) LockLib() macht ein ObtainSemaphore(ss_lock), wobei die ss_lock 
  98.     die öffentliche (public) SignalSemaphore für die gfx.library ist. Name : TIGA_SEMAPHORE .
  99.     UnlockLib() "released" die Semaphore wieder.
  100.     Außerdem habe ich noch ein paar Mouse-Funktionen aus der gsp_gfx.library geholt. Default wird
  101.     jetzt beim OpenLibrary() ein Mousezeiger installiert (der normale Amigamauszeiger), geht was
  102.     schief, wird der TIGA-Pointer aktiviert. Somit steht sofort ein Mauszeiger zur Verfügung.
  103.     Ein Maustreiber kann jetzt parallel (als eigener Task) laufen. (s. Mouse.c bzw. Mouse)
  104.  
  105.     Jetzt habe ich noch schnell die zwei Funktionen DrawEllipse() und AreaEllipse geholt. Mal sehen
  106.     ob ich die noch ans neue Konzep anpassen kann.
  107.  
  108.     20.10.94
  109.  
  110.     DrawEllipse()/AreaEllipse hab' ich letztens noch geschafft. Heute habe ich noch WritePixel(),
  111.     SetRGB4() und SetRGB32() eingebaut.
  112.     Bei RectFill habe ich einen Fehler behoben. Pattern.data wurde nicht mit NULL initialisiert. 
  113.     Speicher wurd mit if (pattern.data) gsp_free(pattern.data) erledigt. Und wenn zufällig was im 
  114.     data stand -> crash. Ich möchte noch probieren, ob die Priorität der Semaphoren was mit dem
  115.     DOS-deadlock zu tun hat. Die Emulation läuft jetzt (verblüffend) stabil. Leider hängt sich
  116.     dann die Workbench von Zeit zu Zeit auf. z.B. wenn ich ein Verzeichnis aufmache, bleibt se hängen .(?)
  117.     Der TIGA Treiber läuft aber weiter ! Ich kann Fenster verschieben usw. 
  118.     Priorität auf -5 gesetzt. -> No way. Hat sich nix geändert !
  119.  
  120.     Ah ja. Noch was. Bei den Drawmodes. Wenn die rp->FgPen == 0, muß transparent ausgeschalten werden
  121.     (transp_off()). Die PPOP der tiga funktionieren so : Transparent, wenn A verkn. B = 0. Wenn
  122.     also ( (A = rp->FgPen = 0) ODER B (ganz egal was B ist) ) = NULL ! -> Transparent. Das merkt man dann,
  123.     Wenn ein Fenster inaktiv wird. Da wird's nämlich mit col0 (d.h. rp->FgPen = 0) gezeichnet.
  124.  
  125.  
  126.     18:10 . Vorlesung ist wieder einmal gerammelt voll. Das nächste mal ein halbe Stunde frühere !!
  127.  
  128.     So, jetzt werde ich mal den ersten Blitversuch starten. Dazu wird eine Liste eingeführt, wo die 
  129.     Bitmap des aktuellen (Fronmost) Screens eingetragen wird. Anfangs wird nur von host->gsp und von
  130.     gsp->gsp geblittet. Liegt ein Target im Screen, host2gspxy(), liegen Source und Target im Screen
  131.     bitblt(). Genauso wird entschieden, ob eine Funktion gezeichnet wird oder nicht. Später könnte man
  132.     dann bei gsp->host die Bitmap mit in einen Buffer kopieren und dort cachen. Sobald aber das Target
  133.     im cache auftaucht, ist der Eintrag nasty !
  134.     Die Liste soll eine Struktur sein. 
  135.  
  136.     struct globals {
  137.         struct Screen *screen;  // der aktuelle Screen
  138.         struct BitMap *bitmap;  // dessen Bitmap
  139.         struct tiga_Screen *tiga_screen;        // die Adresse des Tiga screens.
  140.         ... // und vielleicht noch was ...
  141.     };
  142.  
  143.     21.10.94
  144.  
  145.     Gestern noch ist die erste Version von GfxBltBitmap() gelaufen. Normalerweise wird mit set_srcbm(0,..)
  146.     /sert_dstbm(0,..) die Bitmap des aktuellen Screens eingestellt. Wenn man aber nur am Schirm blittet
  147.     (ohne Buffer) muß die Adresse auf DisplayAddr eingestellt werden ! set_xxbm(config.display_mem_start) !
  148.     (Laut Tiga-Handbuch darf das gar nicht gehen !)
  149.     Es wird kein tempRas und keine mask unterstützt, die ppop sind im Moment immer {A ODER B}. Die
  150.     muß ich dann noch an die Miniterms anpassen. Allerdings kennt die Originalfunktion 2 Sourcen und ein
  151.     Target !
  152.  
  153.     22.10.94
  154.  
  155.     GfxBltBitMap() kann jetzt auch planare Bitmaps vom Amiga auf den Tigascreen blitten. Ist zwar ein
  156.     bißchen langsam, aber es funktioniert. Ich habe die Routine in die (lokale) Plane2Chunky()-Routine
  157.     ausgelagert und noch eine Funktion GfxBltTiga() eingebaut. Dadurch kann diese Funktion auch als
  158.     planar -> chunky Konverter benutzt werden. (Ist allerdings noch nicht wirklich fertig, weil das Ziel
  159.     immer auf dem Tiga Schirm liegt !).
  160.  
  161.     22.10.94 (abends)
  162.  
  163.     Der Planar->Chunky Modus wurde ein bißchen überarbeitet. Es wird die gesamte planare Bitmap in eine
  164.     chunky map gewandelt. Dadurch steht sie als gecachte Bitmap zur Verfügung. Aus dieser wird nun mit
  165.     host2gspxy() auf die Tiga geblittet. Im  Moment ist der Cache Mechanismus noch nicht eingebaut,
  166.     das heißt es wird vor host2gspxy() _immer_ planar -> chunky gewandelt, und danach der Speicher
  167.     wieder freigegeben. Das änder sich aber gerade. Ich arbeite gerade an cer Cacheverwaltung.
  168.  
  169.  
  170.     23.10.94 
  171.  
  172.     So, Cachefunktionen sind eingebaut. Sie funktionieren - teilweise. Ich habe nur Bitmaps ab einer
  173.     bestimmten Größe gecachet. Dadurch ist der Screenrefresh relativ schnell.
  174.     Habe mir gedacht, schau mir nochmal an, welche Funktion in der Shell bis zum Ende des Fensters löscht.
  175.     Dort wird ein Write() benutzt, und das ruft dann Text() auf. Aber leider weiß ich nicht wer bis zum
  176.     Ende löscht. ClearEOL() o. ClearScreen() sind's jedenfalls nicht !
  177.  
  178.     25.10.94
  179.  
  180.     SetFont() habe ich noch einmal geändert (ObtainSemaphore() statt LockLib() ) und jetzt scheint's wieder zu
  181.     funktionieren.
  182.     Bei den Bitmaps habe ich das Gefühl (ja _Gefühl !) , daß da was beim Speicheranfordern von Plane2Chunky8()
  183.     nicht hinhaut. Wenn ich von 16 auf 256 Farben umschalte, habe ich irgendwann keine Icons mehr da. Das
  184.     passiert eigenlich nur dann, wenn a) die Bitmaps nicht im Cache stehen und b) beim planar->chunky wandeln
  185.     zu wenig Speicher da ist. Werde ich mir dann anschauen.
  186.  
  187.     Wenn Verzeichnisse aufgemacht werden, wird der Hintergrund gelöscht. Ich dachte das macht SetRast(),
  188.     aber auch wenn ich diese Funktion einbaue tut sich nix. (?)
  189.     
  190.  
  191.     28.10.94
  192.  
  193.     Funktionstest :
  194.  
  195.     GfxDraw() - scheint zu funktionieren; Ein Problem tritt bei der Lasofunktion auf.
  196.  
  197.     GfxWritePixel() - hat keinen Crash verursacht
  198.  
  199.     GfxRectFill() - läuft auch stabil - außer beim SetFont(). Da wird irgendwo rausgemalt (?)
  200.  
  201.     GfxDrawEllipse() - ist stabil und schneller als das original (s. <Clock>)
  202.  
  203.     GfxAreaEllipse() - läuft auch stabil (s. <Clock>) braucht aber kein InitArea() !
  204.  
  205.     GfxText() - schaut auch stabil aus, aber ist mit der Methode ziemlich langsam.
  206.  
  207.     GfxSetFont() - Läuft jetzt auch 
  208.     
  209.     GfxSetRGB4() - dito
  210.  
  211.     GfxSetRGB32() - dito
  212.  
  213.     GfxBltBitMap() - da gibt's göbere Probleme, von der Funktion her läuft's, aber ich denke ich habe
  214.                      Schwierigkeiten mit der Blitter-Synchronisation ... (use source debug !!!)
  215.  
  216.  
  217.     Lustig - ohne BltBitMap() funktioniert die Emulation verdammt stabil ! Der TIGA-Treiber hat jetzt 
  218.     einen Algorithmus eingebaut, der nur auf dem eigenen Screen Zeichnet. - Und das läuft. Ich habe mal
  219.     von der TIGA das Palette-Prefs-Programm gestartet - mit Farbrad. Der öffnet tatsächlich einen eigenen
  220.     Screen und schaltet die TIGA ab !!!
  221.  
  222.  
  223.     2.11.94
  224.  
  225.     So, irgendwann zw. 28.10 u. 2.11. hab' ich noch AreaEnd() eingebaut. AreaMove()/AreDraw() wird vom 
  226.     Original übernommen. Gezeichnet wird dann mit AreaEnd(). (Deshalb wird nur AreaEnd() gepatched)
  227.     Area-Befehle haben anscheinend untereinander Schwierigkeiten. (Resourcen , die freigegeben werden oder
  228.     so). Deshalb ruft AreaEllipse()/DrawEllipse() auch die Originalfunktion auf - dann läuft auch
  229.     die Uhr !
  230.  
  231.     BltBitMap() scheint doch zu funktionieren. Ich hab's jetzt mit BitMaps probiert. Wenn als Backgrounds nur
  232.     Brushes benutzt werden, funktionierts. Ich weiß nicht was bei Pattern anders ist. Wenn ich als Fenster-
  233.     hintergrund Pattern benutze, funktioiert's nur ohne BitMap cache. Wenn ein Icon gezeichnet wird, das so groß ist,
  234.     daß die Bitmap gecachet wird, haben auf einmal alle anderen Icons auch die selbe BitMap. Bewege ich ein 
  235.     Fenster über die Icons, sodaß die refreshed werden, habe sie nach dem Refresh ihre richtige BitMap (?).
  236.     Außerdem fehlt ein Modus der benutzt wird, falls die Chunky2Plane Routine zu wenig Speicher hat und 
  237.     wenn beim on-screen blitten der Buffer zu groß wird. Da fehlen zwei Zeilen-Blit-Modi. D.h. es wird 
  238.     Zeilenweise kopiert - wobei beim on-screen-blitten ein Ascent/Descent Mode eingebaut werden muß !
  239.  
  240.     10.12.94
  241.  
  242.     Eigentlich arbeite ich am EGS Treiber ... aber dort habe ich immer Stehzeiten, weil ich Infos
  243.     vom Uli Sigmund brauche ... also hab' ich mir gedacht ich schreibe meine Emulation weiter.
  244.     Außerdem steckt derzeit mehr Know-How in der Emulation als in EGS ... und meine Emulation ist schneller.
  245.     Und durchs EGS Programmieren habe ich neue Debug-Möglichlkeiten gefunden.
  246.  
  247.     Jetzt muß ich noch schnell was ausprobieren : 
  248.     Der Andreas Feck (?) hat mir geschrieben, daß beim öffnen von einem Fenster mit Miniterm = 0 geblittet
  249.     wird -> d.h. src & (~src) = 0 !! logo...
  250.     (Ich werd's mal schnell mit einem fill_rect() mit fcol = 0 probieren !
  251.  
  252.     13.12.94
  253.  
  254.     Ich habe die Planar->Chunky routine in assembler neu geschrieben. Ist echt schnell.
  255.     (subjectiv schneller als die Picasso :-/ ) - aber irgendwas geht nicht.
  256.  
  257.     14.12.94
  258.  
  259.     Die Assmebler-Routine läuft =:-) !!
  260.     War ganz schön viel arbeit. Hab' das Ding aber dann "bitweise" debuged. und jetzt sollte es eigentlich
  261.     gleich funktionieren wie vorher die C-Routine ... aber 100% schneller.
  262.     Ich glaube wenn ich nicht in einen Buffer konvertieren und dann auf die (langsame) Tiga blitten müßte,
  263.     wäre ich schneller als die Picasso !
  264.  
  265.     Da sind jetzt zwei neue Preprozessor-Flags :
  266.  
  267.     DEBUG : ist eh schon alt zum debuggen
  268.     neu sind
  269.     ASSEM_P2C   : assemblerroutine für planar to chunky benutzen
  270.     NO_BM_CACHE : compiliert ohne Bitmapcache !
  271.  
  272.     17.12.94
  273.  
  274.     Durch's EGS programmieren habe ich einiges an der InstallFont-Routine geändert.
  275.     Ich komme jetzt ohne Multiplikation aus. Außerdem habe ich die Wortausrichtung der 
  276.     1 Bit Text-Maske korrigiert.
  277.  
  278.     9.1.95
  279.  
  280.     Ebenfalls durchs EGS programmieren habe ich dort gesehen, daß der Text mit FillMask
  281.     gezeichnet wird. Das entspricht ungefär dem Original BltTemplate() oder BltPattern() Aufruf.
  282.     Außerdem ist das schneller als meine eigene TextRoutine ! (tatsächlich !)
  283.     Ist irgendwie logisch. Durch das "blitten" einer 1 Bit Maske vom FastRAM und dann mit 
  284.     bitblt() auf der TIGA (1 nach 8 bit) erhalte ich immerhin einen Kompressionsfaktor
  285.     von (ca) 1:8 !!
  286.     Ah ja, und auf der EGS Seite habe ich schon das Mausimage eingebaut. Das ist eigentlich
  287.     kompatibel zur Amiga Maus. Das heißt ich muß das mal bei Zeiten rüberholen !
  288.     Dadurch fällt aber das Maus- und das Font-Caching weg ! Das Mausimage jedesmal umzukopieren
  289.     ist schnell genug ! Und der Font bleibt dann 1 bittig auf der AmigaSeite !
  290.     (eventuell muß ich da zuerst in eine 1 BitMaske auf der AmigaSeite schreiben und dann 
  291.     die ganze Maske auf die TIGA blitten !)
  292.     Ja und außerdem brauche ich mir keine Gedanken mehr übers Kerning zu machen.
  293.     Und EGS CopyBitMap (blitting on screen) unterstütz jetzt auch eine Buffer overflow
  294.     beim top down copy. (gsp2gsp) Die Routine gehört da auch noch eingebaut.
  295.  
  296.     17.1.95
  297.  
  298.     Seit 2 Tagen arbeite ich an einem plane-2-chunky Konverter der bitblt() und dessen
  299.     Möglichkeit nutzt, 1 bit BitMaps in 8 Bit Chunky Maps zu "extraieren".
  300.     Dazu wird die 1 Bitplane mit der aktuellen Farben fcolor und bcolor in die chunky map 8
  301.     gestanzt. Plane[0] wird mit DEST_IS_SRC und set_colors(1,0) geblittet d.h. bit 1 = 
  302.     bit eins in chunky map, 0 bleibt null. Jede weitere Plane wird mit color(1^i) und bcol=0 + transp
  303.     als SRC_OR_DEST geblittet (dazu geodert).
  304.     pmask funktioniert da nicht, weil diese auch beim read des bitblt() aktiv wäre und das geht gerade 
  305.     bei plane 0 , alle anderen planes würden ausmaskiert werden !
  306.     Leider habe ich den verdacht, daß die TIGA Implementierung gerade bei Transferbefehlen nicht 
  307.     Fehlerfrei arbeitet. Es kann aber auch sein, das bei schnellen blits die TIGA nicht mehr mit kommt,
  308.     ich werde das dynamische Speichermodell deswegen auf ein statisches umstellen, das mit einem 
  309.     konstant großen Buffer arbeitet (bufmemsize = 512 KB). Vielleicht hilft das weiter.
  310.  
  311.     24.1.95
  312.  
  313.     Plane-2-chunky funktioniert. bitblt() läuft asynchron. Dadurch wird beim >=2. Blit die SrcBitmap
  314.     mit den neuen Daten überschrieben wärend geblittet wird. Das führt dann zu Fehlern.
  315.     Anscheinend haut das blitting mit set_pmask nicht hin. Dann wäre es einfach Miniterms und Masken
  316.     einzubauen, so muß ich in einen Buffer convertieren und dann die 8 Bit durch eine Maske und mit dem
  317.     richtigen ppop blitten...
  318.  
  319.     19.2.95
  320.  
  321.     I decided to make this code public available ! Maybe there is somebody out there who can help
  322.     me finishing this work. 
  323.     I also made some basic consideration of a new conception how a new graphics.library should look
  324.     like.
  325.  
  326.     I) It should be "objective", which means that the library should be extracted from the low level
  327.        graphics stuff which writes to the hardware. -> Hardware extraction layer !
  328.        The library should become a class library only. The classes make the layer handling,
  329.        clipping and such stuff. The drawing functions should be objects of this classes.
  330.  
  331.     II)Basic "Target"-Classes would implement hardware dependent objects. Like one class
  332.        is a chunky-class, the other is a plane-class. Also there could be TrueColor classes like
  333.        15/16/24 bit classes (This sounds like EGS, but it should not be that complex). 
  334.        Hardware depended componets could be overloaded by the driver of the Graphics card.
  335.  
  336.        I do not want to keep old (native) Amiga GfxCode ! There must also be a driver for the
  337.        native Amiga chips !!! This makes sure, if you have a Graphics board that runs in chunky mode
  338.        that all stuff uses Class-library access modes ! This could improve the intuition speed a
  339.        lot ! The dark side is, that it would not allow any code to write directly into the
  340.        Bitmaps ! -> it is (a little bit) incompatible...
  341.  
  342.        But, in this case the normal code would also run in 15/16/24 or what ever mode !
  343.        Also, this would mean there is no "emulation" any more. It is a real new graphics
  344.        sub system ! The Monitor conception has to change a little bit. The Monitors could
  345.        be used as Display-Drivers, where each board has (only) one (!) Monitor file. With
  346.        an utility you can define the available modes (if available !) - Like OCS:Pal, ECS:Pal,
  347.        AGA:Pal, Spectrum:HiRes, A2410:Mode0, etc.
  348.        This also means, there is NO gfx code there on boot up ! Maybe it make sence to implement
  349.        a basic plane and a chunky class in the driver, make the subsystem resident and reboot the
  350.        system ! In this case the new graphics stuff would be available on boot up. If this would work
  351.        we are near an real RTG driver. This code could be build into a ROM on the gfx board !
  352.        So board access would also be available for the GURU (...!) or the boot menue !
  353.        Well, the ROM should NOT hold the whole driver, just gfx primitves for the two classes
  354.        mentioned above ! If the GfxSubsystem runs it is easy to overload the basic classes with
  355.        a new graphics code with a board driver in devs:monitors ! This would keep driver updates
  356.        easy as you only need a new disk instead a new EProm - and it is cheaper, too.
  357.        This is the BIG advatage of Object Oriented Graphics ! This is the way we should go !
  358.        Every other stuff is just a hack and NO real extension like Cybergraphic...!, EGS comes
  359.        close, but they do not change the AmigaOS graphics access mode !
  360.  
  361.        The Basic AmigaOS gfx-hardware access would look like this :
  362.  
  363.         +------------------+
  364.         |   intuition      | 
  365.         +------------------+
  366.                 |
  367.                 +--------------------+
  368.                 x <- patched !       |
  369.                 v                    |  Basic Objects (Draw(),..) are directly called from Intuition
  370.         +------------------+         |  complex calls could stay in the GfxLibrary, like Text() which
  371.         | graphics.library |         |  calls the BltTemplate()... etc.
  372.         +------------------+         |
  373.                 x                    |
  374.                 +--------------------+
  375.                 |
  376.                 v
  377.         +------------------+
  378.         |  class library   |       
  379.         +------------------+
  380.             |          \       ........
  381.             v           V
  382.         +-----------+   +----------+
  383.         |  borad 0  |   | board 1  | ....
  384.         +-----------+   +----------+
  385.  
  386.        A call to e.g. the Draw() function would look like this :
  387.  
  388.         original Draw() - patched by the Class Library,
  389.  
  390.         Class Libray :
  391.             Do the Clipping, Layer, ...
  392.             call the basic Draw()-Object depending which Bitmap to draw !
  393.  
  394.        
  395.  
  396. --------------------------------------------------------------------------------------------------------
  397.  
  398. */
  399. //#define DEBUG 
  400. #define ASSEM_P2C  // assembler modul planar 2 chunky
  401. //#define NO_BM_CACHE
  402.  
  403. #include <string.h>
  404. #include <math.h>
  405.  
  406. /* Pragmas */
  407. #include <pragmas/exec_pragmas.h>
  408. #include <pragmas/mathffp_pragmas.h>
  409. #include <pragmas/mathtrans_pragmas.h>
  410. #include <pragmas/dos_pragmas.h>
  411. #include <pragmas/graphics_pragmas.h>
  412.  
  413. /* Protoypes */
  414. #include <clib/exec_protos.h>
  415. #include <clib/mathffp_protos.h>
  416. #include <clib/mathtrans_protos.h>
  417. #include <clib/dos_protos.h>
  418. #include <clib/graphics_protos.h>
  419.  
  420. /* general Includes */
  421. #include <a2410/typedefs.h>
  422. #include <a2410/devtiga.h>
  423. #include <a2410/ti_function_nums.h> 
  424. #include <a2410/my_macros.h>
  425. #include <exec/types.h>
  426. #include <exec/memory.h>
  427. #include <graphics/gfx.h>
  428. #include <graphics/displayinfo.h>
  429. #include <libraries/mathffp.h>
  430. #include <dos/dos.h>
  431. #include <intuition/screens.h>
  432.  
  433. #include "gfx_types.h"
  434. #include "graphics.h"
  435. #include "tigalogo.h"
  436.  
  437. #define RAND_MAX 5
  438. #define MaxPause 0
  439. #define BIT_SWAP 3
  440.  
  441. #define CLIP_FALSE 0
  442. #define CLIP_TRUE  1
  443. #define CLIP_IN   -1
  444. #define CLIP_OUT  -2
  445.  
  446. UBYTE *version = {"VERS : gfx.library V0.20 Point Design by juergen schober"};
  447.  
  448. /*--------------------------*/
  449. /*   SOME GLOBAL VARIABLES  */
  450. /*--------------------------*/
  451.  
  452. static struct Library *DOSBase,*GfxBase;
  453.  
  454. #ifdef ASSEM_P2C
  455. extern void __asm CopyPlane2Chunky(register __a2 APTR planes,register __a3 APTR chunky,
  456.                                    register __d6 WORD depth,register __d7 long BMSize);
  457. #endif
  458.  
  459. /* Global definition, defined in GfxEntry.o */
  460.  
  461. extern struct TigaScreen
  462. {
  463.     PTR ScreenAddr;
  464.     long Width,Height;
  465.     long Depth;
  466.     long Pitch;
  467. };
  468.  
  469. extern struct Globals
  470. {
  471.     struct Screen *screen;
  472.     struct BitMap *bitmap;
  473.     struct TigaScreen tigascreen;
  474.     struct BMCacheList *first_cache_entry;
  475. } globals;
  476.  
  477. /* global tiga buffer mem */
  478.  
  479. static PTR bufmem = NULL;
  480. long   bufmemsize = 0x80000; // = 512 KB initsize. (maybe I implement a fallback to smaller sizes here...)
  481.  
  482. /* External Functions defined in the GfxEntry.o  */
  483.  
  484. extern long LockLib(void);
  485. extern long UnlockLib(void);
  486. extern BOOL InitTiga(int unit); // well , only unit 0 is supported !
  487. extern void ShutDownTiga(void);
  488.  
  489. /* Global Functions , Prototypes */
  490.  
  491. long ClipIt(struct ClipRect *clip,struct Rectangle *bounds);
  492. long ClipOff(void);
  493. long DwMode(struct RastPort *rp);
  494.  
  495. struct ChunkyMap *Plane2Chunky8(struct BitMap *src);
  496. /* es gibt nur eine BMCache list : globals->first_cache_entry ! */
  497. struct BMCacheList *FindBitmap(struct BitMap *src);
  498. struct BMCacheList *FindChunky(struct ChunkyMap *map);
  499. BOOL InsertChunky(struct ChunkyMap *chunkymap,struct BitMap *bitmap);
  500. BOOL FlushCacheMap(struct BMCacheList *cachelist);
  501.  
  502. void SetDefCols(void);
  503. long InstallFont(struct TextFont *textFont);
  504. long InstallPointer(CURSOR *pointer);
  505.  
  506.  
  507. /*--------------------------*/
  508.  
  509. #ifdef SASC
  510. int CXBRK(void)     { return(0); }
  511. int chkabort(void)  { return(0); }
  512. #endif
  513.  
  514. /* ==========================OpenLibrarySupportFunction===================================== */
  515.  
  516. int __saveds __UserLibInit(void)
  517. {
  518.     struct TextFont *txtfnt;
  519.     struct TextAttr txt;
  520.     CONFIG config;
  521.     struct TigaScreen *tigascreen;
  522.     struct ChunkyMap *logo;
  523.  
  524.     if (DOSBase = (struct Library *)OpenLibrary(DOSNAME,0L))
  525.     {
  526.      if (GfxBase = (struct Library *)OpenLibrary("graphics.library",37L))  
  527.      {
  528.         if (InitTiga(0)) // get the tiga board 0 running
  529.         {
  530.             LockLib();
  531.  
  532.             get_config(&config);    
  533.  
  534.             globals.screen = NULL;
  535.             globals.bitmap = NULL;
  536.             globals.first_cache_entry = NULL;
  537.  
  538.             tigascreen = &(globals.tigascreen);
  539.  
  540.             tigascreen->ScreenAddr = config.display_mem_start;
  541.             tigascreen->Width      = config.mode.disp_hres;
  542.             tigascreen->Height     = config.mode.disp_vres;
  543.             tigascreen->Depth      = config.mode.palet_gun_depth;
  544.             tigascreen->Pitch      = config.mode.disp_pitch;
  545.  
  546.             if (logo = Plane2Chunky8(&LogoMap))
  547.             {
  548.                 host2gspxy(logo->data,logo->xSize,
  549.                         tigascreen->ScreenAddr,tigascreen->Pitch,
  550.                         0,0,
  551.                         (tigascreen->Width-logo->xSize)>>1,
  552.                         (tigascreen->Height-logo->ySize)>>1,
  553.                         logo->xSize,logo->ySize,
  554.                         logo->depth,INTEL_BYTES);
  555.  
  556.                 FreeVec(logo->data);
  557.                 FreeVec(logo);
  558.             }
  559.  
  560.             do{
  561.                 if (!(bufmem = gsp_malloc(bufmemsize)))
  562.                     bufmemsize = bufmemsize>>1;             // half the size
  563.             } while ((!bufmem) && (bufmemsize>0));
  564.  
  565.             UnlockLib();
  566.  
  567.             /*
  568.                 This version uses a own font bitmap on tiga side,
  569.                 Future Versions should use a BltTemplate()
  570.                 instead of the GfxText()-Function,
  571.                 so the font caching will be removed some times !
  572.                 (This works perfectly under EGS !)
  573.              */
  574.             txt.ta_Name  = (UBYTE*)"topaz.font";
  575.             txt.ta_YSize = 8;
  576.             txt.ta_Style = 0;        
  577.             txt.ta_Flags = 0;
  578.  
  579.             if (txtfnt = (struct TextFont*)OpenFont(&txt))
  580.             {
  581.                 InstallFont(txtfnt);
  582.                 CloseFont(txtfnt);
  583.             }
  584.  
  585.             SetDefCols();           // set the 4 basic col registers
  586.             InstallPointer(NULL);   // install a default pointer
  587.  
  588.             return(0);
  589.         }
  590.         CloseLibrary(GfxBase);
  591.      }
  592.      CloseLibrary(DOSBase);
  593.     }
  594.     return(1);
  595. }
  596.  
  597. /* ----------------------------------------------------------------------------------- */
  598. /* =========================CloseLibrarySupportFunction=============================== */
  599.  
  600. void __saveds __UserLibCleanup(void)
  601. {
  602.     struct BMCacheList *cl,*cl_buffer;
  603.     struct FontCacheList *fcl,*fcl_buffer;
  604.  
  605.     LockLib();
  606.  
  607.     cl = globals.first_cache_entry;
  608.     while (cl)
  609.     {
  610.         cl_buffer = cl->next;
  611.         FreeVec(cl->chunkymap->data);
  612.         FreeVec(cl->chunkymap);
  613.         FreeVec(cl);
  614.         cl = cl_buffer;
  615.     }    
  616.     fcl = FirstFontEntry;
  617.     while (fcl)
  618.     {
  619.         fcl_buffer = fcl->ascent;
  620.         gsp_free(fcl->tiga_bm);
  621.         FreeVec(fcl);
  622.         fcl = fcl_buffer;
  623.     }    
  624.  
  625.     UnlockLib();
  626.     ShutDownTiga();
  627.  
  628.     CloseLibrary(DOSBase);
  629.     CloseLibrary(GfxBase);
  630. }
  631.  
  632. /* =====================END OF CloseLibrarySupportFunction============================ */
  633.  
  634. /* ==================================LibCode================================================ */
  635.  
  636.  
  637. /* Some Setup functions : */
  638.  
  639. void SetDefCols(void)
  640. {
  641.     /*
  642.         Setting up a default Palette
  643.     */
  644.     set_palet_entry(0,147L,147L,170L,0);
  645.     set_palet_entry(1,0L,0L,0L,0);
  646.     set_palet_entry(2,255L,255L,255L,0);
  647.     set_palet_entry(3,97L,99L,182L,0);
  648.     set_palet_entry(4,255L,0L,0L,0);
  649.     set_palet_entry(5,0L,255L,0L,0);
  650.     set_palet_entry(6,0L,0L,255L,0);
  651.     set_palet_entry(7,255L,255L,0L,0);
  652. }
  653.  
  654. long InstallFont(struct TextFont *textFont)
  655. {
  656.     /*
  657.         copies a amiga font bitmap into a cache memory in gsp_memory.
  658.         this version does not support kerning values.
  659.         next version should recognise kerning values so 
  660.         the Text() functions need not worry about.
  661.     */
  662.     struct FontCacheList *cachelist,*new_font_entry;
  663.     struct TextFont *AmigaFont;
  664.     WORD   BitMap_Size;
  665.     APTR   TIGA_BitMap;
  666.     CONFIG config;
  667.     long   pitch,size,width,height;
  668.  
  669.     /* check if font already installed ? */
  670.  
  671.     LockLib();
  672.  
  673.     cachelist=FirstFontEntry;
  674.  
  675.     while (cachelist)
  676.     {
  677.         if (AmigaFont = cachelist->amiga_fnt)                        // ok, there is an Amigafont
  678.             if (AmigaFont->tf_CharData == textFont->tf_CharData)     // are the chardata in cache ?
  679.             {
  680.                 UnlockLib();
  681.                 return(TRUE);                                        // then exit
  682.             }
  683.         cachelist=cachelist->ascent;
  684.     }
  685.  
  686.     /* font not in cache, install new font */
  687.  
  688.     AmigaFont   = textFont;
  689.     width       = (AmigaFont->tf_Modulo+1)&~1;
  690.     height      = AmigaFont->tf_YSize;
  691.     BitMap_Size = AmigaFont->tf_Modulo<<3;    // bit size
  692.     pitch       = width<<3;
  693.  
  694.     /* allocate the Memory for the Bitmap on the TIGA */
  695.  
  696.     size = (WORD)width*(WORD)height;
  697.     if (TIGA_BitMap=(APTR)gsp_malloc(size))
  698.     {
  699.  
  700.         /* copy the bitmap data to tiga side */
  701.  
  702.         get_config(&config);
  703.  
  704.         host2gspxy(AmigaFont->tf_CharData,AmigaFont->tf_Modulo,
  705.                 TIGA_BitMap,pitch,
  706.                 0,0,
  707.                 0,0,
  708.                 BitMap_Size,height,
  709.                 8,BIT_SWAP);  // rotate intel bytes (3 = bit rotation)
  710.         
  711.         /* add font to FontCacheList = cache-entrylist */
  712.  
  713.         /* make new entry */
  714.  
  715.         new_font_entry = (struct FontCacheList *)AllocVec(sizeof(struct FontCacheList),MEMF_CLEAR);
  716.  
  717.         new_font_entry->tiga_bm   = TIGA_BitMap;
  718.         new_font_entry->amiga_fnt = AmigaFont;
  719.  
  720.         if (!FirstFontEntry)
  721.             FirstFontEntry = new_font_entry;
  722.         else
  723.         {
  724.             cachelist = FirstFontEntry;
  725.  
  726.         /* go to last but one entry ! */
  727.  
  728.             while (cachelist->ascent) cachelist=cachelist->ascent;
  729.  
  730.         /* and connect to previous entry */
  731.  
  732.             new_font_entry->descent=cachelist;
  733.  
  734.             cachelist->ascent = new_font_entry;
  735.         }
  736.         UnlockLib();
  737.         return(TRUE);
  738.     }
  739.     UnlockLib();
  740.     return(FALSE);
  741. }
  742.  
  743. long InstallPointer(CURSOR *pointer)
  744. {
  745.     /*
  746.         installs a default pointer
  747.     */
  748.     extern CURSOR Pointer,BusyPointer;
  749.     extern UBYTE Pointer_Data[],BusyPointer_Data[];
  750.     UWORD *pointer_data;
  751.     ULONG PointerSize;
  752.     PTR gspPointer,gspBusyPointer;
  753.     CURSOR hstPointer,hstBusyPointer;
  754.     PTR gspPointerData;
  755.     CONFIG config;
  756.  
  757.     if (!pointer)
  758.     {
  759.         get_config(&config);
  760.         PointerSize = ((Pointer.width*Pointer.height)<<1)>>3;
  761.         if (gspPointerData = (PTR) gsp_malloc(PointerSize))
  762.         {
  763.             if (gspPointer = (PTR)gsp_malloc(sizeof(CURSOR)))
  764.             {
  765.                 hstPointer.hot_x  = 0;
  766.                 hstPointer.hot_y  = 0;
  767.                 hstPointer.width  = 16;
  768.                 hstPointer.height = 16;
  769.                 hstPointer.pitch  = Pointer.pitch;
  770.                 hstPointer.color  = 0x00ff0000;
  771.                 hstPointer.mask_rop = 1;
  772.                 hstPointer.shape_rop = 8;
  773.                 hstPointer.data  = gspPointerData;
  774.  
  775.                 // Pointer Data :
  776.                 host2gsp((UBYTE*)&Pointer_Data,gspPointerData,PointerSize,0);
  777.  
  778.                 /*try first sending down first 5 elements of the header - Bitadressen */
  779.                 host2gsp((char*)&hstPointer,gspPointer,10,0);  // no byteswap !
  780.                      /* now send down the color ,which is a long */
  781.                 host2gsp((char*)&(hstPointer.color),(gspPointer+0x50L),4,2);  // byteswap !
  782.                 /* now send down the two raster ops  */ 
  783.                 host2gsp((char*)&(hstPointer.mask_rop),(gspPointer+0x70L),4,0); // no byteswap !
  784.                 /* and the data pointer */
  785.                 host2gsp((char*)&(hstPointer.data),(gspPointer+0x90L),4,2);
  786.  
  787.                 set_curs_shape((PTR)gspPointer);
  788.                 set_curs_state(1);
  789.  
  790.                 set_ovl_color(1,0xff,0xff,0xff);
  791.                 set_ovl_color(2,0xff,0x00,0x00);
  792.                 set_ovl_color(3,0xff,0xff,0x00);
  793.  
  794.                 set_curs_xy(0,0);
  795.  
  796.                 return(TRUE);
  797.             }
  798.             gsp_free(gspPointerData);
  799.         }
  800.     }
  801.     else
  802.     {
  803.         get_config(&config);
  804.         PointerSize = ((pointer->width*pointer->height)<<1)>>3;
  805.         if (gspPointerData = (PTR) gsp_malloc(PointerSize))
  806.         {
  807.             if (gspPointer = (PTR)gsp_malloc(sizeof(CURSOR)))
  808.             {
  809.                 pointer_data = (UWORD*)pointer->data;
  810. //                hstPointer.hot_x  = 0;
  811. //                hstPointer.hot_y  = 0;
  812. //                hstPointer.width  = 16;
  813. //                hstPointer.height = 16;
  814.                 pointer->pitch  = 32;//Pointer.pitch;
  815.                 pointer->color  = 0x00ff0000;
  816.                 pointer->mask_rop = 1;
  817.                 pointer->shape_rop = 8;
  818.                 pointer->data  = gspPointerData;
  819.  
  820.                 // Pointer Data :
  821.                 host2gsp((UBYTE*)pointer_data,gspPointerData,PointerSize,0);
  822.  
  823.                 /*try first sending down first 5 elements of the header - Bitadressen */
  824.                 host2gsp((char*)pointer,gspPointer,10,3);
  825.                      /* now send down the color ,which is a long */
  826.                 host2gsp((char*)pointer->color,(gspPointer+0x50L),4,2);  // byteswap !
  827.                 /* now send down the two raster ops  */ 
  828.                 host2gsp((char*)pointer->mask_rop,(gspPointer+0x70L),4,0); // no byteswap !
  829.                 /* and the data pointer */
  830.                 host2gsp((char*)pointer->data,(gspPointer+0x90L),4,2);
  831.  
  832.                 set_curs_shape((PTR)gspPointer);
  833.                 set_curs_state(1);
  834.  
  835.                 set_ovl_color(1,0xff,0xff,0xff);
  836.                 set_ovl_color(2,0xff,0x00,0x00);
  837.                 set_ovl_color(3,0x00,0x00,0x00);
  838.  
  839.                 set_curs_xy(0,0);
  840.  
  841.                 return(TRUE);
  842.             }
  843.             gsp_free(gspPointerData);
  844.         }
  845.     }
  846.     set_curs_shape(0);
  847.     set_curs_state(1);
  848.  
  849.     set_curs_xy(0,0);
  850.     return(FALSE);
  851. }
  852.  
  853. long ClipIt(struct ClipRect *clip,struct Rectangle *bounds)
  854. {
  855.     /*
  856.         sets up the cliprects on a2410 ! 
  857.     */
  858.     struct Rectangle *rect;
  859.     WORD x0,y0,dx,dy;
  860.  
  861.     if (clip->lobs) return(CLIP_OUT);  /* if lobs!=NULL -> wrong rp/layer */
  862.  
  863.     if (clip)
  864.     {
  865.         if ((rect = &clip->bounds)) 
  866.         {
  867.             x0 = rect->MinX;
  868.             y0 = rect->MinY;
  869.             dx = (rect->MaxX-x0)+1;
  870.             dy = (rect->MaxY-y0)+1;
  871.  
  872.             if ((dx > 0) && (dy > 0) && (x0 >=0) && (y0 >= 0))
  873.                 set_clip_rect(dx,dy,x0,y0);
  874.             return(CLIP_TRUE);
  875.         }
  876.     }
  877.     return(CLIP_FALSE);
  878. }
  879.  
  880. long ClipOff(void)
  881. {
  882.     set_clip_rect(globals.tigascreen.Width,globals.tigascreen.Height,0,0);
  883.     return(TRUE);
  884. }
  885.  
  886. long DwMode(struct RastPort *rp)
  887. {
  888.     /*
  889.      *   sets up the drawmode.
  890.      *   if rp->FgPen = 0, transparency has to be switched off.
  891.      *   A OR B = 0; -> color is transparent ! (0 OR x = 0!)
  892.      */
  893.     long dwmode;
  894.  
  895.     if (rp)
  896.     {
  897.         dwmode = rp->DrawMode;
  898.  
  899.         set_ppop(DST_IS_SRC);
  900.     
  901.         switch (dwmode & (JAM1|JAM2))
  902.         {
  903.             case JAM1 :
  904.                 if (rp->FgPen) transp_on();
  905.                 else transp_off();
  906.                 set_colors(rp->FgPen,0);
  907.                 break;
  908.             case JAM2 :
  909.                 set_colors(rp->FgPen,rp->BgPen);
  910.                 transp_off();
  911.                 break;
  912.         }
  913.         if ((dwmode&COMPLEMENT) == COMPLEMENT)
  914.         {
  915.             transp_off();
  916. //            set_colors(rp->FgPen,rp->BgPen);
  917.             set_colors(0xff,0);
  918.             set_ppop(SRC_XOR_DST);
  919.         }
  920.  
  921.         if ((dwmode&INVERSVID) == INVERSVID)
  922.         {
  923.             set_colors(rp->BgPen,rp->FgPen);    
  924.         }
  925.         return(TRUE);
  926.     }
  927.  
  928.     return(FALSE);
  929. }
  930.  
  931. /* ----------------------------------------------------------
  932.  
  933.                 Bitmap Support functions !
  934.  
  935.    ---------------------------------------------------------- */
  936.  
  937. struct ChunkyMap *GfxAllocBitMap(WORD xSize,WORD ySize,int Depth)
  938. {
  939.     struct ChunkyMap *map;
  940.  
  941.     if (map = (struct ChunkyMap *)AllocVec(sizeof(struct ChunkyMap),MEMF_CLEAR))
  942.     {
  943.         map->depth = 8;
  944.         map->xSize = xSize;
  945.         map->ySize = ySize;
  946.         map ->bmsize = xSize*ySize;
  947.         map->flag = BMF_CACHE_STANDARD;
  948.         if (map->data = (UBYTE *)AllocVec(map->bmsize,MEMF_CLEAR))
  949.             return(map);
  950.         else
  951.         {
  952.             FreeVec(map);
  953.             return(NULL);
  954.         }
  955.     }
  956.     return(NULL);
  957. }
  958.  
  959. void GfxDisposeBitMap(struct ChunkyMap *map)
  960. {
  961.     if (map)
  962.     {
  963.         if (map->data) FreeVec(map->data);
  964.         FreeVec(map);
  965.     }
  966. }
  967.  
  968. struct ChunkyMap *Plane2Chunky8(struct BitMap *src)
  969. {
  970. /*
  971.     converts a planar bitmap into a chunky map.
  972. */
  973.     WORD xSize,ySize;
  974.     WORD depth;
  975.     struct ChunkyMap *chunkymap;
  976.     WORD bm_width;
  977.     UBYTE *planes[8];
  978.     UBYTE *chunky;
  979.     long i;
  980. #ifndef ASSEM_P2C
  981.     WORD num_planes;
  982.     register long x,y,pix;
  983. #endif
  984.  
  985.     if (chunkymap = (struct ChunkyMap *)AllocVec(sizeof(struct ChunkyMap),MEMF_CLEAR))
  986.     {
  987.         chunkymap->depth = 8;
  988.         bm_width = (WORD)src->BytesPerRow;  // Breite für _EINE_ Plane = num_Bits
  989.         chunkymap->xSize = xSize = (WORD)bm_width * 8;
  990.         chunkymap->ySize = ySize = src->Rows;
  991.         chunkymap ->bmsize = xSize*ySize;
  992.         chunkymap->flag = BMF_CACHE_STANDARD;
  993.         if (chunky = (UBYTE *)AllocVec(chunkymap->bmsize,MEMF_CLEAR))
  994.         {
  995. #ifndef ASSEM_P2C
  996.             depth = src->Depth;
  997.             pix = 0;
  998.             for (y=0;y<ySize;y++) 
  999.             {
  1000.  
  1001.                 for (i = 0; i < depth; i++)
  1002.                     planes[i] = src->Planes[i]+bm_width*(WORD)y;
  1003.  
  1004.                 for (x=0;x < (xSize);x++)
  1005.                 {
  1006.                     i = 7;
  1007.                     while (i >= 0 && x < xSize)
  1008.                     {
  1009.                         chunky[pix] = 0;
  1010.  
  1011.                         for (num_planes = 0 ; num_planes < depth ; num_planes ++)
  1012.                             chunky[pix]  += (*planes[num_planes] & (1<<i)) ? (1<<num_planes) : 0;
  1013.                         pix++;
  1014.                         i--;
  1015.                         x++;
  1016.                     }
  1017.  
  1018.                     for (i = 0; i < depth; i++)
  1019.                         planes[i]++;
  1020.     
  1021.                     x--;
  1022.                 }
  1023.             }
  1024.  
  1025. #else
  1026. /*  externes assembler Modul :
  1027. extern void __asm CopyPlane2Chunky(register __a2 APTR planes,register __a3 APTR chunky,
  1028.                                    register __d6 WORD depth,register __d7 long BMSize);
  1029. */
  1030.             CopyPlane2Chunky(src->Planes,chunky,src->Depth,bm_width*ySize);
  1031. #endif
  1032.  
  1033.             chunkymap->data = (UBYTE*)chunky;
  1034.             return(chunkymap);
  1035.         }
  1036.         FreeVec(chunkymap);
  1037.         return(NULL);
  1038.     }
  1039.     return(NULL);
  1040. }
  1041.  
  1042. struct BMCacheList *FindBitmap(struct BitMap *src)
  1043. {
  1044.     struct BMCacheList *cachelist;
  1045.  
  1046.     if ((cachelist = globals.first_cache_entry)&&(src!=NULL))
  1047.     {
  1048.         while (cachelist)
  1049.         {
  1050.             if ((long)cachelist->bitmap == (long)src) return(cachelist);
  1051.             cachelist = cachelist->next;
  1052.         }
  1053.     }
  1054.     return(NULL);
  1055. }
  1056.  
  1057. struct BMCacheList *FindChunky(struct ChunkyMap *map)
  1058. {
  1059.     struct BMCacheList *cachelist;
  1060.  
  1061.     cachelist = globals.first_cache_entry;
  1062.     while (cachelist)
  1063.     {
  1064.         if (cachelist->chunkymap == map) return(cachelist);
  1065.         cachelist = cachelist->next;
  1066.     }
  1067.     return(NULL);
  1068. }
  1069.  
  1070. BOOL InsertChunky(struct ChunkyMap *chunkymap,struct BitMap *bitmap)
  1071. {
  1072.     struct BMCacheList *cachelist,*cl;
  1073.  
  1074.     if (chunkymap->bmsize < 10000) return(FALSE);
  1075. //    if (chunkymap->flag & BMF_NO_CACHE) return(FALSE);
  1076.  
  1077.     if (!(cachelist = globals.first_cache_entry))
  1078.     {
  1079.         if (globals.first_cache_entry = (struct BMCacheList*)AllocVec(sizeof(struct BMCacheList),MEMF_CLEAR|MEMF_PUBLIC))
  1080.         {
  1081.             globals.first_cache_entry->chunkymap = chunkymap;
  1082.             globals.first_cache_entry->bitmap = bitmap;
  1083.  
  1084.             globals.first_cache_entry->flag = BMF_CACHE_STANDARD;
  1085.  
  1086.             return(TRUE);
  1087.         }
  1088.         return(FALSE);
  1089.     }
  1090.   
  1091.     // Letzten Eintrag suchen :
  1092.     while (cachelist->next) cachelist = cachelist->next;
  1093.  
  1094.     if (cl = (struct BMCacheList *)AllocVec(sizeof(struct BMCacheList),MEMF_CLEAR|MEMF_PUBLIC))
  1095.     {
  1096.         cl->chunkymap = chunkymap;
  1097.         cl->bitmap = bitmap;
  1098.         cl->flag = BMF_CACHE_STANDARD;
  1099.  
  1100.         cl->next = NULL;
  1101.         cl->prev = cachelist;
  1102.         cachelist->next = cl;
  1103.  
  1104.         return(TRUE);
  1105.     }
  1106.  
  1107.     return(FALSE);
  1108. }
  1109.  
  1110. BOOL FlushCacheMap(struct BMCacheList *cachelist)
  1111. {
  1112.     struct BMCacheList *cl;
  1113.  
  1114.     if (cachelist->flag & BMF_LOCK_CACHE)
  1115.         if ((cachelist->flag & BMF_FORCE_FLUSH) == 0) return(FALSE);
  1116.  
  1117.     if (cachelist)
  1118.     {
  1119.         if (cl = cachelist->next)
  1120.             cl->prev = cachelist->prev;
  1121.         if (cachelist->prev)
  1122.             cachelist->prev->next = cl;
  1123.         
  1124.         FreeVec(cachelist->chunkymap->data);
  1125.         FreeVec(cachelist->chunkymap);
  1126.         FreeVec(cachelist);
  1127.         return(TRUE);
  1128.     }
  1129.     return(FALSE);
  1130. }
  1131.  
  1132. /* REAL graphics stuff :  **
  1133. ** ---------------------- **
  1134. **                        */
  1135.  
  1136. LONG __asm GfxWritePixel(register __a1 struct RastPort *rp,
  1137.         register __d0 long x,register __d1 long y )
  1138. {
  1139.     struct ClipRect *cliprect;
  1140.  
  1141.     if (rp && rp->Layer) 
  1142.     {
  1143.         LockLayerRom(rp->Layer);
  1144.         LockLib();
  1145.  
  1146.         rp->cp_x=x;
  1147.         rp->cp_y=y;
  1148.  
  1149.         x += ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
  1150.         y += ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
  1151.  
  1152.         DwMode(rp);
  1153.  
  1154.         cliprect = rp->Layer->ClipRect;
  1155.         while (cliprect)
  1156.         {
  1157.             if (ClipIt(cliprect,NULL)!=CLIP_OUT)  // Linie ist im ClipRect ?
  1158.                 draw_point(x,y);
  1159.             cliprect = cliprect->Next;
  1160.         }
  1161.         UnlockLib(); 
  1162.         UnlockLayerRom(rp->Layer);
  1163.     }
  1164.     return(0);
  1165. }
  1166.  
  1167. void __asm GfxDraw(register __a1 struct RastPort *rp,register __d0 long x,register __d1 long y)
  1168. {
  1169.     long XOffset,YOffset;
  1170.     struct Rectangle bounds;
  1171.     struct ClipRect *cliprect;
  1172.     ULONG  line_pattern;
  1173.  
  1174.     if (rp) 
  1175.     {
  1176.         if (rp->Layer) LockLayerRom(rp->Layer);
  1177.         LockLib();
  1178.  
  1179.         DwMode(rp);
  1180.  
  1181.         line_pattern = (rp->LinePtrn<<16)|rp->LinePtrn;
  1182.  
  1183.         if (rp->Layer)
  1184.         {
  1185.  
  1186.             XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
  1187.             YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
  1188.  
  1189.             bounds.MinX = rp->cp_x+XOffset;
  1190.             bounds.MinY = rp->cp_y+YOffset;
  1191.             bounds.MaxX = x+XOffset;
  1192.             bounds.MaxY = y+YOffset;
  1193.  
  1194.             cliprect = rp->Layer->ClipRect;
  1195.             while (cliprect)
  1196.             {
  1197.                 if (ClipIt(cliprect,NULL)!=CLIP_OUT)  // Linie ist im ClipRect ?
  1198.                 {
  1199.                     if (line_pattern == ~0)
  1200.                         draw_line(bounds.MinX,bounds.MinY,bounds.MaxX,bounds.MaxY);
  1201.                     else 
  1202.                         styled_line(bounds.MinX,bounds.MinY,bounds.MaxX,bounds.MaxY,(long)line_pattern,1);
  1203.                 }
  1204.                 cliprect = cliprect->Next;
  1205.             }
  1206.         }
  1207.         else
  1208.         {
  1209.             ClipOff();
  1210.  
  1211.             if ((rp->LinePtrn)==0xffff)
  1212.                 draw_line(rp->cp_x,rp->cp_y,x,y);
  1213.             else 
  1214.             {
  1215.                 styled_line(rp->cp_x,rp->cp_y,x,y,(long)line_pattern,1);
  1216.             }
  1217.         }
  1218.  
  1219.         rp->cp_x=x;
  1220.         rp->cp_y=y;
  1221.  
  1222.         UnlockLib(); 
  1223.         if (rp->Layer) UnlockLayerRom(rp->Layer);
  1224.     }
  1225. }
  1226.  
  1227. void __asm GfxPolyDraw(register __a1 struct RastPort *rp,
  1228.         register __d0 long count,register __a0 WORD *polyTable )
  1229. {
  1230.     long XOffset,YOffset;
  1231.     struct ClipRect *cliprect;
  1232.     ULONG  line_pattern;
  1233.     POINT  *points;
  1234.     int i;
  1235.  
  1236.     if (rp)
  1237.     {
  1238.         if (rp->Layer) LockLayerRom(rp->Layer);
  1239.         LockLib();
  1240.     
  1241.         DwMode(rp);
  1242.  
  1243.         points = (POINT*)polyTable;
  1244.  
  1245.         if (rp->Layer)
  1246.         {
  1247.  
  1248.             XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
  1249.             YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
  1250.  
  1251.             line_pattern = (rp->LinePtrn<<16)|rp->LinePtrn;
  1252.             for (i=0;i<count;i++)
  1253.             {
  1254.                 points[i].x += XOffset;
  1255.                 points[i].y += YOffset;
  1256.             }
  1257.             if (line_pattern == ~0)
  1258.             {
  1259.                 cliprect = rp->Layer->ClipRect;
  1260.                 while (cliprect)
  1261.                 {
  1262.                     if (ClipIt(cliprect,NULL)!=CLIP_OUT)  // Linie ist im ClipRect ?
  1263.                     {
  1264.                         draw_line(rp->cp_x,rp->cp_y,points[0].x,points[0].y);
  1265.                         draw_polyline(count,points);
  1266.                     }
  1267.                     cliprect = cliprect->Next;
  1268.                 }
  1269.             }
  1270.             else 
  1271.             {
  1272.                 cliprect = rp->Layer->ClipRect;
  1273.                 while (cliprect)
  1274.                 {
  1275.                     if (ClipIt(cliprect,NULL)!=CLIP_OUT)  // Linie ist im ClipRect ?
  1276.                     {
  1277.                         styled_line(rp->cp_x+XOffset,rp->cp_y+YOffset,points[0].x,points[0].y,line_pattern,1);
  1278.                         for (i=0;i<count-1;i++)
  1279.                             styled_line(points[i].x,points[i].y,points[i+1].x,points[i+1].y,line_pattern,1);
  1280.                     }
  1281.                     cliprect = cliprect->Next;
  1282.                 }
  1283.             }
  1284.         }
  1285.         else  // RastPort does not have a cliprect !
  1286.         {
  1287.             ClipOff();
  1288.  
  1289.             if ((rp->LinePtrn)==0xffff)
  1290.             {
  1291.                 draw_line(rp->cp_x,rp->cp_y,points[0].x,points[0].y);
  1292.                 draw_polyline(count,points);
  1293.             }
  1294.             else 
  1295.             {
  1296.                 line_pattern = (rp->LinePtrn<<16)|rp->LinePtrn;
  1297.                 styled_line(rp->cp_x+XOffset,rp->cp_y+YOffset,points[0].x,points[0].y,line_pattern,1);
  1298.                 for (i=0;i<count-1;i++)
  1299.                     styled_line(points[i].x,points[i].y,points[i+1].x,points[i+1].y,line_pattern,1);
  1300.             }
  1301.         }
  1302.  
  1303.         rp->cp_x = points[count-1].x;
  1304.         rp->cp_y = points[count-1].y;
  1305.  
  1306.         UnlockLib();
  1307.         if (rp->Layer) UnlockLayerRom(rp->Layer);
  1308.     }
  1309. }
  1310.  
  1311. void __asm GfxSetRast(register __a1 struct RastPort *rp,register __d0 unsigned long pen )
  1312. {
  1313.     long XOffset,YOffset;
  1314.     struct Rectangle bounds;
  1315.     struct ClipRect *cliprect;
  1316.     ULONG  line_pattern;
  1317.     long ret,i;
  1318.     long x0,y0,xw,yh;
  1319.     UWORD ptrnsz;
  1320.     PATTERN gsp_ptrn;
  1321.  
  1322.     if (rp->Layer) 
  1323.     {
  1324.         LockLayerRom(rp->Layer);
  1325.         LockLib(); 
  1326.  
  1327.         bounds.MinX = rp->Layer->bounds.MinX;
  1328.         bounds.MinY = rp->Layer->bounds.MinY;
  1329.         xw = rp->Layer->bounds.MaxX - bounds.MinX;
  1330.         yh = rp->Layer->bounds.MaxX - bounds.MinY ;
  1331.  
  1332.         set_ppop(OR);
  1333.         set_fcolor(pen);
  1334.  
  1335.         cliprect = rp->Layer->ClipRect;
  1336.         while (cliprect)
  1337.         {
  1338.             if (ClipIt(cliprect,NULL)!=CLIP_OUT)
  1339.             {
  1340.                 fill_rect(xw,yh,bounds.MinX,bounds.MinY); // use fill_rect ...
  1341.             }
  1342.             cliprect = cliprect->Next;
  1343.         }
  1344.         UnlockLib();
  1345.         UnlockLayerRom(rp->Layer);
  1346.     }
  1347. }
  1348.  
  1349. void __asm GfxRectFill(register __a1 struct RastPort *rp,
  1350.         register __d0 long xMin,register __d1 long yMin,
  1351.         register __d2 long xMax,register __d3 long yMax )
  1352. {
  1353. /*
  1354.     should work but I guess there is a bug some times.
  1355.     when using the emulation and typing <setfont> in the shell
  1356.     some wrong rectangles are drawn.
  1357. */
  1358.     long XOffset,YOffset;
  1359.     struct Rectangle bounds;
  1360.     struct ClipRect *cliprect;
  1361.     ULONG  line_pattern;
  1362.     long ret,i;
  1363.     long x0,y0,xw,yh;
  1364.     UWORD ptrnsz;
  1365.     PATTERN gsp_ptrn;
  1366.  
  1367.     if (rp) 
  1368.     {
  1369.         if (rp->Layer) LockLayerRom(rp->Layer);
  1370.         LockLib(); 
  1371.  
  1372.         x0 = (xMin<=xMax) ? xMin : xMax;
  1373.         y0 = (yMin<=yMax) ? yMin : yMax;
  1374.  
  1375.         xw = (xMax>=xMin) ? (xMax-xMin)+1 : (xMin-xMax)+1;
  1376.         yh = (yMax>=yMin) ? (yMax-yMin)+1 : (yMin-yMax)+1;
  1377.  
  1378.         DwMode(rp);
  1379.  
  1380.         gsp_ptrn.data = NULL;
  1381.  
  1382.         if (rp->AreaPtrn)
  1383.         {
  1384.                 ptrnsz = ((rp->AreaPtSz)<=4) ? (1<<(rp->AreaPtSz)) : 16;
  1385.                 gsp_ptrn.width=16;
  1386.                 gsp_ptrn.height=16;  // tiga supports only 16 lines !!!
  1387.                 gsp_ptrn.depth=1;    // no more than 1 plane now !
  1388.                 gsp_ptrn.data=(PTR)gsp_malloc(32);  // 32 bytes = 16 WORDS space for pattern !
  1389.                 if (ptrnsz==16)
  1390.                     host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data),2*ptrnsz,2);  // WORD aligned
  1391.                 else
  1392.                     for (i=0;i<=0xF0;i+=(0x10*ptrnsz)) // bit offset to current pos. - WORD aligned !
  1393.                         host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data)+i,2*ptrnsz,2);
  1394.                 set_patn(&gsp_ptrn);
  1395.         }   
  1396.  
  1397.         if (rp->Layer)
  1398.         {
  1399.             XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
  1400.             YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
  1401.  
  1402.             bounds.MinX = x0+XOffset;
  1403.             bounds.MinY = y0+YOffset;
  1404.  
  1405.             cliprect = rp->Layer->ClipRect;
  1406.             while (cliprect)
  1407.             {
  1408.                 if (ClipIt(cliprect,NULL)!=CLIP_OUT)
  1409.                 {
  1410.                     // NO Pattern in Rect
  1411.                     if (!rp->AreaPtrn) 
  1412.                         fill_rect(xw,yh,bounds.MinX,bounds.MinY); // use fill_rect ...
  1413.                     // Patternfilled Rect !
  1414.                     else 
  1415.                         patnfill_rect(xw,yh,bounds.MinX,bounds.MinY);
  1416.     
  1417.                     if ((rp->Flags)&AREAOUTLINE)
  1418.                     {
  1419.                         set_fcolor(rp->AOlPen);
  1420.                         if ((rp->LinePtrn)==0xFFFF) 
  1421.                             draw_rect(xw,yh,bounds.MinX,bounds.MinY);
  1422.                         else 
  1423.                         {
  1424.                         line_pattern=(((rp->LinePtrn)<<16)|(rp->LinePtrn));
  1425.                         styled_line(bounds.MinX,bounds.MinY,bounds.MaxX,bounds.MinY,line_pattern,0);
  1426.                         styled_line(bounds.MaxX,bounds.MinY,bounds.MaxX,bounds.MaxY,line_pattern,0);
  1427.                         styled_line(bounds.MaxX,bounds.MaxY,bounds.MinX,bounds.MaxY,line_pattern,0);
  1428.                         styled_line(bounds.MinX,bounds.MaxY,bounds.MinX,bounds.MinY,line_pattern,0);
  1429.                         }
  1430.                     }
  1431.                 }
  1432.                 cliprect = cliprect->Next;
  1433.             }
  1434.         }
  1435.         else
  1436.         {
  1437.             LockLib(); 
  1438.             ClipOff();
  1439.  
  1440.             // NO Pattern in Rect
  1441.             if (!rp->AreaPtrn) 
  1442.                 fill_rect(xw,yh,x0,y0);
  1443.             // Patternfilled Rect !
  1444.             else 
  1445.                 patnfill_rect(xw,yh,x0,y0);
  1446.                 
  1447.             if ((rp->Flags)&AREAOUTLINE)
  1448.             {
  1449.                 set_fcolor(rp->AOlPen);
  1450.                 if ((rp->LinePtrn)==0xFFFF) 
  1451.                     draw_rect(xw,yh,x0,y0);
  1452.                 else 
  1453.                 {
  1454.                 line_pattern=(((rp->LinePtrn)<<16)|(rp->LinePtrn));
  1455.                 styled_line(xMin,yMin,xMax,yMin,line_pattern,0);
  1456.                 styled_line(xMax,yMin,xMax,yMax,line_pattern,0);
  1457.                 styled_line(xMax,yMax,xMin,yMax,line_pattern,0);
  1458.                 styled_line(xMin,yMax,xMin,yMin,line_pattern,0);
  1459.                 }
  1460.             }
  1461.         }
  1462.  
  1463.         if (gsp_ptrn.data)  gsp_free(gsp_ptrn.data);
  1464.  
  1465.         rp->cp_x=xMin;
  1466.         rp->cp_y=yMin;
  1467.  
  1468.         UnlockLib();
  1469.         if (rp->Layer)  UnlockLayerRom(rp->Layer);
  1470.     }
  1471. }
  1472.  
  1473. void __asm GfxDrawEllipse(register __a1 struct RastPort *rp,
  1474.         register __d0 long xCenter,register __d1 long yCenter,
  1475.         register __d2 long a,register __d3 long b )
  1476. {
  1477.     long XOffset,YOffset;
  1478.     struct Rectangle bounds;
  1479.     struct ClipRect *cliprect;
  1480.  
  1481.     if (rp->Layer) 
  1482.     {
  1483.         LockLayerRom(rp->Layer);
  1484.         LockLib(); 
  1485.  
  1486.         XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
  1487.         YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
  1488.  
  1489.         bounds.MinX = xCenter+XOffset;
  1490.         bounds.MinY = yCenter+YOffset;
  1491.  
  1492.         DwMode(rp);
  1493.  
  1494.         cliprect = rp->Layer->ClipRect;
  1495.         while (cliprect)
  1496.         {
  1497.             if (ClipIt(cliprect,NULL)!=CLIP_OUT)
  1498.             {
  1499.                 draw_oval((a+a),(b+b),bounds.MinX-a,bounds.MinY-b);
  1500.             }
  1501.             cliprect = cliprect->Next;
  1502.         }
  1503.         rp->cp_x=xCenter;
  1504.         rp->cp_y=yCenter;
  1505.  
  1506.         UnlockLib();
  1507.         UnlockLayerRom(rp->Layer);
  1508.     }
  1509. }
  1510.  
  1511. LONG __asm GfxAreaEllipse(register __a1 struct RastPort *rp,register __d0 long xCenter,
  1512.     register __d1 long yCenter,register __d2 long a,register __d3 long b )
  1513. {
  1514.     long XOffset,YOffset;
  1515.     struct Rectangle bounds;
  1516.     struct ClipRect *cliprect;
  1517.     ULONG  line_pattern;
  1518.     long ret,i;
  1519.     UWORD ptrnsz;
  1520.     PATTERN gsp_ptrn;
  1521.  
  1522.     if (rp->Layer) 
  1523.     {
  1524.         LockLayerRom(rp->Layer);
  1525.         LockLib(); 
  1526.  
  1527.         XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
  1528.         YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
  1529.  
  1530.         bounds.MinX = xCenter+XOffset;
  1531.         bounds.MinY = yCenter+YOffset;
  1532.  
  1533.         DwMode(rp);
  1534.  
  1535.         if (rp->AreaPtrn)
  1536.         {
  1537.                 ptrnsz = ((rp->AreaPtSz)<=4) ? (1<<(rp->AreaPtSz)) : 16;
  1538.                 gsp_ptrn.width=16;
  1539.                 gsp_ptrn.height=16;  // tiga supports only 16 lines !!!
  1540.                 gsp_ptrn.depth=1;    // no more than 1 plane now !
  1541.                 gsp_ptrn.data=(PTR)gsp_malloc(32);  // 32 bytes = 16 WORDS space for pattern !
  1542.                 if (ptrnsz==16)
  1543.                     host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data),2*ptrnsz,2);  // WORD aligned
  1544.                 else
  1545.                     for (i=0;i<=0xF0;i+=(0x10*ptrnsz)) // bit offset to current pos. - WORD aligned !
  1546.                         host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data)+i,2*ptrnsz,2);
  1547.                 set_patn(&gsp_ptrn);
  1548.         }   
  1549.  
  1550.         cliprect = rp->Layer->ClipRect;
  1551.         while (cliprect)
  1552.         {
  1553.             if (ClipIt(cliprect,NULL)!=CLIP_OUT)
  1554.             {
  1555.                 // NO Pattern in Ellipse
  1556.                 if (!rp->AreaPtrn) 
  1557.                     fill_oval(a+a,b+b,bounds.MinX-a,bounds.MinY-b);
  1558.                 // Patternfilled Ellipse !
  1559.                 else 
  1560.                     patnfill_oval(a+a,b+b,bounds.MinX-a,bounds.MinY-b);
  1561.             }
  1562.             cliprect = cliprect->Next;
  1563.         }
  1564.  
  1565.         if (gsp_ptrn.data)  gsp_free(gsp_ptrn.data);
  1566.  
  1567.         rp->cp_x=xCenter;
  1568.         rp->cp_y=yCenter;
  1569.  
  1570.         UnlockLib();
  1571.         UnlockLayerRom(rp->Layer);
  1572.     }
  1573.     return(0);
  1574. }
  1575.  
  1576. void __asm GfxClearScreen(register __a1 struct RastPort *rp )
  1577. {
  1578.     LockLib();
  1579.  
  1580.     clear_screen(0);
  1581.  
  1582.     UnlockLib();
  1583. }
  1584.  
  1585.  
  1586. LONG __asm GfxText(register __a1 struct RastPort *rp,
  1587.             register __a0 STRPTR string,register __d0 unsigned long count )
  1588. {
  1589. /*
  1590.     Text function. Is slow. (see loop below !)
  1591.     Clipping has to be changed. ClipIt() uses set_clip_rect(),
  1592.     which must not be used with bitblt() !
  1593.     So a software clipping should be done on Bitmaps befor blitting !
  1594. */
  1595.     CONFIG config;
  1596.     register int i;
  1597.     struct FontCacheList *t_lst; // t_lst = Verbindungsliste zw. aktuellen Amigafonts u. Tigafonts
  1598.     struct TextFont *AmigaFont; // The Textfontstructur 
  1599.     APTR   Tiga_BitMap;         // a copy of the Fontbitmap on the Tiga-side
  1600.     long   pitch;
  1601.     struct ClipRect *cliprect;
  1602.     WORD *TF_CharKern,*TF_CharSpace;
  1603.     BOOL PropFont = FALSE;
  1604.     register UBYTE asc_val;  // ASCII-Code of character
  1605.     register WORD  charX0,charXSize,charKern,charY0,charYSize,X0,Y0;
  1606.     long   XOffset,YOffset;
  1607.     struct LocTable
  1608.     {
  1609.         WORD XPos;      // LocTable & 0xffff0000
  1610.         WORD FontWidth; // LocTable & 0x0000ffff
  1611.     } *TF_CharLoc;
  1612.     
  1613.     if (rp)
  1614.     {
  1615.         if (rp->Layer)
  1616.             LockLayerRom(rp->Layer);
  1617.         LockLib();
  1618.  
  1619.     /*  -----------------------------
  1620.         Do not use Tiga Text-Function,
  1621.         using my own ! 
  1622.         -----------------------------  */
  1623.  
  1624.         /* ----- Suche nach Amigafont in der Cacheliste ----- */
  1625.  
  1626.         t_lst=FirstFontEntry;
  1627.         while (t_lst)
  1628.         {
  1629.             AmigaFont = (struct TextFont *)t_lst->amiga_fnt;
  1630.             if ((LONG)AmigaFont->tf_CharData==(LONG)rp->Font->tf_CharData)
  1631.             {
  1632.                 Tiga_BitMap = (APTR)t_lst->tiga_bm;
  1633.                 break;  // ****  Wenn Font Font in Liste gfunden, dann raus  ****
  1634.             }
  1635.             t_lst=t_lst->ascent; // nächster Eintrag
  1636.         }
  1637.         if (!t_lst)  // **** fallback to topaz.8 . Should be FirstFontEntry !!  ****
  1638.         {
  1639.             t_lst = FirstFontEntry;
  1640.             AmigaFont = (struct TextFont *)t_lst->amiga_fnt;
  1641.             Tiga_BitMap = (APTR)t_lst->tiga_bm;       
  1642.         }
  1643.  
  1644.         DwMode(rp);
  1645.  
  1646.         TF_CharLoc = (struct LocTable*)AmigaFont->tf_CharLoc;
  1647.         TF_CharKern  = (WORD*)AmigaFont->tf_CharKern;
  1648.         TF_CharSpace = (WORD*)AmigaFont->tf_CharSpace;
  1649.         PropFont = (AmigaFont->tf_Flags & FPF_PROPORTIONAL) ? TRUE : FALSE;
  1650.  
  1651.         charKern = 0;
  1652.         charYSize = AmigaFont->tf_YSize;
  1653.  
  1654.         pitch = ((AmigaFont->tf_Modulo+1)&~1)<<3;
  1655.  
  1656.         set_srcbm(Tiga_BitMap,pitch,pitch,AmigaFont->tf_YSize,1);
  1657.  
  1658.         if (rp->Layer)
  1659.         {
  1660.  
  1661.             XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
  1662.             YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
  1663.  
  1664.             Y0 = (rp->cp_y)-AmigaFont->tf_Baseline+YOffset;
  1665.  
  1666.             cliprect = rp->Layer->ClipRect;
  1667.             while (cliprect)
  1668.             {
  1669.                 if (ClipIt(cliprect,NULL)!=CLIP_OUT)
  1670.                 {
  1671.  
  1672.                     X0 = rp->cp_x+XOffset;
  1673.  
  1674.                     for (i=0;(i<count&&string[i]!=0);i++)
  1675.                     {
  1676.                         asc_val     = string[i]-AmigaFont->tf_LoChar;
  1677.                         charX0      = (WORD)TF_CharLoc[asc_val].XPos;
  1678.                         charXSize   = (WORD)TF_CharLoc[asc_val].FontWidth;  
  1679.                         if (PropFont)
  1680.                             charKern    = (WORD)TF_CharKern[asc_val];
  1681.  
  1682.                         bitblt(charXSize,charYSize,                           // Width,Height
  1683.                                     charX0,0,                                 // Origin x,y
  1684.                                     X0+charKern,Y0);                          // dest x/y (RP->Bitmap)
  1685.  
  1686.                         if (PropFont)
  1687.                             X0 += TF_CharSpace[asc_val]+charKern;
  1688.                         else
  1689.                             X0 += AmigaFont->tf_XSize;
  1690.                     }
  1691.                 }
  1692.                 cliprect = cliprect->Next;
  1693.             }
  1694.             rp->cp_x = X0;
  1695.         }
  1696.         else
  1697.         {
  1698.             Y0 = (rp->cp_y)-AmigaFont->tf_Baseline;
  1699.  
  1700.             for (i=0;(i<count&&string[i]!=0);i++)
  1701.             {
  1702.                 asc_val     = string[i]-AmigaFont->tf_LoChar;
  1703.                 charX0      = (WORD)TF_CharLoc[asc_val].XPos;
  1704.                 charXSize   = (WORD)TF_CharLoc[asc_val].FontWidth;  
  1705.                 if (PropFont)
  1706.                     charKern    = (WORD)TF_CharKern[asc_val];
  1707.  
  1708.                 bitblt(charXSize,charYSize,                           // Width,Height
  1709.                             charX0,0,                                 // Origin x,y
  1710.                             rp->cp_x+charKern,Y0);                          // dest x/y (RP->Bitmap)
  1711.  
  1712.                 if (PropFont)
  1713.                     rp->cp_x += TF_CharSpace[asc_val]+charKern;
  1714.                 else
  1715.                     rp->cp_x += AmigaFont->tf_XSize;
  1716.             }
  1717.         }
  1718.         UnlockLib(); 
  1719.         if (rp->Layer)
  1720.             UnlockLayerRom(rp->Layer);
  1721.         return(TRUE);
  1722.     }
  1723.     return(-1);
  1724. }
  1725.  
  1726. LONG __asm GfxSetFont(register __a1 struct RastPort *rp,register __a0 struct TextFont *textFont )
  1727. {
  1728. /*
  1729.     25.9.94 :
  1730.  
  1731.         SetFont 100 % OK !
  1732.  
  1733.         was noch fehlt ist eine Speicherverwaltung der Cachebitmaps !
  1734.  
  1735.         The main code is 100% the original. But when using in a patch,
  1736.         the emulation crashes. Did not find out why. I guess it is something
  1737.         wrong in my Text()/InstallFont() code.
  1738.         - Well , it does work right now (29.10.94)
  1739.  */
  1740.     struct FontCacheList *cachelist,*new_font_entry;
  1741.     struct TextFont *AmigaFont;
  1742.     WORD   TIGA_Modulo;
  1743.     WORD   BitMap_XSize;
  1744.     APTR   TIGA_BitMap;
  1745.     CONFIG config;
  1746.  
  1747.     /* install the textFont into the RastPort */
  1748.  
  1749.     if (textFont) // NULL-Pointer übergeben !
  1750.     {
  1751.  
  1752.     /* -----------------------------------
  1753.      * this is what th original does 
  1754.      * SetFont() calls this gfx-function :
  1755.      * -----------------------------------
  1756.      */
  1757.  
  1758.         ExtendFont(textFont,NULL);  // debug !
  1759.  
  1760.         rp->TxHeight  = textFont->tf_YSize;
  1761.         rp->TxWidth   = textFont->tf_XSize;
  1762.         rp->TxBaseline = textFont->tf_Baseline;
  1763.         rp->AlgoStyle = (UBYTE)0;
  1764.         rp->Font = textFont;
  1765.  
  1766.     /* end of original */
  1767.  
  1768.  
  1769.         if (InstallFont(textFont))  // Additional Functions to install the Font on the a2410 
  1770.             return(0);
  1771.     }
  1772.     return(-1);  /* then exit */
  1773. }
  1774.  
  1775.  
  1776. void __asm GfxSetPointer(register __a0 struct Window *window,register __a1 UWORD *pointer,
  1777.                     register __d0 long height,register __d1 long width,register __d2 long xOffset,register __d3 long yOffset)
  1778. {
  1779. /*
  1780.     not included yet
  1781.     only a default Pointer is available !
  1782.     see InstallPointer() above.
  1783. */ 
  1784.     CURSOR Pointer;
  1785.  
  1786.     Pointer.width = width;
  1787.     Pointer.height = height;
  1788.     Pointer.hot_x = xOffset;
  1789.     Pointer.hot_y = yOffset;
  1790.     Pointer.data = (ULONG)pointer;
  1791.  
  1792.     InstallPointer(&Pointer);
  1793. }
  1794.  
  1795. void __asm GfxClearPointer(register __a0 struct Window *win)
  1796. {
  1797.     LockLib();
  1798.  
  1799.     set_curs_state(0);
  1800.  
  1801.     UnlockLib();
  1802. }
  1803.  
  1804. void __asm GfxPointerXY(register __a0 struct RastPort *rp,register __d0 long x,register __d1 long y)
  1805. {
  1806.     /*
  1807.         Will be replaced by GfxMoveSprite() some times !
  1808.     */
  1809.     LockLib();
  1810.  
  1811.     set_curs_xy(x,y);
  1812.  
  1813.     UnlockLib();
  1814. }
  1815.  
  1816. void __asm GfxSetRGB4(register __a0 struct ViewPort *vp,
  1817.         register __d0 long index,
  1818.         register __d1 unsigned long red,
  1819.         register __d2 unsigned long green,
  1820.         register __d3 unsigned long blue )
  1821. {
  1822.     LockLib();
  1823.  
  1824.     set_palet_entry(index,(red*16),green*16,blue*16,0);
  1825.  
  1826.     UnlockLib();
  1827. }
  1828.  
  1829. void __asm GfxSetRGB32(register __a0 struct ViewPort *vp,
  1830.         register __d0 unsigned long n,
  1831.         register __d1 unsigned long r,
  1832.         register __d2 unsigned long g,
  1833.         register __d3 unsigned long b )
  1834. {
  1835.     LockLib();
  1836.  
  1837.     set_palet_entry(n,r,g,b,0);
  1838.  
  1839.     UnlockLib();
  1840. }
  1841.  
  1842. LONG __asm GfxBltBitMap(register __a0 struct BitMap *srcBitMap,
  1843.                         register __d0 long xSrc, register __d1 long ySrc,
  1844.                         register __a1 struct BitMap *destBitMap,
  1845.                         register __d2 long xDest,register __d3 long yDest,
  1846.                         register __d4 long xSize,register __d5 long ySize,
  1847.                         register __d6 unsigned long minterm,register __d7 unsigned long mask,
  1848.                         register __a2 PLANEPTR tempA )
  1849. {
  1850.     struct TigaScreen *ts;
  1851.     struct BMCacheList *cachelist;
  1852.     struct ChunkyMap *chunkymap;
  1853.     long   i,planesize,plane,y;
  1854.     long   width,height,pitch,workbuffer;
  1855.     ULONG  xoffset,xrest;
  1856.     UBYTE  col,depth;
  1857.   
  1858. /*
  1859.  *  do not use dynamic buffer any more - bufmem is static now
  1860.  */
  1861.  
  1862.     LockLib();
  1863.  
  1864.     set_clip_rect(1024,1024,0,0);
  1865.  
  1866.     ts = &(globals.tigascreen);
  1867.  
  1868. /* Wenn Source und Target am Screen liegen : bitblt() */
  1869. // --------------------------------------------------
  1870.  
  1871.     if (destBitMap == globals.bitmap)
  1872.     {
  1873.      if ((minterm) == 0)
  1874.      {
  1875. #ifdef DEBUG
  1876.         KPrintF("Blt:CLEAR - Miniterm (%02lx)\n",minterm);
  1877. #endif
  1878.         set_ppop(3);  // dest = 0 !
  1879.  
  1880.         fill_rect(xSize,ySize,xDest,yDest);
  1881.      }
  1882.      else
  1883.      {
  1884.       if ((srcBitMap == globals.bitmap)) // && (destBitMap == globals.bitmap))
  1885.       {
  1886. #ifdef DEBUG
  1887.         KPrintF("Blt:ONSCREEN - Miniterm (%02lx) \n",minterm);
  1888. #endif
  1889.         switch (minterm)
  1890.         {
  1891.             case 0x00 : set_ppop(3);
  1892.                         break;
  1893.             case 0xC0 : set_ppop(0);
  1894.                         break;
  1895.             default :   set_ppop(0);
  1896.                         break;
  1897.         }
  1898.         transp_off();
  1899.  
  1900.         set_srcbm(0,0,0,0,0);
  1901.         set_dstbm(0,0,0,0,0);
  1902.         bitblt(xSize,ySize,xSrc,ySrc,xDest,yDest);
  1903.         synchronize();
  1904.      }
  1905.  
  1906. /* Wenn nur das Target am Screen liegt : hst2gsp() + planar2chunky ! */
  1907. // -----------------------------------------------------------------
  1908.  
  1909.      if ((srcBitMap != globals.bitmap))// && (destBitMap == globals.bitmap))
  1910.      {
  1911.  
  1912. #ifdef DEBUG
  1913.         KPrintF("Blt:OFFSCREEN - Miniterm (%02lx) \n",minterm);
  1914. #endif
  1915.  
  1916. /*
  1917.         switch (minterm)
  1918.         {
  1919.             case 0x00 : set_ppop(3);
  1920.                         break;
  1921.             case 0xC0 : set_ppop(0);
  1922.                         break;
  1923.             default :   set_ppop(0);
  1924.                         break;
  1925.         }
  1926.         transp_off();
  1927.         if (cachelist = FindBitmap(srcBitMap))
  1928.         {
  1929.             chunkymap = cachelist->chunkymap;
  1930.             host2gspxy(chunkymap->data,chunkymap->xSize,
  1931.                 ts->ScreenAddr,ts->Pitch,
  1932.                 xSrc,ySrc,
  1933.                 xDest,yDest,
  1934.                 xSize,ySize,
  1935.                 chunkymap->depth,INTEL_BYTES);
  1936.         }
  1937.         else
  1938.         {    
  1939. */
  1940. /*
  1941.     should be a size checking here :
  1942.     size < MinCacheSize :
  1943.         kein Cache -> selectives Planar to chunky :
  1944.             CopyPlane2Chunky(planes,chunkymap,Base,xSize,ySize,pitch);
  1945.             host2gspxy(chunky,ts->ScreenAddr,ts->pitch,0,0,xDest,yDest,xSize,ySize);
  1946. */
  1947. /*
  1948.             if (chunkymap = Plane2Chunky8(srcBitMap))
  1949.             {
  1950.                 host2gspxy(chunkymap->data,chunkymap->xSize,
  1951.                         ts->ScreenAddr,ts->Pitch,
  1952.                         xSrc,ySrc,
  1953.                         xDest,yDest,
  1954.                         xSize,ySize,
  1955.                         chunkymap->depth,INTEL_BYTES);
  1956.  
  1957. #ifndef NO_BM_CACHE
  1958.                if (!(InsertChunky(chunkymap,srcBitMap)))
  1959. #endif
  1960.                 {
  1961.                     FreeVec(chunkymap->data);
  1962.                     FreeVec(chunkymap);
  1963.                 }
  1964.             }
  1965. #ifdef DEBUG
  1966.             else
  1967.                 KPrintF("Blt:NO CHUNKY MEM \n");
  1968. #endif
  1969.         }
  1970. */
  1971.  
  1972. /*
  1973.  *      This is new : use 34010 to convert plane to chunky !
  1974.  *      OR (set_fcolor(1<<i)) TO Dest does work, but I do have some troubles.
  1975.  *      That damn thing does not run without errors, I do not know what's wrong.
  1976.  *      I think it could be a TIGA implementation bug. 
  1977.  *      It does work in most cases but it forgets to blit from time to time ...?
  1978.  *      Do not use dynamic allocation any more - I use a static buffer now ! (maybe this fix some probs)
  1979.  *
  1980.  *      WARNING : host2gxpxy() requires a dest. addr. and pitch that is a multiple of 16 !!!!
  1981.  *
  1982.  *  **** WATCH the line "synchronize();" this fixes my troubles !!! ****
  1983.  */
  1984.         transp_off();
  1985.         xoffset = (xSrc >> 3)&0xff;     // => xSrc/8, max 8 Bit
  1986.         xrest   = (xSrc) & 0x7L;        // => xSrc % 8;  == & %111
  1987.         width   = ((xSize>>3)+2)&~1L;   // to round bytes left
  1988.         pitch   = width<<3;             //  planepitch in bits, WORD boundary
  1989.         planesize = (WORD)width*(WORD)ySize;
  1990.  
  1991.         depth = (UBYTE)srcBitMap->Depth;
  1992.         workbuffer = bufmem;
  1993.         if (planesize <= bufmemsize)
  1994.         {
  1995.             set_srcbm(bufmem,pitch,pitch,ySize,1);  // the new with is the pitch because it is only 1 bit/pixel
  1996.             set_dstbm(0,0,0,0,0);                   // destination is the screen
  1997.             /*
  1998.              *   the plane 0 ( using only plane 0 does work ...)
  1999.              */
  2000.             set_ppop(DST_IS_SRC);           // draw first plane only ! color 1 ( = Plane 1) 
  2001.             host2gspxy(srcBitMap->Planes[0],srcBitMap->BytesPerRow,
  2002.                         workbuffer,pitch,   // is bitsize
  2003.                         xoffset,ySrc,       // have to get the x-offset in BYTES which is xSrc/8
  2004.                         0,0,                // transform Sx/Sy -> 0/0 !
  2005.                         width,ySize,        // this is a new width, rounded first and last byte, and WORD justified
  2006.                         8,BIT_SWAP);        // I copy BytesPerRow x ySize, so host2gsp is faster than pixsize is 1 !
  2007.  
  2008.             set_colors(1,0);                // plane 0 = col 1, 0 -> clear Background
  2009.             bitblt(xSize,ySize,xrest,0,xDest,yDest);  // the xrest is the rest of xSrc/8 in bits
  2010.  
  2011.             synchronize();
  2012.  
  2013.             /*
  2014.              *  the rest of the planes are added to plane 0 (if exists)
  2015.              */
  2016.             set_ppop(SRC_OR_DST);           // "or" the other planes to the dest
  2017.             for (col = 1; col < depth ;col++)
  2018.             {
  2019.                 host2gspxy(srcBitMap->Planes[col],srcBitMap->BytesPerRow,
  2020.                             workbuffer,pitch,   // is bitsize
  2021.                             xoffset,ySrc,       // have to get the x-offset in BYTES which is xSrc/8
  2022.                             0,0,                // transform Sx/Sy -> 0/0 !
  2023.                             width,ySize,        // this is a new width, rounded first and last byte, and WORD justified
  2024.                             8,BIT_SWAP);
  2025.  
  2026.                 set_fcolor(1<<col);
  2027.                 bitblt(xSize,ySize,xrest,0,xDest,yDest);  
  2028.  
  2029.                 synchronize();
  2030.             }
  2031.             set_srcbm(0,0,0,0,0);
  2032.             set_ppop(0);
  2033.         }
  2034.       }
  2035.      }
  2036.     }
  2037.  
  2038. /* Wenn nur die Source am Screen liegt : gsp2hst() + puffern !
  2039.    noch nicht. Kommt noch, wird aber ein bißchen dauern !
  2040. */
  2041. /*
  2042.     if ((destBitMap != globals.bitmap) // &&(srcBitMap == globals.bitmap))
  2043.     {
  2044. #ifdef DEBUG
  2045.         KPrintF("Blt:CASHFLUSH - Miniterm (%02lx) \n",minterm);
  2046. #endif
  2047.         if (cachelist = FindBitmap(destBitMap))
  2048.         {
  2049.             cachelist->chunkymap->flag |= BMF_FORCE_FLUSH;
  2050.             FlushCacheMap(cachelist);
  2051.         }
  2052.     }
  2053. */
  2054.     UnlockLib();
  2055.     return(0);
  2056. }
  2057.  
  2058. struct ChunkyMap __asm *GfxBltTiga(register __a0 struct BitMap *srcBitMap,
  2059.                         register __d0 long xSrc, register __d1 long ySrc,
  2060.                         register __a1 PTR gsp_addr,
  2061.                         register __d2 long xDest,register __d3 long yDest,
  2062.                         register __d4 long xSize,register __d5 long ySize)
  2063. {
  2064.     /*
  2065.         Used to copy a planar bitmap to chunky tiga screen. 
  2066.         gsp_addr could be a buffer address in gsp_memory. 
  2067.         Is not supported yet (no function to allocate gsp_mem in gfx.library !).
  2068.         So make sure gsp_addr = NULL when calling !
  2069.     */
  2070.     struct ChunkyMap *chunkymap;
  2071.     struct TigaScreen *ts;
  2072.  
  2073.     LockLib();
  2074.  
  2075.     chunkymap = Plane2Chunky8(srcBitMap);
  2076.  
  2077.     ts = &globals.tigascreen;
  2078.  
  2079.     gsp_addr = ts->ScreenAddr;
  2080.  
  2081.     host2gspxy(chunkymap->data,chunkymap->xSize,
  2082.                 gsp_addr,ts->Pitch,
  2083.                 xSrc,ySrc,
  2084.                 xDest,yDest,
  2085.                 xSize,ySize,
  2086.                 chunkymap->depth,INTEL_BYTES);
  2087.  
  2088.     UnlockLib();
  2089.  
  2090.     return(chunkymap);
  2091. }
  2092.  
  2093. void __asm BltChunkyMap(register __a0 struct ChunkyMap *chunkymap,
  2094.                         register __d0 long xSrc, register __d1 long ySrc,
  2095.                         register __d2 long xDest,register __d3 long yDest,
  2096.                         register __d4 long xSize,register __d5 long ySize)
  2097. {
  2098.     struct TigaScreen *ts;
  2099.     PTR gsp_addr;
  2100.  
  2101.     LockLib();
  2102.  
  2103.     ts = &globals.tigascreen;
  2104.  
  2105.     gsp_addr = ts->ScreenAddr;
  2106.  
  2107.     host2gspxy(chunkymap->data,chunkymap->xSize,
  2108.                 gsp_addr,ts->Pitch,
  2109.                 xSrc,ySrc,
  2110.                 xDest,yDest,
  2111.                 xSize,ySize,
  2112.                 chunkymap->depth,INTEL_BYTES);
  2113.  
  2114.     UnlockLib();
  2115. }
  2116.  
  2117. BOOL __asm GfxSetUpScreen(register __a0 struct Screen *screen)
  2118. {
  2119.     /*
  2120.         Connects a Intuition Screen to an entry with Infos about the Tiga-display.
  2121.     */
  2122.     CONFIG config;
  2123.     struct TigaScreen *tigascreen;
  2124.  
  2125.     if (!screen) return(FALSE);
  2126.  
  2127.     LockLib();
  2128.  
  2129.     get_config(&config);    
  2130.  
  2131.     globals.screen = screen;
  2132.     globals.bitmap = screen->RastPort.BitMap;
  2133.  
  2134.     tigascreen = &(globals.tigascreen);
  2135.  
  2136.     tigascreen->ScreenAddr = config.display_mem_start;
  2137.     tigascreen->Width      = config.mode.disp_hres;
  2138.     tigascreen->Height     = config.mode.disp_vres;
  2139.     tigascreen->Depth      = config.mode.palet_gun_depth;
  2140.     tigascreen->Pitch      = config.mode.disp_pitch;
  2141.  
  2142.     UnlockLib();
  2143.     return(TRUE);
  2144. }
  2145.  
  2146. LONG __asm GfxCheckTiga(register __a1 struct BitMap *bitmap)
  2147. {
  2148. /*
  2149.     checks out if an operation is performed on Tiga screen or native Amiga display !
  2150.     (not used yet !)
  2151. */
  2152.     struct BMCacheList *cachelist;
  2153.  
  2154.     cachelist = FirstBitMapEntry;
  2155.     while (cachelist)
  2156.     {
  2157.         if ((LONG)cachelist->bitmap == (LONG)bitmap)
  2158.             return(1L);
  2159.         cachelist = cachelist->next;
  2160.     }
  2161.     return(0L);
  2162. }
  2163.  
  2164. LONG __asm GfxCheckBitMap(register __a1 struct BitMap *bitmap)
  2165. {
  2166.     if ((LONG)(globals.screen->RastPort.BitMap) == (LONG)bitmap) return(TRUE);
  2167.  
  2168.     return(FALSE);
  2169. }
  2170.  
  2171. LONG __asm GfxCheckRP(register __a1 struct RastPort *rp)
  2172. {
  2173.     struct RastPort *RP;
  2174.  
  2175.     RP = &(globals.screen->RastPort);
  2176.  
  2177.     if ((LONG)RP == (LONG)rp) return(TRUE);
  2178.  
  2179.     return(FALSE);
  2180. }
  2181.  
  2182. LONG __asm GfxCheckVP(register __a1 struct ViewPort *vp)
  2183. {
  2184.     struct ViewPort *VP;
  2185.  
  2186.     VP = &(globals.screen->ViewPort);
  2187.     if ((LONG)VP == (LONG)vp) return(TRUE);
  2188.  
  2189.     return(FALSE);
  2190. }
  2191.  
  2192. /* 
  2193.     Area-Draw() Befehle !
  2194. */
  2195. LONG __asm GfxAreaEnd(register __a1 struct RastPort *rp )
  2196. {
  2197.     int i;
  2198.     long cnt,ptrnsz;
  2199.     long XOffset=0,YOffset=0;
  2200.     POINT    *pnts;
  2201.     PATTERN gsp_ptrn;
  2202.     struct ClipRect *cliprect;
  2203.  
  2204.     if (rp)
  2205.     {
  2206.         if (rp->Layer)  
  2207.         {
  2208.             LockLayerRom(rp->Layer);
  2209.             XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
  2210.             YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
  2211.         }
  2212.  
  2213.         LockLib();    
  2214.  
  2215.         DwMode(rp);
  2216.  
  2217.         gsp_ptrn.data = NULL;
  2218.  
  2219.         if (rp->AreaPtrn)
  2220.         {
  2221.                 ptrnsz = ((rp->AreaPtSz)<=4) ? (1<<(rp->AreaPtSz)) : 16;
  2222.                 gsp_ptrn.width=16;
  2223.                 gsp_ptrn.height=16;  // tiga supports only 16 lines !!!
  2224.                 gsp_ptrn.depth=1;    // no more than 1 plane now !
  2225.                 gsp_ptrn.data=(PTR)gsp_malloc(32);  // 32 bytes = 16 WORDS space for pattern !
  2226.                 if (ptrnsz==16)
  2227.                     host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data),2*ptrnsz,2);  // WORD aligned
  2228.                 else
  2229.                     for (i=0;i<=0xF0;i+=(0x10*ptrnsz)) // bit offset to current pos. - WORD aligned !
  2230.                         host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data)+i,2*ptrnsz,2);
  2231.                 set_patn(&gsp_ptrn);
  2232.         }   
  2233.  
  2234.         AreaDraw(rp,rp->AreaInfo->FirstX,rp->AreaInfo->FirstY);
  2235.         cnt = rp->AreaInfo->Count;
  2236.         pnts = (POINT*)rp->AreaInfo->VctrTbl;
  2237.  
  2238.         cliprect = rp->Layer->ClipRect;
  2239.         while (cliprect)
  2240.         {
  2241.             if (ClipIt(cliprect,NULL)!=CLIP_OUT)
  2242.             {
  2243.                 set_draw_origin(XOffset,YOffset);
  2244.  
  2245.                 if (!rp->AreaPtrn) 
  2246.                     fill_polygon(cnt,pnts);
  2247.                 else 
  2248.                     patnfill_polygon(cnt,pnts);
  2249.             }
  2250.             cliprect = cliprect->Next;
  2251.             set_draw_origin(0,0);
  2252.         }
  2253. /*
  2254.         if ((rp->Flags)&AREAOUTLINE)
  2255.         {
  2256.             set_fcolor(rp->AOlPen);
  2257.             draw_polyline(cnt,pnts);
  2258.         }
  2259. */
  2260.         if (gsp_ptrn.data)  gsp_free(gsp_ptrn.data);
  2261.  
  2262.         rp->AreaInfo->VctrPtr=rp->AreaInfo->VctrTbl;
  2263.         rp->AreaInfo->FlagPtr=rp->AreaInfo->FlagTbl;
  2264.         rp->AreaInfo->Count=0;
  2265.  
  2266.  
  2267.         UnlockLib();
  2268.         if (rp->Layer)   UnlockLayerRom(rp->Layer);
  2269.  
  2270.         return(0);
  2271.     }
  2272.     return(-1);
  2273. }
  2274.  
  2275. LONG __asm GfxAreaMove(register __a1 struct RastPort *rp,register __d0 long x,register __d1 long y )
  2276. {
  2277.     int i;
  2278.  
  2279.     register long cnt;
  2280.     register UWORD ptrnsz;
  2281.     PATTERN gsp_ptrn;
  2282.  
  2283.     LockLib();
  2284.  
  2285.     set_colors(rp->FgPen,rp->BgPen);
  2286.     if (rp->AreaInfo->VctrPtr)
  2287.     {   
  2288.         cnt=rp->AreaInfo->Count;
  2289.         if (!rp->AreaPtrn)
  2290.             fill_polygon(cnt,rp->AreaInfo->VctrTbl);
  2291.         else 
  2292.         {
  2293.             ptrnsz = ((rp->AreaPtSz)<=4) ? (1<<(rp->AreaPtSz)) : 16;
  2294.             gsp_ptrn.width=16;
  2295.             gsp_ptrn.height=16;  // tiga supports only 16 lines !!!
  2296.             gsp_ptrn.depth=1;    // no more than 1 plane now !
  2297.             gsp_ptrn.data=(PTR)gsp_malloc(32);  // 32 bytes = 16 WORDS space for pattern !
  2298.             if (ptrnsz==16)
  2299.                 host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data),2*ptrnsz,2);  // WORD aligned
  2300.             else
  2301.                 for (i=0;i<=0xF0;i+=(0x10*ptrnsz)) // bit offset to current pos. - WORD aligned !
  2302.                     host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data)+i,2*ptrnsz,2);
  2303.             set_patn(&gsp_ptrn);
  2304.             patnfill_polygon(cnt,rp->AreaInfo->VctrTbl);
  2305.             gsp_free(gsp_ptrn.data);
  2306.         }
  2307.         if (rp->Flags&AREAOUTLINE)
  2308.         {
  2309.             set_fcolor(rp->AOlPen);
  2310.             draw_polyline(cnt,rp->AreaInfo->VctrTbl);
  2311.         }
  2312. //        FreeVec(rp->AreaInfo->VctrTbl);
  2313.         rp->AreaInfo->VctrPtr=NULL;
  2314.         rp->AreaInfo->Count=0;
  2315.         UnlockLib();
  2316.         return(1);
  2317.     }
  2318.  
  2319.     if (rp->AreaInfo->VctrTbl=(WORD *)AllocVec((rp->AreaInfo->MaxCount*4),MEMF_CLEAR))
  2320.     {
  2321.         rp->AreaInfo->FirstX=rp->cp_x=x;
  2322.         rp->AreaInfo->FirstY=rp->cp_y=y;
  2323.         rp->AreaInfo->VctrPtr=rp->AreaInfo->VctrTbl;
  2324.         *(rp->AreaInfo->VctrPtr++)=x;
  2325.         *(rp->AreaInfo->VctrPtr++)=y;
  2326.         *rp->AreaInfo->FlagPtr=(UBYTE)rp->Flags;
  2327.         rp->AreaInfo->Count=1;
  2328.         UnlockLib();
  2329.         return(0);
  2330.     }
  2331.     UnlockLib();
  2332.     return(-1);
  2333. }
  2334.  
  2335. LONG __asm GfxAreaDraw(register __a1 struct RastPort *rp,register __d0 long x,register __d1 long y )
  2336. {
  2337.     int i;
  2338.  
  2339.     register WORD cnt;
  2340.  
  2341.     
  2342.     if (rp->AreaInfo->VctrPtr)
  2343.     {
  2344.         LockLib();
  2345.  
  2346.         cnt=rp->AreaInfo->Count++;
  2347.         *(rp->AreaInfo->VctrPtr++)=x;
  2348.         *(rp->AreaInfo->VctrPtr++)=y;
  2349.  
  2350.         UnlockLib();
  2351.         return(0);
  2352.     }
  2353.     return(-1);
  2354. }
  2355.