//Standard lib #include //strchr #include //print error messages //Third party #include "raylib.h" //Our own files #include "constants.h" #include "programstate.h" #include "drawhelper.h" extern ProgramState programState; float intToHue(int number, int maxnumber) { //previously used to auto-color ports this is now only used for the default port colors. //portnum is 0-VIS_PORTS //hue is 0-360 //return (input-inputLowest) / (inputHighest-inputLowest) * (outputHighest-outputLowest) + outputLowest return (float)number / (float)maxnumber * 360.0f; } Color intToColor(int number, int maxnumber) { Color result; Vector3 hsv; // 3 floats: hue/color, saturation, value/brightness hsv = (Vector3){intToHue(number, VIS_PORTS), 1.0f, (float)(127+40)/(float)167}; //Saturation is always 1, we tweak Value to never go into the black range. result = ColorFromHSV(hsv); return result; } Color midiToColor(Note * note) { Color result; Vector3 hsv; // 3 floats: hue/color, saturation, value/brightness //hsv = (Vector3){intToHue(note->port, VIS_PORTS), 1.0f, (float)(note->velocity+40)/(float)167}; //Saturation is always 1, we tweak Value to never go into the black range. float hue=ColorToHSV(programState.colors[note->port]).x; hsv = (Vector3){hue, 1.0f, (float)(note->velocity+40)/(float)167}; //Saturation is always 1, we tweak Value to never go into the black range. result = ColorFromHSV(hsv); return result; } void drawNoteRect(Note * note, int rotated, int square) { if (note->active) { //opacity is between 0.0f and 1.0f int w,h; if (square==1) { w = NOTE_SMALL_SIDE - NOTE_BORDER; h = NOTE_SMALL_SIDE - NOTE_BORDER; } else { //Not Square if (rotated==0) { w = NOTE_SMALL_SIDE - NOTE_BORDER; h = NOTE_LONG_SIDE - NOTE_BORDER; } else { h = NOTE_SMALL_SIDE - NOTE_BORDER; w = NOTE_LONG_SIDE - NOTE_BORDER; } } const Rectangle rec = (Rectangle){note->x, note->y, w,h}; const Rectangle outer = (Rectangle){note->x-NOTE_BORDER/2, note->y-NOTE_BORDER/2, w+NOTE_BORDER, h+NOTE_BORDER}; Color bordercolor = Fade(BLACK, note->countdown); Color color = Fade(programState.colors[note->port], note->countdown); //Drawing order is reverse Z-Order DrawRectangleRounded(outer, 0.5, 8, bordercolor); //float roundness, int segments/smoothness, Color DrawRectangleRounded(rec, 0.5, 8, color); } } bool portShouldDraw(int port) { //Check various conditions if a port background, port name and pitch marker should be drawn if ( programState.showPortBackgroundForUnconnected || ( programState.connectedPortNames[port] && programState.connectedPortNames[port][0] != '\0' )) { return true; } else { return false; } } void drawJackPortName(const char * portname, int x, int y, int fontsize, Color color, bool vertical) { if (portname && portname[0] != '\0') { const char * finalPortName; if (programState.includeClientInPortNameDisplay) { finalPortName = portname; //TODO: Pretty Names don't contain the client name. Add it ourselves? } else { if (strchr(portname, ':') == NULL ) //Pretty Names don't contain the client name. { finalPortName = portname; } else { finalPortName = strchr(portname, ':')+1; } } //final port name is ready. //Vertical Mode //void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float scale, Color tint); // Draw one character (codepoint) if (vertical) { //TODO: Wow, that is ugly! int counter = 0; char ch = finalPortName[counter]; Font defaultFont = GetFontDefault(); while (ch != '\0') { DrawTextCodepoint(defaultFont, ch, (Vector2){ x, y+counter*(fontsize/1.5) }, 1.8f, color); counter++; ch = finalPortName[counter]; } } else { // Horizontal Mode DrawText(finalPortName, x, y, fontsize, color); } } } float calculateCountdown(float countdown, float ft) { float bpmFactor; switch (programState.fadeOutMode) { case 0: // framelegnth * user factor if (countdown < 1.0f) { countdown -= (float)programState.fadeOutFactor * ft; } //note off has been triggered. Fade out. if (countdown <= 0.0f) { countdown = 0; } // Is it now, or was already, below 0? break; case 1: // bpm bpmFactor = (float)(programState.bpm/40); if (countdown < 1.0f) { countdown -= bpmFactor * ft; } //note off has been triggered. Fade out. if (countdown <= 0.0f) { countdown = 0.0f; } // Is it now, or was already, below 0? break; case 2: // no fadeout if (countdown < 1.0f) { countdown = 0.0f; } // As soon as note off arrives break; default: //just in case countdown = 0.0f; break; } return countdown; } void reduceCountdown(Note * nt, float ft) { //Notes countdown is set to 0 (note-off), 1 (note-on) or 0.999 (note-off) by our jack midi client. float bpmFactor; if (nt->active == 1) { switch (programState.fadeOutMode) { case 0: // framelegnth * user factor if (nt->countdown < 1.0f) { nt->countdown -= (float)programState.fadeOutFactor * ft; } //note off has been triggered. Fade out. if (nt->countdown <= 0.0f) { nt->active = false; } // Is it now, or was already, below 0? break; case 1: // bpm bpmFactor = (float)(programState.bpm/40); if (nt->countdown < 1.0f) { nt->countdown -= bpmFactor * ft; } //note off has been triggered. Fade out. if (nt->countdown <= 0.0f) { nt->active = false; } // Is it now, or was already, below 0? break; case 2: // no fadeout if (nt->countdown < 1.0f) { nt->active = false; } // As soon as note off arrives break; default: //just in case nt->active = false; break; } } }