the cutting room mirror

Source Code

This is a sub-page of Mega Man Legends.

In the Japanese PlayStation and PSP versions, some uncompiled code can be found in ST1E.BIN:

Translation#

eve19.c#

                                                                   32 id);
extern  uint32  Sce_flag_test(uint32 id);

/*------------------------------------------------------------------*/
/* sound.c */
extern  void    Sound_call(uint16 req_no, sint32 pos_xy, sint32 pos_z);

/*------------------------------------------------------------------*/
/* moji.c */
extern  uint32  MojiTaskExec2(sint32 task_no,uint32 mess_no);
extern  uint32  Moji_flag;

/*==================================================================*/
/*      Prototypes                                                  */
/*==================================================================*/
static  void    eve19_main(EVE_WORK *evp);
static  void    eve19_end(EVE_WORK *evp);
/*------------------------------------------------------------------*/
static  void    eve19_main_area_00(EVE_WORK *evp);
static  void    eve19_main_area_01(EVE_WORK *evp);
static  void    eve19_main_area_02(EVE_WORK *evp);
//static    void    eve19_main_area_03(EVE_WORK *evp);
static  void    eve19_main_area_05(EVE_WORK *evp);
static  void    eve19_main_area_06(EVE_WORK *evp);
static  void    eve19_main_area_09(EVE_WORK *evp);
static  void    eve19_main_dummy(EVE_WORK *evp);
/*------------------------------------------------------------------*/
static  sint32  check_block(EVE_WORK *evp, CHECK_BLOCK *cbp);
static  sint32  check_swing_camera(EVE_WORK *evp);

/*==================================================================*/
/*      Tables                                                      */
/*==================================================================*/
static  void    (*eve19_move_tbl[])(EVE_WORK *evp) = {
    eve19_main,
    eve19_end,
};
/*------------------------------------------------------------------*/
static  void    (*eve19_main_tbl[])(EVE_WORK *evp) = {
    eve19_main_area_00,
    eve19_main_area_01,
    eve19_main_area_02,
//  eve19_main_area_03,
    eve19_main_dummy,
    eve19_main_dummy,
    eve19_main_area_05,
    eve19_main_area_06,
    eve19_main_dummy,
    eve19_main_dummy,
    eve19_main_area_09,
};

/*==================================================================*/
/*                                                                  */
/*      Program                                                     */
/*                                                                  */
/*==================================================================*/
void    StXX_eve19_move(EVE_WORK *evp)
{
    eve19_move_tbl[evp->routine_0](evp);
}

/*------------------------------------------------------------------*/
/*      R0_MAIN :   制御                                          */
/*------------------------------------------------------------------*/
static  void    eve19_main(EVE_WORK *evp)
{
    eve19_main_tbl[evp->type](evp);
}

/*------------------------------------------------------------------*/
/*      R0_END  :   終了                                          */
/*------------------------------------------------------------------*/
static  void    eve19_end(EVE_WORK *evp)
{
    Close_EVE_WORK(evp);
}

/*------------------------------------------------------------------*/
/*  AREA 00 :   地下第7層   起動装置                                */
/*              メッセージ   01  「コマンドを入力~」              */
/*------------------------------------------------------------------*/
static  void    eve19_main_area_00(EVE_WORK *evp)
{
    switch(evp->routine_1){
        /* 終了チェック */
        case 0:
            if(Sce_flag_test(OPEN_SUB_GATE_FLAG)){
                evp->routine_0 = R0_END;
            }
            else{
                evp->routine_1++;
            }
            break;

        /* メッセージ0起動チェック */
        case 1:
            if(eve19_check_flag & FLG_OPEN_SUB){
                evp->routine_1++;
            }
            break;

        /* メッセージ起動 */
        case 2:
            if(!(Moji_flag & MOJI_TASK0_ON)){
                MojiTaskExec2(0, MES_OPEN_SUB_0);
                eve19_check_flag &= ~FLG_OPEN_SUB;
                Player_work[0].status_flag |= PL_STATUS_CONTROL_OFF;
                evp->routine_1++;
            }
            break;

        /* メッセージの継続・終了チェック */
        case 3:
            if(!(Moji_flag & MOJI_TASK0_ON)){
                if(Sce_flag_test(OPEN_SUB_GATE_FLAG)){
                    Sound_call(SE_MAIN_CHIKA_YURE, 0, 0);
                    evp->routine_1++;
                    evp->routine_2 = 0;
                    evp->eve_free[0] = 0;
                }
                else{
                    Player_work[0].status_flag &= ~PL_STATUS_CONTROL_OFF;
                    evp->routine_1 = 1;
                }
            }
            break;

        /* カメラの振動 */
        case 4:
            if(check_swing_camera(evp)){
                Sound_call(SE_MAIN_CHIKA_YURE_STOP, 0, 0);
                evp->routine_1++;
            }
            break;

        /* メッセージ起動 */
        case 5:
            if(!(Moji_flag & MOJI_TASK0_ON)){
                st1a_console_flag = 1;
                MojiTaskExec2(0, MES_OPEN_SUB_1);
                evp->routine_1++;
            }
            break;

        /* メッセージの終了チェック */
        case 6:
            if(!(Moji_flag & MOJI_TASK0_ON)){
                Player_work[0].status_flag &= ~PL_STATUS_CONTROL_OFF;
                evp->routine_0 = R0_END;
            }
            break;
    }
}

/*------------------------------------------------------------------*/
/*  AREA 01 :   地下第8層   生命維持装置ルーム                       */
/*              デモ      43 ジュノ復活登場デモ                    */
/*------------------------------------------------------------------*/
static  void    eve19_main_area_01(EVE_WORK *evp)
{
    CHECK_BLOCK check_block_data = {0xfe, 0xfe, 0x04, 0x01};

    if(Sce_flag_test(JUNO_ENTER_DEMO_FLAG)){
        eve19_check_flag |= FLG_EXE_EV43;
        evp->routine_0 = R0_END;
        return;
    }

    if(check_block(evp, &check_block_data)){
        Sce_flag_on(JUNO_BOX_CHECK_FLAG);
        eve19_check_flag |= FLG_EXE_EV43;
        evp->routine_0 = R0_END;
    }
}

/*------------------------------------------------------------------*/
/*  AREA 02 :   地下第8層   ディフレクタールーム                  */
/*              メッセージ   27「すさまじいエネルギー~」         */
/*              メッセージ   28「何か大きな力で~」                    */
/*------------------------------------------------------------------*/
static  void    eve19_main_area_02(EVE_WORK *evp)
{
    CHECK_BLOCK check_block_data = {0x0a, 0xfa, 0x03, 0x01};

    switch(evp->routine_1){
        /* チェック */
        case 0:
            if(Sce_flag_test(ST1A_DIFFRACTER_FLAG)){
                evp->routine_0 = R0_END;
                return;
            }
            if(check_block(evp, &check_block_data)){
                evp->routine_1++;
            }
            break;

        /* メッセージ起動準備 */
        case 1:
            if(!(Moji_flag & MOJI_TASK0_ON)){
                if(check_block(evp, &check_block_data)){
                    evp->routine_1++;
                }
                else{
                    evp->routine_1 = 0;
                }
            }
            break;

        /* メッセージの起動 */
        case 2:
            MojiTaskExec2(0, MES_B8F);
            Player_work[0].status_flag |= PL_STATUS_CONTROL_OFF;
            Sce_flag_on(ST1A_DIFFRACTER_FLAG);
            evp->routine_1++;
            break;

        /* メッセージの終了チェック */
        case 3:
            if(!(Moji_flag & MOJI_TASK0_ON)){
                Player_work[0].status_flag &= (~PL_STATUS_CONTROL_OFF);
                evp->routine_0 = R0_END;
            }
            break;
    }
}

///*------------------------------------------------------------------*/
///*    AREA 03 :   地下第7層   回廊                                  */
///*                メッセージ   10「ロック、街の方がさわがしいの~」 */
///*------------------------------------------------------------------*/
//static    void    eve19_main_area_03(EVE_WORK *evp)
//{
//  CHECK_BLOCK check_block_data = {0x01, 0xda, 0x01, 0x01};
//  PL_WORK     *pp = &Player_work[0];
//
//  switch(evp->routine_1){
//      /* チェック */
//      case 0:
//          if(eve19_check_flag & FLG_MES_B7F){
//              evp->routine_0 = R0_END;
//              return;
//          }
//          if( check_block(evp, &check_block_data) &&
//              Sce_flag_test(OPEN_SUB_GATE_FLAG)){
//              evp->routine_1++;
//          }
//          break;
//
//      /* メッセージ起動準備 */
//      case 1:
//          if(!(Moji_flag & MOJI_TASK0_ON)){
//              if(check_block(evp, &check_block_data)){
//                  evp->routine_1++;
//              }
//              else{
//                  evp->routine_1 = 0;
//              }
//          }
//          break;
//
//      /* メッセージの起動 */
//      case 2:
//          MojiTaskExec2(0, MES_B7F);
//          pp->status_flag |= PL_STATUS_CONTROL_OFF;
//          eve19_check_flag |= FLG_MES_B7F;
//          evp->routine_1++;
//          break;
//
//      /* メッセージの終了チェック */
//      case 3:
//          if(!(Moji_flag & MOJI_TASK0_ON)){
//              pp->status_flag &= (~PL_STATUS_CONTROL_OFF);
//              evp->routine_0 = R0_END;
//          }
//          break;
//  }
//}

/*------------------------------------------------------------------*/
/*  AREA 05 :   地下第5層   回廊                                  */
/*              メッセージ   06「ノイズが入る…そろそろ~」            */
/*------------------------------------------------------------------*/
static  void    eve19_main_area_05(EVE_WORK *evp)
{
    CHECK_BLOCK check_block_data = {0xfb, 0xea, 0x01, 0x01};

    switch(evp->routine_1){
        /* チェック */
        case 0:
            if( (eve19_check_flag & FLG_MES_B5F) ||
                Sce_flag_test(OPEN_SUB_GATE_FLAG)){
                eve19_check_flag |= FLG_MES_B5F;
                evp->routine_0 = R0_END;
                return;
            }
            if(check_block(evp, &check_block_data)){
                evp->routine_1++;
            }
            break;

        /* メッセージ起動準備 */
        case 1:
            if(!(Moji_flag & MOJI_TASK4_ON)){
                if(check_block(evp, &check_block_data)){
                    evp->routine_1++;
                }
                else{
                    evp->routine_1 = 0;
                }
            }
            break;

        /* メッセージの起動 */
        case 2:
            MojiTaskExec2(4, MES_B5F);
            eve19_check_flag |= FLG_MES_B5F;
            evp->routine_1++;
            break;

        /* メッセージの終了チェック */
        case 3:
            if(!(Moji_flag & MOJI_TASK4_ON)){
                evp->routine_0 = R0_END;
            }
            break;
    }
}

/*------------------------------------------------------------------*/
/*  AREA 06 :   地下第3層   回廊                                  */
/*              メッセージ   08「らせん状になってるみたいね~」      */
/*------------------------------------------------------------------*/
static  void    eve19_main_area_06(EVE_WORK *evp)
{
    CHECK_BLOCK check_block_data = {0x01, 0xfa, 0x01, 0x01};

    switch(evp->routine_1){
        /* チェック */
        case 0:
            if( (eve19_check_flag & FLG_MES_B3F) ||
                Sce_flag_test(OPEN_SUB_GATE_FLAG)){
                eve19_check_flag |= FLG_MES_B3F;
                evp->routine_0 = R0_END;
                return;
            }
            if(check_block(evp, &check_block_data)){
                evp->routine_1++;
            }
            break;

        /* メッセージ起動準備 */
        case 1:
            if(!(Moji_flag & MOJI_TASK4_ON)){
                if(check_block(evp, &check_block_data)){
                    evp->routine_1++;
                }
                else{
                    evp->routine_1 = 0;
                }
            }
            break;

        /* メッセージの起動 */
        case 2:
            MojiTaskExec2(4, MES_B3F);
            eve19_check_flag |= FLG_MES_B3F;
            evp->routine_1++;
            break;

        /* メッセージの終了チェック */
        case 3:
            if(!(Moji_flag & MOJI_TASK4_ON)){
                evp->routine_0 = R0_END;
            }
            break;
    }
}

