/*****************************************************************************/
/* Character class for WonderWitch                                           */
/* キャラクターなどのスプライト画像を扱うクラス                              */
/*                                                                           */
/* WonderWitch の「スプライト」は，"Character" と呼ぶので注意．              */
/* WonderWitch の「キャラクタ」は，"Picture" と呼ぶので注意．                */
/*****************************************************************************/

#include "charap.h"

#include "etc.h"

int Character_GetX(Character character) { return (character->x); }
int Character_GetY(Character character) { return (character->y); }
Picture Character_GetPicture(Character character)
{ return (character->picture); }

/*---------------------------------------------------------------------------*/
/* オブジェクトの生成                                                        */
/*---------------------------------------------------------------------------*/

Character Character_Create(Character character, Disp disp, Picture picture,
			   int x, int y)
{
  unsigned short int char_data = 0x0000;

  if (character == NULL) Error("Character_Create", "Cannot allocate memory.");

  character->disp = disp;
  character->picture = picture;
  character->number = Disp_GetSpriteNumber(disp);
  character->x = x;
  character->y = y;

  /* キャラクタ番号設定 */
  char_data |=
    ((unsigned short int)Picture_GetNumber(character->picture)) & 0x01ff;

  /* キャラクタパレット番号 */
  char_data &= ~((0x0001 << 9) | (0x0001 << 10) | (0x0001 << 11));

  char_data &= ~(0x0001 << 12); /* クリッピングタイプ */

  /* スクリーン２に対する優先度．1でスクリーン２より優先． */
  char_data &= ~(0x0001 << 13); /* 初期状態では非表示 */

  char_data &= ~(0x0001 << 14); /* 縦方向反転表示しない */
  char_data &= ~(0x0001 << 15); /* 横方向反転表示しない */

  character->char_data = char_data;

  sprite_set_char(character->number, character->char_data);
  sprite_set_location(character->number, character->x, character->y);

  Character_Hide(character);

  return (character);
}

/*---------------------------------------------------------------------------*/
/* オブジェクトの削除                                                        */
/*---------------------------------------------------------------------------*/

Character Character_Destroy(Character character)
{
  Character_Hide(character);

  /* スプライト番号を Disp オブジェクトに返す． */
  Disp_ReturnSpriteNumber(character->disp, character->number);

  return (NULL);
}

/*---------------------------------------------------------------------------*/
/* 配置                                                                      */
/*---------------------------------------------------------------------------*/

int Character_Locate(Character character, int x, int y)
{
  int w, h;

  character->x = x;
  character->y = y;

  x = character->x * DISP_PICTURE_TICS_X - Disp_GetRollX(character->disp);
  y = character->y * DISP_PICTURE_TICS_Y - Disp_GetRollY(character->disp);

  w = Picture_GetWidth(character->picture);
  h = Picture_GetHeight(character->picture);

  if ( (x <= DISP_GAME_X - w) ||
       (y <= DISP_GAME_Y - h) ||
       (x >= DISP_GAME_X + DISP_GAME_WIDTH) ||
       (y >= DISP_GAME_Y + DISP_GAME_HEIGHT) ) {
    x = 0;
    y = DISP_DISPLAY_HEIGHT;
  }

  sprite_set_location(character->number, x, y);

  return (0);
}

/*---------------------------------------------------------------------------*/
/* 移動                                                                      */
/*---------------------------------------------------------------------------*/

int Character_Move(Character character, int delta_x, int delta_y)
{
  int x, y;

  x = character->x + delta_x;
  y = character->y + delta_y;
  Character_Locate(character, x, y);

  return (0);
}

/*---------------------------------------------------------------------------*/
/* 可視状態にする                                                            */
/*---------------------------------------------------------------------------*/

int Character_Visible(Character character)
{
  /* スクリーン２に対する優先度．1でスクリーン２より優先． */
  character->char_data |=  (0x0001 << 13);
  sprite_set_char(character->number, character->char_data);
  return (1);
}

/*---------------------------------------------------------------------------*/
/* 非表示状態にする                                                          */
/*---------------------------------------------------------------------------*/

int Character_Hide(Character character)
{
  /* スクリーン２に対する優先度．1でスクリーン２より優先． */
  character->char_data &= ~(0x0001 << 13);
  sprite_set_char(character->number, character->char_data);
  return (0);
}

/*---------------------------------------------------------------------------*/
/* 画像を設定する                                                            */
/*---------------------------------------------------------------------------*/

int Character_SetPicture(Character character, Picture picture)
{
  character->picture = picture;
  /* キャラクタ番号設定 */
  character->char_data &= ~0x01ff;
  character->char_data |=
    ((unsigned short int)Picture_GetNumber(character->picture)) & 0x01ff;
  sprite_set_char(character->number, character->char_data);
  return (0);
}

/*---------------------------------------------------------------------------*/
/* 指定したキャラクタを画面の中央にもってくる                                */
/*---------------------------------------------------------------------------*/

int Character_PutCharacterAtCenterOfScreen(Character character)
{
  int x, y;

  x = character->x * DISP_PICTURE_TICS_X +
    Picture_GetWidth( character->picture) / 2;
  y = character->y * DISP_PICTURE_TICS_Y +
    Picture_GetHeight(character->picture) / 2;

  return (Disp_PutPointAtCenterOfScreen(character->disp, x, y));
}

/*****************************************************************************/
/* End of File.                                                              */
/*****************************************************************************/
