tile.c 8 KB
/*
 *  NINTENDO64 SAMPLE PROGRAM
 *
 *  FILE : tile.c
 *
 *  Copyright (C) 1997, NINTENDO Co,Ltd.
 */


#include  <ultra64.h>
#include  <PR/gs2dex.h>
#include  "system.h"
#include  "tile.h"
#include  "sprite.h"


#ifdef THROUGH
#define G_CC_MYNEWMODE  0, 0, 0, TEXEL0, 0, 0, 0, ENVIRONMENT
#endif


/*
 *  $B%?%$%k9=B$BN$N=i4|2=(B
 */
void  tileInit(TILE_STATE       *root,      TILE_STATE         *tileStat,
	       ONE_TILE_SPRITE  *allsprite, ALL_TILES_TEXTURE  *alltiles)
{
  u8  i, j;
  TILE_STATE  *before;


  /* $B%j%9%H$N:,$N=i4|2=(B */
  before = root;
  
  /* $B%@%_!<%?%$%k0J30$N=i4|2=(B */
  for(i = 0; i < TILES - 1; i++){
    
    /* $B%j%9%H$N9=C[(B */
    before->next     = &tileStat[i];
    before           = &tileStat[i];
    
    /* $B%?%$%k0LCV$N=i4|2=(B */
    tileStat[i].loc_x = ORIGIN_X + (i % 4) * TILE_WD;
    tileStat[i].loc_y = ORIGIN_Y + (i / 4) * TILE_HT;

    /* $B%?%$%kMQ%^%H%j%/%99=B$BN$N=i4|2=(B */
    tileStat[i].tileMtx[0].m.X = (s16)tileStat[i].loc_x << 2;
    tileStat[i].tileMtx[0].m.Y = (s16)tileStat[i].loc_y << 2;
    tileStat[i].tileMtx[1].m.X = (s16)tileStat[i].loc_x << 2;
    tileStat[i].tileMtx[1].m.Y = (s16)tileStat[i].loc_y << 2;

    tileStat[i].tileMtx[0].m.BaseScaleX = 1 << 10;
    tileStat[i].tileMtx[0].m.BaseScaleY = 1 << 10;
    tileStat[i].tileMtx[1].m.BaseScaleX = 1 << 10;
    tileStat[i].tileMtx[1].m.BaseScaleY = 1 << 10;

    /* $B%?%$%kMQ%9%W%i%$%H9=B$BN$N=i4|2=(B */
    for(j = 0; j < SUBTILES; j++)
      tileStat[i].tileSprite[j] = allsprite->subtiles[j];

    /* $B%?%$%kMQ%F%/%9%A%c9=B$BN$N=i4|2=(B */
    for(j = 0; j < SUBTILES; j++)
      tileStat[i].tileTxtr[j] = alltiles->tiles[i]->subtiles[j];

    /* $B%?%$%k(B ID $B$N@_Dj(B */
    tileStat[i].id = i;

    /* $BH?E>I=<(%U%i%0$N=i4|2=(B */
    tileStat[i].shade_flag = 0;

    /* $B%?%$%k$N0\F0@h$N=i4|2=(B */
    tileStat[i].dest_x = 0.0;
    tileStat[i].dest_y = 0.0;

    /* $B%?%$%k$N0\F0B.EY$N=i4|2=(B */
    tileStat[i].delta_x = 0.0;
    tileStat[i].delta_y = 0.0;

  }

  /* $B%@%_!<%?%$%k$N=i4|2=(B */
  before->next     = &tileStat[i];
  tileStat[i].next = NULL;
  tileStat[i].id   = i;
}


/*
 *  $B%?%$%k%N!<%I$N%5!<%A(B
 */
s8  tileSearch(TILE_STATE  *root, u8  num, TILE_STATE  **node, TILE_STATE  **pre_node)
{
  u8  i;


  *pre_node = root;
  *node     = root->next;

  for(i = 0; i < num; i++){
    *pre_node =  *node;
    *node     = (*node)->next;

    if(!(*node))
      return -1;
  }

  return 0;
}


/*
 *  $B%?%$%k%N!<%I$N%9%o%C%W(B
 */