/*------------------------------------------------------------------*/
/*  AREA 09 :   地下第1層   回廊                                  */
/*              メッセージ   07「なにかイヤな感じがする~」            */
/*------------------------------------------------------------------*/
static  void    eve19_main_area_09(EVE_WORK *evp)
{
    CHECK_BLOCK check_block_data = {0xfb, 0x24, 0x01, 0x01};

    switch(evp->routine_1){
        /* チェック */
        case 0:
            if(eve19_check_flag & FLG_MES_B1F){
                evp->routine_0 = R0_END;
                return;
            }
            else if(Sce_flag_test(OPEN_SUB_GATE_FLAG)){
                eve19_check_flag |= (FLG_MES_B1F | FLG_MES_B7F);
                evp->routine_0 = R0_END;
                return;
            }
            if(check_block(evp, &check_block_data)){
                evp->routine_1++;
            }
            break;

        /* メッセージ起動準備 */
        case 1:
            if(!(Moji_flag & MOJI_TASK4_ON)){
                if(check_block(evp, &check_block_data)){
                    evp->routine_1++;
                }
                else{
                    evp->routine_1 = 0;
                }
            }
            break;

        /* メッセージの起動 */
        case 2:
            MojiTaskExec2(4, MES_B1F);
            eve19_check_flag |= FLG_MES_B1F;
            evp->routine_1++;
            break;

        /* メッセージの終了チェック */
        case 3:
            if(!(Moji_flag & MOJI_TASK4_ON)){
                evp->routine_0 = R0_END;
            }
            break;
    }
}

/*------------------------------------------------------------------*/
/*      DUMMY                                                       */
/*------------------------------------------------------------------*/
static  void    eve19_main_dummy(EVE_WORK *evp)
{
    evp->routine_0 = R0_END;
}

/*------------------------------------------------------------------*/
/*      プレイヤーのいるブロックのチェック                           */
/*------------------------------------------------------------------*/
static  sint32  check_block(EVE_WORK *evp, CHECK_BLOCK *cbp)
{
    if( ((uint16)((sint8)(Player_work[0].pos.vx >> 9) - cbp->x) < (uint16)cbp->dx) &&
        ((uint16)((sint8)(Player_work[0].pos.vz >> 9) - cbp->z) < (uint16)cbp->dz)){
        return(1);
    }
    else{
        return(0);
    }
}

/*------------------------------------------------------------------*/
/*      カメラ振動のチェック                                      */
/*------------------------------------------------------------------*/
static  sint32  check_swing_camera(EVE_WORK *evp)
{
    sint32  ret = 0;

    switch(evp->routine_2){
        case 0:
            Swing_Camera2(4, 512, 1024, &Player_work[0].pos);
            evp->routine_2++;
            break;

        case 1:
            if(Camera_work.routine_3 == 0){
                if(evp->eve_free[0] >= 90){
                    ret = 1;
                }
                else{
                    evp->routine_2 = 0;
                }
            }
            break;
    }

    evp->eve_free[0]++;
    return(ret);
}

/*==================================================================*/
/*  "eve19.c"   End of File                                         */
/*==================================================================*/

Some Programming#

#define R1_STOP2            7       /* ルーチン1 No. 停止2                */
#define R1_DEAD             8       /* ルーチン1 No. 破壊             */
#define R1_STOP_ATTACK      9       /* ルーチン1 No. 停止攻撃           */
#define R1_TOUCH            10      /* ルーチン1 No. 受け渡し           */

#define R2_ES_WALK          0       /* ルーチン2 No. 逃げ走行           */
#define R2_AT_WALK          1       /* ルーチン2 No. 攻撃走行           */
#define R2_ST_WALK          2       /* ルーチン2 No. 停止走行           */
#define R2_ES_ATTACK        0       /* ルーチン2 No. 逃げ攻撃           */
#define R2_AT_ATTACK        1       /* ルーチン2 No. 攻撃攻撃           */
#define R2_ST_ATTACK        2       /* ルーチン2 No. 停止攻撃           */

#define SEQ_WAIT            0x00    /* シーケンス No. 待機             */
#define SEQ_WALK            0x01    /* シーケンス No. 走行             */
#define SEQ_SPIN            0x03    /* シーケンス No. スリップ(ダッシュ)       */
#define SEQ_DASH            0x04    /* シーケンス No. 加速             */
#define SEQ_SLOW            0x05    /* シーケンス No. 減速ブレーキ            */
#define SEQ_STOP            0x06    /* シーケンス No. 停止→待機          */
#define SEQ_RIGHT           0x08    /* シーケンス No. 右回転                */
#define SEQ_RIGHT_RET       0x09    /* シーケンス No. 右回転戻り          */
#define SEQ_LEFT            0x0a    /* シーケンス No. 左回転                */
#define SEQ_LEFT_RET        0x0b    /* シーケンス No. 左回転戻り          */
#define SEQ_OUT             0x0d    /* シーケンス No. 破壊             */

#define SPD_ES_WALK         (0x260) /* スピード:ランダム 逃げ走行        */
#define SPD_AT_WALK         (0x200) /* スピード:ランダム 攻撃走行        */
#define SPD_ST_WALK         (0x1a0) /* スピード:ランダム 守り走行        */
//#define SPD_AT_WALK           (0x140) /* スピード:ランダム 攻撃走行        */
//#define SPD_ST_WALK           (0x100) /* スピード:ランダム 守り走行        */
#define ADD_ES_WALK         (0x020) /* スピード:ランダム 逃げ走行        */
#define ADD_AT_WALK         (0x020) /* スピード:ランダム 攻撃走行        */
#define ADD_ST_WALK         (0x020) /* スピード:ランダム 守り走行        */

#define DIR_FLY             (256)   /* 角度:吹っ飛び              */
#define DIR_ES_TURN         (24)    /* 角度:逃げ                    */
#define DIR_AT_TURN         (24)    /* 角度:攻撃                    */
#define DIR_ST_TURN         (24)    /* 角度:守り                    */

#define DIST_ATTACK         (((512)*(512))>>1)
                                    /* 距離:攻撃射程範囲            */
#define DIST_CURVE          (((1024)*(1024))<<1)
                                    /* 距離:減速範囲              */
#define DIST_STOP_ATTACK    (((1536)*(1536))>>1)
                                    /* 距離:停止攻撃射程範囲      */
#define DIST_TOUCH          (((2048)*(2048))<<1)
                                    /* 距離:受け渡し範囲            */

#define FLG_END         (1 << 0)    /* フラグ:行動終了                */
#define FLG_DAMAGE      (1 << 1)    /* フラグ:ダメージ許可                */
#define FLG_DAMAGE2     (1 << 2)    /* フラグ:ダメージ                  */
#define FLG_ATARI       (1 << 3)    /* フラグ:あたりセット              */
#define FLG_SEARCH      (1 << 4)    /* フラグ:索敵                  */
#define FLG_ATTACK      (1 << 5)    /* フラグ:攻撃中                 */
#define FLG_TURN_CK     (1 << 6)    /* フラグ:切り替えし               */
#define FLG_TOUCH       (1 << 7)    /* フラグ:受け渡し                */
#define FLG_TAIYA       (1 << 8)    /* フラグ:タイヤ 回転              */
#define FLG_TYPE2       (1 << 9)    /* フラグ:待機型                 */

#define HEIGHT_WALK     (16)        /* 移動できる高さ              */

#define em1c_set_move(a,b,c)\
    ep->routine_1 = a,\
    ep->routine_2 = b,\
    ep->routine_3 = c;

typedef struct{
    sint16      id;
    sint16      flag;
    sint16      x,z;
    sint16      w,h;
    sint8       next[5];
    uint8       pad1;
    uint16      pad2;
} MOVE_TBL;

typedef struct{
    uint16      flag;           /* フラグ                     */
    uint16      rand;           /* 乱数                       */
    sint16      timer;          /* 行動 タイマ                   */
    sint16      timer2;         /* 行動 タイマ2              */
    uint16      damage;         /* ダメージ量                  */
    sint16      damage_cnt;     /* ダメージカウンタ               */
    SVECTOR     at_pos;         /* 当たり用                 */
    uint32      at_code[2];     /* 当たり用コード             */
    SVECTOR     at_svec;        /* 当たり用相手ポジション        */
    uint32      search[4];      /* プレイヤー探索用                */
    EM_WORK     *sub_ep;        /* 子ワーク アドレス               */
    MOVE_TBL    *mp;            /* 目的地ワーク アドレス         */
    MOVE_TBL    *old_mp;        /* 目的地ワーク アドレス         */
    SVECTOR     svec;           /* 目的地座標                */
    sint8       motion;         /**/
    sint8       old_id;         /**/
    sint8       dir;            /**/
    sint8       old_dir;        /**/
    sint16      ang_y;          /**/
    sint16      turn_x;         /**/
    uint16      next_flag;      /**/
    sint16      search_timer;   /**/
    sint32      life;
} ZAKO_WORK;

#define FREE_NO     (EM_PARTS_MAX - 4)
#define ZAKO        (*(ZAKO_WORK*)&ep->parts_mat[FREE_NO])

/*==================================================================*/
/*      Work                                                        */
/*==================================================================*/
/* routine 0 */
static void (*em1c_move00_tbl[])(EM_WORK *ep) = {
    em1c_move_init,         /* 初期化          */
    em1c_move_main,         /* 通常攻撃         */
    em1c_move_erase,        /* 消去               */
    NULL,
    em1c_move_type2,        /* 待機型          */
    em1c_move_opening,      /* デバッグ          */
    em1c_move_type2,        /* 待機型          */
};
/* routine 1 */
static void (*em1c_move01_tbl[])(EM_WORK *ep) = {
    em1c_move_wait,         /* 待機               */
    em1c_move_walk,         /* 歩行               */
    em1c_move_attack,       /* 攻撃               */
    em1c_move_curve,        /* カーブ             */
    em1c_move_curve2,       /* カーブ2            */
    em1c_move_start,        /* 発進               */
    em1c_move_stop,         /* 停止               */
    em1c_move_stop2,        /* 停止2          */
    em1c_move_dead,         /* 破壊               */
    em1c_move_stop_attack,  /* 停止攻撃         */
    em1c_move_touch,        /* 受け渡し         */
};
/* routine 2 */
static void (*em1c_walk_tbl[])(EM_WORK *ep) = {
    em1c_es_walk,           /* 逃げ走行         */
    em1c_at_walk,           /* 攻撃走行         */
    em1c_st_walk,           /* 守り走行         */
};
static void (*em1c_attack_tbl[])(EM_WORK *ep) = {
    em1c_es_attack,         /* 逃げ攻撃         */
    NULL,                   /* 攻撃攻撃         */
    em1c_st_attack,         /* 守り攻撃         */
};

static ADJ_AREA em1c_adjust_size = { -20, 20, -20, 20, -20, 0 };

static MOVE_TBL em1c_00_move_tbl[14] = {
    {-1},
    {-1},
    {-1},
    
    { 3,0, 1536, 8192,1024,1024,{ 5,-1,-1, 6,-1}},
    {-1},
    { 5,0, 1536, -512,1024,1024,{-1,-1, 3,13,-1}},
    
    { 6,0, 4608, 8192,1024,1024,{ 7, 3,-1,11,-1}},
    { 7,0, 4608, 2560,1024,1024,{-1,-1, 6,12,-1}},
    {-1},
    
    {-1},
    {-1},
    
    {11,0, 6656, 8192,1024,1024,{12, 6,-1,-1,-1}},
    {12,0, 6656, 2560,1024,1024,{13, 7,11,-1,-1}},
    {13,0, 6656, -512,1024,1024,{-1, 5,12,-1,-1}},
};
static MOVE_TBL em1c_01_move_tbl[14] = {
    { 0,0,-5120, 8192,1024,1024,{ 1,-1,-1, 3,-1}},
    { 1,0,-5120, 4096,1024,1024,{ 2,-1, 0, 4,-1}},
    { 2,0,-5120, -512,1024,1024,{-1,-1, 1, 5,-1}},
    
    { 3,0,  512, 8192,1024,1024,{ 4, 0,-1,-1,-1}},
    { 4,0,  512, 4096,1024,1024,{ 5, 1, 3,-1,-1}},
    { 5,0,  512, -512,1024,1024,{-1, 2, 4,-1,-1}},
    
    {-1},
    {-1},
    {-1},
    
    {-1},
    {-1},
    
    {-1},
    {-1},
    {-1},
};
static MOVE_TBL em1c_02_move_tbl[14] = {
    { 0,0,-5632, 8704,1024,1024,{ 2,-1,-1, 3,-1}},
    {-1},
    { 2,0,-5632,-1024,1024,1024,{-1,-1, 0, 5,-1}},
    
    { 3,0, 1024, 8704,1024,1024,{ 5, 0,-1,11,-1}},
    {-1},
    { 5,0, 1024,-1024,1024,1024,{-1, 2, 3,13,-1}},
    
    {-1},
    {-1},
    {-1},
    
    {-1},
    {-1},
    
    {11,0, 7168, 8704,1024,1024,{13, 3,-1,-1,-1}},
    {-1},
    {13,0, 7168,-1024,1024,1024,{-1, 5,11,-1,-1}},
};

static MOVE_TBL *em1c_move_tbl[] = {
    em1c_00_move_tbl,
    em1c_01_move_tbl,
    em1c_02_move_tbl,
};


