SCREEN16.C

[目次 | 関数 | マクロ]

目次

関数一覧

マクロ一覧


   1|/***********************************************************************
   2|  1. <<< 16bpp グラフィック画面 (Screen16) >>> 
   3|************************************************************************/
   4|
   5|#include "mixer_precomp.h"  /* Auto precompiled header, Look at mixer-... folder */
   6|
   7|#include  <string.h>
   8|
   9|#define  STDLIBS_INCLUDE
  10|#define  STDLIBS_INCLUDE_STDIO_H
  11|#define  STDLIBS_INCLUDE_STRING_H
  12|#ifdef  USES_MXP_AUTOINC
  13| #include "screen16.ah"  /* Auto include header, Look at mixer-... folder */
  14|#endif
  15|
  16|
  17|
  18| 
  19|/*********************************************************************
  20|  2. <<< [Screen16_init] 初期化する >>> 
  21|【引数】
  22|  ・void*  adr;          バッファまたは VRAM の先頭アドレス
  23|  ・int    size;         adr のメモリサイズ
  24|  ・int  width, height;  画面のサイズ
  25|【補足】
  26|・adr には、グラフィックスのフレームバッファに割り当てられている、
  27|  仮想アドレスだけでなく、任意のメモリ領域を指定することができます。
  28|  グローバル変数に char 型の配列を宣言して、その先頭アドレスを
  29|  指定することもできます。
  30|・adr のバッファに必要なサイズは、width * height * 2 です。
  31|*********************************************************************/
  32|void  Screen16_init( Screen16* m, char* adr, int size,
  33|  int width, int height )
  34|{
  35|  ASSERT( size >= width * height * 2 );
  36|
  37|  m->adr = (char*)adr;
  38|  m->width = width;
  39|  m->height = height;
  40|
  41|  size;  /* avoid warning at Release version */
  42|}
  43|
  44|
  45| 
  46|/*********************************************************************
  47|  3. <<< [Screen16_print] デバッグ表示する >>> 
  48|*********************************************************************/
  49|#ifndef  ERRORS_CUT_DEBUG_TOOL
  50|void  Screen16_print( Screen16* m, const char* title )
  51|{
  52|  Errors_printf( "%sScreen16:  adr=%p, width=%d, height=%d, x+1=[%p], y+1=[%p]", title,
  53|    m->adr, m->width, m->height,
  54|    Screen16_pgetAdr( m, 1,0 ), Screen16_pgetAdr( m, 0,1 ) );
  55|}
  56|#endif
  57|
  58|
  59| 
  60|/*********************************************************************
  61|  4. <<< [Screen16_clear] 画面全体を指定した色でクリアする >>> 
  62|【補足】
  63|・深さ16 の Z バッファとして Screen16 を利用する場合、color には、
  64|  バッファに設定する Z値を指定してください。
  65|*********************************************************************/
  66|void  Screen16_clear( Screen16* m, int color )
  67|{
  68|  int*  p = (int*)m->adr;
  69|  int*  p_over = (int*)(m->adr + m->width * m->height * 2);
  70|
  71|  color = color | (color << 16 );
  72|
  73|  for ( ; p < p_over; p++ ) {
  74|    *p = color;
  75|  }
  76|}
  77|
  78|
  79| 
  80|/*********************************************************************
  81|  5. <<< [Screen16_pset_f] 点を描画する(関数版)>>> 
  82|【補足】
  83|・DrawScr インターフェイス用です。
  84|*********************************************************************/
  85|void  Screen16_pset_f( Screen16* m, int x, int y, int color )
  86|{
  87|  unsigned short*  p = (unsigned short*)Screen16_pgetAdr( m, x, y );
  88|
  89|  *p = (unsigned short)(unsigned int) color;
  90|}
  91|
  92|
  93| 
  94|/************************************************************************
  95|  6. <<< [Screen16_putZ] 画面を Z バッファとして Z 値を書き込む >>> 
  96|【引数】
  97|  ・int  返り値;  1=書き込んだ, 0=書き込まなかった
  98|【補足】
  99|・単に Z値を書き込むのではなく、Zバッファに格納されている値より、
 100|  引数の Z が小さい場合のみ書き込みます。
 101|*************************************************************************/
 102|int  Screen16_putZ( Screen16* m, int x, int y, int z )
 103|{
 104|  unsigned short*  p = (unsigned short*)Screen16_pgetAdr( m, x, y );
 105|
 106|  /*Errors_printf( "Z:[%p] (r=%d, w=%d)", p, (int)*p, z );*/
 107|
 108|  if ( z < (int)*p ) {
 109|    *p = (unsigned short)(unsigned int) z;
 110|    return  1;
 111|  }
 112|  else
 113|    return  0;
 114|}
 115|
 116|
 117| 
 118|/***********************************************************************
 119|  7. <<< [Screen16_line] 直線を描画する >>> 
 120|【引数】
 121|  ・int x1, y1;  直線の端点1のグラフィック座標
 122|  ・int x2, y2;  直線の端点2のグラフィック座標
 123|  ・int  color;  色(16bpp表現)
 124|************************************************************************/
 125|void  Screen16_line( Screen16* m, int x1, int y1, int x2, int y2, int color )
 126|{
 127|  int    x,y;
 128|  int    dx = x2 - x1;
 129|  int    dy = y2 - y1;
 130|
 131|  if ( dx >= 0 ) {
 132|    if ( dy >= 0 ) {
 133|      if ( dx >= dy ) {  /* RIGHT DOWN */
 134|        int  plus = dy * 2;
 135|        int  cup = plus - dx;
 136|        int  minus = cup - dx;
 137|
 138|        y = y1;
 139|        for ( x = x1; x <= x2; x++ ) {
 140|          Screen16_pset_m( m, x, y, color );
 141|          if ( cup >= 0 )  { y++;  cup += minus; }
 142|          else                     cup += plus;
 143|        }
 144|      }
 145|      else {  /* DOWN RIGHT */
 146|        int  plus = dx * 2;
 147|        int  cup = plus - dy;
 148|        int  minus = cup - dy;
 149|
 150|        x = x1;
 151|        for ( y = y1; y <= y2; y++ ) {
 152|          Screen16_pset_m( m, x, y, color );
 153|          if ( cup >= 0 )  { x++;  cup += minus; }
 154|          else                     cup += plus;
 155|        }
 156|      }
 157|    }
 158|    else { /* dy < 0 */
 159|      if ( dx >= -dy ) {  /* RIGHT UP */
 160|        int  plus = -dy * 2;
 161|        int  cup = plus - dx;
 162|        int  minus = cup - dx;
 163|
 164|        y = y1;
 165|        for ( x = x1; x <= x2; x++ ) {
 166|          Screen16_pset_m( m, x, y, color );
 167|          if ( cup >= 0 )  { y--;  cup += minus; }
 168|          else                     cup += plus;
 169|        }
 170|      }
 171|      else {  /* UP RIGHT */
 172|        int  plus = dx * 2;
 173|        int  cup = plus + dy;
 174|        int  minus = cup + dy;
 175|
 176|        x = x1;
 177|        for ( y = y1; y >= y2; y-- ) {
 178|          Screen16_pset_m( m, x, y, color );
 179|          if ( cup >= 0 )  { x++;  cup += minus; }
 180|          else                     cup += plus;
 181|        }
 182|      }
 183|    }
 184|  }
 185|  else { /* dx < 0 */
 186|    if ( dy >= 0 ) {
 187|      if ( -dx >= dy ) {  /* LEFT DOWN */
 188|        int  plus = dy * 2;
 189|        int  cup = plus + dx;
 190|        int  minus = cup + dx;
 191|
 192|        y = y1;
 193|        for ( x = x1; x >= x2; x-- ) {
 194|          Screen16_pset_m( m, x, y, color );
 195|          if ( cup >= 0 )  { y++;  cup += minus; }
 196|          else                     cup += plus;
 197|        }
 198|      }
 199|      else {  /* DOWN LEFT */
 200|        int  plus = -dx * 2;
 201|        int  cup = plus - dy;
 202|        int  minus = cup - dy;
 203|
 204|        x = x1;
 205|        for ( y = y1; y <= y2; y++ ) {
 206|          Screen16_pset_m( m, x, y, color );
 207|          if ( cup >= 0 )  { x--;  cup += minus; }
 208|          else                     cup += plus;
 209|        }
 210|      }
 211|    }
 212|    else { /* dy < 0 */
 213|      if ( dx < dy ) {  /* LEFT UP */
 214|        int  plus = -dy * 2;
 215|        int  cup = plus + dx;
 216|        int  minus = cup + dx;
 217|
 218|        y = y1;
 219|        for ( x = x1; x >= x2; x-- ) {
 220|          Screen16_pset_m( m, x, y, color );
 221|          if ( cup >= 0 )  { y--;  cup += minus; }
 222|          else                     cup += plus;
 223|        }
 224|      }
 225|      else {  /* UP LEFT */
 226|        int  plus = -dx * 2;
 227|        int  cup = plus + dy;
 228|        int  minus = cup + dy;
 229|
 230|        x = x1;
 231|        for ( y = y1; y >= y2; y-- ) {
 232|          Screen16_pset_m( m, x, y, color );
 233|          if ( cup >= 0 )  { x--;  cup += minus; }
 234|          else                     cup += plus;
 235|        }
 236|      }
 237|    }
 238|  }
 239|}
 240|
 241| 
 242|/***********************************************************************
 243|  8. <<< [Screen16_pline] 破線を描画する >>> 
 244|【引数】
 245|  ・Screen16*  m;    8bpp グラフィック画面;
 246|  ・int  x1,y1,x2,y2;  破線の座標
 247|  ・int  color;        色
 248|  ・void*  pattern;    破線のパターン(モノクロ、リトルエンディアン)
 249|  ・int    nPixel;     pattern のビット数
 250|  ・int  iStartPixel;  最初に参照するパターンのピクセル番号(0〜 nPixel-1 )
 251|【補足】
 252|・パターンのピクセル番号は、下位のビットから0、1、2... です。
 253|************************************************************************/
 254|/* sub routine */
 255|/* int  getPat( void* pattern, int iPixel ); */
 256|#define  getPat( pattern, iPixel ) \
 257|  (*( (int*)(pattern) + (iPixel) / (8*sizeof(int)) ))
 258|
 259|/* void  nextPat( int* pat_adr, int* iPixel_adr, void* pattern, int nPixel ); */
 260|#define  nextPat( pat_adr, iPixel_adr, nPixel, pattern ) \
 261|{ \
 262|  (*(pat_adr)) >>= 1;  (*(iPixel_adr)) ++; \
 263|  if ( *(iPixel_adr) == (nPixel) ) \
 264|    { *(iPixel_adr) = 0;  *(pat_adr) = *(int*)(pattern); } \
 265|  else if ( *(iPixel_adr) % (8*sizeof(int)) == 0 ) \
 266|    *(pat_adr) = getPat( pattern, *(iPixel_adr) ); \
 267|}
 268|
 269|/* main routine */
 270|void  Screen16_pline( Screen16* m, int x1, int y1, int x2, int y2, int color,
 271|  void* pattern, int nPixel, int* iStartPixel )
 272|{
 273|  int    x,y;
 274|  int    dx = x2 - x1;
 275|  int    dy = y2 - y1;
 276|  int    iPixel;  /* ピクセル番号 */
 277|  int    pat;    /* パターン 32bit 分をピクセル番号分だけ右シフトしたもの */
 278|
 279|  /* 参照するパターンを初期化する */
 280|  iPixel = *iStartPixel;
 281|  pat = getPat( pattern, iPixel );
 282|  pat >>= (iPixel % (8*sizeof(int)));
 283|
 284|  /* 破線を描画する */
 285|  if ( dx >= 0 ) {
 286|    if ( dy >= 0 ) {
 287|      if ( dx >= dy ) {  /* RIGHT DOWN */
 288|        int  plus = dy * 2;
 289|        int  cup = plus - dx;
 290|        int  minus = cup - dx;
 291|
 292|        y = y1;
 293|        for ( x = x1; x <= x2; x++ ) {
 294|          if ( pat & 1 )
 295|            Screen16_pset_m( m, x, y, color );
 296|          if ( cup >= 0 )  { y++;  cup += minus; }
 297|          else                     cup += plus;
 298|          nextPat( &pat, &iPixel, nPixel, pattern );
 299|        }
 300|      }
 301|      else {  /* DOWN RIGHT */
 302|        int  plus = dx * 2;
 303|        int  cup = plus - dy;
 304|        int  minus = cup - dy;
 305|
 306|        x = x1;
 307|        for ( y = y1; y <= y2; y++ ) {
 308|          if ( pat & 1 )
 309|            Screen16_pset_m( m, x, y, color );
 310|          if ( cup >= 0 )  { x++;  cup += minus; }
 311|          else                     cup += plus;
 312|          nextPat( &pat, &iPixel, nPixel, pattern );
 313|        }
 314|      }
 315|    }
 316|    else { /* dy < 0 */
 317|      if ( dx >= -dy ) {  /* RIGHT UP */
 318|        int  plus = -dy * 2;
 319|        int  cup = plus - dx;
 320|        int  minus = cup - dx;
 321|
 322|        y = y1;
 323|        for ( x = x1; x <= x2; x++ ) {
 324|          if ( pat & 1 )
 325|            Screen16_pset_m( m, x, y, color );
 326|          if ( cup >= 0 )  { y--;  cup += minus; }
 327|          else                     cup += plus;
 328|          nextPat( &pat, &iPixel, nPixel, pattern );
 329|        }
 330|      }
 331|      else {  /* UP RIGHT */
 332|        int  plus = dx * 2;
 333|        int  cup = plus + dy;
 334|        int  minus = cup + dy;
 335|
 336|        x = x1;
 337|        for ( y = y1; y >= y2; y-- ) {
 338|          if ( pat & 1 )
 339|            Screen16_pset_m( m, x, y, color );
 340|          if ( cup >= 0 )  { x++;  cup += minus; }
 341|          else                     cup += plus;
 342|          nextPat( &pat, &iPixel, nPixel, pattern );
 343|        }
 344|      }
 345|    }
 346|  }
 347|  else { /* dx < 0 */
 348|    if ( dy >= 0 ) {
 349|      if ( -dx >= dy ) {  /* LEFT DOWN */
 350|        int  plus = dy * 2;
 351|        int  cup = plus + dx;
 352|        int  minus = cup + dx;
 353|
 354|        y = y1;
 355|        for ( x = x1; x >= x2; x-- ) {
 356|          if ( pat & 1 )
 357|            Screen16_pset_m( m, x, y, color );
 358|          if ( cup >= 0 )  { y++;  cup += minus; }
 359|          else                     cup += plus;
 360|          nextPat( &pat, &iPixel, nPixel, pattern );
 361|        }
 362|      }
 363|      else {  /* DOWN LEFT */
 364|        int  plus = -dx * 2;
 365|        int  cup = plus - dy;
 366|        int  minus = cup - dy;
 367|
 368|        x = x1;
 369|        for ( y = y1; y <= y2; y++ ) {
 370|          if ( pat & 1 )
 371|            Screen16_pset_m( m, x, y, color );
 372|          if ( cup >= 0 )  { x--;  cup += minus; }
 373|          else                     cup += plus;
 374|          nextPat( &pat, &iPixel, nPixel, pattern );
 375|        }
 376|      }
 377|    }
 378|    else { /* dy < 0 */
 379|      if ( dx < dy ) {  /* LEFT UP */
 380|        int  plus = -dy * 2;
 381|        int  cup = plus + dx;
 382|        int  minus = cup + dx;
 383|
 384|        y = y1;
 385|        for ( x = x1; x >= x2; x-- ) {
 386|          if ( pat & 1 )
 387|            Screen16_pset_m( m, x, y, color );
 388|          if ( cup >= 0 )  { y--;  cup += minus; }
 389|          else                     cup += plus;
 390|          nextPat( &pat, &iPixel, nPixel, pattern );
 391|        }
 392|      }
 393|      else {  /* UP LEFT */
 394|        int  plus = -dx * 2;
 395|        int  cup = plus + dy;
 396|        int  minus = cup + dy;
 397|
 398|        x = x1;
 399|        for ( y = y1; y >= y2; y-- ) {
 400|          if ( pat & 1 )
 401|            Screen16_pset_m( m, x, y, color );
 402|          if ( cup >= 0 )  { x--;  cup += minus; }
 403|          else                     cup += plus;
 404|          nextPat( &pat, &iPixel, nPixel, pattern );
 405|        }
 406|      }
 407|    }
 408|  }
 409|  *iStartPixel = iPixel;
 410|}
 411|
 412|#undef  getPat
 413|#undef  nextPat
 414| 
 415|/***********************************************************************
 416|  9. <<< [Screen16_drawImg] RGB データを画面に表示する・転送する >>> 
 417|【引数】
 418|  ・char*  img_adr;               RGB データの先頭アドレス
 419|  ・int  img_width, img_height;   RGB データの大きさ
 420|  ・int  this_x, this_y;          表示位置(RGB データの左上座標)
 421|【補足】
 422|・任意のアドレスに格納されている RGB データを Screen16 のフレームバッファに
 423|  転送します。
 424|・RGB データは、フレームバッファと同じ構造にしてください。
 425|・img_width が奇数の場合、各行のいちばん左のアドレスが4の倍数になるように
 426|  RGB データをパディングしてください。(各行のいちばん右の RGB データの次に
 427|  1ピクセル分ダミーを入れる。)
 428|************************************************************************/
 429|void  Screen16_drawImg( Screen16* m, char* img_adr,
 430|  int img_width, int img_height, int this_x, int this_y )
 431|{
 432|  int  x,y;
 433|  int*  p;
 434|  int   plus;
 435|  bool  bLast;
 436|  int*  p2 = (int*)img_adr;
 437|
 438|  #if ERRORS_DEBUG_FALSE
 439|  if ( Errors_count >= Errors_count0 ) {
 440|    Errors_printf( "Screen16_drawImg()" );
 441|    Screen16_print( m );
 442|    Errors_printf( "img: adr=%p, width=%d, height=%d",
 443|      img_adr, img_width, img_height );
 444|    Errors_printf( "this_x=%d, this_y=%d", this_x, this_y );
 445|  }
 446|  #endif
 447|
 448|  ASSERT( this_x >= 0 );
 449|  ASSERT( this_y >= 0 );
 450|  ASSERT( this_x % 4 == 0 );
 451|  ASSERT( this_y <= m->height );
 452|  #ifndef  NDEBUG
 453|    if ( this_x > m->width ) {
 454|      error2_3( Screen16_Err_WidthOver,
 455|        "イメージの右端が画面から外れます Img.x=%d, Img.w=%d, Scr.w=%d",
 456|        this_x, img_width, m->width );
 457|    }
 458|  #endif
 459|
 460|  p = (int*)Screen16_pgetAdr( m, this_x, this_y );
 461|  plus = (m->width - img_width) / 2;
 462|  bLast = ( img_width & 1 );
 463|
 464|  if ( bLast ) {
 465|    for ( y = 0; y < img_height; y++ ) {  /* 水平線の集合 */
 466|      if ( y >= m->height - this_x )  break;
 467|      for ( x = 2; x <= img_width; x+=2 ){  /* 32bit の集合 */
 468|        if ( x <= m->width - this_x )  *p = *p2;
 469|        p++;  p2++;
 470|      }
 471|
 472|      /* 最後のワード境界に描画する */
 473|      *p = ( *p2 & 0xFFFF ) | ( *p & 0xFFFF0000 );
 474|      p++;  p2++;
 475|
 476|      p += plus;   /* char* 型で加算したほうが高速 */
 477|    }
 478|  }
 479|  else {
 480|    for ( y = 0; y < img_height; y++ ) {  /* 水平線の集合 */
 481|      if ( y >= m->height - this_y )  break;
 482|      for ( x = 2; x <= img_width; x+=2 ){  /* 32bit の集合 */
 483|        if ( x <= m->width - this_x )  *p = *p2;
 484|        p++;  p2++;
 485|      }
 486|      p += plus;   /* char* 型で加算したほうが高速 */
 487|    }
 488|  }
 489|}
 490|
 491|
 492| 
 493|/***********************************************************************
 494|  10. <<< [Screen16_drawImgTile] RGB データを画面にタイル表示する >>> 
 495|【引数】
 496|  ・char*  img_adr;               RGB データの先頭アドレス
 497|  ・int  img_width, img_height;   RGB データの大きさ
 498|************************************************************************/
 499|void  Screen16_drawImgTile( Screen16* m, char* img_adr,
 500|  int img_width, int img_height )
 501|{
 502|  int  x, y;
 503|  int  plusX = (img_width + 3) & 0xFFFFFFFC;
 504|  int  plusY = img_height;
 505|
 506|  for ( y = 0; y < m->height; y += plusY ) {
 507|    for ( x = 0; x < m->width; x += plusX ) {
 508|      Screen16_drawImg( m, img_adr, img_width, img_height, x, y );
 509|    }
 510|  }
 511|}
 512| 
 513|/***********************************************************************
 514|  11. <<< [Screen16_writeBmpFile] ビットマップ・ファイルに出力する >>> 
 515|【引数】
 516|  ・char*  path;  ビットマップ・ファイルのパス
 517|  ・int  x, y;    出力する矩形範囲の左上座標
 518|  ・int  w, h;    出力する矩形範囲の幅と高さ
 519|【補足】
 520|・Windows 標準のビットマップファイルを作成します。
 521|************************************************************************/
 522|void  Screen16_writeBmpFile( Screen16* m, int x, int y, int w, int h );
 523|
 524| 
 525|/***********************************************************************
 526|  12. <<< [Screen16_outBmp] 16bpp を任意の bpp に変換する >>> 
 527|【引数】
 528|  ・char*  buf;          フレームバッファの先頭アドレス
 529|  ・int   width,height;  buf の幅と高さ(ピクセル数)
 530|  ・int   bpp;           buf の BPP(BitParPixel)
 531|【補足】
 532|・bpp は、8,15,16,24 のうちどれかを指定します。
 533|・bpp が 8 の場合、R3G3B2 とします。bpp が 15 の場合、R5G5B5 とします。
 534|************************************************************************/
 535|#ifdef  USES_COLOR
 536|void  Screen16_outBmp( Screen16* m, char* buf, int width, int height,
 537|  int bpp )
 538|{
 539|  int  x,y,c;
 540|
 541|  ASSERT( bpp == 8 || bpp == 15 || bpp == 16 || bpp == 24 || bpp == 32 );
 542|
 543|  if ( bpp == 8 ) {
 544|    for ( y = 0; y < height; y++ ) {
 545|      for ( x = 0; x < width; x++ ) {
 546|        c = Screen16_pget( m, x, y );
 547|        ((char*)buf)[x+y*width] = Color_RGB16_getRGB8( c );
 548|      }
 549|    }
 550|  }
 551|  if ( bpp == 15 ) {
 552|    for ( y = 0; y < height; y++ ) {
 553|      for ( x = 0; x < width; x++ ) {
 554|        c = Screen16_pget( m, x, y );
 555|        ((short*)buf)[x+y*width] = Color_RGB16_getRGB15( c );
 556|      }
 557|    }
 558|  }
 559|  if ( bpp == 16 ) {
 560|    for ( y = 0; y < height; y++ ) {
 561|      for ( x = 0; x < width; x++ ) {
 562|        c = Screen16_pget( m, x, y );
 563|        ((short*)buf)[x+y*width] = c;
 564|      }
 565|    }
 566|  }
 567|  if ( bpp == 24 ) {
 568|    for ( y = 0; y < height; y++ ) {
 569|      for ( x = 0; x < width; x++ ) {
 570|        c = Screen16_pget( m, x, y );
 571|        ((char*)buf)[(x+y*width)*3+0] = Color_RGB16_getB8( c );
 572|        ((char*)buf)[(x+y*width)*3+1] = Color_RGB16_getG8( c );
 573|        ((char*)buf)[(x+y*width)*3+2] = Color_RGB16_getR8( c );
 574|      }
 575|    }
 576|  }
 577|  if ( bpp == 32 ) {
 578|    for ( y = 0; y < height; y++ ) {
 579|      for ( x = 0; x < width; x++ ) {
 580|        c = Screen16_pget( m, x, y );
 581|        ((char*)buf)[(x+y*width)*4+0] = Color_RGB16_getB8( c );
 582|        ((char*)buf)[(x+y*width)*4+1] = Color_RGB16_getG8( c );
 583|        ((char*)buf)[(x+y*width)*4+2] = Color_RGB16_getR8( c );
 584|      }
 585|    }
 586|  }
 587|}
 588|#endif
 589|
 590| 
 591|/***********************************************************************
 592|  13. <<< [Screen16_isEqualFRB] フレームバッファの内容が同じか判断する >>> 
 593|************************************************************************/
 594|bool  Screen16_isEqualFRB( Screen16* a, Screen16* b )
 595|{
 596|  ASSERT( a->width == b->width );
 597|  ASSERT( a->height == b->height );
 598|
 599|  #ifdef  FOR_NSTD
 600|    return  StdX_memcmp( a->adr, b->adr, a->width * a->height * 2 ) == 0;
 601|  #else
 602|    return  memcmp( a->adr, b->adr, a->width * a->height * 2 ) == 0;
 603|  #endif
 604|}
 605|
 606|
 607|
 608| 
 609|/*************************************************************************
 610|  14. <<< [Screen16_paintByMMPaint] ポリゴンを単色で塗りつぶす >>> 
 611|**************************************************************************/
 612|#ifdef USES_MMPAINT
 613|#ifdef USES_MASK
 614|#ifdef USES_TYPEX
 615|void  Screen16_paintByMMPaint( Screen16* m, MMPaint* paint, int color )
 616|{
 617|  #define  PixelPer32Bit  2
 618|  int  y, ymin, ymax;
 619|  UINT32 *p, *p2;                 /* フレームバッファへのポインタ */
 620|  UINT32* p_x0;                                /* X座標が 0 の p */
 621|  UINT32  colorMask = Mask_getColors16bit(color);    /* 色のマスク */
 622|  int  add = m->width / 16;  /*1つ下の Y 座標のバッファ・アドレスの差分 */
 623|
 624|  ASSERT( m->width % PixelPer32Bit == 0 );
 625|
 626|  /* paint がクリアされていたら、何もしないで関数を抜ける */
 627|  if ( MMPaint_isNoBound( paint ) )  return;
 628|
 629|  /* 変数の初期化 */
 630|  ymin = paint->ymin;
 631|  ymax = paint->ymax;
 632|
 633|  /* 塗りつぶす */
 634|  p = (UINT32*)Screen16_pgetAdr( m, 0, ymin );
 635|  p_x0 = p;
 636|  for ( y = ymin; y <= ymax; y++ ) {  /* 水平線の集合 */
 637|    UINT32  pixelMask;
 638|    int  xmin, xmax;
 639|
 640|    /* 変数の初期化 */
 641|    xmin = paint->xmin[y-ymin];
 642|    xmax = paint->xmax[y-ymin];
 643|
 644|    /* 左端と右端を塗る */
 645|    p = p_x0 + xmin / PixelPer32Bit;
 646|    p2 = p_x0 + xmax / PixelPer32Bit;
 647|    if ( p == p2 ) {
 648|      pixelMask = Mask_leftEnd_for16bpp[xmin & 0x01] &
 649|                  Mask_rightEnd_for16bpp[xmax & 0x01];
 650|      *p = (pixelMask & colorMask) | (~pixelMask & *p);
 651|    }
 652|    else if ( p < p2 ) {
 653|      pixelMask = Mask_leftEnd_for16bpp[xmin & 0x01];
 654|      *p = (pixelMask & colorMask) | (~pixelMask & *p);
 655|      pixelMask = Mask_rightEnd_for16bpp[xmax & 0x01];
 656|      *p2 = (pixelMask & colorMask) | (~pixelMask & *p2);
 657|
 658|      /* 32bit 単位で間を水平に塗りつぶす */
 659|      for ( p = p+1;  p < p2;  p++ )
 660|        *p = colorMask;
 661|    }
 662|
 663|    p_x0 += add;
 664|  }
 665|  #undef  PixelPer32Bit
 666|}
 667|#endif /* USES_TYPEX */
 668|#endif /* USES_MMPAINT */
 669|#endif /* USES_MASK */
 670| 
 671|/*************************************************************************
 672|  15. <<< [Screen16_psetForCircle] 円描画用の点描画コールバック関数 >>> 
 673|【補足】
 674|・参照:Draw2_circle 関数
 675|**************************************************************************/
 676|#ifdef USES_DRAW2
 677|void  Screen16_psetForCircle( void* obj, int cx, int cy, int d1, int d2 )
 678|{
 679|  Screen16_C*  m = (Screen16_C*)obj;
 680|
 681|  #if  ERRORS_DEBUG_FALSE
 682|    Errors_printf( "Screen16_psetForCircle: %p, (cx,cy)=(%d,%d), (d1,d2)=(%d,%d)",
 683|      m, cx, cy, d1, d2 );
 684|  #endif
 685|
 686|  Screen16_pset( &m->scr, cx+d2, cy+d1, m->color1 );  /* 右下 */
 687|  Screen16_pset( &m->scr, cx+d2, cy-d1, m->color1 );  /* 右上 */
 688|  Screen16_pset( &m->scr, cx+d1, cy+d2, m->color1 );  /* 下右 */
 689|  Screen16_pset( &m->scr, cx-d1, cy+d2, m->color1 );  /* 下左 */
 690|
 691|  Screen16_pset( &m->scr, cx-d2, cy+d1, m->color1 );  /* 左下 */
 692|  Screen16_pset( &m->scr, cx-d2, cx-d1, m->color1 );  /* 左上 */
 693|  Screen16_pset( &m->scr, cx+d1, cx-d2, m->color1 );  /* 上右 */
 694|  Screen16_pset( &m->scr, cx-d1, cx-d2, m->color1 );  /* 上左 */
 695|}
 696|#endif
 697|
 698| 
 699|/*************************************************************************
 700|  16. <<< [Screen16_psetForEllipse] 楕円描画用の点描画コールバック関数 >>> 
 701|【補足】
 702|・参照:Draw2_circle 関数
 703|**************************************************************************/
 704|#ifdef USES_DRAW2
 705|void  Screen16_psetForEllipse( void* obj, int cx, int cy, int d1, int d2 )
 706|{
 707|  Screen16_C*  m = (Screen16_C*)obj;
 708|
 709|  #if  ERRORS_DEBUG_FALSE
 710|    Errors_printf( "Screen16_psetForCircle: %p, (cx,cy)=(%d,%d), (d1,d2)=(%d,%d)",
 711|      m, cx, cy, d1, d2 );
 712|  #endif
 713|
 714|  Screen16_pset( &m->scr, cx+d1, cy+d2, m->color1 );  /* 右下 */
 715|  Screen16_pset( &m->scr, cx-d1, cy+d2, m->color1 );  /* 左下 */
 716|
 717|  Screen16_pset( &m->scr, cx+d1, cx-d2, m->color1 );  /* 右上 */
 718|  Screen16_pset( &m->scr, cx-d1, cx-d2, m->color1 );  /* 左上 */
 719|}
 720|#endif
 721| 
 722|/***********************************************************************
 723|  17. <<< [Screen16_drawPolyByDDA] DDA 機能を用いてポリゴンを描画する >>> 
 724|【引数】
 725|  ・Screen16*  screen;      描画対象画面
 726|  ・Screen16*  zbuf;        Zバッファ
 727|  ・MMPaint2*  poly;       ポリゴンデータ
 728|【補足】
 729|・必要に応じて、screen や zbuf をクリアしてから呼び出してください。
 730|************************************************************************/
 731|#ifdef USES_MMPAINT2
 732|#ifdef USES_D54SOFT
 733|void  Screen16_drawPolyByDDA( Screen16* screen, Screen16* zbuf,
 734|  MMPaint2* poly )
 735|{
 736|  int  r;
 737|  D54Soft_DDA16  dda;
 738|  MMPaint2_Point*  left = MMPaint2_getLeftPoint(poly);
 739|  MMPaint2_Point*  right = MMPaint2_getRightPoint(poly);
 740|  int  dx;
 741|  int  start_r, delta_r;  /* DDAの赤色の開始番号と差分番号(固定小数)*/
 742|  int  start_g, delta_g;  /* DDAの緑色の開始番号と差分番号(固定小数)*/
 743|  int  start_b, delta_b;  /* DDAの青色の開始番号と差分番号(固定小数)*/
 744|  int  start_z, delta_z, delta_z_dec;  /* 同、Z 値, dec=小数 */
 745|
 746|  D54Soft_DDA16_init( &dda, screen, zbuf );
 747|
 748|  /* 水平線をいくつも塗って、全体としてポリゴンを塗る */
 749|  for( r = 0; ; ) {  /* 水平線の集合 */
 750|
 751|    /* DDA のパラメータを計算する */
 752|    dx = right->x - left->x;
 753|    start_r = left->r;  /* delta_r のため後でシフトする */
 754|    start_g = left->g;
 755|    start_b = left->b;
 756|    start_z = left->z;
 757|    if ( dx != 0 ) {
 758|      delta_r = (( right->r - start_r ) << D54R_DLR_SFT) / dx;
 759|      delta_g = (( right->g - start_g ) << D54R_DLG_SFT) / dx;
 760|      delta_b = (( right->b - start_b ) << D54R_DLB_SFT) / dx;
 761|      if ( right->z < left->z )
 762|        delta_z = -(left->z - right->z + dx - 1) / dx;
 763|      else
 764|        delta_z = (right->z - left->z) / dx;
 765|      delta_z_dec = ( ((right->z - left->z) << 16) /dx ) << 16;
 766|      delta_z_dec += 0x8000;  /* 四捨五入 */
 767|    }
 768|    start_r <<= D54R_CRS_SFT;
 769|    start_g <<= D54R_CGS_SFT;
 770|    start_b <<= D54R_CBS_SFT;
 771|
 772|    /* DDA 機能を起動する */
 773|    D54Soft_DDA16_runFor3D( &dda, left->x, right->x, left->y,
 774|      start_r, delta_r, start_g, delta_g, start_b, delta_b,
 775|      start_z, 0, delta_z, delta_z_dec );
 776|
 777|    if ( r != 0 )  break;  /* 最後の水平線を塗ってから抜ける */
 778|
 779|    /* 水平線を1ピクセル下にする */
 780|    r = MMPaint2_nextLine( poly );
 781|  }
 782|}
 783|#endif  /* USES_D54SOFT */
 784|#endif  /* USES_MMPAINT2 */
 785|
 786|
 787| 
 788|/***********************************************************************
 789|  18. <<< [Screen16_drawPolyByDDA_V] DDA 機能を用いてポリゴンを描画する >>> 
 790|【引数】
 791|  ・Screen16*  screen;      描画対象画面
 792|  ・Screen16*  zbuf;        Zバッファ
 793|  ・MMPaint2_V*  poly;     ポリゴンデータ
 794|【補足】
 795|・内部で使用する D54Soft_DDA16_runFor3D_V が無いため
 796|  使用できません。
 797|・Screen16_drawPolyByDDA との違いは、poly の型です。
 798|************************************************************************/
 799|#ifdef USES_MMPAINT2
 800|#ifdef USES_D54SOFT
 801|#if 0
 802|void  Screen16_drawPolyByDDA_V( Screen16* screen, Screen16* zbuf,
 803|  MMPaint2_V* poly )
 804|{
 805|  int  r;
 806|  D54Soft_DDA16  dda;
 807|  MMPaint2_Point*  top = MMPaint2_V_getTopPoint(poly);
 808|  MMPaint2_Point*  bottom = MMPaint2_V_getBottomPoint(poly);
 809|  int  dy;
 810|  int  start_r, delta_r;  /* DDAの赤色の開始番号と差分番号(固定小数)*/
 811|  int  start_g, delta_g;  /* DDAの緑色の開始番号と差分番号(固定小数)*/
 812|  int  start_b, delta_b;  /* DDAの青色の開始番号と差分番号(固定小数)*/
 813|  int  start_z, delta_z, delta_z_dec;  /* 同、Z 値, dec=小数 */
 814|
 815|  D54Soft_DDA16_init( &dda, screen, zbuf );
 816|
 817|  /* 水平線をいくつも塗って、全体としてポリゴンを塗る */
 818|  for( r = 0; ; ) {  /* 水平線の集合 */
 819|
 820|    /* DDA のパラメータを計算する */
 821|    dy = bottom->y - top->y;
 822|    start_r = top->r;  /* delta_r のため後でシフトする */
 823|    start_g = top->g;
 824|    start_b = top->b;
 825|    start_z = top->z;
 826|    if ( dy != 0 ) {
 827|      delta_r = (( bottom->r - start_r ) << D54R_DLR_SFT) / dy;
 828|      delta_g = (( bottom->g - start_g ) << D54R_DLG_SFT) / dy;
 829|      delta_b = (( bottom->b - start_b ) << D54R_DLB_SFT) / dy;
 830|      if ( bottom->z < top->z )
 831|        delta_z = -(top->z - bottom->z + dy - 1) / dy;
 832|      else
 833|        delta_z = (bottom->z - top->z) / dy;
 834|      delta_z_dec = ( ((bottom->z - top->z) << 16) /dy ) << 16;
 835|      delta_z_dec += 0x8000;  /* 四捨五入 */
 836|    }
 837|    start_r <<= D54R_CRS_SFT;
 838|    start_g <<= D54R_CGS_SFT;
 839|    start_b <<= D54R_CBS_SFT;
 840|
 841|    /* DDA 機能を起動する */
 842|    D54Soft_DDA16_runFor3D_V( &dda, top->x, top->y, bottom->y,
 843|      start_r, delta_r, start_g, delta_g, start_b, delta_b,
 844|      start_z, 0, delta_z, delta_z_dec );
 845|
 846|    if ( r != 0 )  break;  /* 最後の水平線を塗ってから抜ける */
 847|
 848|    /* 水平線を1ピクセル下にする */
 849|    r = MMPaint2_V_nextLine( poly );
 850|  }
 851|}
 852|#endif
 853|#endif  /* USES_D54SOFT */
 854|#endif  /* USES_MMPAINT2 */
 855|
 856|
 857| 
 858|/***********************************************************************
 859|  19. <<< [Screen16_inf_DrawScr] DrawScr インターフェイス >>> 
 860|************************************************************************/
 861|#ifdef USES_DRAWSCR
 862|INF_SUB_FUNC( Screen16, DrawScr, Screen16_by_DrawScr )
 863|
 864|DrawScr  Screen16_inf_DrawScr( Screen16* m )
 865|{
 866|  INF_SUB_SC_START( Screen16, DrawScr );
 867|  INF_SUB_SC_METHOD_NULL( Screen16,getWidth )
 868|  INF_SUB_SC_METHOD_NULL( Screen16,getHeight )
 869|  INF_SUB_SC_METHOD_NULL( Screen16,getExAdr )
 870|  INF_SUB_SC_METHOD_NULL( Screen16,getExVectors )
 871|  INF_SUB_SC_METHOD_1( Screen16,clear, void, Screen16_clear, Screen16*,int )
 872|  INF_SUB_SC_METHOD_3( Screen16,pset, void, Screen16_pset_f, Screen16*,int,int,int )
 873|  INF_SUB_SC_METHOD_NULL( Screen16,exPset )
 874|  INF_SUB_SC_METHOD_NULL( Screen16,psetXor )
 875|  #ifdef USES_MASK
 876|  INF_SUB_SC_METHOD_NULL( Screen16,psets )
 877|  #endif
 878|  INF_SUB_SC_METHOD_NULL( Screen16,xorPaint )
 879|  #ifdef USES_MASK
 880|  INF_SUB_SC_METHOD_NULL( Screen16,flushTo2 )
 881|  #ifdef USES_SCREEN
 882|    INF_SUB_SC_METHOD_NULL( Screen16,flushFromScreen2 )
 883|  #endif
 884|  #ifdef USES_DSCREEN
 885|    INF_SUB_SC_METHOD_NULL( Screen16,flushFromDScreen2 )
 886|  #endif
 887|  #endif /* USES_MASK */
 888|  INF_SUB_SC_END( Screen16, DrawScr );
 889|}
 890|#endif /* USES_DRAWSCR */
 891| 
 892|