fae0beef创建于 7月26日历史提交
// BanjoDecomp: core2/code_73640.c
#include <ultra64.h>
#include "functions.h"
#include "variables.h"

#include "bk_time.h"

#define _73640_MAX(s,t) ((s < t)? t: s)
#define _73640_MIN(s,t) ((s > t)? t: s)

// [port] _new funcs have varying signatures (struct7s*/struct8s*/void* returns, asset_e/item_e/s32 params).
// On N64 these were all equivalent. Use a generic function pointer type and cast in initializer.
typedef void *(*ItemPrintNewFn)(s32);

typedef struct item_print_s{
    ItemPrintNewFn unk0;
    void (*unk4)(s32, struct8s *);
    void (*unk8)(enum item_e, struct8s *, Gfx**, Mtx**, Vtx**);
    void (*unkC)(s32, struct8s *);
    s32 unk10;
    struct8s *unk14;
} ItemPrint;


s32 func_802FAD9C(enum item_e item_id);

/* .data */
s16 D_803692E0[6] = {
    ASSET_89D_ZOOMBOX_SPRITE, 
    ASSET_7D9_SPRITE_NOTE, 
    ASSET_7DD_SPRITE_HEALTH, 
    ASSET_35F_MODEL_JIGGY, 
    0x360, 
    -1
};
// Lighthouse [port] This array was incorrectly sized
s16 D_803692EC[5] = {
    ASSET_580_SPRITE_RED_FEATHER, 
    ASSET_6D1_SPRITE_GOLDFEATHER, 
    ASSET_41A_SPRITE_MUMBO_TOKEN, 
    ASSET_36D_SPRITE_BLUE_EGG, 
    -1
};

#define NF(fn) (ItemPrintNewFn)(fn)
#define UF(fn) (void (*)(s32, struct8s *))(fn)
#define DF(fn) (void (*)(enum item_e, struct8s *, Gfx**, Mtx**, Vtx**))(fn)
ItemPrint D_803692F8[0x2C] = {
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon2score_draw), UF(fxcommon2score_free), 5, NULL }, //ITEM_0_HOURGLASS_TIMER
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon2score_draw), UF(fxcommon2score_free), 0, NULL }, // ITEM_1_SKULL_HOURGLASS_TIMER
    { NF(fxcommon1score_new), UF(fxcommon1score_update), DF(fxcommon1score_draw), UF(fxcommon1score_free), 0, NULL }, //2
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon2score_draw), UF(fxcommon2score_free), 5, NULL }, //ITEM_3_PROPELLOR_TIMER
    { NF(fxcommon1score_new), UF(fxcommon1score_update), DF(fxcommon1score_draw), UF(fxcommon1score_free), 0, NULL }, //
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon2score_draw), UF(fxcommon2score_free), 0, NULL }, //ITEM_5_XMAS_TREE_TIMER
    { NF(fxcommon1score_new), UF(fxcommon1score_update), DF(fxcommon1score_draw), UF(fxcommon1score_free), 0, NULL }, //ITEM_6_HOURGLASS
    { NF(fxcommon1score_new), UF(fxcommon1score_update), DF(fxcommon1score_draw), UF(fxcommon1score_free), 0, NULL }, //ITEM_7_SKULL_HOURGLASS
    { NF(fxcommon1score_new), UF(fxcommon1score_update), DF(fxcommon1score_draw), UF(fxcommon1score_free), 0, NULL }, //8
    { NF(fxcommon1score_new), UF(fxcommon1score_update), DF(fxcommon1score_draw), UF(fxcommon1score_free), 0, NULL }, //ITEM_9_PROPELLOR
    { NF(fxcommon1score_new), UF(fxcommon1score_update), DF(fxcommon1score_draw), UF(fxcommon1score_free), 0, NULL }, //10
    { NF(fxcommon1score_new), UF(fxcommon1score_update), DF(fxcommon1score_draw), UF(fxcommon1score_free), 0, NULL }, //ITEM_B_XMAS_TREE
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon2score_draw), UF(fxcommon2score_free), 1, NULL }, //ITEM_C_NOTE
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon2score_draw), UF(fxcommon2score_free), 1, NULL }, //ITEM_D_EGGS
    { NF(fxcommon3score_new), UF(fxcommon3score_update), DF(fxcommon3score_draw), UF(fxcommon3score_free), 3, NULL }, //ITEM_14_HEALTH
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon2score_draw), UF(fxcommon2score_free), 1, NULL }, //ITEM_F_RED_FEATHER
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon2score_draw), UF(fxcommon2score_free), 1, NULL }, //ITEM_10_GOLD_FEATHER
    { NF(fxcommon1score_new), UF(fxcommon1score_update), DF(fxcommon1score_draw), UF(fxcommon1score_free), 0, NULL }, //17
    { NF(fxjinjoscore_new), UF(fxjinjoscore_update), DF(fxjinjoscore_draw), UF(fxjinjoscore_free),   3, NULL }, //ITEM_12_JINJOS
    { NF(fxhoneycarrierscore_new), UF(fxhoneycarrierscore_update), DF(fxhoneycarrierscore_draw), UF(fxhoneycarrierscore_free), 0, NULL }, //ITEM_13_EMPTY_HONEYCOMB
    { NF(fxhealthscore_new), UF(fxhealthscore_update), DF(fxhealthscore_draw), UF(fxhealthscore_free),  0, NULL }, //ITEM_14_HEALTH
    { NF(fxcommon1score_new), UF(fxcommon1score_update), DF(fxcommon1score_draw), UF(fxcommon1score_free), 0, NULL }, //ITEM_15_HEALTH_TOTAL
    { NF(fxlifescore_new), UF(fxlifescore_update), DF(fxlifescore_draw), UF(fxlifescore_free),    6, NULL }, //ITEM_16_LIFE
    { NF(fxairscore_new), UF(fxairscore_update), DF(fxairscore_draw), UF(fxairscore_free),     0, NULL }, //ITEM_17_AIR
    { NF(fxcommon3score_new), UF(fxcommon3score_update), DF(fxcommon3score_draw), UF(fxcommon3score_free), 2, NULL }, //ITEM_18_GOLD_BULLIONS
    { NF(fxcommon3score_new), UF(fxcommon3score_update), DF(fxcommon3score_draw), UF(fxcommon3score_free), 2, NULL }, //ITEM_19_ORANGE
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon2score_draw), UF(fxcommon2score_free), 6, NULL }, //ITEM_1A_PLAYER_VILE_SCORE
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon2score_draw), UF(fxcommon2score_free), 0, NULL }, //ITEM_1B_VILE_VILE_SCORE
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon2score_draw), UF(fxcommon2score_free), 2, NULL }, //ITEM_1C_MUMBO_TOKEN
    { NF(fxcommon3score_new), UF(fxcommon3score_update), DF(fxcommon3score_draw), UF(fxcommon3score_free), 0, NULL }, //ITEM_1D_GRUMBLIE
    { NF(fxcommon3score_new), UF(fxcommon3score_update), DF(fxcommon3score_draw), UF(fxcommon3score_free), 0, NULL }, //ITEM_1E_YUMBLIE
    { NF(fxcommon3score_new), UF(fxcommon3score_update), DF(fxcommon3score_draw), UF(fxcommon3score_free), 2, NULL }, //ITEM_1F_GREEN_PRESENT
    { NF(fxcommon3score_new), UF(fxcommon3score_update), DF(fxcommon3score_draw), UF(fxcommon3score_free), 2, NULL }, //ITEM_20_BLUE_PRESENT
    { NF(fxcommon3score_new), UF(fxcommon3score_update), DF(fxcommon3score_draw), UF(fxcommon3score_free), 2, NULL }, //ITEM_21_RED_PRESENT
    { NF(fxcommon3score_new), UF(fxcommon3score_update), DF(fxcommon3score_draw), UF(fxcommon3score_free), 2, NULL }, //ITEM_22_CATERPILLAR
    { NF(fxcommon3score_new), UF(fxcommon3score_update), DF(fxcommon3score_draw), UF(fxcommon3score_free), 2, NULL }, //ITEM_23_ACORNS
    { NF(fxcommon3score_new), UF(fxcommon3score_update), DF(fxcommon3score_draw), UF(fxcommon3score_free), 0, NULL }, //ITEM_24_TWINKLY_SCORE
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon2score_draw), UF(fxcommon2score_free), 4, NULL }, //ITEM_25_MUMBO_TOKEN_TOTAL
    { NF(fxcommon3score_new), UF(fxcommon3score_update), DF(fxcommon3score_draw), UF(fxcommon3score_free), 4, NULL }, //ITEM_26_JIGGY_TOTAL
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon2score_draw), UF(fxcommon2score_free), 2, NULL }, //ITEM_27_JOKER_CARD
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon1score_draw), UF(fxcommon2score_free), 5, NULL }, //40
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon1score_draw), UF(fxcommon2score_free), 3, NULL }, //41
    { NF(fxcommon2score_new), UF(fxcommon2score_update), DF(fxcommon1score_draw), UF(fxcommon2score_free), 2, NULL }, //42
    { NF(fxcommon3score_new), UF(fxcommon3score_update), DF(fxcommon3score_draw), UF(fxcommon3score_free), 2, NULL }  //43
};

/* .bss */
s32 D_803810B0;
f32 itemPrintValues[0x2C]; //item_print_value
s32 D_80381168[0x2C]; // item_e => comusic_e
f32 D_80381218[0x2C]; //item_sfx_volume???
s32 D_803812C8[0x2C]; //comusic_e
s32 D_80381378[0x2C]; //sfx_e
void *D_80381428[10];
void *D_80381450[10];
s32 D_80381478[0X2C];

/* .code */
void itemPrint_reset(void){
    s32 i;

    for(i = 0; i < 0x2C; i++){
        
        itemPrintValues[i] = item_getCount(i);
        D_80381378[i] = 0;
        D_803812C8[i] = 0;
        D_80381168[i] = 0;
        D_80381218[i] = 0.7f; //D_80377360
        
    }
}

void func_802FA69C(void){
    s32 i;

    D_803810B0 = 1;
    for(i = 0; i< 0x2C; i++){
        D_803692F8[i].unk14 = D_803692F8[i].unk0(i);
        func_802FB104(D_803692F8[i].unk10, D_803692F8[i].unk14);
    }
    itemPrint_reset();
}

void func_802FA718(s32 arg0){
    D_803810B0 = arg0;
}


void itemPrint_update(void) {
    f32 diff;
    s32 i;
    f32 sign;

    func_802FB1CC();
    for(i = 0; i< 0x2C; i++){
        if(func_802FAD9C(i)){
            if (item_getCount(i) != (s32) (itemPrintValues[i] + 0.01)) {
                diff = (f32) item_getCount(i) - itemPrintValues[i];
                sign = (diff >= 0.0f) ? 1.0f : -1.0f;
                if (D_80381378[i] != 0) {
                    itemPrintValues[i] += sign *_73640_MIN(time_getDelta() * 6.0f, 1.0);
                } else {
                    itemPrintValues[i] += (sign * _73640_MIN(time_getDelta() * _73640_MAX(diff, 8.0f), 1.0));
                }
                if ((D_80381168[i] != 0) && ((globalTimer_getTime() & 7) == 0)) {
                    coMusicPlayer_playMusic(D_80381168[i], 32000);
                }
                if (D_80381378[i] != 0) {
                    if ((D_80381478[i] != 0) && ((s32) diff != D_80381478[i])) {
                        if (itemPrintValues[i] > 9.0f) {
                            gcsfx_playWithPitch(D_80381378[i], D_80381218[i], 0x7D00);
                             D_80381218[i] = _73640_MIN(D_80381218[i] + 0.1, 2.0);
                        }
                    }
                }
                D_80381478[i] = diff;
                func_802FB020(D_803692F8[i].unk14, 1);
                if ((i == ITEM_14_HEALTH) || (i == ITEM_17_AIR)) {
                    func_802FB020(D_803692F8[0x16].unk14, 1);
                }
                
                if (item_getCount(i) == (s32) (itemPrintValues[i] + 0.01)) {
                    do{
                        if (D_803812C8[i] != 0) { 
                            coMusicPlayer_playMusic(D_803812C8[i], 0x7D00);
                        }
                        
                        D_80381378[i] = 0;
                        D_803812C8[i] = 0;
                        D_80381168[i] = 0;
                        D_80381218[i] = 0.7f;
                        D_80381478[i] = 0;
                    }while(0);
                }
            }
        }
    }

    for(i = 0; i< 0x2C; i++){
        func_802FB15C(D_803692F8[i].unk10, D_803692F8[i].unk14);
        D_803692F8[i].unk4(i, D_803692F8[i].unk14);
    }
}


