-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathanother-world.cpp
More file actions
100 lines (77 loc) · 2.52 KB
/
another-world.cpp
File metadata and controls
100 lines (77 loc) · 2.52 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
/*
Another World game engine demo
by Jonathan Williamson (lowfatcode)
*/
#include <cstring>
#include "32blit.hpp"
#include "virtual-machine.hpp"
using namespace blit;
using namespace another_world;
VirtualMachine vm;
Pen palette_buffer[16];
void init() {
set_screen_mode(ScreenMode::hires);
another_world::read_file = [](std::string filename, uint32_t offset, uint32_t length, char* buffer) {
blit::File file(filename);
uint32_t bytes_read = file.read(offset, length, buffer);
return bytes_read == length;
};
another_world::update_screen = [](uint8_t *buffer) {
};
another_world::set_palette = [](uint16_t* p) {
// sixten palette entries in the format 0x0RGB
for (uint8_t i = 0; i < 16; i++) {
uint16_t color = p[i];
uint8_t r = (color & 0b0000000000001111) >> 0;
uint8_t g = (color & 0b1111000000000000) >> 12;
uint8_t b = (color & 0b0000111100000000) >> 8;
palette_buffer[i].r = (r << 4) | r;
palette_buffer[i].g = (g << 4) | g;
palette_buffer[i].b = (b << 4) | b;
palette_buffer[i].a = 255;
}
};
vm.init();
vm.initialise_chapter(16001);
}
void render(uint32_t time_ms) {
static uint16_t tick = 0;
tick++;
uint32_t ms_start = now();
screen.pen = Pen(0, 0, 0);
screen.clear();
for(uint16_t y = 0; y < 200; y++) {
for(uint16_t x = 0; x < 160; x++) {
uint8_t v = vm.visible_vram[y * 160 + x];
uint8_t v1 = v >> 4;
uint8_t v2 = v & 0x0f;
screen.pen = palette_buffer[v1];
screen.pixel(blit::Point(x * 2, y + 20));
screen.pen = palette_buffer[v2];
screen.pixel(blit::Point(x * 2 + 1, y + 20));
}
}
uint32_t ms_end = now();
// draw FPS meter & watermark
screen.watermark();
screen.pen = Pen(255, 255, 255);
screen.text(std::to_string(ms_end - ms_start) + "ms/frame", minimal_font, blit::Point(2, 240 - 10));
screen.pen = Pen(255, 0, 0);
for (int i = 0; i < uint16_t(ms_end - ms_start); i++) {
screen.pen = Pen(i * 5, 255 - (i * 5), 0);
screen.rectangle(blit::Rect(i * 3 + 2, 227, 2, 2));
}
}
void update(uint32_t time_ms) {
static uint32_t last_frame_clock = 0;
uint16_t pause_ms = 20 * vm.registers[0xff];
if(now() - last_frame_clock > pause_ms) {
last_frame_clock = now();
vm.execute_threads();
}
another_world::input.up = buttons & DPAD_UP;
another_world::input.down = buttons & DPAD_DOWN;
another_world::input.left = buttons & DPAD_LEFT;
another_world::input.right = buttons & DPAD_RIGHT;
another_world::input.action = buttons & A;
}