Skip to content

Commit

Permalink
fixed text and sprite drawing functions, wrote renderers for both
Browse files Browse the repository at this point in the history
  • Loading branch information
mdrobot7 committed Jan 4, 2023
1 parent 95fe762 commit dca8463
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 54 deletions.
56 changes: 32 additions & 24 deletions sdk/draw-2d.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ RenderQueueItem * drawPixel(RenderQueueItem *prev, uint16_t x, uint16_t y, uint8
prev->next = item;
}

item->flags = 1; //Clear bit field, set the update bit
item->flags = RQI_UPDATE;

return item;
}
Expand Down Expand Up @@ -51,7 +51,7 @@ RenderQueueItem * drawLine(RenderQueueItem *prev, uint16_t x1, uint16_t y1, uint
prev->next = item;
}

item->flags = 1; //Clear bit field, set the update bit
item->flags = RQI_UPDATE;

return item;
}
Expand All @@ -78,7 +78,7 @@ RenderQueueItem * drawRectangle(RenderQueueItem *prev, uint16_t x1, uint16_t y1,
prev->next = item;
}

item->flags = 1; //Clear bit field, set the update bit
item->flags = RQI_UPDATE;

return item;
}
Expand Down Expand Up @@ -120,7 +120,7 @@ RenderQueueItem * drawCircle(RenderQueueItem *prev, uint16_t x, uint16_t y, uint
prev->next = item;
}

item->flags = 1; //Clear bit field, set the update bit
item->flags = RQI_UPDATE;

return item;
}
Expand Down Expand Up @@ -151,7 +151,7 @@ RenderQueueItem * drawFilledRectangle(RenderQueueItem *prev, uint16_t x1, uint16
prev->next = item;
}

item->flags = 1; //Clear bit field, set the update bit
item->flags = RQI_UPDATE;

return item;
}
Expand Down Expand Up @@ -181,7 +181,7 @@ RenderQueueItem * drawFilledCircle(RenderQueueItem *prev, uint16_t x, uint16_t y
prev->next = item;
}

item->flags = 1; //Clear bit field, set the update bit
item->flags = RQI_UPDATE;

return item;
}
Expand Down Expand Up @@ -211,7 +211,7 @@ RenderQueueItem * fillScreen(RenderQueueItem *prev, uint8_t obj[FRAME_HEIGHT][FR
prev->next = item;
}

item->flags = 1; //Clear bit field, set the update bit
item->flags = RQI_UPDATE;

return item;
}
Expand All @@ -227,7 +227,7 @@ void clearScreen() {
item = item->next;
}

background.flags = 1;
background.flags = RQI_UPDATE;
}


Expand All @@ -236,19 +236,26 @@ void clearScreen() {
==============================
*/
uint8_t *font = (uint8_t *)cp437; //The current font in use by the system
#define CHAR_WIDTH 5
#define CHAR_HEIGHT 8

//add word wrap
RenderQueueItem * drawText(RenderQueueItem *prev, uint16_t x, uint16_t y, char *str, uint8_t color, uint8_t scale) {
RenderQueueItem * drawText(RenderQueueItem *prev, uint16_t x1, uint16_t y, uint16_t x2, char *str,
uint8_t color, uint16_t bgColor, bool wrap, uint8_t strSizeOverride) {
RenderQueueItem *item = (RenderQueueItem *) malloc(sizeof(RenderQueueItem));
if(item == NULL) return NULL;

item->type = 'c';
item->x1 = x;
item->x1 = x1;
item->y1 = y;
item->x2 = x2;
item->y2 = bgColor;
item->color = color;
item->obj = str;

if(strSizeOverride) {
item->obj = (uint8_t *) malloc((strSizeOverride + 1)*sizeof(char));
}
else {
item->obj = (uint8_t *) malloc((strlen(str) + 1)*sizeof(char));
}
strcpy(item->obj, str);

if(prev == NULL) {
item->next = NULL; //Set *next to NULL, means it is the last item in linked list
Expand All @@ -261,7 +268,8 @@ RenderQueueItem * drawText(RenderQueueItem *prev, uint16_t x, uint16_t y, char *
prev->next = item;
}

item->flags = 1; //Clear bit field, set the update bit
item->flags = RQI_UPDATE;
if(wrap) item->flags |= RQI_WORDWRAP;

return item;
}
Expand All @@ -280,10 +288,10 @@ RenderQueueItem * drawSprite(RenderQueueItem *prev, uint8_t *sprite, uint16_t x,
if(item == NULL) return NULL;

item->type = 's';
item->x1 = x; //Makes sure the point closer to (0,0) is assigned to (x,y) and not (w,h)
item->x1 = x;
item->y1 = y;
item->x2 = x + dimX;
item->y2 = y + dimY;
item->x2 = dimX;
item->y2 = dimY;
item->color = nullColor;
item->obj = sprite;

Expand All @@ -298,7 +306,7 @@ RenderQueueItem * drawSprite(RenderQueueItem *prev, uint8_t *sprite, uint16_t x,
prev->next = item;
}

item->flags = 1; //Clear bit field, set the update bit
item->flags = RQI_UPDATE;

return item;
}
Expand All @@ -317,20 +325,20 @@ void setBackground(uint8_t obj[FRAME_HEIGHT][FRAME_WIDTH], uint8_t color) {
else { //set the background to a picture/sprite/something not a solid color
background.obj = (uint8_t *)obj;
}
background.flags |= 1u;
background.flags |= RQI_UPDATE;
}

//Set item to be hidden (true = hidden, false = showing)
void setHidden(RenderQueueItem *item, uint8_t hidden) {
if(hidden) item->flags |= (1u << 1);
else item->flags &= ~(1u << 1);
item->flags |= 1u; //Set the update bit
item->flags |= RQI_UPDATE;
}

//Set the color for item.
void setColor(RenderQueueItem *item, uint8_t color) {
item->color = color;
item->flags |= 1u; //Set the update bit
item->flags |= RQI_UPDATE;
}

//Set the coordinates for item. Set parameter to -1 to leave it unchanged.
Expand All @@ -339,11 +347,11 @@ void setCoordinates(RenderQueueItem *item, int16_t x1, int16_t y1, int16_t x2, i
if(y1 >= 0) item->y1 = y1;
if(x2 >= 0) item->x2 = x2;
if(y2 >= 0) item->y2 = y2;
item->flags |= 1u; //Set the update bit
item->flags |= RQI_UPDATE;
}

//Permanently remove item from the render queue.
void removeItem(RenderQueueItem *item) {
item->type = 'n';
item->flags |= 1u; //Set the update bit
item->flags |= RQI_UPDATE;
}
2 changes: 1 addition & 1 deletion sdk/font.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/

const uint8_t cp437[256][8] = {
const uint8_t cp437[256][CHAR_HEIGHT] = {
{ 0b00000,
0b00000,
0b00000,
Expand Down
4 changes: 2 additions & 2 deletions sdk/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ static void initSecondCore();
static void updateFramePtr();


int initDisplay(uint8_t autoRenderEn) {
int initDisplay(bool autoRenderEn) {
//Clock configuration -- 120MHz system clock frequency
clocks_init();
set_sys_clock_pll(1440000000, 6, 2); //VCO frequency (MHz), PD1, PD2 -- see vcocalc.py

autoRender = autoRenderEn;
autoRender = (uint8_t)autoRenderEn;

initController();

Expand Down
15 changes: 11 additions & 4 deletions sdk/pico-vga.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

/*
Structs
Expand Down Expand Up @@ -106,14 +107,19 @@ extern volatile Controller C4;
#define COLOR_PURPLE 0b10000010

//RenderQueueItem.flags macros
#define RQI_UPDATE (1 << 0)
#define RQI_HIDDEN (1 << 1)
#define RQI_UPDATE (1 << 0)
#define RQI_HIDDEN (1 << 1)
#define RQI_WORDWRAP (1 << 2)

#define RQI_UPDATE_GET(b) (b >> RQI_UPDATE) & 1u
#define RQI_HIDDEN_GET(b) (b >> RQI_HIDDEN) & 1u
#define RQI_WORDWRAP_GET(b) (b >> RQI_WORDWRAP) & 1u

/*
Functions
=========================
*/
int initDisplay(uint8_t autoRenderEn);
int initDisplay(bool autoRenderEn);
void updateDisplay();

extern volatile RenderQueueItem background;
Expand All @@ -140,7 +146,7 @@ void clearScreen();
RenderQueueItem * drawSprite(RenderQueueItem* prev, uint8_t *sprite, uint16_t x, uint16_t y, uint16_t dimX, uint16_t dimY, uint8_t nullColor, uint8_t scale);

//Draws the chars from the default character library. Dimensions are 5x8 pixels each.
RenderQueueItem * drawText(RenderQueueItem* prev, uint16_t x, uint16_t y, char *str, uint8_t color, uint8_t scale);
RenderQueueItem * drawText(RenderQueueItem *prev, uint16_t x1, uint16_t y, uint16_t x2, char *str, uint8_t color, uint16_t bgColor, bool wrap, uint8_t strSizeOverride);
void setTextFont(uint8_t *newFont);

//Modifiers:
Expand All @@ -154,5 +160,6 @@ void removeItem(RenderQueueItem *item);
uint8_t HTMLTo8Bit(uint32_t color);
uint8_t rgbTo8Bit(uint8_t r, uint8_t g, uint8_t b);
uint8_t hsvToRGB(uint8_t hue, uint8_t saturation, uint8_t value);
uint8_t invertColor(uint8_t color);

#endif
51 changes: 28 additions & 23 deletions sdk/render.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "sdk.h"
#include "font.h"

#include "pico/multicore.h"
#include "pico/malloc.h"
Expand All @@ -20,7 +19,7 @@ static volatile uint8_t update = 0;

void updateDisplay() {
update = 1;
if(autoRender) background.flags |= 1u; //force-update in autoRender mode
if(autoRender) background.flags |= RQI_UPDATE; //force-update in autoRender mode
}

//Checks for out-of-bounds coordinates and writes to the frame
Expand All @@ -29,6 +28,10 @@ static inline void writePixel(uint16_t y, uint16_t x, uint8_t color) {
else frame[y][x] = color;
}

static inline uint8_t getFontBit(uint8_t c, uint8_t x, uint8_t y) {
return *(font + CHAR_HEIGHT*c + y) >> (CHAR_WIDTH - x + 1) & 1u;
}

void render() {
multicore_fifo_push_blocking(13); //tell core 0 that everything is ok/it's running

Expand All @@ -39,20 +42,20 @@ void render() {
if(autoRender) {
item = (RenderQueueItem *) &background;
//look for the first item that needs an update, render that item and everything after it
while(!(item->flags & 1u)) {
while(!(item->flags & RQI_UPDATE)) {
previousItem = item;
item = item->next;
if(item == NULL) item = (RenderQueueItem *) &background;
}
if(((item->flags >> 1) & 1u) || item->type == 'n') item = (RenderQueueItem *) &background; //if the update is to hide an item, rerender the whole thing
if(RQI_HIDDEN_GET(item->flags) || item->type == 'n') item = (RenderQueueItem *) &background; //if the update is to hide an item, rerender the whole thing
}
else { //manual rendering
while(!update); //wait until it's told to update the display
item = (RenderQueueItem *) &background;
}

while(item != NULL) {
if(!((item->flags >> 1) & 1u)) {
if(!RQI_HIDDEN_GET(item->flags)) {
switch(item->type) {
case 'p': //Pixel
writePixel(item->y1, item->x1, item->color);
Expand Down Expand Up @@ -103,28 +106,30 @@ void render() {
}
break;
case 'c': //Character/String
/*for(uint16_t i = 0; item->obj[i] != '\0'; i++) {
x = item->x1 + (i*CHAR_WIDTH);
for(uint8_t j; j < CHAR_WIDTH; j++) {
//font[][] is a bit array, so check if a particular bit is true, if so, set the pixel array
if(((*font)[item->obj[i]][currentLine - item->y1]) & ((1 << (CHAR_WIDTH - 1)) >> j)) {
frame[l][x + j] = item->color;
//x1, y1 = top left corner, x2 = right side (for word wrap), y2 = background color
uint16_t x = item->x1;
uint16_t y = item->y1;
for(uint16_t c = 0; item->obj[c] != '\0'; c++) {
for(uint8_t i = 0; i < CHAR_HEIGHT; i++) {
for(uint8_t j = 0; j < CHAR_WIDTH; j++) {
writePixel(y + i, x + j, getFontBit(item->obj[c], i, j) ? item->color : item->y2);
}
}
}*/
x += CHAR_WIDTH + 1;
if(RQI_WORDWRAP_GET(item->flags) && x + CHAR_WIDTH >= item->x2) {
x = item->x1;
y += CHAR_HEIGHT;
}
}
break;
case 's': //Sprites
/*for(uint16_t i = item->x1; i < item->x2; i++) {
//Skip changing the pixel if it's set to the COLOR_NULL value
if(*(item->obj + ((currentLine - item->y1)*(item->x2 - item->x1)) + i) == COLOR_NULL) continue;
if(item->color == 0) {
//*(original mem location + (currentRowInArray * nColumns) + currentColumnInArray)
frame[l][i] = *(item->obj + ((currentLine - item->y1)*(item->x2 - item->x1)) + i);
}
else {
frame[l][i] = item->color;
for(uint16_t i = 0; i < item->y2; i++) {
for(uint16_t j = 0; j < item->x2; j++) {
if(*(item->obj + i*item->x2 + j) != item->color) {
writePixel(item->y1 + i, item->x1 + j, *(item->obj + i*item->x2 + j));
}
}
}*/
}
break;
case 'f': //Fill the screen
for(uint16_t y = 0; y < FRAME_HEIGHT; y++) {
Expand Down Expand Up @@ -154,7 +159,7 @@ void render() {
}
}

item->flags &= ~(1u); //Clear the update bit
item->flags &= ~RQI_UPDATE; //Clear the update bit
previousItem = item;
item = item->next;
}
Expand Down
2 changes: 2 additions & 0 deletions sdk/sdk.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ extern uint8_t autoRender;
extern volatile RenderQueueItem background; //First element of the linked list, can be reset to any background
extern volatile RenderQueueItem *lastItem; //Last item in linked list, used to set *last in RenderQueueItem

#define CHAR_WIDTH 5
#define CHAR_HEIGHT 8
extern uint8_t *font; //The current font in use by the system

inline void busyWait(uint64_t n) {
Expand Down
4 changes: 4 additions & 0 deletions sdk/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,8 @@ uint8_t hsvToRGB(uint8_t hue, uint8_t saturation, uint8_t value) {
else return 0;

return rgbTo8Bit(r, g, b);
}

uint8_t invertColor(uint8_t color) {
return 255 - color;
}

0 comments on commit dca8463

Please sign in to comment.