# HG changeset patch # User sl # Date 1400884998 -7200 # Node ID 233a997193b8511a819606398c9a68d82cb91e4d # Parent c6b5c552980a7b7178721f53af6a352795e0ca08 Now using host frame buffer and sending the whole frame upon swap buffers. BitArray saved the day to implement proper BitBlit. Any font now drawing nicely. diff -r c6b5c552980a -r 233a997193b8 FutabaVfd.vcxproj --- a/FutabaVfd.vcxproj Thu May 22 22:36:43 2014 +0200 +++ b/FutabaVfd.vcxproj Sat May 24 00:43:18 2014 +0200 @@ -104,6 +104,7 @@ + @@ -111,6 +112,7 @@ + diff -r c6b5c552980a -r 233a997193b8 inc/BitArray.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inc/BitArray.h Sat May 24 00:43:18 2014 +0200 @@ -0,0 +1,159 @@ +/*************************************************************************** +* Arrays of Arbitrary Bit Length +* +* File : bitarray.h +* Purpose : Header file for class supporting the creation and +* manipulation of arbitrary length arrays of bits. +* Author : Michael Dipperstein +* Date : July 23, 2004 +* +**************************************************************************** +* HISTORY +* +* $Id: bitarray.h,v 1.5 2010/02/04 03:31:43 michael Exp $ +* $Log: bitarray.h,v $ +* Revision 1.5 2010/02/04 03:31:43 michael +* Replaced vector with an array of unsigned char. +* +* Made updates for GCC 4.4. +* +* Revision 1.4 2007/08/06 05:23:12 michael +* Updated for LGPL Version 3. +* +* All methods that don't modify object have been made +* const to increase functionality of const bit_array_c. +* +* All assignment operators return a reference to the object being assigned a value so that operator chaining will work. +* +* Added >> and << operators. +* +* Revision 1.3 2006/04/30 23:34:07 michael +* Improved performance by incorporating Benjamin Schindler's +* changes to pass arguments as a reference. +* +* Revision 1.2 2004/08/05 22:17:04 michael +* Add overloads for bitwise operators returning values. +* Add a more natural looking way to set bit values. +* +* Revision 1.1.1.1 2004/08/04 13:28:20 michael +* bit_array_c +* +**************************************************************************** +* +* Bitarray: An ANSI C++ class for manipulating arbitrary length bit arrays +* Copyright (C) 2004, 2006-2007, 2010 by +* Michael Dipperstein (mdipper@alumni.engr.ucsb.edu) +* +* This file is part of the bit array library. +* +* The bit array library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 3 of the +* License, or (at your option) any later version. +* +* The bit array library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +* General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +***************************************************************************/ +#ifndef BIT_ARRAY_H +#define BIT_ARRAY_H + +/*************************************************************************** +* INCLUDED FILES +***************************************************************************/ +#include + +/*************************************************************************** +* TYPE DEFINITIONS +***************************************************************************/ +class BitArray; + +/** +*/ +class BitArrayIndex +{ + public: + BitArrayIndex(BitArray *array, const unsigned int index); + + /* assignment */ + void operator=(const bool src); + + private: + BitArray *m_BitArray; /* array index applies to */ + unsigned int m_Index; /* index of bit in array */ +}; + +/** +*/ +class BitArray +{ + public: + BitArray(const int numBits); + BitArray(unsigned char *array, const int numBits); + + virtual ~BitArray(void); + + void Dump(std::ostream &outStream); + + const unsigned int SizeInBits() { return m_NumBits; }; + const unsigned int SizeInBytes() { return m_SizeInBytes; }; + + /* set/clear functions */ + void SetAll(void); + void ClearAll(void); + void SetBit(const unsigned int bit); + void SetBitValue(const unsigned int bit, bool aValue); + void ClearBit(const unsigned int bit); + + BitArrayIndex operator()(const unsigned int bit); + + /* boolean operator */ + bool operator[](const unsigned int bit) const; + bool operator==(const BitArray &other) const; + bool operator!=(const BitArray &other) const; + bool operator<(const BitArray &other) const; + bool operator<=(const BitArray &other) const; + bool operator>(const BitArray &other) const; + bool operator>=(const BitArray &other) const; + + /* bitwise operators */ + BitArray operator&(const BitArray &other) const; + BitArray operator^(const BitArray &other) const; + BitArray operator|(const BitArray &other) const; + BitArray operator~(void) const; + + BitArray operator<<(const unsigned int count) const; + BitArray operator>>(const unsigned int count) const; + + /* increment/decrement */ + BitArray& operator++(void); /* prefix */ + BitArray& operator++(int dummy); /* postfix */ + BitArray& operator--(void); /* prefix */ + BitArray& operator--(int dummy); /* postfix */ + + /* assignments */ + BitArray& operator=(const BitArray &src); + + BitArray& operator&=(const BitArray &src); + BitArray& operator^=(const BitArray &src); + BitArray& operator|=(const BitArray &src); + BitArray& Not(void); /* negate (~=) */ + + BitArray& operator<<=(unsigned const int shifts); + BitArray& operator>>=(unsigned const int shifts); + + unsigned char* Ptr(){return m_Array;} + const unsigned char* Ptr() const{return m_Array;} + + protected: + unsigned int m_NumBits; /* number of bits in the array */ + unsigned int m_SizeInBytes; + unsigned char *m_Array; /* vector of characters */ +}; + +#endif /* ndef BIT_ARRAY_H */ diff -r c6b5c552980a -r 233a997193b8 inc/FutabaVfd.h --- a/inc/FutabaVfd.h Thu May 22 22:36:43 2014 +0200 +++ b/inc/FutabaVfd.h Sat May 24 00:43:18 2014 +0200 @@ -7,6 +7,7 @@ #include "hidapi.h" #include "HidDevice.h" +#include "BitArray.h" #ifndef MIN #define MIN(a,b) (((a)<(b))?(a):(b)) @@ -29,6 +30,11 @@ const unsigned short KFutabaVendorId = 0x1008; const unsigned short KFutabaProductIdGP1212A01A = 0x100C; const unsigned short KFutabaProductIdGP1212A02A = 0x1013; //Or is it 0x1015 +const int KGP12xWidthInPixels = 256; +const int KGP12xHeightInPixels = 64; +const int KGP12xPixelsPerByte = 8; +const int KGP12xFrameBufferSizeInBytes = KGP12xWidthInPixels*KGP12xHeightInPixels/KGP12xPixelsPerByte; //256*64/8=2048 +const int KGP12xFrameBufferPixelCount = KGP12xWidthInPixels*KGP12xHeightInPixels; //typedef struct hid_device_info HidDeviceInfo; @@ -88,6 +94,8 @@ virtual void SetPixel(unsigned char aX, unsigned char aY, bool aOn)=0; virtual void SetAllPixels(unsigned char aOn)=0; virtual int FrameBufferSizeInBytes() const=0; + //virtual int BitBlit(unsigned char* aSrc, unsigned char aSrcWidth, unsigned char aSrcHeight, unsigned char aTargetX, unsigned char aTargetY) const=0; + }; /** @@ -110,14 +118,16 @@ { public: GP1212A01A(); + ~GP1212A01A(); // int Open(); //From FutabaGraphicVfd - virtual int WidthInPixels() const {return 256;}; - virtual int HeightInPixels() const {return 64;}; + virtual int WidthInPixels() const {return KGP12xWidthInPixels;}; + virtual int HeightInPixels() const {return KGP12xHeightInPixels;}; virtual void SetPixel(unsigned char aX, unsigned char aY, bool aOn); virtual void SetAllPixels(unsigned char aPattern); - virtual int FrameBufferSizeInBytes() const {return 2048;}; //256*64/8 + virtual int FrameBufferSizeInBytes() const {return KGP12xFrameBufferSizeInBytes;}; + virtual void BitBlit(BitArray& aBitmap, unsigned char aSrcWidth, unsigned char aSrcHeight, unsigned char aTargetX, unsigned char aTargetY) const; //From FutabaVfd virtual void SetBrightness(int aBrightness); virtual void Clear(); @@ -135,6 +145,8 @@ // void ToggleOffScreenMode(); bool OffScreenMode() const {return iOffScreenMode;}; + // + private: enum DW @@ -147,6 +159,7 @@ unsigned char OffScreenY() const; void SendClearCommand(); void OffScreenTranslation(unsigned char& aX, unsigned char& aY); + void ResetBuffers(); private: unsigned char iDisplayPositionX; @@ -157,7 +170,11 @@ /// //FutabaVfdReport iReport; /// - //unsigned char iPixelBuffer[256][128]; + //unsigned char iFrameBuffer[256*64]; + BitArray* iFrameBuffer; + //unsigned char iFrameBeta[256*64]; + //unsigned char *iFrontBuffer; + //unsigned char *iBackBuffer; }; diff -r c6b5c552980a -r 233a997193b8 inc/MainWindow.h --- a/inc/MainWindow.h Thu May 22 22:36:43 2014 +0200 +++ b/inc/MainWindow.h Sat May 24 00:43:18 2014 +0200 @@ -124,7 +124,7 @@ FXFont* iCurrentFont; FXTGAImage* iFontImage; ///Used the following to convert our bitmap into display format - unsigned char* iPixelBuffer; + BitArray* iPixelBuffer; struct hid_device_info *devices; hid_device *connected_device; diff -r c6b5c552980a -r 233a997193b8 src/BitArray.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/BitArray.cpp Sat May 24 00:43:18 2014 +0200 @@ -0,0 +1,1012 @@ +/*************************************************************************** +* Arrays of Arbitrary Bit Length +* +* File : bitarray.cpp +* Purpose : Provides object with methods for creation and manipulation of +* arbitrary length arrays of bits. +* +* Bit arrays are implemented as vectors of unsigned chars. Bit +* 0 is the MSB of char 0, and the last bit is the least +* significant (non-spare) bit of the last unsigned char. +* +* Example: array of 20 bits (0 through 19) with 8 bit unsigned +* chars requires 3 unsigned chars (0 through 2) to +* store all the bits. +* +* char 0 1 2 +* +--------+--------+--------+ +* | | | | +* +--------+--------+--------+ +* bit 01234567 8911111111111XXXX +* 012345 6789 +* +* Author : Michael Dipperstein +* Date : July 23, 2004 +* +**************************************************************************** +* HISTORY +* +* $Id: bitarray.cpp,v 1.7 2010/02/04 03:31:43 michael Exp $ +* $Log: bitarray.cpp,v $ +* Revision 1.7 2010/02/04 03:31:43 michael +* Replaced vector with an array of unsigned char. +* +* Made updates for GCC 4.4. +* +* Revision 1.5 2007/08/06 05:23:29 michael +* Updated for LGPL Version 3. +* +* All methods that don't modify object have been made +* const to increase functionality of const bit_array_c. +* +* All assignment operators return a reference to the object being assigned a value so that operator chaining will work. +* +* Added >> and << operators. +* +* Revision 1.3 2006/04/30 23:34:07 michael +* Improved performance by incorporating Benjamin Schindler's +* changes to pass arguments as a reference. +* +* Revision 1.2 2004/08/05 22:16:49 michael +* Add overloads for bitwise operators returning values. +* Add a more natural looking way to set bit values. +* +* Revision 1.1.1.1 2004/08/04 13:28:20 michael +* bit_array_c +* +**************************************************************************** +* +* Bitarray: An ANSI C++ class for manipulating arbitrary length bit arrays +* Copyright (C) 2004, 2006-2007, 2010 by +* Michael Dipperstein (mdipper@alumni.engr.ucsb.edu) +* +* This file is part of the bit array library. +* +* The bit array library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 3 of the +* License, or (at your option) any later version. +* +* The bit array library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +* General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +***************************************************************************/ + +/*************************************************************************** +* INCLUDED FILES +***************************************************************************/ +#include +#include +#include "bitarray.h" + +using namespace std; + +/*************************************************************************** +* MACROS +***************************************************************************/ + +/* make CHAR_BIT 8 if it's not defined in limits.h */ +#ifndef CHAR_BIT +#warning CHAR_BIT not defined. Assuming 8 bits. +#define CHAR_BIT 8 +#endif + +/* position of bit within character */ +#define BIT_CHAR(bit) ((bit) / CHAR_BIT) + +/* array index for character containing bit */ +//SL: that for big endian? +//#define BIT_IN_CHAR(bit) (1 << (CHAR_BIT - 1 - ((bit) % CHAR_BIT))) +//SL: I guess we want little endian for our Futaba GP1212A01A +#define BIT_IN_CHAR(bit) (1 << (((bit) % CHAR_BIT))) + +/* number of characters required to contain number of bits */ +#define BITS_TO_CHARS(bits) ((((bits) - 1) / CHAR_BIT) + 1) + +/* most significant bit in a character */ +#define MS_BIT (1 << (CHAR_BIT - 1)) + +/*************************************************************************** +* METHODS +***************************************************************************/ + +/*************************************************************************** +* Method : bit_array_c - constructor +* Description: This is the bit_array_c constructor. It reserves memory +* for the vector storing the array. +* Parameters : numBits - number of bits in the array +* Effects : Allocates vectory for array bits +* Returned : None +***************************************************************************/ +BitArray::BitArray(const int numBits): + m_NumBits(numBits) +{ + m_SizeInBytes = BITS_TO_CHARS(numBits); + + + /* allocate space for bit array */ + m_Array = new unsigned char[m_SizeInBytes]; + + /* set all bits to 0 */ + fill_n(m_Array, m_SizeInBytes, 0); +} + +/*************************************************************************** +* Method : bit_array_c - constructor +* Description: This is the bit_array_c constructor. It copies the +* for contents of a vector of unsigned char into the +* bitarray. +* Parameters : vect - vector to be copied +* numBits - number of bits in the array +* Effects : Allocates vectory for array bits +* Returned : None +***************************************************************************/ +BitArray::BitArray(unsigned char *array, const int numBits): + m_NumBits(numBits), + m_Array(array) +{ +} + +/*************************************************************************** +* Method : ~bit_array_c - destructor +* Description: This is the bit_array_c destructor. At this point it's +* just a place holder. +* Parameters : None +* Effects : None +* Returned : None +***************************************************************************/ +BitArray::~BitArray(void) +{ + delete[] m_Array; +} + +/*************************************************************************** +* Method : Dump +* Description: This method dumps the conents of a bit array to stdout. +* The format of the dump is a series of bytes represented in +* hexadecimal. +* Parameters : outStream - stream to write to +* Effects : Array contents are dumped to stdout +* Returned : None +***************************************************************************/ +void BitArray::Dump(std::ostream &outStream) +{ + int size; + + size = BITS_TO_CHARS(m_NumBits); + + outStream.width(2); + outStream.fill('0'); + outStream << uppercase << hex << (int)(m_Array[0]); /* first byte */ + + for (int i = 1; i < size; i++) + { + /* remaining bytes with a leading space */ + outStream << " "; + outStream.width(2); + outStream.fill('0'); + outStream << (int)(m_Array[i]); + } + + outStream << dec; +} + +/*************************************************************************** +* Method : SetAll +* Description: This method sets every bit in the bit array to 1. This +* method uses UCHAR_MAX to determine what it means to set +* all bits in an unsigned char, so it is crucial that the +* machine implementation of unsigned char utilizes all of +* the bits in the memory allocated for an unsigned char. +* Parameters : None +* Effects : Each of the bits used in the bit array are set to 1. +* Unused (spare) bits are set to 0. +* Returned : None +***************************************************************************/ +void BitArray::SetAll(void) +{ + int bits, size; + unsigned char mask; + + size = BITS_TO_CHARS(m_NumBits); + + /* set bits in all bytes to 1 */ + fill_n(m_Array, size, UCHAR_MAX); + + /* zero any spare bits so increment and decrement are consistent */ + bits = m_NumBits % CHAR_BIT; + if (bits != 0) + { + mask = UCHAR_MAX << (CHAR_BIT - bits); + m_Array[BIT_CHAR(m_NumBits - 1)] = mask; + } +} + +/*************************************************************************** +* Method : ClearAll +* Description: This method sets every bit in the bit array to 0. +* Parameters : None +* Effects : Each of the bits in the bit array are set to 0. +* Returned : None +***************************************************************************/ +void BitArray::ClearAll(void) +{ + int size; + + size = BITS_TO_CHARS(m_NumBits); + + /* set bits in all bytes to 0 */ + fill_n(m_Array, size, 0); +} + +/*************************************************************************** +* Method : SetBit +* Description: This method sets a bit in the bit array to 1. +* Parameters : bit - the number of the bit to set +* Effects : The specified bit will be set to 1. +* Returned : None +***************************************************************************/ +void BitArray::SetBit(const unsigned int bit) +{ + if (m_NumBits <= bit) + { + return; /* bit out of range */ + } + + m_Array[BIT_CHAR(bit)] |= BIT_IN_CHAR(bit); +} + +/** +*/ +void BitArray::SetBitValue(const unsigned int bit, bool aValue) + { + if (aValue) + { + SetBit(bit); + } + else + { + ClearBit(bit); + } + } + +/*************************************************************************** +* Method : ClearBit +* Description: This method sets a bit in the bit array to 0. +* Parameters : bit - the number of the bit to clear +* Effects : The specified bit will be set to 0. +* Returned : None +***************************************************************************/ +void BitArray::ClearBit(const unsigned int bit) +{ + unsigned char mask; + + if (m_NumBits <= bit) + { + return; /* bit out of range */ + } + + /* create a mask to zero out desired bit */ + mask = BIT_IN_CHAR(bit); + mask = ~mask; + + m_Array[BIT_CHAR(bit)] &= mask; +} + +/*************************************************************************** +* Method : operator() +* Description: Overload of the () operator. This method approximates +* array indices used for assignment. It returns a +* bit_array_index_c which includes an = method used to +* set bit values. +* Parameters : bit - index of array bit +* Effects : None +* Returned : bit_array_index_c (pointer to bit) +***************************************************************************/ +BitArrayIndex BitArray::operator()(const unsigned int bit) +{ + BitArrayIndex result(this, bit); + + return result; +} + +/*************************************************************************** +* Method : operator[] +* Description: Overload of the [] operator. This method returns the +* value of a bit in the bit array. +* Parameters : bit - index of array bit +* Effects : None +* Returned : The value of the specified bit. +***************************************************************************/ +bool BitArray::operator[](const unsigned int bit) const +{ + return((m_Array[BIT_CHAR(bit)] & BIT_IN_CHAR(bit)) != 0); +} + +/*************************************************************************** +* Method : operator== +* Description: overload of the == operator +* Parameters : other - bit array to compare +* Effects : None +* Returned : True if this == other. Otherwise false. +***************************************************************************/ +bool BitArray::operator==(const BitArray &other) const +{ + if (m_NumBits != other.m_NumBits) + { + /* unequal sizes */ + return false; + } + + return (this->m_Array == other.m_Array); +} + +/*************************************************************************** +* Method : operator!= +* Description: overload of the != operator +* Parameters : other - bit array to compare +* Effects : None +* Returned : True if this != other. Otherwise false. +***************************************************************************/ +bool BitArray::operator!=(const BitArray &other) const +{ + if (m_NumBits != other.m_NumBits) + { + /* unequal sizes */ + return true; + } + + return (this->m_Array != other.m_Array); +} + +/*************************************************************************** +* Method : operator< +* Description: overload of the < operator +* Parameters : other - bit array to compare +* Effects : None +* Returned : True if this < other. Otherwise false. +***************************************************************************/ +bool BitArray::operator<(const BitArray &other) const +{ + if (m_NumBits != other.m_NumBits) + { + /* unequal sizes */ + return false; + } + + return (this->m_Array < other.m_Array); +} + +/*************************************************************************** +* Method : operator<= +* Description: overload of the <= operator +* Parameters : other - bit array to compare +* Effects : None +* Returned : True if this <= other. Otherwise false. +***************************************************************************/ +bool BitArray::operator<=(const BitArray &other) const +{ + if (m_NumBits != other.m_NumBits) + { + /* unequal sizes */ + return false; + } + + return (this->m_Array <= other.m_Array); +} + +/*************************************************************************** +* Method : operator> +* Description: overload of the > operator +* Parameters : other - bit array to compare +* Effects : None +* Returned : True if this > other. Otherwise false. +***************************************************************************/ +bool BitArray::operator>(const BitArray &other) const +{ + if (m_NumBits != other.m_NumBits) + { + /* unequal sizes */ + return false; + } + + return (this->m_Array > other.m_Array); +} + +/*************************************************************************** +* Method : operator>= +* Description: overload of the >= operator +* Parameters : other - bit array to compare +* Effects : None +* Returned : True if this >= other. Otherwise false. +***************************************************************************/ +bool BitArray::operator>=(const BitArray &other) const +{ + if (m_NumBits != other.m_NumBits) + { + /* unequal sizes */ + return false; + } + + return (this->m_Array >= other.m_Array); +} + +/*************************************************************************** +* Method : operator~ +* Description: overload of the ~ operator. Negates all non-spare bits in +* bit array +* Parameters : None +* Effects : None +* Returned : value of this after bitwise not +***************************************************************************/ +BitArray BitArray::operator~(void) const +{ + BitArray result(this->m_NumBits); + result = *this; + result.Not(); + + return result; +} + +/*************************************************************************** +* Method : operator& +* Description: overload of the & operator. Performs a bitwise and +* between the source array and this bit array. +* Parameters : other - bit array on righthand side of & +* Effects : None +* Returned : value of bitwise and of this and other. +***************************************************************************/ +BitArray BitArray::operator&(const BitArray &other) const +{ + BitArray result(this->m_NumBits); + result = *this; + result &= other; + + return result; +} + + +/*************************************************************************** +* Method : operator^ +* Description: overload of the ^ operator. Performs a bitwise xor +* between the source array and this bit array. +* Parameters : other - bit array on righthand side of ^ +* Effects : None +* Returned : value of bitwise xor of this and other. +***************************************************************************/ +BitArray BitArray::operator^(const BitArray &other) const +{ + BitArray result(this->m_NumBits); + result = *this; + result ^= other; + + return result; +} + +/*************************************************************************** +* Method : operator| +* Description: overload of the | operator. Performs a bitwise or +* between the source array and this bit array. +* Parameters : other - bit array on righthand side of | +* Effects : None +* Returned : value of bitwise or of this and other. +***************************************************************************/ +BitArray BitArray::operator|(const BitArray &other) const +{ + BitArray result(this->m_NumBits); + result = *this; + result |= other; + + return result; +} + +/*************************************************************************** +* Method : operator<< +* Description: overload of the << operator. Performs a bitwise left +* shift of this bit array. +* Parameters : count - the number of bits to shift left +* Effects : None +* Returned : result of bitwise left shift +***************************************************************************/ +BitArray BitArray::operator<<(const unsigned int count) const +{ + BitArray result(this->m_NumBits); + result = *this; + result <<= count; + + return result; +} + +/*************************************************************************** +* Method : operator>> +* Description: overload of the >> operator. Performs a bitwise right +* shift of this bit array. +* Parameters : count - the number of bits to shift right +* Effects : None +* Returned : result of bitwise right shift +***************************************************************************/ +BitArray BitArray::operator>>(const unsigned int count) const +{ + BitArray result(this->m_NumBits); + result = *this; + result >>= count; + + return result; +} + +/*************************************************************************** +* Method : operator++ (prefix) +* Description: overload of the ++ operator. Increments the contents of +* a bit array. Overflows cause rollover. +* Parameters : None +* Effects : Bit array contents are incremented +* Returned : Reference to this array after increment +***************************************************************************/ +BitArray& BitArray::operator++(void) +{ + int i; + unsigned char maxValue; /* maximum value for current char */ + unsigned char one; /* least significant bit in current char */ + + if (m_NumBits == 0) + { + return *this; /* nothing to increment */ + } + + /* handle arrays that don't use every bit in the last character */ + i = (m_NumBits % CHAR_BIT); + if (i != 0) + { + maxValue = UCHAR_MAX << (CHAR_BIT - i); + one = 1 << (CHAR_BIT - i); + } + else + { + maxValue = UCHAR_MAX; + one = 1; + } + + for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--) + { + if (m_Array[i] != maxValue) + { + m_Array[i] = m_Array[i] + one; + return *this; + } + else + { + /* need to carry to next byte */ + m_Array[i] = 0; + + /* remaining characters must use all bits */ + maxValue = UCHAR_MAX; + one = 1; + } + } + + return *this; +} + +/*************************************************************************** +* Method : operator++ (postfix) +* Description: overload of the ++ operator. Increments the contents of +* a bit array. Overflows cause rollover. +* Parameters : dumy - needed for postfix increment +* Effects : Bit array contents are incremented +* Returned : Reference to this array after increment +***************************************************************************/ +BitArray& BitArray::operator++(int dummy) +{ + ++(*this); + return *this; +} + +/*************************************************************************** +* Method : operator-- (prefix) +* Description: overload of the -- operator. Decrements the contents of +* a bit array. Underflows cause rollover. +* Parameters : None +* Effects : Bit array contents are decremented +* Returned : None +***************************************************************************/ +BitArray& BitArray::operator--(void) +{ + int i; + unsigned char maxValue; /* maximum value for current char */ + unsigned char one; /* least significant bit in current char */ + + if (m_NumBits == 0) + { + return *this; /* nothing to decrement */ + } + + /* handle arrays that don't use every bit in the last character */ + i = (m_NumBits % CHAR_BIT); + if (i != 0) + { + maxValue = UCHAR_MAX << (CHAR_BIT - i); + one = 1 << (CHAR_BIT - i); + } + else + { + maxValue = UCHAR_MAX; + one = 1; + } + + for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--) + { + if (m_Array[i] >= one) + { + m_Array[i] = m_Array[i] - one; + return *this; + } + else + { + /* need to borrow from the next byte */ + m_Array[i] = maxValue; + + /* remaining characters must use all bits */ + maxValue = UCHAR_MAX; + one = 1; + } + } + + return *this; +} + +/*************************************************************************** +* Method : operator-- (postfix) +* Description: overload of the -- operator. Decrements the contents of +* a bit array. Underflows cause rollover. +* Parameters : dumy - needed for postfix decrement +* Effects : Bit array contents are decremented +* Returned : None +***************************************************************************/ +BitArray& BitArray::operator--(int dummy) +{ + --(*this); + return *this; +} + +/*************************************************************************** +* Method : operator= +* Description: overload of the = operator. Copies source contents into +* this bit array. +* Parameters : src - Source bit array +* Effects : Source bit array contents are copied into this array +* Returned : Reference to this array after copy +***************************************************************************/ +BitArray& BitArray::operator=(const BitArray &src) +{ + if (*this == src) + { + /* don't do anything for a self assignment */ + return *this; + } + + if (m_NumBits != src.m_NumBits) + { + /* don't do assignment with different array sizes */ + return *this; + } + + if ((m_NumBits == 0) || (src.m_NumBits == 0)) + { + /* don't do assignment with unallocated array */ + return *this; + } + + /* copy bits from source */ + int size; + size = BITS_TO_CHARS(m_NumBits); + + copy(src.m_Array, &src.m_Array[size], this->m_Array); + return *this; +} + +/*************************************************************************** +* Method : operator&= +* Description: overload of the &= operator. Performs a bitwise and +* between the source array and this bit array. This bit +* array will contain the result. +* Parameters : src - Source bit array +* Effects : Results of bitwise and are stored in this array +* Returned : Reference to this array after and +***************************************************************************/ +BitArray& BitArray::operator&=(const BitArray &src) +{ + int size; + + size = BITS_TO_CHARS(m_NumBits); + + if (m_NumBits != src.m_NumBits) + { + /* don't do assignment with different array sizes */ + return *this; + } + + /* AND array one unsigned char at a time */ + for(int i = 0; i < size; i++) + { + m_Array[i] = m_Array[i] & src.m_Array[i]; + } + + return *this; +} + +/*************************************************************************** +* Method : operator^= +* Description: overload of the ^= operator. Performs a bitwise xor +* between the source array and this bit array. This bit +* array will contain the result. +* Parameters : src - Source bit array +* Effects : Results of bitwise xor are stored in this array +* Returned : Reference to this array after xor +***************************************************************************/ +BitArray& BitArray::operator^=(const BitArray &src) +{ + int size; + + size = BITS_TO_CHARS(m_NumBits); + + if (m_NumBits != src.m_NumBits) + { + /* don't do assignment with different array sizes */ + return *this; + } + + /* XOR array one unsigned char at a time */ + for(int i = 0; i < size; i++) + { + m_Array[i] = m_Array[i] ^ src.m_Array[i]; + } + + return *this; +} + +/*************************************************************************** +* Method : operator|= +* Description: overload of the |= operator. Performs a bitwise or +* between the source array and this bit array. This bit +* array will contain the result. +* Parameters : src - Source bit array +* Effects : Results of bitwise or are stored in this array +* Returned : Reference to this array after or +***************************************************************************/ +BitArray& BitArray::operator|=(const BitArray &src) +{ + int size; + + size = BITS_TO_CHARS(m_NumBits); + + if (m_NumBits != src.m_NumBits) + { + /* don't do assignment with different array sizes */ + return *this; + } + + /* OR array one unsigned char at a time */ + for(int i = 0; i < size; i++) + { + m_Array[i] = m_Array[i] | src.m_Array[i]; + } + + return *this; +} + +/*************************************************************************** +* Method : Not +* Description: Negates all non-spare bits in bit array. +* Parameters : None +* Effects : Contents of bit array are negated. Any spare bits are +* left at 0. +* Returned : Reference to this array after not +***************************************************************************/ +BitArray& BitArray::Not(void) +{ + int bits; + unsigned char mask; + int size; + + size = BITS_TO_CHARS(m_NumBits); + + if (m_NumBits == 0) + { + /* don't do not with unallocated array */ + return *this; + } + + /* NOT array one unsigned char at a time */ + for(int i = 0; i < size; i++) + { + m_Array[i] = ~m_Array[i]; + } + + /* zero any spare bits so increment and decrement are consistent */ + bits = m_NumBits % CHAR_BIT; + if (bits != 0) + { + mask = UCHAR_MAX << (CHAR_BIT - bits); + m_Array[BIT_CHAR(m_NumBits - 1)] &= mask; + } + + return *this; +} + +/*************************************************************************** +* Method : operator<<= +* Description: overload of the <<= operator. Performs a left shift on +* this bit array. This bit array will contain the result. +* Parameters : shifts - number of bit positions to shift +* Effects : Results of the shifts are stored in this array +* Returned : Reference to this array after shift +***************************************************************************/ +BitArray& BitArray::operator<<=(const unsigned int shifts) +{ + int i; + int chars = shifts / CHAR_BIT; /* number of whole byte shifts */ + + if (shifts >= m_NumBits) + { + /* all bits have been shifted off */ + this->ClearAll(); + return *this; + } + + /* first handle big jumps of bytes */ + if (chars > 0) + { + int size; + + size = BITS_TO_CHARS(m_NumBits); + + for (i = 0; (i + chars) < size; i++) + { + m_Array[i] = m_Array[i + chars]; + } + + /* now zero out new bytes on the right */ + for (i = size; chars > 0; chars--) + { + m_Array[i - chars] = 0; + } + } + + /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */ + for (i = 0; i < (int)(shifts % CHAR_BIT); i++) + { + for (unsigned int j = 0; j < BIT_CHAR(m_NumBits - 1); j++) + { + m_Array[j] <<= 1; + + /* handle shifts across byte bounds */ + if (m_Array[j + 1] & MS_BIT) + { + m_Array[j] |= 0x01; + } + } + + m_Array[BIT_CHAR(m_NumBits - 1)] <<= 1; + } + + return *this; +} + +/*************************************************************************** +* Method : operator>>= +* Description: overload of the >>= operator. Performs a right shift on +* this bit array. This bit array will contain the result. +* Parameters : shifts - number of bit positions to shift +* Effects : Results of the shifts are stored in this array +* Returned : Reference to this array after shift +***************************************************************************/ +BitArray& BitArray::operator>>=(const unsigned int shifts) +{ + int i; + char mask; + int chars = shifts / CHAR_BIT; /* number of whole byte shifts */ + + if (shifts >= m_NumBits) + { + /* all bits have been shifted off */ + this->ClearAll(); + return *this; + } + + /* first handle big jumps of bytes */ + if (chars > 0) + { + for (i = BIT_CHAR(m_NumBits - 1); (i - chars) >= 0; i--) + { + m_Array[i] = m_Array[i - chars]; + } + + /* now zero out new bytes on the right */ + for (; chars > 0; chars--) + { + m_Array[chars - 1] = 0; + } + } + + /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */ + for (i = 0; i < (int)(shifts % CHAR_BIT); i++) + { + for (unsigned int j = BIT_CHAR(m_NumBits - 1); j > 0; j--) + { + m_Array[j] >>= 1; + + /* handle shifts across byte bounds */ + if (m_Array[j - 1] & 0x01) + { + m_Array[j] |= MS_BIT; + } + } + + m_Array[0] >>= 1; + } + + /*********************************************************************** + * zero any spare bits that are shifted beyond the end of the bit array + * so that increment and decrement are consistent. + ***********************************************************************/ + i = m_NumBits % CHAR_BIT; + if (i != 0) + { + mask = UCHAR_MAX << (CHAR_BIT - i); + m_Array[BIT_CHAR(m_NumBits - 1)] &= mask; + } + + return *this; +} + +/*************************************************************************** +* Method : bit_array_index_c - constructor +* Description: This is the bit_array_index_c constructor. It stores a +* pointer to the bit array and the bit index. +* Parameters : array - pointer to bit array +* index - index of bit in array +* Effects : Pointer to bit array and bit index are stored. +* Returned : None +***************************************************************************/ +BitArrayIndex::BitArrayIndex(BitArray *array, + const unsigned int index) +{ + m_BitArray = array; + m_Index = index; +} + +/*************************************************************************** +* Method : operator= +* Description: overload of the = operator. Sets the bit array bit to +* the value of src. +* Parameters : src - bit value +* Effects : Bit pointed to by this object is set to the value of +* source. +* Returned : None +***************************************************************************/ +void BitArrayIndex::operator=(const bool src) +{ + if (m_BitArray == NULL) + { + return; /* no array */ + } + + if (m_BitArray->SizeInBits() <= m_Index) + { + return; /* index is out of bounds */ + } + + if (src) + { + m_BitArray->SetBit(m_Index); + } + else + { + m_BitArray->ClearBit(m_Index); + } +} diff -r c6b5c552980a -r 233a997193b8 src/FutabaVfd.cpp --- a/src/FutabaVfd.cpp Thu May 22 22:36:43 2014 +0200 +++ b/src/FutabaVfd.cpp Sat May 24 00:43:18 2014 +0200 @@ -71,19 +71,40 @@ // class GP1212A01A // -GP1212A01A::GP1212A01A():iDisplayPositionX(0),iDisplayPositionY(0),iOffScreenMode(true) +GP1212A01A::GP1212A01A(): + iDisplayPositionX(0),iDisplayPositionY(0), + iOffScreenMode(true),iFrameBuffer(NULL) { + //ResetBuffers(); } +/** +*/ +GP1212A01A::~GP1212A01A() + { + delete iFrameBuffer; + iFrameBuffer=NULL; + } + +/** +*/ int GP1212A01A::Open() { int success = HidDevice::Open(KFutabaVendorId,KFutabaProductIdGP1212A01A,NULL); if (success) { + delete iFrameBuffer; + iFrameBuffer = NULL; + iFrameBuffer=new BitArray(KGP12xFrameBufferPixelCount); SetNonBlocking(1); //Since we can't get our display position we for it to our default //This makes sure frames are in sync from the start SetDisplayPosition(iDisplayPositionX,iDisplayPositionY); + //Now clear both front and back buffer on host and device + Clear(); + SwapBuffers(); + Clear(); + SwapBuffers(); } return success; } @@ -93,7 +114,32 @@ void GP1212A01A::SetPixel(unsigned char aX, unsigned char aY, bool aOn) { //Just specify a one pixel block - SetPixelBlock(aX,aY,0x00,0x01,aOn); + //SetPixelBlock(aX,aY,0x00,0x01,aOn); + // + //int byteOffset=(aX*HeightInPixels()+aY)/8; + //int bitOffset=(aX*HeightInPixels()+aY)%8; + //iFrameBuffer[byteOffset] |= ( (aOn?0x01:0x00) << bitOffset ); + if (aOn) + { + iFrameBuffer->SetBit(aX*HeightInPixels()+aY); + } + else + { + iFrameBuffer->ClearBit(aX*HeightInPixels()+aY); + } + } + +/** +*/ +void GP1212A01A::BitBlit(BitArray& aBitmap, unsigned char aSrcWidth, unsigned char aSrcHeight, unsigned char aTargetX, unsigned char aTargetY) const + { + for (int i=0;iSetBitValue((aTargetX+i)*HeightInPixels()+aTargetY+j,aBitmap[+i*aSrcHeight+j]); + } + } } /** @@ -109,7 +155,10 @@ //SetPixelBlock(0,0,63,sizeof(screen),screen); //Using pattern SetPixelBlock variant. - SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),aPattern); + memset(iFrameBuffer->Ptr(),aPattern,FrameBufferSizeInBytes()); + // + + } /** @@ -220,14 +269,13 @@ /** -Clear our display's screen. -This operation is performed off screen to avoid tearing. +Clear our client side back buffer. +Call to SwapBuffers must follow to actually clear the display. */ void GP1212A01A::Clear() { - //Using pattern SetPixelBlock variant. - //First fill our off screen buffer with the desired values - SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),(unsigned char)0x00); + //memset(iFrameBuffer->Ptr(),0x00,FrameBufferSizeInBytes()); + iFrameBuffer->ClearAll(); } /** @@ -297,7 +345,14 @@ //Only perform buffer swapping if off screen mode is enabled if (OffScreenMode()) { + //Send host back buffer to device back buffer + SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),iFrameBuffer->Ptr()); + //Swap device front and back buffer SetDisplayPosition(iDisplayPositionX,OffScreenY()); + //Swap host buffers + //unsigned char* backBuffer=iBackBuffer; + //iBackBuffer = iFrontBuffer; + //iFrontBuffer = backBuffer; } } @@ -312,6 +367,17 @@ aY+=HeightInPixels()-iDisplayPositionY; } } + + +/** +*/ +void GP1212A01A::ResetBuffers() + { + //iFrameBuffer->ClearAll(); + //memset(iFrameBuffer,0x00,sizeof(iFrameBuffer)); + //memset(iFrameBeta,0x00,sizeof(iFrameBeta)); + } + /** */ void GP1212A01A::RequestId() diff -r c6b5c552980a -r 233a997193b8 src/test.cpp --- a/src/test.cpp Thu May 22 22:36:43 2014 +0200 +++ b/src/test.cpp Sat May 24 00:43:18 2014 +0200 @@ -790,26 +790,23 @@ //Create display pixel buffer from our image pixels int w=iFontImage->getWidth(); int h=iFontImage->getHeight(); - int pixelBufferSize=(w*h)/8; - iPixelBuffer = new unsigned char[pixelBufferSize]; - memset(iPixelBuffer,0x00,pixelBufferSize); + int pixelCount=(w*h); + iPixelBuffer = new BitArray(pixelCount); for (int i=0;igetPixel(i,j); if (color!=0xffffffff) { - iPixelBuffer[byteOffset] |= ( 1 << bitOffset ); + iPixelBuffer->SetBit(i*h+j); } } } if (iVfd01.IsOpen()) { - iVfd01.SetPixelBlock(0,0,h-1,pixelBufferSize,iPixelBuffer); + iVfd01.BitBlit(*iPixelBuffer,w,h,0,0); iVfd01.SwapBuffers(); }