Raylib 3
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
6.4 KiB

8 months ago
//Standard lib
#include <string.h> //strchr
#include <stdio.h> //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;
}
}
}