Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

gfxcore.cpp

Go to the documentation of this file.
00001 /*  gfxcore.cpp
00002     Display independent graphic primitives
00003 
00004     Copyright (c)2001 by Thomas Kindler, thomas.kindler@gmx.de
00005 
00006     This program is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU General Public License as
00008     published by the Free Software Foundation; either version 2 of
00009     the License, or (at your option) any later version. Read the
00010     full License at http://www.gnu.org/copyleft for more details.
00011 */
00012 
00013 // include files -----
00014 //
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <malloc.h>
00018 #include <string.h>
00019 #include <assert.h>
00020 
00021 #include "gfxcore.h"
00022 #include "ztimer.h"
00023 #include "misc.h"
00024 
00025 
00026 #include "sysfont.cpp"
00027 
00028 
00029 static struct {
00030   Bitmap  bitmap;
00031   char    bmBits[GFX_SCRATCH_SIZE];
00032 } scratch = {0, 0, GFX_SCRATCH_SIZE};
00033 
00034 Bitmap *_gfx_scratch = (Bitmap*)&scratch;
00035 Font   *_gfx_defaultFont = NULL;
00036 
00037 // some fillStyles
00038 //
00039 char emptyFill[]     = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00040 char solidFill[]     = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
00041 char lineFill[]      = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 };
00042 char ltSlashFill[]   = { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 };
00043 char slashFill[]     = { 0x99, 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33 };
00044 char bkSlashFill[]   = { 0x33, 0x66, 0xcc, 0x99, 0x33, 0x66, 0xcc, 0x99 };
00045 char ltBkSlashFill[] = { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 };
00046 char hatchFill[]     = { 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55 };
00047 char xHatchFill[]    = { 0x55, 0x22, 0x55, 0x88, 0x55, 0x22, 0x55, 0x88 };
00048 char xLeaveFill[]    = { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa };
00049 char wDotFill[]      = { 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44 };
00050 char cDotFill[]      = { 0x11, 0x44, 0x88, 0x22, 0x11, 0x44, 0x88, 0x22 };
00051 
00061 void GFX_Init(Graphics *gfx, Bitmap *bm)
00062 {
00063   memset(gfx, 0, sizeof(Graphics));
00064   gfx->bitmap    = bm;
00065   gfx->font      = _font_sysfont;
00066   gfx->fillStyle = solidFill;
00067   gfx->color     = 1;
00068   gfx->blitMode  = BLT_OR;
00069 }
00070 
00071 
00081 void GFX_Init(Graphics *gfx, Graphics *gfx2)
00082 {
00083   memcpy(gfx, gfx2, sizeof(Graphics));
00084 }
00085 
00086 
00092 void GFX_SetFont(Graphics *gfx, Font *font)
00093 {
00094   if (!font)
00095     font = _font_sysfont;
00096   gfx->font = font;
00097 }
00098 
00099 
00104 void GFX_SetFillStyle(Graphics *gfx, char *style)
00105 {
00106   gfx->fillStyle = style;
00107 }
00108 
00109 
00110 void GFX_SetColor(Graphics *gfx, int color)
00111 {
00112   gfx->color = color ? 1 : 0;
00113 }
00114 
00115 
00116 void GFX_SetBlitMode(Graphics *gfx, int mode)
00117 {
00118   gfx->blitMode = mode & 15;
00119 }
00120 
00121 
00126 void GFX_MoveTo(Graphics *gfx, int x, int y)
00127 {
00128   gfx->x = x;
00129   gfx->y = y;
00130 }
00131 
00132 
00137 void GFX_MoveRel(Graphics *gfx, int dx, int dy)
00138 {
00139   gfx->x += dx;
00140   gfx->y += dy;
00141 }
00142 
00143 
00150 void GFX_HLine(Graphics *gfx, int x, int y, int w)
00151 {
00152   // clip coordinates
00153   //
00154   if (y<0 || y>= gfx->bitmap->height)
00155     return;
00156   if (x<0)
00157     { w -= -x; x = 0; }
00158   if (x+w >= gfx->bitmap->width)
00159     w -= (x+w)-gfx->bitmap->width;
00160   if (w<=0)
00161     return;
00162 
00163   char *dst   = &gfx->bitmap->bmBits[x+(y>>3)*gfx->bitmap->width];
00164   char  mask  = 1 << (y & 7);
00165   int   color = gfx->color;
00166 
00167   asm {
00168     push  bx
00169     push  cx
00170     push  di
00171     push  es
00172 
00173     les   di, dst
00174     mov   cx, w
00175     mov   bl, mask
00176     mov   bh, bl
00177     cmp   color, 0
00178     je    clr
00179 
00180 set:
00181     shr   cx, 1
00182     lahf          // save carry flag
00183     jz    set_onepix
00184 set_loop:
00185     or    word ptr [es:di], bx
00186     add   di, 2
00187     loop  set_loop
00188     sahf          // restore carry flag
00189     jnc   done
00190 set_onepix:
00191     or    byte ptr [es:di], bl
00192     stosb
00193     jmp   done
00194 
00195 clr:
00196     not   bx
00197     shr   cx, 1
00198     lahf          // save carry flag
00199     jz    clr_onepix
00200 clr_loop:
00201     and   word ptr [es:di], ax
00202     add   di, 2
00203     stosw
00204     loop  clr_loop
00205     sahf          // restore carry flag
00206     jnc   done
00207 clr_onepix:
00208     and   byte ptr [es:di], bl
00209     stosb
00210 
00211 done:
00212     pop   es
00213     pop   di
00214     pop   cx
00215     pop   bx
00216   }
00217 }
00218 
00219 
00220 
00227 void GFX_VLine(Graphics *gfx, int x, int y, int h)
00228 {
00229   // clip coordinates
00230   //
00231   if (x<0 || x>= gfx->bitmap->width)
00232     return;
00233   if (y<0)
00234     { h -= -y;  y = 0; }
00235   if (y+h >= gfx->bitmap->height)
00236     h -= (y+h)-gfx->bitmap->height;
00237   if (h<=0)
00238     return;
00239 
00240   char *dst = &gfx->bitmap->bmBits[x+(y>>3)*gfx->bitmap->width];
00241 
00242   // calculate destination masks
00243   //
00244   unsigned char fbm, lbm;
00245   fbm = 0xff << (   y & 7);
00246   lbm = 0xff >> (-y-h & 7);
00247 
00248   // calculate number of pages
00249   //
00250   int psize = gfx->bitmap->width;
00251   int pages = ((y+h+7)>>3) - (y>>3);
00252   if (pages == 1)
00253     fbm &= lbm;
00254 
00255   int color = gfx->color;
00256 
00257   asm {
00258     push  bx
00259     push  cx
00260     push  di
00261     push  es
00262 
00263     les   di, dst
00264     mov   al, fbm
00265     mov   cx, pages
00266     mov   bx, psize
00267 
00268     cmp   color, 0
00269     je    clr
00270 
00271 set_loop:
00272     or    byte ptr [es:di], al
00273     add   di, bx
00274     mov   al, 0xff
00275     dec   cx
00276     cmp   cx, 1
00277     jg    set_loop
00278     mov   al, lbm
00279     je    set_loop
00280     jmp   done
00281 
00282 clr:
00283     not   al
00284 clr_loop:
00285     and   byte ptr [es:di], al
00286     add   di, bx
00287     xor   al, al
00288     dec   cx
00289     cmp   cx, 1
00290     jg    clr_loop
00291     mov   al, lbm
00292     not   al
00293     je    clr_loop
00294 
00295 done:
00296     pop   es
00297     pop   di
00298     pop   cx
00299     pop   bx
00300   }
00301 
00302 }
00303 
00304 
00318 void GFX_Line(Graphics *gfx, int x1, int y1, int x2, int y2)
00319 {
00320   int dy = y2 - y1;
00321   int dx = x2 - x1;
00322   int stepx, stepy;
00323 
00324   if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }
00325   if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
00326 
00327   if (dx == 0)  GFX_VLine(gfx, min(x1, x2), min(y1, y2), dy);
00328   if (dy == 0)  GFX_HLine(gfx, min(x1, x2), min(y1, y2), dx);
00329 
00330   dy <<= 1;                                    // dy is now 2*dy
00331   dx <<= 1;                                    // dx is now 2*dx
00332 
00333   BM_PutPixel(gfx->bitmap, x1, y1, gfx->color);
00334   if (dx > dy) {
00335     int fraction = dy - (dx >> 1);             // same as 2*dy - dx
00336     while (x1 != x2) {
00337       if (fraction >= 0) {
00338         y1 += stepy;
00339         fraction -= dx;                        // same as fraction -= 2*dx
00340       }
00341       x1 += stepx;
00342       fraction += dy;                          // same as fraction -= 2*dy
00343       BM_PutPixel(gfx->bitmap, x1, y1, gfx->color);
00344     }
00345   } else {
00346     int fraction = dx - (dy >> 1);
00347     while (y1 != y2) {
00348       if (fraction >= 0) {
00349         x1 += stepx;
00350         fraction -= dy;
00351       }
00352       y1 += stepy;
00353       fraction += dx;
00354       BM_PutPixel(gfx->bitmap, x1, y1, gfx->color);
00355     }
00356   }
00357 }
00358 
00359 
00366 void GFX_LineRel(Graphics *gfx, int dx, int dy)
00367 {
00368   GFX_Line(gfx, gfx->x, gfx->y, gfx->x+dx, gfx->y+dy);
00369   gfx->x += dx;
00370   gfx->y += dy;
00371 }
00372 
00373 
00381 void GFX_LineTo (Graphics *gfx, int x, int y)
00382 {
00383   GFX_Line(gfx, gfx->x, gfx->y, x, y);
00384   gfx->x = x;
00385   gfx->y = y;
00386 }
00387 
00388 
00398 void GFX_Rectangle(Graphics *gfx, int x, int y, int w, int h)
00399 {
00400   if (w<=0 || h<=0)
00401     return;
00402   GFX_HLine(gfx, x    , y    , w);
00403   GFX_HLine(gfx, x    , y+h-1, w);
00404   GFX_VLine(gfx, x    , y+1  , h-2);
00405   GFX_VLine(gfx, x+w-1, y+1  , h-2);
00406 }
00407 
00408 
00416 void GFX_Circle(Graphics *gfx, int xc, int yc, int r)
00417 {
00418   int x = 0;
00419   int y = r;
00420   int p = 3 - (r<<1);
00421 
00422   while (x <= y)  {
00423     BM_PutPixel(gfx->bitmap, xc+x, yc+y, gfx->color);
00424     BM_PutPixel(gfx->bitmap, xc+x, yc-y, gfx->color);
00425     BM_PutPixel(gfx->bitmap, xc-x, yc+y, gfx->color);
00426     BM_PutPixel(gfx->bitmap, xc-x, yc-y, gfx->color);
00427     BM_PutPixel(gfx->bitmap, xc+y, yc+x, gfx->color);
00428     BM_PutPixel(gfx->bitmap, xc+y, yc-x, gfx->color);
00429     BM_PutPixel(gfx->bitmap, xc-y, yc+x, gfx->color);
00430     BM_PutPixel(gfx->bitmap, xc-y, yc-x, gfx->color);
00431     if (p < 0)
00432       p += (x++ << 2) + 6;
00433     else
00434       p += ((x++ - y--)<<2) + 10;
00435   }
00436 }
00437 
00438 
00449 void GFX_FillRect(Graphics *gfx, int x, int y, int w, int h)
00450 {
00451   if (x<0) {
00452     w -= -x;
00453     x  =  0;
00454   }
00455   if (x+w >= gfx->bitmap->width)
00456     w -= (x+w) - gfx->bitmap->width;
00457   if (w<=0)
00458     return;
00459 
00460   if (y<0) {
00461     h -= -y;
00462     y  =  0;
00463   }
00464   if (y+h >= gfx->bitmap->height)
00465     h -= (y+h) - gfx->bitmap->height;
00466   if (h<=0)
00467     return;
00468 
00469   assert(w <= _gfx_scratch->bmBitsSize);
00470 
00471   // copy pattern to scratch memory and blit
00472   //
00473   char *dst = _gfx_scratch->bmBits;
00474   char *src = gfx->fillStyle;
00475   asm {
00476     pushf
00477     push  cx
00478     push  si
00479     push  di
00480     push  ds
00481     push  es
00482     cld
00483     lds   si, dword ptr src
00484     les   di, dword ptr dst
00485     mov   cx, w
00486     shr   cx, 3
00487     inc   cx
00488 
00489 fill_loop:
00490     movsw
00491     movsw
00492     movsw
00493     movsw
00494     sub   si, 8
00495     loop  fill_loop
00496 
00497     pop   es
00498     pop   ds
00499     pop   di
00500     pop   si
00501     pop   cx
00502     popf
00503   }
00504 
00505   _gfx_scratch->width  = 0; // always blit the same page..
00506   BM_FastBlit(gfx->bitmap, x, y, _gfx_scratch, 0, 0, w, h, gfx->blitMode);
00507 }

Generated on Sun Aug 4 21:47:28 2002 for k/os mp3v2 by doxygen1.2.16