DRAW.C

[目次 | 型・クラス・構造体 | 関数 | マクロ]

目次

型・クラス・構造体一覧

関数一覧

マクロ一覧


   1|/**************************************************************************
   2|*  1. <<< 描画ツール (Draw) >>> 
   3|*
   4|*・線分や領域塗りつぶしといった基本的な図形を描画するツールです。
   5|*・表示画面を Draw_Scr クラスで抽象化しているので、様々な画面に対して
   6|*  描画することが出来ます。
   7|*
   8|*・次のクラスがあります。
   9|*  ・描画ツール・クラス [Draw]
  10|*  ・描画ペン・クラス [Draw_Pen]
  11|*  ・太線タイプ [Draw_BoldType]
  12|*
  13|*
  14|* 2. <<<【解説】基本的な描画の仕方(旧式) >>>
  15|*
  16|*・アプリケーションは、Draw クラスや XorPaint クラスなど描画関係のコン
  17|*  ポーネントに対し、線分の描画や塗りつぶしなどのメッセージを送ります。
  18|*  描画対象の画面は DrawScr 抽象クラスから継承している Screen, DScreen
  19|*  または Screen98 クラスのインスタンスであり、それらをアクティブ(描画
  20|*  対象)に設定(Draw_setActiveScreen 関数)して描画します。
  21|*
  22|*  
  23|*
  24|*・地図画面は Screen クラスのインスタンスです。テスト用として PC-98 の
  25|*  DOS 画面に表示する場合は、 Screen98 クラスのインスタンスを作成します。
  26|*  ワーク領域として Screen クラスのインスタンスや DScreen クラスのイン
  27|*  スタンスを作成します。
  28|*・アプリケーションが描画する場合は、 Draw クラスか XorPaint クラスの
  29|*  グローバル・インスタンスに Screen クラスなどの画面インスタンスを
  30|*  関連付けてから、そのグローバル・インスタンスにメッセージを送ります。
  31|***************************************************************************/
  32|
  33|#include "mixer_precomp.h"
  34|// #pragma hdrstop ("mixer_precomp")
  35|
  36|#ifdef  USES_MXP_AUTOINC
  37| #include "draw.ah"  /* Auto include header, Look at mixer-... folder */
  38|#endif
  39|
  40|
  41|/*************************************************************************
  42|* 3. <<< 線分を描く[Draw_line()] >>>
  43|**************************************************************************/
  44|#define _Draw_line
  45|#include "draw.cc"
  46|#undef  _Draw_line
  47|
  48|#ifdef USES_TYPEX
  49|/*************************************************************************
  50|*  4. <<< 線分を描画する [Draw_line2()] >>>
  51|*【補足】
  52|*・拡張座標値を用いて長い線分を高速に描画します。
  53|*・x1,y1,x2,y2 は、画面の中に入っている必要があります。
  54|**************************************************************************/
  55|void  Draw_line2( Draw* m, int x1, int y1, int x2, int y2, int color )
  56|{
  57|  UINT32  exAdr;             /* 座標値を表す拡張座標値 */
  58|  UINT32  exAdr_last;        /* 同・終点 */
  59|  UINT32  plus0, plus1;      /* 拡張ベクトル値 */
  60|  int  dx,dy;             /* 方向ベクトルの x,y 成分の絶対値 */
  61|  int  dir;               /* 方向番号([x1,y1]→[x2,y2])*/
  62|  int  cup, plus, minus;  /* Bresenham のアルゴリズムの3変数 */
  63|  void*  obj;             /* m->drawScr 画面クラスのアドレス */
  64|  void  (*exPset)(void*,int,int);   /* obj クラスの拡張・点描画の関数ポインタ */
  65|
  66|  #ifdef _CHECKER
  67|    if ( x1 < 0 || x1 >= DrawScr_getWidth( m->drawScr ) )  error();
  68|    if ( x2 < 0 || x2 >= DrawScr_getWidth( m->drawScr ) )  error();
  69|    if ( y1 < 0 || y1 >= DrawScr_getHeight( m->drawScr ) ) error();
  70|    if ( y2 < 0 || y2 >= DrawScr_getHeight( m->drawScr ) ) error();
  71|  #endif
  72|
  73|  /* x1 <= x2 にする */
  74|  if ( x1 > x2 ) {
  75|    int  a;
  76|    a = x1; x1 = x2; x2 = a;
  77|    a = y1; y1 = y2; y2 = a;
  78|  }
  79|
  80|  /* 各種変数を初期化する */
  81|  exAdr = DrawScr_getExAdr( m->drawScr, x1, y1 );
  82|  exAdr_last = DrawScr_getExAdr( m->drawScr, x2, y2 );
  83|  dx = x2 - x1;
  84|  dy = ( y1 < y2 ? y2 - y1 : y1 - y2 );
  85|  dir = Draw_getDirec( dx, y2 - y1 );
  86|  DrawScr_getExVectors( m->drawScr, dir, &plus0, &plus1 );
  87|  if ( dx >= dy ) {
  88|    plus = 2 * dy;    /* plus = 2dy */
  89|    cup = plus - dx;  /* (dy % dx) * 2 */
  90|    minus = cup - dx; /* minus = -2dx */
  91|  }
  92|  else {
  93|    plus = 2 * dx;
  94|    cup = plus - dy;
  95|    minus = cup - dy;
  96|  }
  97|  obj = m->drawScr.obj;
  98|  exPset = m->drawScr.sc->exPset;
  99|
 100|  /* 線を描く(Bresenham のアルゴリズム) */
 101|  exPset( obj, exAdr, color );
 102|  while ( exAdr != exAdr_last ) {
 103|    if ( cup > 0 )
 104|      { exAdr += plus1;  cup += minus; }
 105|    else
 106|      { exAdr += plus0;  cup += plus; }
 107|
 108|    exPset( obj, exAdr, color );
 109|  }
 110|}
 111|#endif /* USES_TYPEX */
 112|
 113|
 114|#ifdef USES_TYPEX
 115|#ifdef USES_SCREEN
 116|/*************************************************************************
 117|*  5. <<< 線分を描画する [Draw_line3()] >>>
 118|*【補足】
 119|*・マクロ展開しています。レジスタ指定しています。
 120|*・Draw の対象は Screen 専用です。
 121|*・拡張座標値を用いて長い線分を高速に描画します。
 122|*・x1,y1,x2,y2 は、画面の中に入っている必要があります。
 123|**************************************************************************/
 124|void  Draw_line3( Draw* m, int x1, int y1, int x2, int y2, int color )
 125|{
 126|  register UINT32  exAdr;             /* 座標値を表す拡張座標値 */
 127|  register UINT32  exAdr_last;        /* 同・終点 */
 128|  register UINT32  plus0, plus1;      /* 拡張ベクトル値 */
 129|  register int  dx,dy;             /* 方向ベクトルの x,y 成分の絶対値 */
 130|  register int  dir;               /* 方向番号([x1,y1]→[x2,y2])*/
 131|  register int  cup, plus, minus;  /* Bresenham のアルゴリズムの3変数 */
 132|  register Screen*  scr = m->drawScr.obj;
 133|
 134|  #ifdef _CHECKER
 135|    if ( x1 < 0 || x1 >= DrawScr_getWidth( m->drawScr ) )  error();
 136|    if ( x2 < 0 || x2 >= DrawScr_getWidth( m->drawScr ) )  error();
 137|    if ( y1 < 0 || y1 >= DrawScr_getHeight( m->drawScr ) ) error();
 138|    if ( y2 < 0 || y2 >= DrawScr_getHeight( m->drawScr ) ) error();
 139|  #endif
 140|
 141|  /* x1 <= x2 にする */
 142|  if ( x1 > x2 ) {
 143|    int  a;
 144|    a = x1; x1 = x2; x2 = a;
 145|    a = y1; y1 = y2; y2 = a;
 146|  }
 147|
 148|  /* 各種変数を初期化する */
 149|  exAdr = Screen_getExAdr2( scr, x1, y1 );
 150|  exAdr_last = Screen_getExAdr2( scr, x2, y2 );
 151|  dx = x2 - x1;
 152|  dy = ( y1 < y2 ? y2 - y1 : y1 - y2 );
 153|  Draw_getDirec2( dx, y2 - y1, dir );
 154|  Screen_getExVectors2( scr, dir, plus0, plus1 );
 155|  if ( dx >= dy ) {
 156|    plus = dy << 1;    /* plus = 2dy */
 157|    cup = plus - dx;  /* (dy % dx) * 2 */
 158|    minus = cup - dx; /* minus = -2dx */
 159|  }
 160|  else {
 161|    plus = dx << 1;
 162|    cup = plus - dy;
 163|    minus = cup - dy;
 164|  }
 165|
 166|  /* 線を描く(Bresenham のアルゴリズム) */
 167|  Screen_exPset2( scr, exAdr, color );
 168|  while ( exAdr != exAdr_last ) {
 169|    if ( cup > 0 )
 170|      { exAdr += plus1;  cup += minus; }
 171|    else
 172|      { exAdr += plus0;  cup += plus; }
 173|
 174|    Screen_exPset2( scr, exAdr, color );
 175|  }
 176|}
 177|#endif /* USES_SCREEN */
 178|#endif /* USES_TYPEX */
 179|
 180|
 181|/*************************************************************************
 182|* 6. <<< 破線を描く[Draw_loseLine()] >>>
 183|**************************************************************************/
 184|#define _Draw_loseLine
 185|#include "draw.cc"
 186|#undef  _Draw_loseLine
 187|
 188|
 189|/*************************************************************************
 190|* 7. <<< コピーラインを描く[Draw_copyLine()] >>>
 191|**************************************************************************/
 192|#ifdef USES_SCREEN
 193|#define _Draw_copyLine
 194|#include "draw.cc"
 195|#undef  _Draw_copyLine
 196|#endif
 197|
 198|
 199|/*************************************************************************
 200|* 8. <<< 塗りつぶし境界を描く[Draw_lineForXorPaint()] >>>
 201|**************************************************************************/
 202|void  Draw_lineForXorPaint( Draw* m, int x1, int y1, int x2, int y2,
 203|    int color )
 204|{
 205|  int  x,y,n;
 206|  int  dx, dy;
 207|  register int  cup;           /* カウンタ */
 208|  register int  plus, minus;   /* カウンタの増分、減分 */
 209|  int  flag;          /* cup による座標の増減, +1 or -1 */
 210|  int  prevX;         /* 直前に描いた点の x 座標 */
 211|
 212|  /* 90度〜270度(左向き)の場合 */
 213|  if ( x1 > x2 ) {
 214|    n = x1; x1 = x2; x2 = n;
 215|    n = y1; y1 = y2; y2 = n;
 216|  }
 217|
 218|  /* 最初の1点を x, y に color 色で打つ */
 219|  prevX = x1;  /* 最初の1点は描かない */
 220|
 221|  /* dx, dy, flag の設定 */
 222|  dx = x2 - x1;
 223|  dy = y2 - y1;
 224|  if ( dy > 0 )
 225|    flag = +1;
 226|  else {
 227|    flag = -1;  dy = -dy;
 228|  }
 229|
 230|  /* 0度〜45度(水平より右下がり)の場合 */
 231|  /* 0度〜-45度(水平より右上がり)の場合 */
 232|  if ( dx >= dy ) {
 233|    plus = 2 * dy;    /* plus = 2dy */
 234|    cup = plus - dx;  /* (dy % dx) * 2 */
 235|    minus = cup - dx; /* minus = -2dx */
 236|
 237|    y = y1;
 238|    for ( x = x1 + 1; x <= x2; x++ ) {
 239|      if ( cup > 0 )
 240|        { y += flag;  cup += minus; }
 241|      else
 242|        cup += plus;
 243|
 244|      /* x, y に color 色の点を打つ */
 245|      Draw_psetXor( m, x, y, color );
 246|    }
 247|  }
 248|
 249|  /* 45度〜90度(垂直より右下がり)の場合 */
 250|  /* -45度〜-90度(垂直より右上がり)の場合 */
 251|  else {
 252|    if ( flag < 0 ) {
 253|      n = x1; x1 = x2; x2 = n;
 254|      n = y1; y1 = y2; y2 = n;
 255|
 256|      /* 最初の点(右上端点)は必ず描く、ただし、垂直でないとき */
 257|      if ( x1 != x2 )
 258|        Draw_psetXor( m, x1, y1, color );
 259|      prevX = x1;
 260|    }
 261|    plus = 2 * dx;
 262|    cup = plus - dy;
 263|    minus = cup - dy;
 264|
 265|    x = x1;
 266|    for ( y = y1 + 1; y <= y2; y ++ ) {
 267|      if ( cup > 0 )
 268|        { x += flag;  cup += minus; }
 269|      else
 270|        cup += plus;
 271|
 272|      /* x, y に color 色の点を打つ */
 273|      if ( x != prevX && ( flag > 0 || x != x2 ) ) {
 274|        /* Draw_psetXor( m, x, y, color ); *//*GHSで落ちる*/
 275|        DrawScr_psetXor( (m)->drawScr, x, y, color );
 276|        prevX = x;
 277|      }
 278|    }
 279|  }
 280|}
 281|
 282|
 283|/**************************************************************************
 284|*  9. <<< 太線を描く [Draw_boldLine()] >>>
 285|*  ・width : 太さ(pixel)
 286|*  ・type : 筆, 線筆=Draw_BoldType_Line, 丸筆=Draw_BoldType_Circle
 287|*  Draw_Pen_init() してから実行すること。
 288|***************************************************************************/
 289|void  Draw_boldLine( Draw* m, int x1, int y1, int x2, int y2,
 290|  int color, int width, int type )
 291|{
 292|  int  i;
 293|
 294|  /* 線筆 */
 295|  if ( type == Draw_BoldType_Line ) {
 296|    int dx = ( x1 < x2 ? x2 - x1 : x1 - x2 );
 297|    int dy = ( y1 < y2 ? y2 - y1 : y1 - y2 );
 298|    if ( dx >= dy ) {  /* 水平から 45°以下 */
 299|      for ( i = -(width-1) / 2; i <= width / 2; i++ )
 300|        Draw_line( m, x1, y1+i, x2, y2+i, color );
 301|    }
 302|    else {             /* 垂直から 45°以下 */
 303|      for ( i = -(width-1) / 2; i <= width / 2; i++ )
 304|        Draw_line( m, x1+i, y1, x2+i, y2, color );
 305|    }
 306|  }
 307|  /* 丸筆 */
 308|  else {
 309|    #ifdef USES_SCREEN
 310|      int* points = Draw_Pen_maru[width]; /* 筆の形, Draw_Pen_maru[] 変数 */
 311|
 312|      for ( i=0; i < points[0]; i+=2 ) {
 313|        Draw_line( m, x1 + points[i+1], y1 + points[i+2],
 314|                x2 + points[i+1], y2 + points[i+2], color );
 315|      }
 316|    #else
 317|      #ifndef NDEBUG
 318|        error();
 319|      #endif
 320|    #endif
 321|  }
 322|}
 323|
 324|
 325|#ifdef USES_SSTACK
 326|/**************************************************************************
 327|*  10. <<< ベジェ曲線を描く [Draw_bezier(), Draw_bezierForXorPaint()] >>>
 328|***************************************************************************/
 329|#define  Bezier_max  1000 /* ベジェ曲線用スタックのサイズ、点を打つ数 * 2 */
 330|
 331|typedef struct {
 332|  int  x1,y1, x2,y2, x3,y3, x4,y4;
 333|} Draw_BezierCup;
 334|
 335|void  Draw_BezierCup_copy( Draw_BezierCup* a, Draw_BezierCup* b );
 336|void  Draw_bezierSub( Draw* m, Draw_BezierCup* in,
 337|           int* x, int* y, Draw_BezierCup* out1, Draw_BezierCup* out2 );
 338|
 339|#define _Draw_bezier
 340|#include "draw.cc"
 341|#undef  _Draw_bezier
 342|
 343|#define _Draw_bezierForXorPaint
 344|#include "draw.cc"
 345|#undef  _Draw_bezierForXorPaint
 346|
 347|
 348|/*
 349|*  ベジェ分割
 350|*  ベジェ中点と、サブ・ベジェカップ を2つ得る
 351|*  ・in : ベジェカップ(入力)
 352|*  ・x, y : ベジェ中点、点を描画する位置(出力)
 353|*  ・out1, out2 : サブ・ベジェカップ(出力)
 354|*/
 355|void  Draw_bezierSub( Draw* m, Draw_BezierCup* in,
 356|          int* x, int* y, Draw_BezierCup* out1, Draw_BezierCup* out2 )
 357|{
 358|  int  bx, by;
 359|
 360|  #if 0
 361|    pset( in->x1, in->y1, 0x00FF00 );
 362|    pset( in->x2, in->y2, 0x00FF00 );
 363|    pset( in->x3, in->y3, 0x00FF00 );
 364|    pset( in->x4, in->y4, 0x00FF00 );
 365|  #endif
 366|
 367|  out1->x2 = (in->x1 + in->x2) / 2;  /* a */
 368|  out1->y2 = (in->y1 + in->y2) / 2;
 369|  bx = (in->x2 + in->x3) / 2;        /* b */
 370|  by = (in->y2 + in->y3) / 2;
 371|  out2->x3 = (in->x3 + in->x4) / 2;  /* c */
 372|  out2->y3 = (in->y3 + in->y4) / 2;
 373|  out1->x3 = (out1->x2 + bx) / 2;    /* d */
 374|  out1->y3 = (out1->y2 + by) / 2;
 375|  out2->x2 = (bx + out2->x3) / 2;    /* e */
 376|  out2->y2 = (by + out2->y3) / 2;
 377|  *x = (out1->x3 + out2->x2) / 2;    /* f */
 378|  *y = (out1->y3 + out2->y2) / 2;
 379|
 380|  #if 0
 381|    pset( out1->x2, out1->y2, 0xFF0000 );
 382|    pset( bx, by, 0xFF0000 );
 383|    pset( out2->x3, out2->y3, 0xFF0000 );
 384|    pset( out1->x3, out1->y3, 0xFF0000 );
 385|    pset( out2->x2, out2->y2, 0xFF0000 );
 386|  #endif
 387|
 388|  out1->x1 = in->x1; out1->y1 = in->y1;
 389|  out1->x4 = *x;     out1->y4 = *y;
 390|  out2->x1 = *x;     out2->y1 = *y;
 391|  out2->x4 = in->x4; out2->y4 = in->y4;
 392|}
 393|
 394|void  Draw_BezierCup_copy( Draw_BezierCup* a, Draw_BezierCup* b )
 395|{
 396|  a->x1 = b->x1;  a->y1 = b->y1;
 397|  a->x2 = b->x2;  a->y2 = b->y2;
 398|  a->x3 = b->x3;  a->y3 = b->y3;
 399|  a->x4 = b->x4;  a->y4 = b->y4;
 400|}
 401|
 402|
 403|#endif  /* USES_SSTACK */
 404|
 405|
 406|/**************************************************************************
 407|*  11. <<< 矩形塗りつぶし [Draw_rectFill()] >>>
 408|***************************************************************************/
 409|void  Draw_rectFill( Draw* m, int x1, int y1, int x2, int y2,
 410|  int color )
 411|{
 412|  int  x,y;
 413|
 414|  #ifdef _CHECKER
 415|    if ( x1 > x2 )  error();
 416|    if ( y1 > y2 )  error();
 417|  #endif
 418|
 419|  for ( x = x1; x <= x2; x++ )
 420|    for ( y = y1; y <= y2; y++ )
 421|      Draw_pset( m, x, y, color );
 422|}
 423|
 424|
 425|#ifdef USES_THREED
 426|#ifdef USES_SCALE
 427|
 428|/***********************************************************************
 429|*  12. <<< 3次元で線分を描く [Draw_line3dP()] >>>
 430|************************************************************************/
 431|void  Draw_line3dP( Draw* draw, ThreeD_ViewL* viewp, Scale* scale,
 432|  ThreeD_XYZ* p1, ThreeD_XYZ* p2, int color )
 433|{
 434|  ThreeD_XYZ  sp1, sp2;
 435|  int  x1,y1,xx,yy;
 436|
 437|  ThreeD_XYZ_get2D( p1, viewp, &sp1 );
 438|  ThreeD_XYZ_get2D( p2, viewp, &sp2 );
 439|
 440|  x1 = (int)Scale_toGX( scale, sp1.x );
 441|  y1 = (int)Scale_toGY( scale, sp1.y );
 442|  xx = (int)Scale_toGX( scale, sp2.x );
 443|  yy = (int)Scale_toGY( scale, sp2.y );
 444|  Draw_line( draw, x1,y1, xx,yy, color );
 445|}
 446|
 447|#endif /* USES_SCALE */
 448|#endif /* USES_THREED */
 449|
 450|#ifdef USES_THREED
 451|#ifdef USES_SCALE
 452|
 453|/***********************************************************************
 454|*  13. <<< 3次元で線分を描く [Draw_line3d()] >>>
 455|************************************************************************/
 456|void  Draw_line3d( Draw* draw, ThreeD_ViewL* viewp, Scale* scale,
 457|  double x1, double y1, double z1,
 458|  double x2, double y2, double z2, int color )
 459|{
 460|  ThreeD_XYZ  p1, p2;
 461|
 462|  p1.x = x1;  p1.y = y1;  p1.z = z1;
 463|  p2.x = x2;  p2.y = y2;  p2.z = z2;
 464|
 465|  Draw_line3dP( draw, viewp, scale, &p1, &p2, color );
 466|}
 467|
 468|#endif /* USES_SCALE */
 469|#endif /* USES_THREED */
 470|
 471|#ifdef USES_THREED2
 472|#ifdef USES_SCALE3
 473|
 474|/***********************************************************************
 475|*  14. <<< 3次元で線分を描く [Draw_line3dP2()] >>>
 476|************************************************************************/
 477|void  Draw_line3dP2( Draw* draw, ThreeD2_ViewL* viewp, Scale3* scale,
 478|  ThreeD2_XYZ* p1, ThreeD2_XYZ* p2, int color )
 479|{
 480|  ThreeD2_XYZ  sp1, sp2;
 481|  int  x1,y1,xx,yy;
 482|
 483|  ThreeD2_XYZ_get2D( p1, viewp, &sp1 );
 484|  ThreeD2_XYZ_get2D( p2, viewp, &sp2 );
 485|
 486|  x1 = Scale3_toGX( scale, sp1.x );
 487|  y1 = Scale3_toGY( scale, sp1.y );
 488|  xx = Scale3_toGX( scale, sp2.x );
 489|  yy = Scale3_toGY( scale, sp2.y );
 490|
 491|  Draw_line( draw, x1,y1, xx,yy, color );
 492|}
 493|
 494|#endif /* USES_SCALE3 */
 495|#endif /* USES_THREED2 */
 496|
 497|#ifdef USES_THREED2
 498|#ifdef USES_SCALE3
 499|
 500|/***********************************************************************
 501|*  15. <<< 3次元で線分を描く [Draw_line3d2()] >>>
 502|************************************************************************/
 503|void  Draw_line3d2( Draw* draw, ThreeD2_ViewL* viewp, Scale3* scale,
 504|  int x1, int y1, int z1,
 505|  int x2, int y2, int z2, int color )
 506|{
 507|  ThreeD2_XYZ  p1, p2;
 508|
 509|  p1.x = x1;  p1.y = y1;  p1.z = z1;
 510|  p2.x = x2;  p2.y = y2;  p2.z = z2;
 511|
 512|  Draw_line3dP2( draw, viewp, scale, &p1, &p2, color );
 513|}
 514|
 515|#endif /* USES_SCALE3 */
 516|#endif /* USES_THREED2 */
 517|
 518|#ifdef  USES_ASCII
 519|
 520|/**************************************************************************
 521|*  16. <<< ASCII 半角文字の表示 [Draw_ascii()] >>>
 522|*【引数】
 523|* ・char code;  文字 ASCII コード
 524|*【補足】
 525|*・半角文字は 8×16 pixel です。
 526|***************************************************************************/
 527|void  Draw_ascii( Draw* m, int x, int y, char code, int color )
 528|{
 529|  extern unsigned char asciidata[];
 530|  int  iCode, iCodeOver;
 531|  #define  fontWidth  8    /* 文字の横ピクセル数 */
 532|
 533|#if 0
 534|  /* クリッピング(1) */
 535|  if ( x <= Draw_getClipMinX(m) - fontWidth / 2 ||
 536|       x >  Draw_getClipMaxX(m) ||
 537|       y <= Draw_getClipMinY(m) - fontWidth ||
 538|       y >  Draw_getClipMaxY(m) )
 539|    return;
 540|#endif
 541|
 542|  /* 文字の一部でも表示画面よりはみ出たら表示しない */
 543|  if ( x < 0 || x + fontWidth -1 >= Draw_getWidth(m) ||
 544|       y < 0 || y + 15 >= Draw_getHeight(m) ) {
 545|    #ifdef Draw_ChkCharOut
 546|      #ifdef _CHECKER
 547|        #ifdef USES_WATCH
 548|          watch( 0, 0 );  watch( x, y );  watch_s( code, "ascii is out" );
 549|          brk( 1,1,0xFFFF, 0xFFFF, 1 );
 550|        #endif
 551|      #endif
 552|    #endif
 553|    return;
 554|  }
 555|
 556|  /* 表示 */
 557|  iCode = (unsigned char)code * 16;
 558|  iCodeOver = iCode + 16;
 559|  for ( iCode; iCode < iCodeOver; iCode ++ ) {
 560|    #ifdef _CHECKER
 561|      if ( Screen_getPixelPerByte(m) != 2 )  error();
 562|    #endif
 563|
 564|    Draw_psets( m, x, y, &asciidata[iCode], fontWidth, color );
 565|    y++;
 566|  }
 567|
 568|  #undef  fontWidth
 569|}
 570|#endif
 571|
 572|
 573|#ifdef  USES_JISDATA
 574|
 575|/**************************************************************************
 576|*  17. <<< JIS 漢字の表示 [Draw_jis()] >>>
 577|* ・code : 漢字 JIS コード
 578|***************************************************************************/
 579|void  Draw_jis( Draw* m, int x, int y, unsigned short code, int color )
 580|{
 581|  extern unsigned char jisdata[];
 582|  int  iCode, iCodeOver;
 583|  #define  fontWidth  16
 584|
 585|  /* 文字の一部でも表示画面よりはみ出たら表示しない */
 586|  if ( x < 0 || x + fontWidth -1 >= Draw_getWidth(m) ||
 587|       y < 0 || y + 15 >= Draw_getHeight(m) ) {
 588|    #ifdef Draw_ChkCharOut
 589|      #ifdef _CHECKER
 590|        watch( 0, 0 );  watch( x, y );  watch_s( code, "jis is out" );
 591|        brk( 1,1,0xFFFF, 0xFFFF, 1 );
 592|      #endif
 593|    #endif
 594|    return;
 595|  }
 596|
 597|  /* クリッピング(1) */
 598|#if 0
 599|  if ( m->sc == &DScreen_sc_Draw_Scr ) {
 600|    if ( x <= DScreen_getClipMinX(m) - fontWidth ||
 601|         x >  DScreen_getClipMaxX(m) ||
 602|         y <= DScreen_getClipMinY(m) - fontWidth ||
 603|         y >  DScreen_getClipMaxY(m) ) {
 604|      return;
 605|    }
 606|  }
 607|#endif
 608|
 609|  /* 表示 */
 610|  iCode = (code - 0x2120) * 32;
 611|  iCodeOver = iCode + 32;
 612|  for ( iCode; iCode < iCodeOver; iCode += 2 ) {
 613|    Draw_psets( m, x, y, &jisdata[iCode], fontWidth, color );
 614|    y++;
 615|  }
 616|
 617|  #undef  fontWidth
 618|}
 619|#endif
 620|
 621|
 622|#ifdef USES_MASK
 623|/**************************************************************************
 624|*  18. <<< 16×16のピクセル・パターンを描画する [Draw_pattern()] >>>
 625|*【引数】
 626|*  ・pattern : ピクセル・パターンが格納されているアドレス
 627|*【補足】
 628|*・ピクセル・パターンは 1bpp で 32byte 分、用意してください。
 629|*・たとえば、シンボルの表示に使います。
 630|***************************************************************************/
 631|void  Draw_pattern( Draw* m, int x, int y, char* pattern,
 632|  int color )
 633|{
 634|  char*  pattern_over = pattern + 32;
 635|  #define  fontWidth  16
 636|
 637|#if 0
 638|  /* クリッピング(1) */
 639|  if ( x <= Draw_getClipMinX(m) - fontWidth ||
 640|       x >  Draw_getClipMaxX(m) ||
 641|       y <= Draw_getClipMinY(m) - fontWidth ||
 642|       y >  Draw_getClipMaxY(m) )
 643|    return;
 644|#endif
 645|
 646|  /* 16×16のピクセル・パターンを描画する */
 647|  for ( pattern ; pattern < pattern_over; pattern += 2 ) {
 648|    Draw_psets( m, x, y, (unsigned char*)pattern, fontWidth, color );
 649|    y++;
 650|  }
 651|
 652|  #undef  fontWidth
 653|}
 654|#endif /* USES_MASK */
 655|
 656|
 657|/**************************************************************************
 658|*  19. <<< ペン(太い)[Draw_Pen...] >>>
 659|***************************************************************************/
 660|#ifdef USES_SCREEN
 661|int*  Draw_Pen_maru[9];
 662|/* penDataは [0] が x と y の数, [奇数]が x, [偶数]が y */
 663|static int penData_maru0[1] = { 0 };
 664|static int penData_maru1[3] = { 2, 0,0 };
 665|static int penData_maru2[9] = { 8, 0,0, 1,1, 0,1, 1,0 };
 666|static int penData_maru3[11]= { 10, 0,0, 1,0, -1,0, 0,1, 0,-1 };
 667|static int penData_maru4[25] =
 668| { 24, 0,0, 1,1, 0,1, 1,0,
 669|   0,-1, 1,-1, -1,0, 2,0, -1,1, 2,1, 0,2, 1,2 };
 670|static int penData_maru5[27] =
 671| { 26, 0,0, -1,0, 1,0, 0,-1, 0,1, -1,-1, 1,1, 1,-1, -1,1,
 672|   -2,0, 2,0, 0,-2, 0,2 };
 673|/*
 674|* # +#  #   ##    #
 675|*   ## #+# #+##  ###
 676|*       #  #### ##+##
 677|*           ##   ###
 678|*                 #
 679|*/
 680|
 681|static int penData_maru6[49] =
 682| { 48, 0,0, 1,1, 1,0, 0,1, -1,-1, -1,0, -1,1, -1,2,
 683|   0,-1, 0,2, 1,-1, 1,2, 2,-1, 2,0, 2,1, 2,2,
 684|   -2,0, -2,1, 0,-2, 0,3, 1,-2, 1,3, 3,0, 3,1  };
 685|/*
 686|*    ##
 687|*   ####
 688|*  ##+###
 689|*  ######
 690|*   ####
 691|*    ##
 692|*/
 693|
 694|static int penData_maru7[75] =
 695| { 74, 0,0, 1,1, 1,0, 0,1, -1,-1, -1,0, -1,1, -1,2,
 696|   0,-1, 0,2, 1,-1, 1,2, 2,-1, 2,0, 2,1, 2,2,
 697|   -2,0, -2,1, 0,-2, 0,3, 1,-2, 1,3, 3,0, 3,1,
 698|   -1,-3, 0,-3, 1,-3, -2,-2, -1,-2, 2,-2,
 699|   -3,-1, -2,-1, 3,-1, -3,0, -3,1, -2,2, -1,3  };
 700|/*
 701|*   ***
 702|*  **##*
 703|* **####*
 704|* *##+###
 705|* *######
 706|*  *####   *... 6 からの差分
 707|*   *##
 708|*/
 709|
 710|static int penData_maru8[81] =
 711| { 80, 0,0, 1,1, 1,0, 0,1, -1,-1, -1,0, -1,1, -1,2,
 712|   0,-1, 0,2, 1,-1, 1,2, 2,-1, 2,0, 2,1, 2,2,
 713|   -2,0, -2,1, 0,-2, 0,3, 1,-2, 1,3, 3,0, 3,1,
 714|   0,-3, 1,-3, -1,-2, 2,-2, -2,-1, 3,-1, -3,0, 4,0,
 715|   -3,1, 4,1, -2,2, 3,2, -1,3, 2,3, 0,4, 1,4 };
 716|/*
 717|*    **
 718|*   *##*
 719|*  *####*
 720|* *##+###*
 721|* *######*
 722|*  *####*   *... 6 からの差分
 723|*   *##*
 724|*    **
 725|*/
 726|
 727|/*
 728|*  初期化
 729|*/
 730|void  Draw_Pen_init()
 731|{
 732|  Draw_Pen_maru[0] = penData_maru0;
 733|  Draw_Pen_maru[1] = penData_maru1;
 734|  Draw_Pen_maru[2] = penData_maru2;
 735|  Draw_Pen_maru[3] = penData_maru3;
 736|  Draw_Pen_maru[4] = penData_maru4;
 737|  Draw_Pen_maru[5] = penData_maru5;
 738|  Draw_Pen_maru[6] = penData_maru6;
 739|  Draw_Pen_maru[7] = penData_maru7;
 740|  Draw_Pen_maru[8] = penData_maru8;
 741|}
 742|#endif /* USES_SCREEN */
 743|
 744|
 745|#ifdef USES_SCREEN
 746|#ifdef USES_MASK
 747|/**************************************************************************
 748|*  20. <<< Screen work 画面から Screen Active 画面へコピー [Draw_Scr_flushFromScreen()] >>>
 749|*  詳細は Screen_flushTo() を参照
 750|***************************************************************************/
 751|#undef  Draw_Scr_flushFromScreen
 752|void  Draw_Scr_flushFromScreen( Screen* work, Mask_A* mask,
 753|  int baseX, int baseY, int clipX )
 754|{
 755|  #ifdef _CHECHER
 756|    error();
 757|  #endif
 758|}
 759|
 760|#endif
 761|#endif
 762|
 763|#ifdef USES_DSCREEN
 764|
 765|/**************************************************************************
 766|*  21. <<< DScreen work 画面から Screen Active 画面へコピー [Draw_Scr_flushFromDScreen()] >>>
 767|*  引数の内容は DScreen_flushTo() を参照
 768|***************************************************************************/
 769|#undef  Draw_Scr_flushFromDScreen
 770|void  Draw_Scr_flushFromDScreen( DScreen* work, Mask_A* mask,
 771|  int baseX, int baseY, int clipX )
 772|{
 773|  #ifdef _CHECHER
 774|    error();
 775|  #endif
 776|}
 777|
 778|#endif
 779|
 780|/*************************************************************************
 781|*  22. <<< ベクトル成分 dx,dy から方向番号を取得する [Draw_getDirec()] >>>
 782|*
 783|*  
 784|*
 785|*【引数】
 786|*  ・int  dx,dy;    方向ベクトルの x,y 成分
 787|*  ・int  返り値;   方向番号
 788|*【補足】
 789|*・返り値は、全方向を8分割して、左上水平寄りの 0度〜 45度を0とします。
 790|*  以後、右回りに1〜7とします。(数学の一般角とは逆方向)
 791|*・この値は、|dx|(絶対値)と|dy| のうち、大きい方が dx なら、第1ビットが0、
 792|*  dy なら第1ビットが1になります。
 793|*・|dx|>|dy| の場合、dx がプラスなら第2ビットが0、マイナスなら1になり、
 794|*  dy がプラスなら第0ビットから第2ビットまでのうち値が1になっている数が
 795|*  奇数になります。
 796|*・|dx|<|dy| の場合、dy がプラスなら第2ビットが0、マイナスなら1になり、
 797|*  dx がプラスなら第0ビットから第2ビットまでのうち値が1になっている数が
 798|*  奇数になります。
 799|**************************************************************************/
 800|int  Draw_getDirec( int dx, int dy )
 801|{
 802|  if ( dx > 0 ) {
 803|    if ( dy < 0 ) {
 804|      if ( dx > -dy )  return  0;
 805|      else             return  7;
 806|    }
 807|    else {
 808|      if ( dx > dy )  return  1;
 809|      else            return  2;
 810|    }
 811|  }
 812|  else {
 813|    if ( dy < 0 ) {
 814|      if ( dx < dy )  return  5;
 815|      else            return  6;
 816|    }
 817|    else {
 818|      if ( -dx > dy )  return  4;
 819|      else             return  3;
 820|    }
 821|  }
 822|}
 823| 
 824|