static sint16   spd_tbl[3] = {
    SPD_ES_WALK,SPD_AT_WALK,SPD_ST_WALK
};
static sint16   add_tbl[3] = {
    ADD_ES_WALK,ADD_AT_WALK,ADD_ST_WALK
};
static sint16   dir_tbl[3] = {
    DIR_ES_TURN,DIR_AT_TURN,DIR_ST_TURN
};

/*==================================================================*/
/*      Program : routine 0                                         */
/*==================================================================*/
/*------------------------------------------------------------------*/
/*  関数名:StXX_em1c_move                                          */
/*  引き数:敵ワークのポインタ                                       */
/*  戻り値:なし                                                  */
/*  機 能:EM1Cの起動ルーチン                                 */
/*  備 考:ミキサー君                                               */
/*------------------------------------------------------------------*/
void StXX_em1c_move(EM_WORK *ep)
{
    ZAKO_WORK   *zako;
#if EM1C_DEBUG_PRINT
    PL_WORK         *pwp = &Player_work[0];
    uint32          proc;
    static uint8    stat[][8] = {"INIT","MAIN","ERASE","DEMO"};
    
    sint32  cnt;
//  SVECTOR svec[6];
    
    if( ep->work_3 & WORK3_FLG_DEBUG ) proc = VSync(1);
#endif
    if( ep->routine_0 == R0_INIT ){
        em1c_move00_tbl[ep->routine_0](ep);
    }
    
    /* 汎用ワーク */
    zako = &ZAKO;
#if EM1C_DEBUG_PRINT
    if( ep->work_3 & WORK3_FLG_DEBUG ){
    
    if( ep->routine_0 == R0_MOVE ) {
        if( ((uint8)ep->type > 0x03) ){
            PRINT_PAGE(6);
            Print(XYC( 16, 120,2),"BUG!!");
        }
        if( zako->mp->id == -1 ){
            PRINT_PAGE(6);
            Print(XYC( 16, 128,2),"BUG!!");
        }
        switch( ep->type ){
            case 0:
            if( ((uint32)zako->mp < (uint32)&em1c_00_move_tbl[ 0]) ||
                ((uint32)zako->mp > (uint32)&em1c_00_move_tbl[13]) ){
                PRINT_PAGE(6);
                Print(XYC( 16, 136,2),"BUG_A!!");
            }
            break;
            
            case 1:
            if( ((uint32)zako->mp < (uint32)&em1c_01_move_tbl[ 0]) ||
                ((uint32)zako->mp > (uint32)&em1c_01_move_tbl[13]) ){
                PRINT_PAGE(6);
                Print(XYC( 16, 144,2),"BUG_B!!");
            }
            break;
            
            case 2:
            if( ((uint32)zako->mp < (uint32)&em1c_02_move_tbl[ 0]) ||
                ((uint32)zako->mp > (uint32)&em1c_02_move_tbl[13]) ){
                PRINT_PAGE(6);
                Print(XYC( 16, 152,2),"BUG_C!!");
            }
            break;
        }
    }
    }
#endif
    /* 表示中のシーケンスナンバー退避 */
    ep->seq_old = ep->seq_no;
    /* ポジション退避 */
    ep->old = ep->pos;
    ep->old_l = ep->pos_l;
    ep->ang_old = ep->ang;
    /* 輝度設定 */
    ep->size.pad = 0x4210;
    /* 乱数 */
    zako->rand = rand();
    
    /* テーブル ジャンプ */
    em1c_move00_tbl[ep->routine_0](ep);
    
    if(ep->seq_old != ep->seq_no)   /* 敵キャラセット */
        EM_Char_Set2((MODEL_WORK*)ep,ep->seq_no,zako->motion);
    else                            /* シーケンス送り */
        EM_Char_Move2((MODEL_WORK*)ep);
    zako->motion = 0;
    /* タイヤを回転 */
    if( zako->flag & FLG_TAIYA )
        zako->turn_x = (zako->turn_x + (-ep->spd.vx >> 2)) & 0x0fff;
    else
        zako->turn_x = (zako->turn_x + (ep->spd.vx >> 2)) & 0x0fff;
        
    (((SVECTOR*)Unfold_buff_ptr1) + 3)->vx = zako->turn_x;
    (((SVECTOR*)Unfold_buff_ptr1) + 5)->vx = zako->turn_x << 1;
    EM_World_Pos_Calc(ep);
    
//  cnt = 0;
//  while(cnt < 6){
//      svec[cnt] = *(((SVECTOR*)Unfold_buff_ptr1) + cnt);
//      cnt++;
//  }
    
    /* 影をつける */
    if( ep->be_flag & TRANS )
        Model_Shadow_Trans((MODEL_WORK*)ep,128,512,1);
    
    if( (ep->be_flag & MOVE) && (zako->flag & FLG_ATARI) ){
        /* 当たりの設定 */
        zako->at_pos = ep->parts_posl[0];
        zako->at_pos.vy -= 64;
        Set_Atari(&zako->at_pos,200,ATARI_1,ATARI_ENEMY,
            ep->work_id,(uint32*)&zako->at_code[0],
            AT_ENEMY | CANCEL_ENEMY | CANCEL_PLAYER1 | zako->damage,
            POS_INFO_ON,AT_FLAG_OFF);
    }
    
    /* 子 */
//  EM1A_MOVE(zako->sub_ep);
    
#if EM1C_DEBUG_PRINT
    if( ep->work_3 & WORK3_FLG_DEBUG ){
        PRINT_PAGE(6);
        Print(XYC(16,80,0),"ENEMY1C %s /%d.%d.%d.%d/%d,%d/%d",
            &stat[ep->routine_0][0],
            ep->routine_0,ep->routine_1,ep->routine_2,ep->routine_3,
            zako->mp->id,zako->old_mp->id,VSync(1) - proc);
        Print(XYC( 16, 88,0),"  x:%6d dx:%4u",ep->pos.vx,ep->ang.vx);
        Print(XYC( 16, 96,0),"  y:%6d dy:%4u",ep->pos.vy,ep->ang.vy);
        Print(XYC( 16,104,0),"  z:%6d dz:%4u",ep->pos.vz,ep->ang.vz);
        Print(XYC(168, 88,0),"x:%6d ax:%4u",ep->spd.vx,ep->add.vx);
        Print(XYC(168, 96,0),"y:%6d ay:%4u",ep->spd.vy,ep->add.vy);
        Print(XYC(168,104,0),"z:%6d az:%4u",ep->spd.vz,ep->add.vz);
        
        if(Angle_ck(&ep->pos_l,ep->ang.vy,1024,&pwp->pos_l,pwp->ang.vy,2048)){
            Print(XYC(168,40,0),"FLAG:%x",zako->flag);
            Print(XYC(168,48,0),"RAND:%u",zako->rand);
            Print(XYC(168,56,0),"LIFE:%d/%d",ep->life,ep->life_max);
            Print(XYC(168,64,0),"AT  :%08x",zako->at_code[0]);
        }else{
            Print(XYC(168,40,2),"FLAG:%x",zako->flag);
            Print(XYC(168,48,2),"RAND:%u",zako->rand);
            Print(XYC(168,56,2),"LIFE:%d/%d",ep->life,ep->life_max);
            Print(XYC(168,64,2),"AT  :%08x",zako->at_code[0]);
        }
        
        Print(XYC(16,128,0),"TIME:%d/%d",zako->search_timer,Mixer_touch_timer);
        if( Joy1.trg & JOY_RR ){
//          em1c_set_move(R1_WAIT,0,0);
//          em1c_set_move(R1_WALK,0,0);
//          em1c_set_move(R1_STOP,0,0);
//          em1c_set_move(R1_START,0,0);
//          em1c_set_move(R1_DEAD,0,0);
//          zako->at_code[0] |= (AT_EFFECT | 0xfff);
        }
        if( Joy2.trg & JOY_RR ){
            ep->life = ep->life_old = ep->life_max;
        }
    }
#endif
    zako->at_code[0] = 0;
};
/*------------------------------------------------------------------*/
/*  関数名:em1c_move_init                                          */
/*  引き数:敵ワークのポインタ                                       */
/*  戻り値:なし                                                  */
/*  機 能:EM1Cの初期化ルーチン                                */
/*  備 考:ミキサー君                                               */
/*------------------------------------------------------------------*/
static void em1c_move_init(EM_WORK *ep)
{
    ZAKO_WORK       *zako;
    static uint8    tbl[][3] = {{6,0,5},{3,1,0},{3,3,3}};
    
    /* 汎用ワーク */
    zako = &ZAKO;
    
    /* 基本 ルーチン設定 */
    if( ep->type & 0x20 ){
        ep->routine_0 = R0_TYPE3;
        ep->routine_1 = R1_WAIT;
        zako->flag = FLG_ATARI;
    }else if( ep->type & 0x40 ){
        ep->routine_0 = R0_TYPE2;
        ep->routine_1 = R1_WAIT;
        zako->flag = (FLG_TYPE2 | FLG_ATARI);
    }else{
        if( !(ep->type & 0x80) ){
            ep->routine_0 = R0_MOVE;
            ep->routine_1 = R1_START;
            zako->flag = FLG_ATARI;
        }else{
            ep->routine_0 = R0_OPENING;
            ep->routine_1 = R1_WAIT;
            zako->flag = 0;
        }
    }
    *((uint16*)&ep->routine_2) = 0;
    
    /* 胴体 */
    if( (zako->sub_ep = (EM_WORK*)Open_EM_WORK()) != NULL ){
        zako->sub_ep->be_flag = MOVE;
        zako->sub_ep->id = 0x1a;
        zako->sub_ep->type = ep->type;
        *((uint32 *)&zako->sub_ep->routine_0) = 0;
        *((uint32 *)&zako->sub_ep->work_0) = *((uint32 *)&ep->work_0);
        zako->sub_ep->pos_l.vx = ep->parts_posl[0].vx << 16;
        zako->sub_ep->pos_l.vy = ep->parts_posl[0].vy << 16;
        zako->sub_ep->pos_l.vz = ep->parts_posl[0].vz << 16;
        zako->sub_ep->pos = ep->parts_posl[0];
        zako->sub_ep->work_1 = ep->work_id;
    }else{
        Close_EM_WORK(ep);
        return;
    }
    
    /* 回転角など */
    ep->be_flag |= TRANS;
    ep->type &= 0x1f;
    ep->ang.vx = 0;
    ep->ang.vy = ((ep->work_0 & 0x0f) << 9) & 0x0fff;
    ep->ang.vz = 0;
    *((uint32*)&ep->dir_x) = 0;
    if( !(zako->flag & FLG_TYPE2) ){
        ep->spd.vx = spd_tbl[ep->type];
        ep->add.vx = add_tbl[ep->type];
        ep->dir_y  = dir_tbl[ep->type];
    }
    /* 登場向きを消す */
    ep->work_0 &= 0xf0;
    /* 体力 */
    ep->life_old = ep->life_max = ep->life = (*(&em_tbl[ep->id]->free_0 + ep->type) << 5);
    /* スクロール補正データアドレス設定 */
    ep->adj_size_adrs = &em1c_adjust_size;
    ep->sp_act_data_adrs = NULL;
    /* 高さ情報取得 */
    ep->pos.vy = Scr_height_check((MODEL_WORK*)ep);
    ep->pos_l.vy = ep->pos.vy << 16;
    /* 輝度設定 */
    ep->size.pad = 0x4210;
    
    /* モデルのリンク情報など */
    Model_work_init((MODEL_WORK*)ep,(uint8*)&ep->type);
    
    /* モデルの拡大率:512は標準 */
    *((uint32*)&ep->size.vx) = 0x02000200;
    *((uint32*)&ep->size.vz) = 0x00000200;
    
    /* ミキサー君 ワークの初期化 */
    zako->flag |= (FLG_DAMAGE|FLG_DAMAGE2/*|FLG_ATARI*/);
    *((uint32*)&zako->timer)  = 0;
    *((uint32*)&zako->damage) = 0;
    zako->at_code[0] = 0;
    zako->at_code[1] = 0;
    Search_Player_Init(&zako->search[0],em_tbl[ep->id]->free_5,-512);
    if( !(zako->flag & FLG_TYPE2) ){
        zako->mp = &(em1c_move_tbl[ep->type])[tbl[0][ep->type]];
        zako->old_mp = &(em1c_move_tbl[ep->type])[tbl[2][ep->type]];
        zako->old_id = 3;
        zako->svec.vx = zako->mp->x;
        zako->svec.vy = 0;
        zako->svec.vz = zako->mp->z;
        zako->dir = tbl[1][ep->type];
        /**/
        Mixer_ptr[ep->type] = zako->sub_ep;
        Mixer_ptr2[ep->type] = ep;
        Mixer_flag = Dbl_buff_idx;
//      Mixer_touch_timer = 300;
        Mixer_touch_timer = 0;
        
        if( ep->type == 0x02 ){
            if( (Mixer_key = (SHL_WORK*)Open_SHL_WORK()) != NULL ){
                Mixer_key->be_flag = MOVE;
                Mixer_key->id = 0x0d;
                Mixer_key->type = 0x00;
//              Mixer_ptr[rand() % 0x03]->work_3 |= WORK3_FLG_KEY;
                Mixer_ptr[0x01]->work_3 |= WORK3_FLG_KEY;
//          }else{
//どうしよう…。
            }
        }
    }
    zako->ang_y = 0;
    zako->turn_x = 0;
    zako->motion = 0;
    zako->search_timer = 0;
    zako->life = 320;
    zako->next_flag = 0;
    zako->old_dir = 0;
    
//  if( ep->routine_0 == R0_TYPE3 ){
//      Open_Boss_Gauge((BOSS_WORK*)ep,0,ep->type * 20,0x60 | 0x00);
//  }
    
    /* 敵セット・待機モーションセット */
    EM_Char_Set((MODEL_WORK*)ep,SEQ_WAIT,0);
}
/*------------------------------------------------------------------*/
/*  関数名:em1c_move_main                                          */
/*  引き数:敵ワークのポインタ                                       */
/*  戻り値:なし                                                  */
/*  機 能:EM1Cの通常行動ルーチン                               */
/*  備 考:ミキサー君                                               */
/*------------------------------------------------------------------*/
static void em1c_move_main(EM_WORK *ep)
{
    static uint8    touch_tbl[] = {0,1,0,2,1,2};
    static EM_WORK  *mp,*mp2,*mp3,*mp4;
    
    ZAKO_WORK       *zako;
    sint32          px,pz,cnt;
    
    zako = &ZAKO;
    
    /* 各ミキサー の距離 and 受け渡しチェック */
#if 1
    if( !(Mixer_touch_flag) ){
        if( Mixer_flag != Dbl_buff_idx ){
            if( Mixer_touch_timer ){
                Mixer_touch_timer--;
            }else{
                cnt = 0;
                while( cnt < 3 ){
                    mp  =  Mixer_ptr[touch_tbl[(cnt << 1)]];
                    mp2 =  Mixer_ptr[touch_tbl[(cnt << 1) + 1]];
                    px = mp->pos.vx - mp2->pos.vx;
                    pz = mp->pos.vz - mp2->pos.vz;
                    Mixer_dist[cnt] = (px * px) + (pz * pz);
                    cnt++;
                }
                
                cnt = 0;
                while( cnt < 3 ){
                    if( Mixer_dist[cnt] < DIST_TOUCH ){
                        mp  = Mixer_ptr[touch_tbl[(cnt << 1)]];
                        mp2 = Mixer_ptr[touch_tbl[(cnt << 1) + 1]];
                        mp3 = Mixer_ptr2[touch_tbl[(cnt << 1)]];
                        mp4 = Mixer_ptr2[touch_tbl[(cnt << 1) + 1]];
                        if( !((mp->work_3 | mp2->work_3) & WORK3_FLG_KEY) ){
                            goto next;
                        }
                        if( !(mp->work_2  & (WORK2_FLG_NO_TOUCH|WORK2_FLG_DEAD|WORK2_FLG_NO_TOUCH2))&&
                            !(mp2->work_2 & (WORK2_FLG_NO_TOUCH|WORK2_FLG_DEAD|WORK2_FLG_NO_TOUCH2))){
                            
                            mp->work_1 = touch_tbl[(cnt << 1) + 1];
                            mp->work_2 |= WORK2_FLG_TOUCH;
                            if( mp->work_3 & WORK3_FLG_KEY ){
                                mp->work_2 |= WORK2_FLG_NO_DEATH;
                                mp->routine_1 = ROUTINE_THROW;
                                mp3->routine_1 = R1_TOUCH;
                            }else{
                                mp->routine_1 = ROUTINE_TOUCH;
                                mp3->routine_1 = R1_TOUCH;
                            }
                            *((uint16*)&mp->routine_2) = 0;
                            *((uint16*)&mp3->routine_2) = 0;
                            
                            mp2->work_1 = touch_tbl[(cnt << 1)];
                            mp2->work_2 |= WORK2_FLG_TOUCH;
                            if( mp2->work_3 & WORK3_FLG_KEY ){
                                mp2->work_2 |= WORK2_FLG_NO_DEATH;
                                mp2->routine_1 = ROUTINE_THROW;
                                mp4->routine_1 = R1_TOUCH;
                            }else{
                                mp2->routine_1 = ROUTINE_TOUCH;
                                mp4->routine_1 = R1_TOUCH;
                            }
                            *((uint16*)&mp2->routine_2) = 0;
                            *((uint16*)&mp4->routine_2) = 0;
                            
                            Mixer_touch_flag = 1;
                            break;
                        }
                    }
next:               cnt++;
                }
            }
            Mixer_flag = Dbl_buff_idx;
        }
    }
#endif
    /* 索敵 */
    if( Search_Player(&zako->search[0],ep) )
        zako->flag |= FLG_SEARCH;
    else
        zako->flag &= (~FLG_SEARCH);
    
    /* ダメージチェック   */
    if( zako->flag & FLG_DAMAGE ) em1c_ck_atari(ep);
    
    /* テーブル ジャンプ */
    em1c_move01_tbl[ep->routine_1](ep);
    
    /* 次行動決定 */
    if( zako->flag & FLG_END ){
        switch( ep->routine_1 ){
            case R1_WALK:
            {
                static uint8    tbl[] = {R1_STOP,0,R1_STOP_ATTACK};
                ep->routine_1 = tbl[ep->type];
            }
            break;
            
            case R1_STOP_ATTACK:
            if( Angle_ck(&ep->pos_l,ep->ang.vy,1024,&Player_work[0].pos_l,Player_work[0].ang.vy,2048) ){
                em1c_change(ep);
            }else{
                zako->flag &= (~FLG_ATTACK);
            }
            ep->routine_1 = R1_START;
            break;
            
            case R1_CURVE:
            ep->routine_1 = R1_WALK;
            break;
            
            case R1_CURVE2:
            ep->routine_1 = R1_ATTACK;
            break;
            
            case R1_START:
            if( zako->flag & FLG_ATTACK ){
                ep->routine_1 = R1_ATTACK;
            }else{
                ep->routine_1 = R1_WALK;
            }
            break;
            
            case R1_TOUCH:
            zako->flag &= (~FLG_TOUCH);
            
            case R1_STOP:
            case R1_STOP2:
            ep->routine_1 = R1_START;
            break;
            
            default:
            ep->routine_1 = R1_WAIT;
        }
        
        *((uint16*)&ep->routine_2) = 0;
        zako->flag &= (~FLG_END);
    }
    
    /* ダメージカウンタ */
    if( zako->damage_cnt ) zako->damage_cnt--;
    /* 索敵 カウンタ */
    if( zako->search_timer ) zako->search_timer--;
    
#if EM1C_DEBUG_PRINT
#endif
}
/*------------------------------------------------------------------*/
/*  関数名:em1c_move_opening                                       */
/*  引き数:敵ワークのポインタ                                       */
/*  戻り値:なし                                                  */
/*  機 能:EM1Cの通常行動ルーチン                               */
/*  備 考:ミキサー君                                               */
/*------------------------------------------------------------------*/
static void em1c_move_opening(EM_WORK *ep)
{
    ZAKO_WORK       *zako;
    
    zako = &ZAKO;
    
    /* 索敵 */
    if( Search_Player(&zako->search[0],ep) )
        zako->flag |= FLG_SEARCH;
    else
        zako->flag &= (~FLG_SEARCH);
    
    /* ダメージチェック   */
    if( zako->flag & FLG_DAMAGE ) em1c_ck_atari(ep);
    
    /* テーブル ジャンプ */
    em1c_move01_tbl[ep->routine_1](ep);
    
    /* 次行動決定 */
    if( zako->flag & FLG_END ){
        switch( ep->routine_1 ){
            default:
            ep->routine_1 = R1_WAIT;
        }
        *((uint16*)&ep->routine_2) = 0;
        zako->flag &= (~FLG_END);
    }
    
    /* ダメージカウンタ */
    if( zako->damage_cnt ) zako->damage_cnt--;
    /* 索敵 カウンタ */
    if( zako->search_timer ) zako->search_timer--;
}
/*------------------------------------------------------------------*/
/*  関数名:em1c_move_type2                                         */
/*  引き数:敵ワークのポインタ                                       */
/*  戻り値:なし                                                  */
/*  機 能:EM1C待機型ルーチン                                 */
/*  備 考:ミキサー君                                               */
/*------------------------------------------------------------------*/
static void em1c_move_type2(EM_WORK *ep)
{
    ZAKO_WORK       *zako;
    
    zako = &ZAKO;
    
    /* 索敵 */
    if( Search_Player(&zako->search[0],ep) )
        zako->flag |= FLG_SEARCH;
    else
        zako->flag &= (~FLG_SEARCH);
    
    /* ダメージチェック   */
    if( zako->flag & FLG_DAMAGE ) em1c_ck_atari2(ep);
    
    /* テーブル ジャンプ */
    em1c_move01_tbl[ep->routine_1](ep);
    
    /* 次行動決定 */
    if( zako->flag & FLG_END ){
        switch( ep->routine_1 ){
            default:
            ep->routine_1 = R1_WAIT;
        }
        *((uint16*)&ep->routine_2) = 0;
        zako->flag &= (~FLG_END);
    }
    
    /* ダメージカウンタ */
    if( zako->damage_cnt ) zako->damage_cnt--;
    /* 索敵 カウンタ */
    if( zako->search_timer ) zako->search_timer--;
}
/*------------------------------------------------------------------*/
/*  関数名:em1c_move_erase                                         */
/*  引き数:敵ワークのポインタ                                       */
/*  戻り値:なし                                                  */
/*  機 能:EM1Cの強制破壊ルーチン                               */
/*  備 考:ミキサー君                                               */
/*------------------------------------------------------------------*/
static void em1c_move_erase(EM_WORK *ep)
{
    ZAKO_WORK *zako;
    
    zako = &ZAKO;
    /* 消滅 */
    Close_EM_WORK(ep);
    zako->sub_ep->routine_0 = 2;
    ((uint32 (*)())(((uint32 **)Enemy_move_ptr)[zako->sub_ep->id])[zako->sub_ep->id2])(zako->sub_ep);
//  (*((uint32(**)())Enemy_move_ptr)[zako->sub_ep->id])(zako->sub_ep);
    if( zako->sub_ep->work_3 & WORK3_FLG_KEY ){
        Close_SHL_WORK(Mixer_key);
    }
#if EM1C_DEBUG_PRINT
    
#endif
}
/*==================================================================*/
/*      Program : routine 1                                         */
/*==================================================================*/
/*------------------------------------------------------------------*/
/*  関数名:em1c_move_wait                                          */
/*  引き数:敵ワークのポインタ                                       */
/*  戻り値:なし                                                  */
/*  機 能:EM1Cの待機ルーチン                                 */
/*  備 考:ミキサー君                                               */
/*------------------------------------------------------------------*/
static void em1c_move_wait(EM_WORK *ep)
{
    ZAKO_WORK *zako;
    
    zako = &ZAKO;
    
    switch( ep->routine_2 ){
        case 0:
        ep->routine_2 = 1;
        ep->seq_no = SEQ_WAIT;
        ep->spd.vx = 0;
        zako->timer = 60;
        zako->damage = 0x00;
        zako->flag &= (~FLG_TAIYA);
        
        case 1:
        if( --zako->timer < 0 )
            zako->flag |= FLG_END;
    }
    
#if EM1C_DEBUG_PRINT
    if( ep->work_3 & WORK3_FLG_DEBUG ){
        PRINT_PAGE(6);
        Print(XYC(16,120,0),"STAT:WAIT:%d",zako->timer);
    }
#endif
}
/*------------------------------------------------------------------*/
/*  関数名:em1c_move_walk                                          */
/*  引き数:敵ワークのポインタ                                       */
/*  戻り値:なし                                                  */
/*  機 能:EM1Cの歩行ルーチン                                 */
/*  備 考:ミキサー君                                               */
/*------------------------------------------------------------------*/
static void em1c_move_walk(EM_WORK *ep)
{
    ZAKO_WORK   *zako;
    
    zako = &ZAKO;
    
    ep->routine_2 = ep->type;
    
    /* テーブル ジャンプ */
    em1c_walk_tbl[ep->routine_2](ep);
    
#if EM1C_DEBUG_PRINT
#endif
}
/*------------------------------------------------------------------*/
/*  関数名:em1c_move_attack                                        */
/*  引き数:敵ワークのポインタ                                       */
/*  戻り値:なし                                                  */
/*  機 能:EM1Cの攻撃ルーチン                                 */
/*  備 考:ミキサー君                                               */
/*------------------------------------------------------------------*/
static void em1c_move_attack(EM_WORK *ep)
{
    ZAKO_WORK   *zako;
    
    zako = &ZAKO;
    
    ep->routine_2 = ep->type;
    
    /* テーブル ジャンプ */
    em1c_attack_tbl[ep->routine_2](ep);
    
#if EM1C_DEBUG_PRINT
#endif
}
/*------------------------------------------------------------------*/
/*  関数名:em1c_move_curve                                         */
/*  引き数:敵ワークのポインタ                                       */
/*  戻り値:なし                                                  */
/*  機 能:EM1Cの進路変更ルーチン                               */
/*  備 考:ミキサー君                                               */
/*------------------------------------------------------------------*/
static void em1c_move_curve(EM_WORK *ep)
{
    ZAKO_WORK   *zako;
    sint32      px,pz;
    sint16      dir,ang;
    
    zako = &ZAKO;
    
    switch( ep->routine_2 ){
        case 0:
        ep->routine_2 = 1;
        zako->damage = 0x00;
        zako->flag &= (~FLG_TAIYA);
        
        case 1: /* 減速 */
        /* 分岐範囲 */
        px = ep->pos.vx - (zako->old_mp->x - (zako->old_mp->w >> 1));
        pz = ep->pos.vz - (zako->old_mp->z - (zako->old_mp->h >> 1));
        if( ((uint32)px < zako->old_mp->w) && ((uint32)pz < zako->old_mp->h) ){
            ep->routine_2 = 2;
//          if( Muku(&ep->pos,&zako->svec,ep->ang.vy,2048) > 0 )
//              ep->seq_no = SEQ_RIGHT;
//          else
//              ep->seq_no = SEQ_LEFT;
        }else{
            /* 移動 */
            if( (spd_tbl[0] >> 1) < ep->spd.vx ) ep->spd.vx -= ep->add.vx;
            Obj_pos_set((MODEL_WORK*)ep,ep->spd.vx,0,0);
            break;
        }
        
        case 2:
        ang = Calc_degree2(&ep->pos,&zako->svec);
        if( ((ep->ang.vy - ang + 512) & 0x0fff) < (512 << 1) ){
//          ep->seq_no = ep->seq_old + 1;
            ep->routine_2 = 3;
//          zako->motion = (9 - ep->frame_no);
        }
        
        case 3: /* 回転 */
        dir = Muku(&ep->pos,&zako->svec,ep->ang.vy,ep->dir_y);
        ep->ang.vy = (ep->ang.vy + dir) & 0x0fff;
        
        /* 移動 */
//      if( spd_tbl[ep->type] > ep->spd.vx ) ep->spd.vx += ep->add.vx;
        Obj_pos_set((MODEL_WORK*)ep,ep->spd.vx,0,0);
        
        if( dir == 0 ){
            zako->flag |= FLG_END;
            zako->sub_ep->work_2 &= (~WORK2_FLG_NO_TOUCH);
        }
    }
    
#if EM1C_DEBUG_PRINT
    if( ep->work_3 & WORK3_FLG_DEBUG ){
        PRINT_PAGE(6);
        Print(XYC(16,120,0),"STAT:CURVE:%d/%d",zako->timer,ep->seq_no);
        {
            sint32 dis;
            
            px = ep->pos.vx - zako->old_mp->x;
            pz = ep->pos.vz - zako->old_mp->z;
            dis = SquareRoot0((px * px) + (pz * pz));
            Print(XYC(16,136,3),"%ld",dis);
        }
    }
#endif
}
/*------------------------------------------------------------------*/
/*  関数名:em1c_move_curve2                                        */
/*  引き数:敵ワークのポインタ                                       */
/*  戻り値:なし                                                  */
/*  機 能:EM1Cの進路変更ルーチン                               */
/*  備 考:ミキサー君                                               */
/*------------------------------------------------------------------*/
static void em1c_move_curve2(EM_WORK *ep)
{
    ZAKO_WORK   *zako;
    sint32      px,pz;
    sint16      dir;
    
    zako = &ZAKO;
    
    switch( ep->routine_2 ){
        case 0:
        ep->routine_2 = 1;
        zako->damage = 0x00;
        zako->flag |= FLG_TAIYA;
        
        case 1: /* 減速 */
        /* 分岐範囲 */
        px = ep->pos.vx - (zako->old_mp->x - (zako->old_mp->w >> 1));
        pz = ep->pos.vz - (zako->old_mp->z - (zako->old_mp->h >> 1));
        if( ((uint32)px < zako->old_mp->w) && ((uint32)pz < zako->old_mp->h) ){
            ep->routine_2 = 2;
        }else{
            /* 移動 */
            if( (spd_tbl[0] >> 1) < ep->spd.vx ) ep->spd.vx -= ep->add.vx;
            Obj_pos_set((MODEL_WORK*)ep,-ep->spd.vx,0,0);
            break;
        }
        
        case 2: /* 回転 */
        dir = Muku(&ep->pos,&zako->svec,(ep->ang.vy + 2048) & 0x0fff,ep->dir_y);
        ep->ang.vy = (ep->ang.vy + dir) & 0x0fff;
        
        /* 移動 */
        Obj_pos_set((MODEL_WORK*)ep,-ep->spd.vx,0,0);
        
        if( dir == 0 ){
            zako->flag |= FLG_END;
            zako->sub_ep->work_2 &= (~WORK2_FLG_NO_TOUCH);
        }
    }
    
#if EM1C_DEBUG_PRINT
    if( ep->work_3 & WORK3_FLG_DEBUG ){
        PRINT_PAGE(6);
        Print(XYC(16,120,0),"STAT:CURVE2:%d/%d",zako->timer,ep->seq_no);
        {
            sint32 dis;
            
            px = ep->pos.vx - zako->old_mp->x;
            pz = ep->pos.vz - zako->old_mp->z;
            dis = SquareRoot0((px * px) + (pz * pz));
            Print(XYC(16,136,3),"%ld",dis);
        }
    }
#endif
}
/*------------------------------------------------------------------*/
/*  関数名:em1c_move_start                                         */
/*  引き数:敵ワークのポインタ                                       */
/*  戻り値:なし                                                  */
/*  機 能:EM1Cの発進ルーチン                                 */
/*  備 考:ミキサー君                                               */

