Subversion Repositories DIN Is Noise

Rev

Rev 2297 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
964 jag 1
/*
2
* levels.cc
2302 jag 3
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
1713 jag 4
* DIN Is Noise is released under GNU Public License 2.0
1479 jag 5
* For more information, please visit https://dinisnoise.org/
964 jag 6
*/
7
 
8
 
9
#include "main.h"
10
#include "levels.h"
11
#include "viewwin.h"
12
#include "input.h"
13
#include "console.h"
14
#include "utils.h"
15
#include "font.h"
16
#include "log.h"
17
 
18
using namespace std;
19
 
20
extern string user_data_dir;
1263 jag 21
extern int mousex, mousey, wheel, mouseyy, prev_mousey;
964 jag 22
extern char BUFFER [];
23
extern int line_height;
24
 
1584 jag 25
levels::levels (const string& s) {
26
  name = s;
1263 jag 27
  editing = lmb_clicked = paint = nsel = 0;
28
  selection = 0;
1585 jag 29
  chgl = 0;
30
  shftl = 0;
31
  paintl = 0;
1625 jag 32
  load ();
33
 
34
  if (editable) {
1588 jag 35
    const char* bt [] = {"Wrap", "Slide", "<<", ">>", "All", "None", "Invert", "+", "-", "x"};
1625 jag 36
    button* b[] = {&cbwrap, &bslide, &blshift, &brshift, &ball, &bnone, &binvert, &plus, &minus, &cross};
1588 jag 37
    click_listener* cl [] = {&cbwrap, &sll, &lsl, &rsl, &alll, &nonl, &invl, &pll, &mil, &crol};
38
    for (int i = 0; i < 10; ++i) {
1584 jag 39
      button* pbi = b[i];
40
      click_listener* pcl = cl[i];
41
      pbi->set_text (bt[i]);
42
      pbi->set_listener (pcl);
43
      pcl->data = this;
44
      this->add_child (pbi);
45
    }
1587 jag 46
 
1586 jag 47
    this->add_child (&szr);
1587 jag 48
 
49
    MOVE (szr);
1625 jag 50
    szr.movlis = this;
1587 jag 51
 
1584 jag 52
    blshift.click_repeat = brshift.click_repeat = 1;
1587 jag 53
 
54
    bml.data = this;
1584 jag 55
  }
964 jag 56
}
57
 
58
levels::~levels () {
59
  save ();
1588 jag 60
  removeallbookmarks ();
1263 jag 61
  if (selection) delete[] selection;
964 jag 62
}
63
 
64
void levels::load () {
65
 
66
  string ignore;
67
  int left, bottom;
68
 
69
  ifstream file ((user_data_dir + name).c_str(), ios::in);
1587 jag 70
  file >> ignore >> n;
71
  last = n - 1;
72
  file >> ignore >> left >> bottom;
73
  file >> ignore >> elem;
74
  file >> ignore >> height;
75
  file >> ignore >> editable;
76
  file >> ignore >> saveable;
1584 jag 77
 
1587 jag 78
  int w;
79
  file >> ignore >> w;
80
  cbwrap.set_state (w,0);
1584 jag 81
 
964 jag 82
  a = 0.7;
83
  a0 = a / 4;
1584 jag 84
  extents (left, bottom, left + n * elem, bottom + height);
1585 jag 85
  set_pos (left, bottom);
86
 
1584 jag 87
  values.resize (n);
88
  heights.resize (n);
89
 
90
  selection = new bool [n];
91
  sel_sz = sizeof (bool) * n;
1263 jag 92
  memset (selection, 0, sel_sz);
93
 
964 jag 94
  if (saveable) {
95
    int savings;
96
    file >> ignore >> savings;
97
    for (int i = 0; i < savings; ++i) {
1266 jag 98
      float h; file >> h >> selection[i];
964 jag 99
      heights[i] = h;
100
      values[i] =  h * extents.height_1;
101
    }
1331 jag 102
    file >> nsel;
964 jag 103
  }
104
 
1587 jag 105
  int nb;
106
  file >> ignore >> nb;
107
  if (nb) {
108
    bmk.resize (nb);
109
    for (int i = 0, y = minus.extents.bottom - state_button::SIZE2; i < nb; ++i) {
110
      bookmark* b = new bookmark ();
111
      b->set_pos (minus.extents.left, y);
112
      y -= state_button::SIZE2;
113
      b->set_listener (&bml);
114
      this->add_child (b);
115
      bmk[i] = b;
116
      int nid;
117
      file >> nid;
118
      vector<int>& ids = b->ids;
119
      ids.resize (nid);
120
      for (int m = 0; m < nid; ++m) file >> ids[m];
121
    }
122
  }
964 jag 123
 
1587 jag 124
  editing = 0;
125
 
964 jag 126
}
127
 
128
void levels::save () {
129
  ofstream file ((user_data_dir+name).c_str(), ios::out);
130
  if (file) {
1584 jag 131
    file << "num_levels " << n << endl;
1695 jag 132
    file << "lower_corner " << extents.left << spc << extents.bottom << endl;
1584 jag 133
    file << "element_width " << elem << endl;
964 jag 134
    file << "height " << height << endl;
135
    file << "editable " << editable << endl;
136
    file << "saveable " << saveable << endl;
1584 jag 137
    file << "wrap " << cbwrap.state << endl;
964 jag 138
    if (saveable) {
1695 jag 139
      file << "savings " << n << spc;
140
      for (int i = 0; i < n; ++i) file << heights[i] << spc << selection[i] << spc;
1331 jag 141
      file << nsel << endl;
964 jag 142
    } else {
143
      file << "savings 0" << endl;
144
    }
1587 jag 145
 
146
    int j = bmk.size ();
1695 jag 147
    file << "bookmarks " << j << spc;
1625 jag 148
    if (j) {
149
      for (int i = 0; i < j; ++i) {
150
        bookmark* bi = bmk[i];
151
        vector<int>& ids = bi->ids;
152
        int n = ids.size ();
1695 jag 153
        file << n << spc;
154
        for (int m = 0; m < n; ++m) file << ids[m] << spc;
1625 jag 155
      }
1587 jag 156
    }
964 jag 157
  } else dlog << "!!! couldnt save levels !!!" << endl;
158
}
159
 
160
int levels::stop_editing () {
161
  if (editing == FINISH) {
162
    editing = 0;
163
    return 1;
164
  }
165
  return 0;
166
}
167
 
168
int levels::handle_input () {
169
 
1263 jag 170
  prev_mousey = mousey;
171
 
964 jag 172
  widget::handle_input ();
173
 
174
  int hne = hover && !editing;
175
  if (hne) calc_lev ();
176
 
1562 jag 177
 
964 jag 178
  if (editable) {
1584 jag 179
 
2297 jag 180
    if (keypressed (SDLK_f)) {
181
      paint = !paint;
182
      if (paintl) paintl->paint (*this);
183
    } else if (keypressedd (SDLK_LEFT)) {
184
      lshift ();
185
    } else if (keypressedd (SDLK_RIGHT)) {
186
      rshift ();
187
    }
188
 
1587 jag 189
    for (int i = 0, j = children.size(); i < j; ++i) {
190
      if (children[i]->handle_input ()) return 1;
1584 jag 191
    }
192
 
964 jag 193
    if (lmb) {
194
      if (lmb_clicked == 0) {
195
        if (stop_editing () == 0) {
196
          if (hne) {
1449 jag 197
            if (SHIFT) {
1263 jag 198
              bool& k = selection [lev];
199
              k = !k;
200
              if (k) ++nsel; else --nsel;
201
            } else {
964 jag 202
              editing = STARTED;
203
              widget::focus = this;
1263 jag 204
            }
964 jag 205
          }
206
        }
207
      }
208
      lmb_clicked = 1;
209
    } else {
1587 jag 210
 
964 jag 211
      lmb_clicked = 0;
1587 jag 212
      if (editing) {
1263 jag 213
 
964 jag 214
        if (wheel) {
215
          mousey -= wheel;
216
          warp_mouse (mousex, mousey);
217
        }
1263 jag 218
 
964 jag 219
        if (paint) calc_lev ();
1263 jag 220
 
964 jag 221
        calc_hgt_val ();
1263 jag 222
 
223
        int dh = set (lev, val, hgt);
1266 jag 224
        int uml = 0;
1449 jag 225
        if (selection[lev] && !SHIFT ) uml = update_mul_lev (dh);
1585 jag 226
        if (chgl && (dh || uml)) chgl->changed (*this);
1263 jag 227
 
964 jag 228
        editing = FINISH;
1263 jag 229
 
1107 jag 230
      } else {
231
        if (widget::focus == this) widget::focus = 0;
964 jag 232
      }
233
    }
234
  }
235
 
1587 jag 236
  return 1;
964 jag 237
 
238
}
239
 
1266 jag 240
int levels::update_mul_lev (int dh) {
1263 jag 241
  float dv = dh * extents.height_1;
1294 jag 242
  int ret = 0;
1584 jag 243
  for (int i = 0; i < n; ++i) {
1266 jag 244
    if ((i != lev) && selection[i]) {
1263 jag 245
      int& hi = heights[i];
246
      float& vi = values[i];
247
      int hji = hi + dh;
248
      float vji = vi + dv;
1266 jag 249
 
1295 jag 250
      if (hji < 0) hji = 0; else if (hji > extents.height) hji = extents.height;
251
      if (vji < 0.0f) vji = 0.0f; else if (vji > 1.0f) vji = 1.0f;
1263 jag 252
      hi = hji;
253
      vi = vji;
1266 jag 254
      ret = 1;
1263 jag 255
    }
256
  }
1266 jag 257
  return ret;
1263 jag 258
}
259
 
964 jag 260
void levels::calc_lev () {
1584 jag 261
  lev =  (mousex - extents.left) / elem;
262
  if (lev > last || lev < 0) lev = -1;
964 jag 263
}
264
 
265
void levels::calc_hgt_val () {
266
  hgt = mouseyy - extents.bottom;
267
  clamp<int> (0, hgt, extents.height);
268
  val = hgt * extents.height_1;
269
}
270
 
271
void levels::clear_hgt_val () {
1584 jag 272
  for (int i = 0; i < n; ++i) values[i] = heights[i] = 0;
964 jag 273
}
274
 
275
void levels::draw () {
276
 
2012 jag 277
  if (editing) {
278
    glColor3f (.5f, .5f, .5f);
279
    int ybh = extents.bottom + hgt;
280
    glBegin (GL_LINES);
281
      glVertex2i (extents.left, ybh);
282
      glVertex2i (extents.right, ybh);
283
    glEnd ();
284
  }
285
 
964 jag 286
  glEnable (GL_BLEND);
287
  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1584 jag 288
    int i = 0, x = extents.left, ds = elem - 2;
964 jag 289
    if (extents.left < 0) {
1584 jag 290
      i = -extents.left / elem;
964 jag 291
      x = 0;
292
    }
1584 jag 293
    for (;i < n; ++i) {
964 jag 294
      int l = x + 1, r = x + ds;
295
      glColor4f (clr.r, clr.g, clr.b, a0);
296
        glRecti (l, extents.bottom, r, extents.top);
1265 jag 297
 
1587 jag 298
      float dc = selection[i] * 0.4;
1586 jag 299
      glColor4f (clr.r + dc * clr.r, clr.g + dc * clr.g, clr.b + dc * clr.b, a);
964 jag 300
        glRecti (l, extents.bottom, r, extents.bottom + heights[i]);
1584 jag 301
      x += elem;
964 jag 302
      extern viewport view;
303
      if (x > view.xmax) break;
304
    }
305
  glDisable (GL_BLEND);
306
 
307
  sprintf (BUFFER, "%d/%.3f", lev+1, lev > -1? values[lev]:-1);
308
  draw_string (BUFFER, extents.left, extents.bottom - line_height, 0);
1584 jag 309
 
1587 jag 310
  if (editable) for (int i = 0, j = children.size(); i < j; ++i) children[i]->draw ();
311
 
964 jag 312
}
313
 
314
int levels::change (int i, float dv) {
1584 jag 315
  if (i > -1 && i < n) {
964 jag 316
    float& vi = values[i];
317
    vi += dv;
318
    int result = clamp<float> (0, vi, 1);
319
    heights[i] = (int) (vi * extents.height + 0.5);
320
    return result;
321
  }
322
  return 0;
323
}
324
 
325
void levels::set_only (int i, float v) {
1584 jag 326
  if (i > -1 && i < n) {
964 jag 327
    clamp<float> (0, v, 1);
328
    values[i] = v;
329
    heights[i] = (int)(v * extents.height + 0.5);
330
  }
331
}
332
 
1263 jag 333
int levels::set (int i, float v, int h) { // from ui
1584 jag 334
  if (i > -1 && i < n) {
1263 jag 335
    int& hi = heights[i];
336
    int dh = h - hi;
337
    hi = h;
964 jag 338
    float& vi = values[i];
339
    if (vi != v) { // bcos from ui
340
      vi = v;
341
    }
1263 jag 342
    return dh;
964 jag 343
  }
1263 jag 344
  return 0;
964 jag 345
}
346
 
347
void levels::update () {
1585 jag 348
  if (chgl) chgl->changed (*this);
964 jag 349
}
350
 
351
void levels::chkpos () {
352
  extern viewport view;
353
  if (!view.inside (extents.left, extents.bottom)) extents.lower_corner (0, 0);
354
}
355
 
356
void levels::reheight () {
1584 jag 357
  for (int i = 0; i < n; ++i) {
964 jag 358
    float v = values[i];
359
    int h = v * height + 0.5;
360
    heights[i] = h;
361
  }
362
}
363
 
1080 jag 364
int levels::lshift () {
1023 jag 365
 
964 jag 366
  float v0 = values[0];
367
  int h0 = heights[0];
1023 jag 368
 
1584 jag 369
  int wrap = cbwrap.state;
370
 
1023 jag 371
  if (wrap == 0) {
1584 jag 372
    if (h0) return 0;
1023 jag 373
  }
374
 
1584 jag 375
  for (int i = 0, j = 1; i < last; ++i, ++j) {
964 jag 376
    values[i] = values[j];
377
    heights[i] = heights[j];
378
  }
1023 jag 379
 
1584 jag 380
  float& vl = values[last];
381
  int& hl = heights[last];
964 jag 382
  if (wrap) {
1584 jag 383
    vl = v0;
384
    hl = h0;
1023 jag 385
  } else {
1584 jag 386
    vl = 0;
387
    hl = 0;
964 jag 388
  }
1023 jag 389
 
1585 jag 390
  if (shftl) shftl->shifted (*this);
1584 jag 391
 
1080 jag 392
  return 1;
393
 
964 jag 394
}
395
 
1080 jag 396
int levels::rshift () {
1584 jag 397
  float vl = values[last];
398
  int hl = heights[last];
1023 jag 399
 
1584 jag 400
  int wrap = cbwrap.state;
1023 jag 401
  if (wrap == 0) {
1080 jag 402
    if (hl) return 0;
1023 jag 403
  }
404
 
1584 jag 405
  for (int j = last, i = last - 1; j > 0; --j, --i) {
964 jag 406
    values[j]=values[i];
407
    heights[j]=heights[i];
408
  }
1023 jag 409
 
1584 jag 410
  float& v0 = values[0];
411
  int& h0 = heights[0];
412
 
964 jag 413
  if (wrap) {
1584 jag 414
    v0 = vl;
415
    h0 = hl;
1023 jag 416
  } else {
1584 jag 417
    v0 = 0;
418
    h0 = 0;
964 jag 419
  }
1023 jag 420
 
1585 jag 421
  if (shftl) shftl->shifted (*this);
1584 jag 422
 
1080 jag 423
  return 1;
424
 
964 jag 425
}
1584 jag 426
 
427
void levels::selall () {
1587 jag 428
  nsel = 0;
1584 jag 429
  for (int i = 0; i < n; ++i) {
1587 jag 430
    if (heights[i]) {
431
      selection[i] = 1;
432
      ++nsel;
433
    }
1584 jag 434
  }
1587 jag 435
  clearbookmarks ();
1584 jag 436
}
437
 
438
void levels::selnon () {
439
  for (int i = 0; i < n; ++i) selection[i] = 0;
440
  nsel = 0;
1587 jag 441
  clearbookmarks ();
1584 jag 442
}
443
 
444
void levels::invsel () {
445
  for (int i = 0; i < n; ++i) {
446
    bool& si = selection[i];
447
    if (si) {
448
      si = 0;
449
      --nsel;
450
    }
451
    else if (heights[i]) {
452
      si = 1;
453
      ++nsel;
454
    }
455
  }
1587 jag 456
  clearbookmarks ();
1584 jag 457
}
458
 
459
CLICKED_BUTTON (levels, alllis) {
460
  levels* l = (levels*) data;
461
  l->selall();
462
}
463
 
464
CLICKED_BUTTON (levels, nonlis) {
465
  levels* l = (levels*) data;
466
  l->selnon();
467
}
468
 
469
 
470
CLICKED_BUTTON (levels, invlis) {
471
  levels* l = (levels*) data;
472
  l->invsel();
473
}
474
 
475
CLICKED_BUTTON (levels, lshiftlis) {
476
  levels* l = (levels*) data;
477
  l->lshift ();
478
}
479
 
480
CLICKED_BUTTON (levels, rshiftlis) {
481
  levels* l = (levels*) data;
482
  l->rshift ();
483
}
484
 
1587 jag 485
CLICKED_BUTTON (levels, pluslis) {
486
  levels* l = (levels*) data;
487
  l->addbookmark ();
488
}
489
 
1584 jag 490
void levels::slide::clicked (button& b) {
491
  if (!mouse_slider0.active) {
492
    mouse_slider0.add (this);
493
    activate_mouse_slider ();
494
  }
495
}
496
 
497
void levels::slide::moused (int dir, double scl) {
498
  levels* l = (levels*) data;
499
  if (dir > 0) l->rshift (); else l->lshift ();
500
}
1585 jag 501
 
