/*******************************************************************

  XPUYO   puyo-puyo for X11          (c)1997 CDR/TK  (Tatsuya Kudoh)

  graph.c ---- low-level graphical handling

  低水準グラフィック処理

    x,y : キャラクタ単位の座標、左上が(2､0)
    col : ぷよの色、0はぷよ以外 (背景、壁、透明ぷよ)
    form: ぷよの形、col==0の時はキャラクタの種類

*******************************************************************/


#include<stdio.h>
#include<X11/Xlib.h>
#include"xpuyo.h"
#include"xpuyo_x11.h"

static int Map[8][15];   /* 仮想画面         */
static int Change_flag;  /* 画面更新するか？ */



/* ドロワブルにキャラクタを描画。実際に描画した時 1、何もしない時 0 を返す。*/
/* x,yがマイナス、またはドロワブルより大きい時の動作は不定                  */

static int copy_graph( Drawable drw, int x, int y, int col, int form )
{
  int sy;

  sy = form * 32;

  x *= 32;
  y = (y-2) * 32;

  if( y < 0 )
    return 0;

  XCopyArea( Disp,Graph[0],drw,Gc_nomask,0,0,32,32,x,y );

  if( col > 0 || form > 0 ){
    XSetClipOrigin( Disp,Gc_mask[col],x,y-sy );
    XCopyArea( Disp,Graph[col],drw,Gc_mask[col],0,sy,32,32,x,y );
  }
  return 1;
}



/* 仮想画面を書き換える。変化しない時は 0 を返す。 */

static int change( int x, int y, int col, int form )
{
  form += col * 256;
  if( Map[x][y] == form )
    return 0;
  Map[x][y] = form;
  return 1;
}



/* 裏画面にキャラクタを描画。変化しない時 0 を返す。*/

int set_graph( int x, int y, int col, int form )
{

  if( change( x,y,col,form ) && copy_graph( Scr_p,x,y,col,form ) ){
    Change_flag = 1;
    return 1;
  }else
    return 0;
}



/* キャラクタを描画 */

void put_graph( int x, int y, int col, int form )
{
  if( change( x,y,col,form ) && copy_graph( Scr_p,x,y,col,form ) ){
    x *= 32;
    y = (y-2)*32;
    XCopyArea( Disp,Scr_p,Scr_w,Gc_nomask,x,y,32,32,x,y );
  }
}



/* 裏画面、仮想画面の初期化 */

void clear_screen( void )
{
  int x,y;

  for( y = 2 ; y < 15 ; y++ )
    for( x = 0 ; x < 8 ; x++ ){
      Map[x][y] = -1;
      set_graph( x,y,0,1 );
    }

  for( y = 2 ; y < 6 ; y++ )
    for( x = 0 ; x < 3 ; x++ )
      copy_graph( Next_p,x,y,0,1 );

  Change_flag = 1;
}



/* NEXTぷよを表示 */

void put_next( int col1, int col2 )
{
  copy_graph( Next_p,1,4,col1,0 );
  copy_graph( Next_p,1,3,col2,16 );

  XCopyArea( Disp,Next_p,Next_w,Gc_nomask,32,32,32,64,32,32 );
}



/* 裏画面を保存 (点滅用に使う) */

void save_scr( void )
{
  XCopyArea( Disp,Scr_p,Scr_sp,Gc_nomask,0,0,256,416,0,0 );
}



/* 点滅。引数が 0 の時、save_scrで保存したグラフィック、  */
/*              1 の時、裏画面を表示                  */

void blink( int i )
{
  if( i )
    XCopyArea( Disp,Scr_p,Scr_w,Gc_nomask,0,0,256,416,0,0 );
  else
    XCopyArea( Disp,Scr_sp,Scr_w,Gc_nomask,0,0,256,416,0,0 );
}



/* 画面更新 (裏画面を表示する) */

void flush_scr( void )
{
  if( Change_flag ){
    XCopyArea( Disp,Scr_p,Scr_w,Gc_nomask,0,0,256,416,0,0 );
    Change_flag = 0;
  }
}