void  tileSwap(TILE_STATE  *tileStat, u8  src, u8  dest)
{
  u32  tmp;
  TILE_STATE  *srcTile, *destTile;
  TILE_STATE  *srctmp,  *desttmp;


  /* $B%9%o%C%W$9$k%?%$%k$NC5:w(B */
  tileSearch(tileStat, src,  &srcTile,  &srctmp);
  tileSearch(tileStat, dest, &destTile, &desttmp);

  /* $B%?%$%k$N%9%o%C%W(B */
  if(srcTile->next == destTile){
    tmp = (u32)destTile->next;

    srcTile->next = (TILE_STATE *)tmp;
    destTile->next = srcTile;
    srctmp->next  = destTile;
  } else if(destTile->next == srcTile){
    tmp = (u32)srcTile->next;

    destTile->next = (TILE_STATE *)tmp;
    srcTile->next   = destTile;
    desttmp->next  = srcTile;
  } else {
    tmp = (u32)destTile->next;

    destTile->next = srcTile->next;
    srcTile->next = (TILE_STATE *)tmp;
    desttmp->next  = srcTile;
    srctmp->next  = destTile;
  }
}


/*
 *  $B%?%$%k$N0\F0A0=hM}(B
 */
void  tilePreMove(TILE_STATE  *tileStat, u8  move, u8  blank)
{
  u32  tmp;
  TILE_STATE  *moveTile, *blankTile;
  TILE_STATE  *movetmp,  *blanktmp;


  /* $B%9%o%C%W$9$k%?%$%k$NC5:w(B */
  tileSearch(tileStat, move,  &moveTile,  &movetmp);
  tileSearch(tileStat, blank, &blankTile, &blanktmp);

#ifdef MOVE_WITH_NO_SHADE  
  /* $B0\F0;~$N%?%$%k$NH?E>$OL5$7(B */
  moveTile->shade_flag = 0;
#endif

  /* $B0\F0@h$NEPO?(B */
  moveTile->dest_x = blankTile->loc_x;
  moveTile->dest_y = blankTile->loc_y;

  /* $B0\F0B.EY$NEPO?(B */
  if(moveTile->next == blankTile) {
    moveTile->delta_x = (f32)TILE_WD / MOVE_FRAMES;
    moveTile->delta_y = 0;
  } else if(blankTile->next == moveTile){
    moveTile->delta_x = - (f32)TILE_WD / MOVE_FRAMES;
    moveTile->delta_y = 0;
  } else if(move > blank) {
    moveTile->delta_x = 0;
    moveTile->delta_y = - (f32)TILE_HT / MOVE_FRAMES;
  } else if(move < blank) {
    moveTile->delta_x = 0;
    moveTile->delta_y = (f32)TILE_HT / MOVE_FRAMES;
  } else
    osSyncPrintf("speed error\n");

  /* $B%V%i%s%/%?%$%k$O0\F0$NI,MW$J$7(B */
  blankTile->loc_x = moveTile->loc_x;
  blankTile->loc_y = moveTile->loc_y;

  blankTile->tileMtx[0].m.X = moveTile->tileMtx[0].m.X;
  blankTile->tileMtx[0].m.Y = moveTile->tileMtx[0].m.Y;
  blankTile->tileMtx[1].m.X = moveTile->tileMtx[1].m.X;
  blankTile->tileMtx[1].m.Y = moveTile->tileMtx[1].m.Y;

  /* $B%?%$%k$N%9%o%C%W(B */
  if(moveTile->next == blankTile){
    tmp             = (u32)blankTile->next;
    moveTile ->next = (TILE_STATE *)tmp;
    blankTile->next = moveTile;
    movetmp ->next  = blankTile;
  } else if(blankTile->next == moveTile){
    tmp             = (u32)moveTile->next;
    moveTile ->next = blankTile;
    blankTile->next = (TILE_STATE *)tmp;
    blanktmp ->next  = moveTile;
  } else {
    tmp             = (u32)blankTile->next;
    blankTile->next = moveTile->next;
    moveTile ->next = (TILE_STATE *)tmp;
    blanktmp->next  = moveTile;
    movetmp ->next  = blankTile;
  }
}


/*
 *  $B%?%$%k$N0\F0=hM}(B
 */
