[WIP] Add some changes for 16bpp fb running on NST
This commit is contained in:
parent
0e7a4d7ab7
commit
e146eb6145
4
Makefile
4
Makefile
|
@ -12,8 +12,8 @@ KBD_PATH ?= /dev/input/event1
|
||||||
MOUSE_PATH ?= /dev/input/mice
|
MOUSE_PATH ?= /dev/input/mice
|
||||||
C_DEFINES := -DKBD_PATH=\"$(KBD_PATH)\" -DMOUSE_PATH=\"$(MOUSE_PATH)\"
|
C_DEFINES := -DKBD_PATH=\"$(KBD_PATH)\" -DMOUSE_PATH=\"$(MOUSE_PATH)\"
|
||||||
|
|
||||||
CC ?= cc
|
CC := ../ndk/bin/arm-linux-androideabi-gcc
|
||||||
CFLAGS := -Wall -Wextra -pedantic -static
|
CFLAGS := -Wall -Wextra -std=c99
|
||||||
|
|
||||||
REL_FLAGS := -DNDEBUG -O2
|
REL_FLAGS := -DNDEBUG -O2
|
||||||
DEB_FLAGS := -DDEBUG -O0 -g
|
DEB_FLAGS := -DDEBUG -O0 -g
|
||||||
|
|
132
src/main.c
132
src/main.c
|
@ -80,14 +80,14 @@ init_input(void) {
|
||||||
if (in.kbd_fd == -1) {
|
if (in.kbd_fd == -1) {
|
||||||
// NOTE: Some applications may not require a keyboard so this is
|
// NOTE: Some applications may not require a keyboard so this is
|
||||||
// optional, but we are still displaying an error.
|
// optional, but we are still displaying an error.
|
||||||
fprintf(stderr, "error: no couldn't open keyboard %s: %s.\n", KBD_PATH, strerror(errno));
|
// fprintf(stderr, "error: couldn't open keyboard %s: %s.\n", KBD_PATH, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
in.mouse_fd = open(MOUSE_PATH, O_RDONLY | O_NONBLOCK);
|
in.mouse_fd = open(MOUSE_PATH, O_RDONLY | O_NONBLOCK);
|
||||||
if (in.mouse_fd == -1) {
|
if (in.mouse_fd == -1) {
|
||||||
// NOTE: Some applications may not require a mouse so this is
|
// NOTE: Some applications may not require a mouse so this is
|
||||||
// optional, but we are still displaying an error.
|
// optional, but we are still displaying an error.
|
||||||
fprintf(stderr, "error: no couldn't open mouse %s: %s.\n", MOUSE_PATH, strerror(errno));
|
// fprintf(stderr, "error: couldn't open mouse %s: %s.\n", MOUSE_PATH, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,6 +367,20 @@ screen_dei(Device *d, u8 port) {
|
||||||
void
|
void
|
||||||
screen_deo(Device *d, u8 port) {
|
screen_deo(Device *d, u8 port) {
|
||||||
switch(port) {
|
switch(port) {
|
||||||
|
// case 0x3:
|
||||||
|
// if(!FIXED_SIZE) {
|
||||||
|
// Uint16 w;
|
||||||
|
// DEVPEEK16(w, 0x2);
|
||||||
|
// screen_resize(&uxn_screen, clamp(w, 1, 1024), uxn_screen.height);
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
// case 0x5:
|
||||||
|
// if(!FIXED_SIZE) {
|
||||||
|
// Uint16 h;
|
||||||
|
// DEVPEEK16(h, 0x4);
|
||||||
|
// screen_resize(&uxn_screen, uxn_screen.width, clamp(h, 1, 1024));
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
case 0xe: {
|
case 0xe: {
|
||||||
u16 x, y;
|
u16 x, y;
|
||||||
u8 layer = d->dat[0xe] & 0x40;
|
u8 layer = d->dat[0xe] & 0x40;
|
||||||
|
@ -509,6 +523,7 @@ main(int argc, char *argv[]) {
|
||||||
|
|
||||||
// Main loop.
|
// Main loop.
|
||||||
Time frame_time = time_now();
|
Time frame_time = time_now();
|
||||||
|
size_t frames = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
poll_input();
|
poll_input();
|
||||||
size_t elapsed = time_elapsed(frame_time);
|
size_t elapsed = time_elapsed(frame_time);
|
||||||
|
@ -520,9 +535,122 @@ main(int argc, char *argv[]) {
|
||||||
|
|
||||||
// Blit ppu.pixels to the framebuffer.
|
// Blit ppu.pixels to the framebuffer.
|
||||||
blit_framebuffer();
|
blit_framebuffer();
|
||||||
|
if (++frames > 5) {
|
||||||
|
// memset(framebuffer, 0xFF, screen_width * screen_height * bpp);
|
||||||
|
// system("echo 0 > /dev/graphics/fb0");
|
||||||
|
// redraw_screen();
|
||||||
|
// blit_framebuffer();
|
||||||
|
|
||||||
|
// FIXME: Thre HAS to be a better way to refresh the display lol.
|
||||||
|
system("echo 0 > /dev/graphics/fb0");
|
||||||
|
|
||||||
|
// Time t = time_now();
|
||||||
|
// while (time_elapsed(t) < 16666666 * 2) {
|
||||||
|
// // nop wait X frames for the refresh?
|
||||||
|
// }
|
||||||
|
// wait(ret);
|
||||||
|
// memset(framebuffer, 0xFF, screen_width * screen_height * bpp);
|
||||||
|
// redraw_screen();
|
||||||
|
// memset(framebuffer, 0x00, screen_width * screen_height * bpp);
|
||||||
|
// redraw_screen();
|
||||||
|
|
||||||
|
frames = 0;
|
||||||
|
}
|
||||||
frame_time = time_now();
|
frame_time = time_now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// int
|
||||||
|
// main(int argc, char *argv[]) {
|
||||||
|
// // FIXME: Experimental
|
||||||
|
// int fb = open("/dev/graphics/fb0", O_RDWR);
|
||||||
|
// if (fb <= 0) {
|
||||||
|
// fprintf(stderr, "error: couldn't open the framebuffer\n");
|
||||||
|
// exit(EXIT_FAILURE);
|
||||||
|
// }
|
||||||
|
// struct fb_var_screeninfo info;
|
||||||
|
// if (ioctl(fb, FBIOGET_VSCREENINFO, &info) != 0) {
|
||||||
|
// fprintf(stderr, "error: couldn't get the framebuffer size\n");
|
||||||
|
// exit(EXIT_FAILURE);
|
||||||
|
// }
|
||||||
|
// size_t screen_width = info.xres;
|
||||||
|
// size_t screen_height = info.yres;
|
||||||
|
// size_t bpp = info.bits_per_pixel / 8;
|
||||||
|
// size_t len = bpp * screen_width * screen_height;
|
||||||
|
// u8 *framebuffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
|
||||||
|
// if (framebuffer == MAP_FAILED) {
|
||||||
|
// fprintf(stderr, "error: couldn't mmap the framebuffer\n");
|
||||||
|
// exit(EXIT_FAILURE);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Print all relevant elements from the fb_var_screeninfo struct
|
||||||
|
// printf("> xres: %d\n"
|
||||||
|
// "> yres: %d\n"
|
||||||
|
// "> xres_virtual: %d\n"
|
||||||
|
// "> yres_virtual: %d\n"
|
||||||
|
// "> xoffset: %d\n"
|
||||||
|
// "> yoffset: %d\n"
|
||||||
|
// "> bits_per_pixel: %d\n"
|
||||||
|
// "> grayscale: %d\n"
|
||||||
|
// "> activate: %d\n"
|
||||||
|
// "> height: %d\n"
|
||||||
|
// "> width: %d\n"
|
||||||
|
// "> hsync_len: %d\n"
|
||||||
|
// "> vsync_len: %d\n"
|
||||||
|
// "> sync: %d\n"
|
||||||
|
// "> vmode: %d\n"
|
||||||
|
// "> rotate: %d\n"
|
||||||
|
// "> len: %d\n",
|
||||||
|
// info.xres,
|
||||||
|
// info.yres,
|
||||||
|
// info.xres_virtual,
|
||||||
|
// info.yres_virtual,
|
||||||
|
// info.xoffset,
|
||||||
|
// info.yoffset,
|
||||||
|
// info.bits_per_pixel,
|
||||||
|
// info.grayscale,
|
||||||
|
// info.activate,
|
||||||
|
// info.height,
|
||||||
|
// info.width,
|
||||||
|
// info.hsync_len,
|
||||||
|
// info.vsync_len,
|
||||||
|
// info.sync,
|
||||||
|
// info.vmode,
|
||||||
|
// info.rotate,
|
||||||
|
// len);
|
||||||
|
|
||||||
|
|
||||||
|
// // Clean screen
|
||||||
|
// // memset(framebuffer, 0x00, screen_width * screen_height * 2); // black
|
||||||
|
// memset(framebuffer, 0xFF, len); // white
|
||||||
|
// for (size_t i = 0, k = 0; i < (screen_width * screen_height) / 2; i++) {
|
||||||
|
// for (size_t b = 0; b < bpp; b++) {
|
||||||
|
// framebuffer[k++] = 0xF0;
|
||||||
|
// }
|
||||||
|
// // p[i] = 0xF0F0;
|
||||||
|
// // framebuffer[k++] = 0xFF;
|
||||||
|
// // framebuffer[k++] = 0x00;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Main loop.
|
||||||
|
// Time frame_time = time_now();
|
||||||
|
// size_t frames = 0;
|
||||||
|
// while (true) {
|
||||||
|
// size_t elapsed = time_elapsed(frame_time);
|
||||||
|
// if (elapsed >= 16666666) {
|
||||||
|
|
||||||
|
// // FIXME: Thre HAS to be a better way lol.
|
||||||
|
// frame_time = time_now();
|
||||||
|
// frames++;
|
||||||
|
// if (frames > 10) {
|
||||||
|
// system("echo 0 > /dev/graphics/fb0");
|
||||||
|
// frames = 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
82
src/ppu.c
82
src/ppu.c
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include <linux/fb.h>
|
#include <linux/fb.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/kd.h>
|
// #include <sys/kd.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#include "ppu.h"
|
#include "ppu.h"
|
||||||
|
@ -24,8 +24,9 @@
|
||||||
|
|
||||||
static size_t screen_width = 0;
|
static size_t screen_width = 0;
|
||||||
static size_t screen_height = 0;
|
static size_t screen_height = 0;
|
||||||
|
static size_t bpp = 0;
|
||||||
|
|
||||||
static u32 *framebuffer = 0;
|
static u8 *framebuffer = 0;
|
||||||
|
|
||||||
static u32 palette[16];
|
static u32 palette[16];
|
||||||
static u8 *pixels_fg;
|
static u8 *pixels_fg;
|
||||||
|
@ -42,6 +43,14 @@ static u8 blending[5][16] = {
|
||||||
{2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2},
|
{2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2},
|
||||||
{1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}};
|
{1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}};
|
||||||
|
|
||||||
|
u16
|
||||||
|
rgb565(u32 rgba) {
|
||||||
|
u16 r = rgba >> 16 & 0xFF;
|
||||||
|
u16 g = rgba >> 8 & 0xFF;
|
||||||
|
u16 b = rgba >> 0 & 0xFF;
|
||||||
|
return (r << 8) | (g << 3) | (b >> 3);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ppu_pixel(u8 *layer, u16 x, u16 y, u8 color) {
|
ppu_pixel(u8 *layer, u16 x, u16 y, u8 color) {
|
||||||
if(x < screen_width && y < screen_height) {
|
if(x < screen_width && y < screen_height) {
|
||||||
|
@ -101,39 +110,39 @@ set_tty(bool graphics) {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (graphics) {
|
// if (graphics) {
|
||||||
if (ioctl(tty, KDSETMODE, KD_GRAPHICS)) {
|
// if (ioctl(tty, KDSETMODE, KD_GRAPHICS)) {
|
||||||
fprintf(stderr,"error: setting graphics mode failed\n");
|
// fprintf(stderr,"error: setting graphics mode failed\n");
|
||||||
exit(EXIT_FAILURE);
|
// exit(EXIT_FAILURE);
|
||||||
}
|
// }
|
||||||
struct termios t;
|
// struct termios t;
|
||||||
if (tcgetattr(STDIN_FILENO, &t)) {
|
// if (tcgetattr(STDIN_FILENO, &t)) {
|
||||||
fprintf(stderr, "error: couldn't disable terminal echo\n");
|
// fprintf(stderr, "error: couldn't disable terminal echo\n");
|
||||||
exit(EXIT_FAILURE);
|
// exit(EXIT_FAILURE);
|
||||||
}
|
// }
|
||||||
prev_t = t;
|
// prev_t = t;
|
||||||
t.c_lflag &= ~((tcflag_t) ECHO);
|
// t.c_lflag &= ~((tcflag_t) ECHO);
|
||||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &t)) {
|
// if (tcsetattr(STDIN_FILENO, TCSANOW, &t)) {
|
||||||
fprintf(stderr, "error: couldn't disable terminal echo\n");
|
// fprintf(stderr, "error: couldn't disable terminal echo\n");
|
||||||
exit(EXIT_FAILURE);
|
// exit(EXIT_FAILURE);
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
if (ioctl(tty, KDSETMODE, KD_TEXT)) {
|
// if (ioctl(tty, KDSETMODE, KD_TEXT)) {
|
||||||
fprintf(stderr,"error: setting text mode failed\n");
|
// fprintf(stderr,"error: setting text mode failed\n");
|
||||||
exit(EXIT_FAILURE);
|
// exit(EXIT_FAILURE);
|
||||||
}
|
// }
|
||||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &prev_t)) {
|
// if (tcsetattr(STDIN_FILENO, TCSANOW, &prev_t)) {
|
||||||
fprintf(stderr, "error: couldn't restore terminal attributes\n");
|
// fprintf(stderr, "error: couldn't restore terminal attributes\n");
|
||||||
exit(EXIT_FAILURE);
|
// exit(EXIT_FAILURE);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
close(tty);
|
close(tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ppu_init(void) {
|
ppu_init(void) {
|
||||||
// Open frambuffer and get the size.
|
// Open frambuffer and get the size.
|
||||||
int fb = open("/dev/fb0", O_RDWR);
|
int fb = open("/dev/graphics/fb0", O_RDWR);
|
||||||
if (fb <= 0) {
|
if (fb <= 0) {
|
||||||
fprintf(stderr, "error: couldn't open the framebuffer\n");
|
fprintf(stderr, "error: couldn't open the framebuffer\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -147,7 +156,8 @@ ppu_init(void) {
|
||||||
// Mmap the framebuffer to a buffer object.
|
// Mmap the framebuffer to a buffer object.
|
||||||
screen_width = info.xres;
|
screen_width = info.xres;
|
||||||
screen_height = info.yres;
|
screen_height = info.yres;
|
||||||
size_t len = 4 * screen_width * screen_height;
|
bpp = info.bits_per_pixel / 8;
|
||||||
|
size_t len = bpp * screen_width * screen_height;
|
||||||
framebuffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
|
framebuffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
|
||||||
if (framebuffer == MAP_FAILED) {
|
if (framebuffer == MAP_FAILED) {
|
||||||
fprintf(stderr, "error: couldn't mmap the framebuffer\n");
|
fprintf(stderr, "error: couldn't mmap the framebuffer\n");
|
||||||
|
@ -164,7 +174,7 @@ ppu_init(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare TTY for graphics mode.
|
// Prepare TTY for graphics mode.
|
||||||
set_tty(true);
|
// set_tty(true);
|
||||||
|
|
||||||
// Initialize default palette.
|
// Initialize default palette.
|
||||||
palette[0] = 0x444444;
|
palette[0] = 0x444444;
|
||||||
|
@ -177,6 +187,9 @@ ppu_init(void) {
|
||||||
memset(pixels_bg, 0, screen_width * screen_height);
|
memset(pixels_bg, 0, screen_width * screen_height);
|
||||||
memset(dirty_lines, 1, screen_height);
|
memset(dirty_lines, 1, screen_height);
|
||||||
|
|
||||||
|
// Clear framebuffer.
|
||||||
|
memset(framebuffer, 0xFF, len);
|
||||||
|
|
||||||
// Make sure we perform an initial screen drawing.
|
// Make sure we perform an initial screen drawing.
|
||||||
reqdraw = 1;
|
reqdraw = 1;
|
||||||
redraw_screen();
|
redraw_screen();
|
||||||
|
@ -189,11 +202,16 @@ blit_framebuffer(void) {
|
||||||
if (reqdraw == 0) {
|
if (reqdraw == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// TODO: add some parameter to account for zoom? for example we may want to
|
||||||
|
// have an internal resolution smaller than the screen!
|
||||||
for (size_t j = 0; j < screen_height; j++) {
|
for (size_t j = 0; j < screen_height; j++) {
|
||||||
if (dirty_lines[j] != 0) {
|
if (dirty_lines[j] != 0) {
|
||||||
for (size_t i = 0; i < screen_width; i++) {
|
for (size_t i = 0; i < screen_width; i++) {
|
||||||
size_t idx = i + j * screen_width;
|
size_t idx = i + j * screen_width;
|
||||||
framebuffer[idx] = palette[pixels_fg[idx] << 2 | pixels_bg[idx]];
|
u16 *p = framebuffer;
|
||||||
|
p[idx] = rgb565(palette[pixels_fg[idx] << 2 | pixels_bg[idx]]);
|
||||||
|
// FIXME: can we generalize this to use bpp instead of having
|
||||||
|
// a version for 32/16 bit color?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dirty_lines[j] = 0;
|
dirty_lines[j] = 0;
|
||||||
|
|
Loading…
Reference in New Issue