Skip to content
Snippets Groups Projects
Unverified Commit ba67e116 authored by CNLohr's avatar CNLohr Committed by GitHub
Browse files

Merge pull request #110 from recallmenot/SSD1306_drawimage

SSD1306 drawImage
parents 626a40bf f9eb8b5a
No related branches found
No related tags found
No related merge requests found
/*
The bomb illustration has been drawn and provided by [DoubleWaffleCakes](https://www.reddit.com/user/DoubleWaffleCakes/).
*/
const unsigned char bomb_i_stripped[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x48, 0x00,
0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x03, 0xfe, 0x00,
0x00, 0x0f, 0xff, 0x80, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x1f, 0xff, 0xc0,
0x00, 0x3f, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x73, 0x9f, 0xf0,
0x00, 0x73, 0x9f, 0xf0, 0x00, 0x73, 0x9f, 0xf0, 0x00, 0x73, 0x9f, 0xf0,
0x00, 0x73, 0x9f, 0xf0, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xe0,
0x00, 0x1f, 0xff, 0xc0, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0x80,
0x00, 0x13, 0xe0, 0x40, 0x00, 0x20, 0xc0, 0x20, 0x00, 0x7f, 0xff, 0xe0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned int bomb_i_stripped_len = 128;
......@@ -17,6 +17,8 @@
#include "ssd1306_i2c.h"
#include "ssd1306.h"
#include "bomb.h"
int main()
{
// 48MHz internal clock
......@@ -42,7 +44,7 @@ int main()
printf("Looping on test modes...");
while(1)
{
for(uint8_t mode=0;mode<(SSD1306_H>32?8:7);mode++)
for(uint8_t mode=0;mode<(SSD1306_H>32?9:8);mode++)
{
// clear buffer for next mode
ssd1306_setbuf(0);
......@@ -85,8 +87,11 @@ int main()
else
ssd1306_fillCircle(x, SSD1306_H/2, 15, 1);
break;
case 4:
printf("Image\n\r");
ssd1306_drawImage(0, 0, bomb_i_stripped, 32, 32, 0);
break;
case 5:
printf("Unscaled Text\n\r");
ssd1306_drawstr(0,0, "This is a test", 1);
ssd1306_drawstr(0,8, "of the emergency", 1);
......@@ -102,19 +107,19 @@ int main()
ssd1306_xorrect(SSD1306_W/2, 0, SSD1306_W/2, SSD1306_W);
break;
case 5:
case 6:
printf("Scaled Text 1, 2\n\r");
ssd1306_drawstr_sz(0,0, "sz 8x8", 1, fontsize_8x8);
ssd1306_drawstr_sz(0,16, "16x16", 1, fontsize_16x16);
break;
case 6:
case 7:
printf("Scaled Text 4\n\r");
ssd1306_drawstr_sz(0,0, "32x32", 1, fontsize_32x32);
break;
case 7:
case 8:
printf("Scaled Text 8\n\r");
ssd1306_drawstr_sz(0,0, "64", 1, fontsize_64x64);
break;
......
......@@ -240,6 +240,77 @@ void ssd1306_xorPixel(uint8_t x, uint8_t y)
ssd1306_buffer[addr] ^= (1<<(y&7));
}
/*
* draw a an image from an array, directly into to the display buffer
* the color modes allow for overwriting and even layering (sprites!)
*/
void ssd1306_drawImage(uint8_t x, uint8_t y, const unsigned char* input, uint8_t width, uint8_t height, uint8_t color_mode) {
uint8_t x_absolute;
uint8_t y_absolute;
uint8_t pixel;
uint8_t bytes_to_draw = width / 8;
uint16_t buffer_addr;
for (uint8_t line = 0; line < height; line++) {
y_absolute = y + line;
if (y_absolute >= SSD1306_H) {
break;
}
// SSD1306 is in vertical mode, yet we want to draw horizontally, which necessitates assembling the output bytes from the input data
// bitmask for current pixel in vertical (output) byte
uint8_t v_mask = 1 << (y_absolute & 7);
for (uint8_t byte = 0; byte < bytes_to_draw; byte++) {
uint8_t input_byte = input[byte + line * bytes_to_draw];
for (pixel = 0; pixel < 8; pixel++) {
x_absolute = x + 8 * (bytes_to_draw - byte) + pixel;
if (x_absolute >= SSD1306_W) {
break;
}
// looking at the horizontal display, we're drawing bytes bottom to top, not left to right, hence y / 8
buffer_addr = x_absolute + SSD1306_W * (y_absolute / 8);
// state of current pixel
uint8_t input_pixel = input_byte & (1 << pixel);
switch (color_mode) {
case 0:
// write pixels as they are
ssd1306_buffer[buffer_addr] = (ssd1306_buffer[buffer_addr] & ~v_mask) | (input_pixel ? v_mask : 0);
break;
case 1:
// write pixels after inversion
ssd1306_buffer[buffer_addr] = (ssd1306_buffer[buffer_addr] & ~v_mask) | (!input_pixel ? v_mask : 0);
break;
case 2:
// 0 clears pixel
ssd1306_buffer[buffer_addr] &= input_pixel ? 0xFF : ~v_mask;
break;
case 3:
// 1 sets pixel
ssd1306_buffer[buffer_addr] |= input_pixel ? v_mask : 0;
break;
case 4:
// 0 sets pixel
ssd1306_buffer[buffer_addr] |= !input_pixel ? v_mask : 0;
break;
case 5:
// 1 clears pixel
ssd1306_buffer[buffer_addr] &= input_pixel ? ~v_mask : 0xFF;
break;
}
}
#if SSD1306_LOG_IMAGE == 1
printf("%02x ", input_byte);
#endif
}
#if SSD1306_LOG_IMAGE == 1
printf("\n\r");
#endif
}
}
/*
* fast vert line
*/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment