-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgui.cpp
More file actions
138 lines (126 loc) · 2.73 KB
/
Copy pathgui.cpp
File metadata and controls
138 lines (126 loc) · 2.73 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
// TODO: think about apu communication with gui?
class GUI {
public:
PPU* ppu;
Memory* memory;
SDL_Window* window;
SDL_Renderer* renderer;
SDL_Texture* texture;
SDL_Rect baselayer;
bool valid;
int frames;
void set_ppu(PPU*);
void initialize();
void close_gui();
void render_frame(uint8_t*);
uint8_t get_input();
};
struct InputData {
bool a : 1;
bool b : 1;
bool select : 1;
bool start : 1;
bool up : 1;
bool down : 1;
bool left : 1;
bool right : 1;
};
union Input {
uint8_t value;
InputData data;
};
void GUI::initialize() {
SDL_Init(SDL_INIT_VIDEO || SDL_INIT_AUDIO);
// Create window
window = SDL_CreateWindow(
"NESmerize",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
256,
240,
SDL_WINDOW_RESIZABLE
);
renderer = SDL_CreateRenderer(
window,
-1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
);
SDL_RenderSetLogicalSize(renderer, 256, 240);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
texture = SDL_CreateTexture(
renderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
256,
240
);
if (texture == NULL) {
exit(1);
}
baselayer = {
0,
0,
256,
240
};
valid = true;
frames = 0;
}
void GUI::close_gui() {
// Destroy window
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
// Quit SDL subsystems
IMG_Quit();
SDL_Quit();
valid = false;
}
uint8_t GUI::get_input() {
Input input_data;
input_data.value = 0;
SDL_PumpEvents(); // update event queue to avoid being a frame behind
const uint8_t* keystate = SDL_GetKeyboardState(NULL);
// update bitfield with information about keyboard
if (keystate[SDL_SCANCODE_DOWN]) {
input_data.data.down = 1;
}
if (keystate[SDL_SCANCODE_UP]) {
input_data.data.up = 1;
}
if (keystate[SDL_SCANCODE_RIGHT]) {
input_data.data.right = 1;
}
if (keystate[SDL_SCANCODE_LEFT]) {
input_data.data.left = 1;
}
if (keystate[SDL_SCANCODE_Z]) {
input_data.data.a = 1;
}
if (keystate[SDL_SCANCODE_X]) {
input_data.data.b = 1;
}
if (keystate[SDL_SCANCODE_RSHIFT]) {
input_data.data.select = 1;
}
if (keystate[SDL_SCANCODE_RETURN]) {
input_data.data.start = 1;
}
return input_data.value;
}
// TODO: why does this work at 60fps even without vsync or anything?
void GUI::render_frame(uint8_t* framebuffer) {
SDL_Event e;
while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT) {
close_gui();
return;
}
}
// update with new frame data
SDL_UpdateTexture(texture, nullptr, framebuffer, 256 * 4);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, nullptr, nullptr);
SDL_RenderPresent(renderer);
frames++;
}