Files
NJU_PA/navy-apps/libs/libndl/NDL.c
tracer-ics2023 7fd92e4c49 > compile NEMU
221220000 张三
Linux zzy 5.15.146.1-microsoft-standard-WSL2 #1 SMP Thu Jan 11 04:09:03 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
 13:06:42 up 8 days, 15:51,  1 user,  load average: 0.25, 0.10, 0.02
2024-09-27 13:06:42 +08:00

154 lines
3.6 KiB
C

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static int evtdev = -1;
static int fbdev = -1;
static int screen_w = 0, screen_h = 0;
#include <NDL.h>
#include <sys/time.h>
uint32_t NDL_GetTicks() {
struct timeval t;
gettimeofday(&t, NULL);
return t.tv_sec * 1000 + t.tv_usec / 1000;
}
int NDL_PollEvent(char *buf, int len) {
FILE* fd = fopen("/dev/events", "r");
if (fd == NULL) {
printf("cannot open /dev/events");
exit(-1);
}
size_t ret = fread(buf, 1, len, fd);
// if (ret) printf("NDL_PollEvent read %d bytes is %s", ret, buf);
fclose(fd);
return ret;
}
static void _get_screen(int *w, int *h) {
static int dev_w = -1, dev_h = -1, num = -1;
FILE* fp = fopen("/proc/dispinfo", "r");
if (fp == NULL) {
printf("cannot open /proc/dispinfo");
exit(-1);
}
char buf[64], name[32];
const char* pos = buf;
fread(buf, 1, sizeof(buf), fp);
int life = 2;
// FIXME this have a bug to phase the ` [KEY] : [VALUE] `
while (sscanf(pos, "%s : %d\n", name, &num) == 2 && life--) {
pos = strchr(pos, '\n');
if (pos == NULL) break;
if (strcmp(name, "WIDTH") == 0) { dev_w = num; }
if (strcmp(name, "HEIGHT") == 0) { dev_h = num; }
}
*w = dev_w;
*h = dev_h;
// printf("screen size: %d %d\n", dev_w, dev_h);
fclose(fp);
}
void NDL_OpenCanvas(int *w, int *h) {
if (getenv("NWM_APP")) {
int fbctl = 4;
fbdev = 5;
screen_w = *w; screen_h = *h;
char buf[64];
int len = sprintf(buf, "%d %d", screen_w, screen_h);
// let NWM resize the window and create the frame buffer
write(fbctl, buf, len);
while (1) {
// 3 = evtdev
int nread = read(3, buf, sizeof(buf) - 1);
if (nread <= 0) continue;
buf[nread] = '\0';
if (strcmp(buf, "mmap ok") == 0) break;
}
close(fbctl);
}
int dev_w, dev_h;
_get_screen(&dev_w, &dev_h);
screen_w = (*w == 0 || *w > dev_w) ? dev_w : *w;
screen_h = (*h == 0 || *h > dev_h) ? dev_h : *h;
*w = screen_w;
*h = screen_h;
// printf("NDL_OpenCanvas: %d,%d, dev %d,%d\n", screen_w, screen_h, dev_w, dev_h);
}
void NDL_DrawRect(uint32_t *pixels, int x, int y, int w, int h) {
FILE* fp = fopen("/dev/fb", "w");
if (fp == NULL) {
printf("cannot open /dev/fb");
exit(-1);
}
int dev_w, dev_h;
_get_screen(&dev_w, &dev_h);
int _x = (dev_w - w) / 2;
int _y = (dev_h - h) / 2;
// printf("NDL_DrawRect: %d,%d, dev %d,%d, wh %d,%d, xy %d,%d\n", _x, _y, dev_w, dev_h, w, h, x, y);
for (int i = 0; i < h; i ++) {
// printf("log:%d,%d, dev %d,%d, wh %d,%d, xy %d,%d\n", _x, _y + i, dev_w, dev_h, w, h, x, y);
fseek(fp, NDL_SCREEN_POS(_x, _y + i, dev_w, dev_h), SEEK_SET);
fwrite(pixels + NDL_SCREEN_IDX(x, y + i, w, h), 4, w, fp);
}
fclose(fp);
}
void NDL_OpenAudio(int freq, int channels, int samples) {
FILE* fp = fopen("/dev/sbctl", "w");
if (fp == NULL) {
printf("cannot open /dev/fb");
exit(-1);
}
int arr[] = {
freq, channels, samples
};
fwrite(arr, sizeof(int), 3, fp);
fclose(fp);
}
void NDL_CloseAudio() {
}
int NDL_PlayAudio(void *buf, int len) {
FILE* fp = fopen("/dev/sb", "w");
if (fp == NULL) {
printf("cannot open /dev/fb");
exit(-1);
}
fwrite(buf, 1, len, fp);
fclose(fp);
return len;
}
int NDL_QueryAudio() {
FILE* fp = fopen("/dev/sbctl", "r");
if (fp == NULL) {
printf("cannot open /dev/fb");
exit(-1);
}
int ret;
fread(&ret, sizeof(int), 1, fp);
fclose(fp);
return ret;
}
int NDL_Init(uint32_t flags) {
if (getenv("NWM_APP")) {
evtdev = 3;
}
return 0;
}
void NDL_Quit() {
}