?? genfunc.c
字號:
/*** $Id: genfunc.c,v 1.9 2003/09/04 02:57:09 weiym Exp $**** genfunc.c: Native Low Level Graphics Engine 's commone file**** Copyright (C) 2003 Feynman Software** Copyright (C) 2000 Song Lixin**** Create by Song Lixin, 2000/10/18*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "common.h"#include "minigui.h"#include "gal.h"#include "native.h"//==================================================================================================//general functions//static void drawrow(PSD psd, int x1, int x2, int y);static void drawcol(PSD psd, int x,int y1,int y2);static inline void setpixel(PSD psd, int x, int y, int c);static void setcirclepixels(PSD psd, int x, int y, int sx, int sy, int c);static void setcirclepixels(PSD psd, int x, int y, int sx, int sy, int c);static inline int muldiv64(int m1, int m2, int d);/* initialize memory device with passed parms*/void native_gen_initmemgc(PSD mempsd,int w,int h,int planes,int bpp,int linelen, int size,void *addr) { mempsd->xres = w; mempsd->yres = h; mempsd->xvirtres = w; mempsd->yvirtres = h; mempsd->planes = planes; mempsd->bpp = bpp; mempsd->linelen = linelen; mempsd->size = size; mempsd->addr = addr;}/* allocate a memory screen device*/PSD native_gen_allocatememgc(PSD psd){ PSD mempsd; mempsd = malloc(sizeof(SCREENDEVICE)); if (!mempsd) return NULL; /* copy passed device get initial values*/ *mempsd = *psd; /* initialize*/ mempsd->flags |= PSF_MEMORY; mempsd->flags &= ~PSF_SCREEN; mempsd->addr = NULL; return mempsd;}void native_gen_freememgc(PSD mempsd){ /* note: mempsd->addr must be freed elsewhere*/ free(mempsd);}void native_gen_fillrect(PSD psd,int x, int y, int w, int h, gal_pixel c){#if 1 while (h--) psd->DrawHLine(psd, x, y++, w, c);#else while (w--) psd->DrawVLine(psd, x++, y , h, c);#endif}int native_gen_clippoint(PSD psd, int x ,int y){ if(psd->doclip) { if ((x >= psd->clipminx) && (x < psd->clipmaxx) && (y >= psd->clipminy) && (y < psd->clipmaxy)) return CLIP_VISIBLE; } else { if ((x >= 0) && (x < psd->xres) && (y >= 0) && (y < psd->yres)) return CLIP_VISIBLE; } return CLIP_INVISIBLE;}int native_gen_cliphline(PSD psd,int * px,int * py, int * pw){ if (psd->doclip) { if ( (*px >= psd->clipmaxx) || (*py >= psd->clipmaxy) || (*px + *pw - 1 < psd->clipminx) || (*py < psd->clipminy) ) return CLIP_INVISIBLE; if ( (*px >= psd->clipminx) && (*py >= psd->clipminy) && (*px + *pw -1 < psd->clipmaxx) && (*py < psd->clipmaxy) ) return CLIP_VISIBLE; if (*px < psd->clipminx) { *pw -= psd->clipminx - *px; *px = psd->clipminx; } if (*px + *pw - 1 >= psd->clipmaxx) *pw = psd->clipmaxx - *px; } else { if ( (*px >= psd->xres) || (*py >= psd->yres) || (*px + *pw - 1 < 0) || (*py < 0) ) return CLIP_INVISIBLE; if ( (*px >= 0) && (*py >= 0) && (*px + *pw -1 < psd->xres) && (*py < psd->yres) ) return CLIP_VISIBLE; if (*px < 0) { *pw += *px; *px = 0; } if (*px + *pw - 1 >= psd->xres) *pw = psd->xres - *px; } if (*pw <= 0) return CLIP_INVISIBLE; return CLIP_PARTIAL; }int native_gen_clipvline(PSD psd,int * px,int * py, int *ph){ if (psd->doclip) { if ( (*px >= psd->clipmaxx) || (*py >= psd->clipmaxy) || (*px < psd->clipminx) || (*py + *ph - 1 < psd->clipminy) ) return CLIP_INVISIBLE; if ( (*px >= psd->clipminx) && (*py >= psd->clipminy) && (*px < psd->clipmaxx) && (*py + *ph - 1 < psd->clipmaxy) ) return CLIP_VISIBLE; if (*py < psd->clipminy) { *ph -= psd->clipminy - *py; *py = psd->clipminy; } if (*py + *ph - 1 >= psd->clipmaxy) *ph = psd->clipmaxy - *py; } else { if ( (*py >= psd->yres) || (*px >= psd->xres) || (*py + *ph - 1 < 0) || (*px < 0) ) return CLIP_INVISIBLE; if ( (*py >= 0) && (*px >= 0) && (*py + *ph -1 < psd->yres) && (*px < psd->xres) ) return CLIP_VISIBLE; if (*py < 0) { *ph += *py; *py = 0; } if (*py + *ph - 1 >= psd->yres) *ph = psd->yres - *py; } if (*ph <= 0) return CLIP_INVISIBLE; return CLIP_PARTIAL; }int native_gen_clipline (PSD psd,int * px1,int * py1, int * px2,int *py2){ int w,h; int r1; int clip_first; int clip_last; if(*px1 == *px2) { if (*py1 == *py2) return native_gen_clippoint (psd,*px1,*px2); if (*py1 > *py2) { h = *py1 - *py2 + 1; r1 = native_gen_clipvline (psd, px1, py2, &h); if (r1 == CLIP_PARTIAL) *py1 = *py2 + h - 1; return r1; } else { h = *py2 - *py1 + 1; r1 = native_gen_clipvline (psd, px1, py1, &h); if (r1 == CLIP_PARTIAL) *py2 = *py1 + h - 1; return r1; } } if(*py1 == *py2) { if (*px1 > *px2) { w = *px1 - *px2 + 1; r1 = native_gen_clipvline (psd, px2, py1, &w); if (r1 == CLIP_PARTIAL) *px1 = *px2 + w - 1; return r1; } else { w = *px2 - *px1 + 1; r1 = native_gen_clipvline (psd, px2, py2, &w); if (r1 == CLIP_PARTIAL) *px2 = *px1 + w - 1; return r1; } } return cs_clipline(psd,px1,py1,px2,py2,&clip_first,&clip_last); }/* * You should give a normalized rect. that is *pw > 0 *ph > 0 * * returned value: * CLIP_VISIBLE The whole rectangle is visible * CLIP_INVISIBLE The whole rectangle is invisible * CLIP_PARTIAL The rectangle may be partially visible * * if returned CLIP_PARTIAL,the parameter is modified to hold the part * that is in the clip region. */int native_gen_clipbox (PSD psd,int * px,int * py, int * pw,int *ph){ if (*pw == 1) return native_gen_clipvline(psd, px, py, ph); if (*ph == 1) return native_gen_cliphline(psd, px, py, pw); if (psd->doclip) { if ( (*px >= psd->clipmaxx) || (*py >= psd->clipmaxy) || (*px + *pw - 1 < psd->clipminx) || (*py + *ph - 1 < psd->clipminy) ) return CLIP_INVISIBLE; if ( (*px >= psd->clipminx) && (*py >= psd->clipminy) && (*px + *pw -1 < psd->clipmaxx) && (*py + *ph - 1 < psd->clipmaxy) ) return CLIP_VISIBLE; if (*px < psd->clipminx) { *pw -= psd->clipminx - *px; *px = psd->clipminx; } if (*py < psd->clipminy) { *ph -= psd->clipminy - *py; *py = psd->clipminy; } if (*px + *pw - 1 >= psd->clipmaxx) *pw = psd->clipmaxx - *px; if (*py + *ph - 1 >= psd->clipmaxy) *ph = psd->clipmaxy - *py; } else { if ( (*px >= psd->xres) || (*py >= psd->yres) || (*px + *pw - 1 < 0) || (*py +*ph - 1 < 0) ) return CLIP_INVISIBLE; if ( (*px >= 0) && (*py >= 0) && (*px + *pw -1 < psd->xres) && (*py + *ph - 1 < psd->yres) ) return CLIP_VISIBLE; if (*px < 0) { *pw += *px; *px = 0; } if (*px + *pw - 1 >= psd->xres) *pw = psd->xres - *px; if (*py < 0) { *ph += *py; *py = 0; } if (*py + *ph - 1 >= psd->yres) *ph = psd->yres - *py; } if (*pw <= 0 || *ph <= 0) return CLIP_INVISIBLE; return CLIP_PARTIAL; }//==================================================================================================// help functions/* * Calculate size and linelen of memory gc. * If bpp or planes is 0, use passed psd's bpp/planes. * Note: linelen is calculated to be DWORD aligned for speed * for bpp <= 8. Linelen is converted to bytelen for bpp > 8. */int native_gen_calcmemgcalloc(PSD psd, unsigned int width, unsigned int height, int planes, int bpp, int *psize, int *plinelen){ int bytelen, linelen; if(!planes) planes = psd->planes; if (!bpp) bpp = psd->bpp; /* * use bpp and planes to create size and linelen. * linelen is in bytes for bpp 1, 2, 4, 8, and pixels for bpp 16,24,32. */ if(planes == 1) { switch(bpp) { case 1: case 2: case 4: case 8: bytelen = linelen = (width+3) & ~3; break; case 16: linelen = width; bytelen = width * 2; break; case 24: linelen = width; bytelen = width * 3; break; case 32: linelen = width; bytelen = width * 4; break; default: return 0; } } else if(planes == 4) { /* FIXME assumes VGA 4 planes 4bpp*/ /* we use 4bpp linear for memdc format*/ bytelen = linelen = (width+3) & ~3; } else { *psize = *plinelen = 0; return 0; } *plinelen = linelen; *psize = bytelen * height; return 1;}void native_gen_rect(PSD psd , int l, int t, int r, int b){ drawrow(psd, l, r, t); drawrow(psd, l, r, b); drawcol(psd, l, t, b); drawcol(psd, r, t, b);}/* * Draw an arbitrary line using the current clipping region and foreground color * If bDrawLastPoint is FALSE, draw up to but not including point x2, y2. * * This routine is the only routine that adjusts coordinates for supporting * two different types of upper levels, those that draw the last point * in a line, and those that draw up to the last point. All other local * routines draw the last point. This gives this routine a bit more overhead, * but keeps overall complexity down. */void native_gen_line(PSD psd, int x1, int y1, int x2, int y2, BOOL bDrawLastPoint){ int xdelta; /* width of rectangle around line */ int ydelta; /* height of rectangle around line */ int xinc; /* increment for moving x coordinate */ int yinc; /* increment for moving y coordinate */ int rem; /* current remainder */ int temp; /* See if the line is horizontal or vertical. If so, then call * special routines. */ if (y1 == y2) { /* * Adjust coordinates if not drawing last point. Tricky. */ if(!bDrawLastPoint) { if (x1 > x2) { temp = x1; x1 = x2 + 1; x2 = temp; } else --x2; } /* call faster line drawing routine*/ drawrow(psd, x1, x2, y1); return; } if (x1 == x2) { /* * Adjust coordinates if not drawing last point. Tricky. */ if(!bDrawLastPoint) { if (y1 > y2) { temp = y1; y1 = y2 + 1; y2 = temp; } else --y2; } /* call faster line drawing routine*/ drawcol(psd, x1, y1, y2); return; } /* The line may be partially obscured. Do the draw line algorithm * checking each point against the clipping regions. */ xdelta = x2 - x1; ydelta = y2 - y1; if (xdelta < 0) xdelta = -xdelta; if (ydelta < 0) ydelta = -ydelta; xinc = (x2 > x1) ? 1 : -1; yinc = (y2 > y1) ? 1 : -1; if (psd->ClipPoint(psd, x1, y1)) psd->DrawPixel(psd, x1, y1, psd->gr_foreground); if (xdelta >= ydelta) { rem = xdelta / 2; for(;;) { if(!bDrawLastPoint && x1 == x2) break; x1 += xinc; rem += ydelta; if (rem >= xdelta) { rem -= xdelta; y1 += yinc; } if (psd->ClipPoint(psd, x1, y1)) psd->DrawPixel(psd, x1, y1, psd->gr_foreground); if(bDrawLastPoint && x1 == x2) break; } } else { rem = ydelta / 2; for(;;) { if(!bDrawLastPoint && y1 == y2) break; y1 += yinc; rem += xdelta; if (rem >= ydelta) { rem -= ydelta; x1 += xinc; } if (psd->ClipPoint(psd, x1, y1)) psd->DrawPixel(psd, x1, y1, psd->gr_foreground); if(bDrawLastPoint && y1 == y2) break; } }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -