home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / GFX / Painting / XiPaint3.2-Aminet11.lzx / XiPaint / Developer / OutputLib / xout_P.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-25  |  56.9 KB  |  1,545 lines

  1. /* Last Change: Mon Sep 26 12:44:15 1994 */
  2. /*
  3.   xiout_w.c
  4.   Picasso-Screen 
  5. */
  6.  
  7. /* ************************************************************************************************** */
  8. /* Includes (+gst) */
  9. /* ************************************************************************************************** */
  10.  
  11. #include "xOut_P.library_rev.h"
  12.  
  13. #include "libraries/vilintuisup.h"
  14. #include "libraries/screenmode.h"
  15. #include "proto/vilintuisup_lib.h"
  16.  
  17. #include "libraries/retina.h"           /* Für den RectMode_RGBA */
  18.  
  19. #include "libraries/xigfx.h"
  20. #include "libraries/xout.h"
  21.  
  22. #define RED 0
  23. #define GRN 1
  24. #define BLU 2
  25. #define KEY 3
  26.  
  27. /* ************************************************************************************************** */
  28. /* Typendeklaration für Brush (Könnte gefährlich werden! */
  29. /* ************************************************************************************************** */
  30. struct brush{
  31.   union color *memory;  /* Brush-Speicher */
  32.   WORD x,y;             /* Merker für letzte Transaktion. Für Blit! */
  33.   WORD width,height;
  34.   WORD alpha;           /* Yes=1, No = 0 */
  35.   WORD nr;              /* Welcher Brush in der Liste ist es denn? */
  36.   WORD hd_ram;          /* Ist der Brush im RAM(0) oder auf der HD(1)? */
  37.   WORD mode;            /* 0 = Rechteckiger Brush, 1 Polygon */
  38.   WORD offx, offy;      /* Offset des Cursors von der linken oberen Ecke des Brushes */
  39.   WORD art;             /* 0 = Pinsel, 1=Stift */
  40.   WORD belegt;          /* 0= frei, 255 ist besetzt */
  41. };
  42.  
  43. /* ************************************************************************************************** */
  44. /* Prototyping */
  45. /* ************************************************************************************************** */
  46. __asm __saveds BOOL XO_init_brushblit(register __a0 struct Display *Display, register __d0 WORD x, register __d1 WORD y, 
  47.                         register __d2 WORD width, register __d3 WORD height, register __a1 union color *memory, register __d4 LONG mode);
  48. __asm __saveds void XO_free_brushblit(register __a0 struct Display *Display);
  49. __asm __saveds BOOL XO_move_brushblit(register __a0 struct Display *Display, register __d0 WORD x, register __d1 WORD y);
  50.  
  51. /* Die beiden Routinen sind unsicher! Sie funktionieren nur, wenn sich weder der Brush noch deren
  52.    Koordinaten geändert haben!. Der Untergrund darf sich geändert haben! 
  53. */
  54. __asm __saveds void XO_on_brushblit(register __a0 struct Display *Display);
  55. __asm __saveds void XO_off_brushblit(register __a0 struct Display *Display);
  56.  
  57. __asm __saveds BOOL XO_init (register __a0 struct Display *Display, register __a1 struct xo_init *mode);
  58. __asm __saveds void XO_close(register __a0 struct Display *Display);
  59.  
  60. /****  Prototypes der Zeichen-Behelfsroutinen  ****/
  61.  
  62. __asm __saveds void XO_inv_hline(register __a0 struct Display *Display, register __d0 SHORT x, register __d1 SHORT y, register __d2 SHORT x2);
  63. __asm __saveds void XO_inv_vline(register __a0 struct Display *Display, register __d0 SHORT x, register __d1 SHORT y, register __d2 SHORT y2);
  64. __asm __saveds void XO_inv_point(register __a0 struct Display *Display, register __d0 SHORT x, register __d1 SHORT y);
  65.  
  66. __asm __saveds void XO_cls_rect(register __a0 struct Display *Display, register __d0 SHORT x1, register __d1 SHORT y1, register __d2 SHORT x2, register __d3 SHORT y2);
  67.  
  68. __asm __saveds void XO_writerect(register __a0 struct Display *Display, register __a1 UBYTE *Mem,register __d0 UWORD MemX,
  69.                 register __d1 UWORD MemY, register __d2 UWORD MemWidth, register __d3 ULONG Mode,
  70.                 register __d4 WORD ScreenX, register __d5 WORD ScreenY, register __d6 WORD SizeX,  register __d7 WORD SizeY, register __a2 UBYTE *clut);
  71.  
  72. __asm __saveds void XO_readrect(register __a0 struct Display *Display, register __a1 UBYTE *Mem, register __d0 UWORD MemX, register __d1 UWORD MemY, 
  73.                 register __d2 UWORD MemWidth, register __d3 WORD ScreenX,  register __d4 WORD ScreenY, register __d5 WORD SizeX, register __d6 WORD SizeY);
  74.  
  75. /* Liefert NULL oder bei abgeschnittenen Brush die Koordinaten vom Blit 
  76.    (Es werden die Update-Koordinaten angegeben, aber nichts geblittet)
  77. */
  78. __asm __saveds struct brush *XO_blitrect(register __a0 struct Display *Display, register __d0 WORD x, register __d1 WORD y, 
  79.                         register __d2 WORD width, register __d3 WORD height, register __d4 WORD x2, register __d5 WORD y2);
  80.  
  81. /* Und die Schlüsselroutine */
  82.  
  83. __asm __saveds BOOL XO_who_are_you (register __a0 struct xo_init *init_struct);
  84. __asm __saveds void XO_ScreenToFront (register __a0 struct Display *Display);
  85. __asm __saveds void XO_ScreenToBack (register __a0 struct Display *Display);
  86. __asm __saveds BOOL XO_screen_request (register __a0 struct xo_init *init_struct);
  87.  
  88. /* Die Möglichkeit für Erweiterungen */
  89.  
  90. __asm __saveds ULONG XO_SetReg(register __d0 ULONG Tag, register __d1 ULONG Data);
  91.  
  92.  
  93.  
  94. /* ************************************************************************************************** */
  95. /* Globale Variable */
  96. /* ************************************************************************************************** */
  97. #define DOSLIB  "dos.library"
  98. #define DOSVER  36L     
  99. #define INTUILIB "intuition.library"
  100. #define INTUIVER 37L                    /* Wegen SetWindowPointer */
  101. #define GFXLIB "graphics.library"
  102. #define GFXVER 36
  103.  
  104. struct DosLibrary *DOSBase;
  105. struct ExecBase *SysBase;
  106. struct Library *DiskfontBase;
  107. struct GfxBase *GfxBase = NULL;
  108. struct IntuitionBase *IntuitionBase=NULL;
  109. /* struct VLabBase *VLabBase = NULL; */
  110.  
  111. struct Screen *PaintScreen = NULL;                         /* Picasso-Screen, Retina */
  112. struct NewWindow nw_p;                                     /* Struktur für das IDCMP Fenster           */
  113.  
  114. ULONG *clut24;
  115. ULONG BACKGROUND = 0x88888888;
  116.  
  117. #define ABS(x)   ((x<0)?(-(x)):(x))
  118. /* Picasso, villagetronic */
  119.  
  120. /* Picasso: bgrbgrbgr
  121.    XiPaint: bgbgbgbg  rrrr
  122.        neu: argbargb
  123. */
  124.  
  125. typedef
  126. struct
  127. {
  128.   UBYTE b;                                                 /* blue byte first !!! */
  129.   UBYTE g;                                                 /* green byte second   */
  130.   UBYTE r;                                                 /* red byte third      */
  131. }
  132. p_RGB;
  133.  
  134. typedef
  135. struct
  136. {
  137.   UBYTE r;
  138.   UBYTE g;
  139.   UBYTE b;
  140.   UBYTE a;
  141. }
  142. argb;
  143.  
  144. struct Library *VilIntuiBase = NULL;
  145.  
  146. struct TagItem openscreentags[] =
  147. {
  148.   {TAVIS_SCREEN_MODEID, 0},
  149.   {TAG_DONE, 0}
  150. };
  151.  
  152. struct TagItem requesttags[] =
  153. {
  154.   {TAVIS_MINDEPTH, 24},
  155.   {TAVIS_MAXDEPTH, 24},
  156.   {TAG_DONE, 0}
  157. };
  158.  
  159. void HardFBox (struct Display *Display, SHORT x, SHORT y, SHORT x2, SHORT y2, ULONG color);
  160. void PIILineI (struct Screen *s, UWORD xs, UWORD ys, UWORD xe, UWORD ye);
  161. void SetPixelI (struct Screen *s, UWORD x, UWORD y);
  162. void unlock (void);
  163. void lock (void);
  164.  
  165. /* old_blit.memory ist der Untergrund, wo der Brush draufgezeichnet ist.
  166.    bbrush_mem ist der Pointer auf den Wirklichen Brushspeicher.
  167.    tmpmem ist der vorübergehende Speicher vom Untergrund, solange nicht
  168.    geblittet ist */
  169. struct brush old_blit;
  170. union color *bbrush_mem;                                                       /* Pointer auf den aktuellen wirklichen Speicher des Brush
  171.                                                                                 * (Merker) */
  172. WORD _rect_drawn;
  173. char lib_buffer[255];
  174.  
  175. /****  Namen der zugehörigen Windows und Gfx-Libraries  ****/
  176.  
  177. char xigfx_libname[] = "xigfx_u.library";
  178.  
  179. char *xiwin_libnames[] = {      "xiwin_u.library",
  180.                                 "xiwin_uw.library"
  181.                          };
  182.  
  183. char *xiwin_mousenames[] = {    "Amiga-Maus",
  184.                                 "Wacom II-S/IV Tablett"
  185.                            };
  186.  
  187. short ximousenr = 2;
  188.  
  189.  
  190.  
  191. /* ************************************************************************************************** */
  192. /* Internes Prototyping */
  193. /* ************************************************************************************************** */
  194. void rect_brushblito (struct Display *Display);
  195. void rect_brushblitn (struct Display *Display, WORD x, WORD y);
  196. void rect_brushblit (struct Display *Display, WORD x, WORD y);
  197. void move_pbrushblit (struct Display *Display, WORD x, WORD y);
  198. BOOL move_ibrushblit (struct Display *Display, WORD x, WORD y);
  199.  
  200. /* Source - und Destination-Rechteck ist gleich breit (from_w) */
  201. BOOL rect_mem_cpy (union color *from_mem, WORD from_x, WORD from_y, UWORD from_w, union color *to_mem,
  202.                    WORD to_x, WORD to_y, UWORD to_w, UWORD to_h)
  203. {
  204.   union color *anfang, *dest;
  205.   WORD i;
  206.  
  207.   if (from_mem == 0)
  208.     return (FALSE);
  209.   if (to_mem == 0)
  210.     return (FALSE);
  211.  
  212.   anfang = from_mem + from_y * from_w + from_x;
  213.   dest = to_mem + to_y * from_w + to_x;
  214.   for (i = 0; i < to_h; i++)
  215.     CopyMem (anfang + (from_w * i), dest + (from_w * i), (LONG) (to_w * sizeof (union color)));
  216.  
  217. /*     memcpy(dest + (from_w * i), anfang + (from_w * i), (size_t)(to_w * sizeof(union color))); */
  218.   return (TRUE);
  219. }
  220.  
  221. /* ************************************************************************************************** */
  222. /* Los geths */
  223. /* ************************************************************************************************** */
  224. __asm __saveds BOOL XO_init_brushblit(register __a0 struct Display *Display, register __d0 WORD x, register __d1 WORD y, 
  225.                         register __d2 WORD width, register __d3 WORD height, register __a1 union color *memory, register __d4 LONG mode)
  226. {
  227.   if ((width == 0) && (height == 0))
  228.   {
  229.     old_blit.width = width;
  230.     old_blit.height = height;
  231.     return (FALSE);
  232.   }
  233.  
  234.   if (old_blit.memory)                                                         /* Falls noch Speicher da, erst freen */
  235.     XO_free_brushblit (Display);
  236.   old_blit.memory = AllocVec ((ULONG)(width * height * sizeof (union color)), MEMF_ANY | MEMF_CLEAR);
  237.  
  238.   old_blit.x = x;
  239.   old_blit.y = y;
  240.   old_blit.width = width;
  241.   old_blit.height = height;
  242.   old_blit.mode = mode;
  243.   bbrush_mem = memory;                                                         /* Pointer zuweisen und merken */
  244.  
  245.   if (mode != 0)
  246.   {
  247.     move_ibrushblit (Display, x, y);
  248.   }
  249.   else
  250.   {
  251.     if (old_blit.memory)                                                       /* Speicher da */
  252.     {
  253.       XO_readrect (Display, (UBYTE *) old_blit.memory, 0, 0, old_blit.width, old_blit.x, old_blit.y,
  254.                    old_blit.width, old_blit.height);
  255.       XO_writerect (Display, (UBYTE *) memory, 0, 0, old_blit.width, RECTMODE_RGBA, old_blit.x, old_blit.y,
  256.                     old_blit.width, old_blit.height, NULL);
  257.     }
  258.     else
  259.       /* Kein Speicher zum Zwischenlagern */
  260.     {
  261.       rect_brushblito (Display);                /* Falls was da war wegräumen */
  262.       rect_brushblitn (Display, x, y);
  263.     }
  264.   }
  265.   return (TRUE);
  266. }
  267.  
  268. __asm __saveds void XO_free_brushblit(register __a0 struct Display *Display)
  269. {
  270.   if ((old_blit.width == 0) && (old_blit.height == 0))
  271.     return;
  272.  
  273.   if (old_blit.memory)                                                         /* Falls noch Speicher da, erst freen */
  274.   {
  275.     XO_writerect (Display, (UBYTE *) old_blit.memory, 0, 0, old_blit.width, RECTMODE_RGBA, old_blit.x, old_blit.y,
  276.                   old_blit.width, old_blit.height, NULL);
  277.     FreeVec (old_blit.memory);
  278.     old_blit.memory = NULL;
  279.   }
  280.   else
  281.   {
  282.     rect_brushblito (Display);
  283.   }
  284.   bbrush_mem = NULL;                                                           /* Brauch ich nicht mehr (Merker für alten Brush */
  285. }
  286.  
  287. void rect_brushblito (struct Display *Display)
  288. {
  289.   if (_rect_drawn == 1)                                                        /* Rechteck wurde schon gezeichnet */
  290.   {
  291.     XO_inv_hline (Display, old_blit.x, old_blit.y, (WORD) (old_blit.x + old_blit.width));       /* Alte Koordinaten löschen */
  292.     XO_inv_hline (Display, old_blit.x, (WORD) (old_blit.y + old_blit.height), (WORD) (old_blit.x + old_blit.width));
  293.     XO_inv_vline (Display, old_blit.x, (WORD) (old_blit.y + 1), (WORD) (old_blit.y + old_blit.height - 1));
  294.     XO_inv_vline (Display, (WORD) (old_blit.x + old_blit.width), (WORD) (old_blit.y + 1), (WORD) (old_blit.y + old_blit.height - 1));
  295.     _rect_drawn = 0;
  296.   }
  297. }
  298. void rect_brushblitn (struct Display *Display, WORD x, WORD y)
  299. {
  300.   if (_rect_drawn == 0)                                                        /* Noch nichts gezeichnet */
  301.   {
  302.     XO_inv_hline (Display, x, y, (WORD) (x + old_blit.width));                 /* Neue Koordinaten zeichnen */
  303.     XO_inv_hline (Display, x, (WORD) (y + old_blit.height), (WORD) (x + old_blit.width));
  304.     XO_inv_vline (Display, x, (WORD) (y + 1), (WORD) (y + old_blit.height - 1));
  305.     XO_inv_vline (Display, (WORD) (x + old_blit.width), (WORD) (y + 1), (WORD) (y + old_blit.height - 1));
  306.     _rect_drawn = 1;
  307.   }
  308. }
  309. void rect_brushblit (struct Display *Display, WORD x, WORD y)
  310. {
  311.   rect_brushblito (Display);
  312.   rect_brushblitn (Display, x, y);
  313. }
  314.  
  315. __asm __saveds BOOL XO_move_brushblit(register __a0 struct Display *Display, register __d0 WORD x, register __d1 WORD y)
  316. {
  317.   WORD dx, dy, adx, ady, sw, sh;
  318.   struct brush *okblit;
  319.   union color *tmpmem;
  320.  
  321.   if ((old_blit.width == 0) && (old_blit.height == 0))
  322.     return (FALSE);
  323.  
  324.   dx = x - old_blit.x;
  325.   dy = y - old_blit.y;
  326.  
  327.   if ((dx == 0) && (dy == 0))                                                  /* Kein Blit da keine Verschiebung */
  328.     return (TRUE);
  329.  
  330. #if 0
  331.   if ((dx + old_blit.width) < 0)                                               /* Blit ausserhalb von Gut und Böse */
  332.     return (TRUE);
  333.   if ((dy + old_blit.height) < 0)                                              /* Blit ausserhalb von Gut und Böse */
  334.     return (TRUE);
  335. #endif
  336.  
  337.   if (!old_blit.memory)                                                        /* Kein Speicher zum verschieben da ... */
  338.   {
  339.     rect_brushblit (Display, x, y);
  340.   }
  341.   else
  342.     /* Jetzt gehts heiss her: Fallunterscheidung der rechteckigen Blits */
  343.   {
  344.     if (old_blit.mode == 0)                                                    /* Rechteck blitten */
  345.     {
  346.       adx = ABS (dx);
  347.       ady = ABS (dy);
  348.       sw = old_blit.width - adx;
  349.       sh = old_blit.height - ady;
  350.  
  351.       /* Temporären Speicher belegen */
  352.       tmpmem = AllocVec ((ULONG)(old_blit.width * old_blit.height * sizeof (union color)), MEMF_ANY);
  353.  
  354.       if (!tmpmem)                                                             /* Keinen Speicher bekommen */
  355.       {
  356.         rect_brushblitn (Display, x, y);
  357.         XO_free_brushblit (Display);                                           /* Wenns eh nicht geht, dann brauch ich auch keinen
  358.                                                                                 * ZwischenSpeicher */
  359.         return (TRUE);
  360.       }
  361.  
  362.       if ((adx > old_blit.width) || (ady > old_blit.height))                   /* Verschiebung größer als Brush */
  363.       {
  364.         /* Komplette Brushdest retten */
  365.         XO_readrect (Display, (UBYTE *) tmpmem, 0, 0, old_blit.width, x, y, old_blit.width, old_blit.height);
  366.         /* Bereich mit Blitter verschieben */
  367.         okblit = XO_blitrect (Display, old_blit.x, old_blit.y, old_blit.width, old_blit.height, x, y);
  368.         if (okblit)                                                            /* Es ist nicht 0 zurückgekommen, also der Wurm drin! */
  369.         {                                                                      /* Also Destination komplett updaten */
  370.           if (bbrush_mem)                                                      /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  371.             XO_writerect (Display, (UBYTE *) bbrush_mem, 0, 0, old_blit.width, RECTMODE_RGBA, x, y,
  372.                           old_blit.width, old_blit.height, NULL);
  373.  
  374.           /* Sollte derzeit nicht vorkommen! \nIst nur für teilw. Blit von negativ gedacht\n */
  375.           /* FreeVec(okblit);    *//* Speicher wieder freigeben (Future) */
  376.         }
  377.         /* Kompletten Alten Bereich updaten */
  378.         if (old_blit.memory)                                                   /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  379.           XO_writerect (Display, (UBYTE *) old_blit.memory, 0, 0, old_blit.width, RECTMODE_RGBA, old_blit.x, old_blit.y,
  380.                         old_blit.width, old_blit.height, NULL);
  381.       }
  382.       else if (dx == 0)                                                        /* Verschiebung nach oben oder unten */
  383.       {
  384.         if (dy > 0)                                                            /* Verschiebung nach unten */
  385.         {
  386.           /* Brushdest retten */
  387.           XO_readrect (Display, (UBYTE *) tmpmem, 0, sh, old_blit.width, old_blit.x, (WORD) (old_blit.y + old_blit.height),
  388.                        old_blit.width, ady);
  389.           /* Bereich mit Blitter verschieben */
  390.           okblit = XO_blitrect (Display, old_blit.x, old_blit.y, old_blit.width, old_blit.height, x, y);
  391.           if (okblit)                                                          /* Es ist nicht 0 zurückgekommen, also der Wurm drin! */
  392.           {
  393.             if (bbrush_mem)                                                    /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  394.               XO_writerect (Display, (UBYTE *) bbrush_mem, 0, 0, old_blit.width, RECTMODE_RGBA, x, y,
  395.                             old_blit.width, old_blit.height, NULL);
  396.  
  397.             /* Sollte derzeit nicht vorkommen! \nIst nur für teilw. Blit von negativ gedacht\n */
  398.             /* FreeVec(okblit);  *//* Speicher wieder freigeben (Future) */
  399.           }
  400.           /* Alten Bereich updaten */
  401.           if (old_blit.memory)                                                 /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  402.             XO_writerect (Display, (UBYTE *) old_blit.memory, 0, 0, old_blit.width, RECTMODE_RGBA, old_blit.x, old_blit.y,
  403.                           old_blit.width, ady, NULL);
  404.  
  405.           /*
  406.            * Memoryblöcke zusammenfügen (tmpmem und old_blit.memory); /*           FROM x y w  TO x y w h  (Pointer sind union color)
  407.            */
  408.           rect_mem_cpy (old_blit.memory, 0, ady, old_blit.width, tmpmem, 0, 0, old_blit.width, (WORD) (old_blit.height - ady));
  409.         }
  410.         else
  411.           /* Verschiebung nach oben */
  412.         {
  413.           /* Brushdest retten */
  414.           XO_readrect (Display, (UBYTE *) tmpmem, 0, 0, old_blit.width, x, y, old_blit.width, ady);
  415.           /* Bereich mit Blitter verschieben */
  416.           okblit = XO_blitrect (Display, old_blit.x, old_blit.y, old_blit.width, old_blit.height, x, y);
  417.           if (okblit)                                                          /* Es ist nicht 0 zurückgekommen, also der Wurm drin! */
  418.           {
  419.             if (bbrush_mem)                                                    /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  420.               XO_writerect (Display, (UBYTE *) bbrush_mem, 0, 0, old_blit.width, RECTMODE_RGBA, x, y,
  421.                             old_blit.width, old_blit.height, NULL);
  422.  
  423.             /* Sollte derzeit nicht vorkommen! \nIst nur für teilw. Blit von negativ gedacht\n */
  424.             /* FreeVec(okblit);  *//* Speicher wieder freigeben (Future) */
  425.           }
  426.           /* Alten Bereich updaten */
  427.           if (old_blit.memory)                                                 /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  428.             XO_writerect (Display, (UBYTE *) old_blit.memory, 0, sh, old_blit.width, RECTMODE_RGBA, x, (WORD) (y + old_blit.height),
  429.                           old_blit.width, ady, NULL);
  430.  
  431.           /*
  432.            * Memoryblöcke zusammenfügen (tmpmem und old_blit.memory); /*           FROM x y w  TO x y w h  (Pointer sind union color)
  433.            */
  434.           rect_mem_cpy (old_blit.memory, 0, 0, old_blit.width, tmpmem, 0, ady, old_blit.width, sh);
  435.         }
  436.       }
  437.       else if (dy == 0)                                                        /* Verschiebung links / rechts */
  438.       {
  439.         if (dx > 0)                                                            /* Verschiebung nach rechts */
  440.         {
  441.           /* Brushdest retten */
  442.           XO_readrect (Display, (UBYTE *) tmpmem, sw, 0, old_blit.width, (WORD) (old_blit.x + old_blit.width), old_blit.y,
  443.                        adx, old_blit.height);
  444.           /* Bereich mit Blitter verschieben */
  445.           okblit = XO_blitrect (Display, old_blit.x, old_blit.y, old_blit.width, old_blit.height, x, y);
  446.           if (okblit)                                                          /* Es ist nicht 0 zurückgekommen, also der Wurm drin! */
  447.           {
  448.             if (bbrush_mem)                                                    /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  449.               XO_writerect (Display, (UBYTE *) bbrush_mem, 0, 0, old_blit.width, RECTMODE_RGBA, x, y,
  450.                             old_blit.width, old_blit.height, NULL);
  451.  
  452.             /* Sollte derzeit nicht vorkommen! \nIst nur für teilw. Blit von negativ gedacht\n */
  453.             /* FreeVec(okblit);  *//* Speicher wieder freigeben (Future) */
  454.           }
  455.           /* Alten Bereich updaten */
  456.           if (old_blit.memory)                                                 /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  457.             XO_writerect (Display, (UBYTE *) old_blit.memory, 0, 0, old_blit.width, RECTMODE_RGBA, old_blit.x, old_blit.y,
  458.                           adx, old_blit.height, NULL);
  459.  
  460.           /*
  461.            * Memoryblöcke zusammenfügen (tmpmem und old_blit.memory); /*           FROM x y w  TO x y w h  (Pointer sind union color)
  462.            */
  463.           rect_mem_cpy (old_blit.memory, adx, 0, old_blit.width, tmpmem, 0, 0, sw, old_blit.height);
  464.         }
  465.         else
  466.           /* Verschiebung nach links */
  467.         {
  468.           /* Brushdest retten */
  469.           XO_readrect (Display, (UBYTE *) tmpmem, 0, 0, old_blit.width, x, y, adx, old_blit.height);
  470.           /* Bereich mit Blitter verschieben */
  471.           okblit = XO_blitrect (Display, old_blit.x, old_blit.y, old_blit.width, old_blit.height, x, y);
  472.           if (okblit)                                                          /* Es ist nicht 0 zurückgekommen, also der Wurm drin! */
  473.           {
  474.             if (bbrush_mem)                                                    /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  475.               XO_writerect (Display, (UBYTE *) bbrush_mem, 0, 0, old_blit.width, RECTMODE_RGBA, x, y,
  476.                             old_blit.width, old_blit.height, NULL);
  477.  
  478.             /* Sollte derzeit nicht vorkommen! \nIst nur für teilw. Blit von negativ gedacht\n */
  479.             /* FreeVec(okblit);  *//* Speicher wieder freigeben (Future) */
  480.           }
  481.           /* Alten Bereich updaten */
  482.           if (old_blit.memory)                                                 /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  483.             XO_writerect (Display, (UBYTE *) old_blit.memory, sw, 0, old_blit.width, RECTMODE_RGBA, (WORD) (x + old_blit.width), y,
  484.                           adx, old_blit.height, NULL);
  485.  
  486.           /*
  487.            * Memoryblöcke zusammenfügen (tmpmem und old_blit.memory); /*           FROM x y w  TO x y w h  (Pointer sind union color)
  488.            */
  489.           rect_mem_cpy (old_blit.memory, 0, 0, old_blit.width, tmpmem, adx, 0, sw, old_blit.height);
  490.         }
  491.       }
  492.       else
  493.         /* X und Y überlappen */
  494.       {
  495.         if ((dx > 0) && (dy > 0))                                              /* Verschiebung + Überlappung nach rechts unten */
  496.         {
  497.           /* Brushdest retten */
  498.           XO_readrect (Display, (UBYTE *) tmpmem, sw, 0, old_blit.width, (WORD) (old_blit.x + old_blit.width), y, adx, sh);
  499.           XO_readrect (Display, (UBYTE *) tmpmem, 0, sh, old_blit.width, x, (WORD) (old_blit.y + old_blit.height), old_blit.width, ady);
  500.           /* Bereich mit Blitter verschieben */
  501.           okblit = XO_blitrect (Display, old_blit.x, old_blit.y, old_blit.width, old_blit.height, x, y);
  502.           if (okblit)                                                          /* Es ist nicht 0 zurückgekommen, also der Wurm drin! */
  503.           {
  504.             if (bbrush_mem)                                                    /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  505.               XO_writerect (Display, (UBYTE *) bbrush_mem, 0, 0, old_blit.width, RECTMODE_RGBA, x, y,
  506.                             old_blit.width, old_blit.height, NULL);
  507.             /* FreeVec(okblit);  *//* Speicher wieder freigeben (Future) */
  508.           }
  509.           /* Alten Bereich updaten */
  510.           if (old_blit.memory)                                                 /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  511.           {
  512.             XO_writerect (Display, (UBYTE *) old_blit.memory, 0, 0, old_blit.width, RECTMODE_RGBA, old_blit.x, old_blit.y,
  513.                           old_blit.width, ady, NULL);
  514.             XO_writerect (Display, (UBYTE *) old_blit.memory, 0, ady, old_blit.width, RECTMODE_RGBA, old_blit.x, (WORD) (old_blit.y + ady),
  515.                           adx, sh, NULL);
  516.           }
  517.  
  518.           /*
  519.            * Memoryblöcke zusammenfügen (tmpmem und old_blit.memory); /*           FROM x y w  TO x y w h  (Pointer sind union color)
  520.            */
  521.           rect_mem_cpy (old_blit.memory, adx, ady, old_blit.width, tmpmem, 0, 0, sw, sh);
  522.         }
  523.         else if ((dx > 0) && (dy < 0))                                         /* Verschiebung + Überlappung nach rechts oben */
  524.         {
  525.           /* Brushdest retten */
  526.           XO_readrect (Display, (UBYTE *) tmpmem, 0, 0, old_blit.width, x, y, old_blit.width, ady);
  527.           XO_readrect (Display, (UBYTE *) tmpmem, sw, ady, old_blit.width, (WORD) (old_blit.x + old_blit.width), old_blit.y, adx, sh);
  528.           /* Bereich mit Blitter verschieben */
  529.           okblit = XO_blitrect (Display, old_blit.x, old_blit.y, old_blit.width, old_blit.height, x, y);
  530.           if (okblit)                                                          /* Es ist nicht 0 zurückgekommen, also der Wurm drin! */
  531.           {
  532.             if (bbrush_mem)                                                    /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  533.               XO_writerect (Display, (UBYTE *) bbrush_mem, 0, 0, old_blit.width, RECTMODE_RGBA, x, y,
  534.                             old_blit.width, old_blit.height, NULL);
  535.             /* FreeVec(okblit);  *//* Speicher wieder freigeben (Future) */
  536.           }
  537.           /* Alten Bereich updaten */
  538.           if (old_blit.memory)                                                 /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  539.           {
  540.             XO_writerect (Display, (UBYTE *) old_blit.memory, 0, 0, old_blit.width, RECTMODE_RGBA, old_blit.x, old_blit.y,
  541.                           adx, sh, NULL);
  542.             XO_writerect (Display, (UBYTE *) old_blit.memory, 0, sh, old_blit.width, RECTMODE_RGBA, old_blit.x, (WORD) (old_blit.y + sh),
  543.                           old_blit.width, ady, NULL);
  544.           }
  545.  
  546.           /*
  547.            * Memoryblöcke zusammenfügen (tmpmem und old_blit.memory); /*           FROM x y w  TO x y w h  (Pointer sind union color)
  548.            */
  549.           rect_mem_cpy (old_blit.memory, adx, 0, old_blit.width, tmpmem, 0, ady, sw, sh);
  550.         }
  551.         else if ((dx < 0) && (dy > 0))                                         /* Verschiebung + Überlappung nach links unten */
  552.         {
  553.           /* Brushdest retten */
  554.           XO_readrect (Display, (UBYTE *) tmpmem, 0, 0, old_blit.width, x, y, adx, sh);
  555.           XO_readrect (Display, (UBYTE *) tmpmem, 0, sh, old_blit.width, x, (WORD) (old_blit.y + old_blit.height), old_blit.width, ady);
  556.           /* Bereich mit Blitter verschieben */
  557.           okblit = XO_blitrect (Display, old_blit.x, old_blit.y, old_blit.width, old_blit.height, x, y);
  558.           if (okblit)                                                          /* Es ist nicht 0 zurückgekommen, also der Wurm drin! */
  559.           {
  560.             if (bbrush_mem)                                                    /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  561.               XO_writerect (Display, (UBYTE *) bbrush_mem, 0, 0, old_blit.width, RECTMODE_RGBA, x, y,
  562.                             old_blit.width, old_blit.height, NULL);
  563.             /* FreeVec(okblit);  *//* Speicher wieder freigeben (Future) */
  564.           }
  565.           /* Alten Bereich updaten */
  566.           if (old_blit.memory)                                                 /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  567.           {
  568.             XO_writerect (Display, (UBYTE *) old_blit.memory, 0, 0, old_blit.width, RECTMODE_RGBA, old_blit.x, old_blit.y,
  569.                           old_blit.width, ady, NULL);
  570.             XO_writerect (Display, (UBYTE *) old_blit.memory, sw, ady, old_blit.width, RECTMODE_RGBA, (WORD) (x + old_blit.width), y,
  571.                           adx, sh, NULL);
  572.           }
  573.  
  574.           /*
  575.            * Memoryblöcke zusammenfügen (tmpmem und old_blit.memory); /*           FROM x y w  TO x y w h  (Pointer sind union color)
  576.            */
  577.           rect_mem_cpy (old_blit.memory, 0, ady, old_blit.width, tmpmem, adx, 0, sw, sh);
  578.         }
  579.         else
  580.           /* Verschiebung + Überlappung nach links oben */
  581.         {
  582.           /* Brushdest retten */
  583.           XO_readrect (Display, (UBYTE *) tmpmem, 0, 0, old_blit.width, x, y, old_blit.width, ady);
  584.           XO_readrect (Display, (UBYTE *) tmpmem, 0, ady, old_blit.width, x, old_blit.y, adx, sh);
  585.           /* Bereich mit Blitter verschieben */
  586.           okblit = XO_blitrect (Display, old_blit.x, old_blit.y, old_blit.width, old_blit.height, x, y);
  587.           if (okblit)                                                          /* Es ist nicht 0 zurückgekommen, also der Wurm drin! */
  588.           {
  589.             if (bbrush_mem)                                                    /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  590.               XO_writerect (Display, (UBYTE *) bbrush_mem, 0, 0, old_blit.width, RECTMODE_RGBA, x, y,
  591.                             old_blit.width, old_blit.height, NULL);
  592.             /* FreeVec(okblit);  *//* Speicher wieder freigeben (Future) */
  593.           }
  594.           /* Alten Bereich updaten */
  595.           if (old_blit.memory)                                                 /* Wenn der nicht da ist, dann ist der Wurm unterwegs ... */
  596.           {
  597.             XO_writerect (Display, (UBYTE *) old_blit.memory, sw, 0, old_blit.width, RECTMODE_RGBA, (WORD) (x + old_blit.width), old_blit.y,
  598.                           adx, sh, NULL);
  599.             XO_writerect (Display, (UBYTE *) old_blit.memory, 0, sh, old_blit.width, RECTMODE_RGBA, old_blit.x, (WORD) (y + old_blit.height),
  600.                           old_blit.width, ady, NULL);
  601.           }
  602.  
  603.           /*
  604.            * Memoryblöcke zusammenfügen (tmpmem und old_blit.memory); /*           FROM x y w  TO x y w h  (Pointer sind union color)
  605.            */
  606.           rect_mem_cpy (old_blit.memory, 0, 0, old_blit.width, tmpmem, adx, ady, sw, sh);
  607.         }
  608.         /* Brushdest retten */
  609.         /* Alten Bereich updaten */
  610.       }
  611.  
  612.       FreeVec (old_blit.memory);
  613.       old_blit.memory = tmpmem;                                                /* Zuweisung von neuen Memory */
  614.     }
  615.     else
  616.       /* Polygon blitten */
  617.     {
  618.       move_pbrushblit (Display, x, y);
  619.     }
  620.   }
  621.   old_blit.x = x;                                                              /* Neue Koordinaten merken */
  622.   old_blit.y = y;
  623.   return (TRUE);
  624. }
  625.  
  626.  
  627. /* Die beiden Routinen sind unsicher! Sie funktionieren nur, wenn sich weder der Brush noch deren
  628.    Koordinaten geändert haben!. Der Untergrund darf sich geändert haben! 
  629. */
  630. __asm __saveds void XO_on_brushblit(register __a0 struct Display *Display)
  631. {
  632.   if (old_blit.mode != 0)
  633.   {
  634.     move_ibrushblit (Display, old_blit.x, old_blit.y);
  635.     return;
  636.   }
  637.  
  638.   if (old_blit.memory)                                                         /* Falls noch Speicher da, erst freen */
  639.   {
  640.     XO_readrect (Display, (UBYTE *) old_blit.memory, 0, 0, old_blit.width, old_blit.x, old_blit.y,
  641.                  old_blit.width, old_blit.height);
  642.     XO_writerect (Display, (UBYTE *) bbrush_mem, 0, 0, old_blit.width, RECTMODE_RGBA, old_blit.x, old_blit.y,
  643.                   old_blit.width, old_blit.height, NULL);
  644.   }
  645.   else
  646.   {
  647.     rect_brushblitn (Display, old_blit.x, old_blit.y);
  648.   }
  649. }
  650.  
  651. void move_pbrushblit (struct Display *Display, WORD x, WORD y)
  652. {
  653.  
  654.   if (old_blit.memory)                                                         /* Zwischenspeicher vorhanden */
  655.   {                                                                            /* Alten Bereich updaten, dann neuen Bereich in den selben
  656.                                                                                 * Speicher zurück */
  657.     XO_writerect (Display, (UBYTE *) old_blit.memory, 0, 0, old_blit.width, RECTMODE_RGBA, old_blit.x, old_blit.y,
  658.                   old_blit.width, old_blit.height, NULL);
  659.   }
  660.   move_ibrushblit (Display, x, y);
  661. }
  662.  
  663. __asm __saveds void XO_off_brushblit(register __a0 struct Display *Display)
  664. {
  665.   if (old_blit.memory)
  666.   {
  667.     XO_writerect (Display, (UBYTE *) old_blit.memory, 0, 0, old_blit.width, RECTMODE_RGBA, old_blit.x, old_blit.y,
  668.                   old_blit.width, old_blit.height, NULL);
  669.   }
  670.   else
  671.   {
  672.     rect_brushblito (Display);
  673.   }
  674. }
  675.  
  676. BOOL move_ibrushblit (struct Display *Display, WORD x, WORD y)
  677. {
  678.   union color *tmpmem, *bb, *tp, *old, *end;
  679.  
  680.   if (old_blit.memory)                                                         /* Zwischenspeicher vorhanden */
  681.   {                                                                            /* Alten Bereich updaten, dann neuen Bereich in den selben
  682.                                                                                 * Speicher zurück */
  683.     XO_readrect (Display, (UBYTE *) old_blit.memory, 0, 0, old_blit.width, x, y,
  684.                  old_blit.width, old_blit.height);
  685.     /* Nun noch den Brush auslesen auf alpha und rausschreiben */
  686.  
  687.     /* Temporären Speicher belegen */
  688.     tmpmem = AllocVec ((ULONG)(old_blit.width * old_blit.height * sizeof (union color)), MEMF_ANY);
  689.  
  690.     if (!tmpmem)                                                               /* Keinen Speicher bekommen */
  691.     {
  692.       rect_brushblitn (Display, x, y);
  693.       XO_free_brushblit (Display);                                                     /* Wenns eh nicht geht, dann brauch ich auch keinen
  694.                                                                                 * ZwischenSpeicher */
  695.       return (TRUE);
  696.     }
  697.     tp = tmpmem;
  698.     old = old_blit.memory;
  699.     bb = bbrush_mem;
  700.     end = tmpmem + (old_blit.width * old_blit.height);
  701.     for (; tp < end; tp++, old++, bb++)
  702.     {
  703.       if (bb->c8[3])
  704.         tp->c24 = bb->c24;
  705.       else
  706.         tp->c24 = old->c24;
  707.     }
  708.     XO_writerect (Display, (UBYTE *) tmpmem, 0, 0, old_blit.width, RECTMODE_RGBA, x, y,
  709.                   old_blit.width, old_blit.height, NULL);
  710.     FreeVec (tmpmem);
  711.  
  712.   }
  713. }
  714.  
  715.  
  716. __asm __saveds BOOL XO_init(register __a0 struct  Display *Display, register __a1 struct xo_init *mode)
  717. {
  718.   struct Window *InputWindow;
  719.  
  720.    SysBase = (*((struct ExecBase **) 4));
  721.  
  722.    if (!((DOSBase = (struct DosLibrary *)OpenLibrary(DOSLIB, DOSVER))))
  723.     {
  724.       return 0; /* Failed! */
  725.     }
  726.    if (!((IntuitionBase = (struct IntuitionBase *)OpenLibrary(INTUILIB,INTUIVER))))
  727.       {
  728.         SetIoErr(901);
  729.         return 0;
  730.       }
  731.  
  732.    if (!((GfxBase = (struct GfxBase *)OpenLibrary(GFXLIB,GFXVER))))
  733.       {
  734.         SetIoErr(900);
  735.         return 0;
  736.       }
  737.  
  738.     if ((VilIntuiBase = OpenLibrary ("vilintuisup.library", 2)) == NULL)
  739.     {
  740.       sprintf (lib_buffer, "Couldn't open vilintuisup.library (V 2.0).\n");
  741.       XO_close (Display);
  742.       return(FALSE);
  743.     }
  744.  
  745.     openscreentags[0].ti_Data = mode->display_id;
  746.     if (openscreentags[0].ti_Data == ~0L)
  747.     {
  748.       XO_close (Display);
  749.       return(FALSE);
  750.     }
  751.  
  752.     if (!(PaintScreen = OpenVillageScreenTagList (openscreentags)))
  753.     {
  754.       sprintf (lib_buffer, "Couldn't open Picasso-Screen\n");
  755.       XO_close (Display);
  756.       return(FALSE);
  757.     }
  758.  
  759.     nw_p.LeftEdge = 0;                                     /* Das Fenster soll den ganzen Screen abdecken */
  760.     nw_p.TopEdge = 0;
  761.     nw_p.Width = PaintScreen->Width;
  762.     nw_p.Height = PaintScreen->Height;
  763.     nw_p.FirstGadget = NULL;                               /* keine Gadgets im Fenster */
  764.     nw_p.Title = NULL;
  765.     nw_p.IDCMPFlags = IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_RAWKEY |
  766.          IDCMP_VANILLAKEY| IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW;
  767.     nw_p.Flags = WFLG_BORDERLESS | WFLG_RMBTRAP | WFLG_ACTIVATE | WFLG_REPORTMOUSE;
  768.     nw_p.Type = CUSTOMSCREEN;
  769.     nw_p.Screen = PaintScreen;
  770.  
  771.     if (!(InputWindow = OpenWindow (&nw_p)))
  772.     {
  773.       sprintf (lib_buffer, "Couldn't open PaintWindow.\n");
  774.       XO_close (Display);
  775.       return(FALSE);
  776.     }
  777.     Display->InputWindow = InputWindow;
  778.     Display->Width = PaintScreen->Width;
  779.     Display->Height = PaintScreen->Height;
  780.     Display->RetScreen = (struct RetinaScreen *) PaintScreen;
  781.     return(TRUE);
  782. }
  783.  
  784. __asm __saveds void XO_close(register __a0 struct Display *Display)
  785. {
  786.   if (Display->InputWindow)
  787.     CloseWindow (Display->InputWindow);
  788.  
  789.     if (PaintScreen)
  790.       UnLockVillageScreen (PaintScreen);
  791.  
  792.     if (PaintScreen)
  793.       CloseVillageScreen (PaintScreen);
  794.  
  795.     if (VilIntuiBase)
  796.       CloseLibrary ((struct Library *) VilIntuiBase);
  797.  
  798.     if (IntuitionBase)
  799.       CloseLibrary ((struct Library *) IntuitionBase);
  800.  
  801.     CloseLibrary((struct Library *)GfxBase);
  802.     CloseLibrary((struct Library *)DOSBase);
  803. }
  804.  
  805.  
  806. /****  Prototypes der Zeichen-Behelfsroutinen  ****/
  807.  
  808. __asm __saveds void XO_inv_hline(register __a0 struct Display *Display, register __d0 SHORT x, register __d1 SHORT y, register __d2 SHORT x2)
  809. {
  810.   SHORT help;
  811.  
  812.   if (x >= Display->Width)
  813.     x = Display->Width - 1;
  814.   else if (x < 1)
  815.     x = 1;
  816.  
  817.   if (y >= Display->Height)
  818.     y = Display->Height - 1;
  819.   else if (y < 1)
  820.     y = 1;
  821.  
  822.   if (x2 > Display->Width)
  823.     x2 = Display->Width - 1;
  824.   else if (x2 < 1)
  825.     x2 = 1;
  826.  
  827.   help = MIN (x, x2);
  828.   x2 = MAX (x, x2);
  829.   PIILineI (PaintScreen, help, y, x2, y);
  830. }
  831.  
  832. __asm __saveds void XO_inv_vline(register __a0 struct Display *Display, register __d0 SHORT x, register __d1 SHORT y, register __d2 SHORT y2)
  833. {
  834.   SHORT help;
  835.  
  836.   if (x >= Display->Width)
  837.     x = Display->Width - 1;
  838.   else if (x < 0)
  839.     x = 0;
  840.  
  841.   if (y >= Display->Height)
  842.     y = Display->Height - 1;
  843.   else if (y < 0)
  844.     y = 0;
  845.  
  846.   if (y2 > Display->Height)
  847.     y2 = Display->Height - 1;
  848.   else if (y2 < 0)
  849.     y2 = 0;
  850.  
  851.   help = MIN (y, y2);
  852.   y2 = MAX (y, y2);
  853.  
  854.     PIILineI (PaintScreen, x, help, x, y2);
  855. }
  856.  
  857. __asm __saveds void XO_inv_point(register __a0 struct Display *Display, register __d0 SHORT x, register __d1 SHORT y)
  858. {
  859.     SetPixelI (PaintScreen, x, y);
  860. }
  861.  
  862.  
  863. __asm __saveds void XO_cls_rect(register __a0 struct Display *Display, register __d0 SHORT x1, register __d1 SHORT y1, register __d2 SHORT x2, register __d3 SHORT y2)
  864. {
  865.     HardFBox (Display, x1, y1, x2, y2, BACKGROUND);
  866. }
  867.  
  868.  
  869. __asm __saveds void XO_writerect(register __a0 struct Display *Display, register __a1 UBYTE *Mem,register __d0 UWORD MemX,
  870.                 register __d1 UWORD MemY, register __d2 UWORD MemWidth, register __d3 ULONG Mode,
  871.                 register __d4 WORD ScreenX, register __d5 WORD ScreenY, register __d6 WORD SizeX,  register __d7 WORD SizeY, register __a2 UBYTE *clut)
  872. {
  873.     SHORT i;
  874.     p_RGB *pstart;
  875.     argb *mstart, *mend;
  876.     UBYTE *bstart, *bend;
  877.     UBYTE *ScrBase;
  878.     struct Screen *MyScreen;
  879.  
  880.   if (SizeX <= 0)
  881.     return;
  882.   if (SizeY <= 0)
  883.     return;
  884.  
  885.   if (ScreenX >= Display->Width)
  886.     return;
  887.   if (ScreenY >= Display->Height)
  888.     return;
  889.  
  890.   if ((ScreenX + SizeX) < 0)                               /* Außerhalb der Darstellung */
  891.     return;
  892.   if ((ScreenY + SizeY) < 0)                               /* Außerhalb der Darstellung */
  893.     return;
  894.  
  895.   if (ScreenX < 0)
  896.   {
  897.     SizeX += ScreenX;
  898.     MemX = (UWORD) ((WORD) MemX - ScreenX);
  899.     ScreenX = 0;
  900.   }
  901.  
  902.   if (ScreenY < 0)
  903.   {
  904.     SizeY += ScreenY;
  905.     MemY = (UWORD) ((WORD) MemY - ScreenY);
  906.     ScreenY = 0;
  907.   }
  908.  
  909.   if ((ScreenX + SizeX) > Display->Width)
  910.     SizeX = Display->Width - ScreenX;
  911.  
  912.   if ((ScreenY + SizeY) > Display->Height)
  913.     SizeY = Display->Height - ScreenY;
  914.  
  915.  
  916.     MyScreen = (struct Screen *) (Display->RetScreen);
  917.     ScrBase = MyScreen->RastPort.BitMap->Planes[0];
  918.     lock ();
  919.     WaitVillageBlit ();
  920.     if (Mode == RECTMODE_RGBA)
  921.     {
  922.       for (i = 0; i < SizeY; i++)
  923.       {
  924.         mstart = (argb *) (Mem + (((MemY + i) * MemWidth) + MemX) * 4); /* mein Speicher */
  925.         mend = mstart + SizeX;
  926.         pstart = (p_RGB *) (ScrBase + (MyScreen->Width * (ScreenY + i) + ScreenX) * 3); /* Offset in der Karte */
  927.  
  928.         for (mstart; mstart < mend; mstart++, pstart++)    /* Die Zeile */
  929.         {
  930.           pstart->r = mstart->r;
  931.           pstart->g = mstart->g;
  932.           pstart->b = mstart->b;
  933.         }
  934.       }
  935.     }
  936.     else if (Mode == RECTMODE_CLUT)                        /* Jetzt wirds ernst: mit CLUT von 8-Bit in 24 Bit */
  937.     {
  938.       for (i = 0; i < SizeY; i++)
  939.       {
  940.         bstart = Mem + (((MemY + i) * MemWidth) + MemX);   /* mein Speicher */
  941.         bend = bstart + SizeX;
  942.         pstart = (p_RGB *) (ScrBase + (MyScreen->Width * (ScreenY + i) + ScreenX) * 3); /* Offset in der Karte (+2 Ist word!) */
  943.  
  944.         for (bstart; bstart < bend; bstart++, pstart++)    /* Die Zeile */
  945.         {
  946.           pstart->r = clut[*bstart * 4];
  947.           pstart->g = clut[*bstart * 4 + 1];
  948.           pstart->b = clut[*bstart * 4 + 2];
  949.         }
  950.       }
  951.     }
  952.     unlock ();
  953. }
  954.  
  955.  
  956. __asm __saveds void XO_readrect(register __a0 struct Display *Display, register __a1 UBYTE *Mem, register __d0 UWORD MemX, register __d1 UWORD MemY,
  957.                 register __d2 UWORD MemWidth, register __d3 WORD ScreenX,  register __d4 WORD ScreenY, register __d5 WORD SizeX, register __d6 WORD SizeY)
  958. {
  959.     SHORT i;
  960.     p_RGB *pstart;
  961.     argb *mstart, *mend;
  962.     UBYTE *ScrBase;
  963.     struct Screen *MyScreen;
  964.  
  965. /************* Clipping? ********************/
  966.   if (SizeX <= 0)
  967.     return;
  968.   if (SizeY <= 0)
  969.     return;
  970.  
  971.   if (ScreenX >= Display->Width)
  972.     return;
  973.   if (ScreenY >= Display->Height)
  974.     return;
  975.  
  976.   if ((ScreenX + SizeX) < 0)                               /* Außerhalb der Darstellung */
  977.     return;
  978.   if ((ScreenY + SizeY) < 0)                               /* Außerhalb der Darstellung */
  979.     return;
  980.  
  981.   if (ScreenX < 0)
  982.   {
  983.     SizeX += ScreenX;
  984.     MemX -= ScreenX;
  985.     ScreenX = 0;
  986.   }
  987.  
  988.   if (ScreenY < 0)
  989.   {
  990.     SizeY += ScreenY;
  991.     MemY -= ScreenY;
  992.     ScreenY = 0;
  993.   }
  994.  
  995.   if ((ScreenX + SizeX) > Display->Width)
  996.     SizeX = Display->Width - ScreenX;
  997.  
  998.   if ((ScreenY + SizeY) > Display->Height)
  999.     SizeY = Display->Height - ScreenY;
  1000. /*******************************************/
  1001.  
  1002.  
  1003.     MyScreen = (struct Screen *) (Display->RetScreen);
  1004.     ScrBase = MyScreen->RastPort.BitMap->Planes[0];
  1005.     lock ();
  1006.     WaitVillageBlit ();
  1007.     for (i = 0; i < SizeY; i++)
  1008.     {
  1009.       mstart = (argb *) (Mem + (((MemY + i) * MemWidth) + MemX) * 4);   /* mein Speicher */
  1010.       mend = mstart + SizeX;
  1011.       pstart = (p_RGB *) (ScrBase + (MyScreen->Width * (ScreenY + i) + ScreenX) * 3);   /* Offset in der Karte */
  1012.  
  1013.       for (mstart; mstart < mend; mstart++, pstart++)      /* Die Zeile */
  1014.       {
  1015.         mstart->r = pstart->r;
  1016.         mstart->g = pstart->g;
  1017.         mstart->b = pstart->b;
  1018.       }
  1019.     }
  1020.     unlock ();
  1021. }
  1022.  
  1023.  
  1024. /* Liefert NULL oder bei abgeschnittenen Brush die Koordinaten vom Blit 
  1025.    (Es werden die Update-Koordinaten angegeben, aber nichts geblittet)
  1026. */
  1027. __asm __saveds struct brush *XO_blitrect(register __a0 struct Display *Display, register __d0 WORD x, register __d1 WORD y, 
  1028.                         register __d2 WORD width, register __d3 WORD height, register __d4 WORD x2, register __d5 WORD y2)
  1029. {
  1030.   struct brush *myblit;
  1031.   WORD warwas = 0;
  1032.     UBYTE *ScrBase;
  1033.     struct Screen *MyScreen;
  1034.     struct VilCopyRecord vilcopy;
  1035.  
  1036. /************* Clipping? ********************/
  1037.   /* printf("1: x:%d y:%d w:%d h:%d x2:%d y2:%d\n",x,y,width, height, x2, y2);  */
  1038.  
  1039.   if (height < 0)
  1040.     return (NULL);
  1041.   if (width < 0)
  1042.     return (NULL);
  1043.  
  1044.   if ((x + width) < 0)                                     /* Außerhalb der Darstellung */
  1045.     return (NULL);
  1046.   if ((y + height) < 0)                                    /* Außerhalb der Darstellung */
  1047.     return (NULL);
  1048.   if ((x2 + width) < 0)                                    /* Außerhalb der Darstellung */
  1049.     return (NULL);
  1050.   if ((y2 + height) < 0)                                   /* Außerhalb der Darstellung */
  1051.     return (NULL);
  1052.  
  1053.   if (x >= Display->Width)
  1054.     return (NULL);
  1055.   if (x2 >= Display->Width)
  1056.     return (NULL);
  1057.   if (y >= Display->Height)
  1058.     return (NULL);
  1059.   if (y2 >= Display->Height)
  1060.     return (NULL);
  1061.  
  1062.   /* Und nun zum Dest-Bereich: */
  1063.   if (x2 >= Display->Width)
  1064.     return (NULL);
  1065.   if (y2 >= Display->Height)
  1066.     return (NULL);
  1067.  
  1068.   if ((x2 + width) > Display->Width)                       /* Abschneiden, Blit ist aber OK */
  1069.     width = Display->Width - x2;
  1070.   if ((y2 + height) > Display->Height)                     /* Abschneiden, Blit ist aber OK */
  1071.     height = Display->Height - y2;
  1072.  
  1073.   if (x2 < 0)                                              /* Dest-Blit ist zu weit links */
  1074.   {
  1075.     width += x2;
  1076.     x += ABS (x2);
  1077.     x2 = 0;
  1078.   }
  1079.  
  1080.   if (y2 < 0)                                              /* Dest-Blit ist zu weit oben */
  1081.   {
  1082.     height += y2;
  1083.     y += ABS (y2);
  1084.     y2 = 0;
  1085.   }
  1086.  
  1087.   /* Jetzt Source! *** */
  1088.   if (x < 0)
  1089.   {
  1090.     /* width += x; */
  1091.     /* x = ABS(x);       */
  1092.     warwas = 1;
  1093.   }
  1094.  
  1095.   if (y < 0)
  1096.   {
  1097.     /* height += y; *//* Falls Blit - dann andere Berechnung (0) */
  1098.     /* y = ABS(y);               */
  1099.     warwas = 1;
  1100.   }
  1101.  
  1102.   if (width > Display->Width)                              /* Kann man ruhig blitten! */
  1103.   {
  1104.     width = Display->Width;
  1105.   }
  1106.  
  1107.   if (height > Display->Height)                            /* Kann man ruhig blitten! */
  1108.   {
  1109.     height = Display->Height;
  1110.   }
  1111.  
  1112.   if ((y + height) > Display->Height)
  1113.   {
  1114.     height = Display->Height - y;
  1115.     warwas = 1;
  1116.   }
  1117.  
  1118.   if ((x + width) > Display->Width)
  1119.   {
  1120.     width = Display->Width - x;
  1121.     warwas = 1;
  1122.   }
  1123.  
  1124.   /* printf("2: x:%d y:%d w:%d h:%d x2:%d y2:%d\n",x,y,width, height, x2, y2);  */
  1125.  
  1126.   if (warwas)                                              /* Aussprung, aber so, dass man korrigieren kann */
  1127.   {
  1128. #if 0
  1129.     /* Future enhancemens; falls negativer Blit anders abgefange werden soll */
  1130.     myblit = AllocVec (sizeof (struct brush), MEMF_PUBLIC | MEMF_CLEAR);
  1131.  
  1132.     if (myblit)
  1133.     {
  1134.       myblit->width = width;
  1135.       myblit->height = height;
  1136.       myblit->x = x;
  1137.       myblit->y = y;
  1138.     }
  1139. #endif
  1140.     myblit = (struct brush *) 1;
  1141.     return (myblit);
  1142.   }
  1143.  
  1144. /*******************************************/
  1145.  
  1146.  
  1147.     MyScreen = (struct Screen *) (Display->RetScreen);
  1148.     ScrBase = MyScreen->RastPort.BitMap->Planes[0];
  1149.     /* ScrBase = LockVillageScreen(MyScreen); */
  1150.     lock ();
  1151.     WaitVillageBlit ();
  1152.  
  1153.     vilcopy.SrcAdr = ScrBase + (x + y * Display->Width) * 3;
  1154.     vilcopy.DestAdr = ScrBase + (x2 + y2 * Display->Width) * 3;
  1155.     vilcopy.SrcPitch = Display->Width;
  1156.     vilcopy.DestPitch = Display->Width;
  1157.     vilcopy.Width = width;
  1158.     vilcopy.Height = height;
  1159.     vilcopy.ROP = VIL_SRCCOPY;
  1160.  
  1161.     VillageBlitCopy (MyScreen, &vilcopy);
  1162.  
  1163.     unlock ();
  1164. }
  1165.  
  1166.  
  1167.  
  1168. /****************************************** Picasso klumpert **************************/
  1169.  
  1170. BYTE _lockvar = 0;
  1171. void lock (void)
  1172. {
  1173.   if (_lockvar == 0)
  1174.     LockVillageScreen (PaintScreen);
  1175.   _lockvar = 1;
  1176. }
  1177. void unlock (void)
  1178. {
  1179.   if (_lockvar == 1)
  1180.     UnLockVillageScreen (PaintScreen);
  1181.   _lockvar = 0;
  1182. }
  1183.  
  1184. void SetPixelI (struct Screen *s, UWORD x, UWORD y)
  1185. {
  1186.   register ULONG offset;
  1187.   UBYTE *ScrBase;
  1188.  
  1189.   lock ();
  1190.   WaitVillageBlit ();
  1191.   ScrBase = s->RastPort.BitMap->Planes[0];
  1192.  
  1193.   offset = (s->Width * y + x) * 3;
  1194.  
  1195.   if ((offset >= 0) && (offset < 0x00100000))
  1196.   {
  1197.     ScrBase[offset] = ~ScrBase[offset];
  1198.     offset++;
  1199.     ScrBase[offset] = ~ScrBase[offset];
  1200.     offset++;
  1201.     ScrBase[offset] = ~ScrBase[offset];
  1202.   }
  1203.   unlock ();
  1204. }
  1205.  
  1206. void PIILineI (struct Screen *s, UWORD xs, UWORD ys, UWORD xe, UWORD ye)
  1207. {
  1208.   ULONG offset;                                            /* Startpunkt der Linie               */
  1209.   register UBYTE *ScrBase;                                 /* Speicherbeginn des Screens         */
  1210.   WORD xsign = 3,                                          /* Vorzeichen der Linie in X-Richtung */
  1211.    ysign = s->Width * 3;                                   /* Vorzeichen der Linie in Y-Richtung */
  1212.   register WORD akku;                              /* wird zum Zeichnen gebraucht        */
  1213.   WORD xoffset,                                            /* Distanzen in beide ...             */
  1214.    yoffset;                                                /* ... Richtungen                     */
  1215.  
  1216.   /* zuerst einmal die Koordinaten abchecken */
  1217.   if ((xs > s->Width) || (xe > s->Width) ||
  1218.       (ys > s->Height) || (ye > s->Height))
  1219.   {
  1220.     return;                                                /* kein Clipping, die Linie erscheint einfach nicht */
  1221.   }
  1222.  
  1223.   /* wenn der Startpunkt weiter rechts liegt, als der Endpunkt, dann die */
  1224.   /* Koordinaten umdrehen */
  1225.   lock ();
  1226.   if (xs > xe)
  1227.   {
  1228.     xsign = -xsign;
  1229.   }
  1230.  
  1231.   /* sollte dies eine waagerechte Linie sein, wird sie besonders schnell gezeichnet */
  1232.   if (ye == ys)                                            /* alles in einer Zeile ? */
  1233.   {
  1234.     ScrBase = s->RastPort.BitMap->Planes[0];
  1235.     ScrBase += (s->Width * ys + xs) * 3;                   /* Startadresse im Screen berechnen */
  1236.     if (xsign < 0)
  1237.     {
  1238.       xs = xs - xe;
  1239.     }
  1240.     else
  1241.     {
  1242.       xs = xe - xs;
  1243.     }
  1244.  
  1245.     while (xs--)
  1246. #ifdef __SASC
  1247.     {
  1248.       *((UBYTE *) ScrBase) = ~(*((UBYTE *) ScrBase));
  1249.       ScrBase++;
  1250.       *((UBYTE *) ScrBase) = ~(*((UBYTE *) ScrBase));
  1251.       ScrBase++;
  1252.       *((UBYTE *) ScrBase) = ~(*((UBYTE *) ScrBase));
  1253.       ScrBase++;
  1254.     }
  1255.     /* typisch SAS, wenn's kompliziert wird, muß er passen */
  1256. #else
  1257.     {
  1258.       *((RGB *) ScrBase)++ = *color;
  1259.     }
  1260. #endif
  1261.     unlock ();
  1262.     return;                                                /* und fertig */
  1263.   }
  1264.  
  1265.   /* wenn der Startpunkt weiter unten liegt, als der Endpunkt, dann die */
  1266.   /* Koordinaten umdrehen */
  1267.  
  1268.   if (ys > ye)
  1269.   {
  1270.     ysign = -ysign;
  1271.   }
  1272.  
  1273.   /* sollte dies eine senkrechte Linie sein, wird sie besonders schnell gezeichnet */
  1274.  
  1275.   if (xs == xe)                                            /* alles in einer Spalte ? */
  1276.   {
  1277.     if (ys > ye)
  1278.     {
  1279.       akku = ys;
  1280.       ys = ye;
  1281.       ye = akku;
  1282.     }
  1283.     ScrBase = s->RastPort.BitMap->Planes[0];
  1284.     ScrBase += (s->Width * ys + xs) * 3;                   /* Startadresse im Screen berechnen */
  1285.     offset = s->Width * 3;                                 /* offset bekommt neue Funktion */
  1286.     while (ys++ <= ye)                                     /* und die Linie solange ziehen bis ys = ye */
  1287.     {
  1288.       *((UBYTE *) ScrBase) = ~(*((UBYTE *) ScrBase));
  1289.       ScrBase++;
  1290.       *((UBYTE *) ScrBase) = ~(*((UBYTE *) ScrBase));
  1291.       ScrBase++;
  1292.       *((UBYTE *) ScrBase) = ~(*((UBYTE *) ScrBase));
  1293.       ScrBase++;
  1294.       ScrBase -= 3;
  1295.       ScrBase += offset;                                   /* und eine Zeile tiefer setzen */
  1296.     }
  1297.     unlock ();
  1298.     return;
  1299.   }
  1300.  
  1301.   /* die Linie ist also eine Schräge. Nun gilt es zu ermittelt, welcher Teil */
  1302.   /* länger ist. Dieser Teil ist dann die Hauptachse. */
  1303.  
  1304.   if (xsign > 0)
  1305.   {
  1306.     xoffset = xe - xs;
  1307.   }                                                        /* Abstand von Start- und Endpunkt auf der X-Achse */
  1308.   else
  1309.   {
  1310.     xoffset = xs - xe;
  1311.   }                                                        /* Abstand von Start- und Endpunkt auf der X-Achse */
  1312.  
  1313.   if (ysign > 0)
  1314.   {
  1315.     yoffset = ye - ys;
  1316.   }                                                        /* Abstand von Start- und Endpunkt auf der Y-Achse */
  1317.   else
  1318.   {
  1319.     yoffset = ys - ye;
  1320.   }                                                        /* Abstand von Start- und Endpunkt auf der Y-Achse */
  1321.  
  1322.   /* bevor es losgeht, den Startpunkt zeichnen */
  1323.   SetPixelI (s, xs, ys);
  1324.  
  1325.   /* allgemeine Initialisierungen */
  1326.   ScrBase = s->RastPort.BitMap->Planes[0];
  1327.   ScrBase += (s->Width * ys + xs) * 3;                     /* Startadresse im Screen berechnen */
  1328.  
  1329.   if (xoffset >= yoffset)                                  /* X-Abstand ist größer oder gleich */
  1330.   {
  1331.     akku = -xoffset;                                       /* Startwert für den Akku */
  1332.     xs = xoffset;
  1333.     ysign += xsign;
  1334.     while (xs--)                                           /* solange die Linie noch läuft */
  1335.     {
  1336.       akku += yoffset;
  1337.       if (akku >= 0)
  1338.       {
  1339.         akku -= xoffset;
  1340.         ScrBase += ysign;
  1341.       }
  1342.       else
  1343.       {
  1344.         ScrBase += xsign;
  1345.       }
  1346.  
  1347.       *((UBYTE *) ScrBase) = ~(*((UBYTE *) ScrBase));
  1348.       ScrBase++;
  1349.       *((UBYTE *) ScrBase) = ~(*((UBYTE *) ScrBase));
  1350.       ScrBase++;
  1351.       *((UBYTE *) ScrBase) = ~(*((UBYTE *) ScrBase));
  1352.     }
  1353.   }
  1354.   else
  1355.     /* Y-Abstand ist größer oder gleich */
  1356.   {
  1357.     akku = -yoffset;                                       /* Startwert für den Akku */
  1358.     ys = yoffset;
  1359.     xsign += ysign;
  1360.     while (ys--)
  1361.     {
  1362.       akku += xoffset;
  1363.       if (akku >= 0)
  1364.       {
  1365.         akku -= yoffset;
  1366.         ScrBase += xsign;
  1367.       }
  1368.       else
  1369.       {
  1370.         ScrBase += ysign;
  1371.       }
  1372.  
  1373.       *((UBYTE *) ScrBase) = ~(*((UBYTE *) ScrBase));
  1374.       ScrBase++;
  1375.       *((UBYTE *) ScrBase) = ~(*((UBYTE *) ScrBase));
  1376.       ScrBase++;
  1377.       *((UBYTE *) ScrBase) = ~(*((UBYTE *) ScrBase));
  1378.     }
  1379.   }
  1380.  
  1381.   unlock ();
  1382.   return;
  1383. }
  1384.  
  1385. void HardFBox (struct Display *Display, SHORT x, SHORT y, SHORT x2, SHORT y2, ULONG color)
  1386. {
  1387.  
  1388.   struct VilFillRecord vilfill =
  1389.   {0,
  1390.    1024,                                                   /* Width of destination display (480 * 3 = 1024!) */
  1391.    256,                                                    /* Width of rectangle box                         */
  1392.    256,                                                    /* Height of rectangle box                        */
  1393.    0
  1394.   };
  1395.   UBYTE *memstart;
  1396.  
  1397.   memstart = PaintScreen->RastPort.BitMap->Planes[0];
  1398.  
  1399.   vilfill.DestAdr = (APTR) (memstart + (((UWORD) (x)) * 3 + (((UWORD) (y)) * Display->Width * 3)));
  1400.   vilfill.DestPitch = Display->Width;
  1401.   vilfill.Width = (UWORD) (x2) - (UWORD) (x) + 1;
  1402.   vilfill.Height = (UWORD) (y2) - (UWORD) (y) + 1;
  1403.   vilfill.Color = color;
  1404.   lock ();
  1405.   WaitVillageBlit ();
  1406.   VillageRectFill (PaintScreen, &vilfill);
  1407.   unlock ();
  1408. }
  1409.  
  1410. __asm __saveds void XO_ScreenToFront(register __a0 struct Display *Display)
  1411. {
  1412.   ScreenToFront((struct Screen *)Display->RetScreen);
  1413. }
  1414. __asm __saveds void XO_ScreenToBack(register __a0 struct Display *Display)
  1415. {
  1416.   ScreenToBack((struct Screen *)Display->RetScreen);
  1417. }
  1418.  
  1419. void dummy(void)
  1420. {
  1421.   sprintf(NULL, "%ls\n",VERSTAG);
  1422. }
  1423.  
  1424. __asm __saveds BOOL XO_screen_request (register __a0 struct xo_init *init_struct)
  1425. {
  1426.   BOOL retval = FALSE;
  1427.  
  1428.  
  1429.   SysBase = (*((struct ExecBase **) 4));
  1430.  
  1431.    if ((DOSBase = (struct DosLibrary *) OpenLibrary (DOSLIB, DOSVER)) != NULL)
  1432.   {
  1433.  
  1434.      if ((IntuitionBase = (struct IntuitionBase *) OpenLibrary (INTUILIB, INTUIVER)) != NULL)
  1435.     {
  1436.  
  1437.       if ((VilIntuiBase = OpenLibrary ("vilintuisup.library", 2)) != NULL)
  1438.       {
  1439.  
  1440.             if (openscreentags[0].ti_Data = VillageModeRequest (requesttags))
  1441.             {
  1442.               init_struct->width = 0;
  1443.               init_struct->height = 0;
  1444.               init_struct->depth = 24;
  1445.               init_struct->display_id = openscreentags[0].ti_Data;
  1446.               retval = TRUE;
  1447.             }
  1448.             else
  1449.             {
  1450.               sprintf (lib_buffer, "Konnte keinen Picasso-Screenrequester öffnen!\n");
  1451.             }
  1452.  
  1453.          CloseLibrary ((struct Library *) VilIntuiBase);
  1454.       }
  1455.       else
  1456.       {
  1457.         sprintf (lib_buffer, "Couldn't open vilintuisup.library (V 2.0).\n");
  1458.       }
  1459.  
  1460.       CloseLibrary ((struct Library *) IntuitionBase);
  1461.     }
  1462.     else
  1463.     {
  1464.       SetIoErr (901);
  1465.     }
  1466.     CloseLibrary ((struct Library *) DOSBase);
  1467.   }
  1468.   return (retval);
  1469. }
  1470.  
  1471. __asm __saveds BOOL XO_who_are_you (register __a0 struct xo_init *init_struct)
  1472. {
  1473.   init_struct->kennung = HW_PICASSO24;                             /* Picasso 24 Bit */
  1474.   strcpy (init_struct->lib_name, "xout_p.library");
  1475.   strcpy (init_struct->hw_name, "Picasso, TrueColor");
  1476.   strcpy (init_struct->version, VERSTAG);
  1477.   init_struct->prozessor = 0;                              /* any-Prozessor */
  1478.   init_struct->res_request = 1;                            /* Resolution-Requester ist vorhanden */
  1479.  
  1480.   init_struct->versionnumber = VERSIONNUMBER;                      /* Versionsnummer erhöhen! */
  1481.  
  1482. #if 0
  1483.   init_struct->width;                                      /* Für fixe Grafikkarten */
  1484.   init_struct->height;
  1485.   init_struct->depth;
  1486.   init_struct->display_id;
  1487. #endif
  1488.  
  1489.   init_struct->mousemax = ximousenr;                       /* Anzahl der verfügbaren Maustreiber */
  1490.  
  1491.   return (TRUE);
  1492. }
  1493.  
  1494.  
  1495.  
  1496. /****  Erweiterung der Library mit SetReg-Funktion  ****/
  1497.  
  1498. __asm __saveds ULONG XO_SetReg(register __d0 ULONG Tag, register __d1 ULONG Data)
  1499.   {
  1500.     union color test, help;
  1501.     switch(Tag)
  1502.       {
  1503.         case XO_SR_GETWINLIB_STD:
  1504.                 return (ULONG)(xiwin_libnames[0]);
  1505.                 break;
  1506.  
  1507.         case XO_SR_GETGFXLIB:
  1508.                 return (ULONG)(xigfx_libname);
  1509.                 break;
  1510.  
  1511.         case XO_GET_ERROR:      /* Errormeldungen durchslcheifen */
  1512.                   return (ULONG)(lib_buffer);
  1513.                   break;
  1514.  
  1515.         case XO_SET_CLUT:       /* Wegen Hintergrundfarbe */
  1516.                 clut24 = (ULONG *)(Data);
  1517.                 test.c24 = clut24[0];
  1518.                 help.c8[KEY] = test.c8[BLU];
  1519.                 help.c8[BLU] = test.c8[GRN];
  1520.                 help.c8[RED] = 0;
  1521.                 help.c8[GRN] = test.c8[RED];
  1522.                 BACKGROUND = help.c24;
  1523.                   break;
  1524.  
  1525.         case XO_SR_GETWINLIBS:
  1526.                   return (ULONG)(xiwin_libnames[0]);
  1527.                   break;
  1528.  
  1529.         case XO_SR_GETWINLIBS2: 
  1530.                 return (ULONG)(xiwin_libnames[1]);
  1531.                   break;
  1532.  
  1533.         case XO_SR_GETMOUSENAMES:
  1534.                   return (ULONG)(xiwin_mousenames[0]);
  1535.                   break;
  1536.  
  1537.         case XO_SR_GETMOUSENAMES2:
  1538.                  return (ULONG)(xiwin_mousenames[1]);
  1539.                   break;
  1540.  
  1541.         default: return 0;
  1542.                  break;
  1543.       }
  1544.   }
  1545.