7 Commits

Author SHA1 Message Date
Gavin MacGregor
0901803186 Simplify storage of NOS control bits 2025-02-19 15:22:28 +00:00
Gavin MacGregor
923c5563d5 Store text in packets instead of array
This removes the character array from the LevelOnePage class and stores the
characters in packets 0 to 24 natively, adding a packet when a character is
first added to a row and removing a packet when a row becomes space
characters.
2025-02-13 22:55:11 +00:00
Gavin MacGregor
9427760631 Put back unhandled packet storage 2025-02-13 16:41:08 +00:00
Gavin MacGregor
0cc49e7ea5 Move from dynamically allocating arrays to fixed arrays
This should allow the page bass class to be copy constructed.
2025-02-12 21:49:56 +00:00
Gavin MacGregor
8bb05ed250 Use proper superclass 2025-02-11 21:29:58 +00:00
Gavin MacGregor
0a1c018a02 Remove unused and incorrect subclass copy constructor 2025-02-11 20:48:05 +00:00
Gavin MacGregor
4024efaf01 Rename packet variables
"y": packet number
"d": designation code
"t": triplet number

"packet" renamed to "pkt" in method parameters to avoid ambiguity with
the "packet" method.
2025-02-11 18:46:01 +00:00
6 changed files with 174 additions and 260 deletions

View File

