00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
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
00183 jz set_onepix
00184 set_loop:
00185 or word ptr [es:di], bx
00186 add di, 2
00187 loop set_loop
00188 sahf
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
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
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
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
00243
00244 unsigned char fbm, lbm;
00245 fbm = 0xff << ( y & 7);
00246 lbm = 0xff >> (-y-h & 7);
00247
00248
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;
00331 dx <<= 1;
00332
00333 BM_PutPixel(gfx->bitmap, x1, y1, gfx->color);
00334 if (dx > dy) {
00335 int fraction = dy - (dx >> 1);
00336 while (x1 != x2) {
00337 if (fraction >= 0) {
00338 y1 += stepy;
00339 fraction -= dx;
00340 }
00341 x1 += stepx;
00342 fraction += 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
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;
00506 BM_FastBlit(gfx->bitmap, x, y, _gfx_scratch, 0, 0, w, h, gfx->blitMode);
00507 }