|
| 1 | +#include <cstddef> |
| 2 | +#include <string.h> |
| 3 | +#include "device.h" |
| 4 | +#include "MonochromeScreenPatch.h" |
| 5 | +#include "ProgramVector.h" |
| 6 | +#include "PatchProcessor.h" |
| 7 | +#include "ServiceCall.h" |
| 8 | + |
| 9 | +#include "font.c" // todo load as resource |
| 10 | + |
| 11 | +PatchProcessor* getInitialisingPatchProcessor(); |
| 12 | + |
| 13 | +void onDrawCallback(uint8_t* pixels, uint16_t width, uint16_t height){ |
| 14 | + MonochromeScreenPatch* patch = (MonochromeScreenPatch*)getInitialisingPatchProcessor()->patch; |
| 15 | + if(patch != NULL){ |
| 16 | + MonochromeScreenBuffer screen(width, height); |
| 17 | + screen.setBuffer(pixels); |
| 18 | + patch->processScreen(screen); |
| 19 | + } |
| 20 | +} |
| 21 | + |
| 22 | +MonochromeScreenPatch::MonochromeScreenPatch(){ |
| 23 | + void* drawArgs[] = {(void*)SYSTEM_FUNCTION_DRAW, (void*)&onDrawCallback}; |
| 24 | + getProgramVector()->serviceCall(OWL_SERVICE_REGISTER_CALLBACK, drawArgs, 2); |
| 25 | +} |
| 26 | + |
| 27 | +MonochromeScreenPatch::~MonochromeScreenPatch(){} |
| 28 | + |
| 29 | +void drawMessage(MonochromeScreenBuffer& screen){ |
| 30 | + ProgramVector* pv = getProgramVector(); |
| 31 | + if(pv->message != NULL){ |
| 32 | + screen.setTextSize(1); |
| 33 | + screen.setTextWrap(true); |
| 34 | + screen.print(0, 26, pv->message); |
| 35 | + } |
| 36 | +} |
| 37 | +void drawTitle(const char* title, MonochromeScreenBuffer& screen){ |
| 38 | + // draw title |
| 39 | + screen.setTextSize(2); |
| 40 | + screen.print(0, 16, title); |
| 41 | +} |
| 42 | + |
| 43 | +void MonochromeScreenPatch::processScreen(MonochromeScreenBuffer& screen){ |
| 44 | + // screen.clear(); |
| 45 | + const char* title = getInitialisingPatchProcessor()->getPatchName(); |
| 46 | + drawTitle(title, screen); |
| 47 | + drawMessage(screen); |
| 48 | + // const char title[] = "KickBox"; |
| 49 | + // screen.setTextSize(2); |
| 50 | + // screen.print(0, 16, title); |
| 51 | +} |
| 52 | + |
| 53 | + |
| 54 | +template<> |
| 55 | +Colour MonochromeScreenBuffer::getPixel(unsigned int x, unsigned int y){ |
| 56 | + if(x >= width || y >= height) |
| 57 | + return 0; |
| 58 | + uint8_t ucByteOffset = 0; |
| 59 | + uint16_t usiArrayLoc = 0; |
| 60 | + // Determine array location |
| 61 | + usiArrayLoc = (y/8)+(x*8); |
| 62 | + // Determine byte offset |
| 63 | + ucByteOffset = y-((uint8_t)(y/8)*8); |
| 64 | + // Return bit state from buffer |
| 65 | + return pixels[usiArrayLoc] & (1 << ucByteOffset); |
| 66 | + // return pixels[y*width+x]; |
| 67 | +} |
| 68 | + |
| 69 | +template<> |
| 70 | +void MonochromeScreenBuffer::setPixel(unsigned int x, unsigned int y, Colour c){ |
| 71 | + if(x < width && y < height){ |
| 72 | + uint8_t ucByteOffset = 0; |
| 73 | + uint16_t usiArrayLoc = 0; |
| 74 | + // Determine array location |
| 75 | + usiArrayLoc = (y/8)+(x*8); |
| 76 | + // Determine byte offset |
| 77 | + ucByteOffset = y-((uint8_t)(y/8)*8); |
| 78 | + // Set pixel in buffer |
| 79 | + if(c == BLACK) |
| 80 | + pixels[usiArrayLoc] &= ~(1 << ucByteOffset); |
| 81 | + else |
| 82 | + pixels[usiArrayLoc] |= (1 << ucByteOffset); |
| 83 | + } |
| 84 | +} |
| 85 | + |
| 86 | +template<> |
| 87 | +void MonochromeScreenBuffer::invertPixel(unsigned int x, unsigned int y){ |
| 88 | + if(x < width && y < height){ |
| 89 | + uint8_t ucByteOffset = 0; |
| 90 | + uint16_t usiArrayLoc = 0; |
| 91 | + // Determine array location |
| 92 | + usiArrayLoc = (y/8)+(x*8); |
| 93 | + // Determine byte offset |
| 94 | + ucByteOffset = y-((uint8_t)(y/8)*8); |
| 95 | + uint8_t pixel = (1 << ucByteOffset); |
| 96 | + // Set pixel in buffer |
| 97 | + if(pixels[usiArrayLoc] & pixel) |
| 98 | + pixels[usiArrayLoc] &= ~pixel; |
| 99 | + else |
| 100 | + pixels[usiArrayLoc] |= pixel; |
| 101 | + } |
| 102 | +} |
| 103 | + |
| 104 | +template<> |
| 105 | +void MonochromeScreenBuffer::fade(uint16_t steps){ |
| 106 | + // for(unsigned int i=0; i<height*width; ++i) |
| 107 | + // pixels[i] = |
| 108 | + // (((pixels[i] & RED) >> steps) & RED) | |
| 109 | + // (((pixels[i] & GREEN) >> steps) & GREEN) | |
| 110 | + // (((pixels[i] & BLUE) >> steps) & BLUE); |
| 111 | + // todo! |
| 112 | + |
| 113 | + // todo: update contrast setting |
| 114 | +} |
| 115 | + |
| 116 | +template<> |
| 117 | +void MonochromeScreenBuffer::fill(Colour c) { |
| 118 | + memset(pixels, c, height*width/8); |
| 119 | + // for(unsigned int i=0; i<height*width; ++i) |
| 120 | + // pixels[i] = c; |
| 121 | +} |
| 122 | + |
| 123 | +// Draw a character |
| 124 | +template<typename Colour> |
| 125 | +void ScreenBuffer<Colour>::drawChar(uint16_t x, uint16_t y, unsigned char ch, |
| 126 | + Colour c, Colour bg, uint8_t size) { |
| 127 | + // if((x >= width) || // Clip right |
| 128 | + // (y >= height) || // Clip bottom |
| 129 | + // ((x + 6 * size - 1) < 0) || // Clip left |
| 130 | + // ((y + 8 * size - 1) < 0)) // Clip top |
| 131 | + // return; |
| 132 | + y -= 8 * size; // set origin to bottom left |
| 133 | + for(int8_t i=0; i<6; i++ ) { |
| 134 | + uint8_t line; |
| 135 | + if (i == 5) |
| 136 | + line = 0x0; |
| 137 | + else |
| 138 | + line = font[(ch*5)+i]; |
| 139 | + for (int8_t j = 0; j<8; j++) { |
| 140 | + if (line & 0x1) { |
| 141 | + if (size == 1) // default size |
| 142 | + setPixel(x+i, y+j, c); |
| 143 | + else { // big size |
| 144 | + fillRectangle(x+(i*size), y+(j*size), size, size, c); |
| 145 | + } |
| 146 | + } else if (bg != c) { |
| 147 | + if (size == 1) // default size |
| 148 | + setPixel(x+i, y+j, bg); |
| 149 | + else { // big size |
| 150 | + fillRectangle(x+i*size, y+j*size, size, size, bg); |
| 151 | + } |
| 152 | + } |
| 153 | + line >>= 1; |
| 154 | + } |
| 155 | + } |
| 156 | +} |
| 157 | + |
| 158 | +// Draw a character rotated 90 degrees |
| 159 | +template<typename Colour> |
| 160 | +void ScreenBuffer<Colour>::drawRotatedChar(uint16_t x, uint16_t y, unsigned char ch, |
| 161 | + Colour c, Colour bg, uint8_t size) { |
| 162 | + // if((x >= width) || // Clip right |
| 163 | + // (y >= height) || // Clip bottom |
| 164 | + // ((x + 8 * size - 1) < 0) || // Clip left |
| 165 | + // ((y + 6 * size - 1) < 0)) // Clip top |
| 166 | + // return; |
| 167 | + // for (int8_t i=5; i>=0; i-- ) { |
| 168 | + for (int8_t i=0; i<6; i++ ) { |
| 169 | + uint8_t line; |
| 170 | + if (i == 5) |
| 171 | + line = 0x0; |
| 172 | + else |
| 173 | + line = font[(ch*5)+i]; |
| 174 | + // for (int8_t j = 0; j<8; j++) { |
| 175 | + for (int8_t j = 7; j>=0; j--) { |
| 176 | + if (line & 0x1) { |
| 177 | + if (size == 1) // default size |
| 178 | + setPixel(y+i, x+j, c); |
| 179 | + else { // big size |
| 180 | + // fillRectangle(x+(i*size), y+(j*size), size, size, c); |
| 181 | + fillRectangle(y+(j*size), x+(i*size), size, size, c); |
| 182 | + } |
| 183 | + } else if (bg != c) { |
| 184 | + if (size == 1) // default size |
| 185 | + setPixel(y+i, x+j, bg); |
| 186 | + else { // big size |
| 187 | + // fillRectangle(x+i*size, y+j*size, size, size, bg); |
| 188 | + fillRectangle(y+j*size, x+i*size, size, size, bg); |
| 189 | + } |
| 190 | + } |
| 191 | + line >>= 1; |
| 192 | + } |
| 193 | + } |
| 194 | +} |
0 commit comments