|
// Errors are 9.x
#include "global.h"
#include "Processor.h"
extern short cycleinterval; // access a variable declared in GEColorEffects.cpp
void Processor::ParallelDisplay()
{
#ifdef PARALLELDISPLAY
#ifdef FASTPARALLELDISPLAY
// this routine is faster because it displays in parallel changed bulbs from multiple strings even if they are not at the same address
// only downside is its extra complexity may make it slightly slower when every bulb has changed
byte currentbulb[MAXSTRINGS]; // counter of which bulb we are up to on each string
Bulb* bulbs[MAXSTRINGS]; // allocate memory for our bulbs
bool done = false; // flag to indicate we are done with all strings
// initialise the counters to the bulb count
for (byte j = 0; j < MAXSTRINGS; j++)
{
currentbulb[j] = _strings[j]->BulbCount() -1;
}
// while we still have bulbs to check
while(!done)
{
done = true; // assume we are done
// check each string
for (byte j = 0; j < MAXSTRINGS; j++)
{
// assume there will be no bulb
bulbs[j] = NULL;
// loop back through the bulbs looking for the next changed bulb
while (currentbulb[j] != 255 && _strings[j]->GetBulb(currentbulb[j]) != NULL && !_strings[j]->GetBulb(currentbulb[j])->IsChanged())
{
(currentbulb[j])--;
}
// if we have a bulb
if (_strings[j]->GetBulb(currentbulb[j]) != NULL)
{
// add it to our bulbs to display
bulbs[j] = _strings[j]->GetBulb(currentbulb[j]);
// we are obviously not done
done = false;
}
}
// now we have the bulbs to display ... display them
Bulb::DisplayParallel(bulbs);
}
#else
// now display each of the bulbs
for (byte i = 0; i <= _maxbulbs; i++)
{
// get the bulbs to display in parallel
Bulb* bulbs[MAXSTRINGS];
for (byte j = 0; j < MAXSTRINGS; j++)
{
bulbs[j] = _strings[j]->GetBulb(i);
}
// display them
Bulb::DisplayParallel(bulbs);
}
#endif
#endif
}
// set all the bulbs on all the strings to the nominated colour
void Processor::SetAllColour(short colour)
{
// do it for each string
for (byte i = 0; i < MAXSTRINGS; i++)
{
// if there is a program there
if (_strings[i]->IsValid())
{
// execute a step
_strings[i]->SetAllColour(colour);
}
}
#ifdef PARALLELDISPLAY
ParallelDisplay();
#endif
}
// Run the program
void Processor::Run()
{
#if defined(PC) || defined(RASPBERRY)
int cycle = 0;
#endif
byte exec = 0;
// forever
while(true)
{
#if defined(PC) || defined(RASPBERRY)
cycle++;
#ifdef INCLUDE_MSG_DETAIL
#ifdef MINMEMORY
_platform->WriteMessage("9.1");
#else
_platform->WriteMessage("Cycle %d\n", cycle);
#endif
#endif
#endif
// flash the 13 pin
_platform->WritePin(PROGRESSPIN, exec);
_platform->SendToEmulator(PROGRESSPIN, exec);
exec++;
if (exec > 1)
{
exec = 0;
}
// go through all the strings
for (byte i = 0; i < MAXSTRINGS; i++)
{
#ifdef INCLUDE_PARAM_CHECK
if (_strings[i] == NULL)
{
_platform->Error(9);
}
#endif
// if there is a program there
if (_strings[i]->IsValid())
{
// if there are no instructions in the queue to execute or at least all the donothings are done
if (_strings[i]->Executing()->IsEmpty() || _strings[i]->AllDone())
{
// load some instructions
_strings[i]->LoadInstructions();
}
}
}
#ifdef INCLUDE_MSG_DETAIL
_platform->WriteMessage("\n");
#endif
// go through all the strings to calculate the new light states
for (byte i = 0; i < MAXSTRINGS; i++)
{
// if there is a program there
if (_strings[i]->IsValid())
{
// execute a step
_strings[i]->Execute();
}
}
#ifdef PARALLELDISPLAY
ParallelDisplay();
#endif
#ifdef INCLUDE_MSG_DETAIL
#ifdef MINMEMORY
_platform->WriteMessage("9.2");
#else
// debug progress statements
_platform->WriteMessage("End of cycle.\n");
_platform->WriteMessage("Sleeping for %d\n", cycleinterval);
#endif
#endif
// sleep for our cycle interval
#if defined(PC) || defined(RASPBERRY)
if (_break)
{
#ifdef PC
MessageBox(NULL, L"Debug Break", L"Debug Break", MB_OK);
#elif defined(RASPBERRY)
printf("Debug Break ... press enter to continue\n");
int i = 0;
scanf("%d", &i);
#endif
_break = false;
}
else
{
_platform->Delay(cycleinterval);
}
#else
_platform->Delay(cycleinterval);
#endif
}
}
// Dont need this as the processor is never destroyed
//Processor::~Processor()
//{
// for (short i = 0; i < MAXSTRINGS; i++)
// {
// delete _string[i];
// }
//}
// add a string of lights with a program
#if defined(PC) || defined(RASPBERRY)
void Processor::AddString(const byte pin, short* program, byte stringlen, short* subroutinestable)
#else
void Processor::AddString(const byte pin, prog_int16_t* program, prog_int8_t* stringlen, prog_int16_t* subroutinestable)
#endif
{
#ifdef INCLUDE_PARAM_CHECK
if (_strings[pin] == NULL)
{
_platform->Error(9);
}
#endif
// keep track of the longest string of bulbs be have seen
#if defined(PC) || defined(RASPBERRY)
if (stringlen > _maxbulbs)
{
_maxbulbs = stringlen;
}
#else
if (pgm_read_byte_near(stringlen) > _maxbulbs)
{
_maxbulbs = pgm_read_byte_near(stringlen);
}
#endif
// create the lights string
_strings[pin]->Construct(pin, program, stringlen, subroutinestable);
}
// Create a processor
void Processor::Construct()
{
#ifdef PC
_break = false;
#endif
_maxbulbs = 0;
// create the strings but set them to invalid
for (byte i = 0; i < MAXSTRINGS; i++)
{
#if defined(PC) || defined(RASPBERRY)
_strings[i] = new LightsString(this);
#else
_strings[i] = new LightsString();
#endif
#ifdef INCLUDE_PARAM_CHECK
if (_strings[i] == NULL)
{
_platform->Error(9);
}
#endif
_strings[i]->SetInvalid();
}
}
#ifdef INCLUDE_DEBUG_PATTERNS
void Processor::SetStringBulb(byte string, byte bulb, short colour, short brightness)
{
if (_strings[string] != NULL)
{
if (_strings[string]->GetBulb(bulb) != NULL)
{
_strings[string]->GetBulb(bulb)->SetColour(colour);
_strings[string]->GetBulb(bulb)->SetBrightness(brightness);
_strings[string]->GetBulb(bulb)->Display();
}
}
}
#endif
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.