Merge branch 'master' of mx.cogentleman.com:cogentleman/guitarHeroButBetter

This commit is contained in:
Joseph DiMaria 2026-01-31 16:55:02 -08:00
commit 13146298bf
22 changed files with 1037890 additions and 82 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

BIN
assets/instruments/sax.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

107832
assets/songs/json/africa.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

40405
assets/songs/json/pimp.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -10,9 +10,9 @@ using SongCatalogEntry = std::pair<std::string, int>;
inline std::vector<SongCatalogEntry> get_song_catalog()
{
return {
{"assets/songs/json/mary.json", 0},
{"assets/songs/json/pallettown.json", 0},
{"assets/songs/json/tetris.json", 0},
{"assets/songs/json/mary.json", -1},
{"assets/songs/json/pallettown.json", -1},
{"assets/songs/json/tetris.json", -1},
{"assets/songs/json/undertale.json", 0},
};
}

View File

@ -257,8 +257,6 @@ std::vector<Glyph> chart_from_song(const Song& song, int track_override)
// Log original glyph timing (time is bottom, time + duration is top)
float new_bottom_time = time_sec;
float new_top_time = time_sec + duration_sec;
std::printf("[NEW GLYPH] lane=%d bottom=%.3f top=%.3f dur=%.3f\n",
lane, new_bottom_time, new_top_time, duration_sec);
Glyph* last_in_lane = nullptr;
for (size_t i = glyphs.size(); i-- > 0;)
@ -275,21 +273,13 @@ std::vector<Glyph> chart_from_song(const Song& song, int track_override)
float existing_bottom = last_in_lane->time;
float existing_top = last_in_lane->time + last_in_lane->duration_sec;
std::printf(" [CHECK] existing lane=%d bottom=%.3f top=%.3f vs new_bottom=%.3f\n",
last_in_lane->lane, existing_bottom, existing_top, new_bottom_time);
if (existing_top > new_bottom_time)
{
// Truncate existing glyph so its top doesn't go past new glyph's bottom
float shortened_duration = new_bottom_time - existing_bottom;
std::printf(" [OVERLAP DETECTED] shortened_dur=%.3f (was %.3f)\n",
shortened_duration, last_in_lane->duration_sec);
if (shortened_duration < MIN_GLYPH_DURATION_SEC)
{
std::printf(" [SKIP] shortened duration %.3f < MIN %.3f, skipping new glyph\n",
shortened_duration, MIN_GLYPH_DURATION_SEC);
note_index++;
continue;
}
@ -297,14 +287,10 @@ std::vector<Glyph> chart_from_song(const Song& song, int track_override)
float old_duration = last_in_lane->duration_sec;
last_in_lane->duration_sec = shortened_duration;
std::printf(" [TRUNCATED] lane=%d: duration %.3f -> %.3f (new_top=%.3f)\n",
last_in_lane->lane, old_duration, shortened_duration,
last_in_lane->time + shortened_duration);
}
}
glyphs.push_back(Glyph{time_sec, duration_sec, lane, instrument_slot, octave});
std::printf(" [ADDED] glyph count now: %zu\n\n", glyphs.size());
note_index++;
}
@ -478,20 +464,16 @@ public:
return false;
}
bool is_instrument_auto_played(int instrument_slot) const
{
return INSTRUMENT_PHYSICAL_GAMEPAD[instrument_slot] < 0;
}
bool is_lane_held_by_instrument(int lane, int instrument_slot) const
{
int physical_id = INSTRUMENT_PHYSICAL_GAMEPAD[instrument_slot];
if (physical_id < 0)
{
if (IsKeyDown(KEY_KEYS[lane]))
return true;
for (int i = 0; i < MAX_GAMEPADS; i++)
{
if (IsGamepadAvailable(i) && IsGamepadButtonDown(i, GAMEPAD_BUTTONS[lane]))
return true;
}
return false;
}
return IsGamepadAvailable(physical_id) &&
IsGamepadButtonDown(physical_id, GAMEPAD_BUTTONS[lane]);
}
@ -500,6 +482,8 @@ public:
{
for (int slot = 0; slot < MAX_INSTRUMENT_TYPES; slot++)
{
if (is_instrument_auto_played(slot))
continue;
if (is_lane_held_by_instrument(lane, slot))
continue;
auto it = std::find_if(active_sustained.begin(), active_sustained.end(),
@ -523,14 +507,7 @@ public:
{
int physical_id = INSTRUMENT_PHYSICAL_GAMEPAD[instrument_slot];
if (physical_id < 0)
{
for (int i = 0; i < MAX_GAMEPADS; i++)
{
if (IsGamepadAvailable(i) && IsGamepadButtonPressed(i, GAMEPAD_BUTTONS[lane]))
return true;
}
return false;
}
return IsGamepadAvailable(physical_id) &&
IsGamepadButtonPressed(physical_id, GAMEPAD_BUTTONS[lane]);
}
@ -637,8 +614,6 @@ public:
{
float bottom_hits_line_time = g.time + chart_time_offset;
float top_hits_line_time = bottom_hits_line_time + g.duration_sec;
std::printf("[chart] glyph lane=%d bottom_time=%.3f top_time=%.3f dur=%.3f\n",
g.lane, bottom_hits_line_time, top_hits_line_time, g.duration_sec);
}
debug_bottom_printed = true;
}
@ -741,6 +716,8 @@ public:
continue;
if (missed_notes.count(n) != 0)
continue;
if (is_instrument_auto_played(n->instrument_slot))
continue;
float bottom_y = glyph_bottom_y(*n);
if (bottom_y > hit_line_y + HIT_ZONE_MARGIN)
{
@ -779,25 +756,21 @@ public:
}
}
if (dev_auto_hit_mode)
std::vector<Glyph*> to_auto_consume;
for (Glyph* n : spawned)
{
std::vector<Glyph*> to_consume;
for (Glyph* n : spawned)
{
if (completed_notes.count(n) != 0)
continue;
if (is_note_hittable(*n))
{
to_consume.push_back(n);
}
}
for (Glyph* n : to_consume)
{
consume_note(n);
}
if (completed_notes.count(n) != 0)
continue;
if (!is_note_hittable(*n))
continue;
if (dev_auto_hit_mode || is_instrument_auto_played(n->instrument_slot))
to_auto_consume.push_back(n);
}
else
for (Glyph* n : to_auto_consume)
{
consume_note(n);
}
for (int lane = 0; lane < LANE_COUNT; lane++)
{
stop_playing_released_notes(lane, time_per_glyph_height);
@ -813,17 +786,13 @@ public:
for (Glyph* n : spawned)
{
if (n->lane != lane)
{
continue;
}
if (!is_note_hittable(*n))
{
continue;
}
if (is_instrument_auto_played(n->instrument_slot))
continue;
if (!lane_pressed_by_instrument_owner(lane, n->instrument_slot))
{
continue;
}
float bottom_y = glyph_bottom_y(*n);
float d = fabsf(bottom_y - hit_line_y);
if (d < best_dist)
@ -842,7 +811,6 @@ public:
score = std::max(0, score - 25);
}
}
}
if (is_menu_pressed())
{

View File

@ -88,23 +88,31 @@ public:
}
}
bool all_selected = true;
bool at_least_one_selected = false;
for (int s = 0; s < MAX_INSTRUMENT_TYPES; s++)
{
if (instrument_owner[s] < 0)
if (instrument_owner[s] >= 0)
{
all_selected = false;
at_least_one_selected = true;
break;
}
}
if (all_selected)
if (at_least_one_selected)
{
if (IsKeyPressed(KEY_ENTER))
{
for (int i = 0; i < MAX_INSTRUMENT_TYPES; i++)
{
INSTRUMENT_GAMEPAD_INDEX[i] = instrument_owner[i];
INSTRUMENT_PHYSICAL_GAMEPAD[i] = participant_order[instrument_owner[i]];
if (instrument_owner[i] >= 0)
{
INSTRUMENT_GAMEPAD_INDEX[i] = instrument_owner[i];
INSTRUMENT_PHYSICAL_GAMEPAD[i] = participant_order[instrument_owner[i]];
}
else
{
INSTRUMENT_GAMEPAD_INDEX[i] = -1;
INSTRUMENT_PHYSICAL_GAMEPAD[i] = -1;
}
}
game->go_to_scene("ghhb");
return;
@ -115,8 +123,16 @@ public:
{
for (int i = 0; i < MAX_INSTRUMENT_TYPES; i++)
{
INSTRUMENT_GAMEPAD_INDEX[i] = instrument_owner[i];
INSTRUMENT_PHYSICAL_GAMEPAD[i] = participant_order[instrument_owner[i]];
if (instrument_owner[i] >= 0)
{
INSTRUMENT_GAMEPAD_INDEX[i] = instrument_owner[i];
INSTRUMENT_PHYSICAL_GAMEPAD[i] = participant_order[instrument_owner[i]];
}
else
{
INSTRUMENT_GAMEPAD_INDEX[i] = -1;
INSTRUMENT_PHYSICAL_GAMEPAD[i] = -1;
}
}
game->go_to_scene("ghhb");
return;
@ -186,36 +202,52 @@ public:
const float label_font_size = 60.0f;
const float label_offset = 50.0f;
const float label_offset_bottom = 110.0f;
auto draw_player_label = [this, &player_labels, label_font_size, label_offset,
label_offset_bottom](float ix, float iy, int slot) {
if (instrument_owner[slot] < 0)
return;
const char* label = player_labels[instrument_owner[slot]];
float lw = MeasureTextEx(font, label, label_font_size, 1.0f).x;
float ly = (slot == SLOT_BOTTOM) ? iy - label_offset_bottom : iy + label_offset;
DrawTextEx(font, label, Vector2{ix - lw * 0.5f, ly}, label_font_size, 1.0f, WHITE);
auto draw_slot_label = [this, &player_labels, label_font_size, label_offset,
label_offset_bottom](float ix, float iy, int slot) {
if (instrument_owner[slot] >= 0)
{
const char* label = player_labels[instrument_owner[slot]];
float lw = MeasureTextEx(font, label, label_font_size, 1.0f).x;
float ly = (slot == SLOT_BOTTOM) ? iy - label_offset_bottom : iy + label_offset;
DrawTextEx(font, label, Vector2{ix - lw * 0.5f, ly}, label_font_size, 1.0f, WHITE);
}
else
{
const char* label = "CPU";
float lw = MeasureTextEx(font, label, label_font_size, 1.0f).x;
float ly = (slot == SLOT_BOTTOM) ? iy - label_offset_bottom : iy + label_offset;
DrawTextEx(font, label, Vector2{ix - lw * 0.5f, ly}, label_font_size, 1.0f,
Color{180, 180, 180, 255});
}
};
draw_player_label(cx, icon_y_top, SLOT_TOP);
draw_player_label(cx, icon_y_bottom, SLOT_BOTTOM);
draw_player_label(icon_x_left, cy, SLOT_LEFT);
draw_player_label(icon_x_right, cy, SLOT_RIGHT);
draw_slot_label(cx, icon_y_top, SLOT_TOP);
draw_slot_label(cx, icon_y_bottom, SLOT_BOTTOM);
draw_slot_label(icon_x_left, cy, SLOT_LEFT);
draw_slot_label(icon_x_right, cy, SLOT_RIGHT);
bool all_selected = true;
bool at_least_one_selected = false;
for (int s = 0; s < MAX_INSTRUMENT_TYPES; s++)
{
if (instrument_owner[s] < 0)
if (instrument_owner[s] >= 0)
{
all_selected = false;
at_least_one_selected = true;
break;
}
}
if (all_selected)
if (at_least_one_selected)
{
const char* prompt = "Press Start to begin";
float font_size = 24.0f;
float pw = MeasureTextEx(font, prompt, font_size, 1.0f).x;
DrawTextEx(font, prompt, Vector2{cx - pw * 0.5f, h - 40.0f}, font_size, 1.0f, WHITE);
}
else
{
const char* prompt = "Select at least one instrument";
float font_size = 24.0f;
float pw = MeasureTextEx(font, prompt, font_size, 1.0f).x;
DrawTextEx(font, prompt, Vector2{cx - pw * 0.5f, h - 40.0f}, font_size, 1.0f, WHITE);
}
}
};