sub_scrn.c#

        (subp->rb_parts_no_2 != pp->rb_parts_equip_data[2]) ){

        Pl00_shot_enable_off( pp );
        Pl00_shot_enable_on( pp );

        if( subp->weapon_no != pp->weapon_right_no )
            Obj_work_flag_change( WORK_PL_SHL, WORK_KILL );
    }
    return( 1 );
}

/*==================================================================*/
static  sint32  sub_screen_cancel_check( void )
{
    uint32  joy_trg;

    joy_trg = Joy1.trg;

    if( (joy_trg & (JOY_CANCEL | JOY_ST)) ){
        Sound_call( SE_CANCEL, 1, 0 );

        MojiTaskKill();
        Game_logo_kill( -1 );
        Cd_read_comb( EXIT_SUB_BIN );

        return( 1 );
    } else {
        return( 0 );
    }
}

/*==================================================================*/
static  void    sub_screen_shift_check( SUB_SCREEN_WORK *subp )
{
    uint32  joy_trg;

    joy_trg = Joy1.trg;

    if( joy_trg & (JOY_L1 | JOY_R1) ){
        Sound_call( SE_DECISION, 1, 0 );

        MojiTaskKill();
        Game_logo_kill( -1 );
        if( joy_trg & JOY_L1 ){
            if( (--subp->routine_0) < 0x02 ) subp->routine_0 = 0x06;
        } else {
            if( (++subp->routine_0) > 0x06 ) subp->routine_0 = 0x02;
        }
        subp->routine_1 = 0;
        *(uint16 *)&subp->routine_2 = 0;
    }
}

