Review my SNES bitplane graphics code? 
Author Message
User avatar

Joined: 2014-09-27 09:38
Posts: 898
Location: New York, NY, USA
 Review my SNES bitplane graphics code?
Hey there, I'm curious if someone here more experienced than myself at N-bitplane graphics would review my code and let me know if I'm missing something or I've got something completely wrong. I'm cautiously optimistic that I'm headed in the right direction, as 2-bpp and 4-bpp seem to work properly, but I haven't yet implemented palette swapping in my display code yet. Currently only handles 2 and 4, and I want to add 1-bpp once I clean it up a bit.

For reference, it's JavaScript but easily editable to become C or C++. The main bits I'm worried about are how _p1, _p2, _p3, and _p4 are assigned.

Web JS-specific stuff:

* the 'd' parameter can be a raw ArrayBuffer (basically array of bytes) or an array of uint8 values
* new Uint8Array(d) is a constructor that basically says "treat 'd' as if it was an array of uint8 values" (there are variants for signed, unsigned, even float of up to 32 bits)
* Array.unshift(...) is web JS's std::vector<Object>.push_front(...) (or std::deque's)
* for those unfamiliar, JS before ES6 doesn't explicitly type and instead declares pretty much all variables as 'var' type
* console.log(...) is web JS's stderr
* bitwise ops in JS work as C++ and (IIRC) have the same precedence rules

Code:
function _parse_gfx(d,bpp,w,h) {
   // d: buffer
   // bpp: bits per pixel
   // w: pixels per row (usually 8)
   // h: number of rows (usually 8)
   var ret = null;
   if (bpp>0) {
      var l = d.length||d.byteLength||0;
      var _a = new Uint8Array(d);
      var i=0, _w = w;
      if (w>8) console.log("GFX::BPP"+bpp+", - width > 8",w);
      else if (w<8) _w = 8;   // force min width of 8 bits
      var _p1 = 0, _p2 = 0, _p3 = 0, _p4 = 0;
      var off_h = h<<1;
      var y = 0;
      if (bpp>1) { // todo: allow 1bpp
         ret = [ ];
         while (i<l&&y<h) {
            // rows are w wide
            // and 2*w bits handle one row
            // for each pair/column: ((row[1]&bit_x)<<1)|(row[0]&bit_x)
            _p1 = _a[ i ]
            if (bpp>1) _p2 = _a[ i+1 ];
            if (bpp>2) _p3 = _a[ i+off_h ], _p4 = _a[ i+off_h+1 ];
            //if (w>8) _p3 = _a[ i+2 ];
            var _row = [ ], x;
            for (x=0; x<_w; ++x) {
               var _p = 0;
               _p = (_p<<1) | ((_p1&(1<<x))>>x);   // bitplane 1
               _p = (_p<<1) | ((_p2&(1<<x))>>x);   // bitplane 2
               _p = (_p<<1) | ((_p3&(1<<x))>>x);   // bitplane 3
               _p = (_p<<1) | ((_p4&(1<<x))>>x);   // bitplane 4
               _row.unshift(_p);   // unshift because "big-endian-ish"
            }
            if (w<8) _row.length = w;
            //console.log(_row[x]);
            ret.push(new Uint8Array(_row));
            i += 2;
            ++y;
         }
      }
   }
   return ret;
}

_________________
Apollolux Digital Designs :: website development
Alex Rosario Type :: typeface and font design and development
President, ACM - CUNY Hunter College chapter
:: A student at Hunter? Interested in tech? Find us!


2017-06-09 05:36