502
void levels::set_pos (int x, int y) {
503
  widget::set_pos (x, y);
504
  extern int line_height;
505
  int bx = extents.right + 3, by = extents.top - line_height;
506
  blshift.set_pos (bx, by);
507
  brshift.set_pos (bx + 28, by);
508
  by -= line_height;
509
  {
510
    button* b[] = {&cbwrap, &bslide, &ball, &bnone, &binvert};
511
    for (int i = 0; i < 5; ++i) {
512
      button& bi = *b[i];
513
      bi.set_pos (bx, by);
514
      by -= line_height;
515
    }
516
  }
517
  {
518
    button* b[] = {&plus, &minus, &cross};
519
    for (int i = 0; i < 3; ++i) {
520
      b[i]->set_pos (bx, by);
521
      bx += 20;
522
    }
523
  }
1586 jag 524
  szr.set_pos (extents.right + elem, extents.bottom);
1585 jag 525
}
1586 jag 526
 
1587 jag 527
void levels::addbookmark () {
1588 jag 528
 
1587 jag 529
  if (nsel) {
530
    bookmark* bm = new bookmark ();
531
    int bs = bmk.size ();
532
    if (bs) {
533
      int lb = bs - 1;
534
      bookmark* plb = bmk [lb];
535
      bm->set_pos (minus.extents.left, plb->extents.bottom - state_button::SIZE2);
536
    } else {
537
      bm->set_pos (minus.extents.left, minus.extents.bottom - state_button::SIZE2);
538
    }
539
 
540
    for (int i = 0; i < n; ++i) if (selection[i]) bm->ids.push_back (i);
541
 
542
    clearbookmarks ();
543
 
544
    bm->set_state (1, 0);
545
    bm->set_listener (&bml);
546
 
547
    bmk.push_back (bm);
548
    this->add_child (bm);
549
 
1695 jag 550
    cons << GREEN << "Bookmarked " << nsel << spc << name << eol;
1587 jag 551
 
552
  } else {
553
    cons << RED << "No " << name << " selected to bookmark. SHIFT+click " << name << " to select." << eol;
554
  }
1588 jag 555
 
1587 jag 556
}
557
 
1588 jag 558
void levels::removebookmark () {
559
  for (vector<bookmark*>::iterator i = bmk.begin (), j = bmk.end (); i != j; ) {
560
    bookmark* b = *i;
561
    if (b->state) {
562
      i = bmk.erase (i);
563
      j = bmk.end ();
564
      this->remove_child (b);
565
      delete b;
566
    } else {
567
      ++i;
568
    }
569
  }
570
}
571
 
1587 jag 572
void levels::removeallbookmarks () {
573
  for (int i = 0, j = bmk.size (); i < j; ++i) {
574
    bookmark* pbi = bmk[i];
575
    this->remove_child (pbi);
576
    delete pbi;
577
  }
578
  bmk.clear ();
579
}
580
 
581
void levels::clearbookmarks () {
582
  for (int i = 0, j = bmk.size (); i < j; ++i) bmk[i]->set_state (0,0);
583
}
584
 
585
CLICKED_CHECKBUTTON (levels, bmlis) {
586
  bookmark& b = dynamic_cast<bookmark&>(cb);
587
  int s = b.state;
588
  levels& l = *( (levels*) data);
589
  if (SHIFT)
590
    ;
591
  else {
592
    l.selnon ();
593
    if (s == 0) s = 1;
594
    b.set_state (s, 0);
595
  }
1588 jag 596
 
597
  int sl [] = {-1, 1};
1587 jag 598
  for (int i = 0, j = l.bmk.size (); i < j; ++i) {
599
    if (&b == l.bmk[i]) {
600
      vector<int>& ids = b.ids;
601
      int n = ids.size ();
602
      for (int m = 0; m < n; ++m) l.selection[ids[m]] = s;
1588 jag 603
      l.nsel += (n * sl[s]);
1587 jag 604
    }
605
  }
606
}
607
 
1588 jag 608
CLICKED_BUTTON (levels, minuslis) {
609
  ((levels*) data)->removebookmark ();
610
}
611
 
1587 jag 612
CLICKED_BUTTON (levels, crosslis) {
613
  ((levels*) data)->removeallbookmarks ();
614
}
1588 jag 615
 
1625 jag 616
/*MOVED (levels,szrlis) {
617
  levels* pl = (levels *) data;
618
  l->sized ();
619
}*/
1588 jag 620
 
1625 jag 621
void levels::moved () {
1588 jag 622
  if (extents.top > szr.extents.bottom) {
623
    height = extents.height = extents.top - szr.extents.bottom;
624
    set_pos (posx, szr.posy);
625
    reheight ();
626
  }
627
}