/*==================================================================*/
void    Sub_screen_sort_attack( void )
{
    sint32          d0, d1;
    uint8           sort_src, sort_dist;

    PL_WORK         *pp;

    pp = &Player_work[0];

    for( d0 = 0; d0 < 0x1f; d0++ ){
        for( d1 = 0; d1 < 0x1f - d0; d1++ ){
            if( !(sort_dist = pp->rb_parts_sort_data[d1 + 1]) ) continue;
            if( (!(sort_src = pp->rb_parts_sort_data[d1])) ||
                (Rock_buster_parts_tbl[sort_src - 1].attack_level <
                        Rock_buster_parts_tbl[sort_dist - 1].attack_level) )
                sub_screen_sort_sub( pp, d1, d1 + 1 );
        }
    }
}

/*==================================================================*/
void    Sub_screen_sort_energy( void )
{
    sint32          d0, d1;
    uint8           sort_src, sort_dist;

    PL_WORK         *pp;

    pp = &Player_work[0];

    for( d0 = 0; d0 < 0x1f; d0++ ){
        for( d1 = 0; d1 < 0x1f - d0; d1++ ){
            if( !(sort_dist = pp->rb_parts_sort_data[d1 + 1]) ) continue;
            if( (!(sort_src = pp->rb_parts_sort_data[d1])) ||
                (Rock_buster_parts_tbl[sort_src - 1].bullet_level <
                        Rock_buster_parts_tbl[sort_dist - 1].bullet_level) )
                sub_screen_sort_sub( pp, d1, d1 + 1 );
        }
    }
}

/*==================================================================*/
void    Sub_screen_sort_range( void )
{
    sint32          d0, d1;
    uint8           sort_src, sort_dist;

    PL_WORK         *pp;

    pp = &Player_work[0];

    for( d0 = 0; d0 < 0x1f; d0++ ){
        for( d1 = 0; d1 < 0x1f - d0; d1++ ){
            if( !(sort_dist = pp->rb_parts_sort_data[d1 + 1]) ) continue;
            if( (!(sort_src = pp->rb_parts_sort_data[d1])) ||
                (Rock_buster_parts_tbl[sort_src - 1].dist_level <
                        Rock_buster_parts_tbl[sort_dist - 1].dist_level) )
                sub_screen_sort_sub( pp, d1, d1 + 1 );
        }
    }
}

/*==================================================================*/
void    Sub_screen_sort_rapid( void )
{
    sint32          d0, d1;
    uint8           sort_src, sort_dist;

    PL_WORK         *pp;

    pp = &Player_work[0];

    for( d0 = 0; d0 < 0x1f; d0++ ){
        for( d1 = 0; d1 < 0x1f - d0; d1++ ){
            if( !(sort_dist = pp->rb_parts_sort_data[d1 + 1]) ) continue;
            if( (!(sort_src = pp->rb_parts_sort_data[d1])) ||
                (Rock_buster_parts_tbl[sort_src - 1].repeat_level <
                        Rock_buster_parts_tbl[sort_dist - 1].repeat_level) )
                sub_screen_sort_sub( pp, d1, d1 + 1 );
        }
    }
}

/*==================================================================*/
static  void    sub_screen_sort_sub( PL_WORK *pp, sint32 d0, sint32 d1 )
{
    uint8           sort_buff;

    sort_buff = pp->rb_parts_sort_data[d0];
    pp->rb_parts_sort_data[d0] = pp->rb_parts_sort_data[d1];
    pp->rb_parts_sort_data[d1] = sort_buff;
}

/*==================================================================*/
void    Sub_screen_rb_parts_set( void )
{
    sint32          d0, d1, d2;

    PL_WORK         *pp;

    pp = &Player_work[0];

    if( Sce_flag_test(PL_KEY_ITEM_06) ) d0 = 3; else d0 = 2;

    pp->weapon_data[1].attack_level = 0x00;
    pp->weapon_data[1].bullet_level = 0x00;
    pp->weapon_data[1].dist_level = 0x00;
    pp->weapon_data[1].repeat_level = 0x00;

    for( d1 = 0; d1 < d0; d1++ ){
        if( !(d2 = pp->rb_parts_equip_data[d1]) ) continue;
        pp->weapon_data[1].attack_level +=
                                Rock_buster_parts_tbl[d2 - 1].attack_level;
        pp->weapon_data[1].bullet_level +=
                                Rock_buster_parts_tbl[d2 - 1].bullet_level;
        pp->weapon_data[1].dist_level +=
                                Rock_buster_parts_tbl[d2 - 1].dist_level;
        pp->weapon_data[1].repeat_level +=
                                Rock_buster_parts_tbl[d2 - 1].repeat_level;
    }
    if( pp->weapon_data[1].attack_level > 0x07 )
        pp->weapon_data[1].attack_level = 0x07;

    if( pp->weapon_data[1].bullet_level > 0x07 )
        pp->weapon_data[1].bullet_level = 0x07;

    if( pp->weapon_data[1].dist_level > 0x07 )
        pp->weapon_data[1].dist_level = 0x07;

    if( pp->weapon_data[1].repeat_level > 0x07 )
        pp->weapon_data[1].repeat_level = 0x07;
}

