//Standard lib #include //Third party #include "raylib.h" #include "raygui.h" // Required for GUI controls //Our own files #include "constants.h" #include "programstate.h" #include "drawhelper.h" #include "draw_meterbridge.h" extern ProgramState programState; static Rectangle backgroundRect; static bool guiGroupEditMode= false; static int screenHeight; static int bottom; static void reposition(Note *allGUINotes) { //This is both init and update. We only call it internally, the name of the function doesn't matter. //Once guaranteed called on program start and then each window resize int screenWidth = GetScreenWidth(); int screenHeight = GetScreenHeight(); int xOffset = (int)(screenWidth/2) - (int)(60*(NOTE_LONG_SIDE+NOTE_GAP)); //we want all tracks around the center. int yOffset = (int)(screenHeight/2) - (int)(NOTE_SMALL_SIDE+NOTE_GAP)*2; //we want all tracks below the center. programState.modeDescription = "All port are in one horizontal row.\ \nPitches are left to right, low to high.\ \n\ \nVelocity 'shoots' notes upwards, then they fall back\ \ninfluenced by the fade-out setting.\ \n\ \nYou can set the a 'grouping' parameter for this mode\ \nwhich combines several pitches into a single indicator.\ \nGrouping uses the pitch marker pitch as baseline.\ \nThink of it like the tonic or root note.\ \n\ \n\ \nNotes are only lit up when they are played.\ \nThere is no time-dimension."; int rootNote = programState.pitchMarkerValue % 12; //factor out the octave. used to start groups on the pitchmarker as root note of the scale int xpos = xOffset; int pitchToTheCenter = 64 - (128/programState.meterbridge_grouping/2); for (int port=0; portx, nt->y+NOTE_SMALL_SIDE, NOTE_LONG_SIDE-NOTE_BORDER, NOTE_SMALL_SIDE-NOTE_BORDER}; //TODO: Ha! :) This falls down as well, together with the note. DrawRectangleRounded(rec, 0.5, 8, programState.colors[backgroundLighter]); } //Debug: Show 0 and 127 //DrawLine(allGUINotes[0].x, 0, allGUINotes[0].x, GetScreenHeight(), RAYWHITE); //(int startPosX, int startPosY, int endPosX, int endPosY, Color color); //DrawLine(allGUINotes[127].x, 0, allGUINotes[127].x, GetScreenHeight(), RAYWHITE); //(int startPosX, int startPosY, int endPosX, int endPosY, Color color); for (int port=0; portactive) { nt->y = backgroundRect.y - 2*(nt->countdown * nt->velocity); //Shift the notes upwards. Don't use -= or +=, that is exponential modifications reduceCountdown(nt, ft/2); //handles 0.0 and 1.0 as special cases drawNoteRect(nt, 1, 0); //note, rotated, square. Will not draw if not active/countdown == 0 } } } //Our own GUI section if (programState.guiVisible) { EndMode2D(); //We are already in camera mode because this is a draw_ function. GUI is not under camera control. int row = 0; screenHeight = GetScreenHeight(); //Changes on resize bottom = screenHeight - 2*SPACING; int remember = programState.meterbridge_grouping; GuiLabel((Rectangle){ 34, bottom-row*SPACING, 105, HEIGHT }, "Meterbridge Note Grouping"); // void GuiLabel(Rectangle bounds, const char *text); if (GuiSpinner((Rectangle){ 250, bottom-row*SPACING, 80, HEIGHT }, "", &programState.meterbridge_grouping, 0, 127, guiGroupEditMode)) guiGroupEditMode = !guiGroupEditMode; // bool GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode) if (programState.meterbridge_grouping > 128) {programState.meterbridge_grouping=128;} if (programState.meterbridge_grouping < 1) {programState.meterbridge_grouping=1;} if (remember != programState.meterbridge_grouping) { reposition(allGUINotes); } //we cannot set guiRedrawNeeded to true here because parent draw() will reset it after we return row++; BeginMode2D(programState.camera); //Switch back to previously active camera mode } }