PlayerBase.cpp

Committer:
daan
Date:
2011-12-22
Revision:
2:ce4c7e5ab241
Parent:
1:578d6bbe9f09

File content as of revision 2:ce4c7e5ab241:

#include "PlayerBase.h"

#include "assert.h"
#include "VectorFormat.h"

//#include <iostream>

olc::PlayerBase::PlayerBase() :
mData(0),
mSize(0),
mPlayHead(0),
mPenDown(false),
mLaserPower(0xFFFF),
mGalvoX(0),
mGalvoY(0),
mDelay(0),
mStepSize(1)
{
}

void olc::PlayerBase::setGalvo(uint16_t x, uint16_t y) {
}

void olc::PlayerBase::setLaserPower(uint16_t power) {
  //  std::cout << "laser power " << power << std::endl;
}

void olc::PlayerBase::wait(uint16_t ms) {  
}

void olc::PlayerBase::setData(uint8_t *aData, int aSize) {
  reset();
  assert(aSize > 0);
  assert(aData != 0);
  mSize = aSize;
  mData = aData;
}

void olc::PlayerBase::reset() {
  mPlayHead = 0;
  setLaserPower(0);
}

bool olc::PlayerBase::hasNext() {
  // std::cout << "bytes left " << bytesLeft() << std::endl;
  if ( bytesLeft() > 0 ) return true;
  return false;
}

bool olc::PlayerBase::playOne() {
  if ( bytesLeft() == 0  ) return true;
  
  // definition of variables neccesairy due to the switch statement. maybe
  // use the if else if construction.
  
  uint16_t x;
  uint16_t y;
  uint8_t header = get();
  
  // this cannot be a byte because we overflow with 255 packets.
  int size;
  uint16_t power;
  char messageString[256];
  char *mesgPtr;
  uint8_t messageLength;
  uint8_t messageLevel;
  uint16_t delay;
  uint8_t r,g,b;
  
  switch (header) {
    case olc::MOVE_TO:
      // if pen was down, make it go up.
      if (mPenDown) {
        penUp();
      }
      mGalvoX = decodeU16();
      mGalvoY = decodeU16();
      setGalvo(mGalvoX,mGalvoY);
      //std::cout << "move to [" << mGalvoX << "," << mGalvoY << "]" << std::endl;
      break;       
      
    case olc::LINE_TO:
      // if pen was up, make it go down.
      if (!mPenDown) {
        penDown();
        // setLaserPower(mLaserPower);
        // mPenDown = true;
      }
      x = decodeU16();
      y = decodeU16();
      rasterLine(mGalvoX, mGalvoY, x, y, mStepSize);
      mGalvoX = x;
      mGalvoY = y;
      // setGalvo(mGalvoX,mGalvoY);
      //std::cout << "line to [" << mGalvoX << "," << mGalvoY << "]" << std::endl;
      break;
    case olc::STEP_DELAY:
      mDelay = decodeU16();
      break;
    case olc::PEN_DOWN:
      penDown();
      break;
    case olc::PEN_UP:
      penUp();
      break;
    case olc::STEP_SIZE:
      // std::cout << "step size" << std::endl;      
      mStepSize = decodeU16();
      break;
    // sending a message. length is as strlen: number of characters
    // preceeding the terminating /0 character
    case olc:: REPORT_BUFFER_IN_SIZE:
      reportBufferInSize();
      break;
    case olc::WAIT:
      delay = decodeU16();
      wait(delay);
      break;
    case olc::MESSAGE:
      messageLevel  = get(); 
      messageLength = get();
      assert(messageLength < 255);
      // now skip x bytes
      mesgPtr = &(messageString[0]);
      while(1) { 
        *mesgPtr = get(); 
        if (*mesgPtr == '\0') break;
        mesgPtr++;
        // check for buffer overflow.
        if ( mesgPtr - &(messageString[0]) == 256 ) break;
      }
      message(messageLevel, messageLength, &(messageString[0])); 
      break;
      
    case olc::CALIBRATION_SCAN:
      calibrationScan();
      break;
    case olc::POINT:
      x = decodeU16();
      y = decodeU16();
      point(x,y);
      break;
    case olc::READ_COLOR:
      readColor();
      break;      
    case olc::AYT:
      areYouThere();
      break;      
    case olc::READY:
      ready();
      break;  
      
    case olc::LASER_POWER_RGB:
      r = get();
      g = get();
      b = get();
      setLaserPowerRgb(r,g,b);
      break;          
    case olc::LASER_POWER:
      //std::cout << "laser power" << std::endl;      
      mLaserPower = decodeU16();
      //setLaserPower(mLaserPower);
      break;
    case olc::BITMAPU8:
      //std::cout << "bitmapU8" << std::endl;
      penDown();
      size = (int)get();
      for( int i = 0; i < size; i++ ) {
        uint16_t delay = ((uint16_t) get() ) << 4;
        wait(delay);
        // setLaserPower( power );
        mGalvoX += mStepSize;
        setGalvo(mGalvoX, mGalvoY);
        //std::cout << "power " << (int)power << std::endl;
      }      
      break;
    default:
      //std::cout << "found unknown code " << (int)header << std::endl;
      return false;
  }
  // if (mPlayHead >= mSize) return false;
  return true;
}

// a simple bresenheim line integer algorithm
void olc::PlayerBase::rasterLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, int step) 
{
  
  int dy = y1 - y0;
  int dx = x1 - x0;
  int stepx, stepy;
  if (dy < 0) { dy = -dy;  stepy = -step; } else { stepy = step; }
  if (dx < 0) { dx = -dx;  stepx = -step; } else { stepx = step; }
  dy <<= 2;  // dy is now 2*dy
  dx <<= 2;  // dx is now 2*dx
  
  if ( (dx == 0) && (dy == 0) ) return;   // nothing to move.
  
  if (dx > dy) {
    int fraction = dy - (dx >> 1);   // same as 2*dy - dx
    if ( stepx > 0) {
      while (x0 < x1) {
        if (fraction >= 0) { y0 += stepy; fraction -= dx; }
        x0 += stepx; fraction += dy;
        setGalvo(x0, y0);
        wait(mDelay);
      }
    } else {
      while (x0 > x1) {
        if (fraction >= 0) { y0 += stepy; fraction -= dx; }
        x0 += stepx; fraction += dy;
        setGalvo(x0, y0);
        wait(mDelay);
      }
    }
  } else {
    int fraction = dx - (dy >> 1);
    if ( stepy >  0) {
      while (y0 < y1) {
        if (fraction >= 0) { x0 += stepx; fraction -= dy; }
        y0 += stepy;
        fraction += dx;
        setGalvo(x0, y0);
        wait(mDelay);
      }
    } else {
      while (y0 > y1) {
        if (fraction >= 0) { x0 += stepx; fraction -= dy; }
        y0 += stepy;
        fraction += dx;
        setGalvo(x0, y0);
        wait(mDelay);
      }
    }
  }
}