/*==================================================================*/
static  void    sub_screen_rb_parts_calc( SUB_SCREEN_WORK *subp )
{
    sint32          d0, d1, d2;

    PL_WORK         *pp;

    pp = &Player_work[0];

    if( Sce_flag_test(PL_KEY_ITEM_06) ) d0 = 3; else d0 = 2;

    subp->attack_end_0 = subp->attack_end_1 = 0x00;
    subp->bullet_end_0 = subp->bullet_end_1 = 0x00;
    subp->dist_end_0   = subp->dist_end_1   = 0x00;
    subp->repeat_end_0 = subp->repeat_end_1 = 0x00;

    if( Moji_flag & MOJI_TASK0_ON ){
        for( d1 = 0; d1 < d0; d1++ ){
            if( !(d2 = pp->rb_parts_equip_data[d1]) ) continue;
            sub_screen_rb_parts_calc_sub00( subp, d2 - 1 );
            sub_screen_rb_parts_calc_sub01( subp, d2 - 1 );
        }
    } else {
        if( Moji_flag3 & MOJI3_PARTS_TASK ){
            for( d1 = 0; d1 < d0; d1++ ){
                if( (d2 = pp->rb_parts_equip_data[d1]) )
                    sub_screen_rb_parts_calc_sub00( subp, d2 - 1 );

                if( d1 == GET_SELECT_NO(1) ) continue;
                if( d2 ) sub_screen_rb_parts_calc_sub01( subp, d2 - 1 );
            }
        } else {
            for( d1 = 0; d1 < d0; d1++ ){
//              if( (d1 != GET_SELECT_NO(1)) &&
//                                      (d2 = pp->rb_parts_equip_data[d1]) )
                if( (d2 = pp->rb_parts_equip_data[d1]) )
                    sub_screen_rb_parts_calc_sub00( subp, d2 - 1 );

                if( d1 == GET_SELECT_NO(1) ) d2 = GET_PARTS_NO(1);
                if( d2 ) sub_screen_rb_parts_calc_sub01( subp, d2 - 1 );
            }
        }
    }
}

/*------------------------------------------------------------------*/
static  void    sub_screen_rb_parts_calc_sub00( SUB_SCREEN_WORK *subp,
                                                                sint32 d0 )
{
    subp->attack_end_0 += Rock_buster_parts_tbl[d0].attack_level * 0x0a;
    subp->bullet_end_0 += Rock_buster_parts_tbl[d0].bullet_level * 0x0a;
    subp->dist_end_0   += Rock_buster_parts_tbl[d0].dist_level * 0x0a;
    subp->repeat_end_0 += Rock_buster_parts_tbl[d0].repeat_level * 0x0a;

    if( subp->attack_end_0 > (0x07 * 0x0a) ) subp->attack_end_0 = 0x07 * 0x0a;
    if( subp->bullet_end_0 > (0x07 * 0x0a) ) subp->bullet_end_0 = 0x07 * 0x0a;
    if( subp->dist_end_0   > (0x07 * 0x0a) ) subp->dist_end_0 = 0x07 * 0x0a;
    if( subp->repeat_end_0 > (0x04 * 0x0a) ) subp->repeat_end_0 = 0x04 * 0x0a;
}

/*------------------------------------------------------------------*/
static  void    sub_screen_rb_parts_calc_sub01( SUB_SCREEN_WORK *subp,
                                                                sint32 d0 )
{
    subp->attack_end_1 += Rock_buster_parts_tbl[d0].attack_level * 0x0a;
    subp->bullet_end_1 += Rock_buster_parts_tbl[d0].bullet_level * 0x0a;
    subp->dist_end_1   += Rock_buster_parts_tbl[d0].dist_level * 0x0a;
    subp->repeat_end_1 += Rock_buster_parts_tbl[d0].repeat_level * 0x0a;

    if( subp->attack_end_1 > (0x07 * 0x0a) ) subp->attack_end_1 = 0x07 * 0x0a;
    if( subp->bullet_end_1 > (0x07 * 0x0a) ) subp->bullet_end_1 = 0x07 * 0x0a;
    if( subp->dist_end_1   > (0x07 * 0x0a) ) subp->dist_end_1 = 0x07 * 0x0a;
    if( subp->repeat_end_1 > (0x04 * 0x0a) ) subp->repeat_end_1 = 0x04 * 0x0a;
}

/*==================================================================*/
static  void    sub_screen_status_calc( SUB_SCREEN_WORK *subp, sint32 d0 )
{
    PL_WORK         *pp;

    pp = &Player_work[0];

    if( d0 < 0 ){
        subp->attack_end_0  = subp->attack_infi_0  = 0x00;
        subp->bullet_end_0  = subp->bullet_infi_0  = 0x00;
        subp->dist_end_0    = subp->dist_infi_0    = 0x00;
        subp->repeat_end_0  = subp->repeat_infi_0  = 0x00;
        subp->special_end_0 = subp->special_infi_0 = 0x00;
    } else {
        subp->attack_end_0 =
                    g_tbl[w_tbl[d0]].attack[pp->weapon_data[d0].attack_level];
        subp->bullet_end_0 =
                    g_tbl[w_tbl[d0]].energy[pp->weapon_data[d0].bullet_level];
        subp->dist_end_0 =
                    g_tbl[w_tbl[d0]].range[pp->weapon_data[d0].dist_level];
        subp->repeat_end_0 =
                    g_tbl[w_tbl[d0]].rapid[pp->weapon_data[d0].repeat_level];
        subp->special_end_0 =
                    g_tbl[w_tbl[d0]].special[pp->weapon_data[d0].sp_perform];

        if( subp->attack_end_0  == 0xff ){
            subp->attack_end_0  = 88;
            subp->attack_infi_0 = 1;
        } else {
            subp->attack_infi_0 = 0;
        }
        if( subp->bullet_end_0  == 0xff ){
            subp->bullet_end_0  = 88;
            subp->bullet_infi_0 = 1;
        } else {
            subp->bullet_infi_0 = 0;
        }
        if( subp->dist_end_0    == 0xff ){
            subp->dist_end_0    = 88;
            subp->dist_infi_0   = 1;
        } else {
            subp->dist_infi_0   = 0;
        }
        if( subp->repeat_end_0  == 0xff ){
            subp->repeat_end_0  = 88;
            subp->repeat_infi_0 = 1;
        } else {
            subp->repeat_infi_0 = 0;
        }
        if( subp->special_end_0 == 0xff ){
            subp->special_end_0  = 88;
            subp->special_infi_0 = 1;
        } else {
            subp->special_infi_0 = 0;
        }
    }
}

/*==================================================================*/
void    Sub_screen_gauge_set( sint32 x0, sint32 y0, sint32 power, sint32 flag )
{
    POLY_FT4        *ft4_buff_ptr1, *ft4_buff_ptr2;

    ft4_buff_ptr1 = ft4_buff_ptr2 = Map_prim_ptr;

    *(uint32 *)ft4_buff_ptr2 =
                    ((uint32)(ft4_buff_ptr2 + 1) & 0x00ffffff) | 0x09000000;
    *(uint32 *)&ft4_buff_ptr2->r0 = 0x2c808080;

    ft4_buff_ptr2->x0 = ft4_buff_ptr2->x2 = x0;
    ft4_buff_ptr2->x1 = ft4_buff_ptr2->x3 = x0 + power + 0x06;
    ft4_buff_ptr2->y0 = ft4_buff_ptr2->y1 = y0 + flag * 0x02;
    ft4_buff_ptr2->y2 = ft4_buff_ptr2->y3 = y0 + flag * 0x02 + 0x05;

    ft4_buff_ptr2->tpage = 0x0c;
    ft4_buff_ptr2->clut = 0xfa0c>>2;

    *(uint16 *)&ft4_buff_ptr2->u0 = 0x60 | ((0x90 + flag * 0x08)<<8);
    *(uint16 *)&ft4_buff_ptr2->u1 = 0x61 | ((0x90 + flag * 0x08)<<8);
    *(uint16 *)&ft4_buff_ptr2->u2 = 0x60 | ((0x95 + flag * 0x08)<<8);
    *(uint16 *)&ft4_buff_ptr2->u3 = 0x61 | ((0x95 + flag * 0x08)<<8);

    ft4_buff_ptr2++;

    *(uint32 *)ft4_buff_ptr2 =
                    ((uint32)(ft4_buff_ptr2 + 1) & 0x00ffffff) | 0x09000000;
    *(uint32 *)&ft4_buff_ptr2->r0 = 0x2c808080;

    ft4_buff_ptr2->x0 = ft4_buff_ptr2->x2 = x0 + power + 0x06;
    ft4_buff_ptr2->x1 = ft4_buff_ptr2->x3 = x0 + power + 0x0a;
    ft4_buff_ptr2->y0 = ft4_buff_ptr2->y1 = y0 + flag * 0x02;
    ft4_buff_ptr2->y2 = ft4_buff_ptr2->y3 = y0 + flag * 0x02 + 0x05;

    ft4_buff_ptr2->tpage = 0x0c;
    ft4_buff_ptr2->clut = 0xfa0c>>2;

    *(uint16 *)&ft4_buff_ptr2->u0 = 0x6f | ((0x90 + flag * 0x08)<<8);
    *(uint16 *)&ft4_buff_ptr2->u1 = 0x73 | ((0x90 + flag * 0x08)<<8);
    *(uint16 *)&ft4_buff_ptr2->u2 = 0x6f | ((0x95 + flag * 0x08)<<8);
    *(uint16 *)&ft4_buff_ptr2->u3 = 0x73 | ((0x95 + flag * 0x08)<<8);

    ft4_buff_ptr2++;

    if( (!flag) && (((y0 != 0x46) && (power == 0x0a * 7)) ||
                    ((y0 == 0x46) && (power == 0x0a * 4))) ){
        *(uint32 *)ft4_buff_ptr2 =
                    ((uint32)(ft4_buff_ptr2 + 1) & 0x00ffffff) | 0x04000000;
        *(uint32 *)&ft4_buff_ptr2->r0 = 0x64808080;
        ((SPRT *)ft4_buff_ptr2)->x0 = x0 + 0x0a + (power == 0x0a * 7) * 0x0e;
        ((SPRT *)ft4_buff_ptr2)->y0 = y0;
        *(uint32 *)&(((SPRT *)ft4_buff_ptr2)->u0) =
                                     0x28 | (0xf0<<8) | ((0xfa08>>2)<<16);
        *(uint32 *)&(((SPRT *)ft4_buff_ptr2)->w) = 0x00060018;

        ft4_buff_ptr2++;
    }
    addPrims( &Disp_env_ptr->ot[2], ft4_buff_ptr1, ft4_buff_ptr2 - 1 );
    Map_prim_ptr = (POLY_FT4 *)ft4_buff_ptr2;
}