void itemPrint_draw(Gfx **gfx, Mtx **mtx, Vtx **vtx) {
    s32 i;
    if(D_803810B0 && level_get() != LEVEL_D_CUTSCENE){
        for(i = 0; i < 0x2C; i++){
            if(!func_802E4A08() || i < 6){
                if(func_802FB0D4(D_803692F8[i].unk14)){
                    D_803692F8[i].unk8(i, D_803692F8[i].unk14, gfx, mtx, vtx);
                }
            }
        }
    }
}

void func_802FAC3C(void){
    s32 i;
    for(i = 0; i< 0x2C; i++){
        func_802FB194(D_803692F8[i].unk10, D_803692F8[i].unk14);
        D_803692F8[i].unkC(i, D_803692F8[i].unk14);
    }
}


void code_73640_printItemCount(enum item_e item_id){
    if(func_802FB0D4(D_803692F8[item_id].unk14) == 2 || item_id < 6 || item_id == ITEM_17_AIR ){
        itemPrintValues[item_id] += ((f32)item_getCount(item_id) - itemPrintValues[item_id] )*0.7;
    }
    func_802FB020(D_803692F8[item_id].unk14, 1);
}

void func_802FAD64(enum item_e item_id){
    func_802FB020(D_803692F8[item_id].unk14, 3);
}

s32 func_802FAD9C(enum item_e item_id){
    return (func_802FB0D4(D_803692F8[item_id].unk14) == 2);
}

bool func_802FADD4(enum item_e item_id){
    s32 v0 = func_802FB0D4(D_803692F8[item_id].unk14);
    return (v0 == 2)||(v0 == 1);
}

s32 itemPrint_getValue(s32 item_id){
    return itemPrintValues[item_id] + 0.01;
}

void itemPrint_init(void){
    s32 i;
    BKSpriteDisplayData *sp40;
    for(i = 0; D_803692E0[i] != -1; i++){
        D_80381428[i] = assetcache_get(D_803692E0[i]);
    }
    for(i = 0; D_803692EC[i] != -1; i++){
        D_80381450[i] = codeB3A80_getSprite(D_803692EC[i], &sp40);
    }
}

void itemPrint_free(void){
    s32 i;
    for(i = 0; D_803692E0[i] != -1; i++){
        assetcache_release(D_80381428[i]);
    }
    for(i = 0; D_803692EC[i] != -1; i++){
        assetcache_release(D_80381450[i]);
    }
}

void func_802FAFAC(enum item_e item_id, enum comusic_e music_id){
    D_80381168[item_id] = music_id;
}

void func_802FAFC0(enum item_e item_id, enum comusic_e music_id){
    D_803812C8[item_id] = music_id;
}

void func_802FAFD4(enum item_e item_id, enum sfx_e sfx_id){
    D_80381378[item_id] = sfx_id;
}

bool func_802FAFE8(enum item_e item_id){
    return func_802FCD98(D_803692F8[item_id].unk14);
}