forked from lualiliu/esp32-gameboy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsdl.cpp
More file actions
150 lines (127 loc) · 4.49 KB
/
sdl.cpp
File metadata and controls
150 lines (127 loc) · 4.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include "sdl.h"
#include <Arduino_GFX_Library.h>
#include "SPI.h"
#define _cs 5 // 3 goes to TFT CS
#define _dc 21 // 4 goes to TFT DC
#define _mosi 23 // 5 goes to TFT MOSI
#define _sclk 18 // 6 goes to TFT SCK/CLK
#define _rst 25 // ESP RST to TFT RESET
#define _miso 19 // Not connected
#define _led 22
// 3.3V // Goes to TFT LED
// 5v // Goes to TFT Vcc
// Gnd // Goes to TFT Gnd
#define _left GPIO_NUM_4
#define _right GPIO_NUM_26
#define _up GPIO_NUM_17
#define _down GPIO_NUM_27
#define _select GPIO_NUM_15
#define _start GPIO_NUM_35
#define _a GPIO_NUM_33
#define _b GPIO_NUM_32
Arduino_DataBus *bus = new Arduino_ESP32SPI(_dc);
// Arduino_DataBus *bus = new Arduino_ESP32SPI(_dc, _cs, _sclk, _mosi, _miso);
Arduino_GFX *tft = new Arduino_ILI9341(bus, _rst, 3 /* rotation */);
void backlighting(bool state) {
if (!state) {
digitalWrite(_led, LOW);
} else {
digitalWrite(_led, HIGH);
}
}
#define GAMEBOY_HEIGHT 144
#define GAMEBOY_WIDTH 160
#define DRAW_HEIGHT 144
#define DRAW_WIDTH 160
#define SCREEN_HEIGHT 240
#define SCREEN_WIDTH 320
#define SPI_FREQ 40000000
static uint8_t *frame_buffer;
static int button_start, button_select, button_a, button_b, button_down,
button_up, button_left, button_right;
static volatile bool frame_ready = false;
TaskHandle_t draw_task_handle;
void draw_button(bool value, int x_pos, int y_pos,
const char *label = nullptr) {
if (value) {
tft->fillCircle(x_pos, y_pos, 7, 0xffff);
} else {
tft->fillCircle(x_pos, y_pos, 7, 0x0000);
}
if (label) {
int len = strlen(label);
constexpr int char_len = 8;
int width = char_len * len;
for (int i = 0; i < len; ++i) {
tft->drawChar(x_pos - width / 2 + char_len * i, y_pos + 20, label[i],
0xffff, RED);
}
}
}
void draw_task(void *parameter) {
uint16_t color_palette[] = {0xffff, (16 << 11) + (32 << 5) + 16,
(8 << 11) + (16 << 5) + 8, 0x0000};
int h_offset = (SCREEN_WIDTH - DRAW_WIDTH) / 2;
int v_offset = (SCREEN_HEIGHT - DRAW_HEIGHT) / 2;
while (true) {
while (!frame_ready) {
delay(1);
}
frame_ready = false;
tft->drawIndexedBitmap(h_offset, v_offset, frame_buffer, color_palette,
DRAW_WIDTH, DRAW_HEIGHT);
draw_button(button_up, 30, SCREEN_HEIGHT / 2 - 15);
draw_button(button_left, 15, SCREEN_HEIGHT / 2);
draw_button(button_right, 45, SCREEN_HEIGHT / 2);
draw_button(button_down, 30, SCREEN_HEIGHT / 2 + 15);
draw_button(button_select, 30, SCREEN_HEIGHT / 2 + 70, "select");
draw_button(button_start, SCREEN_WIDTH - 30, SCREEN_HEIGHT / 2 + 70,
"start");
draw_button(button_a, SCREEN_WIDTH - 45, SCREEN_HEIGHT / 2, "a");
draw_button(button_b, SCREEN_WIDTH - 15, SCREEN_HEIGHT / 2 - 15, "b");
}
}
void sdl_init(void) {
frame_buffer = new uint8_t[DRAW_WIDTH * DRAW_HEIGHT];
// GFX_EXTRA_PRE_INIT();
tft->begin(SPI_FREQ);
pinMode(_led, OUTPUT);
backlighting(true);
tft->fillScreen(RED);
gpio_num_t gpios[] = {_left, _right, _down, _up, _start, _select, _a, _b};
for (gpio_num_t pin : gpios) {
gpio_pad_select_gpio(pin);
gpio_set_direction(pin, GPIO_MODE_INPUT);
// uncomment to use builtin pullup resistors
// gpio_set_pull_mode(pin, GPIO_PULLUP_ONLY);
}
xTaskCreatePinnedToCore(draw_task, /* Function to implement the task */
"drawTask", /* Name of the task */
10000, /* Stack size in words */
NULL, /* Task input parameter */
0, /* Priority of the task */
&draw_task_handle, /* Task handle. */
0); /* Core where the task should run */
}
int sdl_update(void) {
button_up = !gpio_get_level(_up);
button_left = !gpio_get_level(_left);
button_down = !gpio_get_level(_down);
button_right = !gpio_get_level(_right);
button_start = !gpio_get_level(_start);
button_select = !gpio_get_level(_select);
button_a = !gpio_get_level(_a);
button_b = !gpio_get_level(_b);
sdl_frame();
return 0;
}
unsigned int sdl_get_buttons(void) {
unsigned int buttons =
(button_start * 8) | (button_select * 4) | (button_b * 2) | button_a;
return buttons;
}
unsigned int sdl_get_directions(void) {
return (button_down * 8) | (button_up * 4) | (button_left * 2) | button_right;
}
uint8_t *sdl_get_framebuffer(void) { return frame_buffer; }
void sdl_frame(void) { frame_ready = true; }