@@ -33,32 +33,11 @@ LevelOnePage::LevelOnePage()
clearPage(); clearPage();
} }
// BUG this copy constructor isn't used? Parameter should be LevelOnePage
LevelOnePage::LevelOnePage(const PageBase &other)
{
m_enhancements.reserve(maxEnhancements());
clearPage();
for (int i=0; i<26; i++)
if (other.packetExists(i))
setPacket(i, other.packet(i));
for (int i=26; i<30; i++)
for (int j=0; j<16; j++)
if (other.packetExists(i, j))
setPacket(i, j, other.packet(i));
for (int i=PageBase::C4ErasePage; i<=PageBase::C14NOS; i++)
setControlBit(i, other.controlBit(i));
}
// So far we only call clearPage() once, within the constructor // So far we only call clearPage() once, within the constructor
void LevelOnePage::clearPage() void LevelOnePage::clearPage()
{ {
for (int r=0; r<25; r++) for (int b=C4ErasePage; b<=C14NOS; b++)
for (int c=0; c<40; c++) setControlBit(b, false);
m_level1Page[r][c] = 0x20;
for (int i=C4ErasePage; i<=C14NOS; i++)
setControlBit(i, false);
for (int i=0; i<8; i++) for (int i=0; i<8; i++)
m_composeLink[i] = { (i<4) ? i : 0, false, i>=4, 0x0ff, 0x0000 }; m_composeLink[i] = { (i<4) ? i : 0, false, i>=4, 0x0ff, 0x0000 };
for (int i=0; i<6; i++) for (int i=0; i<6; i++)
@@ -92,38 +71,24 @@ bool LevelOnePage::isEmpty() const
return false; return false;
for (int r=0; r<25; r++) for (int r=0; r<25; r++)
for (int c=0; c<40; c++) if (!PageX26Base::packet(r).isEmpty())
if (m_level1Page[r][c] != 0x20)
return false; return false;
return true; return true;
} }
QByteArray LevelOnePage::packet(int packetNumber) const QByteArray LevelOnePage::packet(int y, int d) const
{ {
QByteArray result(40, 0x00); QByteArray result(40, 0x00);
if (packetNumber <= 24) { if (y == 26) {
for (int c=0; c<40; c++) if (!packetFromEnhancementListNeeded(d))
result[c] = m_level1Page[packetNumber][c];
return result;
}
return PageBase::packet(packetNumber);
}
QByteArray LevelOnePage::packet(int packetNumber, int designationCode) const
{
QByteArray result(40, 0x00);
if (packetNumber == 26) {
if (!packetFromEnhancementListNeeded(designationCode))
return result; // Blank result return result; // Blank result
return packetFromEnhancementList(designationCode); return packetFromEnhancementList(d);
} }
if (packetNumber == 27 && designationCode == 0) { if (y == 27 && d == 0) {
for (int i=0; i<6; i++) { for (int i=0; i<6; i++) {
result[i*6+1] = m_fastTextLink[i].pageNumber & 0x00f; result[i*6+1] = m_fastTextLink[i].pageNumber & 0x00f;
result[i*6+2] = (m_fastTextLink[i].pageNumber & 0x0f0) >> 4; result[i*6+2] = (m_fastTextLink[i].pageNumber & 0x0f0) >> 4;
@@ -138,9 +103,9 @@ QByteArray LevelOnePage::packet(int packetNumber, int designationCode) const
return result; return result;
} }
if (packetNumber == 27 && (designationCode == 4 || designationCode == 5)) { if (y == 27 && (d == 4 || d == 5)) {
for (int i=0; i<(designationCode == 4 ? 6 : 2); i++) { for (int i=0; i<(d == 4 ? 6 : 2); i++) {
int pageLinkNumber = i+(designationCode == 4 ? 0 : 6); int pageLinkNumber = i+(d == 4 ? 0 : 6);
result[i*6+1] = (m_composeLink[pageLinkNumber].level3p5 << 3) | (m_composeLink[pageLinkNumber].level2p5 << 2) | m_composeLink[pageLinkNumber].function; result[i*6+1] = (m_composeLink[pageLinkNumber].level3p5 << 3) | (m_composeLink[pageLinkNumber].level2p5 << 2) | m_composeLink[pageLinkNumber].function;
result[i*6+2] = ((m_composeLink[pageLinkNumber].pageNumber & 0x100) >> 3) | 0x10 | (m_composeLink[pageLinkNumber].pageNumber & 0x00f); result[i*6+2] = ((m_composeLink[pageLinkNumber].pageNumber & 0x100) >> 3) | 0x10 | (m_composeLink[pageLinkNumber].pageNumber & 0x00f);
@@ -154,8 +119,8 @@ QByteArray LevelOnePage::packet(int packetNumber, int designationCode) const
return result; return result;
} }
if (packetNumber == 28 && (designationCode == 0 || designationCode == 4)) { if (y == 28 && (d == 0 || d == 4)) {
int CLUToffset = (designationCode == 0) ? 16 : 0; int CLUToffset = (d == 0) ? 16 : 0;
result[1] = 0x00; result[1] = 0x00;
result[2] = ((m_defaultCharSet & 0x3) << 4) | (m_defaultNOS << 1); result[2] = ((m_defaultCharSet & 0x3) << 4) | (m_defaultNOS << 1);
@@ -175,36 +140,32 @@ QByteArray LevelOnePage::packet(int packetNumber, int designationCode) const
return result; return result;
} }
return PageBase::packet(packetNumber, designationCode); return PageX26Base::packet(y, d);
} }
bool LevelOnePage::setPacket(int packetNumber, QByteArray packetContents) /*
bool LevelOnePage::setPacket(int y, QByteArray pkt)
{ {
if (packetNumber <= 24) { if (y == 25)
for (int c=0; c<40; c++) qDebug("LevelOnePage unhandled setPacket X/25");
m_level1Page[packetNumber][c] = packetContents.at(c);
return PageX26Base::setPacket(y, pkt);
}
*/
bool LevelOnePage::setPacket(int y, int d, QByteArray pkt)
{
if (y == 26) {
setEnhancementListFromPacket(d, pkt);
return true; return true;
} }
qDebug("LevelOnePage unhandled setPacket X/%d", packetNumber); if (y == 27 && d == 0) {
// BUG can't store unhandled packets as default copy constructor uses pointers
//return PageBase::setPacket(packetNumber, packetContents);
return false;
}
bool LevelOnePage::setPacket(int packetNumber, int designationCode, QByteArray packetContents)
{
if (packetNumber == 26) {
setEnhancementListFromPacket(designationCode, packetContents);
return true;
}
if (packetNumber == 27 && designationCode == 0) {
for (int i=0; i<6; i++) { for (int i=0; i<6; i++) {
int relativeMagazine = (packetContents.at(i*6+4) >> 3) | ((packetContents.at(i*6+6) & 0xc) >> 1); int relativeMagazine = (pkt.at(i*6+4) >> 3) | ((pkt.at(i*6+6) & 0xc) >> 1);
int pageNumber = (packetContents.at(i*6+2) << 4) | packetContents.at(i*6+1); int pageNumber = (pkt.at(i*6+2) << 4) | pkt.at(i*6+1);
m_fastTextLink[i].pageNumber = (relativeMagazine << 8) | pageNumber; m_fastTextLink[i].pageNumber = (relativeMagazine << 8) | pageNumber;
m_fastTextLink[i].subPageNumber = packetContents.at(i*6+3) | ((packetContents.at(i*6+4) & 0x7) << 4) | (packetContents.at(i*6+5) << 8) | ((packetContents.at(i*6+6) & 0x3) << 12); m_fastTextLink[i].subPageNumber = pkt.at(i*6+3) | ((pkt.at(i*6+4) & 0x7) << 4) | (pkt.at(i*6+5) << 8) | ((pkt.at(i*6+6) & 0x3) << 12);
// TODO remove this warning when we can preserve FastText subpage links // TODO remove this warning when we can preserve FastText subpage links
if (m_fastTextLink[i].subPageNumber != 0x3f7f) if (m_fastTextLink[i].subPageNumber != 0x3f7f)
qDebug("FastText link %d has custom subPageNumber %x - will NOT be saved!", i, m_fastTextLink[i].subPageNumber); qDebug("FastText link %d has custom subPageNumber %x - will NOT be saved!", i, m_fastTextLink[i].subPageNumber);
@@ -212,73 +173,59 @@ bool LevelOnePage::setPacket(int packetNumber, int designationCode, QByteArray p
return true; return true;
} }
if (packetNumber == 27 && (designationCode == 4 || designationCode == 5)) { if (y == 27 && (d == 4 || d == 5)) {
for (int i=0; i<(designationCode == 4 ? 6 : 2); i++) { for (int i=0; i<(d == 4 ? 6 : 2); i++) {
int pageLinkNumber = i+(designationCode == 4 ? 0 : 6); int pageLinkNumber = i+(d == 4 ? 0 : 6);
int pageFunction = packetContents.at(i*6+1) & 0x03; int pageFunction = pkt.at(i*6+1) & 0x03;
if (i >= 4) if (i >= 4)
m_composeLink[pageLinkNumber].function = pageFunction; m_composeLink[pageLinkNumber].function = pageFunction;
else if (i != pageFunction) else if (i != pageFunction)
qDebug("X/27/4 link number %d fixed at function %d. Attempted to set to %d.", pageLinkNumber, pageLinkNumber, pageFunction); qDebug("X/27/4 link number %d fixed at function %d. Attempted to set to %d.", pageLinkNumber, pageLinkNumber, pageFunction);
m_composeLink[pageLinkNumber].level2p5 = packetContents.at(i*6+1) & 0x04; m_composeLink[pageLinkNumber].level2p5 = pkt.at(i*6+1) & 0x04;
m_composeLink[pageLinkNumber].level3p5 = packetContents.at(i*6+1) & 0x08; m_composeLink[pageLinkNumber].level3p5 = pkt.at(i*6+1) & 0x08;
m_composeLink[pageLinkNumber].pageNumber = ((packetContents.at(i*6+3) & 0x03) << 9) | ((packetContents.at(i*6+2) & 0x20) << 3) | ((packetContents.at(i*6+3) & 0x3c) << 2) | (packetContents.at(i*6+2) & 0x0f); m_composeLink[pageLinkNumber].pageNumber = ((pkt.at(i*6+3) & 0x03) << 9) | ((pkt.at(i*6+2) & 0x20) << 3) | ((pkt.at(i*6+3) & 0x3c) << 2) | (pkt.at(i*6+2) & 0x0f);
m_composeLink[pageLinkNumber].subPageCodes = (packetContents.at(i*6+4) >> 2) | (packetContents.at(i*6+5) << 4) | (packetContents.at(i*6+6) << 10); m_composeLink[pageLinkNumber].subPageCodes = (pkt.at(i*6+4) >> 2) | (pkt.at(i*6+5) << 4) | (pkt.at(i*6+6) << 10);
} }
return true; return true;
} }
if (packetNumber == 28 && (designationCode == 0 || designationCode == 4)) { if (y == 28 && (d == 0 || d == 4)) {
int CLUToffset = (designationCode == 0) ? 16 : 0; int CLUToffset = (d == 0) ? 16 : 0;
m_defaultCharSet = ((packetContents.at(2) >> 4) & 0x3) | ((packetContents.at(3) << 2) & 0xc); m_defaultCharSet = ((pkt.at(2) >> 4) & 0x3) | ((pkt.at(3) << 2) & 0xc);
m_defaultNOS = (packetContents.at(2) >> 1) & 0x7; m_defaultNOS = (pkt.at(2) >> 1) & 0x7;
m_secondCharSet = ((packetContents.at(3) >> 5) & 0x1) | ((packetContents.at(4) << 1) & 0xe); m_secondCharSet = ((pkt.at(3) >> 5) & 0x1) | ((pkt.at(4) << 1) & 0xe);
m_secondNOS = (packetContents.at(3) >> 2) & 0x7; m_secondNOS = (pkt.at(3) >> 2) & 0x7;
m_leftSidePanelDisplayed = (packetContents.at(4) >> 3) & 1; m_leftSidePanelDisplayed = (pkt.at(4) >> 3) & 1;
m_rightSidePanelDisplayed = (packetContents.at(4) >> 4) & 1; m_rightSidePanelDisplayed = (pkt.at(4) >> 4) & 1;
m_sidePanelStatusL25 = (packetContents.at(4) >> 5) & 1; m_sidePanelStatusL25 = (pkt.at(4) >> 5) & 1;
m_sidePanelColumns = packetContents.at(5) & 0xf; m_sidePanelColumns = pkt.at(5) & 0xf;
for (int c=0; c<16; c++) for (int c=0; c<16; c++)
m_CLUT[CLUToffset+c] = ((packetContents.at(c*2+5) << 4) & 0x300) | ((packetContents.at(c*2+6) << 10) & 0xc00) | ((packetContents.at(c*2+6) << 2) & 0x0f0) | (packetContents.at(c*2+7) & 0x00f); m_CLUT[CLUToffset+c] = ((pkt.at(c*2+5) << 4) & 0x300) | ((pkt.at(c*2+6) << 10) & 0xc00) | ((pkt.at(c*2+6) << 2) & 0x0f0) | (pkt.at(c*2+7) & 0x00f);
m_defaultScreenColour = (packetContents.at(37) >> 4) | ((packetContents.at(38) << 2) & 0x1c); m_defaultScreenColour = (pkt.at(37) >> 4) | ((pkt.at(38) << 2) & 0x1c);
m_defaultRowColour = ((packetContents.at(38)) >> 3) | ((packetContents.at(39) << 3) & 0x18); m_defaultRowColour = ((pkt.at(38)) >> 3) | ((pkt.at(39) << 3) & 0x18);
m_blackBackgroundSubst = (packetContents.at(39) >> 2) & 1; m_blackBackgroundSubst = (pkt.at(39) >> 2) & 1;
m_colourTableRemap = (packetContents.at(39) >> 3) & 7; m_colourTableRemap = (pkt.at(39) >> 3) & 7;
return true; return true;
} }
qDebug("LevelOnePage unhandled setPacket X/%d/%d", packetNumber, designationCode); qDebug("LevelOnePage unhandled setPacket X/%d/%d", y, d);
// BUG can't store unhandled packets as default copy constructor uses pointers return PageX26Base::setPacket(y, d, pkt);
//return PageBase::setPacket(packetNumber, designationCode, packetContents);
return false;
} }
bool LevelOnePage::packetExists(int packetNumber) const bool LevelOnePage::packetExists(int y, int d) const
{ {
if (packetNumber <= 24) { if (y == 26)
for (int c=0; c<40; c++) return packetFromEnhancementListNeeded(d);
if (m_level1Page[packetNumber][c] != 0x20)
return true;
return false;
}
return PageBase::packetExists(packetNumber); if (y == 27 && d == 0) {
}
bool LevelOnePage::packetExists(int packetNumber, int designationCode) const
{
if (packetNumber == 26)
return packetFromEnhancementListNeeded(designationCode);
if (packetNumber == 27 && designationCode == 0) {
for (int i=0; i<6; i++) for (int i=0; i<6; i++)
if ((m_fastTextLink[i].pageNumber & 0x0ff) != 0xff) if ((m_fastTextLink[i].pageNumber & 0x0ff) != 0xff)
return true; return true;
@@ -286,63 +233,49 @@ bool LevelOnePage::packetExists(int packetNumber, int designationCode) const
return false; return false;
} }
if (packetNumber == 27 && (designationCode == 4 || designationCode == 5)) { if (y == 27 && (d == 4 || d == 5)) {
for (int i=0; i<(designationCode == 4 ? 6 : 2); i++) { for (int i=0; i<(d == 4 ? 6 : 2); i++) {
int pageLinkNumber = i+(designationCode == 4 ? 0 : 6); int pageLinkNumber = i+(d == 4 ? 0 : 6);
if ((m_composeLink[pageLinkNumber].pageNumber & 0x0ff) != 0x0ff) if ((m_composeLink[pageLinkNumber].pageNumber & 0x0ff) != 0x0ff)
return true; return true;
} }
return false; return false;
} }
if (packetNumber == 28) { if (y == 28) {
if (designationCode == 0) { if (d == 0) {
if (m_leftSidePanelDisplayed || m_rightSidePanelDisplayed || m_defaultScreenColour !=0 || m_defaultRowColour !=0 || m_blackBackgroundSubst || m_colourTableRemap !=0 || m_defaultCharSet != 0 || m_secondCharSet != 0xf) if (m_leftSidePanelDisplayed || m_rightSidePanelDisplayed || m_defaultScreenColour !=0 || m_defaultRowColour !=0 || m_blackBackgroundSubst || m_colourTableRemap !=0 || m_defaultCharSet != 0 || m_secondCharSet != 0xf)
return true; return true;
return !isPaletteDefault(16, 31); return !isPaletteDefault(16, 31);
} }
if (designationCode == 4) if (d == 4)
return !isPaletteDefault(0, 15); return !isPaletteDefault(0, 15);
} }
return PageBase::packetExists(packetNumber, designationCode); return PageX26Base::packetExists(y, d);
} }
bool LevelOnePage::controlBit(int bitNumber) const bool LevelOnePage::setControlBit(int b, bool active)
{ {
switch (bitNumber) { switch (b) {
case C12NOS: case C12NOS:
return (m_defaultNOS & 1) == 1; m_defaultNOS &= 0x6;
if (active)
m_defaultNOS |= 0x1;
break;
case C13NOS: case C13NOS:
return (m_defaultNOS & 2) == 2; m_defaultNOS &= 0x5;
if (active)
m_defaultNOS |= 0x2;
break;
case C14NOS: case C14NOS:
return (m_defaultNOS & 4) == 4; m_defaultNOS &= 0x3;
default: if (active)
return PageBase::controlBit(bitNumber); m_defaultNOS |= 0x4;
break;
} }
}
bool LevelOnePage::setControlBit(int bitNumber, bool active) return PageX26Base::setControlBit(b, active);
{
switch (bitNumber) {
case C12NOS:
m_defaultNOS &= 0x06;
if (active)
m_defaultNOS |= 0x01;
return true;
case C13NOS:
m_defaultNOS &= 0x05;
if (active)
m_defaultNOS |= 0x02;
return true;
case C14NOS:
m_defaultNOS &= 0x03;
if (active)
m_defaultNOS |= 0x04;
return true;
default:
return PageBase::setControlBit(bitNumber, active);
}
} }
/* void LevelOnePage::setSubPageNumber(int newSubPageNumber) { m_subPageNumber = newSubPageNumber; } */ /* void LevelOnePage::setSubPageNumber(int newSubPageNumber) { m_subPageNumber = newSubPageNumber; } */
@@ -353,6 +286,10 @@ void LevelOnePage::setDefaultCharSet(int newDefaultCharSet) { m_defaultCharSet =
void LevelOnePage::setDefaultNOS(int defaultNOS) void LevelOnePage::setDefaultNOS(int defaultNOS)
{ {
m_defaultNOS = defaultNOS; m_defaultNOS = defaultNOS;
PageX26Base::setControlBit(C12NOS, m_defaultNOS & 0x1);
PageX26Base::setControlBit(C13NOS, m_defaultNOS & 0x2);
PageX26Base::setControlBit(C14NOS, m_defaultNOS & 0x4);
} }
void LevelOnePage::setSecondCharSet(int newSecondCharSet) void LevelOnePage::setSecondCharSet(int newSecondCharSet)
@@ -363,7 +300,27 @@ void LevelOnePage::setSecondCharSet(int newSecondCharSet)
} }
void LevelOnePage::setSecondNOS(int newSecondNOS) { m_secondNOS = newSecondNOS; } void LevelOnePage::setSecondNOS(int newSecondNOS) { m_secondNOS = newSecondNOS; }
void LevelOnePage::setCharacter(int row, int column, unsigned char newCharacter) { m_level1Page[row][column] = newCharacter; }
void LevelOnePage::setCharacter(int r, int c, unsigned char newCharacter)
{
QByteArray pkt;
if (!packetExists(r)) {
if (newCharacter == 0x20)
return;
pkt = QByteArray(40, 0x20);
pkt[c] = newCharacter;
setPacket(r, pkt);
} else {
pkt = packet(r);
pkt[c] = newCharacter;
if (pkt == QByteArray(40, 0x20))
clearPacket(r);
else
setPacket(r, pkt);
}
}
void LevelOnePage::setDefaultScreenColour(int newDefaultScreenColour) { m_defaultScreenColour = newDefaultScreenColour; } void LevelOnePage::setDefaultScreenColour(int newDefaultScreenColour) { m_defaultScreenColour = newDefaultScreenColour; }
void LevelOnePage::setDefaultRowColour(int newDefaultRowColour) { m_defaultRowColour = newDefaultRowColour; } void LevelOnePage::setDefaultRowColour(int newDefaultRowColour) { m_defaultRowColour = newDefaultRowColour; }
void LevelOnePage::setColourTableRemap(int newColourTableRemap) { m_colourTableRemap = newColourTableRemap; } void LevelOnePage::setColourTableRemap(int newColourTableRemap) { m_colourTableRemap = newColourTableRemap; }

View File

@@ -33,23 +33,21 @@ class LevelOnePage : public PageX26Base //: public QObject
//Q_OBJECT //Q_OBJECT
public: public:
using PageX26Base::packet;
using PageX26Base::setPacket;
using PageX26Base::packetExists;
enum CycleTypeEnum { CTcycles, CTseconds }; enum CycleTypeEnum { CTcycles, CTseconds };
LevelOnePage(); LevelOnePage();
// BUG this copy constructor isn't used? Parameter should be LevelOnePage
LevelOnePage(const PageBase &other);
bool isEmpty() const override; bool isEmpty() const override;
QByteArray packet(int packetNumber) const override; QByteArray packet(int y, int d) const override;
QByteArray packet(int packetNumber, int designationCode) const override; bool setPacket(int y, int d, QByteArray pkt) override;
bool packetExists(int packetNumber) const override; bool packetExists(int y, int d) const override;
bool packetExists(int packetNumber, int designationCode) const override;
bool setPacket(int packetNumber, QByteArray packetContents) override;
bool setPacket(int packetNumber, int designationCode, QByteArray packetContents) override;
bool controlBit(int bitNumber) const override; bool setControlBit(int b, bool active) override;
bool setControlBit(int bitNumber, bool active) override;
void clearPage(); void clearPage();
@@ -68,8 +66,8 @@ public:
void setSecondCharSet(int newSecondCharSet); void setSecondCharSet(int newSecondCharSet);
int secondNOS() const { return m_secondNOS; } int secondNOS() const { return m_secondNOS; }
void setSecondNOS(int newSecondNOS); void setSecondNOS(int newSecondNOS);
unsigned char character(int row, int column) const { return m_level1Page[row][column]; } unsigned char character(int r, int c) const { return PageX26Base::packetExists(r) ? PageX26Base::packet(r).at(c) : 0x20; }
void setCharacter(int row, int column, unsigned char newCharacter); void setCharacter(int r, int c, unsigned char newChar);
int defaultScreenColour() const { return m_defaultScreenColour; } int defaultScreenColour() const { return m_defaultScreenColour; }
void setDefaultScreenColour(int newDefaultScreenColour); void setDefaultScreenColour(int newDefaultScreenColour);
int defaultRowColour() const { return m_defaultRowColour; } int defaultRowColour() const { return m_defaultRowColour; }
@@ -106,7 +104,6 @@ public:
void setComposeLinkSubPageCodes(int linkNumber, int newSubPageCodes); void setComposeLinkSubPageCodes(int linkNumber, int newSubPageCodes);
private: private:
unsigned char m_level1Page[25][40];
/* int m_subPageNumber; */ /* int m_subPageNumber; */
int m_cycleValue; int m_cycleValue;
CycleTypeEnum m_cycleType; CycleTypeEnum m_cycleType;

View File

@@ -23,100 +23,62 @@
PageBase::PageBase() PageBase::PageBase()
{ {
// We use nullptrs to keep track of allocated packets, so initialise them this way for (int b=PageBase::C4ErasePage; b<=PageBase::C14NOS; b++)
for (int i=0; i<26; i++) m_controlBits[b] = false;
m_displayPackets[i] = nullptr;
for (int i=0; i<4; i++)
for (int j=0; j<16; j++)
m_designationPackets[i][j] = nullptr;
for (int i=PageBase::C4ErasePage; i<=PageBase::C14NOS; i++)
m_controlBits[i] = false;
}
PageBase::~PageBase()
{
for (int i=0; i<26; i++)
if (m_displayPackets[i] != nullptr)
delete m_displayPackets[i];
for (int i=0; i<4; i++)
for (int j=0; j<16; j++)
if (m_designationPackets[i][j] != nullptr)
delete m_designationPackets[i][j];
} }
bool PageBase::isEmpty() const bool PageBase::isEmpty() const
{ {
for (int i=0; i<26; i++) for (int y=0; y<26; y++)
if (m_displayPackets[i] != nullptr) if (!m_displayPackets[y].isEmpty())
return false; return false;
for (int i=0; i<4; i++) for (int y=0; y<3; y++)
for (int j=0; j<16; j++) for (int d=0; d<16; d++)
if (m_designationPackets[i][j] != nullptr) if (!m_designationPackets[y][d].isEmpty())
return false; return false;
return true; return true;
} }
QByteArray PageBase::packet(int i) const bool PageBase::setPacket(int y, QByteArray pkt)
{ {
if (m_displayPackets[i] == nullptr) m_displayPackets[y] = pkt;
return QByteArray(); // Blank result
return *m_displayPackets[i];
}
QByteArray PageBase::packet(int i, int j) const
{
if (m_designationPackets[i-26][j] == nullptr)
return QByteArray(); // Blank result
return *m_designationPackets[i-26][j];
}
bool PageBase::setPacket(int i, QByteArray packetContents)
{
if (m_displayPackets[i] == nullptr)
m_displayPackets[i] = new QByteArray(40, 0x00);
*m_displayPackets[i] = packetContents;
return true; return true;
} }
bool PageBase::setPacket(int i, int j, QByteArray packetContents) bool PageBase::setPacket(int y, int d, QByteArray pkt)
{ {
if (m_designationPackets[i-26][j] == nullptr) m_designationPackets[y-26][d] = pkt;
m_designationPackets[i-26][j] = new QByteArray(40, 0x00);
*m_designationPackets[i-26][j] = packetContents;
return true; return true;
} }
/* bool PageBase::clearPacket(int y)
bool PageBase::deletePacket(int i)
{ {
if (m_displayPackets[i] != nullptr) { m_displayPackets[y] = QByteArray();
delete m_displayPackets[i];
m_displayPackets[i] = nullptr;
}
return true; return true;
} }
bool PageBase::deletePacket(int i) bool PageBase::clearPacket(int y, int d)
{ {
if (m_designationPackets[i-26][j] != nullptr) { m_designationPackets[y-26][d] = QByteArray();
delete m_designationPackets[i-26][j];
m_designationPackets[i-26][j] = nullptr;
}
return true; return true;
} }
*/
bool PageBase::setControlBit(int bitNumber, bool active) void PageBase::clearAllPackets()
{ {
m_controlBits[bitNumber] = active; for (int y=0; y<26; y++)
clearPacket(y);
for (int y=0; y<3; y++)
for (int d=0; d<16; d++)
clearPacket(y, d);
}
bool PageBase::setControlBit(int b, bool active)
{
m_controlBits[b] = active;
return true; return true;
} }

View File

@@ -31,25 +31,25 @@ public:
enum ControlBitsEnum { C4ErasePage, C5Newsflash, C6Subtitle, C7SuppressHeader, C8Update, C9InterruptedSequence, C10InhibitDisplay, C11SerialMagazine, C12NOS, C13NOS, C14NOS }; enum ControlBitsEnum { C4ErasePage, C5Newsflash, C6Subtitle, C7SuppressHeader, C8Update, C9InterruptedSequence, C10InhibitDisplay, C11SerialMagazine, C12NOS, C13NOS, C14NOS };
PageBase(); PageBase();
virtual ~PageBase();
virtual bool isEmpty() const; virtual bool isEmpty() const;
virtual QByteArray packet(int i) const; virtual QByteArray packet(int y) const { return m_displayPackets[y]; }
virtual QByteArray packet(int i, int j) const; virtual QByteArray packet(int y, int d) const { return m_designationPackets[y-26][d]; }
virtual bool packetExists(int i) const { return m_displayPackets[i] != nullptr; } virtual bool setPacket(int y, QByteArray pkt);
virtual bool packetExists(int i, int j) const { return m_designationPackets[i-26][j] != nullptr; } virtual bool setPacket(int y, int d, QByteArray pkt);
virtual bool setPacket(int i, QByteArray packetContents); virtual bool packetExists(int y) const { return !m_displayPackets[y].isEmpty(); }
virtual bool setPacket(int i, int j, QByteArray packetContents); virtual bool packetExists(int y, int d) const { return !m_designationPackets[y-26][d].isEmpty(); }
// bool deletePacket(int); bool clearPacket(int y);
// bool deletePacket(int, int); bool clearPacket(int y, int d);
void clearAllPackets();
virtual bool controlBit(int bitNumber) const { return m_controlBits[bitNumber]; } virtual bool controlBit(int b) const { return m_controlBits[b]; }
virtual bool setControlBit(int bitNumber, bool active); virtual bool setControlBit(int b, bool active);
private: private:
bool m_controlBits[11]; bool m_controlBits[11];
QByteArray *m_displayPackets[26], *m_designationPackets[4][16]; QByteArray m_displayPackets[26], m_designationPackets[3][16];
}; };
#endif #endif

View File

@@ -21,20 +21,19 @@
#include "pagex26base.h" #include "pagex26base.h"
QByteArray PageX26Base::packetFromEnhancementList(int packetNumber) const QByteArray PageX26Base::packetFromEnhancementList(int p) const
{ {
QByteArray result(40, 0x00); QByteArray result(40, 0x00);
int enhanceListPointer;
X26Triplet lastTriplet; X26Triplet lastTriplet;
for (int i=0; i<13; i++) { for (int t=0; t<13; t++) {
enhanceListPointer = packetNumber*13+i; const int enhanceListPointer = p*13+t;
if (enhanceListPointer < m_enhancements.size()) { if (enhanceListPointer < m_enhancements.size()) {
result[i*3+1] = m_enhancements.at(enhanceListPointer).address(); result[t*3+1] = m_enhancements.at(enhanceListPointer).address();
result[i*3+2] = m_enhancements.at(enhanceListPointer).mode() | ((m_enhancements.at(enhanceListPointer).data() & 1) << 5); result[t*3+2] = m_enhancements.at(enhanceListPointer).mode() | ((m_enhancements.at(enhanceListPointer).data() & 1) << 5);
result[i*3+3] = m_enhancements.at(enhanceListPointer).data() >> 1; result[t*3+3] = m_enhancements.at(enhanceListPointer).data() >> 1;
// If this is the last triplet, get a copy to repeat to the end of the packet // If this is the last triplet, get a copy to repeat to the end of the packet
if (enhanceListPointer == m_enhancements.size()-1) { if (enhanceListPointer == m_enhancements.size()-1) {
@@ -48,32 +47,31 @@ QByteArray PageX26Base::packetFromEnhancementList(int packetNumber) const
} }
} else { } else {
// We've gone past the end of the triplet list, so repeat the Termination Marker to the end // We've gone past the end of the triplet list, so repeat the Termination Marker to the end
result[i*3+1] = lastTriplet.address(); result[t*3+1] = lastTriplet.address();
result[i*3+2] = lastTriplet.mode() | ((lastTriplet.data() & 1) << 5); result[t*3+2] = lastTriplet.mode() | ((lastTriplet.data() & 1) << 5);
result[i*3+3] = lastTriplet.data() >> 1; result[t*3+3] = lastTriplet.data() >> 1;
} }
} }
return result; return result;
} }
void PageX26Base::setEnhancementListFromPacket(int packetNumber, QByteArray packetContents) void PageX26Base::setEnhancementListFromPacket(int p, QByteArray pkt)
{ {
// Preallocate entries in the m_enhancements list to hold our incoming triplets. // Preallocate entries in the m_enhancements list to hold our incoming triplets.
// We write "dummy" reserved 11110 Row Triplets in the allocated entries which then get overwritten by the packet contents. // We write "dummy" reserved 11110 Row Triplets in the allocated entries which then get overwritten by the packet contents.
// This is in case of missing packets so we can keep Local Object pointers valid. // This is in case of missing packets so we can keep Local Object pointers valid.
while (m_enhancements.size() < (packetNumber+1)*13) while (m_enhancements.size() < (p+1)*13)
m_enhancements.append(m_paddingX26Triplet); m_enhancements.append(m_paddingX26Triplet);
int enhanceListPointer;
X26Triplet newX26Triplet; X26Triplet newX26Triplet;
for (int i=0; i<13; i++) { for (int t=0; t<13; t++) {
enhanceListPointer = packetNumber*13+i; const int enhanceListPointer = p*13+t;
newX26Triplet.setAddress(packetContents.at(i*3+1) & 0x3f); newX26Triplet.setAddress(pkt.at(t*3+1) & 0x3f);
newX26Triplet.setMode(packetContents.at(i*3+2) & 0x1f); newX26Triplet.setMode(pkt.at(t*3+2) & 0x1f);
newX26Triplet.setData(((packetContents.at(i*3+3) & 0x3f) << 1) | ((packetContents.at(i*3+2) & 0x20) >> 5)); newX26Triplet.setData(((pkt.at(t*3+3) & 0x3f) << 1) | ((pkt.at(t*3+2) & 0x20) >> 5));
m_enhancements.replace(enhanceListPointer, newX26Triplet); m_enhancements.replace(enhanceListPointer, newX26Triplet);
} }
if (newX26Triplet.mode() == 0x1f && newX26Triplet.address() == 0x3f && newX26Triplet.data() & 0x01) if (newX26Triplet.mode() == 0x1f && newX26Triplet.address() == 0x3f && newX26Triplet.data() & 0x01)

View File

@@ -35,8 +35,8 @@ public:
virtual int maxEnhancements() const =0; virtual int maxEnhancements() const =0;
protected: protected:
QByteArray packetFromEnhancementList(int packetNumber) const; QByteArray packetFromEnhancementList(int p) const;
void setEnhancementListFromPacket(int packetNumber, QByteArray packetContents); void setEnhancementListFromPacket(int p, QByteArray pkt);
bool packetFromEnhancementListNeeded(int n) const { return ((m_enhancements.size()+12) / 13) > n; }; bool packetFromEnhancementListNeeded(int n) const { return ((m_enhancements.size()+12) / 13) > n; };
X26TripletList m_enhancements; X26TripletList m_enhancements;