ELEC2645 (2018/19) / Mbed 2 deprecated el17ajf

Dependencies:   mbed

Fork of el17ajf by Angus Findlay

Graphics/Graphics.cpp

Committer:
el17ajf
Date:
2019-04-13
Revision:
33:0a5bc157bbf8
Parent:
31:69fedaa9b171

File content as of revision 33:0a5bc157bbf8:

#include "Graphics.h"
#include "Grid.h"
#include "Math.h"

namespace Graphics {
    
    // "private" methods
    void drawPoint(int x, int y);
    void drawLine(int x1, int y1, int x2, int y2);
    void drawBox(int x1, int y1, int x2, int y2);
    void drawDottedLine(int x1, int y1, int x2, int y2);
    bool light_on;
    
    int offset_x = 0, offset_y = 0;
    
    namespace LCD {
        const int MAX_X = 83;
        const int MAX_Y = 47;
        
        N5110 * lcd;
        
        int YToLcdX(int y) {
            int lcd_x = y + offset_y;
            
            if (lcd_x < 0)
                return 0;
            else if (lcd_x > MAX_X)
                return MAX_X;
            else
                return lcd_x;
        }
        
        int XToLcdY(int x) {
            int lcd_y = MAX_Y - x + offset_x;
            
            if (lcd_y < 0)
                return 0;
            else if (lcd_y > MAX_Y)
                return MAX_Y;
            else
                return lcd_y;
        }
    };
    
    void init() {
        LCD::lcd = new N5110(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);
        LCD::lcd->init();
        LCD::lcd->setContrast(0.5);
        LCD::lcd->setBrightness(0);
        light_on = false;
    }
    
    void deinit() {
        delete LCD::lcd;
    }
    
    void clear() {
        LCD::lcd->clear();
    }
    
    void render() {
        offset_x = Math::lerp(offset_x, 0, 0.1);
        offset_y = Math::lerp(offset_y, 0, 0.1);
        LCD::lcd->refresh();
    }
    
    void toggleLight() {
        light_on = !light_on;
        LCD::lcd->setBrightness(light_on ? 1 : 0);
    }
    
    void drawPoint(int x, int y) {
        LCD::lcd->setPixel(
            LCD::YToLcdX(y),
            LCD::XToLcdY(x),
            true
        );
    }
    
    void drawLine(int x1, int y1, int x2, int y2) {
        LCD::lcd->drawLine(
            LCD::YToLcdX(y1),
            LCD::XToLcdY(x1),
            LCD::YToLcdX(y2),
            LCD::XToLcdY(x2),
            1 // not dotted
        );
    }
    
    void drawDottedLine(int x1, int y1, int x2, int y2) {
        LCD::lcd->drawLine(
            LCD::YToLcdX(y1),
            LCD::XToLcdY(x1),
            LCD::YToLcdX(y2),
            LCD::XToLcdY(x2),
            2 // dotted
        );
    }
    
    void drawBox(int x1, int y1, int x2, int y2) {
        drawLine(x1, y1, x2, y1);
        drawLine(x2, y1, x2, y2);
        drawLine(x2, y2, x1, y2);
        drawLine(x1, y2, x1, y1);
    }
    
    namespace Game {
        int getBlockSize() {
            int block_width = SCREEN_WIDTH / Grid::GRID_WIDTH;
            int block_height = SCREEN_HEIGHT / (Grid::GRID_HEIGHT - Grid::HIDDEN_HEIGHT);    
            return block_width < block_height ? block_width : block_height;
        }
        
        int getBorderSizeX(int block_size) {
            return (SCREEN_WIDTH - Grid::GRID_WIDTH * block_size) / 2;
        }
        
        int getBorderSizeY(int block_size) {
            return (SCREEN_HEIGHT - (Grid::GRID_HEIGHT - Grid::HIDDEN_HEIGHT) * block_size) / 2;
        }
        
        int BLOCK_SIZE = getBlockSize();
        int BORDER_SIZE_X = getBorderSizeX(BLOCK_SIZE);
        int BORDER_SIZE_Y = getBorderSizeY(BLOCK_SIZE);
        
        int gridYToY(int grid_y) {
            return (grid_y - Grid::HIDDEN_HEIGHT) * BLOCK_SIZE + BORDER_SIZE_Y;
        }
        
        int gridXToX(int grid_x) {
            return grid_x * BLOCK_SIZE + BORDER_SIZE_X;
        }
        
        void drawBlock(int grid_x, int grid_y) {
            // screen coords
            int x = gridXToX(grid_x);
            int y = gridYToY(grid_y);
            drawBox(x, y, x + BLOCK_SIZE - 1, y + BLOCK_SIZE - 1);
        }
        
