Skip to content

Instantly share code, notes, and snippets.

@camprevail
Created February 18, 2025 00:17
Show Gist options
  • Save camprevail/8866321fa0a7e4743217f681b360c447 to your computer and use it in GitHub Desktop.
Save camprevail/8866321fa0a7e4743217f681b360c447 to your computer and use it in GitHub Desktop.
museca - judge_hold_note decomp
void __fastcall judge_hold_note(CGameSceneComponent *cGSC_, NoteStruct *noteStruct_, __int64 flag)
{
char some_holdnote_flag; // r15
NoteStruct *noteStruct; // rbx
CGameSceneComponent *cGSC; // rdi
int note_stime; // er10
float temp_flt; // xmm0_4
int note_etime; // er14
int curTime; // eax
int adjTime; // er12
int adjTime_; // esi
int stime_delta_; // er12
int etime_delta; // esi
char isPressed; // r13
char judged; // r11
__int64 lane; // r9
__int64 v17; // rax
BUTTON_TYPE btn; // ecx
__int64 v19; // rax
BUTTON_TYPE btn_; // ecx
int freewheel; // eax
signed int charge_pct; // er12
__int64 lane_; // rax
signed int freewheel_; // eax
float etime_delta_; // xmm2_4
int judgeType_; // esi
PlayScore *ptr_PlayScore; // rcx
signed int abs_stime_delta; // er8
int v29; // er12
int judgeFrame; // eax
int currentTime; // er8
signed __int64 v32; // rcx
__int64 v33; // rcx
__int64 v34; // rax
NOTE_TYPE_INTERNAL lane___; // ecx
signed int v36; // eax
PlayScore *v37; // rcx
signed __int64 v38; // rdx
signed int stime_delta; // [rsp+88h] [rbp+10h]
if ( !noteStruct_ )
return;
some_holdnote_flag = flag;
noteStruct = noteStruct_;
cGSC = cGSC_;
if ( noteStruct_->kind_internal != EVENT_KIND_HOLD )
return;
note_stime = noteStruct_->stime_ms;
temp_flt = -300.0;
note_etime = note_stime + noteStruct_->duration_ms;
curTime = cGSC_->currentTime;
adjTime = cGSC_->currentTime - cGSC_->offset;
adjTime_ = adjTime;
stime_delta_ = adjTime - note_stime;
etime_delta = adjTime_ - note_etime;
stime_delta = stime_delta_;
if ( stime_delta_ <= -300.0 )
return;
isPressed = 0;
if ( curTime >= note_stime && curTime <= note_etime )
++noteStruct_->holdnote_window_frames;
judged = noteStruct_->judged;
if ( judged )
{
if ( cGSC_->autoplay || dead_debug_check() )
isPressed = 1;
lane = noteStruct_->lane;
if ( lane <= 5 )
{
v17 = off_1801EE5FC[lane];
switch ( lane )
{
case lane1:
btn = 4;
break;
case lane2:
btn = 5;
break;
case lane3:
btn = 6;
break;
case lane4:
btn = 7;
break;
case lane5:
btn = 8;
break;
case PEDAL_AND_MARKERS:
btn = 9;
break;
}
if ( CRVOLDevice::GetButtonPress(btn) )
isPressed = 1;
}
}
else
{
lane = noteStruct_->lane;
if ( lane <= 5 )
{
v19 = off_1801EE614[lane];
switch ( lane )
{
case 0i64:
btn_ = 4;
goto LABEL_28;
case 1i64:
btn_ = 5;
goto LABEL_28;
case 2i64:
btn_ = 6;
goto LABEL_28;
case 3i64:
btn_ = 7;
goto LABEL_28;
case 4i64:
btn_ = 8;
LABEL_28:
if ( CRVOLDevice::GetButtonTrigger(btn_) )
isPressed = 1;
break;
case 5i64:
isPressed = 0;
if ( CRVOLDevice::GetButtonTrigger(btn_pedal) )
isPressed = 1;
break;
}
}
}
freewheel = noteStruct->holdnote_freewheel_frames;
if ( freewheel )
noteStruct->holdnote_freewheel_frames = freewheel - 1;
if ( judged )
{
charge_pct = 0;
if ( !noteStruct->hold_note_ended_ )
JUMPOUT(loc_1801EDF00);
if ( noteStruct->holdnote_freewheel_frames || isPressed )// Hold notes can "freewheel", or continue to be held down on their own for 5 frames after releasing the spinner.
{
lane_ = noteStruct->lane;
++noteStruct->holdnote_active_frames;
++noteStruct->holdnote_active_frames_;
noteStruct->field_44 = 0;
*(cGSC->field_9C4 + 3 * lane_) = 0x3F800000;// array of 16 bytes[5]
cGSC->hold_note_hit_array[noteStruct->lane] = 0xE;
if ( !noteStruct->hold_note_ended )
{
if ( noteStruct->holdnote_window_frames )
charge_pct = ((125 * noteStruct->holdnote_active_frames) / (noteStruct->duration_ms / 16.700001));// Hold notes charge at a rate of 125% so they reach 100% before the end of the note
if ( some_holdnote_flag )
set_charge_frame_label(cGSC->CLayerJudgeComponent, noteStruct->lane, charge_pct, frameLabel_action_in);
set_charge_frame_label(cGSC->CLayerJudgeComponent, noteStruct->lane, charge_pct, frameLabel_draw_percent_usr);
}
freewheel_ = noteStruct->holdnote_freewheel_frames;
if ( !freewheel_ )
freewheel_ = 5;
noteStruct->holdnote_freewheel_frames = freewheel_;
if ( noteStruct->judgeType == CRITICAL )
cGSC->holdnote_charge_crit_lanemask |= 1 << noteStruct->lane;
if ( noteStruct->judgeType == NEAR )
cGSC->holdnote_charge_near_lanemask |= 1 << noteStruct->lane;
sub_1801F81A0(&cGSC->DrawLane, noteStruct->lane, noteStruct->judgeType);
}
return;
}
etime_delta_ = etime_delta;
if ( etime_delta > 0.0 )
{
judgeType_ = 1;
if ( !cGSC->field_4FC0 )
cGSC->field_4FC0 = 10;
goto LABEL_69;
}
if ( cGSC->autoplay || dead_debug_check() )
{
if ( cGSC->currentTime < note_stime )
return;
judgeType_ = CRITICAL;
goto LABEL_69;
}
if ( !isPressed )
return;
judgeType_ = CRITICAL;
ptr_PlayScore = &cGSC->PlayScore;
abs_stime_delta = abs(stime_delta_);
if ( lane == PEDAL_AND_MARKERS )
{
temp_flt = PlayScore::GetJudgeWindow(ptr_PlayScore, CRITICAL) * 1.5;// +- 72ms for pedal CRIT
if ( temp_flt >= abs_stime_delta )
goto LABEL_69;
temp_flt = PlayScore::GetJudgeWindow(&cGSC->PlayScore, NEAR) * 3.0;// +- 216ms for pedal NEAR
if ( temp_flt >= abs_stime_delta )
{
judgeType_ = NEAR;
goto LABEL_69;
}
goto LABEL_62;
}
if ( abs_stime_delta > PlayScore::GetJudgeWindow(ptr_PlayScore, CRITICAL) )// 48
{
temp_flt = PlayScore::GetJudgeWindow(&cGSC->PlayScore, NEAR) * 2.0;// 144
if ( temp_flt >= abs_stime_delta )
{
judgeType_ = NEAR;
goto LABEL_69;
}
LABEL_62:
if ( etime_delta_ >= 0.0 )
return;
judgeType_ = NEAR;
}
LABEL_69:
v29 = 0;
cGSC->field_4FE7 = 1;
cGSC->early_late_indicator = 0;
if ( judgeType_ != 1 )
cGSC->note_hit_array[noteStruct->lane] = 1;
if ( judgeType_ == NEAR )
{
if ( stime_delta < 0.0 )
{
temp_flt = floorf((abs(stime_delta) + 8.335) / 16.67);
judgeFrame = -temp_flt;
}
else
{
temp_flt = floorf((stime_delta + 8.335) / 16.67);
judgeFrame = temp_flt;
}
LOBYTE(v29) = judgeFrame >= 0;
cGSC->early_late_indicator = v29 + 2;
}
currentTime = cGSC->currentTime;
cGSC->field_4FBC = 10;
NoteStruct::SetJudgeInfo(noteStruct, judgeType_, currentTime);
if ( noteStruct->is_GA_note )
{
v32 = (&cGSC->GiftParam + 397 * noteStruct->GA_grafica_index);
cGSC->PlayScore.GiftParam__ = cGSC->PlayScore.GiftParam.GiftParam_Current;
cGSC->PlayScore.GiftParam.GiftParam_Current = v32;
update_playscore(
cGSC->currentTime,
&cGSC->PlayScore,
noteStruct->lane,
noteStruct->kind_internal,
temp_flt,
judgeType_,
2,
noteStruct->GA_grafica_index);
}
else
{
update_playscore(
cGSC->currentTime,
&cGSC->PlayScore,
noteStruct->lane,
noteStruct->kind_internal,
temp_flt,
judgeType_,
1,
noteStruct->GA_grafica_index);
}
copyNoteStruct(&cGSC->CGameSequence, noteStruct);// move noteStruct to judged noteStructs
set_judge_frame_labels(cGSC->CLayerJudgeComponent, noteStruct->lane, noteStruct->judgeType);
set_charge_frame_label(cGSC->CLayerJudgeComponent, noteStruct->lane, 0, frameLabel_charge_in);
v33 = cGSC->GameMatchingComponent;
if ( v33 )
{
sub_1801F6C50(v33, cGSC->PlayScore.total_score);
if ( cGSC->mission_mode == 1 )
sub_1801F6C20(cGSC->GameMatchingComponent, *&cGSC->PlayScore.gap1B0[4]);
sub_1801F7C30(cGSC->GameMatchingComponent);
}
if ( judgeType_ == 1 )
{
v36 = cGSC->field_4FC0;
v37 = &cGSC->PlayScore;
if ( !v36 )
v36 = 10;
cGSC->field_4FC0 = v36;
if ( noteStruct->is_GA_note )
{
v38 = (&cGSC->GiftParam + 397 * noteStruct->GA_grafica_index);
cGSC->PlayScore.GiftParam__ = cGSC->PlayScore.GiftParam.GiftParam_Current;
cGSC->PlayScore.GiftParam.GiftParam_Current = v38;
update_playscore(
cGSC->currentTime,
v37,
noteStruct->lane,
noteStruct->kind_internal,
temp_flt,
1,
2,
noteStruct->GA_grafica_index);
}
else
{
update_playscore(
cGSC->currentTime,
v37,
noteStruct->lane,
noteStruct->kind_internal,
temp_flt,
1,
1,
noteStruct->GA_grafica_index);
}
set_charge_frame_label(cGSC->CLayerJudgeComponent, noteStruct->lane, 0, frameLabel_charge_out);
noteStruct->hold_note_ended = 1;
noteStruct->hold_note_ended_ = 1;
}
else
{
sub_1801FF080(&cGSC->field_1C60, noteStruct->lane, judgeType_);
v34 = noteStruct->lane;
++noteStruct->holdnote_active_frames;
*(cGSC->field_9C4 + 3 * v34) = 0x3F800000;
cGSC->hold_note_hit_array[noteStruct->lane] = 14;
lane___ = noteStruct->lane;
if ( lane___ == PEDAL_AND_MARKERS )
{
if ( noteStruct->judgeType == CRITICAL )
cGSC->pedalnote_crit_lanemask |= 0x20u;
if ( noteStruct->judgeType == NEAR )
cGSC->pedalnote_near_lanemask |= 1 << noteStruct->lane;
}
else
{
if ( noteStruct->judgeType == CRITICAL )
cGSC->holdnote_charge_crit_lanemask |= 1 << lane___;
if ( noteStruct->judgeType == NEAR )
cGSC->holdnote_charge_near_lanemask |= 1 << noteStruct->lane;
if ( noteStruct->judgeType == CRITICAL )
cGSC->holdnote_hit_crit_lanemask |= 1 << noteStruct->lane;
if ( noteStruct->judgeType == NEAR )
cGSC->holdnote_hit_near_lanemask |= 1 << noteStruct->lane;
}
if ( cGSC->field_20427 )
++cGSC->field_19196;
if ( cGSC->field_20428 )
++cGSC->field_19200;
sub_1801F81A0(&cGSC->DrawLane, noteStruct->lane, noteStruct->judgeType);
++noteStruct->holdnote_active_frames_;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment