-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathmain.cpp
157 lines (141 loc) · 4.59 KB
/
main.cpp
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
151
152
153
154
155
156
157
#include <SDL2/SDL.h>
#include "nc1020.h"
#include <iostream>
#define FRAME_RATE 30
#define FRAME_INTERVAL (1000/FRAME_RATE)
#define SCREEN_WIDTH 160
#define SCREEN_HEIGHT 80
#define LINE_SIZE 2
SDL_Renderer* renderer;
static uint8_t lcd_buf[SCREEN_WIDTH * SCREEN_HEIGHT / 8];
bool InitEverything() {
if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {
std::cout << " Failed to initialize SDL : " << SDL_GetError() << std::endl;
return false;
}
SDL_Window* window =
SDL_CreateWindow("WQX", 0, 40, LINE_SIZE * SCREEN_WIDTH, LINE_SIZE * SCREEN_HEIGHT, 0);
if (!window) {
std::cout << "Failed to create window : " << SDL_GetError() << std::endl;
return false;
}
renderer = SDL_CreateRenderer(window, -1, 0);
if (!renderer) {
std::cout << "Failed to create renderer : " << SDL_GetError() << std::endl;
return false;
}
SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH * LINE_SIZE, SCREEN_HEIGHT * LINE_SIZE);
wqx::WqxRom rom = {
.romPath = "./obj_lu.bin",
.norFlashPath = "./nc1020.fls",
.statesPath = "./nc1020.sts",
};
wqx::Initialize(rom);
wqx::LoadNC1020();
return true;
}
void Render() {
SDL_RenderClear(renderer);
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT);
unsigned char* bytes = nullptr;
int pitch = 0;
static const SDL_Rect source = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
SDL_LockTexture(texture, &source, reinterpret_cast<void**>(&bytes), &pitch);
static const unsigned char on_color[4] = { 255, 0, 0, 0 };
static const unsigned char off_color[4] = { 255, 255, 255, 255 };
static const size_t color_size = sizeof(on_color);
for (int i = 0; i < sizeof(lcd_buf); ++i) {
for (int j = 0; j < 8; ++j) {
bool pixel = (lcd_buf[i] & (1 << (7 - j))) != 0;
memcpy(bytes, pixel ? on_color : off_color, color_size);
bytes += color_size;
}
}
SDL_UnlockTexture(texture);
static const SDL_Rect destination =
{ 0, 0, SCREEN_WIDTH * LINE_SIZE, SCREEN_HEIGHT * LINE_SIZE };
SDL_RenderCopy(renderer, texture, &source, &destination);
SDL_RenderPresent(renderer);
SDL_DestroyTexture(texture);
}
void RunGame() {
bool loop = true;
while (loop) {
uint32_t tick = SDL_GetTicks();
wqx::RunTimeSlice(FRAME_INTERVAL, false);
SDL_Event event;
while (SDL_PollEvent(&event)) {
if ( event.type == SDL_QUIT ) {
loop = false;
} else if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) {
bool key_down = event.type == SDL_KEYDOWN;
switch ( event.key.keysym.sym ) {
case SDLK_RIGHT: // Right
wqx::SetKey(0x1F, key_down);
break;
case SDLK_LEFT: // Left
wqx::SetKey(0x3F, key_down);
break;
case SDLK_DOWN: // Down
wqx::SetKey(0x1B, key_down);
break;
case SDLK_UP: // Up
wqx::SetKey(0x1A, key_down);
break;
case SDLK_u: // X
wqx::SetKey(0x10, key_down); // F1 - fly
break;
case SDLK_i: // Y
wqx::SetKey(0x13, key_down); // F4 - menu
break;
case SDLK_j: // A
wqx::SetKey(0x1D, key_down); // enter
break;
case SDLK_k: // B
wqx::SetKey(0x3B, key_down); // ESC - back
break;
case SDLK_KP_ENTER: // START
wqx::SetKey(0x08, key_down); // F10 - main screen
break;
case SDLK_SPACE: // SELECT
wqx::SetKey(0x0E, key_down); // F11 - game menu
break;
case SDLK_y: // Shift-X
wqx::SetKey(0x31, key_down); // X
break;
case SDLK_0: // Shift-Y
wqx::SetKey(0x25, key_down); // Y
break;
case SDLK_h: // Shift-A
wqx::SetKey(0x37, key_down); // Page Up
break;
case SDLK_l: // Shift-B
wqx::SetKey(0x1E, key_down); // Page Down
break;
case SDLK_ESCAPE: // Menu
wqx::SetKey(0x0F, key_down); // Power
break;
case SDLK_BACKSPACE: // Shift-Menu
loop = false;
break;
default : // unsupported
break;
}
}
}
if (!wqx::CopyLcdBuffer(lcd_buf)) {
std::cout << "Failed to copy buffer renderer." << std::endl;
}
Render();
tick = SDL_GetTicks() - tick;
SDL_Delay(FRAME_INTERVAL < tick ? 0 : FRAME_INTERVAL - tick);
}
}
int main(int argc, char* args[]) {
if (!InitEverything())
return -1;
RunGame();
wqx::SaveNC1020();
return 0;
}