        void drawStripedBlock(int grid_x, int grid_y) {
            // screen coords
            int x = gridXToX(grid_x);
            int y = gridYToY(grid_y);
            drawBox(x, y, x + BLOCK_SIZE - 1, y + BLOCK_SIZE - 1);
            drawLine(x, y, x + BLOCK_SIZE - 1, y + BLOCK_SIZE - 1); 
        }
        
        void drawBorder() {
            int min_x = gridXToX(0) - 1;
            int max_x = gridXToX(Grid::GRID_WIDTH - 1) + BLOCK_SIZE - 1 + 1;
            int min_y = gridYToY(0) - 1;
            int max_y = gridYToY(Grid::GRID_HEIGHT - 1) + BLOCK_SIZE - 1 + 1;
            
            drawDottedLine(min_x, min_y, min_x, max_y);
            drawDottedLine(min_x, max_y, max_x, max_y);
            drawDottedLine(max_x, max_y, max_x, min_y);
        }
        
        void shake(int dx, int dy) {
            offset_x += dx;
            offset_y += dy;
        }
    };

    namespace UI {
        void drawBorder(int x1, int y1, int x2, int y2) {
            drawBox(x1, y1, x2, y2);
        }
        
        void drawChar(int x, int y, char c);
        
        void drawText(int x, int y, const char * text) {
            for (int i = 0; text[i] != '\0'; i++) {
                drawChar(x + i * (CHAR_WIDTH + CHAR_SPACE), y, text[i]);
            }
        }
        
        void drawSprite(Bitmap * bitmap, int x, int y) {
            (*bitmap).render(*LCD::lcd, x, y);
        }
        
        void drawChar(int x, int y, char c) {
            int binc = 0b1111111111111111111111111111;
            
            switch (c) {
                case 'a': case 'A': binc = 0b0000011010011001011100000000; break;
                case 'b': case 'B': binc = 0b1000111010011001111100000000; break;
                case 'c': case 'C': binc = 0b0000011110001000111100000000; break;
                case 'd': case 'D': binc = 0b0001011110011001111100000000; break;
                case 'e': case 'E': binc = 0b0000111110011000011000000000; break;
                case 'f': case 'F': binc = 0b0000001101000100011101000000; break;
                case 'g': case 'G': binc = 0b0000011110011001111100010110; break;
                case 'h': case 'H': binc = 0b1000111010011001100100000000; break;
                case 'i': case 'I': binc = 0b0100000001000100001000000000; break;
                case 'j': case 'J': binc = 0b0010000000100010001001000000; break;
                case 'k': case 'K': binc = 0b1000101011001010101000000000; break;
                case 'l': case 'L': binc = 0b0100010001000100001000000000; break;
                case 'm': case 'M': binc = 0b0000111110111001100100000000; break;
                case 'n': case 'N': binc = 0b0000111010011001100100000000; break;
                case 'o': case 'O': binc = 0b0000111110011001111100000000; break;
                case 'p': case 'P': binc = 0b0000111010011001111110000000; break;
                case 'q': case 'Q': binc = 0b0000011110011001111100010001; break;
                case 'r': case 'R': binc = 0b0000001001000100010000000000; break;
                case 's': case 'S': binc = 0b0000011111000011111000000000; break;
                case 't': case 'T': binc = 0b0100111001000100001000000000; break;
                case 'u': case 'U': binc = 0b0000100110011001011100000000; break;
                case 'v': case 'V': binc = 0b0000100110011001011000000000; break;
                case 'w': case 'W': binc = 0b0000100110011011111100000000; break;
                case 'x': case 'X': binc = 0b0000100101000010100100000000; break;
                case 'y': case 'Y': binc = 0b0000100110011001011100010110; break;
                case 'z': case 'Z': binc = 0b0000111000111100011100000000; break;
                case '0': binc = 0b0111100110011001111000000000; break;
                case '1': binc = 0b0010011000100010011100000000; break;
                case '2': binc = 0b1110000100100100111100000000; break;
                case '3': binc = 0b1110000101100001111000000000; break;
                case '4': binc = 0b1001100101110001000100000000; break;
                case '5': binc = 0b1111100001100001111000000000; break;
                case '6': binc = 0b0110100011101001011100000000; break;
                case '7': binc = 0b1111000100100010001000000000; break;
                case '8': binc = 0b0110100101101001011000000000; break;
                case '9': binc = 0b0111100101110001000100000000; break;
                case '-': binc = 0b0000000011110000000000000000; break;
                case '+': binc = 0b0000001001110010000000000000; break;
                case '!': binc = 0b0010001000100000001000000000; break;
                case '.': binc = 0b0000000000000000100000000000; break;
                case ' ': binc = 0b0000000000000000000000000000; break;
                default: break;
            }
            
            for (int n = 0; n <= 27; n++) {
                if (binc & 0b1000000000000000000000000000 >> n) {
                    int dx = n % CHAR_WIDTH;
                    int dy = n / CHAR_WIDTH;
                    drawPoint(x + dx, y + dy);
                }
            }   
        }
    };
};