Fluid-Simulation-Monochrome/src/menus.c

321 lines
9.8 KiB
C

char strFPS[20];
char strDyeDiff[20];
char strVelDiff[20];
char strDyeForce[20];
char strVelForce[20];
char strRadius[20];
char strPressureIter[20];
char strEmptyTreshold[20];
char strSaturateTreshold[20];
// Main Screen
void main_menu() {
const int gap = 8;
const int startY = 11;
dhline(5, C_BLACK);
dtext_opt(64, 2, C_BLACK, C_WHITE, DTEXT_CENTER, DTEXT_TOP, " CASIO FLUID SIMULATION ", -1);
dtext_opt(3, startY, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "Implementation of Jos Stam's", -1);
dtext_opt(3, startY + gap, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "\"Real Time Fluid Dynamics for", -1);
dtext_opt(3, startY + gap*2, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "games\" paper on monochrome", -1);
dtext_opt(3, startY + gap*3, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "Casio calculators", -1);
dtext_opt(3, startY + gap*4+2, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "[Optn] key displays the help", -1);
dtext_opt(124, 62, C_BLACK, C_WHITE, DTEXT_RIGHT, DTEXT_BOTTOM, "[EXE] Start", -1);
dupdate();
dclear(C_WHITE);
sleep_ms(500);
while(1) {
clearevents();
uint key = getkey().key;
if (key == KEY_EXE || key == K_HELP) break;
}
}
// Controls/Help Menu
int help_menu() {
const int margin = 2;
drect_border(margin, margin, 128 - margin-1, 64 - margin-1, C_WHITE, 1, C_BLACK);
dtext_opt(margin+2, margin+3+8*0, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "[Arrows]: Interact", -1);
dtext_opt(margin+2, margin+3+8*1, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "[Shift]: Toggle edit mode", -1);
dtext_opt(margin+2, margin+3+8*2, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "[Alpha]: Toggle color mode", -1);
dtext_opt(margin+2, margin+3+8*3, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "[Del]: Reset the simulation", -1);
dtext_opt(margin+2, margin+3+8*4, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "[+]/[-]: Toggle fullscreen", -1);
dtext_opt(margin+2, margin+3+8*5, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "[x]: Hide/Show FPS", -1);
dtext_opt(margin+2, margin+3+8*6, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "[Exit]: Quit [EXE]: Continue", -1);
dupdate();
dclear(C_WHITE);
while(1) {
uint key = getkey().key;
if (key == KEY_EXIT) return -1;
if (key == KEY_EXE || key == K_HELP) return 0;
}
// if (getkey().key == KEY_EXIT) return -1;
// return 0;
}
// Fluid Simulation Settings Menu
void settings_menu(bool redraw) {
static int selected = 0;
const int menuX = 66;
const int menuY = 2;
const int gap = 8;
const int rx = 64;
const bool activated = redraw;
bool updateRect = false, updateDyeD = activated, updateVelD = activated, updateDyeF = activated, updateVelF = activated, updateRadius = activated, updatePressureIter = activated;
static bool releaseParams = true;
if (currentView == 1 && releaseParams && keydown(K_PARAMS)) {
releaseParams = false;
currentView = 0;
int ry = menuY+gap*(selected+1)+2;
drect(rx, ry, rx, ry+2, C_WHITE);
drect_border(63, 0, 127, H-1, C_NONE, 1, C_WHITE);
}
else if (currentView != 1 && releaseParams && keydown(K_PARAMS)) {
releaseParams = false;
currentView = 1;
updateRect = true;
updateDyeD = true, updateVelD = true, updateDyeF = true, updateVelF = true, updateRadius = true, updatePressureIter = true;
drect(64, 0, 128, 64, C_WHITE);
drect_border(0, 0, W-1, H-1, C_NONE, 1, C_WHITE);
} else if (!keydown(K_PARAMS)) {
releaseParams = true;
}
if (currentView == 0) {
drect_border(0, 0, W-1, H-1, C_NONE, 1, C_BLACK);
if (!redraw) return;
} else if (currentView == 2) return;
{
drect_border(0, 0, W-1, H-1, C_NONE, 1, C_WHITE);
drect_border(63, 0, 127, H-1, C_NONE, 1, C_BLACK);
}
if (keydown(KEY_LEFT)) {
if (selected == 0 && dyeDiffusion > 0) {
dyeDiffusion -= PREC_STEP;
updateDyeD = true;
}
else if (selected == 1 && velDiffusion > 0) {
velDiffusion -= PREC_STEP;
updateVelD = true;
}
else if (selected == 2 && dyeIntensity > 0) {
dyeIntensity -= PREC_STEP;
updateDyeF = true;
}
else if (selected == 3 && velIntensity > 0) {
velIntensity -= PREC_STEP;
updateVelF = true;
}
else if (selected == 4 && radius > ONE) {
radius -= FIX(1);
updateRadius = true;
}
else if (selected == 5 && pressureIterations > 0) {
pressureIterations--;
updatePressureIter = true;
}
}
else if (keydown(KEY_RIGHT)) {
if (selected == 0 && dyeDiffusion < ONE) {
dyeDiffusion += PREC_STEP;
updateDyeD = true;
}
else if (selected == 1 && velDiffusion < ONE) {
velDiffusion += PREC_STEP;
updateVelD = true;
}
else if (selected == 2 && dyeIntensity < ONE*2) {
dyeIntensity += PREC_STEP;
updateDyeF = true;
}
else if (selected == 3 && velIntensity < ONE*2) {
velIntensity += PREC_STEP;
updateVelF = true;
}
else if (selected == 4 && radius < ONE*10) {
radius += FIX(1);
updateRadius = true;
}
else if (selected == 5) {
pressureIterations++;
updatePressureIter = true;
}
}
else if (keydown(KEY_UP)) {
int ry = menuY+gap*(selected+1)+2;
drect(rx, ry, rx, ry+2, C_WHITE);
if (--selected < 0) selected = 5;
updateRect = true;
}
else if (keydown(KEY_DOWN)) {
int ry = menuY+gap*(selected+1)+2;
drect(rx, ry, rx, ry+2, C_WHITE);
if (++selected > 5) selected = 0;
updateRect = true;
}
if (updateDyeD) {
sprintf(strDyeDiff, "dye diff:%.3f ", fixtof(dyeDiffusion));
dtext_opt(menuX, menuY + gap, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, strDyeDiff, -1);
}
if (updateVelD) {
sprintf(strVelDiff, "vel diff:%.3f ", fixtof(velDiffusion));
dtext_opt(menuX, menuY + gap*2, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, strVelDiff, -1);
}
if (updateDyeF) {
sprintf(strDyeForce, "dye force:%.1f ", fixtof(dyeIntensity));
dtext_opt(menuX, menuY + gap*3, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, strDyeForce, -1);
}
if (updateVelF) {
sprintf(strVelForce, "vel force:%.1f ", fixtof(velIntensity));
dtext_opt(menuX, menuY + gap*4, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, strVelForce, -1);
}
if (updateRadius) {
sprintf(strRadius, "radius: %d ", UNFIX(radius));
dtext_opt(menuX, menuY + gap*5, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, strRadius, -1);
}
if (updatePressureIter) {
sprintf(strPressureIter, "iterations: %d ", pressureIterations);
dtext_opt(menuX, menuY + gap*6, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, strPressureIter, -1);
}
if (updateRect) {
int ry = menuY+gap*(selected+1)+2;
drect(rx, ry, rx, ry+2, C_BLACK);
}
}
// Fluid color settings Menu
void color_menu() {
const int xmargin = 3;
const float fw = 64. - (float)xmargin * 2.;
const int y = 22;
const int h = 5;
const int bar_overflow = 3;
const int STEP_MULT = 20;
const float tresh1 = fixtof(emptyTreshold);
const float tresh2 = fixtof(saturateTreshold);
const int x1 = 64 + xmargin + (int)(tresh1 * fw);
const int x2 = 64 + xmargin + (int)(tresh2 * fw);
static bool x1Selected = true;
static bool releaseKey = true;
bool updated = false;
// Manage keys
if (keydown(K_COLORS) && releaseKey) {
releaseKey = false;
if (currentView == 2) {
currentView = 0;
drect_border(63, 0, 127, H-1, C_NONE, 1, C_WHITE);
}
else {
currentView = 2;
updated = true;
}
} else if (!keydown(K_COLORS) && !releaseKey) {
releaseKey = true;
}
if (currentView != 2) return;
if (keydown(KEY_F1)) {
emptyTreshold -= PREC_STEP * STEP_MULT;
if (emptyTreshold < 0) emptyTreshold = 0;
x1Selected = true;
updated = true;
}
else if (keydown(KEY_F2)) {
emptyTreshold += PREC_STEP * STEP_MULT;
if (emptyTreshold > ONE) emptyTreshold = ONE;
if (emptyTreshold > saturateTreshold) saturateTreshold = emptyTreshold;
x1Selected = true;
updated = true;
}
else if (keydown(KEY_F3)) {
saturateTreshold -= PREC_STEP * STEP_MULT;
if (saturateTreshold < 0) saturateTreshold = 0;
if (saturateTreshold < emptyTreshold) emptyTreshold = saturateTreshold;
x1Selected = false;
updated = true;
}
else if (keydown(KEY_F4)) {
saturateTreshold += PREC_STEP * STEP_MULT;
if (saturateTreshold > ONE) saturateTreshold = ONE;
x1Selected = false;
updated = true;
}
else if (keydown(KEY_F5)) {
fix diff = saturateTreshold - emptyTreshold;
emptyTreshold -= PREC_STEP * STEP_MULT;
if (emptyTreshold < 0) emptyTreshold = 0;
saturateTreshold = emptyTreshold + diff;
x1Selected = true;
updated = true;
}
else if (keydown(KEY_F6)) {
fix diff = saturateTreshold - emptyTreshold;
saturateTreshold += PREC_STEP * STEP_MULT;
if (saturateTreshold > ONE) saturateTreshold = ONE;
emptyTreshold = saturateTreshold - diff;
x1Selected = false;
updated = true;
}
if (updated) {
// Clear
drect(64, 0, 128, 64, C_WHITE);
drect_border(0, 0, W-1, H-1, C_NONE, 1, C_WHITE);
// Draw selectors
if (x1Selected) {
drect(x1-1, y - bar_overflow-1, x1+1, y+h+bar_overflow+1, C_BLACK);
dline(x2, y - bar_overflow, x2, y+h+bar_overflow, C_BLACK);
} else {
dline(x1, y - bar_overflow, x1, y+h+bar_overflow, C_BLACK);
drect(x2-1, y - bar_overflow-1, x2+1, y+h+bar_overflow+1, C_BLACK);
}
// Draw white band
drect(64 + xmargin, y, x1, y + h, C_WHITE);
// Draw checker band
for (int j = y; j <= y+h; j++) {
dline(x1, j, x2, j, j%2 ? C_BLACK : C_WHITE);
}
for (int i = x1; i < x2; i+=2) {
dline(i, y, i, y+h, C_BLACK);
}
// Draw black band
drect(x2, y, 128 - xmargin, y + h, C_BLACK);
// Draw border
drect_border(64 + xmargin-1, y-1, 128 - xmargin+1, y+h+1, C_NONE, 1, C_BLACK);
// Draw float values
sprintf(strEmptyTreshold, "%.2f", tresh1);
sprintf(strSaturateTreshold, "%.2f", tresh2);
dtext_opt(x1, y - bar_overflow - 1, C_BLACK, C_WHITE, DTEXT_CENTER, DTEXT_BOTTOM, strEmptyTreshold, -1);
dtext_opt(x2, y + h + bar_overflow + 1, C_BLACK, C_WHITE, DTEXT_CENTER, DTEXT_TOP, strSaturateTreshold, -1);
dtext_opt(65, 40, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "[F1/F2] Lower", -1);
dtext_opt(65, 48, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "[F3/F4] Upper", -1);
dtext_opt(65, 56, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "[F5/F6] Both", -1);
}
drect_border(63, 0, 127, H-1, C_NONE, 1, C_BLACK);
}