void  tileMove(TILE_STATE  *tileStat, u8  move, u8 frame)
{
  s16  tmpi;
  f32  tmpf;
  TILE_STATE  *moveTile, *movetmp;


  /* $B0\F0%?%$%k$NC5:w(B */
  tileSearch(tileStat, move, &moveTile, &movetmp);

  /* $B%?%$%kMQ%^%H%j%/%99=B$BN$N99?7(B */
  moveTile->loc_x += moveTile->delta_x;
  tmpi = (s16)moveTile->loc_x;
  tmpf = moveTile->loc_x - tmpi;
  moveTile->tileMtx[frame].m.X = (tmpi << 2) + (s16)(tmpf * FRAC_CONST);

  moveTile->loc_y += moveTile->delta_y;
  tmpi = (s16)moveTile->loc_y;
  tmpf = moveTile->loc_y - tmpi;
  moveTile->tileMtx[frame].m.Y = (tmpi << 2) + (s16)(tmpf * FRAC_CONST);
}


/*
 *  $B%?%$%k$N0\F08e=hM}(B
 */
void  tileAfterMove(TILE_STATE  *tileStat, u8  move)
{
  TILE_STATE  *moveTile, *movetmp;


  /* $B0\F0%?%$%k$NC5:w(B */
  tileSearch(tileStat, move, &moveTile, &movetmp);

  /* $B%?%$%k0LCV$N99?7(B */
  moveTile->loc_x = moveTile->dest_x;
  moveTile->loc_y = moveTile->dest_y;

  moveTile->tileMtx[0].m.X = (s16)moveTile->dest_x << 2;
  moveTile->tileMtx[0].m.Y = (s16)moveTile->dest_y << 2;
  moveTile->tileMtx[1].m.X = (s16)moveTile->dest_x << 2;
  moveTile->tileMtx[1].m.Y = (s16)moveTile->dest_y << 2;

  /* $B%?%$%k$N0\F0@h$N=i4|2=(B */
  moveTile->dest_x = 0.0;
  moveTile->dest_y = 0.0;

  /* $B%?%$%k$N0\F0B.EY$N=i4|2=(B */
  moveTile->delta_x = 0.0;
  moveTile->delta_y = 0.0;

  /* $B%?%$%kH?E>I=<(MQ%U%i%0$N=i4|2=(B */
  moveTile->shade_flag = 0;
}


/*
 *  $B%?%$%k$NIA2h(B
 */
Gfx  *tileDraw(Gfx  *gp, TILE_STATE  *tileStat, u8 frame)
{
  u8  i;
  TILE_STATE  *current = tileStat->next;


  /* $B%j%9%H:G8eHx$+$iIA2h(B */
  if(current->next)
    gp = tileDraw(gp, current, frame);

  /* $B%@%_!<%?%$%k$J$i%j%?!<%s(B */
  if(current->id == (TILES - 1))
    return gp;

  /* $B%?%$%kIA2hMQ(B RSP $B@_Dj(B */
  gSPObjRenderMode(gp ++, 0);
  
  /* $B%?%$%kIA2hMQ(B RDP $B@_Dj(B */
  gDPPipeSync(gp ++);
  /* Global */
  gDPSetCycleType(gp ++, G_CYC_1CYCLE);
  /* TX */
  gDPSetTextureLUT(gp ++, G_TT_NONE);
  /* TF */
  gDPSetTextureFilter(gp ++, G_TF_POINT);
  /* CC */
#ifdef THROUGH
  gDPSetCombineMode(gp ++, G_CC_MYNEWMODE, G_CC_MYNEWMODE);
  gDPSetEnvColor   (gp ++, 0x0, 0x0, 0x0, 0x7f);
#else
  if(current->shade_flag)
    gDPSetCombineMode(gp ++, G_CC_MODULATEIDECALA_PRIM, G_CC_MODULATEIDECALA_PRIM)
  else
    gDPSetCombineMode(gp ++, G_CC_DECALRGBA, G_CC_DECALRGBA);
#endif
  /* BL */
#ifdef THROUGH
  gDPSetRenderMode(gp ++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
#else
  gDPSetRenderMode(gp ++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
#endif
  
  /* $B%?%$%k$NIA2h(B */
  gSPObjSubMatrix (gp ++, &current->tileMtx[frame]);
  for(i = 0; i < SUBTILES; i++){
    gSPObjLoadTxtr  (gp ++, current->tileTxtr[i]);
    gSPObjRectangleR(gp ++, current->tileSprite[i]);
  }

  return gp;
}