First contrib taken from Qt MiniDisplayManager.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/BitArray.cpp Tue Jun 17 09:55:20 2014 +0200
1.3 @@ -0,0 +1,1020 @@
1.4 +/***************************************************************************
1.5 +* Arrays of Arbitrary Bit Length
1.6 +*
1.7 +* File : bitarray.cpp
1.8 +* Purpose : Provides object with methods for creation and manipulation of
1.9 +* arbitrary length arrays of bits.
1.10 +*
1.11 +* Bit arrays are implemented as vectors of unsigned chars. Bit
1.12 +* 0 is the MSB of char 0, and the last bit is the least
1.13 +* significant (non-spare) bit of the last unsigned char.
1.14 +*
1.15 +* Example: array of 20 bits (0 through 19) with 8 bit unsigned
1.16 +* chars requires 3 unsigned chars (0 through 2) to
1.17 +* store all the bits.
1.18 +*
1.19 +* char 0 1 2
1.20 +* +--------+--------+--------+
1.21 +* | | | |
1.22 +* +--------+--------+--------+
1.23 +* bit 01234567 8911111111111XXXX
1.24 +* 012345 6789
1.25 +*
1.26 +* Author : Michael Dipperstein
1.27 +* Date : July 23, 2004
1.28 +*
1.29 +****************************************************************************
1.30 +* HISTORY
1.31 +*
1.32 +* $Id: bitarray.cpp,v 1.7 2010/02/04 03:31:43 michael Exp $
1.33 +* $Log: bitarray.cpp,v $
1.34 +* Revision 1.7 2010/02/04 03:31:43 michael
1.35 +* Replaced vector<unsigned char> with an array of unsigned char.
1.36 +*
1.37 +* Made updates for GCC 4.4.
1.38 +*
1.39 +* Revision 1.5 2007/08/06 05:23:29 michael
1.40 +* Updated for LGPL Version 3.
1.41 +*
1.42 +* All methods that don't modify object have been made
1.43 +* const to increase functionality of const bit_array_c.
1.44 +*
1.45 +* All assignment operators return a reference to the object being assigned a value so that operator chaining will work.
1.46 +*
1.47 +* Added >> and << operators.
1.48 +*
1.49 +* Revision 1.3 2006/04/30 23:34:07 michael
1.50 +* Improved performance by incorporating Benjamin Schindler's
1.51 +* <bschindler@student.ethz.ch> changes to pass arguments as a reference.
1.52 +*
1.53 +* Revision 1.2 2004/08/05 22:16:49 michael
1.54 +* Add overloads for bitwise operators returning values.
1.55 +* Add a more natural looking way to set bit values.
1.56 +*
1.57 +* Revision 1.1.1.1 2004/08/04 13:28:20 michael
1.58 +* bit_array_c
1.59 +*
1.60 +****************************************************************************
1.61 +*
1.62 +* Bitarray: An ANSI C++ class for manipulating arbitrary length bit arrays
1.63 +* Copyright (C) 2004, 2006-2007, 2010 by
1.64 +* Michael Dipperstein (mdipper@alumni.engr.ucsb.edu)
1.65 +*
1.66 +* This file is part of the bit array library.
1.67 +*
1.68 +* The bit array library is free software; you can redistribute it and/or
1.69 +* modify it under the terms of the GNU Lesser General Public License as
1.70 +* published by the Free Software Foundation; either version 3 of the
1.71 +* License, or (at your option) any later version.
1.72 +*
1.73 +* The bit array library is distributed in the hope that it will be useful,
1.74 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
1.75 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
1.76 +* General Public License for more details.
1.77 +*
1.78 +* You should have received a copy of the GNU Lesser General Public License
1.79 +* along with this program. If not, see <http://www.gnu.org/licenses/>.
1.80 +*
1.81 +***************************************************************************/
1.82 +
1.83 +/***************************************************************************
1.84 +* INCLUDED FILES
1.85 +***************************************************************************/
1.86 +#include <iostream>
1.87 +#include <climits>
1.88 +#include "bitarray.h"
1.89 +
1.90 +using namespace std;
1.91 +
1.92 +/***************************************************************************
1.93 +* MACROS
1.94 +***************************************************************************/
1.95 +
1.96 +/* make CHAR_BIT 8 if it's not defined in limits.h */
1.97 +#ifndef CHAR_BIT
1.98 +#warning CHAR_BIT not defined. Assuming 8 bits.
1.99 +#define CHAR_BIT 8
1.100 +#endif
1.101 +
1.102 +/* position of bit within character */
1.103 +#define BIT_CHAR(bit) ((bit) / CHAR_BIT)
1.104 +
1.105 +/* array index for character containing bit */
1.106 +//SL: We had to change that macro since bits in our frame buffer are the other way around
1.107 +//TODO: Find a solution to tackle that problem
1.108 +//#define BIT_IN_CHAR(bit) (1 << (CHAR_BIT - 1 - ((bit) % CHAR_BIT)))
1.109 +#define BIT_IN_CHAR(bit) (1 << (((bit) % CHAR_BIT)))
1.110 +
1.111 +/* number of characters required to contain number of bits */
1.112 +#define BITS_TO_CHARS(bits) ((((bits) - 1) / CHAR_BIT) + 1)
1.113 +
1.114 +/* most significant bit in a character */
1.115 +#define MS_BIT (1 << (CHAR_BIT - 1))
1.116 +
1.117 +/***************************************************************************
1.118 +* METHODS
1.119 +***************************************************************************/
1.120 +
1.121 +/***************************************************************************
1.122 +* Method : bit_array_c - constructor
1.123 +* Description: This is the bit_array_c constructor. It reserves memory
1.124 +* for the vector storing the array.
1.125 +* Parameters : numBits - number of bits in the array
1.126 +* Effects : Allocates vectory for array bits
1.127 +* Returned : None
1.128 +***************************************************************************/
1.129 +BitArray::BitArray(const int numBits):
1.130 + m_NumBits(numBits),
1.131 + m_Array(NULL),
1.132 + m_OwnsBuffer(true)
1.133 +{
1.134 + m_SizeInBytes = BITS_TO_CHARS(numBits);
1.135 +
1.136 +
1.137 + /* allocate space for bit array */
1.138 + m_Array = new unsigned char[m_SizeInBytes];
1.139 +
1.140 + /* set all bits to 0 */
1.141 + fill_n(m_Array, m_SizeInBytes, 0);
1.142 +}
1.143 +
1.144 +/***************************************************************************
1.145 +* Method : bit_array_c - constructor
1.146 +* Description: This is the bit_array_c constructor. It copies the
1.147 +* for contents of a vector of unsigned char into the
1.148 +* bitarray.
1.149 +* Parameters : vect - vector to be copied
1.150 +* numBits - number of bits in the array
1.151 +* Effects : Allocates vectory for array bits
1.152 +* Returned : None
1.153 +***************************************************************************/
1.154 +BitArray::BitArray(unsigned char *array, const int numBits,bool aOwnsBuffer):
1.155 + m_NumBits(numBits),
1.156 + m_Array(array),
1.157 + m_OwnsBuffer(aOwnsBuffer)
1.158 +{
1.159 +
1.160 +}
1.161 +
1.162 +/***************************************************************************
1.163 +* Method : ~bit_array_c - destructor
1.164 +* Description: This is the bit_array_c destructor. At this point it's
1.165 +* just a place holder.
1.166 +* Parameters : None
1.167 +* Effects : None
1.168 +* Returned : None
1.169 +***************************************************************************/
1.170 +BitArray::~BitArray(void)
1.171 +{
1.172 + if (m_OwnsBuffer)
1.173 + {
1.174 + delete[] m_Array;
1.175 + m_Array = NULL;
1.176 + }
1.177 +}
1.178 +
1.179 +/***************************************************************************
1.180 +* Method : Dump
1.181 +* Description: This method dumps the conents of a bit array to stdout.
1.182 +* The format of the dump is a series of bytes represented in
1.183 +* hexadecimal.
1.184 +* Parameters : outStream - stream to write to
1.185 +* Effects : Array contents are dumped to stdout
1.186 +* Returned : None
1.187 +***************************************************************************/
1.188 +void BitArray::Dump(std::ostream &outStream)
1.189 +{
1.190 + int size;
1.191 +
1.192 + size = BITS_TO_CHARS(m_NumBits);
1.193 +
1.194 + outStream.width(2);
1.195 + outStream.fill('0');
1.196 + outStream << uppercase << hex << (int)(m_Array[0]); /* first byte */
1.197 +
1.198 + for (int i = 1; i < size; i++)
1.199 + {
1.200 + /* remaining bytes with a leading space */
1.201 + outStream << " ";
1.202 + outStream.width(2);
1.203 + outStream.fill('0');
1.204 + outStream << (int)(m_Array[i]);
1.205 + }
1.206 +
1.207 + outStream << dec;
1.208 +}
1.209 +
1.210 +/***************************************************************************
1.211 +* Method : SetAll
1.212 +* Description: This method sets every bit in the bit array to 1. This
1.213 +* method uses UCHAR_MAX to determine what it means to set
1.214 +* all bits in an unsigned char, so it is crucial that the
1.215 +* machine implementation of unsigned char utilizes all of
1.216 +* the bits in the memory allocated for an unsigned char.
1.217 +* Parameters : None
1.218 +* Effects : Each of the bits used in the bit array are set to 1.
1.219 +* Unused (spare) bits are set to 0.
1.220 +* Returned : None
1.221 +***************************************************************************/
1.222 +void BitArray::SetAll(void)
1.223 +{
1.224 + int bits, size;
1.225 + unsigned char mask;
1.226 +
1.227 + size = BITS_TO_CHARS(m_NumBits);
1.228 +
1.229 + /* set bits in all bytes to 1 */
1.230 + fill_n(m_Array, size, UCHAR_MAX);
1.231 +
1.232 + /* zero any spare bits so increment and decrement are consistent */
1.233 + bits = m_NumBits % CHAR_BIT;
1.234 + if (bits != 0)
1.235 + {
1.236 + mask = UCHAR_MAX << (CHAR_BIT - bits);
1.237 + m_Array[BIT_CHAR(m_NumBits - 1)] = mask;
1.238 + }
1.239 +}
1.240 +
1.241 +/***************************************************************************
1.242 +* Method : ClearAll
1.243 +* Description: This method sets every bit in the bit array to 0.
1.244 +* Parameters : None
1.245 +* Effects : Each of the bits in the bit array are set to 0.
1.246 +* Returned : None
1.247 +***************************************************************************/
1.248 +void BitArray::ClearAll(void)
1.249 +{
1.250 + int size;
1.251 +
1.252 + size = BITS_TO_CHARS(m_NumBits);
1.253 +
1.254 + /* set bits in all bytes to 0 */
1.255 + fill_n(m_Array, size, 0);
1.256 +}
1.257 +
1.258 +/***************************************************************************
1.259 +* Method : SetBit
1.260 +* Description: This method sets a bit in the bit array to 1.
1.261 +* Parameters : bit - the number of the bit to set
1.262 +* Effects : The specified bit will be set to 1.
1.263 +* Returned : None
1.264 +***************************************************************************/
1.265 +void BitArray::SetBit(const unsigned int bit)
1.266 +{
1.267 + if (m_NumBits <= bit)
1.268 + {
1.269 + return; /* bit out of range */
1.270 + }
1.271 +
1.272 + m_Array[BIT_CHAR(bit)] |= BIT_IN_CHAR(bit);
1.273 +}
1.274 +
1.275 +/**
1.276 +*/
1.277 +void BitArray::SetBitValue(const unsigned int bit, bool aValue)
1.278 + {
1.279 + if (aValue)
1.280 + {
1.281 + SetBit(bit);
1.282 + }
1.283 + else
1.284 + {
1.285 + ClearBit(bit);
1.286 + }
1.287 + }
1.288 +
1.289 +/***************************************************************************
1.290 +* Method : ClearBit
1.291 +* Description: This method sets a bit in the bit array to 0.
1.292 +* Parameters : bit - the number of the bit to clear
1.293 +* Effects : The specified bit will be set to 0.
1.294 +* Returned : None
1.295 +***************************************************************************/
1.296 +void BitArray::ClearBit(const unsigned int bit)
1.297 +{
1.298 + unsigned char mask;
1.299 +
1.300 + if (m_NumBits <= bit)
1.301 + {
1.302 + return; /* bit out of range */
1.303 + }
1.304 +
1.305 + /* create a mask to zero out desired bit */
1.306 + mask = BIT_IN_CHAR(bit);
1.307 + mask = ~mask;
1.308 +
1.309 + m_Array[BIT_CHAR(bit)] &= mask;
1.310 +}
1.311 +
1.312 +/***************************************************************************
1.313 +* Method : operator()
1.314 +* Description: Overload of the () operator. This method approximates
1.315 +* array indices used for assignment. It returns a
1.316 +* bit_array_index_c which includes an = method used to
1.317 +* set bit values.
1.318 +* Parameters : bit - index of array bit
1.319 +* Effects : None
1.320 +* Returned : bit_array_index_c (pointer to bit)
1.321 +***************************************************************************/
1.322 +BitArrayIndex BitArray::operator()(const unsigned int bit)
1.323 +{
1.324 + BitArrayIndex result(this, bit);
1.325 +
1.326 + return result;
1.327 +}
1.328 +
1.329 +/***************************************************************************
1.330 +* Method : operator[]
1.331 +* Description: Overload of the [] operator. This method returns the
1.332 +* value of a bit in the bit array.
1.333 +* Parameters : bit - index of array bit
1.334 +* Effects : None
1.335 +* Returned : The value of the specified bit.
1.336 +***************************************************************************/
1.337 +bool BitArray::operator[](const unsigned int bit) const
1.338 +{
1.339 + return((m_Array[BIT_CHAR(bit)] & BIT_IN_CHAR(bit)) != 0);
1.340 +}
1.341 +
1.342 +/***************************************************************************
1.343 +* Method : operator==
1.344 +* Description: overload of the == operator
1.345 +* Parameters : other - bit array to compare
1.346 +* Effects : None
1.347 +* Returned : True if this == other. Otherwise false.
1.348 +***************************************************************************/
1.349 +bool BitArray::operator==(const BitArray &other) const
1.350 +{
1.351 + if (m_NumBits != other.m_NumBits)
1.352 + {
1.353 + /* unequal sizes */
1.354 + return false;
1.355 + }
1.356 +
1.357 + return (this->m_Array == other.m_Array);
1.358 +}
1.359 +
1.360 +/***************************************************************************
1.361 +* Method : operator!=
1.362 +* Description: overload of the != operator
1.363 +* Parameters : other - bit array to compare
1.364 +* Effects : None
1.365 +* Returned : True if this != other. Otherwise false.
1.366 +***************************************************************************/
1.367 +bool BitArray::operator!=(const BitArray &other) const
1.368 +{
1.369 + if (m_NumBits != other.m_NumBits)
1.370 + {
1.371 + /* unequal sizes */
1.372 + return true;
1.373 + }
1.374 +
1.375 + return (this->m_Array != other.m_Array);
1.376 +}
1.377 +
1.378 +/***************************************************************************
1.379 +* Method : operator<
1.380 +* Description: overload of the < operator
1.381 +* Parameters : other - bit array to compare
1.382 +* Effects : None
1.383 +* Returned : True if this < other. Otherwise false.
1.384 +***************************************************************************/
1.385 +bool BitArray::operator<(const BitArray &other) const
1.386 +{
1.387 + if (m_NumBits != other.m_NumBits)
1.388 + {
1.389 + /* unequal sizes */
1.390 + return false;
1.391 + }
1.392 +
1.393 + return (this->m_Array < other.m_Array);
1.394 +}
1.395 +
1.396 +/***************************************************************************
1.397 +* Method : operator<=
1.398 +* Description: overload of the <= operator
1.399 +* Parameters : other - bit array to compare
1.400 +* Effects : None
1.401 +* Returned : True if this <= other. Otherwise false.
1.402 +***************************************************************************/
1.403 +bool BitArray::operator<=(const BitArray &other) const
1.404 +{
1.405 + if (m_NumBits != other.m_NumBits)
1.406 + {
1.407 + /* unequal sizes */
1.408 + return false;
1.409 + }
1.410 +
1.411 + return (this->m_Array <= other.m_Array);
1.412 +}
1.413 +
1.414 +/***************************************************************************
1.415 +* Method : operator>
1.416 +* Description: overload of the > operator
1.417 +* Parameters : other - bit array to compare
1.418 +* Effects : None
1.419 +* Returned : True if this > other. Otherwise false.
1.420 +***************************************************************************/
1.421 +bool BitArray::operator>(const BitArray &other) const
1.422 +{
1.423 + if (m_NumBits != other.m_NumBits)
1.424 + {
1.425 + /* unequal sizes */
1.426 + return false;
1.427 + }
1.428 +
1.429 + return (this->m_Array > other.m_Array);
1.430 +}
1.431 +
1.432 +/***************************************************************************
1.433 +* Method : operator>=
1.434 +* Description: overload of the >= operator
1.435 +* Parameters : other - bit array to compare
1.436 +* Effects : None
1.437 +* Returned : True if this >= other. Otherwise false.
1.438 +***************************************************************************/
1.439 +bool BitArray::operator>=(const BitArray &other) const
1.440 +{
1.441 + if (m_NumBits != other.m_NumBits)
1.442 + {
1.443 + /* unequal sizes */
1.444 + return false;
1.445 + }
1.446 +
1.447 + return (this->m_Array >= other.m_Array);
1.448 +}
1.449 +
1.450 +/***************************************************************************
1.451 +* Method : operator~
1.452 +* Description: overload of the ~ operator. Negates all non-spare bits in
1.453 +* bit array
1.454 +* Parameters : None
1.455 +* Effects : None
1.456 +* Returned : value of this after bitwise not
1.457 +***************************************************************************/
1.458 +BitArray BitArray::operator~(void) const
1.459 +{
1.460 + BitArray result(this->m_NumBits);
1.461 + result = *this;
1.462 + result.Not();
1.463 +
1.464 + return result;
1.465 +}
1.466 +
1.467 +/***************************************************************************
1.468 +* Method : operator&
1.469 +* Description: overload of the & operator. Performs a bitwise and
1.470 +* between the source array and this bit array.
1.471 +* Parameters : other - bit array on righthand side of &
1.472 +* Effects : None
1.473 +* Returned : value of bitwise and of this and other.
1.474 +***************************************************************************/
1.475 +BitArray BitArray::operator&(const BitArray &other) const
1.476 +{
1.477 + BitArray result(this->m_NumBits);
1.478 + result = *this;
1.479 + result &= other;
1.480 +
1.481 + return result;
1.482 +}
1.483 +
1.484 +
1.485 +/***************************************************************************
1.486 +* Method : operator^
1.487 +* Description: overload of the ^ operator. Performs a bitwise xor
1.488 +* between the source array and this bit array.
1.489 +* Parameters : other - bit array on righthand side of ^
1.490 +* Effects : None
1.491 +* Returned : value of bitwise xor of this and other.
1.492 +***************************************************************************/
1.493 +BitArray BitArray::operator^(const BitArray &other) const
1.494 +{
1.495 + BitArray result(this->m_NumBits);
1.496 + result = *this;
1.497 + result ^= other;
1.498 +
1.499 + return result;
1.500 +}
1.501 +
1.502 +/***************************************************************************
1.503 +* Method : operator|
1.504 +* Description: overload of the | operator. Performs a bitwise or
1.505 +* between the source array and this bit array.
1.506 +* Parameters : other - bit array on righthand side of |
1.507 +* Effects : None
1.508 +* Returned : value of bitwise or of this and other.
1.509 +***************************************************************************/
1.510 +BitArray BitArray::operator|(const BitArray &other) const
1.511 +{
1.512 + BitArray result(this->m_NumBits);
1.513 + result = *this;
1.514 + result |= other;
1.515 +
1.516 + return result;
1.517 +}
1.518 +
1.519 +/***************************************************************************
1.520 +* Method : operator<<
1.521 +* Description: overload of the << operator. Performs a bitwise left
1.522 +* shift of this bit array.
1.523 +* Parameters : count - the number of bits to shift left
1.524 +* Effects : None
1.525 +* Returned : result of bitwise left shift
1.526 +***************************************************************************/
1.527 +BitArray BitArray::operator<<(const unsigned int count) const
1.528 +{
1.529 + BitArray result(this->m_NumBits);
1.530 + result = *this;
1.531 + result <<= count;
1.532 +
1.533 + return result;
1.534 +}
1.535 +
1.536 +/***************************************************************************
1.537 +* Method : operator>>
1.538 +* Description: overload of the >> operator. Performs a bitwise right
1.539 +* shift of this bit array.
1.540 +* Parameters : count - the number of bits to shift right
1.541 +* Effects : None
1.542 +* Returned : result of bitwise right shift
1.543 +***************************************************************************/
1.544 +BitArray BitArray::operator>>(const unsigned int count) const
1.545 +{
1.546 + BitArray result(this->m_NumBits);
1.547 + result = *this;
1.548 + result >>= count;
1.549 +
1.550 + return result;
1.551 +}
1.552 +
1.553 +/***************************************************************************
1.554 +* Method : operator++ (prefix)
1.555 +* Description: overload of the ++ operator. Increments the contents of
1.556 +* a bit array. Overflows cause rollover.
1.557 +* Parameters : None
1.558 +* Effects : Bit array contents are incremented
1.559 +* Returned : Reference to this array after increment
1.560 +***************************************************************************/
1.561 +BitArray& BitArray::operator++(void)
1.562 +{
1.563 + int i;
1.564 + unsigned char maxValue; /* maximum value for current char */
1.565 + unsigned char one; /* least significant bit in current char */
1.566 +
1.567 + if (m_NumBits == 0)
1.568 + {
1.569 + return *this; /* nothing to increment */
1.570 + }
1.571 +
1.572 + /* handle arrays that don't use every bit in the last character */
1.573 + i = (m_NumBits % CHAR_BIT);
1.574 + if (i != 0)
1.575 + {
1.576 + maxValue = UCHAR_MAX << (CHAR_BIT - i);
1.577 + one = 1 << (CHAR_BIT - i);
1.578 + }
1.579 + else
1.580 + {
1.581 + maxValue = UCHAR_MAX;
1.582 + one = 1;
1.583 + }
1.584 +
1.585 + for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--)
1.586 + {
1.587 + if (m_Array[i] != maxValue)
1.588 + {
1.589 + m_Array[i] = m_Array[i] + one;
1.590 + return *this;
1.591 + }
1.592 + else
1.593 + {
1.594 + /* need to carry to next byte */
1.595 + m_Array[i] = 0;
1.596 +
1.597 + /* remaining characters must use all bits */
1.598 + maxValue = UCHAR_MAX;
1.599 + one = 1;
1.600 + }
1.601 + }
1.602 +
1.603 + return *this;
1.604 +}
1.605 +
1.606 +/***************************************************************************
1.607 +* Method : operator++ (postfix)
1.608 +* Description: overload of the ++ operator. Increments the contents of
1.609 +* a bit array. Overflows cause rollover.
1.610 +* Parameters : dumy - needed for postfix increment
1.611 +* Effects : Bit array contents are incremented
1.612 +* Returned : Reference to this array after increment
1.613 +***************************************************************************/
1.614 +BitArray& BitArray::operator++(int dummy)
1.615 +{
1.616 + ++(*this);
1.617 + return *this;
1.618 +}
1.619 +
1.620 +/***************************************************************************
1.621 +* Method : operator-- (prefix)
1.622 +* Description: overload of the -- operator. Decrements the contents of
1.623 +* a bit array. Underflows cause rollover.
1.624 +* Parameters : None
1.625 +* Effects : Bit array contents are decremented
1.626 +* Returned : None
1.627 +***************************************************************************/
1.628 +BitArray& BitArray::operator--(void)
1.629 +{
1.630 + int i;
1.631 + unsigned char maxValue; /* maximum value for current char */
1.632 + unsigned char one; /* least significant bit in current char */
1.633 +
1.634 + if (m_NumBits == 0)
1.635 + {
1.636 + return *this; /* nothing to decrement */
1.637 + }
1.638 +
1.639 + /* handle arrays that don't use every bit in the last character */
1.640 + i = (m_NumBits % CHAR_BIT);
1.641 + if (i != 0)
1.642 + {
1.643 + maxValue = UCHAR_MAX << (CHAR_BIT - i);
1.644 + one = 1 << (CHAR_BIT - i);
1.645 + }
1.646 + else
1.647 + {
1.648 + maxValue = UCHAR_MAX;
1.649 + one = 1;
1.650 + }
1.651 +
1.652 + for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--)
1.653 + {
1.654 + if (m_Array[i] >= one)
1.655 + {
1.656 + m_Array[i] = m_Array[i] - one;
1.657 + return *this;
1.658 + }
1.659 + else
1.660 + {
1.661 + /* need to borrow from the next byte */
1.662 + m_Array[i] = maxValue;
1.663 +
1.664 + /* remaining characters must use all bits */
1.665 + maxValue = UCHAR_MAX;
1.666 + one = 1;
1.667 + }
1.668 + }
1.669 +
1.670 + return *this;
1.671 +}
1.672 +
1.673 +/***************************************************************************
1.674 +* Method : operator-- (postfix)
1.675 +* Description: overload of the -- operator. Decrements the contents of
1.676 +* a bit array. Underflows cause rollover.
1.677 +* Parameters : dumy - needed for postfix decrement
1.678 +* Effects : Bit array contents are decremented
1.679 +* Returned : None
1.680 +***************************************************************************/
1.681 +BitArray& BitArray::operator--(int dummy)
1.682 +{
1.683 + --(*this);
1.684 + return *this;
1.685 +}
1.686 +
1.687 +/***************************************************************************
1.688 +* Method : operator=
1.689 +* Description: overload of the = operator. Copies source contents into
1.690 +* this bit array.
1.691 +* Parameters : src - Source bit array
1.692 +* Effects : Source bit array contents are copied into this array
1.693 +* Returned : Reference to this array after copy
1.694 +***************************************************************************/
1.695 +BitArray& BitArray::operator=(const BitArray &src)
1.696 +{
1.697 + if (*this == src)
1.698 + {
1.699 + /* don't do anything for a self assignment */
1.700 + return *this;
1.701 + }
1.702 +
1.703 + if (m_NumBits != src.m_NumBits)
1.704 + {
1.705 + /* don't do assignment with different array sizes */
1.706 + return *this;
1.707 + }
1.708 +
1.709 + if ((m_NumBits == 0) || (src.m_NumBits == 0))
1.710 + {
1.711 + /* don't do assignment with unallocated array */
1.712 + return *this;
1.713 + }
1.714 +
1.715 + /* copy bits from source */
1.716 + int size;
1.717 + size = BITS_TO_CHARS(m_NumBits);
1.718 +
1.719 + copy(src.m_Array, &src.m_Array[size], this->m_Array);
1.720 + return *this;
1.721 +}
1.722 +
1.723 +/***************************************************************************
1.724 +* Method : operator&=
1.725 +* Description: overload of the &= operator. Performs a bitwise and
1.726 +* between the source array and this bit array. This bit
1.727 +* array will contain the result.
1.728 +* Parameters : src - Source bit array
1.729 +* Effects : Results of bitwise and are stored in this array
1.730 +* Returned : Reference to this array after and
1.731 +***************************************************************************/
1.732 +BitArray& BitArray::operator&=(const BitArray &src)
1.733 +{
1.734 + int size;
1.735 +
1.736 + size = BITS_TO_CHARS(m_NumBits);
1.737 +
1.738 + if (m_NumBits != src.m_NumBits)
1.739 + {
1.740 + /* don't do assignment with different array sizes */
1.741 + return *this;
1.742 + }
1.743 +
1.744 + /* AND array one unsigned char at a time */
1.745 + for(int i = 0; i < size; i++)
1.746 + {
1.747 + m_Array[i] = m_Array[i] & src.m_Array[i];
1.748 + }
1.749 +
1.750 + return *this;
1.751 +}
1.752 +
1.753 +/***************************************************************************
1.754 +* Method : operator^=
1.755 +* Description: overload of the ^= operator. Performs a bitwise xor
1.756 +* between the source array and this bit array. This bit
1.757 +* array will contain the result.
1.758 +* Parameters : src - Source bit array
1.759 +* Effects : Results of bitwise xor are stored in this array
1.760 +* Returned : Reference to this array after xor
1.761 +***************************************************************************/
1.762 +BitArray& BitArray::operator^=(const BitArray &src)
1.763 +{
1.764 + int size;
1.765 +
1.766 + size = BITS_TO_CHARS(m_NumBits);
1.767 +
1.768 + if (m_NumBits != src.m_NumBits)
1.769 + {
1.770 + /* don't do assignment with different array sizes */
1.771 + return *this;
1.772 + }
1.773 +
1.774 + /* XOR array one unsigned char at a time */
1.775 + for(int i = 0; i < size; i++)
1.776 + {
1.777 + m_Array[i] = m_Array[i] ^ src.m_Array[i];
1.778 + }
1.779 +
1.780 + return *this;
1.781 +}
1.782 +
1.783 +/***************************************************************************
1.784 +* Method : operator|=
1.785 +* Description: overload of the |= operator. Performs a bitwise or
1.786 +* between the source array and this bit array. This bit
1.787 +* array will contain the result.
1.788 +* Parameters : src - Source bit array
1.789 +* Effects : Results of bitwise or are stored in this array
1.790 +* Returned : Reference to this array after or
1.791 +***************************************************************************/
1.792 +BitArray& BitArray::operator|=(const BitArray &src)
1.793 +{
1.794 + int size;
1.795 +
1.796 + size = BITS_TO_CHARS(m_NumBits);
1.797 +
1.798 + if (m_NumBits != src.m_NumBits)
1.799 + {
1.800 + /* don't do assignment with different array sizes */
1.801 + return *this;
1.802 + }
1.803 +
1.804 + /* OR array one unsigned char at a time */
1.805 + for(int i = 0; i < size; i++)
1.806 + {
1.807 + m_Array[i] = m_Array[i] | src.m_Array[i];
1.808 + }
1.809 +
1.810 + return *this;
1.811 +}
1.812 +
1.813 +/***************************************************************************
1.814 +* Method : Not
1.815 +* Description: Negates all non-spare bits in bit array.
1.816 +* Parameters : None
1.817 +* Effects : Contents of bit array are negated. Any spare bits are
1.818 +* left at 0.
1.819 +* Returned : Reference to this array after not
1.820 +***************************************************************************/
1.821 +BitArray& BitArray::Not(void)
1.822 +{
1.823 + int bits;
1.824 + unsigned char mask;
1.825 + int size;
1.826 +
1.827 + size = BITS_TO_CHARS(m_NumBits);
1.828 +
1.829 + if (m_NumBits == 0)
1.830 + {
1.831 + /* don't do not with unallocated array */
1.832 + return *this;
1.833 + }
1.834 +
1.835 + /* NOT array one unsigned char at a time */
1.836 + for(int i = 0; i < size; i++)
1.837 + {
1.838 + m_Array[i] = ~m_Array[i];
1.839 + }
1.840 +
1.841 + /* zero any spare bits so increment and decrement are consistent */
1.842 + bits = m_NumBits % CHAR_BIT;
1.843 + if (bits != 0)
1.844 + {
1.845 + mask = UCHAR_MAX << (CHAR_BIT - bits);
1.846 + m_Array[BIT_CHAR(m_NumBits - 1)] &= mask;
1.847 + }
1.848 +
1.849 + return *this;
1.850 +}
1.851 +
1.852 +/***************************************************************************
1.853 +* Method : operator<<=
1.854 +* Description: overload of the <<= operator. Performs a left shift on
1.855 +* this bit array. This bit array will contain the result.
1.856 +* Parameters : shifts - number of bit positions to shift
1.857 +* Effects : Results of the shifts are stored in this array
1.858 +* Returned : Reference to this array after shift
1.859 +***************************************************************************/
1.860 +BitArray& BitArray::operator<<=(const unsigned int shifts)
1.861 +{
1.862 + int i;
1.863 + int chars = shifts / CHAR_BIT; /* number of whole byte shifts */
1.864 +
1.865 + if (shifts >= m_NumBits)
1.866 + {
1.867 + /* all bits have been shifted off */
1.868 + this->ClearAll();
1.869 + return *this;
1.870 + }
1.871 +
1.872 + /* first handle big jumps of bytes */
1.873 + if (chars > 0)
1.874 + {
1.875 + int size;
1.876 +
1.877 + size = BITS_TO_CHARS(m_NumBits);
1.878 +
1.879 + for (i = 0; (i + chars) < size; i++)
1.880 + {
1.881 + m_Array[i] = m_Array[i + chars];
1.882 + }
1.883 +
1.884 + /* now zero out new bytes on the right */
1.885 + for (i = size; chars > 0; chars--)
1.886 + {
1.887 + m_Array[i - chars] = 0;
1.888 + }
1.889 + }
1.890 +
1.891 + /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */
1.892 + for (i = 0; i < (int)(shifts % CHAR_BIT); i++)
1.893 + {
1.894 + for (unsigned int j = 0; j < BIT_CHAR(m_NumBits - 1); j++)
1.895 + {
1.896 + m_Array[j] <<= 1;
1.897 +
1.898 + /* handle shifts across byte bounds */
1.899 + if (m_Array[j + 1] & MS_BIT)
1.900 + {
1.901 + m_Array[j] |= 0x01;
1.902 + }
1.903 + }
1.904 +
1.905 + m_Array[BIT_CHAR(m_NumBits - 1)] <<= 1;
1.906 + }
1.907 +
1.908 + return *this;
1.909 +}
1.910 +
1.911 +/***************************************************************************
1.912 +* Method : operator>>=
1.913 +* Description: overload of the >>= operator. Performs a right shift on
1.914 +* this bit array. This bit array will contain the result.
1.915 +* Parameters : shifts - number of bit positions to shift
1.916 +* Effects : Results of the shifts are stored in this array
1.917 +* Returned : Reference to this array after shift
1.918 +***************************************************************************/
1.919 +BitArray& BitArray::operator>>=(const unsigned int shifts)
1.920 +{
1.921 + int i;
1.922 + char mask;
1.923 + int chars = shifts / CHAR_BIT; /* number of whole byte shifts */
1.924 +
1.925 + if (shifts >= m_NumBits)
1.926 + {
1.927 + /* all bits have been shifted off */
1.928 + this->ClearAll();
1.929 + return *this;
1.930 + }
1.931 +
1.932 + /* first handle big jumps of bytes */
1.933 + if (chars > 0)
1.934 + {
1.935 + for (i = BIT_CHAR(m_NumBits - 1); (i - chars) >= 0; i--)
1.936 + {
1.937 + m_Array[i] = m_Array[i - chars];
1.938 + }
1.939 +
1.940 + /* now zero out new bytes on the right */
1.941 + for (; chars > 0; chars--)
1.942 + {
1.943 + m_Array[chars - 1] = 0;
1.944 + }
1.945 + }
1.946 +
1.947 + /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */
1.948 + for (i = 0; i < (int)(shifts % CHAR_BIT); i++)
1.949 + {
1.950 + for (unsigned int j = BIT_CHAR(m_NumBits - 1); j > 0; j--)
1.951 + {
1.952 + m_Array[j] >>= 1;
1.953 +
1.954 + /* handle shifts across byte bounds */
1.955 + if (m_Array[j - 1] & 0x01)
1.956 + {
1.957 + m_Array[j] |= MS_BIT;
1.958 + }
1.959 + }
1.960 +
1.961 + m_Array[0] >>= 1;
1.962 + }
1.963 +
1.964 + /***********************************************************************
1.965 + * zero any spare bits that are shifted beyond the end of the bit array
1.966 + * so that increment and decrement are consistent.
1.967 + ***********************************************************************/
1.968 + i = m_NumBits % CHAR_BIT;
1.969 + if (i != 0)
1.970 + {
1.971 + mask = UCHAR_MAX << (CHAR_BIT - i);
1.972 + m_Array[BIT_CHAR(m_NumBits - 1)] &= mask;
1.973 + }
1.974 +
1.975 + return *this;
1.976 +}
1.977 +
1.978 +/***************************************************************************
1.979 +* Method : bit_array_index_c - constructor
1.980 +* Description: This is the bit_array_index_c constructor. It stores a
1.981 +* pointer to the bit array and the bit index.
1.982 +* Parameters : array - pointer to bit array
1.983 +* index - index of bit in array
1.984 +* Effects : Pointer to bit array and bit index are stored.
1.985 +* Returned : None
1.986 +***************************************************************************/
1.987 +BitArrayIndex::BitArrayIndex(BitArray *array,
1.988 + const unsigned int index)
1.989 +{
1.990 + m_BitArray = array;
1.991 + m_Index = index;
1.992 +}
1.993 +
1.994 +/***************************************************************************
1.995 +* Method : operator=
1.996 +* Description: overload of the = operator. Sets the bit array bit to
1.997 +* the value of src.
1.998 +* Parameters : src - bit value
1.999 +* Effects : Bit pointed to by this object is set to the value of
1.1000 +* source.
1.1001 +* Returned : None
1.1002 +***************************************************************************/
1.1003 +void BitArrayIndex::operator=(const bool src)
1.1004 +{
1.1005 + if (m_BitArray == NULL)
1.1006 + {
1.1007 + return; /* no array */
1.1008 + }
1.1009 +
1.1010 + if (m_BitArray->SizeInBits() <= m_Index)
1.1011 + {
1.1012 + return; /* index is out of bounds */
1.1013 + }
1.1014 +
1.1015 + if (src)
1.1016 + {
1.1017 + m_BitArray->SetBit(m_Index);
1.1018 + }
1.1019 + else
1.1020 + {
1.1021 + m_BitArray->ClearBit(m_Index);
1.1022 + }
1.1023 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/BitArray.h Tue Jun 17 09:55:20 2014 +0200
2.3 @@ -0,0 +1,161 @@
2.4 +/***************************************************************************
2.5 +* Arrays of Arbitrary Bit Length
2.6 +*
2.7 +* File : bitarray.h
2.8 +* Purpose : Header file for class supporting the creation and
2.9 +* manipulation of arbitrary length arrays of bits.
2.10 +* Author : Michael Dipperstein
2.11 +* Date : July 23, 2004
2.12 +*
2.13 +****************************************************************************
2.14 +* HISTORY
2.15 +*
2.16 +* $Id: bitarray.h,v 1.5 2010/02/04 03:31:43 michael Exp $
2.17 +* $Log: bitarray.h,v $
2.18 +* Revision 1.5 2010/02/04 03:31:43 michael
2.19 +* Replaced vector<unsigned char> with an array of unsigned char.
2.20 +*
2.21 +* Made updates for GCC 4.4.
2.22 +*
2.23 +* Revision 1.4 2007/08/06 05:23:12 michael
2.24 +* Updated for LGPL Version 3.
2.25 +*
2.26 +* All methods that don't modify object have been made
2.27 +* const to increase functionality of const bit_array_c.
2.28 +*
2.29 +* All assignment operators return a reference to the object being assigned a value so that operator chaining will work.
2.30 +*
2.31 +* Added >> and << operators.
2.32 +*
2.33 +* Revision 1.3 2006/04/30 23:34:07 michael
2.34 +* Improved performance by incorporating Benjamin Schindler's
2.35 +* <bschindler@student.ethz.ch> changes to pass arguments as a reference.
2.36 +*
2.37 +* Revision 1.2 2004/08/05 22:17:04 michael
2.38 +* Add overloads for bitwise operators returning values.
2.39 +* Add a more natural looking way to set bit values.
2.40 +*
2.41 +* Revision 1.1.1.1 2004/08/04 13:28:20 michael
2.42 +* bit_array_c
2.43 +*
2.44 +****************************************************************************
2.45 +*
2.46 +* Bitarray: An ANSI C++ class for manipulating arbitrary length bit arrays
2.47 +* Copyright (C) 2004, 2006-2007, 2010 by
2.48 +* Michael Dipperstein (mdipper@alumni.engr.ucsb.edu)
2.49 +*
2.50 +* This file is part of the bit array library.
2.51 +*
2.52 +* The bit array library is free software; you can redistribute it and/or
2.53 +* modify it under the terms of the GNU Lesser General Public License as
2.54 +* published by the Free Software Foundation; either version 3 of the
2.55 +* License, or (at your option) any later version.
2.56 +*
2.57 +* The bit array library is distributed in the hope that it will be useful,
2.58 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
2.59 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
2.60 +* General Public License for more details.
2.61 +*
2.62 +* You should have received a copy of the GNU Lesser General Public License
2.63 +* along with this program. If not, see <http://www.gnu.org/licenses/>.
2.64 +*
2.65 +***************************************************************************/
2.66 +#ifndef BIT_ARRAY_H
2.67 +#define BIT_ARRAY_H
2.68 +
2.69 +/***************************************************************************
2.70 +* INCLUDED FILES
2.71 +***************************************************************************/
2.72 +#include <ostream>
2.73 +
2.74 +/***************************************************************************
2.75 +* TYPE DEFINITIONS
2.76 +***************************************************************************/
2.77 +class BitArray;
2.78 +
2.79 +/**
2.80 +*/
2.81 +class BitArrayIndex
2.82 +{
2.83 + public:
2.84 + BitArrayIndex(BitArray *array, const unsigned int index);
2.85 +
2.86 + /* assignment */
2.87 + void operator=(const bool src);
2.88 +
2.89 + private:
2.90 + BitArray *m_BitArray; /* array index applies to */
2.91 + unsigned int m_Index; /* index of bit in array */
2.92 +};
2.93 +
2.94 +/**
2.95 +TODO: Derive a Bit Frame class from this one for X Y access to pixels.
2.96 +*/
2.97 +class BitArray
2.98 +{
2.99 + public:
2.100 + BitArray(const int numBits);
2.101 + BitArray(unsigned char *array, const int numBits, bool aOwnsBuffer);
2.102 +
2.103 + virtual ~BitArray(void);
2.104 +
2.105 + void Dump(std::ostream &outStream);
2.106 +
2.107 + const unsigned int SizeInBits() { return m_NumBits; }
2.108 + const unsigned int SizeInBytes() { return m_SizeInBytes; }
2.109 +
2.110 + /* set/clear functions */
2.111 + void SetAll(void);
2.112 + void ClearAll(void);
2.113 + void SetBit(const unsigned int bit);
2.114 + void SetBitValue(const unsigned int bit, bool aValue);
2.115 + void ClearBit(const unsigned int bit);
2.116 +
2.117 + BitArrayIndex operator()(const unsigned int bit);
2.118 +
2.119 + /* boolean operator */
2.120 + bool operator[](const unsigned int bit) const;
2.121 + bool operator==(const BitArray &other) const;
2.122 + bool operator!=(const BitArray &other) const;
2.123 + bool operator<(const BitArray &other) const;
2.124 + bool operator<=(const BitArray &other) const;
2.125 + bool operator>(const BitArray &other) const;
2.126 + bool operator>=(const BitArray &other) const;
2.127 +
2.128 + /* bitwise operators */
2.129 + BitArray operator&(const BitArray &other) const;
2.130 + BitArray operator^(const BitArray &other) const;
2.131 + BitArray operator|(const BitArray &other) const;
2.132 + BitArray operator~(void) const;
2.133 +
2.134 + BitArray operator<<(const unsigned int count) const;
2.135 + BitArray operator>>(const unsigned int count) const;
2.136 +
2.137 + /* increment/decrement */
2.138 + BitArray& operator++(void); /* prefix */
2.139 + BitArray& operator++(int dummy); /* postfix */
2.140 + BitArray& operator--(void); /* prefix */
2.141 + BitArray& operator--(int dummy); /* postfix */
2.142 +
2.143 + /* assignments */
2.144 + BitArray& operator=(const BitArray &src);
2.145 +
2.146 + BitArray& operator&=(const BitArray &src);
2.147 + BitArray& operator^=(const BitArray &src);
2.148 + BitArray& operator|=(const BitArray &src);
2.149 + BitArray& Not(void); /* negate (~=) */
2.150 +
2.151 + BitArray& operator<<=(unsigned const int shifts);
2.152 + BitArray& operator>>=(unsigned const int shifts);
2.153 +
2.154 + unsigned char* Ptr(){return m_Array;}
2.155 + const unsigned char* Ptr() const{return m_Array;}
2.156 +
2.157 + protected:
2.158 + unsigned int m_NumBits; /* number of bits in the array */
2.159 + unsigned int m_SizeInBytes;
2.160 + unsigned char *m_Array; /* vector of characters */
2.161 + bool m_OwnsBuffer;
2.162 +};
2.163 +
2.164 +#endif /* ndef BIT_ARRAY_H */
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/FutabaVfd.cpp Tue Jun 17 09:55:20 2014 +0200
3.3 @@ -0,0 +1,699 @@
3.4 +
3.5 +#include "FutabaVfd.h"
3.6 +//#include <stdlib.h>
3.7 +#include <string.h>
3.8 +
3.9 +
3.10 +#ifdef DEBUG_FRAME_DIFF
3.11 +#include <QImage>
3.12 +#include <QTextStream>
3.13 +#endif
3.14 +
3.15 +
3.16 +const int KNumberOfFrameBeforeDiffAlgo = 3;
3.17 +
3.18 +//
3.19 +//
3.20 +//
3.21 +
3.22 +FutabaVfdCommand::FutabaVfdCommand():/*iBuffer(NULL),*/iSize(0),iMaxSize(0)
3.23 + {
3.24 + }
3.25 +
3.26 +FutabaVfdCommand::~FutabaVfdCommand()
3.27 + {
3.28 + //Delete();
3.29 + }
3.30 +
3.31 +
3.32 +/**
3.33 +
3.34 +*/
3.35 +void FutabaVfdCommand::Reset()
3.36 + {
3.37 + memset(iReports,0,sizeof(iReports));
3.38 + }
3.39 +
3.40 +
3.41 +
3.42 +/**
3.43 +
3.44 +*/
3.45 +/*
3.46 +void FutabaVfdCommand::Create(int aMaxSize)
3.47 + {
3.48 + iBuffer=new unsigned char[aMaxSize];
3.49 + if (iBuffer)
3.50 + {
3.51 + iMaxSize = aMaxSize;
3.52 + iSize = 0;
3.53 + }
3.54 + }
3.55 +*/
3.56 +
3.57 +/**
3.58 +
3.59 +*/
3.60 +/*
3.61 +void FutabaVfdCommand::Delete()
3.62 +{
3.63 + delete[] iBuffer;
3.64 + iBuffer = NULL;
3.65 + iMaxSize = 0;
3.66 + iSize = 0;
3.67 +}
3.68 +*/
3.69 +
3.70 +
3.71 +
3.72 +
3.73 +//
3.74 +// class GP1212A01A
3.75 +//
3.76 +
3.77 +GP1212A01A::GP1212A01A():
3.78 + iDisplayPositionX(0),iDisplayPositionY(0),
3.79 + iOffScreenMode(true),
3.80 + iUseFrameDifferencing(true),
3.81 + iFrameNext(NULL),
3.82 + iFrameCurrent(NULL),
3.83 + iFramePrevious(NULL),
3.84 + iFrameAlpha(NULL),
3.85 + iFrameBeta(NULL),
3.86 + iFrameGamma(NULL),
3.87 + iNeedFullFrameUpdate(0),
3.88 + iRequest(ERequestNone),iPowerOn(false)
3.89 + {
3.90 + //ResetBuffers();
3.91 + }
3.92 +
3.93 +/**
3.94 +*/
3.95 +GP1212A01A::~GP1212A01A()
3.96 + {
3.97 + delete iFrameAlpha;
3.98 + iFrameAlpha=NULL;
3.99 + //
3.100 + delete iFrameBeta;
3.101 + iFrameBeta=NULL;
3.102 + //
3.103 + delete iFrameGamma;
3.104 + iFrameGamma=NULL;
3.105 + //
3.106 + iFrameNext=NULL;
3.107 + iFrameCurrent=NULL;
3.108 + iFramePrevious=NULL;
3.109 + //
3.110 + iNeedFullFrameUpdate=0;
3.111 + }
3.112 +
3.113 +/**
3.114 +*/
3.115 +int GP1212A01A::Open()
3.116 + {
3.117 + int success = HidDevice::Open(KFutabaVendorId,KFutabaProductIdGP1212A01A,NULL);
3.118 + if (success)
3.119 + {
3.120 + //Allocate both frames
3.121 + delete iFrameAlpha;
3.122 + iFrameAlpha=NULL;
3.123 + iFrameAlpha=new BitArray(KGP12xFrameBufferPixelCount);
3.124 + //
3.125 + delete iFrameBeta;
3.126 + iFrameBeta=NULL;
3.127 + iFrameBeta=new BitArray(KGP12xFrameBufferPixelCount);
3.128 + //
3.129 + delete iFrameGamma;
3.130 + iFrameGamma=NULL;
3.131 + iFrameGamma=new BitArray(KGP12xFrameBufferPixelCount);
3.132 + //
3.133 + iFrameNext=iFrameAlpha;
3.134 + iFrameCurrent=iFrameBeta;
3.135 + iFramePrevious=iFrameGamma;
3.136 +
3.137 +
3.138 + //To make sure it is synced properly
3.139 + iNeedFullFrameUpdate=0;
3.140 + //
3.141 + SetNonBlocking(1);
3.142 + //Since we can't get our display position we force it to our default
3.143 + //This makes sure frames are in sync from the start
3.144 + //Clever clients will have taken care of putting back frame (0,0) before closing
3.145 + SetDisplayPosition(iDisplayPositionX,iDisplayPositionY);
3.146 + }
3.147 + return success;
3.148 + }
3.149 +
3.150 +/**
3.151 +*/
3.152 +void GP1212A01A::SetPixel(unsigned char aX, unsigned char aY, bool aOn)
3.153 + {
3.154 + //
3.155 + //int byteOffset=(aX*HeightInPixels()+aY)/8;
3.156 + //int bitOffset=(aX*HeightInPixels()+aY)%8;
3.157 + //iNextFrame[byteOffset] |= ( (aOn?0x01:0x00) << bitOffset );
3.158 +
3.159 + if (iOffScreenMode)
3.160 + {
3.161 + if (aOn)
3.162 + {
3.163 + iFrameNext->SetBit(aX*HeightInPixels()+aY);
3.164 + }
3.165 + else
3.166 + {
3.167 + iFrameNext->ClearBit(aX*HeightInPixels()+aY);
3.168 + }
3.169 + }
3.170 + else
3.171 + {
3.172 + //Just specify a one pixel block
3.173 + SetPixelBlock(aX,aY,0x00,0x01,aOn);
3.174 + }
3.175 + }
3.176 +
3.177 +/**
3.178 +*/
3.179 +void GP1212A01A::BitBlit(const BitArray& aBitmap, int aSrcWidth, int aSrcHeight, int aTargetX, int aTargetY) const
3.180 + {
3.181 + //TODO: amend loop values so that we don't keep on looping past our frame buffer dimensions.
3.182 + for (int i=0;i<aSrcWidth;i++)
3.183 + {
3.184 + for (int j=0;j<aSrcHeight;j++)
3.185 + {
3.186 + iFrameNext->SetBitValue((aTargetX+i)*HeightInPixels()+aTargetY+j,aBitmap[+i*aSrcHeight+j]);
3.187 + }
3.188 + }
3.189 + }
3.190 +
3.191 +/**
3.192 +Clear our client side back buffer.
3.193 +Call to SwapBuffers must follow to actually clear the display.
3.194 +*/
3.195 +void GP1212A01A::Clear()
3.196 + {
3.197 + //memset(iNextFrame->Ptr(),0x00,FrameBufferSizeInBytes());
3.198 + if (iOffScreenMode)
3.199 + {
3.200 + iFrameNext->ClearAll();
3.201 + }
3.202 + else
3.203 + {
3.204 + SendClearCommand();
3.205 + }
3.206 + }
3.207 +
3.208 +/**
3.209 +Set all pixels on our screen to the desired value.
3.210 +This operation is performed off screen to avoid tearing.
3.211 +@param 8 pixels pattern
3.212 +*/
3.213 +void GP1212A01A::SetAllPixels(unsigned char aPattern)
3.214 + {
3.215 + //With a single buffer
3.216 + //unsigned char screen[2048]; //One screen worth of pixels
3.217 + //memset(screen,0xFF,sizeof(screen));
3.218 + //SetPixelBlock(0,0,63,sizeof(screen),screen);
3.219 +
3.220 +
3.221 + if (iOffScreenMode)
3.222 + {
3.223 + memset(iFrameNext->Ptr(),aPattern,FrameBufferSizeInBytes());
3.224 + }
3.225 + else
3.226 + {
3.227 + //Using pattern SetPixelBlock variant.
3.228 + SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),aPattern);
3.229 + }
3.230 + //
3.231 + }
3.232 +
3.233 +
3.234 +/**
3.235 +Set the defined pixel block to the given value.
3.236 +@param X coordinate of our pixel block starting point.
3.237 +@param Y coordinate of our pixel block starting point.
3.238 +@param The height of our pixel block.
3.239 +@param The size of our pixel data. Number of pixels divided by 8.
3.240 +@param The value set to 8 pixels used as a pattern.
3.241 +*/
3.242 +void GP1212A01A::SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char aValue)
3.243 + {
3.244 + OffScreenTranslation(aX,aY);
3.245 + FutabaVfdReport report;
3.246 + report[0]=0x00; //Report ID
3.247 + report[1]=(aSize<=report.Size()-10?aSize+0x08:64); //Report length. -10 is for our header first 10 bytes. +8 is for our Futaba header size
3.248 + report[2]=0x1B; //Command ID
3.249 + report[3]=0x5B; //Command ID
3.250 + report[4]=0xF0; //Command ID
3.251 + report[5]=aX; //X
3.252 + report[6]=aY; //Y
3.253 + report[7]=aHeight; //Y length before return. Though outside the specs, setting this to zero apparently allows us to modify a single pixel without touching any other.
3.254 + report[8]=aSize>>8; //Size of pixel data in bytes (MSB)
3.255 + report[9]=aSize; //Size of pixel data in bytes (LSB)
3.256 + int sizeWritten=MIN(aSize,report.Size()-10);
3.257 + memset(report.Buffer()+10, aValue, sizeWritten);
3.258 + Write(report);
3.259 +
3.260 + int remainingSize=aSize;
3.261 + //We need to keep on sending our pixel data until we are done
3.262 + while (report[1]==64)
3.263 + {
3.264 + report.Reset();
3.265 + remainingSize-=sizeWritten;
3.266 + report[0]=0x00; //Report ID
3.267 + report[1]=(remainingSize<=report.Size()-2?remainingSize:64); //Report length, should be 64 or the remaining size
3.268 + sizeWritten=(report[1]==64?63:report[1]);
3.269 + memset(report.Buffer()+2, aValue, sizeWritten);
3.270 + Write(report);
3.271 + }
3.272 + }
3.273 +
3.274 +/**
3.275 +Set the defined pixel block to the given value.
3.276 +@param X coordinate of our pixel block starting point.
3.277 +@param Y coordinate of our pixel block starting point.
3.278 +@param The height of our pixel block.
3.279 +@param The size of our pixel data. Number of pixels divided by 8.
3.280 +@param Pointer to our pixel data.
3.281 +*/
3.282 +void GP1212A01A::SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char* aPixels)
3.283 + {
3.284 + OffScreenTranslation(aX,aY);
3.285 + FutabaVfdReport report;
3.286 + report[0]=0x00; //Report ID
3.287 + report[1]=(aSize<=report.Size()-10?aSize+0x08:64); //Report length. -10 is for our header first 10 bytes. +8 is for our Futaba header size
3.288 + report[2]=0x1B; //Command ID
3.289 + report[3]=0x5B; //Command ID
3.290 + report[4]=0xF0; //Command ID
3.291 + report[5]=aX; //X
3.292 + report[6]=aY; //Y
3.293 + report[7]=aHeight; //Y length before return. Though outside the specs, setting this to zero apparently allows us to modify a single pixel without touching any other.
3.294 + report[8]=aSize>>8; //Size of pixel data in bytes (MSB)
3.295 + report[9]=aSize; //Size of pixel data in bytes (LSB)
3.296 + int sizeWritten=MIN(aSize,report.Size()-10);
3.297 + memcpy(report.Buffer()+10, aPixels, sizeWritten);
3.298 + Write(report);
3.299 +
3.300 + int remainingSize=aSize;
3.301 + //We need to keep on sending our pixel data until we are done
3.302 + while (report[1]==64)
3.303 + {
3.304 + report.Reset();
3.305 + remainingSize-=sizeWritten;
3.306 + report[0]=0x00; //Report ID
3.307 + report[1]=(remainingSize<=report.Size()-2?remainingSize:64); //Report length, should be 64 or the remaining size
3.308 + sizeWritten=(report[1]==64?63:report[1]);
3.309 + memcpy(report.Buffer()+2, aPixels+(aSize-remainingSize), sizeWritten);
3.310 + Write(report);
3.311 + }
3.312 + }
3.313 +
3.314 +/**
3.315 +Using this function is advised against as is causes tearing.
3.316 +Use Clear instead.
3.317 +*/
3.318 +void GP1212A01A::SendClearCommand()
3.319 + {
3.320 + //1BH,5BH,32H,4AH
3.321 + //Send Clear Display Command
3.322 + FutabaVfdReport report;
3.323 + report[0]=0x00; //Report ID
3.324 + report[1]=0x04; //Report length
3.325 + report[2]=0x1B; //Command ID
3.326 + report[3]=0x5B; //Command ID
3.327 + report[4]=0x32; //Command ID
3.328 + report[5]=0x4A; //Command ID
3.329 + Write(report);
3.330 + }
3.331 +
3.332 +/**
3.333 +Change our display position within our buffer.
3.334 +*/
3.335 +void GP1212A01A::SetDisplayPosition(DW aDw,unsigned char aX, unsigned char aY)
3.336 + {
3.337 + //1BH,5BH,Dw,Px,Py
3.338 + //Send Display Position Settings Command
3.339 + FutabaVfdReport report;
3.340 + report[0]=0x00; //Report ID
3.341 + report[1]=0x05; //Report length
3.342 + report[2]=0x1B; //Command ID
3.343 + report[3]=0x5B; //Command ID
3.344 + report[4]=aDw; //Specify our DW
3.345 + report[5]=aX; //X coordinate of our DW top-left corner
3.346 + report[6]=aY; //Y coordinate of our DW top-left corner
3.347 + Write(report);
3.348 + }
3.349 +
3.350 +/**
3.351 +Change our display position within our buffer.
3.352 +*/
3.353 +void GP1212A01A::SetDisplayPosition(unsigned char aX, unsigned char aY)
3.354 + {
3.355 + //Specs apparently says both DW should remain the same
3.356 + //Just don't ask
3.357 + SetDisplayPosition(GP1212A01A::DW1,aX,aY);
3.358 + SetDisplayPosition(GP1212A01A::DW2,aX,aY);
3.359 + iDisplayPositionX=aX;
3.360 + iDisplayPositionY=aY;
3.361 + }
3.362 +
3.363 +/**
3.364 +Provide Y coordinate of our off screen buffer.
3.365 +*/
3.366 +unsigned char GP1212A01A::OffScreenY() const
3.367 + {
3.368 + //Overflowing is fine this is just what we want
3.369 + return iDisplayPositionY+HeightInPixels();
3.370 + }
3.371 +
3.372 +/**
3.373 +Put our off screen buffer on screen.
3.374 +On screen buffer goes off screen.
3.375 +*/
3.376 +void GP1212A01A::SwapBuffers()
3.377 + {
3.378 + //Only perform buffer swapping if off screen mode is enabled
3.379 + if (OffScreenMode())
3.380 + {
3.381 + //Send host back buffer to device back buffer
3.382 + if (!iUseFrameDifferencing || iNeedFullFrameUpdate<KNumberOfFrameBeforeDiffAlgo)
3.383 + {
3.384 + iNeedFullFrameUpdate++;
3.385 + SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),iFrameNext->Ptr());
3.386 + }
3.387 + else
3.388 + {
3.389 + //Frame diff algo is enabled
3.390 + //We are going to send to our device only the differences between next frame and previous frame
3.391 + SendModifiedPixelBlocks();
3.392 + }
3.393 + //Swap device front and back buffer
3.394 + SetDisplayPosition(iDisplayPositionX,OffScreenY());
3.395 +
3.396 + //Cycle through our frame buffers
3.397 + //We keep track of previous frame which is in fact our device back buffer.
3.398 + //We can then compare previous and next frame and send only the differences to our device.
3.399 + //This mechanism allows us to reduce traffic over our USB bus thus improving our frame rate from 14 FPS to 30 FPS.
3.400 + //Keep our previous frame pointer
3.401 + BitArray* previousFrame=iFramePrevious;
3.402 + //Current frame becomes the previous one
3.403 + iFramePrevious = iFrameCurrent;
3.404 + //Next frame becomes the current one
3.405 + iFrameCurrent = iFrameNext;
3.406 + //Next frame is now our former previous
3.407 + iFrameNext = previousFrame;
3.408 + }
3.409 + }
3.410 +
3.411 +
3.412 +//Define the edge of our pixel block
3.413 +//Pixel blocks of 32x32 seems to run almost as fast as full screen update in worse case scenarii.
3.414 +//Though I wonder if in some situations 16 could be better. Make this an attribute at some point if need be.
3.415 +const int KPixelBlockEdge = 32;
3.416 +const int KPixelBlockSizeInBits = KPixelBlockEdge*KPixelBlockEdge;
3.417 +const int KPixelBlockSizeInBytes = KPixelBlockSizeInBits/8;
3.418 +
3.419 +
3.420 +/**
3.421 + * @brief GP1212A01A::SendModifiedPixelBlocks
3.422 + * Compare our back and front buffer and send to the device only the modified pixels.
3.423 + */
3.424 +void GP1212A01A::SendModifiedPixelBlocks()
3.425 + {
3.426 + int w=WidthInPixels();
3.427 + int h=HeightInPixels();
3.428 +
3.429 +
3.430 + //TODO: optimize with memcmp and 16 inc
3.431 + /*
3.432 +
3.433 + for (int i=0;i<w;i++)
3.434 + {
3.435 + for (int j=0;j<h;j++)
3.436 + {
3.437 + //aX*HeightInPixels()+aY
3.438 + if ((*iFrameNext)[i*h+j]!=(*iFramePrevious)[i*h+j])
3.439 + {
3.440 + //We need to update that pixel
3.441 + SetPixelBlock(i,j,0,1,((*iFrameNext)[i*h+j]?0x01:0x00));
3.442 + //SetDisplayPosition(iDisplayPositionX,OffScreenY());
3.443 + //SetDisplayPosition(iDisplayPositionX,OffScreenY());
3.444 +
3.445 + //SetPixelBlock(i,j,15,32,iNextFrame->Ptr()+offset);
3.446 + }
3.447 + }
3.448 + }
3.449 + */
3.450 +
3.451 + BitArray nextBlock(KPixelBlockSizeInBits);
3.452 + BitArray previousBlock(KPixelBlockSizeInBits);
3.453 +
3.454 + for (int i=0;i<w;i+=KPixelBlockEdge)
3.455 + {
3.456 + for (int j=0;j<h;j+=KPixelBlockEdge)
3.457 + {
3.458 + //aX*HeightInPixels()+aY
3.459 + //int offset=(i*w/8)+(j/8);
3.460 +
3.461 +#ifdef DEBUG_FRAME_DIFF
3.462 + QImage imagePrevious(KPixelBlockEdge,KPixelBlockEdge,QImage::Format_RGB32);
3.463 + QImage imageNext(KPixelBlockEdge,KPixelBlockEdge,QImage::Format_RGB32);
3.464 +#endif
3.465 +
3.466 + //Get both our blocks from our buffers
3.467 + for (int x=i;x<i+KPixelBlockEdge;x++)
3.468 + {
3.469 + for (int y=j;y<j+KPixelBlockEdge;y++)
3.470 + {
3.471 + int blockOffset=(x-i)*KPixelBlockEdge+(y-j);
3.472 + int frameOffset=x*h+y;
3.473 + nextBlock.SetBitValue(blockOffset,(*iFrameNext)[frameOffset]);
3.474 + previousBlock.SetBitValue(blockOffset,(*iFramePrevious)[frameOffset]);
3.475 +
3.476 +#ifdef DEBUG_FRAME_DIFF
3.477 + imageNext.setPixel(x-i,y-j,(nextBlock[blockOffset]?0xFFFFFFFF:0x00000000));
3.478 + imagePrevious.setPixel(x-i,y-j,(previousBlock[blockOffset]?0xFFFFFFFF:0x00000000));
3.479 +#endif
3.480 + }
3.481 + }
3.482 +
3.483 +#ifdef DEBUG_FRAME_DIFF
3.484 + QString previousName;
3.485 + QString nextName;
3.486 + QTextStream(&previousName) << "p" << i << "x" << j << ".png";
3.487 + QTextStream(&nextName) << "n" << i << "x" << j << ".png";
3.488 + imagePrevious.save(previousName);
3.489 + imageNext.save(nextName);
3.490 +#endif
3.491 +
3.492 +
3.493 + //if (memcmp(iFrameNext->Ptr()+offset,iFramePrevious->Ptr()+offset,32 )) //32=(16*16/8)
3.494 + if (memcmp(nextBlock.Ptr(),previousBlock.Ptr(),KPixelBlockSizeInBytes)!=0)
3.495 + {
3.496 + //We need to update that block
3.497 + SetPixelBlock(i,j,KPixelBlockEdge-1,KPixelBlockSizeInBytes,nextBlock.Ptr());
3.498 + //SetPixelBlock(i,j,15,32,0xFF/*nextBlock.Ptr()*/);
3.499 + //SetDisplayPosition(iDisplayPositionX,OffScreenY());
3.500 + //SetDisplayPosition(iDisplayPositionX,OffScreenY());
3.501 +
3.502 + //SetPixelBlock(i,j,15,32,iFrameNext->Ptr()+offset);
3.503 + }
3.504 + }
3.505 + }
3.506 +
3.507 + }
3.508 +
3.509 +/**
3.510 +Translate the given pixel coordinate according to our off screen mode.
3.511 +*/
3.512 +void GP1212A01A::OffScreenTranslation(unsigned char& aX, unsigned char& aY)
3.513 + {
3.514 + if (OffScreenMode())
3.515 + {
3.516 + aX+=WidthInPixels()-iDisplayPositionX;
3.517 + aY+=HeightInPixels()-iDisplayPositionY;
3.518 + }
3.519 + }
3.520 +
3.521 +
3.522 +/**
3.523 +*/
3.524 +void GP1212A01A::ResetBuffers()
3.525 + {
3.526 + //iNextFrame->ClearAll();
3.527 + //memset(iFrameAlpha,0x00,sizeof(iFrameAlpha));
3.528 + //memset(iFrameBeta,0x00,sizeof(iFrameBeta));
3.529 + }
3.530 +
3.531 +/**
3.532 +*/
3.533 +void GP1212A01A::RequestDeviceId()
3.534 + {
3.535 + if (RequestPending())
3.536 + {
3.537 + //Abort silently for now
3.538 + return;
3.539 + }
3.540 +
3.541 + //1BH,5BH,63H,49H,44H
3.542 + //Send Read ID command
3.543 + FutabaVfdReport report;
3.544 + report[0]=0x00; //Report ID
3.545 + report[1]=0x05; //Report length
3.546 + report[2]=0x1B; //Command ID
3.547 + report[3]=0x5B; //Command ID
3.548 + report[4]=0x63; //Command ID
3.549 + report[5]=0x49; //Command ID
3.550 + report[6]=0x44; //Command ID
3.551 + if (Write(report)==report.Size())
3.552 + {
3.553 + iRequest=ERequestDeviceId;
3.554 + }
3.555 + }
3.556 +
3.557 +/**
3.558 +*/
3.559 +void GP1212A01A::RequestFirmwareRevision()
3.560 + {
3.561 + if (RequestPending())
3.562 + {
3.563 + //Abort silently for now
3.564 + return;
3.565 + }
3.566 +
3.567 + //1BH,5BH,63H,46H,52H
3.568 + //Send Software Revision Read Command
3.569 + FutabaVfdReport report;
3.570 + report[0]=0x00; //Report ID
3.571 + report[1]=0x05; //Report length
3.572 + report[2]=0x1B; //Command ID
3.573 + report[3]=0x5B; //Command ID
3.574 + report[4]=0x63; //Command ID
3.575 + report[5]=0x46; //Command ID
3.576 + report[6]=0x52; //Command ID
3.577 + if (Write(report)==report.Size())
3.578 + {
3.579 + iRequest=ERequestFirmwareRevision;
3.580 + }
3.581 + }
3.582 +
3.583 +/**
3.584 +*/
3.585 +void GP1212A01A::RequestPowerSupplyStatus()
3.586 + {
3.587 + if (RequestPending())
3.588 + {
3.589 + //Abort silently for now
3.590 + return;
3.591 + }
3.592 + //1BH,5BH,63H,50H,4DH
3.593 + //Send Power Suppply Monitor Command
3.594 + FutabaVfdReport report;
3.595 + report[0]=0x00; //Report ID
3.596 + report[1]=0x05; //Report length
3.597 + report[2]=0x1B; //Command ID
3.598 + report[3]=0x5B; //Command ID
3.599 + report[4]=0x63; //Command ID
3.600 + report[5]=0x50; //Command ID
3.601 + report[6]=0x4D; //Command ID
3.602 + if (Write(report)==report.Size())
3.603 + {
3.604 + iRequest=ERequestPowerSupplyStatus;
3.605 + }
3.606 + }
3.607 +
3.608 +
3.609 +/**
3.610 +This is for development purposes only.
3.611 +Production application should stick to off-screen mode to avoid tearing.
3.612 +*/
3.613 +void GP1212A01A::ToggleOffScreenMode()
3.614 + {
3.615 + SetOffScreenMode(!iOffScreenMode);
3.616 + }
3.617 +
3.618 +/**
3.619 + * @brief GP1212A01A::SetOffScreenMode
3.620 + * @param aOn
3.621 + * @return
3.622 + */
3.623 +void GP1212A01A::SetOffScreenMode(bool aOn)
3.624 + {
3.625 + if (aOn==iOffScreenMode)
3.626 + {
3.627 + //Nothing to do here
3.628 + return;
3.629 + }
3.630 +
3.631 + iOffScreenMode=aOn;
3.632 +
3.633 + //Clean up our buffers upon switching modes
3.634 + SetDisplayPosition(0,0);
3.635 + Clear();
3.636 + SwapBuffers();
3.637 + Clear();
3.638 + }
3.639 +
3.640 +/**
3.641 + */
3.642 +GP1212A01A::Request GP1212A01A::AttemptRequestCompletion()
3.643 + {
3.644 + if (!RequestPending())
3.645 + {
3.646 + return ERequestNone;
3.647 + }
3.648 +
3.649 + int res=Read(iInputReport);
3.650 +
3.651 + if (!res)
3.652 + {
3.653 + return ERequestNone;
3.654 + }
3.655 +
3.656 + //Process our request
3.657 + if (CurrentRequest()==GP1212A01A::ERequestPowerSupplyStatus)
3.658 + {
3.659 + if (iInputReport[1]==0x4F && iInputReport[2]==0x4E)
3.660 + {
3.661 + iPowerOn = true;
3.662 + }
3.663 + else if (iInputReport[1]==0x4F && iInputReport[2]==0x46 && iInputReport[3]==0x46)
3.664 + {
3.665 + iPowerOn = false;
3.666 + }
3.667 + }
3.668 +
3.669 + Request completed=iRequest;
3.670 + //Our request was completed
3.671 + iRequest=ERequestNone;
3.672 +
3.673 + return completed;
3.674 + }
3.675 +
3.676 +
3.677 +/**
3.678 +Set our screen brightness.
3.679 +@param The desired brightness level. Must be between MinBrightness and MaxBrightness.
3.680 +*/
3.681 +void GP1212A01A::SetBrightness(int aBrightness)
3.682 + {
3.683 + if (aBrightness<MinBrightness()||aBrightness>MaxBrightness())
3.684 + {
3.685 + //Brightness out of range.
3.686 + //Just ignore that request.
3.687 + return;
3.688 + }
3.689 +
3.690 + FutabaVfdReport report;
3.691 + report[0]=0x00; //Report ID
3.692 + report[1]=0x06; //Report size
3.693 + report[2]=0x1B; //Command ID
3.694 + report[3]=0x5C; //Command ID
3.695 + report[4]=0x3F; //Command ID
3.696 + report[5]=0x4C; //Command ID
3.697 + report[6]=0x44; //Command ID
3.698 + report[7]=0x30+aBrightness; //Brightness level
3.699 + Write(report);
3.700 + }
3.701 +
3.702 +
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/FutabaVfd.h Tue Jun 17 09:55:20 2014 +0200
4.3 @@ -0,0 +1,217 @@
4.4 +//
4.5 +//
4.6 +//
4.7 +
4.8 +#ifndef FUTABA_VFD_H
4.9 +#define FUTABA_VFD_H
4.10 +
4.11 +#include "hidapi.h"
4.12 +#include "HidDevice.h"
4.13 +#include "BitArray.h"
4.14 +
4.15 +#ifndef MIN
4.16 +#define MIN(a,b) (((a)<(b))?(a):(b))
4.17 +#endif
4.18 +
4.19 +#ifndef MAX
4.20 +#define MAX(a,b) (((a)>(b))?(a):(b))
4.21 +#endif
4.22 +
4.23 +
4.24 +//This was computed from our number of pixels as follow 256x64/8/64 = 32 + 1 = 33
4.25 +//+1 was added for our header
4.26 +const int KFutabaMaxCommandOutputReport = 33;
4.27 +//TODO: Get ride of that constant once we figure out a way to get it from hidapi
4.28 +const int KFutabaMaxHidReportSize = 65;
4.29 +
4.30 +const int KHidReportIdIndex=0;
4.31 +const int KFutabaHidReportSizeIndex=1;
4.32 +//Define Futaba vendor ID to filter our list of device
4.33 +const unsigned short KFutabaVendorId = 0x1008;
4.34 +const unsigned short KFutabaProductIdGP1212A01A = 0x100C;
4.35 +const unsigned short KFutabaProductIdGP1212A02A = 0x1013; //Or is it 0x1015
4.36 +const int KGP12xWidthInPixels = 256;
4.37 +const int KGP12xHeightInPixels = 64;
4.38 +const int KGP12xPixelsPerByte = 8;
4.39 +const int KGP12xFrameBufferSizeInBytes = KGP12xWidthInPixels*KGP12xHeightInPixels/KGP12xPixelsPerByte; //256*64/8=2048
4.40 +const int KGP12xFrameBufferPixelCount = KGP12xWidthInPixels*KGP12xHeightInPixels;
4.41 +
4.42 +//typedef struct hid_device_info HidDeviceInfo;
4.43 +
4.44 +/**
4.45 +Define a Futaba HID report.
4.46 +*/
4.47 +class FutabaVfdReport: public HidReport<KFutabaMaxHidReportSize>
4.48 + {
4.49 +
4.50 +private:
4.51 +
4.52 + };
4.53 +
4.54 +
4.55 +/**
4.56 +Define a generic Futaba VFD command.
4.57 +*/
4.58 +class FutabaVfdCommand
4.59 + {
4.60 +public:
4.61 + FutabaVfdCommand();
4.62 + ~FutabaVfdCommand();
4.63 + //
4.64 + //void Create(int aMaxSize);
4.65 + //void Delete();
4.66 +
4.67 + //inline unsigned char& operator[](int aIndex){return iBuffer[aIndex];}
4.68 +
4.69 + void Reset();
4.70 +
4.71 +private:
4.72 + //unsigned char* iBuffer;
4.73 + FutabaVfdReport iReports[KFutabaMaxCommandOutputReport];
4.74 + int iSize;
4.75 + int iMaxSize;
4.76 + };
4.77 +
4.78 +/**
4.79 +*/
4.80 +class FutabaVfd : public HidDevice
4.81 + {
4.82 +public:
4.83 + virtual int MinBrightness() const=0;
4.84 + virtual int MaxBrightness() const=0;
4.85 + virtual void SetBrightness(int aBrightness)=0;
4.86 + virtual void Clear()=0;
4.87 + };
4.88 +
4.89 +
4.90 +/**
4.91 +*/
4.92 +class FutabaGraphicVfd : public FutabaVfd
4.93 + {
4.94 +public:
4.95 + virtual int WidthInPixels() const=0;
4.96 + virtual int HeightInPixels() const=0;
4.97 + virtual void SetPixel(unsigned char aX, unsigned char aY, bool aOn)=0;
4.98 + virtual void SetAllPixels(unsigned char aOn)=0;
4.99 + virtual int FrameBufferSizeInBytes() const=0;
4.100 + //virtual int BitBlit(unsigned char* aSrc, unsigned char aSrcWidth, unsigned char aSrcHeight, unsigned char aTargetX, unsigned char aTargetY) const=0;
4.101 +
4.102 + };
4.103 +
4.104 +/**
4.105 +Common functionality between GP1212A01A and GP1212A02A
4.106 +*/
4.107 +class GP1212XXXX : public FutabaGraphicVfd
4.108 + {
4.109 +public:
4.110 + //From FutabaVfd
4.111 + virtual int MinBrightness() const {return 0;}
4.112 + virtual int MaxBrightness() const {return 5;}
4.113 + };
4.114 +
4.115 +/**
4.116 +GP1212A01A is a graphic display module using a FUTABA 256x64dots VFD.
4.117 +The module do not include character ROM, the customer will compile the character
4.118 +by themselves (from main system).
4.119 +*/
4.120 +class GP1212A01A : public GP1212XXXX
4.121 + {
4.122 +public:
4.123 + enum Request
4.124 + {
4.125 + ERequestNone,
4.126 + ERequestDeviceId,
4.127 + ERequestFirmwareRevision,
4.128 + ERequestPowerSupplyStatus
4.129 + };
4.130 +
4.131 +public:
4.132 + GP1212A01A();
4.133 + ~GP1212A01A();
4.134 +
4.135 + //
4.136 + int Open();
4.137 + //From FutabaGraphicVfd
4.138 + virtual int WidthInPixels() const {return KGP12xWidthInPixels;}
4.139 + virtual int HeightInPixels() const {return KGP12xHeightInPixels;}
4.140 + virtual void SetPixel(unsigned char aX, unsigned char aY, bool aOn);
4.141 + virtual void SetAllPixels(unsigned char aPattern);
4.142 + virtual int FrameBufferSizeInBytes() const {return KGP12xFrameBufferSizeInBytes;}
4.143 + virtual void BitBlit(const BitArray& aBitmap, int aSrcWidth, int aSrcHeight, int aTargetX, int aTargetY) const;
4.144 + //From FutabaVfd
4.145 + virtual void SetBrightness(int aBrightness);
4.146 + virtual void Clear();
4.147 +
4.148 + //Specific to GP1212A01A
4.149 + void SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char aValue);
4.150 + void SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char* aPixels);
4.151 + //Define display position within our display RAM
4.152 + void SetDisplayPosition(unsigned char aX, unsigned char aY);
4.153 + unsigned char DisplayPositionX() const {return iDisplayPositionX;}
4.154 + unsigned char DisplayPositionY() const {return iDisplayPositionY;}
4.155 + //
4.156 + void SwapBuffers();
4.157 + //
4.158 + void RequestDeviceId();
4.159 + void RequestFirmwareRevision();
4.160 + void RequestPowerSupplyStatus();
4.161 + //
4.162 + void ToggleOffScreenMode();
4.163 + void SetOffScreenMode(bool aOn);
4.164 + bool OffScreenMode() const {return iOffScreenMode;}
4.165 + //
4.166 + void SetFrameDifferencing(bool aOn){iUseFrameDifferencing=aOn;}
4.167 + bool FrameDifferencing() const {return iUseFrameDifferencing;}
4.168 + //
4.169 + bool RequestPending(){return iRequest!=ERequestNone;}
4.170 + Request CurrentRequest(){return iRequest;}
4.171 + void CancelRequest(){iRequest=ERequestNone;}
4.172 + Request AttemptRequestCompletion();
4.173 + FutabaVfdReport& InputReport() {return iInputReport;}
4.174 + bool PowerOn(){return iPowerOn;}
4.175 +
4.176 +private:
4.177 + enum DW
4.178 + {
4.179 + DW1=0xC0,
4.180 + DW2=0xD0
4.181 + };
4.182 +
4.183 + void SetDisplayPosition(DW aDw,unsigned char aX, unsigned char aY);
4.184 + unsigned char OffScreenY() const;
4.185 + void SendClearCommand();
4.186 + void OffScreenTranslation(unsigned char& aX, unsigned char& aY);
4.187 + void ResetBuffers();
4.188 + void SendModifiedPixelBlocks();
4.189 +
4.190 +private:
4.191 + unsigned char iDisplayPositionX;
4.192 + unsigned char iDisplayPositionY;
4.193 + ///Off screen mode is the recommended default settings to avoid tearing.
4.194 + ///Though turning it off can be useful for debugging
4.195 + bool iOffScreenMode;
4.196 + ///Frame differences algo is used to reduce USB bus traffic and improve frame rate in typical use case
4.197 + bool iUseFrameDifferencing;
4.198 + ///
4.199 + //FutabaVfdReport iReport;
4.200 + ///
4.201 + //unsigned char iFrameBuffer[256*64];
4.202 + BitArray* iFrameNext;
4.203 + BitArray* iFrameCurrent;
4.204 + BitArray* iFramePrevious;
4.205 + //
4.206 + BitArray* iFrameAlpha;
4.207 + BitArray* iFrameBeta;
4.208 + BitArray* iFrameGamma;
4.209 + //
4.210 + int iNeedFullFrameUpdate;
4.211 + //unsigned char iFrameBeta[256*64];
4.212 + //unsigned char *iFrontBuffer;
4.213 + //unsigned char *iBackBuffer;
4.214 + Request iRequest;
4.215 + FutabaVfdReport iInputReport;
4.216 + bool iPowerOn;
4.217 + };
4.218 +
4.219 +
4.220 +#endif
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/HidDevice.cpp Tue Jun 17 09:55:20 2014 +0200
5.3 @@ -0,0 +1,122 @@
5.4 +//
5.5 +//
5.6 +//
5.7 +
5.8 +#include "HidDevice.h"
5.9 +
5.10 +
5.11 +
5.12 +//
5.13 +// class HidDevice
5.14 +//
5.15 +
5.16 +HidDevice::HidDevice():iHidDevice(NULL)
5.17 + {
5.18 + Close();
5.19 + }
5.20 +
5.21 +/**
5.22 +*/
5.23 +int HidDevice::Open(const char* aPath)
5.24 + {
5.25 + Close();
5.26 +
5.27 + iHidDevice = hid_open_path(aPath);
5.28 +
5.29 + if (!iHidDevice)
5.30 + {
5.31 + //Fail to connect our device
5.32 + return 0;
5.33 + }
5.34 +
5.35 + FetchStrings();
5.36 +
5.37 + return 1;
5.38 + }
5.39 +
5.40 +/**
5.41 +See hidapi documentation.
5.42 +*/
5.43 +int HidDevice::Open(unsigned short aVendorId, unsigned short aProductId, const wchar_t* aSerialNumber)
5.44 + {
5.45 + Close();
5.46 +
5.47 + iHidDevice = hid_open(aVendorId, aProductId, aSerialNumber);
5.48 +
5.49 + if (!iHidDevice)
5.50 + {
5.51 + //Fail to connect our device
5.52 + return 0;
5.53 + }
5.54 +
5.55 + FetchStrings();
5.56 +
5.57 + return 1;
5.58 + }
5.59 +
5.60 +/**
5.61 +*/
5.62 +void HidDevice::Close()
5.63 + {
5.64 + hid_close(iHidDevice);
5.65 + iHidDevice=NULL;
5.66 + //
5.67 + memset(iVendor,0,sizeof(iVendor));
5.68 + memset(iProduct,0,sizeof(iProduct));
5.69 + memset(iSerialNumber,0,sizeof(iSerialNumber));
5.70 + }
5.71 +
5.72 +/**
5.73 +*/
5.74 +bool HidDevice::IsOpen()
5.75 + {
5.76 + return iHidDevice!=NULL;
5.77 + }
5.78 +
5.79 +
5.80 +/**
5.81 +*/
5.82 +const wchar_t* HidDevice::Error()
5.83 + {
5.84 + return hid_error(iHidDevice);
5.85 + }
5.86 +
5.87 +/**
5.88 +*/
5.89 +int HidDevice::SetNonBlocking(int aNonBlocking)
5.90 + {
5.91 + //Success we are now connected to our HID device
5.92 + //Set read operation as non blocking
5.93 + return hid_set_nonblocking(iHidDevice, aNonBlocking);
5.94 + }
5.95 +
5.96 +/**
5.97 +*/
5.98 +wchar_t* HidDevice::Vendor()
5.99 + {
5.100 + return iVendor;
5.101 + }
5.102 +
5.103 +/**
5.104 +*/
5.105 +wchar_t* HidDevice::Product()
5.106 + {
5.107 + return iProduct;
5.108 + }
5.109 +
5.110 +/**
5.111 +*/
5.112 +wchar_t* HidDevice::SerialNumber()
5.113 + {
5.114 + return iSerialNumber;
5.115 + }
5.116 +
5.117 +/**
5.118 +
5.119 +*/
5.120 +void HidDevice::FetchStrings()
5.121 + {
5.122 + hid_get_manufacturer_string(iHidDevice,iVendor,sizeof(iVendor));
5.123 + hid_get_product_string(iHidDevice,iProduct,sizeof(iProduct));
5.124 + hid_get_serial_number_string(iHidDevice,iSerialNumber,sizeof(iSerialNumber));
5.125 + }
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/HidDevice.h Tue Jun 17 09:55:20 2014 +0200
6.3 @@ -0,0 +1,69 @@
6.4 +//
6.5 +//
6.6 +//
6.7 +
6.8 +#ifndef HID_DEVICE_H
6.9 +#define HID_DEVICE_H
6.10 +
6.11 +#include "HidReport.h"
6.12 +#include "hidapi.h"
6.13 +
6.14 +const int KMaxHidStringChar=256;
6.15 +
6.16 +/**
6.17 +TODO: move to another header
6.18 +*/
6.19 +class HidDevice
6.20 + {
6.21 +public:
6.22 + HidDevice();
6.23 + int Open(const char* aPath);
6.24 + int Open(unsigned short aVendorId, unsigned short aProductId, const wchar_t* aSerialNumber);
6.25 + void Close();
6.26 + bool IsOpen();
6.27 + //
6.28 + int SetNonBlocking(int aNonBlocking);
6.29 + //Read
6.30 + template<int S>
6.31 + int Read(HidReport<S>& aInputReport);
6.32 + //Write
6.33 + template<int S>
6.34 + int Write(const HidReport<S>& aOutputReport);
6.35 + //
6.36 + const wchar_t* Error();
6.37 + //
6.38 + wchar_t* Vendor();
6.39 + wchar_t* Product();
6.40 + wchar_t* SerialNumber();
6.41 +
6.42 +private:
6.43 + void FetchStrings();
6.44 +
6.45 +private:
6.46 + ///Our USB HID device
6.47 + hid_device* iHidDevice;
6.48 + //
6.49 + wchar_t iVendor[KMaxHidStringChar];
6.50 + wchar_t iProduct[KMaxHidStringChar];
6.51 + wchar_t iSerialNumber[KMaxHidStringChar];
6.52 + };
6.53 +
6.54 +
6.55 +/**
6.56 +*/
6.57 +template<int S>
6.58 +int HidDevice::Write(const HidReport<S>& aOutputReport)
6.59 + {
6.60 + return hid_write(iHidDevice,aOutputReport.Buffer(),S);
6.61 + }
6.62 +
6.63 +/**
6.64 +*/
6.65 +template<int S>
6.66 +int HidDevice::Read(HidReport<S>& aInputReport)
6.67 + {
6.68 + return hid_read(iHidDevice,aInputReport.Buffer(),S);
6.69 + }
6.70 +
6.71 +
6.72 +#endif
6.73 \ No newline at end of file
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/HidReport.h Tue Jun 17 09:55:20 2014 +0200
7.3 @@ -0,0 +1,31 @@
7.4 +#ifndef HID_REPORT_H
7.5 +#define HID_REPORT_H
7.6 +
7.7 +#include <string.h>
7.8 +
7.9 +/**
7.10 +Define an HID report.
7.11 +Can be used as input and output.
7.12 +*/
7.13 +template <int S>
7.14 +class HidReport
7.15 + {
7.16 +public:
7.17 + HidReport(){Reset();}
7.18 + void Reset();
7.19 + inline unsigned char& operator[](int aIndex){return iBuffer[aIndex];}
7.20 + const unsigned char* Buffer() const {return iBuffer;}
7.21 + unsigned char* Buffer() {return iBuffer;}
7.22 + int Size() {return S;}
7.23 +protected:
7.24 + unsigned char iBuffer[S];
7.25 + };
7.26 +
7.27 +template <int S>
7.28 +void HidReport<S>::Reset()
7.29 + {
7.30 + memset(iBuffer,0,sizeof(iBuffer));
7.31 + }
7.32 +
7.33 +
7.34 +#endif