home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-02-19 | 76.9 KB | 2,355 lines |
- /*
- File : gfx.c
- Date : 7.10.1994
- Author : Jürgen Schober
-
- Description :
- TIGA Graphics.library module
- This is the basic low level graphics code I use for the WB Emulation
- on the A2410 TIGA !
-
- Uses my_macros instead of a2410/dev_macros.
- do not link with a2410.lib !
-
- ©1994/95 Jürgen Schober
-
- --------------------------------------------------------------------------------------------------------
-
- BASIC NOTES :
-
- sorry, I made my notes in german...I will translate it if I have time sometimes ...
- If somebody wanna do - just do it :-)
- I will use english for further notes ... I swear !
-
- LibBasics :
-
- Jede Funktion enthält als erste Funktion ein Makro, das einige
- a2410.device setups vornimmt und die library auf <BUSY> setzt.
- Am Ende wird <BUSY> wieder gelöscht.
- Jede Funktion ruft danach (in einer Schleife) ClipIt auf.
- ClipIt() baut die Clipping-Rechtecke auf.
- Danach wird der Zeichenmodus mittels DwMode() gesetzt und
- schließlich die Graphikoperation ausgeführt.
-
- 7.10.94 :
-
- Erste Arbeiten an der Draw()-Funktion.
- Untersuchungen über clipping. Im Layer->ClipRect steht das erste ClipRect,
- in ClipRect->bounds die Clipping-Grenzen. ClipRect->Next zeigt auf das
- nächste Clipping-Rechteck. Wenn ClipRect->prev == 0, dann nicht mehr
- clippen (?). Erste Implemetation von ClipLine(), jedoch in dieser Form
- nicht brauchbar. ClipLine() muß, falls die Linie ganz im ClipRect gezeichnet
- werden kann, das clipping unterbrechen ! Der Parameter <struct Layer> sollte
- gegen <struct ClipRect> ausgetauscht werden. Die x/y-Offsets müssen in
- Draw() dazuaddiert werden ! (noch nicht eingebaut !)
-
- Noch nicht kompilieren !
-
- 8.10.94
-
- Clipping geändert. Zum Clippen wird set_clip_rect() verwendet. Dadurch läßt sich
- eine globale Funktion <ClipIt()> zum clippen _aller_ Graphikoperationen einsetzen.
- (Auch Bitmaps, Füllfunktionen, Areafunktionen ...)
- Kompiliert und getestet ! Funktioniert teilweise. Wenn ein Fenster im Vordergrund
- aktiviert wird, kann es passieren, daß die Cliprects nicht mehr stimmen (?).
- DwMode() zum Setzten der DrawModes wurde aus der gsp_gfx.library, RectFill() übernommen.
- Muß eventuell korrigiert werden !
-
-
- 12.10.94
-
- Außer Matura gemacht und durchgeflogen (Ärger) hab' ich noch das Clipping fertig.
- Die ClipRects des aktuellen RastPort bzw. Layer werden durch ClipRect->lobs gekennzeichnet.
- Ist lobs == NULL, gehoert das Rectangle zum aktuellen Window, lobs !=NULL -> anderes Fenster.
- Funktioniert bis jetzt. Ich weiß allerdings nicht, was mit der Linie passiert, die hinter einem
- Fenster gezeichnet wird. Müßte eigentlich in eine temporäre Bitmap gezeichnet werden, .. ???
-
- Ach ja, und RectFill() wurde schon am 8.10.94 aus der gsp_gfx.library geholt !
- (Mein line-clipping macht aber keine Fehler, im Gegensatz zur Picasso !)
-
- 13.10.94
-
- SetFont() / Text() aus der gsp_gfx.library übernommen. Neu ist, das SetFont() jetzt lokal
- InstallFont() aufruft um einen Zeichensatz auf die 2410 zu kopieren. Beim Öffnen der Lib wird
- InstallFont() aufgerufen und topaz 8 als "ROM"-Font installiert. Default ist nun topaz 8.
- Text() sollte eigentlich so funktionieren. Ich hab' da eine Bitmap auf der Tiga-Seite installiert,
- aus der ich mit bit_blt() die einzelnen Zeichen rausschneide. Leider muß ich das für jeden
- Buchstaben einzeln machen. Dadurch wirds natürlich (relativ) langsam. (Sonst müßte ich den
- ganze Text() Algorithmus auf die TIGA portieren - aber wie ???).
-
- SetFont() muß noch mal überarbeitet werden. Beim Umkopieren in die Cachebitmap wird keine
- Aussparung für das Zeichenkerning vorgenommen. Das ist ein bißchen aufwendig und dazu hab'
- ich jetzt keine Lust.
-
- 17.10.94
-
- FuncEntry und FuncExit durch LockLib() und UnlockLib() ausgetauscht. Locking-Mechanismus mit
- Semaphoren realisiert. Semaphoren dürften funktionieren (kann ich nicht real testen, aber ich
- habe meine Line-Routine gegen Draw ausgetauscht, und da ist es gelaufen). Das Problem liegt
- jetzt anscheinend am FindTask(NULL); das ist die Methode, wie das device den aktuellen Task
- findet. Bei einem zweiten Task -> crash !
-
- 18.10.94
-
- LockLib()/UnlockLib() funktioniert jetzt ! Wurde mit SignalSemaphoren verwirklicht.
- ObtainSemaphoreShared() hat nicht funktioniert, ObtainSemaphore funktioniert.
- LockLayerRom() benutzt auch Semaphoren, kann sein, daß ich da in der Verschachtelung einen
- Fehler gehabt habe'. (?) LockLib() macht ein ObtainSemaphore(ss_lock), wobei die ss_lock
- die öffentliche (public) SignalSemaphore für die gfx.library ist. Name : TIGA_SEMAPHORE .
- UnlockLib() "released" die Semaphore wieder.
- Außerdem habe ich noch ein paar Mouse-Funktionen aus der gsp_gfx.library geholt. Default wird
- jetzt beim OpenLibrary() ein Mousezeiger installiert (der normale Amigamauszeiger), geht was
- schief, wird der TIGA-Pointer aktiviert. Somit steht sofort ein Mauszeiger zur Verfügung.
- Ein Maustreiber kann jetzt parallel (als eigener Task) laufen. (s. Mouse.c bzw. Mouse)
-
- Jetzt habe ich noch schnell die zwei Funktionen DrawEllipse() und AreaEllipse geholt. Mal sehen
- ob ich die noch ans neue Konzep anpassen kann.
-
- 20.10.94
-
- DrawEllipse()/AreaEllipse hab' ich letztens noch geschafft. Heute habe ich noch WritePixel(),
- SetRGB4() und SetRGB32() eingebaut.
- Bei RectFill habe ich einen Fehler behoben. Pattern.data wurde nicht mit NULL initialisiert.
- Speicher wurd mit if (pattern.data) gsp_free(pattern.data) erledigt. Und wenn zufällig was im
- data stand -> crash. Ich möchte noch probieren, ob die Priorität der Semaphoren was mit dem
- DOS-deadlock zu tun hat. Die Emulation läuft jetzt (verblüffend) stabil. Leider hängt sich
- dann die Workbench von Zeit zu Zeit auf. z.B. wenn ich ein Verzeichnis aufmache, bleibt se hängen .(?)
- Der TIGA Treiber läuft aber weiter ! Ich kann Fenster verschieben usw.
- Priorität auf -5 gesetzt. -> No way. Hat sich nix geändert !
-
- Ah ja. Noch was. Bei den Drawmodes. Wenn die rp->FgPen == 0, muß transparent ausgeschalten werden
- (transp_off()). Die PPOP der tiga funktionieren so : Transparent, wenn A verkn. B = 0. Wenn
- also ( (A = rp->FgPen = 0) ODER B (ganz egal was B ist) ) = NULL ! -> Transparent. Das merkt man dann,
- Wenn ein Fenster inaktiv wird. Da wird's nämlich mit col0 (d.h. rp->FgPen = 0) gezeichnet.
-
-
- 18:10 . Vorlesung ist wieder einmal gerammelt voll. Das nächste mal ein halbe Stunde frühere !!
-
- So, jetzt werde ich mal den ersten Blitversuch starten. Dazu wird eine Liste eingeführt, wo die
- Bitmap des aktuellen (Fronmost) Screens eingetragen wird. Anfangs wird nur von host->gsp und von
- gsp->gsp geblittet. Liegt ein Target im Screen, host2gspxy(), liegen Source und Target im Screen
- bitblt(). Genauso wird entschieden, ob eine Funktion gezeichnet wird oder nicht. Später könnte man
- dann bei gsp->host die Bitmap mit in einen Buffer kopieren und dort cachen. Sobald aber das Target
- im cache auftaucht, ist der Eintrag nasty !
- Die Liste soll eine Struktur sein.
-
- struct globals {
- struct Screen *screen; // der aktuelle Screen
- struct BitMap *bitmap; // dessen Bitmap
- struct tiga_Screen *tiga_screen; // die Adresse des Tiga screens.
- ... // und vielleicht noch was ...
- };
-
- 21.10.94
-
- Gestern noch ist die erste Version von GfxBltBitmap() gelaufen. Normalerweise wird mit set_srcbm(0,..)
- /sert_dstbm(0,..) die Bitmap des aktuellen Screens eingestellt. Wenn man aber nur am Schirm blittet
- (ohne Buffer) muß die Adresse auf DisplayAddr eingestellt werden ! set_xxbm(config.display_mem_start) !
- (Laut Tiga-Handbuch darf das gar nicht gehen !)
- Es wird kein tempRas und keine mask unterstützt, die ppop sind im Moment immer {A ODER B}. Die
- muß ich dann noch an die Miniterms anpassen. Allerdings kennt die Originalfunktion 2 Sourcen und ein
- Target !
-
- 22.10.94
-
- GfxBltBitMap() kann jetzt auch planare Bitmaps vom Amiga auf den Tigascreen blitten. Ist zwar ein
- bißchen langsam, aber es funktioniert. Ich habe die Routine in die (lokale) Plane2Chunky()-Routine
- ausgelagert und noch eine Funktion GfxBltTiga() eingebaut. Dadurch kann diese Funktion auch als
- planar -> chunky Konverter benutzt werden. (Ist allerdings noch nicht wirklich fertig, weil das Ziel
- immer auf dem Tiga Schirm liegt !).
-
- 22.10.94 (abends)
-
- Der Planar->Chunky Modus wurde ein bißchen überarbeitet. Es wird die gesamte planare Bitmap in eine
- chunky map gewandelt. Dadurch steht sie als gecachte Bitmap zur Verfügung. Aus dieser wird nun mit
- host2gspxy() auf die Tiga geblittet. Im Moment ist der Cache Mechanismus noch nicht eingebaut,
- das heißt es wird vor host2gspxy() _immer_ planar -> chunky gewandelt, und danach der Speicher
- wieder freigegeben. Das änder sich aber gerade. Ich arbeite gerade an cer Cacheverwaltung.
-
-
- 23.10.94
-
- So, Cachefunktionen sind eingebaut. Sie funktionieren - teilweise. Ich habe nur Bitmaps ab einer
- bestimmten Größe gecachet. Dadurch ist der Screenrefresh relativ schnell.
- Habe mir gedacht, schau mir nochmal an, welche Funktion in der Shell bis zum Ende des Fensters löscht.
- Dort wird ein Write() benutzt, und das ruft dann Text() auf. Aber leider weiß ich nicht wer bis zum
- Ende löscht. ClearEOL() o. ClearScreen() sind's jedenfalls nicht !
-
- 25.10.94
-
- SetFont() habe ich noch einmal geändert (ObtainSemaphore() statt LockLib() ) und jetzt scheint's wieder zu
- funktionieren.
- Bei den Bitmaps habe ich das Gefühl (ja _Gefühl !) , daß da was beim Speicheranfordern von Plane2Chunky8()
- nicht hinhaut. Wenn ich von 16 auf 256 Farben umschalte, habe ich irgendwann keine Icons mehr da. Das
- passiert eigenlich nur dann, wenn a) die Bitmaps nicht im Cache stehen und b) beim planar->chunky wandeln
- zu wenig Speicher da ist. Werde ich mir dann anschauen.
-
- Wenn Verzeichnisse aufgemacht werden, wird der Hintergrund gelöscht. Ich dachte das macht SetRast(),
- aber auch wenn ich diese Funktion einbaue tut sich nix. (?)
-
-
- 28.10.94
-
- Funktionstest :
-
- GfxDraw() - scheint zu funktionieren; Ein Problem tritt bei der Lasofunktion auf.
-
- GfxWritePixel() - hat keinen Crash verursacht
-
- GfxRectFill() - läuft auch stabil - außer beim SetFont(). Da wird irgendwo rausgemalt (?)
-
- GfxDrawEllipse() - ist stabil und schneller als das original (s. <Clock>)
-
- GfxAreaEllipse() - läuft auch stabil (s. <Clock>) braucht aber kein InitArea() !
-
- GfxText() - schaut auch stabil aus, aber ist mit der Methode ziemlich langsam.
-
- GfxSetFont() - Läuft jetzt auch
-
- GfxSetRGB4() - dito
-
- GfxSetRGB32() - dito
-
- GfxBltBitMap() - da gibt's göbere Probleme, von der Funktion her läuft's, aber ich denke ich habe
- Schwierigkeiten mit der Blitter-Synchronisation ... (use source debug !!!)
-
-
- Lustig - ohne BltBitMap() funktioniert die Emulation verdammt stabil ! Der TIGA-Treiber hat jetzt
- einen Algorithmus eingebaut, der nur auf dem eigenen Screen Zeichnet. - Und das läuft. Ich habe mal
- von der TIGA das Palette-Prefs-Programm gestartet - mit Farbrad. Der öffnet tatsächlich einen eigenen
- Screen und schaltet die TIGA ab !!!
-
-
- 2.11.94
-
- So, irgendwann zw. 28.10 u. 2.11. hab' ich noch AreaEnd() eingebaut. AreaMove()/AreDraw() wird vom
- Original übernommen. Gezeichnet wird dann mit AreaEnd(). (Deshalb wird nur AreaEnd() gepatched)
- Area-Befehle haben anscheinend untereinander Schwierigkeiten. (Resourcen , die freigegeben werden oder
- so). Deshalb ruft AreaEllipse()/DrawEllipse() auch die Originalfunktion auf - dann läuft auch
- die Uhr !
-
- BltBitMap() scheint doch zu funktionieren. Ich hab's jetzt mit BitMaps probiert. Wenn als Backgrounds nur
- Brushes benutzt werden, funktionierts. Ich weiß nicht was bei Pattern anders ist. Wenn ich als Fenster-
- hintergrund Pattern benutze, funktioiert's nur ohne BitMap cache. Wenn ein Icon gezeichnet wird, das so groß ist,
- daß die Bitmap gecachet wird, haben auf einmal alle anderen Icons auch die selbe BitMap. Bewege ich ein
- Fenster über die Icons, sodaß die refreshed werden, habe sie nach dem Refresh ihre richtige BitMap (?).
- Außerdem fehlt ein Modus der benutzt wird, falls die Chunky2Plane Routine zu wenig Speicher hat und
- wenn beim on-screen blitten der Buffer zu groß wird. Da fehlen zwei Zeilen-Blit-Modi. D.h. es wird
- Zeilenweise kopiert - wobei beim on-screen-blitten ein Ascent/Descent Mode eingebaut werden muß !
-
- 10.12.94
-
- Eigentlich arbeite ich am EGS Treiber ... aber dort habe ich immer Stehzeiten, weil ich Infos
- vom Uli Sigmund brauche ... also hab' ich mir gedacht ich schreibe meine Emulation weiter.
- Außerdem steckt derzeit mehr Know-How in der Emulation als in EGS ... und meine Emulation ist schneller.
- Und durchs EGS Programmieren habe ich neue Debug-Möglichlkeiten gefunden.
-
- Jetzt muß ich noch schnell was ausprobieren :
- Der Andreas Feck (?) hat mir geschrieben, daß beim öffnen von einem Fenster mit Miniterm = 0 geblittet
- wird -> d.h. src & (~src) = 0 !! logo...
- (Ich werd's mal schnell mit einem fill_rect() mit fcol = 0 probieren !
-
- 13.12.94
-
- Ich habe die Planar->Chunky routine in assembler neu geschrieben. Ist echt schnell.
- (subjectiv schneller als die Picasso :-/ ) - aber irgendwas geht nicht.
-
- 14.12.94
-
- Die Assmebler-Routine läuft =:-) !!
- War ganz schön viel arbeit. Hab' das Ding aber dann "bitweise" debuged. und jetzt sollte es eigentlich
- gleich funktionieren wie vorher die C-Routine ... aber 100% schneller.
- Ich glaube wenn ich nicht in einen Buffer konvertieren und dann auf die (langsame) Tiga blitten müßte,
- wäre ich schneller als die Picasso !
-
- Da sind jetzt zwei neue Preprozessor-Flags :
-
- DEBUG : ist eh schon alt zum debuggen
- neu sind
- ASSEM_P2C : assemblerroutine für planar to chunky benutzen
- NO_BM_CACHE : compiliert ohne Bitmapcache !
-
- 17.12.94
-
- Durch's EGS programmieren habe ich einiges an der InstallFont-Routine geändert.
- Ich komme jetzt ohne Multiplikation aus. Außerdem habe ich die Wortausrichtung der
- 1 Bit Text-Maske korrigiert.
-
- 9.1.95
-
- Ebenfalls durchs EGS programmieren habe ich dort gesehen, daß der Text mit FillMask
- gezeichnet wird. Das entspricht ungefär dem Original BltTemplate() oder BltPattern() Aufruf.
- Außerdem ist das schneller als meine eigene TextRoutine ! (tatsächlich !)
- Ist irgendwie logisch. Durch das "blitten" einer 1 Bit Maske vom FastRAM und dann mit
- bitblt() auf der TIGA (1 nach 8 bit) erhalte ich immerhin einen Kompressionsfaktor
- von (ca) 1:8 !!
- Ah ja, und auf der EGS Seite habe ich schon das Mausimage eingebaut. Das ist eigentlich
- kompatibel zur Amiga Maus. Das heißt ich muß das mal bei Zeiten rüberholen !
- Dadurch fällt aber das Maus- und das Font-Caching weg ! Das Mausimage jedesmal umzukopieren
- ist schnell genug ! Und der Font bleibt dann 1 bittig auf der AmigaSeite !
- (eventuell muß ich da zuerst in eine 1 BitMaske auf der AmigaSeite schreiben und dann
- die ganze Maske auf die TIGA blitten !)
- Ja und außerdem brauche ich mir keine Gedanken mehr übers Kerning zu machen.
- Und EGS CopyBitMap (blitting on screen) unterstütz jetzt auch eine Buffer overflow
- beim top down copy. (gsp2gsp) Die Routine gehört da auch noch eingebaut.
-
- 17.1.95
-
- Seit 2 Tagen arbeite ich an einem plane-2-chunky Konverter der bitblt() und dessen
- Möglichkeit nutzt, 1 bit BitMaps in 8 Bit Chunky Maps zu "extraieren".
- Dazu wird die 1 Bitplane mit der aktuellen Farben fcolor und bcolor in die chunky map 8
- gestanzt. Plane[0] wird mit DEST_IS_SRC und set_colors(1,0) geblittet d.h. bit 1 =
- bit eins in chunky map, 0 bleibt null. Jede weitere Plane wird mit color(1^i) und bcol=0 + transp
- als SRC_OR_DEST geblittet (dazu geodert).
- pmask funktioniert da nicht, weil diese auch beim read des bitblt() aktiv wäre und das geht gerade
- bei plane 0 , alle anderen planes würden ausmaskiert werden !
- Leider habe ich den verdacht, daß die TIGA Implementierung gerade bei Transferbefehlen nicht
- Fehlerfrei arbeitet. Es kann aber auch sein, das bei schnellen blits die TIGA nicht mehr mit kommt,
- ich werde das dynamische Speichermodell deswegen auf ein statisches umstellen, das mit einem
- konstant großen Buffer arbeitet (bufmemsize = 512 KB). Vielleicht hilft das weiter.
-
- 24.1.95
-
- Plane-2-chunky funktioniert. bitblt() läuft asynchron. Dadurch wird beim >=2. Blit die SrcBitmap
- mit den neuen Daten überschrieben wärend geblittet wird. Das führt dann zu Fehlern.
- Anscheinend haut das blitting mit set_pmask nicht hin. Dann wäre es einfach Miniterms und Masken
- einzubauen, so muß ich in einen Buffer convertieren und dann die 8 Bit durch eine Maske und mit dem
- richtigen ppop blitten...
-
- 19.2.95
-
- I decided to make this code public available ! Maybe there is somebody out there who can help
- me finishing this work.
- I also made some basic consideration of a new conception how a new graphics.library should look
- like.
-
- I) It should be "objective", which means that the library should be extracted from the low level
- graphics stuff which writes to the hardware. -> Hardware extraction layer !
- The library should become a class library only. The classes make the layer handling,
- clipping and such stuff. The drawing functions should be objects of this classes.
-
- II)Basic "Target"-Classes would implement hardware dependent objects. Like one class
- is a chunky-class, the other is a plane-class. Also there could be TrueColor classes like
- 15/16/24 bit classes (This sounds like EGS, but it should not be that complex).
- Hardware depended componets could be overloaded by the driver of the Graphics card.
-
- I do not want to keep old (native) Amiga GfxCode ! There must also be a driver for the
- native Amiga chips !!! This makes sure, if you have a Graphics board that runs in chunky mode
- that all stuff uses Class-library access modes ! This could improve the intuition speed a
- lot ! The dark side is, that it would not allow any code to write directly into the
- Bitmaps ! -> it is (a little bit) incompatible...
-
- But, in this case the normal code would also run in 15/16/24 or what ever mode !
- Also, this would mean there is no "emulation" any more. It is a real new graphics
- sub system ! The Monitor conception has to change a little bit. The Monitors could
- be used as Display-Drivers, where each board has (only) one (!) Monitor file. With
- an utility you can define the available modes (if available !) - Like OCS:Pal, ECS:Pal,
- AGA:Pal, Spectrum:HiRes, A2410:Mode0, etc.
- This also means, there is NO gfx code there on boot up ! Maybe it make sence to implement
- a basic plane and a chunky class in the driver, make the subsystem resident and reboot the
- system ! In this case the new graphics stuff would be available on boot up. If this would work
- we are near an real RTG driver. This code could be build into a ROM on the gfx board !
- So board access would also be available for the GURU (...!) or the boot menue !
- Well, the ROM should NOT hold the whole driver, just gfx primitves for the two classes
- mentioned above ! If the GfxSubsystem runs it is easy to overload the basic classes with
- a new graphics code with a board driver in devs:monitors ! This would keep driver updates
- easy as you only need a new disk instead a new EProm - and it is cheaper, too.
- This is the BIG advatage of Object Oriented Graphics ! This is the way we should go !
- Every other stuff is just a hack and NO real extension like Cybergraphic...!, EGS comes
- close, but they do not change the AmigaOS graphics access mode !
-
- The Basic AmigaOS gfx-hardware access would look like this :
-
- +------------------+
- | intuition |
- +------------------+
- |
- +--------------------+
- x <- patched ! |
- v | Basic Objects (Draw(),..) are directly called from Intuition
- +------------------+ | complex calls could stay in the GfxLibrary, like Text() which
- | graphics.library | | calls the BltTemplate()... etc.
- +------------------+ |
- x |
- +--------------------+
- |
- v
- +------------------+
- | class library |
- +------------------+
- | \ ........
- v V
- +-----------+ +----------+
- | borad 0 | | board 1 | ....
- +-----------+ +----------+
-
- A call to e.g. the Draw() function would look like this :
-
- original Draw() - patched by the Class Library,
-
- Class Libray :
- Do the Clipping, Layer, ...
- call the basic Draw()-Object depending which Bitmap to draw !
-
-
-
- --------------------------------------------------------------------------------------------------------
-
- */
- //#define DEBUG
- #define ASSEM_P2C // assembler modul planar 2 chunky
- //#define NO_BM_CACHE
-
- #include <string.h>
- #include <math.h>
-
- /* Pragmas */
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/mathffp_pragmas.h>
- #include <pragmas/mathtrans_pragmas.h>
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/graphics_pragmas.h>
-
- /* Protoypes */
- #include <clib/exec_protos.h>
- #include <clib/mathffp_protos.h>
- #include <clib/mathtrans_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/graphics_protos.h>
-
- /* general Includes */
- #include <a2410/typedefs.h>
- #include <a2410/devtiga.h>
- #include <a2410/ti_function_nums.h>
- #include <a2410/my_macros.h>
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <graphics/gfx.h>
- #include <graphics/displayinfo.h>
- #include <libraries/mathffp.h>
- #include <dos/dos.h>
- #include <intuition/screens.h>
-
- #include "gfx_types.h"
- #include "graphics.h"
- #include "tigalogo.h"
-
- #define RAND_MAX 5
- #define MaxPause 0
- #define BIT_SWAP 3
-
- #define CLIP_FALSE 0
- #define CLIP_TRUE 1
- #define CLIP_IN -1
- #define CLIP_OUT -2
-
- UBYTE *version = {"VERS : gfx.library V0.20 Point Design by juergen schober"};
-
- /*--------------------------*/
- /* SOME GLOBAL VARIABLES */
- /*--------------------------*/
-
- static struct Library *DOSBase,*GfxBase;
-
- #ifdef ASSEM_P2C
- extern void __asm CopyPlane2Chunky(register __a2 APTR planes,register __a3 APTR chunky,
- register __d6 WORD depth,register __d7 long BMSize);
- #endif
-
- /* Global definition, defined in GfxEntry.o */
-
- extern struct TigaScreen
- {
- PTR ScreenAddr;
- long Width,Height;
- long Depth;
- long Pitch;
- };
-
- extern struct Globals
- {
- struct Screen *screen;
- struct BitMap *bitmap;
- struct TigaScreen tigascreen;
- struct BMCacheList *first_cache_entry;
- } globals;
-
- /* global tiga buffer mem */
-
- static PTR bufmem = NULL;
- long bufmemsize = 0x80000; // = 512 KB initsize. (maybe I implement a fallback to smaller sizes here...)
-
- /* External Functions defined in the GfxEntry.o */
-
- extern long LockLib(void);
- extern long UnlockLib(void);
- extern BOOL InitTiga(int unit); // well , only unit 0 is supported !
- extern void ShutDownTiga(void);
-
- /* Global Functions , Prototypes */
-
- long ClipIt(struct ClipRect *clip,struct Rectangle *bounds);
- long ClipOff(void);
- long DwMode(struct RastPort *rp);
-
- struct ChunkyMap *Plane2Chunky8(struct BitMap *src);
- /* es gibt nur eine BMCache list : globals->first_cache_entry ! */
- struct BMCacheList *FindBitmap(struct BitMap *src);
- struct BMCacheList *FindChunky(struct ChunkyMap *map);
- BOOL InsertChunky(struct ChunkyMap *chunkymap,struct BitMap *bitmap);
- BOOL FlushCacheMap(struct BMCacheList *cachelist);
-
- void SetDefCols(void);
- long InstallFont(struct TextFont *textFont);
- long InstallPointer(CURSOR *pointer);
-
-
- /*--------------------------*/
-
- #ifdef SASC
- int CXBRK(void) { return(0); }
- int chkabort(void) { return(0); }
- #endif
-
- /* ==========================OpenLibrarySupportFunction===================================== */
-
- int __saveds __UserLibInit(void)
- {
- struct TextFont *txtfnt;
- struct TextAttr txt;
- CONFIG config;
- struct TigaScreen *tigascreen;
- struct ChunkyMap *logo;
-
- if (DOSBase = (struct Library *)OpenLibrary(DOSNAME,0L))
- {
- if (GfxBase = (struct Library *)OpenLibrary("graphics.library",37L))
- {
- if (InitTiga(0)) // get the tiga board 0 running
- {
- LockLib();
-
- get_config(&config);
-
- globals.screen = NULL;
- globals.bitmap = NULL;
- globals.first_cache_entry = NULL;
-
- tigascreen = &(globals.tigascreen);
-
- tigascreen->ScreenAddr = config.display_mem_start;
- tigascreen->Width = config.mode.disp_hres;
- tigascreen->Height = config.mode.disp_vres;
- tigascreen->Depth = config.mode.palet_gun_depth;
- tigascreen->Pitch = config.mode.disp_pitch;
-
- if (logo = Plane2Chunky8(&LogoMap))
- {
- host2gspxy(logo->data,logo->xSize,
- tigascreen->ScreenAddr,tigascreen->Pitch,
- 0,0,
- (tigascreen->Width-logo->xSize)>>1,
- (tigascreen->Height-logo->ySize)>>1,
- logo->xSize,logo->ySize,
- logo->depth,INTEL_BYTES);
-
- FreeVec(logo->data);
- FreeVec(logo);
- }
-
- do{
- if (!(bufmem = gsp_malloc(bufmemsize)))
- bufmemsize = bufmemsize>>1; // half the size
- } while ((!bufmem) && (bufmemsize>0));
-
- UnlockLib();
-
- /*
- This version uses a own font bitmap on tiga side,
- Future Versions should use a BltTemplate()
- instead of the GfxText()-Function,
- so the font caching will be removed some times !
- (This works perfectly under EGS !)
- */
- txt.ta_Name = (UBYTE*)"topaz.font";
- txt.ta_YSize = 8;
- txt.ta_Style = 0;
- txt.ta_Flags = 0;
-
- if (txtfnt = (struct TextFont*)OpenFont(&txt))
- {
- InstallFont(txtfnt);
- CloseFont(txtfnt);
- }
-
- SetDefCols(); // set the 4 basic col registers
- InstallPointer(NULL); // install a default pointer
-
- return(0);
- }
- CloseLibrary(GfxBase);
- }
- CloseLibrary(DOSBase);
- }
- return(1);
- }
-
- /* ----------------------------------------------------------------------------------- */
- /* =========================CloseLibrarySupportFunction=============================== */
-
- void __saveds __UserLibCleanup(void)
- {
- struct BMCacheList *cl,*cl_buffer;
- struct FontCacheList *fcl,*fcl_buffer;
-
- LockLib();
-
- cl = globals.first_cache_entry;
- while (cl)
- {
- cl_buffer = cl->next;
- FreeVec(cl->chunkymap->data);
- FreeVec(cl->chunkymap);
- FreeVec(cl);
- cl = cl_buffer;
- }
- fcl = FirstFontEntry;
- while (fcl)
- {
- fcl_buffer = fcl->ascent;
- gsp_free(fcl->tiga_bm);
- FreeVec(fcl);
- fcl = fcl_buffer;
- }
-
- UnlockLib();
- ShutDownTiga();
-
- CloseLibrary(DOSBase);
- CloseLibrary(GfxBase);
- }
-
- /* =====================END OF CloseLibrarySupportFunction============================ */
-
- /* ==================================LibCode================================================ */
-
-
- /* Some Setup functions : */
-
- void SetDefCols(void)
- {
- /*
- Setting up a default Palette
- */
- set_palet_entry(0,147L,147L,170L,0);
- set_palet_entry(1,0L,0L,0L,0);
- set_palet_entry(2,255L,255L,255L,0);
- set_palet_entry(3,97L,99L,182L,0);
- set_palet_entry(4,255L,0L,0L,0);
- set_palet_entry(5,0L,255L,0L,0);
- set_palet_entry(6,0L,0L,255L,0);
- set_palet_entry(7,255L,255L,0L,0);
- }
-
- long InstallFont(struct TextFont *textFont)
- {
- /*
- copies a amiga font bitmap into a cache memory in gsp_memory.
- this version does not support kerning values.
- next version should recognise kerning values so
- the Text() functions need not worry about.
- */
- struct FontCacheList *cachelist,*new_font_entry;
- struct TextFont *AmigaFont;
- WORD BitMap_Size;
- APTR TIGA_BitMap;
- CONFIG config;
- long pitch,size,width,height;
-
- /* check if font already installed ? */
-
- LockLib();
-
- cachelist=FirstFontEntry;
-
- while (cachelist)
- {
- if (AmigaFont = cachelist->amiga_fnt) // ok, there is an Amigafont
- if (AmigaFont->tf_CharData == textFont->tf_CharData) // are the chardata in cache ?
- {
- UnlockLib();
- return(TRUE); // then exit
- }
- cachelist=cachelist->ascent;
- }
-
- /* font not in cache, install new font */
-
- AmigaFont = textFont;
- width = (AmigaFont->tf_Modulo+1)&~1;
- height = AmigaFont->tf_YSize;
- BitMap_Size = AmigaFont->tf_Modulo<<3; // bit size
- pitch = width<<3;
-
- /* allocate the Memory for the Bitmap on the TIGA */
-
- size = (WORD)width*(WORD)height;
- if (TIGA_BitMap=(APTR)gsp_malloc(size))
- {
-
- /* copy the bitmap data to tiga side */
-
- get_config(&config);
-
- host2gspxy(AmigaFont->tf_CharData,AmigaFont->tf_Modulo,
- TIGA_BitMap,pitch,
- 0,0,
- 0,0,
- BitMap_Size,height,
- 8,BIT_SWAP); // rotate intel bytes (3 = bit rotation)
-
- /* add font to FontCacheList = cache-entrylist */
-
- /* make new entry */
-
- new_font_entry = (struct FontCacheList *)AllocVec(sizeof(struct FontCacheList),MEMF_CLEAR);
-
- new_font_entry->tiga_bm = TIGA_BitMap;
- new_font_entry->amiga_fnt = AmigaFont;
-
- if (!FirstFontEntry)
- FirstFontEntry = new_font_entry;
- else
- {
- cachelist = FirstFontEntry;
-
- /* go to last but one entry ! */
-
- while (cachelist->ascent) cachelist=cachelist->ascent;
-
- /* and connect to previous entry */
-
- new_font_entry->descent=cachelist;
-
- cachelist->ascent = new_font_entry;
- }
- UnlockLib();
- return(TRUE);
- }
- UnlockLib();
- return(FALSE);
- }
-
- long InstallPointer(CURSOR *pointer)
- {
- /*
- installs a default pointer
- */
- extern CURSOR Pointer,BusyPointer;
- extern UBYTE Pointer_Data[],BusyPointer_Data[];
- UWORD *pointer_data;
- ULONG PointerSize;
- PTR gspPointer,gspBusyPointer;
- CURSOR hstPointer,hstBusyPointer;
- PTR gspPointerData;
- CONFIG config;
-
- if (!pointer)
- {
- get_config(&config);
- PointerSize = ((Pointer.width*Pointer.height)<<1)>>3;
- if (gspPointerData = (PTR) gsp_malloc(PointerSize))
- {
- if (gspPointer = (PTR)gsp_malloc(sizeof(CURSOR)))
- {
- hstPointer.hot_x = 0;
- hstPointer.hot_y = 0;
- hstPointer.width = 16;
- hstPointer.height = 16;
- hstPointer.pitch = Pointer.pitch;
- hstPointer.color = 0x00ff0000;
- hstPointer.mask_rop = 1;
- hstPointer.shape_rop = 8;
- hstPointer.data = gspPointerData;
-
- // Pointer Data :
- host2gsp((UBYTE*)&Pointer_Data,gspPointerData,PointerSize,0);
-
- /*try first sending down first 5 elements of the header - Bitadressen */
- host2gsp((char*)&hstPointer,gspPointer,10,0); // no byteswap !
- /* now send down the color ,which is a long */
- host2gsp((char*)&(hstPointer.color),(gspPointer+0x50L),4,2); // byteswap !
- /* now send down the two raster ops */
- host2gsp((char*)&(hstPointer.mask_rop),(gspPointer+0x70L),4,0); // no byteswap !
- /* and the data pointer */
- host2gsp((char*)&(hstPointer.data),(gspPointer+0x90L),4,2);
-
- set_curs_shape((PTR)gspPointer);
- set_curs_state(1);
-
- set_ovl_color(1,0xff,0xff,0xff);
- set_ovl_color(2,0xff,0x00,0x00);
- set_ovl_color(3,0xff,0xff,0x00);
-
- set_curs_xy(0,0);
-
- return(TRUE);
- }
- gsp_free(gspPointerData);
- }
- }
- else
- {
- get_config(&config);
- PointerSize = ((pointer->width*pointer->height)<<1)>>3;
- if (gspPointerData = (PTR) gsp_malloc(PointerSize))
- {
- if (gspPointer = (PTR)gsp_malloc(sizeof(CURSOR)))
- {
- pointer_data = (UWORD*)pointer->data;
- // hstPointer.hot_x = 0;
- // hstPointer.hot_y = 0;
- // hstPointer.width = 16;
- // hstPointer.height = 16;
- pointer->pitch = 32;//Pointer.pitch;
- pointer->color = 0x00ff0000;
- pointer->mask_rop = 1;
- pointer->shape_rop = 8;
- pointer->data = gspPointerData;
-
- // Pointer Data :
- host2gsp((UBYTE*)pointer_data,gspPointerData,PointerSize,0);
-
- /*try first sending down first 5 elements of the header - Bitadressen */
- host2gsp((char*)pointer,gspPointer,10,3);
- /* now send down the color ,which is a long */
- host2gsp((char*)pointer->color,(gspPointer+0x50L),4,2); // byteswap !
- /* now send down the two raster ops */
- host2gsp((char*)pointer->mask_rop,(gspPointer+0x70L),4,0); // no byteswap !
- /* and the data pointer */
- host2gsp((char*)pointer->data,(gspPointer+0x90L),4,2);
-
- set_curs_shape((PTR)gspPointer);
- set_curs_state(1);
-
- set_ovl_color(1,0xff,0xff,0xff);
- set_ovl_color(2,0xff,0x00,0x00);
- set_ovl_color(3,0x00,0x00,0x00);
-
- set_curs_xy(0,0);
-
- return(TRUE);
- }
- gsp_free(gspPointerData);
- }
- }
- set_curs_shape(0);
- set_curs_state(1);
-
- set_curs_xy(0,0);
- return(FALSE);
- }
-
- long ClipIt(struct ClipRect *clip,struct Rectangle *bounds)
- {
- /*
- sets up the cliprects on a2410 !
- */
- struct Rectangle *rect;
- WORD x0,y0,dx,dy;
-
- if (clip->lobs) return(CLIP_OUT); /* if lobs!=NULL -> wrong rp/layer */
-
- if (clip)
- {
- if ((rect = &clip->bounds))
- {
- x0 = rect->MinX;
- y0 = rect->MinY;
- dx = (rect->MaxX-x0)+1;
- dy = (rect->MaxY-y0)+1;
-
- if ((dx > 0) && (dy > 0) && (x0 >=0) && (y0 >= 0))
- set_clip_rect(dx,dy,x0,y0);
- return(CLIP_TRUE);
- }
- }
- return(CLIP_FALSE);
- }
-
- long ClipOff(void)
- {
- set_clip_rect(globals.tigascreen.Width,globals.tigascreen.Height,0,0);
- return(TRUE);
- }
-
- long DwMode(struct RastPort *rp)
- {
- /*
- * sets up the drawmode.
- * if rp->FgPen = 0, transparency has to be switched off.
- * A OR B = 0; -> color is transparent ! (0 OR x = 0!)
- */
- long dwmode;
-
- if (rp)
- {
- dwmode = rp->DrawMode;
-
- set_ppop(DST_IS_SRC);
-
- switch (dwmode & (JAM1|JAM2))
- {
- case JAM1 :
- if (rp->FgPen) transp_on();
- else transp_off();
- set_colors(rp->FgPen,0);
- break;
- case JAM2 :
- set_colors(rp->FgPen,rp->BgPen);
- transp_off();
- break;
- }
- if ((dwmode&COMPLEMENT) == COMPLEMENT)
- {
- transp_off();
- // set_colors(rp->FgPen,rp->BgPen);
- set_colors(0xff,0);
- set_ppop(SRC_XOR_DST);
- }
-
- if ((dwmode&INVERSVID) == INVERSVID)
- {
- set_colors(rp->BgPen,rp->FgPen);
- }
- return(TRUE);
- }
-
- return(FALSE);
- }
-
- /* ----------------------------------------------------------
-
- Bitmap Support functions !
-
- ---------------------------------------------------------- */
-
- struct ChunkyMap *GfxAllocBitMap(WORD xSize,WORD ySize,int Depth)
- {
- struct ChunkyMap *map;
-
- if (map = (struct ChunkyMap *)AllocVec(sizeof(struct ChunkyMap),MEMF_CLEAR))
- {
- map->depth = 8;
- map->xSize = xSize;
- map->ySize = ySize;
- map ->bmsize = xSize*ySize;
- map->flag = BMF_CACHE_STANDARD;
- if (map->data = (UBYTE *)AllocVec(map->bmsize,MEMF_CLEAR))
- return(map);
- else
- {
- FreeVec(map);
- return(NULL);
- }
- }
- return(NULL);
- }
-
- void GfxDisposeBitMap(struct ChunkyMap *map)
- {
- if (map)
- {
- if (map->data) FreeVec(map->data);
- FreeVec(map);
- }
- }
-
- struct ChunkyMap *Plane2Chunky8(struct BitMap *src)
- {
- /*
- converts a planar bitmap into a chunky map.
- */
- WORD xSize,ySize;
- WORD depth;
- struct ChunkyMap *chunkymap;
- WORD bm_width;
- UBYTE *planes[8];
- UBYTE *chunky;
- long i;
- #ifndef ASSEM_P2C
- WORD num_planes;
- register long x,y,pix;
- #endif
-
- if (chunkymap = (struct ChunkyMap *)AllocVec(sizeof(struct ChunkyMap),MEMF_CLEAR))
- {
- chunkymap->depth = 8;
- bm_width = (WORD)src->BytesPerRow; // Breite für _EINE_ Plane = num_Bits
- chunkymap->xSize = xSize = (WORD)bm_width * 8;
- chunkymap->ySize = ySize = src->Rows;
- chunkymap ->bmsize = xSize*ySize;
- chunkymap->flag = BMF_CACHE_STANDARD;
- if (chunky = (UBYTE *)AllocVec(chunkymap->bmsize,MEMF_CLEAR))
- {
- #ifndef ASSEM_P2C
- depth = src->Depth;
- pix = 0;
- for (y=0;y<ySize;y++)
- {
-
- for (i = 0; i < depth; i++)
- planes[i] = src->Planes[i]+bm_width*(WORD)y;
-
- for (x=0;x < (xSize);x++)
- {
- i = 7;
- while (i >= 0 && x < xSize)
- {
- chunky[pix] = 0;
-
- for (num_planes = 0 ; num_planes < depth ; num_planes ++)
- chunky[pix] += (*planes[num_planes] & (1<<i)) ? (1<<num_planes) : 0;
- pix++;
- i--;
- x++;
- }
-
- for (i = 0; i < depth; i++)
- planes[i]++;
-
- x--;
- }
- }
-
- #else
- /* externes assembler Modul :
- extern void __asm CopyPlane2Chunky(register __a2 APTR planes,register __a3 APTR chunky,
- register __d6 WORD depth,register __d7 long BMSize);
- */
- CopyPlane2Chunky(src->Planes,chunky,src->Depth,bm_width*ySize);
- #endif
-
- chunkymap->data = (UBYTE*)chunky;
- return(chunkymap);
- }
- FreeVec(chunkymap);
- return(NULL);
- }
- return(NULL);
- }
-
- struct BMCacheList *FindBitmap(struct BitMap *src)
- {
- struct BMCacheList *cachelist;
-
- if ((cachelist = globals.first_cache_entry)&&(src!=NULL))
- {
- while (cachelist)
- {
- if ((long)cachelist->bitmap == (long)src) return(cachelist);
- cachelist = cachelist->next;
- }
- }
- return(NULL);
- }
-
- struct BMCacheList *FindChunky(struct ChunkyMap *map)
- {
- struct BMCacheList *cachelist;
-
- cachelist = globals.first_cache_entry;
- while (cachelist)
- {
- if (cachelist->chunkymap == map) return(cachelist);
- cachelist = cachelist->next;
- }
- return(NULL);
- }
-
- BOOL InsertChunky(struct ChunkyMap *chunkymap,struct BitMap *bitmap)
- {
- struct BMCacheList *cachelist,*cl;
-
- if (chunkymap->bmsize < 10000) return(FALSE);
- // if (chunkymap->flag & BMF_NO_CACHE) return(FALSE);
-
- if (!(cachelist = globals.first_cache_entry))
- {
- if (globals.first_cache_entry = (struct BMCacheList*)AllocVec(sizeof(struct BMCacheList),MEMF_CLEAR|MEMF_PUBLIC))
- {
- globals.first_cache_entry->chunkymap = chunkymap;
- globals.first_cache_entry->bitmap = bitmap;
-
- globals.first_cache_entry->flag = BMF_CACHE_STANDARD;
-
- return(TRUE);
- }
- return(FALSE);
- }
-
- // Letzten Eintrag suchen :
- while (cachelist->next) cachelist = cachelist->next;
-
- if (cl = (struct BMCacheList *)AllocVec(sizeof(struct BMCacheList),MEMF_CLEAR|MEMF_PUBLIC))
- {
- cl->chunkymap = chunkymap;
- cl->bitmap = bitmap;
- cl->flag = BMF_CACHE_STANDARD;
-
- cl->next = NULL;
- cl->prev = cachelist;
- cachelist->next = cl;
-
- return(TRUE);
- }
-
- return(FALSE);
- }
-
- BOOL FlushCacheMap(struct BMCacheList *cachelist)
- {
- struct BMCacheList *cl;
-
- if (cachelist->flag & BMF_LOCK_CACHE)
- if ((cachelist->flag & BMF_FORCE_FLUSH) == 0) return(FALSE);
-
- if (cachelist)
- {
- if (cl = cachelist->next)
- cl->prev = cachelist->prev;
- if (cachelist->prev)
- cachelist->prev->next = cl;
-
- FreeVec(cachelist->chunkymap->data);
- FreeVec(cachelist->chunkymap);
- FreeVec(cachelist);
- return(TRUE);
- }
- return(FALSE);
- }
-
- /* REAL graphics stuff : **
- ** ---------------------- **
- ** */
-
- LONG __asm GfxWritePixel(register __a1 struct RastPort *rp,
- register __d0 long x,register __d1 long y )
- {
- struct ClipRect *cliprect;
-
- if (rp && rp->Layer)
- {
- LockLayerRom(rp->Layer);
- LockLib();
-
- rp->cp_x=x;
- rp->cp_y=y;
-
- x += ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
- y += ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
-
- DwMode(rp);
-
- cliprect = rp->Layer->ClipRect;
- while (cliprect)
- {
- if (ClipIt(cliprect,NULL)!=CLIP_OUT) // Linie ist im ClipRect ?
- draw_point(x,y);
- cliprect = cliprect->Next;
- }
- UnlockLib();
- UnlockLayerRom(rp->Layer);
- }
- return(0);
- }
-
- void __asm GfxDraw(register __a1 struct RastPort *rp,register __d0 long x,register __d1 long y)
- {
- long XOffset,YOffset;
- struct Rectangle bounds;
- struct ClipRect *cliprect;
- ULONG line_pattern;
-
- if (rp)
- {
- if (rp->Layer) LockLayerRom(rp->Layer);
- LockLib();
-
- DwMode(rp);
-
- line_pattern = (rp->LinePtrn<<16)|rp->LinePtrn;
-
- if (rp->Layer)
- {
-
- XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
- YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
-
- bounds.MinX = rp->cp_x+XOffset;
- bounds.MinY = rp->cp_y+YOffset;
- bounds.MaxX = x+XOffset;
- bounds.MaxY = y+YOffset;
-
- cliprect = rp->Layer->ClipRect;
- while (cliprect)
- {
- if (ClipIt(cliprect,NULL)!=CLIP_OUT) // Linie ist im ClipRect ?
- {
- if (line_pattern == ~0)
- draw_line(bounds.MinX,bounds.MinY,bounds.MaxX,bounds.MaxY);
- else
- styled_line(bounds.MinX,bounds.MinY,bounds.MaxX,bounds.MaxY,(long)line_pattern,1);
- }
- cliprect = cliprect->Next;
- }
- }
- else
- {
- ClipOff();
-
- if ((rp->LinePtrn)==0xffff)
- draw_line(rp->cp_x,rp->cp_y,x,y);
- else
- {
- styled_line(rp->cp_x,rp->cp_y,x,y,(long)line_pattern,1);
- }
- }
-
- rp->cp_x=x;
- rp->cp_y=y;
-
- UnlockLib();
- if (rp->Layer) UnlockLayerRom(rp->Layer);
- }
- }
-
- void __asm GfxPolyDraw(register __a1 struct RastPort *rp,
- register __d0 long count,register __a0 WORD *polyTable )
- {
- long XOffset,YOffset;
- struct ClipRect *cliprect;
- ULONG line_pattern;
- POINT *points;
- int i;
-
- if (rp)
- {
- if (rp->Layer) LockLayerRom(rp->Layer);
- LockLib();
-
- DwMode(rp);
-
- points = (POINT*)polyTable;
-
- if (rp->Layer)
- {
-
- XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
- YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
-
- line_pattern = (rp->LinePtrn<<16)|rp->LinePtrn;
- for (i=0;i<count;i++)
- {
- points[i].x += XOffset;
- points[i].y += YOffset;
- }
- if (line_pattern == ~0)
- {
- cliprect = rp->Layer->ClipRect;
- while (cliprect)
- {
- if (ClipIt(cliprect,NULL)!=CLIP_OUT) // Linie ist im ClipRect ?
- {
- draw_line(rp->cp_x,rp->cp_y,points[0].x,points[0].y);
- draw_polyline(count,points);
- }
- cliprect = cliprect->Next;
- }
- }
- else
- {
- cliprect = rp->Layer->ClipRect;
- while (cliprect)
- {
- if (ClipIt(cliprect,NULL)!=CLIP_OUT) // Linie ist im ClipRect ?
- {
- styled_line(rp->cp_x+XOffset,rp->cp_y+YOffset,points[0].x,points[0].y,line_pattern,1);
- for (i=0;i<count-1;i++)
- styled_line(points[i].x,points[i].y,points[i+1].x,points[i+1].y,line_pattern,1);
- }
- cliprect = cliprect->Next;
- }
- }
- }
- else // RastPort does not have a cliprect !
- {
- ClipOff();
-
- if ((rp->LinePtrn)==0xffff)
- {
- draw_line(rp->cp_x,rp->cp_y,points[0].x,points[0].y);
- draw_polyline(count,points);
- }
- else
- {
- line_pattern = (rp->LinePtrn<<16)|rp->LinePtrn;
- styled_line(rp->cp_x+XOffset,rp->cp_y+YOffset,points[0].x,points[0].y,line_pattern,1);
- for (i=0;i<count-1;i++)
- styled_line(points[i].x,points[i].y,points[i+1].x,points[i+1].y,line_pattern,1);
- }
- }
-
- rp->cp_x = points[count-1].x;
- rp->cp_y = points[count-1].y;
-
- UnlockLib();
- if (rp->Layer) UnlockLayerRom(rp->Layer);
- }
- }
-
- void __asm GfxSetRast(register __a1 struct RastPort *rp,register __d0 unsigned long pen )
- {
- long XOffset,YOffset;
- struct Rectangle bounds;
- struct ClipRect *cliprect;
- ULONG line_pattern;
- long ret,i;
- long x0,y0,xw,yh;
- UWORD ptrnsz;
- PATTERN gsp_ptrn;
-
- if (rp->Layer)
- {
- LockLayerRom(rp->Layer);
- LockLib();
-
- bounds.MinX = rp->Layer->bounds.MinX;
- bounds.MinY = rp->Layer->bounds.MinY;
- xw = rp->Layer->bounds.MaxX - bounds.MinX;
- yh = rp->Layer->bounds.MaxX - bounds.MinY ;
-
- set_ppop(OR);
- set_fcolor(pen);
-
- cliprect = rp->Layer->ClipRect;
- while (cliprect)
- {
- if (ClipIt(cliprect,NULL)!=CLIP_OUT)
- {
- fill_rect(xw,yh,bounds.MinX,bounds.MinY); // use fill_rect ...
- }
- cliprect = cliprect->Next;
- }
- UnlockLib();
- UnlockLayerRom(rp->Layer);
- }
- }
-
- void __asm GfxRectFill(register __a1 struct RastPort *rp,
- register __d0 long xMin,register __d1 long yMin,
- register __d2 long xMax,register __d3 long yMax )
- {
- /*
- should work but I guess there is a bug some times.
- when using the emulation and typing <setfont> in the shell
- some wrong rectangles are drawn.
- */
- long XOffset,YOffset;
- struct Rectangle bounds;
- struct ClipRect *cliprect;
- ULONG line_pattern;
- long ret,i;
- long x0,y0,xw,yh;
- UWORD ptrnsz;
- PATTERN gsp_ptrn;
-
- if (rp)
- {
- if (rp->Layer) LockLayerRom(rp->Layer);
- LockLib();
-
- x0 = (xMin<=xMax) ? xMin : xMax;
- y0 = (yMin<=yMax) ? yMin : yMax;
-
- xw = (xMax>=xMin) ? (xMax-xMin)+1 : (xMin-xMax)+1;
- yh = (yMax>=yMin) ? (yMax-yMin)+1 : (yMin-yMax)+1;
-
- DwMode(rp);
-
- gsp_ptrn.data = NULL;
-
- if (rp->AreaPtrn)
- {
- ptrnsz = ((rp->AreaPtSz)<=4) ? (1<<(rp->AreaPtSz)) : 16;
- gsp_ptrn.width=16;
- gsp_ptrn.height=16; // tiga supports only 16 lines !!!
- gsp_ptrn.depth=1; // no more than 1 plane now !
- gsp_ptrn.data=(PTR)gsp_malloc(32); // 32 bytes = 16 WORDS space for pattern !
- if (ptrnsz==16)
- host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data),2*ptrnsz,2); // WORD aligned
- else
- for (i=0;i<=0xF0;i+=(0x10*ptrnsz)) // bit offset to current pos. - WORD aligned !
- host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data)+i,2*ptrnsz,2);
- set_patn(&gsp_ptrn);
- }
-
- if (rp->Layer)
- {
- XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
- YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
-
- bounds.MinX = x0+XOffset;
- bounds.MinY = y0+YOffset;
-
- cliprect = rp->Layer->ClipRect;
- while (cliprect)
- {
- if (ClipIt(cliprect,NULL)!=CLIP_OUT)
- {
- // NO Pattern in Rect
- if (!rp->AreaPtrn)
- fill_rect(xw,yh,bounds.MinX,bounds.MinY); // use fill_rect ...
- // Patternfilled Rect !
- else
- patnfill_rect(xw,yh,bounds.MinX,bounds.MinY);
-
- if ((rp->Flags)&AREAOUTLINE)
- {
- set_fcolor(rp->AOlPen);
- if ((rp->LinePtrn)==0xFFFF)
- draw_rect(xw,yh,bounds.MinX,bounds.MinY);
- else
- {
- line_pattern=(((rp->LinePtrn)<<16)|(rp->LinePtrn));
- styled_line(bounds.MinX,bounds.MinY,bounds.MaxX,bounds.MinY,line_pattern,0);
- styled_line(bounds.MaxX,bounds.MinY,bounds.MaxX,bounds.MaxY,line_pattern,0);
- styled_line(bounds.MaxX,bounds.MaxY,bounds.MinX,bounds.MaxY,line_pattern,0);
- styled_line(bounds.MinX,bounds.MaxY,bounds.MinX,bounds.MinY,line_pattern,0);
- }
- }
- }
- cliprect = cliprect->Next;
- }
- }
- else
- {
- LockLib();
- ClipOff();
-
- // NO Pattern in Rect
- if (!rp->AreaPtrn)
- fill_rect(xw,yh,x0,y0);
- // Patternfilled Rect !
- else
- patnfill_rect(xw,yh,x0,y0);
-
- if ((rp->Flags)&AREAOUTLINE)
- {
- set_fcolor(rp->AOlPen);
- if ((rp->LinePtrn)==0xFFFF)
- draw_rect(xw,yh,x0,y0);
- else
- {
- line_pattern=(((rp->LinePtrn)<<16)|(rp->LinePtrn));
- styled_line(xMin,yMin,xMax,yMin,line_pattern,0);
- styled_line(xMax,yMin,xMax,yMax,line_pattern,0);
- styled_line(xMax,yMax,xMin,yMax,line_pattern,0);
- styled_line(xMin,yMax,xMin,yMin,line_pattern,0);
- }
- }
- }
-
- if (gsp_ptrn.data) gsp_free(gsp_ptrn.data);
-
- rp->cp_x=xMin;
- rp->cp_y=yMin;
-
- UnlockLib();
- if (rp->Layer) UnlockLayerRom(rp->Layer);
- }
- }
-
- void __asm GfxDrawEllipse(register __a1 struct RastPort *rp,
- register __d0 long xCenter,register __d1 long yCenter,
- register __d2 long a,register __d3 long b )
- {
- long XOffset,YOffset;
- struct Rectangle bounds;
- struct ClipRect *cliprect;
-
- if (rp->Layer)
- {
- LockLayerRom(rp->Layer);
- LockLib();
-
- XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
- YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
-
- bounds.MinX = xCenter+XOffset;
- bounds.MinY = yCenter+YOffset;
-
- DwMode(rp);
-
- cliprect = rp->Layer->ClipRect;
- while (cliprect)
- {
- if (ClipIt(cliprect,NULL)!=CLIP_OUT)
- {
- draw_oval((a+a),(b+b),bounds.MinX-a,bounds.MinY-b);
- }
- cliprect = cliprect->Next;
- }
- rp->cp_x=xCenter;
- rp->cp_y=yCenter;
-
- UnlockLib();
- UnlockLayerRom(rp->Layer);
- }
- }
-
- LONG __asm GfxAreaEllipse(register __a1 struct RastPort *rp,register __d0 long xCenter,
- register __d1 long yCenter,register __d2 long a,register __d3 long b )
- {
- long XOffset,YOffset;
- struct Rectangle bounds;
- struct ClipRect *cliprect;
- ULONG line_pattern;
- long ret,i;
- UWORD ptrnsz;
- PATTERN gsp_ptrn;
-
- if (rp->Layer)
- {
- LockLayerRom(rp->Layer);
- LockLib();
-
- XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
- YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
-
- bounds.MinX = xCenter+XOffset;
- bounds.MinY = yCenter+YOffset;
-
- DwMode(rp);
-
- if (rp->AreaPtrn)
- {
- ptrnsz = ((rp->AreaPtSz)<=4) ? (1<<(rp->AreaPtSz)) : 16;
- gsp_ptrn.width=16;
- gsp_ptrn.height=16; // tiga supports only 16 lines !!!
- gsp_ptrn.depth=1; // no more than 1 plane now !
- gsp_ptrn.data=(PTR)gsp_malloc(32); // 32 bytes = 16 WORDS space for pattern !
- if (ptrnsz==16)
- host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data),2*ptrnsz,2); // WORD aligned
- else
- for (i=0;i<=0xF0;i+=(0x10*ptrnsz)) // bit offset to current pos. - WORD aligned !
- host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data)+i,2*ptrnsz,2);
- set_patn(&gsp_ptrn);
- }
-
- cliprect = rp->Layer->ClipRect;
- while (cliprect)
- {
- if (ClipIt(cliprect,NULL)!=CLIP_OUT)
- {
- // NO Pattern in Ellipse
- if (!rp->AreaPtrn)
- fill_oval(a+a,b+b,bounds.MinX-a,bounds.MinY-b);
- // Patternfilled Ellipse !
- else
- patnfill_oval(a+a,b+b,bounds.MinX-a,bounds.MinY-b);
- }
- cliprect = cliprect->Next;
- }
-
- if (gsp_ptrn.data) gsp_free(gsp_ptrn.data);
-
- rp->cp_x=xCenter;
- rp->cp_y=yCenter;
-
- UnlockLib();
- UnlockLayerRom(rp->Layer);
- }
- return(0);
- }
-
- void __asm GfxClearScreen(register __a1 struct RastPort *rp )
- {
- LockLib();
-
- clear_screen(0);
-
- UnlockLib();
- }
-
-
- LONG __asm GfxText(register __a1 struct RastPort *rp,
- register __a0 STRPTR string,register __d0 unsigned long count )
- {
- /*
- Text function. Is slow. (see loop below !)
- Clipping has to be changed. ClipIt() uses set_clip_rect(),
- which must not be used with bitblt() !
- So a software clipping should be done on Bitmaps befor blitting !
- */
- CONFIG config;
- register int i;
- struct FontCacheList *t_lst; // t_lst = Verbindungsliste zw. aktuellen Amigafonts u. Tigafonts
- struct TextFont *AmigaFont; // The Textfontstructur
- APTR Tiga_BitMap; // a copy of the Fontbitmap on the Tiga-side
- long pitch;
- struct ClipRect *cliprect;
- WORD *TF_CharKern,*TF_CharSpace;
- BOOL PropFont = FALSE;
- register UBYTE asc_val; // ASCII-Code of character
- register WORD charX0,charXSize,charKern,charY0,charYSize,X0,Y0;
- long XOffset,YOffset;
- struct LocTable
- {
- WORD XPos; // LocTable & 0xffff0000
- WORD FontWidth; // LocTable & 0x0000ffff
- } *TF_CharLoc;
-
- if (rp)
- {
- if (rp->Layer)
- LockLayerRom(rp->Layer);
- LockLib();
-
- /* -----------------------------
- Do not use Tiga Text-Function,
- using my own !
- ----------------------------- */
-
- /* ----- Suche nach Amigafont in der Cacheliste ----- */
-
- t_lst=FirstFontEntry;
- while (t_lst)
- {
- AmigaFont = (struct TextFont *)t_lst->amiga_fnt;
- if ((LONG)AmigaFont->tf_CharData==(LONG)rp->Font->tf_CharData)
- {
- Tiga_BitMap = (APTR)t_lst->tiga_bm;
- break; // **** Wenn Font Font in Liste gfunden, dann raus ****
- }
- t_lst=t_lst->ascent; // nächster Eintrag
- }
- if (!t_lst) // **** fallback to topaz.8 . Should be FirstFontEntry !! ****
- {
- t_lst = FirstFontEntry;
- AmigaFont = (struct TextFont *)t_lst->amiga_fnt;
- Tiga_BitMap = (APTR)t_lst->tiga_bm;
- }
-
- DwMode(rp);
-
- TF_CharLoc = (struct LocTable*)AmigaFont->tf_CharLoc;
- TF_CharKern = (WORD*)AmigaFont->tf_CharKern;
- TF_CharSpace = (WORD*)AmigaFont->tf_CharSpace;
- PropFont = (AmigaFont->tf_Flags & FPF_PROPORTIONAL) ? TRUE : FALSE;
-
- charKern = 0;
- charYSize = AmigaFont->tf_YSize;
-
- pitch = ((AmigaFont->tf_Modulo+1)&~1)<<3;
-
- set_srcbm(Tiga_BitMap,pitch,pitch,AmigaFont->tf_YSize,1);
-
- if (rp->Layer)
- {
-
- XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
- YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
-
- Y0 = (rp->cp_y)-AmigaFont->tf_Baseline+YOffset;
-
- cliprect = rp->Layer->ClipRect;
- while (cliprect)
- {
- if (ClipIt(cliprect,NULL)!=CLIP_OUT)
- {
-
- X0 = rp->cp_x+XOffset;
-
- for (i=0;(i<count&&string[i]!=0);i++)
- {
- asc_val = string[i]-AmigaFont->tf_LoChar;
- charX0 = (WORD)TF_CharLoc[asc_val].XPos;
- charXSize = (WORD)TF_CharLoc[asc_val].FontWidth;
- if (PropFont)
- charKern = (WORD)TF_CharKern[asc_val];
-
- bitblt(charXSize,charYSize, // Width,Height
- charX0,0, // Origin x,y
- X0+charKern,Y0); // dest x/y (RP->Bitmap)
-
- if (PropFont)
- X0 += TF_CharSpace[asc_val]+charKern;
- else
- X0 += AmigaFont->tf_XSize;
- }
- }
- cliprect = cliprect->Next;
- }
- rp->cp_x = X0;
- }
- else
- {
- Y0 = (rp->cp_y)-AmigaFont->tf_Baseline;
-
- for (i=0;(i<count&&string[i]!=0);i++)
- {
- asc_val = string[i]-AmigaFont->tf_LoChar;
- charX0 = (WORD)TF_CharLoc[asc_val].XPos;
- charXSize = (WORD)TF_CharLoc[asc_val].FontWidth;
- if (PropFont)
- charKern = (WORD)TF_CharKern[asc_val];
-
- bitblt(charXSize,charYSize, // Width,Height
- charX0,0, // Origin x,y
- rp->cp_x+charKern,Y0); // dest x/y (RP->Bitmap)
-
- if (PropFont)
- rp->cp_x += TF_CharSpace[asc_val]+charKern;
- else
- rp->cp_x += AmigaFont->tf_XSize;
- }
- }
- UnlockLib();
- if (rp->Layer)
- UnlockLayerRom(rp->Layer);
- return(TRUE);
- }
- return(-1);
- }
-
- LONG __asm GfxSetFont(register __a1 struct RastPort *rp,register __a0 struct TextFont *textFont )
- {
- /*
- 25.9.94 :
-
- SetFont 100 % OK !
-
- was noch fehlt ist eine Speicherverwaltung der Cachebitmaps !
-
- The main code is 100% the original. But when using in a patch,
- the emulation crashes. Did not find out why. I guess it is something
- wrong in my Text()/InstallFont() code.
- - Well , it does work right now (29.10.94)
- */
- struct FontCacheList *cachelist,*new_font_entry;
- struct TextFont *AmigaFont;
- WORD TIGA_Modulo;
- WORD BitMap_XSize;
- APTR TIGA_BitMap;
- CONFIG config;
-
- /* install the textFont into the RastPort */
-
- if (textFont) // NULL-Pointer übergeben !
- {
-
- /* -----------------------------------
- * this is what th original does
- * SetFont() calls this gfx-function :
- * -----------------------------------
- */
-
- ExtendFont(textFont,NULL); // debug !
-
- rp->TxHeight = textFont->tf_YSize;
- rp->TxWidth = textFont->tf_XSize;
- rp->TxBaseline = textFont->tf_Baseline;
- rp->AlgoStyle = (UBYTE)0;
- rp->Font = textFont;
-
- /* end of original */
-
-
- if (InstallFont(textFont)) // Additional Functions to install the Font on the a2410
- return(0);
- }
- return(-1); /* then exit */
- }
-
-
- void __asm GfxSetPointer(register __a0 struct Window *window,register __a1 UWORD *pointer,
- register __d0 long height,register __d1 long width,register __d2 long xOffset,register __d3 long yOffset)
- {
- /*
- not included yet
- only a default Pointer is available !
- see InstallPointer() above.
- */
- CURSOR Pointer;
-
- Pointer.width = width;
- Pointer.height = height;
- Pointer.hot_x = xOffset;
- Pointer.hot_y = yOffset;
- Pointer.data = (ULONG)pointer;
-
- InstallPointer(&Pointer);
- }
-
- void __asm GfxClearPointer(register __a0 struct Window *win)
- {
- LockLib();
-
- set_curs_state(0);
-
- UnlockLib();
- }
-
- void __asm GfxPointerXY(register __a0 struct RastPort *rp,register __d0 long x,register __d1 long y)
- {
- /*
- Will be replaced by GfxMoveSprite() some times !
- */
- LockLib();
-
- set_curs_xy(x,y);
-
- UnlockLib();
- }
-
- void __asm GfxSetRGB4(register __a0 struct ViewPort *vp,
- register __d0 long index,
- register __d1 unsigned long red,
- register __d2 unsigned long green,
- register __d3 unsigned long blue )
- {
- LockLib();
-
- set_palet_entry(index,(red*16),green*16,blue*16,0);
-
- UnlockLib();
- }
-
- void __asm GfxSetRGB32(register __a0 struct ViewPort *vp,
- register __d0 unsigned long n,
- register __d1 unsigned long r,
- register __d2 unsigned long g,
- register __d3 unsigned long b )
- {
- LockLib();
-
- set_palet_entry(n,r,g,b,0);
-
- UnlockLib();
- }
-
- LONG __asm GfxBltBitMap(register __a0 struct BitMap *srcBitMap,
- register __d0 long xSrc, register __d1 long ySrc,
- register __a1 struct BitMap *destBitMap,
- register __d2 long xDest,register __d3 long yDest,
- register __d4 long xSize,register __d5 long ySize,
- register __d6 unsigned long minterm,register __d7 unsigned long mask,
- register __a2 PLANEPTR tempA )
- {
- struct TigaScreen *ts;
- struct BMCacheList *cachelist;
- struct ChunkyMap *chunkymap;
- long i,planesize,plane,y;
- long width,height,pitch,workbuffer;
- ULONG xoffset,xrest;
- UBYTE col,depth;
-
- /*
- * do not use dynamic buffer any more - bufmem is static now
- */
-
- LockLib();
-
- set_clip_rect(1024,1024,0,0);
-
- ts = &(globals.tigascreen);
-
- /* Wenn Source und Target am Screen liegen : bitblt() */
- // --------------------------------------------------
-
- if (destBitMap == globals.bitmap)
- {
- if ((minterm) == 0)
- {
- #ifdef DEBUG
- KPrintF("Blt:CLEAR - Miniterm (%02lx)\n",minterm);
- #endif
- set_ppop(3); // dest = 0 !
-
- fill_rect(xSize,ySize,xDest,yDest);
- }
- else
- {
- if ((srcBitMap == globals.bitmap)) // && (destBitMap == globals.bitmap))
- {
- #ifdef DEBUG
- KPrintF("Blt:ONSCREEN - Miniterm (%02lx) \n",minterm);
- #endif
- switch (minterm)
- {
- case 0x00 : set_ppop(3);
- break;
- case 0xC0 : set_ppop(0);
- break;
- default : set_ppop(0);
- break;
- }
- transp_off();
-
- set_srcbm(0,0,0,0,0);
- set_dstbm(0,0,0,0,0);
- bitblt(xSize,ySize,xSrc,ySrc,xDest,yDest);
- synchronize();
- }
-
- /* Wenn nur das Target am Screen liegt : hst2gsp() + planar2chunky ! */
- // -----------------------------------------------------------------
-
- if ((srcBitMap != globals.bitmap))// && (destBitMap == globals.bitmap))
- {
-
- #ifdef DEBUG
- KPrintF("Blt:OFFSCREEN - Miniterm (%02lx) \n",minterm);
- #endif
-
- /*
- switch (minterm)
- {
- case 0x00 : set_ppop(3);
- break;
- case 0xC0 : set_ppop(0);
- break;
- default : set_ppop(0);
- break;
- }
- transp_off();
- if (cachelist = FindBitmap(srcBitMap))
- {
- chunkymap = cachelist->chunkymap;
- host2gspxy(chunkymap->data,chunkymap->xSize,
- ts->ScreenAddr,ts->Pitch,
- xSrc,ySrc,
- xDest,yDest,
- xSize,ySize,
- chunkymap->depth,INTEL_BYTES);
- }
- else
- {
- */
- /*
- should be a size checking here :
- size < MinCacheSize :
- kein Cache -> selectives Planar to chunky :
- CopyPlane2Chunky(planes,chunkymap,Base,xSize,ySize,pitch);
- host2gspxy(chunky,ts->ScreenAddr,ts->pitch,0,0,xDest,yDest,xSize,ySize);
- */
- /*
- if (chunkymap = Plane2Chunky8(srcBitMap))
- {
- host2gspxy(chunkymap->data,chunkymap->xSize,
- ts->ScreenAddr,ts->Pitch,
- xSrc,ySrc,
- xDest,yDest,
- xSize,ySize,
- chunkymap->depth,INTEL_BYTES);
-
- #ifndef NO_BM_CACHE
- if (!(InsertChunky(chunkymap,srcBitMap)))
- #endif
- {
- FreeVec(chunkymap->data);
- FreeVec(chunkymap);
- }
- }
- #ifdef DEBUG
- else
- KPrintF("Blt:NO CHUNKY MEM \n");
- #endif
- }
- */
-
- /*
- * This is new : use 34010 to convert plane to chunky !
- * OR (set_fcolor(1<<i)) TO Dest does work, but I do have some troubles.
- * That damn thing does not run without errors, I do not know what's wrong.
- * I think it could be a TIGA implementation bug.
- * It does work in most cases but it forgets to blit from time to time ...?
- * Do not use dynamic allocation any more - I use a static buffer now ! (maybe this fix some probs)
- *
- * WARNING : host2gxpxy() requires a dest. addr. and pitch that is a multiple of 16 !!!!
- *
- * **** WATCH the line "synchronize();" this fixes my troubles !!! ****
- */
- transp_off();
- xoffset = (xSrc >> 3)&0xff; // => xSrc/8, max 8 Bit
- xrest = (xSrc) & 0x7L; // => xSrc % 8; == & %111
- width = ((xSize>>3)+2)&~1L; // to round bytes left
- pitch = width<<3; // planepitch in bits, WORD boundary
- planesize = (WORD)width*(WORD)ySize;
-
- depth = (UBYTE)srcBitMap->Depth;
- workbuffer = bufmem;
- if (planesize <= bufmemsize)
- {
- set_srcbm(bufmem,pitch,pitch,ySize,1); // the new with is the pitch because it is only 1 bit/pixel
- set_dstbm(0,0,0,0,0); // destination is the screen
- /*
- * the plane 0 ( using only plane 0 does work ...)
- */
- set_ppop(DST_IS_SRC); // draw first plane only ! color 1 ( = Plane 1)
- host2gspxy(srcBitMap->Planes[0],srcBitMap->BytesPerRow,
- workbuffer,pitch, // is bitsize
- xoffset,ySrc, // have to get the x-offset in BYTES which is xSrc/8
- 0,0, // transform Sx/Sy -> 0/0 !
- width,ySize, // this is a new width, rounded first and last byte, and WORD justified
- 8,BIT_SWAP); // I copy BytesPerRow x ySize, so host2gsp is faster than pixsize is 1 !
-
- set_colors(1,0); // plane 0 = col 1, 0 -> clear Background
- bitblt(xSize,ySize,xrest,0,xDest,yDest); // the xrest is the rest of xSrc/8 in bits
-
- synchronize();
-
- /*
- * the rest of the planes are added to plane 0 (if exists)
- */
- set_ppop(SRC_OR_DST); // "or" the other planes to the dest
- for (col = 1; col < depth ;col++)
- {
- host2gspxy(srcBitMap->Planes[col],srcBitMap->BytesPerRow,
- workbuffer,pitch, // is bitsize
- xoffset,ySrc, // have to get the x-offset in BYTES which is xSrc/8
- 0,0, // transform Sx/Sy -> 0/0 !
- width,ySize, // this is a new width, rounded first and last byte, and WORD justified
- 8,BIT_SWAP);
-
- set_fcolor(1<<col);
- bitblt(xSize,ySize,xrest,0,xDest,yDest);
-
- synchronize();
- }
- set_srcbm(0,0,0,0,0);
- set_ppop(0);
- }
- }
- }
- }
-
- /* Wenn nur die Source am Screen liegt : gsp2hst() + puffern !
- noch nicht. Kommt noch, wird aber ein bißchen dauern !
- */
- /*
- if ((destBitMap != globals.bitmap) // &&(srcBitMap == globals.bitmap))
- {
- #ifdef DEBUG
- KPrintF("Blt:CASHFLUSH - Miniterm (%02lx) \n",minterm);
- #endif
- if (cachelist = FindBitmap(destBitMap))
- {
- cachelist->chunkymap->flag |= BMF_FORCE_FLUSH;
- FlushCacheMap(cachelist);
- }
- }
- */
- UnlockLib();
- return(0);
- }
-
- struct ChunkyMap __asm *GfxBltTiga(register __a0 struct BitMap *srcBitMap,
- register __d0 long xSrc, register __d1 long ySrc,
- register __a1 PTR gsp_addr,
- register __d2 long xDest,register __d3 long yDest,
- register __d4 long xSize,register __d5 long ySize)
- {
- /*
- Used to copy a planar bitmap to chunky tiga screen.
- gsp_addr could be a buffer address in gsp_memory.
- Is not supported yet (no function to allocate gsp_mem in gfx.library !).
- So make sure gsp_addr = NULL when calling !
- */
- struct ChunkyMap *chunkymap;
- struct TigaScreen *ts;
-
- LockLib();
-
- chunkymap = Plane2Chunky8(srcBitMap);
-
- ts = &globals.tigascreen;
-
- gsp_addr = ts->ScreenAddr;
-
- host2gspxy(chunkymap->data,chunkymap->xSize,
- gsp_addr,ts->Pitch,
- xSrc,ySrc,
- xDest,yDest,
- xSize,ySize,
- chunkymap->depth,INTEL_BYTES);
-
- UnlockLib();
-
- return(chunkymap);
- }
-
- void __asm BltChunkyMap(register __a0 struct ChunkyMap *chunkymap,
- register __d0 long xSrc, register __d1 long ySrc,
- register __d2 long xDest,register __d3 long yDest,
- register __d4 long xSize,register __d5 long ySize)
- {
- struct TigaScreen *ts;
- PTR gsp_addr;
-
- LockLib();
-
- ts = &globals.tigascreen;
-
- gsp_addr = ts->ScreenAddr;
-
- host2gspxy(chunkymap->data,chunkymap->xSize,
- gsp_addr,ts->Pitch,
- xSrc,ySrc,
- xDest,yDest,
- xSize,ySize,
- chunkymap->depth,INTEL_BYTES);
-
- UnlockLib();
- }
-
- BOOL __asm GfxSetUpScreen(register __a0 struct Screen *screen)
- {
- /*
- Connects a Intuition Screen to an entry with Infos about the Tiga-display.
- */
- CONFIG config;
- struct TigaScreen *tigascreen;
-
- if (!screen) return(FALSE);
-
- LockLib();
-
- get_config(&config);
-
- globals.screen = screen;
- globals.bitmap = screen->RastPort.BitMap;
-
- tigascreen = &(globals.tigascreen);
-
- tigascreen->ScreenAddr = config.display_mem_start;
- tigascreen->Width = config.mode.disp_hres;
- tigascreen->Height = config.mode.disp_vres;
- tigascreen->Depth = config.mode.palet_gun_depth;
- tigascreen->Pitch = config.mode.disp_pitch;
-
- UnlockLib();
- return(TRUE);
- }
-
- LONG __asm GfxCheckTiga(register __a1 struct BitMap *bitmap)
- {
- /*
- checks out if an operation is performed on Tiga screen or native Amiga display !
- (not used yet !)
- */
- struct BMCacheList *cachelist;
-
- cachelist = FirstBitMapEntry;
- while (cachelist)
- {
- if ((LONG)cachelist->bitmap == (LONG)bitmap)
- return(1L);
- cachelist = cachelist->next;
- }
- return(0L);
- }
-
- LONG __asm GfxCheckBitMap(register __a1 struct BitMap *bitmap)
- {
- if ((LONG)(globals.screen->RastPort.BitMap) == (LONG)bitmap) return(TRUE);
-
- return(FALSE);
- }
-
- LONG __asm GfxCheckRP(register __a1 struct RastPort *rp)
- {
- struct RastPort *RP;
-
- RP = &(globals.screen->RastPort);
-
- if ((LONG)RP == (LONG)rp) return(TRUE);
-
- return(FALSE);
- }
-
- LONG __asm GfxCheckVP(register __a1 struct ViewPort *vp)
- {
- struct ViewPort *VP;
-
- VP = &(globals.screen->ViewPort);
- if ((LONG)VP == (LONG)vp) return(TRUE);
-
- return(FALSE);
- }
-
- /*
- Area-Draw() Befehle !
- */
- LONG __asm GfxAreaEnd(register __a1 struct RastPort *rp )
- {
- int i;
- long cnt,ptrnsz;
- long XOffset=0,YOffset=0;
- POINT *pnts;
- PATTERN gsp_ptrn;
- struct ClipRect *cliprect;
-
- if (rp)
- {
- if (rp->Layer)
- {
- LockLayerRom(rp->Layer);
- XOffset = ((rp->Layer->bounds.MinX - rp->Layer->Scroll_X));
- YOffset = ((rp->Layer->bounds.MinY - rp->Layer->Scroll_Y));
- }
-
- LockLib();
-
- DwMode(rp);
-
- gsp_ptrn.data = NULL;
-
- if (rp->AreaPtrn)
- {
- ptrnsz = ((rp->AreaPtSz)<=4) ? (1<<(rp->AreaPtSz)) : 16;
- gsp_ptrn.width=16;
- gsp_ptrn.height=16; // tiga supports only 16 lines !!!
- gsp_ptrn.depth=1; // no more than 1 plane now !
- gsp_ptrn.data=(PTR)gsp_malloc(32); // 32 bytes = 16 WORDS space for pattern !
- if (ptrnsz==16)
- host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data),2*ptrnsz,2); // WORD aligned
- else
- for (i=0;i<=0xF0;i+=(0x10*ptrnsz)) // bit offset to current pos. - WORD aligned !
- host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data)+i,2*ptrnsz,2);
- set_patn(&gsp_ptrn);
- }
-
- AreaDraw(rp,rp->AreaInfo->FirstX,rp->AreaInfo->FirstY);
- cnt = rp->AreaInfo->Count;
- pnts = (POINT*)rp->AreaInfo->VctrTbl;
-
- cliprect = rp->Layer->ClipRect;
- while (cliprect)
- {
- if (ClipIt(cliprect,NULL)!=CLIP_OUT)
- {
- set_draw_origin(XOffset,YOffset);
-
- if (!rp->AreaPtrn)
- fill_polygon(cnt,pnts);
- else
- patnfill_polygon(cnt,pnts);
- }
- cliprect = cliprect->Next;
- set_draw_origin(0,0);
- }
- /*
- if ((rp->Flags)&AREAOUTLINE)
- {
- set_fcolor(rp->AOlPen);
- draw_polyline(cnt,pnts);
- }
- */
- if (gsp_ptrn.data) gsp_free(gsp_ptrn.data);
-
- rp->AreaInfo->VctrPtr=rp->AreaInfo->VctrTbl;
- rp->AreaInfo->FlagPtr=rp->AreaInfo->FlagTbl;
- rp->AreaInfo->Count=0;
-
-
- UnlockLib();
- if (rp->Layer) UnlockLayerRom(rp->Layer);
-
- return(0);
- }
- return(-1);
- }
-
- LONG __asm GfxAreaMove(register __a1 struct RastPort *rp,register __d0 long x,register __d1 long y )
- {
- int i;
-
- register long cnt;
- register UWORD ptrnsz;
- PATTERN gsp_ptrn;
-
- LockLib();
-
- set_colors(rp->FgPen,rp->BgPen);
- if (rp->AreaInfo->VctrPtr)
- {
- cnt=rp->AreaInfo->Count;
- if (!rp->AreaPtrn)
- fill_polygon(cnt,rp->AreaInfo->VctrTbl);
- else
- {
- ptrnsz = ((rp->AreaPtSz)<=4) ? (1<<(rp->AreaPtSz)) : 16;
- gsp_ptrn.width=16;
- gsp_ptrn.height=16; // tiga supports only 16 lines !!!
- gsp_ptrn.depth=1; // no more than 1 plane now !
- gsp_ptrn.data=(PTR)gsp_malloc(32); // 32 bytes = 16 WORDS space for pattern !
- if (ptrnsz==16)
- host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data),2*ptrnsz,2); // WORD aligned
- else
- for (i=0;i<=0xF0;i+=(0x10*ptrnsz)) // bit offset to current pos. - WORD aligned !
- host2gsp((char *)(rp->AreaPtrn),(gsp_ptrn.data)+i,2*ptrnsz,2);
- set_patn(&gsp_ptrn);
- patnfill_polygon(cnt,rp->AreaInfo->VctrTbl);
- gsp_free(gsp_ptrn.data);
- }
- if (rp->Flags&AREAOUTLINE)
- {
- set_fcolor(rp->AOlPen);
- draw_polyline(cnt,rp->AreaInfo->VctrTbl);
- }
- // FreeVec(rp->AreaInfo->VctrTbl);
- rp->AreaInfo->VctrPtr=NULL;
- rp->AreaInfo->Count=0;
- UnlockLib();
- return(1);
- }
-
- if (rp->AreaInfo->VctrTbl=(WORD *)AllocVec((rp->AreaInfo->MaxCount*4),MEMF_CLEAR))
- {
- rp->AreaInfo->FirstX=rp->cp_x=x;
- rp->AreaInfo->FirstY=rp->cp_y=y;
- rp->AreaInfo->VctrPtr=rp->AreaInfo->VctrTbl;
- *(rp->AreaInfo->VctrPtr++)=x;
- *(rp->AreaInfo->VctrPtr++)=y;
- *rp->AreaInfo->FlagPtr=(UBYTE)rp->Flags;
- rp->AreaInfo->Count=1;
- UnlockLib();
- return(0);
- }
- UnlockLib();
- return(-1);
- }
-
- LONG __asm GfxAreaDraw(register __a1 struct RastPort *rp,register __d0 long x,register __d1 long y )
- {
- int i;
-
- register WORD cnt;
-
-
- if (rp->AreaInfo->VctrPtr)
- {
- LockLib();
-
- cnt=rp->AreaInfo->Count++;
- *(rp->AreaInfo->VctrPtr++)=x;
- *(rp->AreaInfo->VctrPtr++)=y;
-
- UnlockLib();
- return(0);
- }
- return(-1);
- }
-