Rev 13 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* levels.cc
* DIN Is Noise is copyright (c) 2006-2017 Jagannathan Sampath
* For more information, please visit http://dinisnoise.org/
*/
#include "main.h"
#include "levels.h"
#include "viewwin.h"
#include "input.h"
#include "console.h"
#include "utils.h"
#include "font.h"
#include <fstream>
#include <iostream>
using namespace std;
extern console cons;
extern string user_data_dir;
extern ofstream dlog;
extern int mousex, mouseyy;
levels::levels (const string& n) {
name = n;
lis = 0;
editing = 0;
load ();
}
levels::~levels () {
save ();
}
void levels::load () {
ifstream file ((user_data_dir + name).c_str(), ios::in);
string ignore;
int left, bottom;
if (!file) {
dlog << "!!! cant read settings for " << name << ", using defaults. !!!" << endl;
nlev = 10;
elem_width = 10;
height = 100;
left = 0;
bottom = 0;
r = g = b = a = 1;
editable = 0;
saveable = 0;
} else {
file >> ignore >> nlev;
lastlev = nlev - 1;
file >> ignore >> left >> bottom;
file >> ignore >> elem_width;
file >> ignore >> height;
file >> ignore >> r >> g >> b >> a;
set_color (r, g, b);
file >> ignore >> editable;
file >> ignore >> saveable;
dlog << "+++ loaded " << name << " +++" << endl;
}
a0 = a / 4;
extents (left, bottom, left + nlev * elem_width, bottom + height);
for (int i = 0; i < nlev; ++i) {
values.push_back (0);
heights.push_back (0);
}
if (saveable) {
int savings;
file >> ignore >> savings;
for (int i = 0; i < savings; ++i) {
file >> values[i];
heights[i] = (int)(values[i] * extents.height);
}
}
editing = edited = 0;
}
void levels::save () {
ofstream file ((user_data_dir+name).c_str(), ios::out);
if (file) {
file << "num_levels " << nlev << endl;
file << "lower_corner " << extents.left << ' ' << extents.bottom << endl;
file << "element_width " << elem_width << endl;
file << "height " << height << endl;
file << "color " << r << ' ' << g << ' ' << b << ' ' << a << endl;
file << "editable " << editable << endl;
file << "saveable " << saveable << endl;
if (saveable) {
file << "savings " << nlev << ' ';
for (int i = 0; i < nlev; ++i) file << values[i] << ' ';
file << endl;
} else {
file << "savings 0" << endl;
}
} else dlog << "!!! couldnt save levels !!!" << endl;
}
int levels::handle_input () {
widget::handle_input ();
edited = 0;
if (editing) {
if (lmb) {
if (shift_down()) { // set current level only
clear_hgt_val ();
calc_hgt_val ();
set (lev, val, hgt);
} else if (ctrl_down()) { // clear current level
set (lev, 0, -1);
} else { // set current level with values
calc_hgt_val ();
set (lev, val, hgt);
}
edited = 1;
} else editing = 0;
} else {
if (hover) {
if (!editing) { // just update the level / value display
calc_lev ();
calc_hgt_val ();
}
if (!editable) return 0;
if (lmb && !editing) editing = 1;
}
}
return edited;
}
/*int levels::handle_auto_input () {
double dtn = ui_clk () - it;
if (dtn >= dt) {
it = ui_clk ();
rnd<float> rd (-amt, amt);
int l[] = {0, 1, 2};
for (int i = 0; i < 3; ++i) {
float v = values[i];
set (i, v+rd(), -1, 0);
}
if (lis) lis->changed (*this);
return 1;
}
return 0;
}*/
void levels::calc_lev () {
int dx = mousex - extents.left;
lev = dx / elem_width;
if (lev > lastlev || lev < 0) lev = -1;
}
void levels::calc_hgt_val () {
hgt = mouseyy - extents.bottom;
clamp<int> (0, hgt, extents.height);
val = hgt * extents.height_1;
}
void levels::clear_hgt_val () {
for (int i = 0; i < nlev; ++i) values[i] = heights[i] = 0;
}
void levels::draw () {
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
int i = 0, x = extents.left, ds = elem_width - 2;
if (extents.left < 0) {
i = -extents.left / elem_width;
x = 0;
}
for (;i < nlev; ++i) {
int l = x + 1, r = x + ds;
glColor4f (clr.r, clr.g, clr.b, a0);
glRecti (l, extents.bottom, r, extents.top);
glColor4f (clr.r, clr.g, clr.b, a);
glRecti (l, extents.bottom, r, extents.bottom + heights[i]);
x += elem_width;
extern viewport view;
if (x > view.xmax) break;
}
glDisable (GL_BLEND);
static char buf [256];
sprintf (buf, "%d/%.3f", lev+1, lev > -1? values[lev]:-1);
draw_string (buf, extents.left, extents.bottom - get_line_height (), 0);
}
void levels::set (int i, float v, int h) {
int n = values.size ();
if (i > -1 && i < n) {
if (h == -1) heights[i] = (int)(v * extents.height + 0.5); else heights[i] = h;
float& vi = values[i];
if (vi != v) {
vi = v;
if (lis) lis->changed (*this);
}
}
}
void levels::chkpos () {
extern viewport view;
if (!view.inside (extents.left, extents.bottom)) extents.lower_corner (0, 0);
}