/[svn]/gigedit/trunk/src/gigedit/dimregionchooser.cpp
ViewVC logotype

Diff of /gigedit/trunk/src/gigedit/dimregionchooser.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2845 by persson, Sun Sep 20 10:18:22 2015 UTC revision 3089 by schoenebeck, Sun Jan 15 19:18:39 2017 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006-2015 Andreas Persson   * Copyright (C) 2006-2017 Andreas Persson
3   *   *
4   * This program is free software; you can redistribute it and/or   * This program is free software; you can redistribute it and/or
5   * modify it under the terms of the GNU General Public License as   * modify it under the terms of the GNU General Public License as
# Line 25  Line 25 
25  #include <glibmm/stringutils.h>  #include <glibmm/stringutils.h>
26  #include <glibmm/ustring.h>  #include <glibmm/ustring.h>
27  #include <gtkmm/messagedialog.h>  #include <gtkmm/messagedialog.h>
28    #include <assert.h>
29    
30  #include "global.h"  #include "global.h"
31    
# Line 88  DimRegionChooser::DimRegionChooser(Gtk:: Line 89  DimRegionChooser::DimRegionChooser(Gtk::
89      cursor_is_resize = false;      cursor_is_resize = false;
90      h = 24;      h = 24;
91      multiSelectKeyDown = false;      multiSelectKeyDown = false;
92        modifybothchannels = modifyalldimregs = modifybothchannels = false;
93      set_can_focus();      set_can_focus();
94    
95      actionGroup = Gtk::ActionGroup::create();      actionGroup = Gtk::ActionGroup::create();
# Line 141  DimRegionChooser::~DimRegionChooser() Line 143  DimRegionChooser::~DimRegionChooser()
143  {  {
144  }  }
145    
146    void DimRegionChooser::setModifyBothChannels(bool b) {
147        modifybothchannels = b;
148    }
149    
150    void DimRegionChooser::setModifyAllDimensionRegions(bool b) {
151        modifyalldimregs = b;
152    }
153    
154    void DimRegionChooser::setModifyAllRegions(bool b) {
155        modifyallregions = b;
156    }
157    
158  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2  #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
159  bool DimRegionChooser::on_expose_event(GdkEventExpose* e)  bool DimRegionChooser::on_expose_event(GdkEventExpose* e)
160  {  {
# Line 507  void DimRegionChooser::get_dimregions(co Line 521  void DimRegionChooser::get_dimregions(co
521    
522  void DimRegionChooser::update_after_resize()  void DimRegionChooser::update_after_resize()
523  {  {
524      if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {      const uint8_t upperLimit = resize.pos - 1;
525        gig::Instrument* instr = (gig::Instrument*)region->GetParent();
526    
527          int bitpos = 0;      int bitpos = 0;
528          for (int j = 0 ; j < resize.dimension ; j++) {      for (int j = 0 ; j < resize.dimension ; j++) {
529              bitpos += region->pDimensionDefinitions[j].bits;          bitpos += region->pDimensionDefinitions[j].bits;
530          }      }
531    
532        const int stereobitpos =
533            (modifybothchannels) ? baseBits(gig::dimension_samplechannel, region) : -1;
534    
535        // the velocity dimension must be handled differently than all other
536        // dimension types, because
537        // 1. it is currently the only dimension type which allows different zone
538        //    sizes for different cases
539        // 2. for v2 format VelocityUpperLimit has to be set, DimensionUpperLimits for v3
540        if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {
541          int mask =          int mask =
542              ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);              ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);
543          int c = maindimregno & mask; // mask away this dimension          int c = maindimregno & mask; // mask away this dimension
# Line 538  void DimRegionChooser::update_after_resi Line 563  void DimRegionChooser::update_after_resi
563              }              }
564          }          }
565    
566          gig::DimensionRegion* d = region->pDimensionRegions[c + resize.offset];          int index = c + (resize.zone << bitpos);
567            gig::DimensionRegion* d = region->pDimensionRegions[index];
568          // update both v2 and v3 values          // update both v2 and v3 values
569          d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;          d->DimensionUpperLimits[resize.dimension] = upperLimit;
570          d->VelocityUpperLimit = resize.pos - 1;          d->VelocityUpperLimit = upperLimit;
571            if (modifybothchannels && stereobitpos >= 0) { // do the same for the other audio channel's dimregion ...
572                gig::DimensionRegion* d = region->pDimensionRegions[index ^ (1 << stereobitpos)];
573                d->DimensionUpperLimits[resize.dimension] = upperLimit;
574                d->VelocityUpperLimit = upperLimit;
575            }
576    
577            if (modifyalldimregs) {
578                gig::Region* rgn = NULL;
579                for (int key = 0; key < 128; ++key) {
580                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
581                    rgn = instr->GetRegion(key);
582                    if (!modifyallregions && rgn != region) continue; // hack to reduce overall code amount a bit
583                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(resize.dimensionDef.dimension);
584                    if (!dimdef) continue;
585                    if (dimdef->zones != resize.dimensionDef.zones) continue;
586                    const int iDim = getDimensionIndex(resize.dimensionDef.dimension, rgn);
587                    assert(iDim >= 0 && iDim < rgn->Dimensions);
588    
589                    // the dimension layout might be completely different in this
590                    // region, so we have to recalculate bitpos etc for this region
591                    const int bitpos = baseBits(resize.dimensionDef.dimension, rgn);
592                    const int stencil = ~(((1 << dimdef->bits) - 1) << bitpos);
593                    const int selection = resize.zone << bitpos;
594    
595                    // primitive and inefficient loop implementation, however due to
596                    // this circumstance the loop code is much simpler, and its lack
597                    // of runtime efficiency should not be notable in practice
598                    for (int idr = 0; idr < 256; ++idr) {
599                        const int index = (idr & stencil) | selection;
600                        assert(index >= 0 && index < 256);
601                        gig::DimensionRegion* dr = rgn->pDimensionRegions[index];
602                        if (!dr) continue;
603                        dr->DimensionUpperLimits[iDim] = upperLimit;
604                        d->VelocityUpperLimit = upperLimit;
605                    }
606                }
607            } else if (modifyallregions) { // implies modifyalldimregs is false ...
608                // resolve the precise case we need to modify for all other regions
609                DimensionCase dimCase = dimensionCaseOf(d);
610                // apply the velocity upper limit change to that resolved dim case
611                // of all regions ...
612                gig::Region* rgn = NULL;
613                for (int key = 0; key < 128; ++key) {
614                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
615                    rgn = instr->GetRegion(key);
616                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(resize.dimensionDef.dimension);
617                    if (!dimdef) continue;
618                    if (dimdef->zones != resize.dimensionDef.zones) continue;
619                    const int iDim = getDimensionIndex(resize.dimensionDef.dimension, rgn);
620                    assert(iDim >= 0 && iDim < rgn->Dimensions);
621    
622                    std::vector<gig::DimensionRegion*> dimrgns = dimensionRegionsMatching(dimCase, rgn);
623                    for (int i = 0; i < dimrgns.size(); ++i) {
624                        gig::DimensionRegion* dr = dimrgns[i];
625                        dr->DimensionUpperLimits[iDim] = upperLimit;
626                        dr->VelocityUpperLimit = upperLimit;
627                    }
628                }
629            }
630      } else {      } else {
631          for (int i = 0 ; i < region->DimensionRegions ; ) {          for (int i = 0 ; i < region->DimensionRegions ; ) {
   
632              if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {              if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {
633                  // the dimension didn't previously have custom                  // the dimension didn't previously have custom
634                  // limits, so we have to set default limits for                  // limits, so we have to set default limits for
635                  // all the dimension regions                  // all the dimension regions
                 int bitpos = 0;  
                 for (int j = 0 ; j < resize.dimension ; j++) {  
                     bitpos += region->pDimensionDefinitions[j].bits;  
                 }  
636                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;                  int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
637    
638                  for (int j = 0 ; j < nbZones ; j++) {                  for (int j = 0 ; j < nbZones ; j++) {
# Line 561  void DimRegionChooser::update_after_resi Line 640  void DimRegionChooser::update_after_resi
640                      d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);                      d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);
641                  }                  }
642              }              }
643              gig::DimensionRegion* d = region->pDimensionRegions[i + resize.offset];              int index = i + (resize.zone << bitpos);
644              d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;              gig::DimensionRegion* d = region->pDimensionRegions[index];
645                d->DimensionUpperLimits[resize.dimension] = upperLimit;
646    #if 0       // the following is currently not necessary, because ATM the gig format uses for all dimension types except of the veleocity dimension the same zone sizes for all cases
647                if (modifybothchannels && stereobitpos >= 0) { // do the same for the other audio channel's dimregion ...
648                    gig::DimensionRegion* d = region->pDimensionRegions[index ^ (1 << stereobitpos)];
649                    d->DimensionUpperLimits[resize.dimension] = upperLimit;
650                }
651    #endif
652              int bitpos = 0;              int bitpos = 0;
653              int j;              int j;
654              for (j = 0 ; j < region->Dimensions ; j++) {              for (j = 0 ; j < region->Dimensions ; j++) {
# Line 577  void DimRegionChooser::update_after_resi Line 662  void DimRegionChooser::update_after_resi
662              if (j == region->Dimensions) break;              if (j == region->Dimensions) break;
663              i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);              i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);
664          }          }
665    
666            if (modifyallregions) { // TODO: this code block could be merged with the similar (and more generalized) code block of the velocity dimension above
667                gig::Region* rgn = NULL;
668                for (int key = 0; key < 128; ++key) {
669                    if (!instr->GetRegion(key) || instr->GetRegion(key) == rgn) continue;
670                    rgn = instr->GetRegion(key);
671                    gig::dimension_def_t* dimdef = rgn->GetDimensionDefinition(resize.dimensionDef.dimension);
672                    if (!dimdef) continue;
673                    if (dimdef->zones != resize.dimensionDef.zones) continue;
674                    const int iDim = getDimensionIndex(resize.dimensionDef.dimension, rgn);
675                    assert(iDim >= 0 && iDim < rgn->Dimensions);
676    
677                    // the dimension layout might be completely different in this
678                    // region, so we have to recalculate bitpos etc for this region
679                    const int bitpos = baseBits(resize.dimensionDef.dimension, rgn);
680                    const int stencil = ~(((1 << dimdef->bits) - 1) << bitpos);
681                    const int selection = resize.zone << bitpos;
682    
683                    // this loop implementation is less efficient than the above's
684                    // loop implementation (which skips unnecessary dimension regions)
685                    // however this code is much simpler, and its lack of runtime
686                    // efficiency should not be notable in practice
687                    for (int idr = 0; idr < 256; ++idr) {
688                        const int index = (idr & stencil) | selection;
689                        assert(index >= 0 && index < 256);
690                        gig::DimensionRegion* dr = rgn->pDimensionRegions[index];
691                        if (!dr) continue;
692                        dr->DimensionUpperLimits[iDim] = upperLimit;
693                    }
694                }
695            }
696      }      }
697  }  }
698    
# Line 805  bool DimRegionChooser::is_in_resize_zone Line 921  bool DimRegionChooser::is_in_resize_zone
921                  if (x <= limitx - 2) break;                  if (x <= limitx - 2) break;
922                  if (x <= limitx + 2) {                  if (x <= limitx + 2) {
923                      resize.dimension = dim;                      resize.dimension = dim;
924                      resize.offset = iZone << bitpos;                      resize.dimensionDef = region->pDimensionDefinitions[dim];
925                        resize.zone = iZone;
926                      resize.pos = limit;                      resize.pos = limit;
927                      resize.min = prev_limit;                      resize.min = prev_limit;
928    

Legend:
Removed from v.2845  
changed lines
  Added in v.3089

  ViewVC Help
Powered by ViewVC