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.
19 FutabaVfdCommand::FutabaVfdCommand():/*iBuffer(NULL),*/iSize(0),iMaxSize(0)
23 FutabaVfdCommand::~FutabaVfdCommand()
32 void FutabaVfdCommand::Reset()
34 memset(iReports,0,sizeof(iReports));
43 void FutabaVfdCommand::Create(int aMaxSize)
45 iBuffer=new unsigned char[aMaxSize];
58 void FutabaVfdCommand::Delete()
74 GP1212A01A::GP1212A01A():
75 iDisplayPositionX(0),iDisplayPositionY(0),
76 iOffScreenMode(true),iFrameBuffer(NULL)
83 GP1212A01A::~GP1212A01A()
91 int GP1212A01A::Open()
93 int success = HidDevice::Open(KFutabaVendorId,KFutabaProductIdGP1212A01A,NULL);
98 iFrameBuffer=new BitArray(KGP12xFrameBufferPixelCount);
100 //Since we can't get our display position we for it to our default
101 //This makes sure frames are in sync from the start
102 SetDisplayPosition(iDisplayPositionX,iDisplayPositionY);
103 //Now clear both front and back buffer on host and device
114 void GP1212A01A::SetPixel(unsigned char aX, unsigned char aY, bool aOn)
116 //Just specify a one pixel block
117 //SetPixelBlock(aX,aY,0x00,0x01,aOn);
119 //int byteOffset=(aX*HeightInPixels()+aY)/8;
120 //int bitOffset=(aX*HeightInPixels()+aY)%8;
121 //iFrameBuffer[byteOffset] |= ( (aOn?0x01:0x00) << bitOffset );
124 iFrameBuffer->SetBit(aX*HeightInPixels()+aY);
128 iFrameBuffer->ClearBit(aX*HeightInPixels()+aY);
134 void GP1212A01A::BitBlit(BitArray& aBitmap, unsigned char aSrcWidth, unsigned char aSrcHeight, unsigned char aTargetX, unsigned char aTargetY) const
136 for (int i=0;i<aSrcWidth;i++)
138 for (int j=0;j<aSrcHeight;j++)
140 iFrameBuffer->SetBitValue((aTargetX+i)*HeightInPixels()+aTargetY+j,aBitmap[+i*aSrcHeight+j]);
146 Set all pixels on our screen to the desired value.
147 This operation is performed off screen to avoid tearing.
148 @param 8 pixels pattern
150 void GP1212A01A::SetAllPixels(unsigned char aPattern)
152 //With a single buffer
153 //unsigned char screen[2048]; //One screen worth of pixels
154 //memset(screen,0xFF,sizeof(screen));
155 //SetPixelBlock(0,0,63,sizeof(screen),screen);
157 //Using pattern SetPixelBlock variant.
158 memset(iFrameBuffer->Ptr(),aPattern,FrameBufferSizeInBytes());
165 Set our screen brightness.
166 @param The desired brightness level. Must be between MinBrightness and MaxBrightness.
168 void GP1212A01A::SetBrightness(int aBrightness)
170 if (aBrightness<MinBrightness()||aBrightness>MaxBrightness())
172 //Brightness out of range.
173 //Just ignore that request.
177 FutabaVfdReport report;
178 report[0]=0x00; //Report ID
179 report[1]=0x06; //Report size
180 report[2]=0x1B; //Command ID
181 report[3]=0x5C; //Command ID
182 report[4]=0x3F; //Command ID
183 report[5]=0x4C; //Command ID
184 report[6]=0x44; //Command ID
185 report[7]=0x30+aBrightness; //Brightness level
191 Set the defined pixel block to the given value.
192 @param X coordinate of our pixel block starting point.
193 @param Y coordinate of our pixel block starting point.
194 @param The height of our pixel block.
195 @param The size of our pixel data. Number of pixels divided by 8.
196 @param The value set to 8 pixels used as a pattern.
198 void GP1212A01A::SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char aValue)
200 OffScreenTranslation(aX,aY);
201 FutabaVfdReport report;
202 report[0]=0x00; //Report ID
203 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
204 report[2]=0x1B; //Command ID
205 report[3]=0x5B; //Command ID
206 report[4]=0xF0; //Command ID
209 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.
210 report[8]=aSize>>8; //Size of pixel data in bytes (MSB)
211 report[9]=aSize; //Size of pixel data in bytes (LSB)
212 int sizeWritten=MIN(aSize,report.Size()-10);
213 memset(report.Buffer()+10, aValue, sizeWritten);
216 int remainingSize=aSize;
217 //We need to keep on sending our pixel data until we are done
218 while (report[1]==64)
221 remainingSize-=sizeWritten;
222 report[0]=0x00; //Report ID
223 report[1]=(remainingSize<=report.Size()-2?remainingSize:64); //Report length, should be 64 or the remaining size
224 sizeWritten=(report[1]==64?63:report[1]);
225 memset(report.Buffer()+2, aValue, sizeWritten);
231 Set the defined pixel block to the given value.
232 @param X coordinate of our pixel block starting point.
233 @param Y coordinate of our pixel block starting point.
234 @param The height of our pixel block.
235 @param The size of our pixel data. Number of pixels divided by 8.
236 @param Pointer to our pixel data.
238 void GP1212A01A::SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char* aPixels)
240 OffScreenTranslation(aX,aY);
241 FutabaVfdReport report;
242 report[0]=0x00; //Report ID
243 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
244 report[2]=0x1B; //Command ID
245 report[3]=0x5B; //Command ID
246 report[4]=0xF0; //Command ID
249 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.
250 report[8]=aSize>>8; //Size of pixel data in bytes (MSB)
251 report[9]=aSize; //Size of pixel data in bytes (LSB)
252 int sizeWritten=MIN(aSize,report.Size()-10);
253 memcpy(report.Buffer()+10, aPixels, sizeWritten);
256 int remainingSize=aSize;
257 //We need to keep on sending our pixel data until we are done
258 while (report[1]==64)
261 remainingSize-=sizeWritten;
262 report[0]=0x00; //Report ID
263 report[1]=(remainingSize<=report.Size()-2?remainingSize:64); //Report length, should be 64 or the remaining size
264 sizeWritten=(report[1]==64?63:report[1]);
265 memcpy(report.Buffer()+2, aPixels+(aSize-remainingSize), sizeWritten);
272 Clear our client side back buffer.
273 Call to SwapBuffers must follow to actually clear the display.
275 void GP1212A01A::Clear()
277 //memset(iFrameBuffer->Ptr(),0x00,FrameBufferSizeInBytes());
278 iFrameBuffer->ClearAll();
282 Using this function is advised against as is causes tearing.
285 void GP1212A01A::SendClearCommand()
288 //Send Clear Display Command
289 FutabaVfdReport report;
290 report[0]=0x00; //Report ID
291 report[1]=0x04; //Report length
292 report[2]=0x1B; //Command ID
293 report[3]=0x5B; //Command ID
294 report[4]=0x32; //Command ID
295 report[5]=0x4A; //Command ID
300 Change our display position within our buffer.
302 void GP1212A01A::SetDisplayPosition(DW aDw,unsigned char aX, unsigned char aY)
305 //Send Display Position Settings Command
306 FutabaVfdReport report;
307 report[0]=0x00; //Report ID
308 report[1]=0x05; //Report length
309 report[2]=0x1B; //Command ID
310 report[3]=0x5B; //Command ID
311 report[4]=aDw; //Specify our DW
312 report[5]=aX; //X coordinate of our DW top-left corner
313 report[6]=aY; //Y coordinate of our DW top-left corner
318 Change our display position within our buffer.
320 void GP1212A01A::SetDisplayPosition(unsigned char aX, unsigned char aY)
322 //Specs apparently says both DW should remain the same
324 SetDisplayPosition(GP1212A01A::DW1,aX,aY);
325 SetDisplayPosition(GP1212A01A::DW2,aX,aY);
326 iDisplayPositionX=aX;
327 iDisplayPositionY=aY;
331 Provide Y coordinate of our off screen buffer.
333 unsigned char GP1212A01A::OffScreenY() const
335 //Overflowing is fine this is just what we want
336 return iDisplayPositionY+HeightInPixels();
340 Put our off screen buffer on screen.
341 On screen buffer goes off screen.
343 void GP1212A01A::SwapBuffers()
345 //Only perform buffer swapping if off screen mode is enabled
348 //Send host back buffer to device back buffer
349 SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),iFrameBuffer->Ptr());
350 //Swap device front and back buffer
351 SetDisplayPosition(iDisplayPositionX,OffScreenY());
353 //unsigned char* backBuffer=iBackBuffer;
354 //iBackBuffer = iFrontBuffer;
355 //iFrontBuffer = backBuffer;
360 Translate the given pixel coordinate according to our off screen mode.
362 void GP1212A01A::OffScreenTranslation(unsigned char& aX, unsigned char& aY)
366 aX+=WidthInPixels()-iDisplayPositionX;
367 aY+=HeightInPixels()-iDisplayPositionY;
374 void GP1212A01A::ResetBuffers()
376 //iFrameBuffer->ClearAll();
377 //memset(iFrameBuffer,0x00,sizeof(iFrameBuffer));
378 //memset(iFrameBeta,0x00,sizeof(iFrameBeta));
383 void GP1212A01A::RequestId()
385 //1BH,5BH,63H,49H,44H
386 //Send Read ID command
387 FutabaVfdReport report;
388 report[0]=0x00; //Report ID
389 report[1]=0x05; //Report length
390 report[2]=0x1B; //Command ID
391 report[3]=0x5B; //Command ID
392 report[4]=0x63; //Command ID
393 report[5]=0x49; //Command ID
394 report[6]=0x44; //Command ID
400 void GP1212A01A::RequestFirmwareRevision()
402 //1BH,5BH,63H,46H,52H
403 //Send Software Revision Read Command
404 FutabaVfdReport report;
405 report[0]=0x00; //Report ID
406 report[1]=0x05; //Report length
407 report[2]=0x1B; //Command ID
408 report[3]=0x5B; //Command ID
409 report[4]=0x63; //Command ID
410 report[5]=0x46; //Command ID
411 report[6]=0x52; //Command ID
417 void GP1212A01A::RequestPowerSupplyStatus()
419 //1BH,5BH,63H,50H,4DH
420 //Send Power Suppply Monitor Command
421 FutabaVfdReport report;
422 report[0]=0x00; //Report ID
423 report[1]=0x05; //Report length
424 report[2]=0x1B; //Command ID
425 report[3]=0x5B; //Command ID
426 report[4]=0x63; //Command ID
427 report[5]=0x50; //Command ID
428 report[6]=0x4D; //Command ID
434 This is for development purposes only.
435 Production application should stick to off-screen mode to avoid tearing.
437 void GP1212A01A::ToggleOffScreenMode()
439 iOffScreenMode=!iOffScreenMode;
440 //Clean up our buffers upon switching modes
441 SetDisplayPosition(0,0);