OpenCores
URL https://opencores.org/ocsvn/s80186/s80186/trunk

Subversion Repositories s80186

[/] [s80186/] [trunk/] [sim/] [display/] [Display.cpp] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jamieiles
// Copyright Jamie Iles, 2017
2
//
3
// This file is part of s80x86.
4
//
5
// s80x86 is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// s80x86 is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with s80x86.  If not, see <http://www.gnu.org/licenses/>.
17
 
18
#include "Display.h"
19
 
20
#include <cassert>
21
#include <cctype>
22
#include <cstdlib>
23
#include <fstream>
24
#include <iostream>
25
#include <map>
26
#include <stdexcept>
27
 
28
#include <SDL.h>
29
 
30
#include "Window.h"
31
 
32
Display::Display(unsigned num_rows, unsigned num_cols)
33
    : num_rows(num_rows), num_cols(num_cols), row(0), col(0)
34
{
35
    if (SDL_Init(SDL_INIT_VIDEO) != 0)
36
        throw std::runtime_error("Failed to initialize SDL " +
37
                                 std::string(SDL_GetError()));
38
 
39
    characters = std::make_unique<uint16_t[]>(num_rows * (num_cols + 1));
40
    window = std::make_unique<Window>("8086sim", 8 * num_cols, 8 * num_rows);
41
 
42
    load_font();
43
}
44
 
45
Display::~Display()
46
{
47
    SDL_Quit();
48
}
49
 
50
void Display::load_font()
51
{
52
    std::ifstream font_file;
53
    font_file.open(FONT_FILE, std::ios::binary | std::ios::in);
54
    font_file.read(font_bitmap, sizeof(font_bitmap));
55
    font_file.close();
56
}
57
 
58
void Display::set_cursor(unsigned row, unsigned col)
59
{
60
    this->row = row;
61
    this->col = col;
62
}
63
 
64
void Display::write_char(uint16_t c)
65
{
66
    uint16_t v = c;
67
 
68
    characters[this->row * (num_cols + 1) + this->col] = v;
69
    this->col++;
70
 
71
    if (this->col == num_cols) {
72
        this->col = 0;
73
        this->row++;
74
    }
75
    if (this->row == num_rows)
76
        this->row = num_rows - 1;
77
}
78
 
79
struct color {
80
    unsigned char r, g, b;
81
};
82
 
83
const struct color get_color(unsigned char idx)
84
{
85
    assert(idx < 16);
86
 
87
    struct color lut[] = {
88
        {0, 0, 0},          // black
89
        {0, 0, 0xaa},       // blue
90
        {0x00, 0xaa, 0x00}, // green
91
        {0x00, 0xaa, 0xaa}, // cyan
92
        {0xaa, 0x00, 0x00}, // red
93
        {0xaa, 0x00, 0xaa}, // magenta
94
        {0xaa, 0x55, 0x00}, // brown
95
        {0xaa, 0xaa, 0xaa}, // white
96
        {0x55, 0x55, 0x55}, // gray
97
        {0x55, 0x55, 0xff}, // bright blue
98
        {0x55, 0xff, 0x55}, // bright green
99
        {0x55, 0xff, 0xff}, // bright cyan
100
        {0xff, 0x55, 0x55}, // bright red
101
        {0xff, 0x55, 0xff}, // bright magenta
102
        {0xff, 0xff, 0x55}, // yellow
103
        {0xff, 0xff, 0xff}, // bright white
104
    };
105
 
106
    return lut[idx];
107
}
108
 
109
void Display::refresh(Cursor cursor)
110
{
111
    window->clear();
112
    for (unsigned y = 0; y < num_rows; ++y) {
113
        for (unsigned x = 0; x < num_cols; ++x) {
114
            uint16_t font_index = characters.get()[(y * (num_cols + 1)) + x];
115
            char *font_data = &font_bitmap[(font_index & 0xff) * 8];
116
 
117
            for (int i = 0; i < 8; ++i)
118
                for (int j = 0; j < 8; ++j) {
119
                    auto fg = get_color((font_index >> 8) & 0xf);
120
                    auto bg = get_color((font_index >> 12) & 0xf);
121
 
122
                    auto render_cursor =
123
                        cursor.is_active_at(y * 8 + i, x * 8 + j);
124
                    bool pixel_set = (font_data[i] & (1 << (8 - j)));
125
                    auto color = (pixel_set && !render_cursor) ||
126
                                         (!pixel_set && render_cursor)
127
                                     ? fg
128
                                     : bg;
129
                    window->set_pixel(x * 8 + j, y * 8 + i, color.r, color.g,
130
                                      color.b);
131
                }
132
        }
133
    }
134
 
135
    window->redraw();
136
 
137
    SDL_UpdateWindowSurface(window->get());
138
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.