/*------------------------------------------------------------------*/
void    Sub_screen_gauge_set2( sint32 x0, sint32 y0,
                                                sint32 power, sint32 infi )
{
    POLY_FT4        *ft4_buff_ptr1, *ft4_buff_ptr2;

    ft4_buff_ptr1 = ft4_buff_ptr2 = Map_prim_ptr;

    *(uint32 *)ft4_buff_ptr2 =
                    ((uint32)(ft4_buff_ptr2 + 1) & 0x00ffffff) | 0x09000000;
    *(uint32 *)&ft4_buff_ptr2->r0 = 0x2c808080;

    ft4_buff_ptr2->x0 = ft4_buff_ptr2->x2 = x0;
    ft4_buff_ptr2->x1 = ft4_buff_ptr2->x3 = x0 + power;
    ft4_buff_ptr2->y0 = ft4_buff_ptr2->y1 = y0;
    ft4_buff_ptr2->y2 = ft4_buff_ptr2->y3 = y0 + 0x08;

    ft4_buff_ptr2->tpage = 0x0c;
    ft4_buff_ptr2->clut = 0xfa0c>>2;

    *(uint16 *)&ft4_buff_ptr2->u0 = 0x48 | (0x90<<8);
    *(uint16 *)&ft4_buff_ptr2->u1 = 0x49 | (0x90<<8);
    *(uint16 *)&ft4_buff_ptr2->u2 = 0x48 | (0x98<<8);
    *(uint16 *)&ft4_buff_ptr2->u3 = 0x49 | (0x98<<8);

    ft4_buff_ptr2++;

    *(uint32 *)ft4_buff_ptr2 =
                    ((uint32)(ft4_buff_ptr2 + 1) & 0x00ffffff) | 0x09000000;
    *(uint32 *)&ft4_buff_ptr2->r0 = 0x2c808080;

    ft4_buff_ptr2->x0 = ft4_buff_ptr2->x2 = x0 + power;
    ft4_buff_ptr2->x1 = ft4_buff_ptr2->x3 = x0 + power + 0x04;
    ft4_buff_ptr2->y0 = ft4_buff_ptr2->y1 = y0;
    ft4_buff_ptr2->y2 = ft4_buff_ptr2->y3 = y0 + 0x08;

    ft4_buff_ptr2->tpage = 0x0c;
    ft4_buff_ptr2->clut = 0xfa0c>>2;

    *(uint16 *)&ft4_buff_ptr2->u0 = 0x4c | (0x90<<8);
    *(uint16 *)&ft4_buff_ptr2->u1 = 0x50 | (0x90<<8);
    *(uint16 *)&ft4_buff_ptr2->u2 = 0x4c | (0x98<<8);
    *(uint16 *)&ft4_buff_ptr2->u3 = 0x50 | (0x98<<8);

    ft4_buff_ptr2++;

    if( (infi) && (power == 88) ){
        *(uint32 *)ft4_buff_ptr2 =
                    ((uint32)(ft4_buff_ptr2 + 1) & 0x00ffffff) | 0x04000000;
        *(uint32 *)&ft4_buff_ptr2->r0 = 0x64808080;
        ((SPRT *)ft4_buff_ptr2)->x0 = x0 + 0x18;
        ((SPRT *)ft4_buff_ptr2)->y0 = y0;
        *(uint32 *)&(((SPRT *)ft4_buff_ptr2)->u0) =
                                     0x28 | (0xf8<<8) | ((0xfa08>>2)<<16);
        *(uint32 *)&(((SPRT *)ft4_buff_ptr2)->w) = 0x00080028;

        ft4_buff_ptr2++;
    }
    addPrims( &Disp_env_ptr->ot[2], ft4_buff_ptr1, ft4_buff_ptr2 - 1 );
    Map_prim_ptr = (POLY_FT4 *)ft4_buff_ptr2;
}

/*==================================================================*/
void    Sub_screen_basic_param_set( void )
{
    sint32          d0, d1, d2;
    sint32          x0;

    SPRT            *sprt_buff_ptr1, *sprt_buff_ptr2;

    d0 = (Player_work[0].life_max - 0x01)>>4;
    d1 = Player_work[0].life;

    sprt_buff_ptr1 = sprt_buff_ptr2 = (SPRT *)Map_prim_ptr;

    ((DR_MODE *)sprt_buff_ptr2)->tag = 0x02000000;
    ((DR_MODE *)sprt_buff_ptr2)->code[0] = 0xe1000000 | 0x0d;
                                            /* テクスチャナンバー */
    ((DR_MODE *)sprt_buff_ptr2)->code[1] = 0x00000000;
    *((uint32 *)sprt_buff_ptr2) =
                    ((uint32)(sprt_buff_ptr2 + 1)  & 0x00ffffff) | 0x02000000;
    sprt_buff_ptr2++;

    for( x0 = 0; x0 <= d0; x0++ ){
        *(uint32 *)sprt_buff_ptr2 =
                    ((uint32)(sprt_buff_ptr2 + 1) & 0x00ffffff) | 0x04000000;
        *(uint32 *)&sprt_buff_ptr2->r0 = 0x64808080;
        *(uint32 *)&sprt_buff_ptr2->x0 = (x0 * 0x05 + 0x31) | (0x24<<16);
        *(uint32 *)&sprt_buff_ptr2->w = 0x00080008;

        if( d1 > x0 * 0x10 ){
            if( ((d1 - 0x10) > x0 * 0x10) || (!(d1 % 0x10)) )
                d2 = (0xf9d4<<14) | 0xb870;
            else
                d2 = (0xf9d4<<14) | 0xb878;
        } else {
            d2 = (0xf9d4<<14) | 0xb880;
        }
        *(uint32 *)&sprt_buff_ptr2->u0 = d2;
        sprt_buff_ptr2++;
    }

    sprt_buff_ptr2 = Sub_screen_basic_param_set_sub( sprt_buff_ptr2,
                0x00a4 | 0x24<<16, Game_work.metal_stock, 0x06 | (0x03<<8) );
    sprt_buff_ptr2 = Sub_screen_basic_param_set_sub( sprt_buff_ptr2,
                0x0106 | 0x24<<16, Game_work.play_time / (30 * 60 * 60),
                                                          0x02 | (0x00<<8) );
    sprt_buff_ptr2 = Sub_screen_basic_param_set_sub( sprt_buff_ptr2,
                0x011a | 0x24<<16, Game_work.play_time / (30 * 60) % 60,
                                                          0x02 | (0x00<<8) );

    addPrims( &Disp_env_ptr->ot[2], sprt_buff_ptr1, sprt_buff_ptr2 - 1 );
    Map_prim_ptr = (POLY_FT4 *)sprt_buff_ptr2;
}

/*==================================================================*/
SPRT    *Sub_screen_basic_param_set_sub( SPRT *ptr, uint32 pos,
                                                    sint32 num, sint32 flag )
{
    sint32          d0, d1;

    for( d0 = (flag & 0xff) - 1; d0 >= 0x00; d0-- ){
        d1 = num % 10;
        if( ((d0 == (flag & 0xff) - 1) && (!(flag & 0x0200))) ||
                                             (num) || (!(flag & 0x0100)) ){
            *(uint32 *)ptr = ((uint32)(ptr + 1) & 0x00ffffff) | 0x04000000;
            *(uint32 *)&ptr->r0 = 0x64808080;
            *(uint32 *)&ptr->x0 = d0 * 0x07 + pos;
            *(uint32 *)&ptr->w = 0x00080008;
            *(uint32 *)&ptr->u0 = (d1 * 0x08 + 0x60) | (0xb0<<8) |
                                                            (0xf9d4<<14);
            ptr++;
        }
        num /= 10;
    }
    return( ptr );
}

/*==================================================================*/
void    Sub_screen_status_param_set( sint32 d0 )
{
    sint32          d1, d2;
    sint32          x0;

    PL_WORK         *pp;
    SPRT            *sprt_buff_ptr1, *sprt_buff_ptr2;

    pp = &Player_work[0];
    sprt_buff_ptr1 = sprt_buff_ptr2 = (SPRT *)Map_prim_ptr;

    d1 = pp->weapon_data[d0].bullet_left;
    if( (d2 = Player_weapon_bullet_calc(pp, d0)) < 0x7fff ){
        ((DR_MODE *)sprt_buff_ptr2)->tag = 0x02000000;
        ((DR_MODE *)sprt_buff_ptr2)->code[0] = 0xe1000000 | 0x0c;
                                            /* テクスチャナンバー */
        ((DR_MODE *)sprt_buff_ptr2)->code[1] = 0x00000000;
        *((uint32 *)sprt_buff_ptr2) =
                    ((uint32)(sprt_buff_ptr2 + 1) & 0x00ffffff) | 0x02000000;
        sprt_buff_ptr2++;

        *(uint32 *)sprt_buff_ptr2 =
                    ((uint32)(sprt_buff_ptr2 + 1) & 0x00ffffff) | 0x04000000;
        *(uint32 *)&sprt_buff_ptr2->r0 = 0x64808080;
        *(uint32 *)&sprt_buff_ptr2->x0 = 0x008c00d1;
        *(uint32 *)&sprt_buff_ptr2->w = 0x00080006;
        *(uint32 *)&sprt_buff_ptr2->u0 = 0x40 | (0xf0<<8) | (0xfa08<<14);
        sprt_buff_ptr2++;

        sprt_buff_ptr2 = Sub_screen_status_param_set_sub( sprt_buff_ptr2,
                                    0x00b4 | 0x8c<<16, d1, 0x04 | (0x00<<8) );
        sprt_buff_ptr2 = Sub_screen_status_param_set_sub( sprt_buff_ptr2,
                                    0x00d8 | 0x8c<<16, d2, 0x04 | (0x00<<8) );
        addPrims( &Disp_env_ptr->ot[2], sprt_buff_ptr1, sprt_buff_ptr2 - 1 );
        Map_prim_ptr = (POLY_FT4 *)sprt_buff_ptr2;
    }
}

/*==================================================================*/
SPRT    *Sub_screen_status_param_set_sub( SPRT *ptr, uint32 pos,
                                                    sint32 num, sint32 flag )
{
    sint32          d0, d1;

    for( d0 = (flag & 0xff) - 1; d0 >= 0x00; d0-- ){
        d1 = num % 10;
        if( ((d0 == (flag & 0xff) - 1) && (!(flag & 0x0200))) ||
                                             (num) || (!(flag & 0x0100)) ){
            *(uint32 *)ptr = ((uint32)(ptr + 1) & 0x00ffffff) | 0x04000000;
            *(uint32 *)&ptr->r0 = 0x64808080;
            *(uint32 *)&ptr->x0 = d0 * 0x07 + pos;
            *(uint32 *)&ptr->w = 0x00080006;
            *(uint32 *)&ptr->u0 = (d1 * 0x08) | (0xc0<<8) | (0xfa08<<14);
            ptr++;
        }
        num /= 10;
    }
    return( ptr );
}

/*==================================================================*/
void    Sub_screen_back_ground_set( void )
{
    sint32          x0, y0;

    SPRT            *sprt_buff_ptr1, *sprt_buff_ptr2;

    sprt_buff_ptr1 = sprt_buff_ptr2 = (SPRT *)Map_prim_ptr;

    ((DR_MODE *)sprt_buff_ptr2)->tag = 0x02000000;
    ((DR_MODE *)sprt_buff_ptr2)->code[0] = 0xe1000000 | 0x0d;
                                            /* テクスチャナンバー */
    ((DR_MODE *)sprt_buff_ptr2)->code[1] = 0x00000000;
    *((uint32 *)sprt_buff_ptr2) =
                    ((uint32)(sprt_buff_ptr2 + 1)  & 0x00ffffff) | 0x02000000;
    sprt_buff_ptr2++;

    for( y0 = 0; y0 <= 0x04; y0++ ){
        for( x0 = 0; x0 <= 0x06; x0++ ){
            *(uint32 *)sprt_buff_ptr2 =
                    ((uint32)(sprt_buff_ptr2 + 1) & 0x00ffffff) | 0x04000000;
            *(uint32 *)&sprt_buff_ptr2->r0 = 0x64808080;
            *(uint32 *)&sprt_buff_ptr2->x0 =
                    (((x0 - 1) * 0x40 + (System_timer & 0x3f)) & 0xffff) |
                    (((y0 - 1) * 0x40 + (System_timer & 0x3f))<<16);
            *(uint32 *)&sprt_buff_ptr2->u0 = (0xf9dc<<14) | 0x88c0;
            *(uint32 *)&sprt_buff_ptr2->w = 0x00400040;

            sprt_buff_ptr2++;
        }
    }

    addPrims( &Disp_env_ptr->ot[7], sprt_buff_ptr1, sprt_buff_ptr2 - 1 );
    Map_prim_ptr = (POLY_FT4 *)sprt_buff_ptr2;
}

/*==================================================================*/
void    Sub_screen_sound_reinit( PL_WORK *pp )
{
    if( (pp->routine_1 == PL_R1_SUPER_DASH) && (pp->routine_2 == 4) ){
        Sound_call( SE_ROCKMAN_ROLLER_GO, 0, 0 );
    }

    if( (pp->shot_status_flag & PL_SHOT_ON_FLAG) ){
        if( (pp->shot_status_flag & PL_SHOT_ON_FLAG) == PL_SHOT_ON_R ){
            if( (pp->weapon_right_no == 0x04) && (pp->shot_rno_0 == 2) )
                Sound_call2(SE_ROCKMAN_DRILL, &pp->parts_posl[4]);

            if( (pp->weapon_right_no == 0x07) && (pp->shot_rno_0 == 2) )
                Sound_call2(SE_ROCKMAN_VACUUM_00, &pp->parts_posl[4]);

            if( (pp->weapon_right_no == 0x0c) && (pp->shot_rno_0 == 2) )
                Sound_call2(SE_ROCKMAN_SHEILD, &pp->parts_posl[4]);

            if( (pp->weapon_right_no == 0x0d) && (pp->shot_rno_0 == 2) )
                Sound_call2(SE_ROCKMAN_LASER, &pp->parts_posl[4]);
        }
    }
}

/*==================================================================*/
/*==================================================================*/
void    Map_screen_init( void )
{
    *(uint32 *)&Map_screen_work.routine_0 = 0x00000000;
    *(uint32 *)&Map_screen_work.type = 0x00000000;
    if( Game_work.sce_no < 0x09 )
        Map_screen_work.type = 0;
    else
        Map_screen_work.type = 1;
}

/*==================================================================*/
sint32  Map_screen_task( void )
{
    uint32              joy_trg;

    MAP_SCREEN_WORK     *mp;

    joy_trg = Joy1.trg;
    mp = &Map_screen_work;

    switch( mp->routine_0 ){
        case 0:
            map_cursor_set();
            map_screen_set();

            /* スタートボタンはキャンセル優先 */
            if( joy_trg & (JOY_SE | JOY_ST | JOY_CANCEL) ){
                Sound_call( SE_CANCEL, 1, 0 );
                return( 1 );
            }

            if( ((joy_trg & (JOY_R1 | JOY_LR | JOY_DECISION)) == 0) !=
                                    ((joy_trg & (JOY_L1 | JOY_LL)) == 0) ){
                if( joy_trg & (JOY_L1 | JOY_LL) ){
                    if( (--mp->type2) < 0 ) mp->type2 = (mp->type > 0) + 1;
                } else {
                    if( (++mp->type2) > (mp->type > 0) + 1 ) mp->type2 = 0;
                }

                Sound_call( SE_DECISION, 1, 0 );
                mp->routine_0++;
                break;
            }
            break;

        case 1:
            if( !mp->type )
                Cd_read_comb( map_a_file_code[mp->type2] );
            else
                Cd_read_comb( map_b_file_code[mp->type2] );

            mp->routine_0++;
            break;

        case 2:
            if( !Cd_read_sync2() ) mp->routine_0 = 0;
            break;
    }
    return( 0 );
}

/*==================================================================*/
/*      Game Map Screen Set                                         */
/*==================================================================*/
static  void    map_screen_set( void )
{
    POLY_FT4    *ft4_buff_ptr;

    ft4_buff_ptr = Map_prim_ptr++;

    *(uint32 *)ft4_buff_ptr = 0x09000000;
    *(uint32 *)&ft4_buff_ptr->r0 = 0x2c808080;

    ft4_buff_ptr->x0 = ft4_buff_ptr->x2 = 32;
    ft4_buff_ptr->x1 = ft4_buff_ptr->x3 = 287;
    ft4_buff_ptr->y0 = ft4_buff_ptr->y1 = 0;
    ft4_buff_ptr->y2 = ft4_buff_ptr->y3 = 240;

    ft4_buff_ptr->tpage = (0x0c) | (0x01<<7);
    ft4_buff_ptr->clut = (0xfa00>>2);

    *(uint16 *)&ft4_buff_ptr->u0 = 0x00 | (0x00<<8);
    *(uint16 *)&ft4_buff_ptr->u1 = 0xff | (0x00<<8);
    *(uint16 *)&ft4_buff_ptr->u2 = 0x00 | (0xf0<<8);
    *(uint16 *)&ft4_buff_ptr->u3 = 0xff | (0xf0<<8);

    AddPrim( &Disp_env_ptr->ot[2], ft4_buff_ptr );
}

/*==================================================================*/
static  void    map_cursor_set( void )
{
    sint32      d0, d1;
    sint32      x0, y0;
    GAME_WORK   *gp;

    POLY_FT4    *ft4_buff_ptr;

    gp = &Game_work;

    switch( gp->stage_no ){
        case 0x17:
        case 0x1d:
            return;

        case 0x03:
        case 0x1b:
            if( gp->area_no < 0x03 )
                d0 = gp->area_no;
            else
                d0 = 0x03;
            break;

        case 0x0f:
            d0 = 0x06;
            break;

        case 0x13:
            d0 = 0x0a;
            break;

        case 0x1c:
            d0 = 0x08;
            break;

        default:
            d0 = gp->stage_no;
            break;
    }

    x0 = map_cursor_pos[d0].vx + 0x20;
    y0 = map_cursor_pos[d0].vy;
    d1 = (System_timer & 0x07) * 0x10;
    ft4_buff_ptr = Map_prim_ptr++;

    *(uint32 *)ft4_buff_ptr = 0x09000000;
    *(uint32 *)&ft4_buff_ptr->r0 = 0x2c808080;

    ft4_buff_ptr->x0 = ft4_buff_ptr->x2 = x0 - 0x08;
    ft4_buff_ptr->x1 = ft4_buff_ptr->x3 = x0 + 0x07;
    ft4_buff_ptr->y0 = ft4_buff_ptr->y1 = y0 - 0x08;
    ft4_buff_ptr->y2 = ft4_buff_ptr->y3 = y0 + 0x07;

    ft4_buff_ptr->tpage = (0x0c) | (0x01<<7);
    ft4_buff_ptr->clut = (0xfa00>>2);

    *(uint16 *)&ft4_buff_ptr->u0 = (d1 + 0x00) | (0xf0<<8);
    *(uint16 *)&ft4_buff_ptr->u1 = (d1 + 0x0f) | (0xf0<<8);
    *(uint16 *)&ft4_buff_ptr->u2 = (d1 + 0x00) | (0xff<<8);
    *(uint16 *)&ft4_buff_ptr->u3 = (d1 + 0x0f) | (0xff<<8);

    AddPrim( &Disp_env_ptr->ot[2], ft4_buff_ptr );
}

/*==================================================================*/
/*  "sub_scrn.c"    End of File                                     */
/*==================================================================*/

EM09_49.C#

c0f_move_init                                                                                                                                                                                                                                                                                                                                                                                                                                           ズと輝度の設定 */
        *(uint32 *)&wk_p->size.vz = 0x42100200;
        EM_Char_Set(wk_p,0x01,0);
        wk_p->routine_0++;
    }
    Obj_pos_adj_round(&wk_p->pos_l,&wk_p->pos);
    EM_Char_Move(wk_p);
    if(wk_p->be_flag & TRANS){
        Model_Shadow_Trans(wk_p,50,683,0);
    }
}

/*--------------------------------------------------------------*/
/*  警部                                                      */
/*--------------------------------------------------------------*/
void    StXX_em26_49_move(EM_WORK *wk_p)
{
    if(wk_p->routine_0 == 0){
        Model_work_init(wk_p,0);
        *(uint32 *)&wk_p->size.vx = 0x02000200;         /* サイズと輝度の設定 */
        *(uint32 *)&wk_p->size.vz = 0x42100200;
        EM_Char_Set(wk_p,0x01,0);
        wk_p->routine_0++;
    }
    Obj_pos_adj_round(&wk_p->pos_l,&wk_p->pos);
    EM_Char_Move(wk_p);
    if(wk_p->be_flag & TRANS){
        Model_Shadow_Trans(wk_p,50,683,0);
    }
}

/*--------------------------------------------------------------*/
/*  TVレポーター                                             */
/*--------------------------------------------------------------*/
void    StXX_em2d_49_move(EM_WORK *wk_p)
{
    if(wk_p->routine_0 == 0){
        Model_work_init(wk_p,0);
        *(uint32 *)&wk_p->size.vx = 0x02000200;         /* サイズと輝度の設定 */
        *(uint32 *)&wk_p->size.vz = 0x42100200;
        wk_p->routine_0++;
    }

    if(wk_p->routine_1 == 0){
        switch(wk_p->routine_2){
            case 0:
                EM_Char_Set(wk_p,0x00,0);
                wk_p->routine_2++;
                break;

            case 1:
                break;

            default:
                break;
        }
    } else {
        switch(wk_p->routine_2){
            case 0:
                EM_Char_Set(wk_p,0x01,0);
                wk_p->routine_2++;
                break;
    
            case 1:
                break;

            default:
                break;
        }
    }

    Obj_pos_adj_round(&wk_p->pos_l,&wk_p->pos);
    EM_Char_Move(wk_p);
    if(wk_p->be_flag & TRANS){
        Model_Shadow_Trans(wk_p,50,683,0);
    }
}

/*--------------------------------------------------------------*/
/*  おねえさん                                                   */
/*--------------------------------------------------------------*/
void    StXX_em34_49_move(EM_WORK *wk_p)
{
    if(wk_p->routine_0 == 0){
        Model_work_init(wk_p,0);
        *(uint32 *)&wk_p->size.vx = 0x02000200;         /* サイズと輝度の設定 */
        *(uint32 *)&wk_p->size.vz = 0x42100200;
        EM_Char_Set(wk_p,0x01,0);
        wk_p->routine_0++;
    }
    Obj_pos_adj_round(&wk_p->pos_l,&wk_p->pos);
    EM_Char_Move(wk_p);
    if(wk_p->be_flag & TRANS){
        Model_Shadow_Trans(wk_p,50,683,0);
    }
}

/*--------------------------------------------------------------*/
/*  ワイリー                                                    */
/*--------------------------------------------------------------*/
void    StXX_em38_49_move(EM_WORK *wk_p)
{
    if(wk_p->routine_0 == 0){
        Model_work_init(wk_p,0);
        *(uint32 *)&wk_p->size.vx = 0x02000200;         /* サイズと輝度の設定 */
        *(uint32 *)&wk_p->size.vz = 0x42100200;
        EM_Char_Set(wk_p,0x01,0);
        wk_p->routine_0++;
    }
    Obj_pos_adj_round(&wk_p->pos_l,&wk_p->pos);
    EM_Char_Move(wk_p);
    if(wk_p->be_flag & TRANS){
        Model_Shadow_Trans(wk_p,50,683,0);
    }
}

/*--------------------------------------------------------------*/
/*  カメラマン                                                   */
/*--------------------------------------------------------------*/
void    StXX_em5c_49_move(EM_WORK *wk_p)
{
    if(wk_p->routine_0 == 0){
        Model_work_init(wk_p,0);
        *(uint32 *)&wk_p->size.vx = 0x02000200;         /* サイズと輝度の設定 */
        *(uint32 *)&wk_p->size.vz = 0x42100200;
        wk_p->routine_0++;
    }

    if(wk_p->routine_1 == 0){
        switch(wk_p->routine_2){
            case 0:
                EM_Char_Set(wk_p,0x00,0);
                wk_p->routine_2++;
                break;

            case 1:
                break;

            default:
                break;
        }
    } else {
        switch(wk_p->routine_2){
            case 0:
                EM_Char_Set(wk_p,0x01,0);
                wk_p->routine_2++;
                break;
    
            case 1:
                break;

            default:
                break;
        }
    }

    Obj_pos_adj_round(&wk_p->pos_l,&wk_p->pos);
    EM_Char_Move(wk_p);
    if(wk_p->be_flag & TRANS){
        Model_Shadow_Trans(wk_p,50,683,0);
    }
}

/*--------------------------------------------------------------*/
/*  雲                                                           */
/*--------------------------------------------------------------*/
typedef struct  {
    VECTOR  pos;            /* 位置 */
    sint16  ctr;            /* カウンター */
    sint16  a;              /* 進む方向 */
    sint16  spd;            /* 進む速度 */
    sint16  pad;
}   SHL38_FREE;

SHL_WORK    *StXX_set_shl38(SVECTOR *vp,sint16 a,sint16 spd,uint8 type)
{
    SHL_WORK *sp;
    SHL38_FREE *fp;

    sp = (SHL_WORK *)0x00000000;
    if((sp = (SHL_WORK *)Open_SHL_WORK())){
        sp->be_flag |= MOVE;
        sp->id = 0x38;
        sp->type = type;

        fp = (SHL38_FREE *)&sp->free[0];
        *(uint32 *)&fp->pos.vx = *(uint32 *)&vp->vx;
        *(uint32 *)&fp->pos.vz = *(uint32 *)&vp->vz;
        fp->ctr = 0;
        fp->a = a;
        fp->spd = spd;
    }

    return(sp);
}

void    StXX_shl38_move(SHL_WORK *wk_p)
{
    VECTOR vec;
    SHL38_FREE *fp;

    if(wk_p->routine_0 == 0){
        wk_p->be_flag |= (TRANS | MODEL);

        Model_work_init(wk_p,&wk_p->type);
        wk_p->efc.model.rgbc = 0x00808080;
        wk_p->routine_1++;
    }

    fp = (SHL38_FREE *)&wk_p->free[0];
    fp->ctr += fp->spd;
    wk_p->pos_l.vx = (fp->pos.vx << 16) + ((fp->ctr * rsin(fp->a)) << 4);
    wk_p->pos_l.vz = (fp->pos.vz << 16) + ((fp->ctr * rcos(fp->a)) << 4);
    wk_p->pos_l.vy = fp->pos.vy << 16;
    wk_p->efc.model.sv.vx = wk_p->pos.vx = wk_p->pos_l.vx >> 16;
    wk_p->efc.model.sv.vz = wk_p->pos.vz = wk_p->pos_l.vz >> 16;
    wk_p->efc.model.sv.vy = wk_p->pos.vy = wk_p->pos_l.vy >> 16;

    E_MATRIX(wk_p->efc.model.m);                            /* マトリックスの初期化 */
    vec.vx = vec.vy = vec.vz = 4096;
    ScaleMatrix(&wk_p->efc.model.m,&vec);
}

/*==============================================================*/
/*  'EM09_49.C' End of File                                     */
/*==============================================================*/

(Source: koolaidman)