Compare commits
5 commits
3f3a18ac85
...
2f5d42d89a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f5d42d89a | ||
|
|
5037b72832 | ||
|
|
94c7c03bc8 | ||
|
|
0112bce1a3 | ||
|
|
0829e56fb5 |
14 changed files with 49089 additions and 20 deletions
15
Makefile
15
Makefile
|
|
@ -30,8 +30,10 @@ KERNEL_SOURCES_x86_64 := \
|
|||
KERNEL_SOURCES := \
|
||||
src/acpi.c \
|
||||
src/console.c \
|
||||
src/doom.c \
|
||||
src/framebuffer.c \
|
||||
src/kernel.c \
|
||||
src/mouse.c \
|
||||
src/pci.c \
|
||||
src/ram.c \
|
||||
src/tar.c \
|
||||
|
|
@ -67,6 +69,10 @@ clean:
|
|||
rm -f $(KERNEL_DEPFILES)
|
||||
rm -f $(KERNEL_TARGET)
|
||||
|
||||
build/src/doom.o: src/doom.[cS] | build/src build/src/small3dlib
|
||||
@printf "CC -sse %s\n" $@
|
||||
@"$(CC)" -std=c17 -Wall -ggdb -ffreestanding -nostdlib -mno-red-zone -mcmodel=kernel -mno-mmx -mno-80387 -MMD -MP -c -o $@ $< $(CPPFLAGS)
|
||||
|
||||
build/src/%.o: src/%.[cS] | build/src build/src/small3dlib
|
||||
@printf "CC %s\n" $@
|
||||
@"$(CC)" $(CFLAGS) -MMD -MP -c -o $@ $< $(CPPFLAGS)
|
||||
|
|
@ -79,7 +85,7 @@ $(KERNEL_TARGET): $(KERNEL_OBJECTS) kernel.ld | build/boot/sys
|
|||
@printf "LD %s\n" $@
|
||||
@"$(LD)" -T kernel.ld $(LDFLAGS) -o $@ $(KERNEL_OBJECTS)
|
||||
|
||||
build/disk.img: $(KERNEL_TARGET) kernel.json bootboot.cfg build/boot/font.sff
|
||||
build/disk.img: $(KERNEL_TARGET) kernel.json bootboot.cfg build/boot/font.sff build/boot/doom/doom1.wad
|
||||
$(MKBOOTIMG) kernel.json $@
|
||||
|
||||
build:
|
||||
|
|
@ -94,6 +100,13 @@ build/src/small3dlib:
|
|||
build/boot:
|
||||
mkdir -p $@
|
||||
|
||||
build/boot/doom:
|
||||
mkdir -p $@
|
||||
|
||||
build/boot/doom/doom1.wad: doom1.wad build/boot build/boot/doom
|
||||
@printf "CP %s\n" $@
|
||||
@cp $< $@
|
||||
|
||||
build/boot/font.sff: font.sff build/boot
|
||||
@printf "CP %s\n" $@
|
||||
@cp $< $@
|
||||
|
|
|
|||
BIN
doom1.wad
Normal file
BIN
doom1.wad
Normal file
Binary file not shown.
48601
include/PureDOOM.h
Normal file
48601
include/PureDOOM.h
Normal file
File diff suppressed because it is too large
Load diff
18
include/mouse.h
Normal file
18
include/mouse.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef KARLOS_MOUSED_H
|
||||
#define KARLOS_MOUSED_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MOUSE_BUTTON_MIDDLE (1 << 2)
|
||||
#define MOUSE_BUTTON_RIGHT (1 << 1)
|
||||
#define MOUSE_BUTTON_LEFT (1 << 0)
|
||||
|
||||
void on_mouse_event(int8_t mouse_x, int8_t mouse_y, uint8_t buttons);
|
||||
typedef void (*mouse_event_listener)(int8_t mouse_x, int8_t mouse_y, uint8_t buttons);
|
||||
|
||||
void register_mouse_event_listener(mouse_event_listener ls);
|
||||
void unregister_mouse_event_listener(mouse_event_listener ls);
|
||||
|
||||
#endif // KARLOS_MOUSED_H
|
||||
|
||||
|
|
@ -17,6 +17,7 @@ struct tar_header {
|
|||
uint8_t link_indicator;
|
||||
char *link_name;
|
||||
void *data;
|
||||
char *cur;
|
||||
};
|
||||
|
||||
int tar_get_file(const char *name, struct tar_header *hd_out);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ bool window_put(struct window *win, unsigned int row, unsigned int col, glyph g)
|
|||
void window_scroll(struct window *win);
|
||||
void window_clear(struct window *win);
|
||||
void window_clear_row(struct window *win, unsigned int row);
|
||||
void glyph_to_framebuffer(struct window *win, unsigned int cx, unsigned int cy, glyph chr, bool invert_color);
|
||||
void window_glyph_to_framebuffer(struct window *win, unsigned int row, unsigned int col, bool invert_color);
|
||||
glyph window_get(struct window *win, unsigned int row, unsigned int col);
|
||||
|
||||
void window_redraw(struct window *win);
|
||||
void window_get_position(unsigned int x, unsigned int y, unsigned int *row, unsigned int *col);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "interpreter.h"
|
||||
#include "keyboard.h"
|
||||
#include "mouse.h"
|
||||
#include "std.h"
|
||||
#include "console.h"
|
||||
#include "framebuffer.h"
|
||||
|
|
@ -30,6 +31,11 @@ int cout_cursor_y;
|
|||
int cin_cursor_x;
|
||||
int cin_cursor_y;
|
||||
|
||||
int mouse_x;
|
||||
int mouse_y;
|
||||
|
||||
bool clicked = false;
|
||||
|
||||
void console_editor_key_event_listener(enum editor_key_event_kind kind, uint32_t codepoint);
|
||||
|
||||
void console_init(void)
|
||||
|
|
@ -62,11 +68,41 @@ void cin_clear() {
|
|||
window_glyph_to_framebuffer(&cin_win, cin_cursor_y, cin_cursor_x, true);
|
||||
}
|
||||
|
||||
|
||||
void console_mouse_event_listener(int8_t rel_x, int8_t rel_y, uint8_t buttons) {
|
||||
mouse_x += rel_x;
|
||||
mouse_y -= rel_y;
|
||||
window_redraw(&cout_win);
|
||||
window_redraw(&cin_win);
|
||||
if (clicked && (buttons & MOUSE_BUTTON_LEFT) == 0) {
|
||||
printf("clicked\n");
|
||||
unsigned int row,col;
|
||||
glyph chr;
|
||||
window_get_position(mouse_x, mouse_y, &row, &col);
|
||||
|
||||
// window_put(&cout_win, row, col, '#');
|
||||
// chr = window_get(&cout_win, row, col);
|
||||
do {
|
||||
chr = window_get(&cout_win, row, col);
|
||||
cin_putc(chr);
|
||||
col++;
|
||||
} while (chr != ' ' && chr != 0 && col < cout_win.num_cols);
|
||||
cin_putc('\n');
|
||||
|
||||
}
|
||||
glyph_to_framebuffer(&cout_win, mouse_x, mouse_y, '<', false);
|
||||
fb_refresh();
|
||||
clicked = buttons & MOUSE_BUTTON_LEFT;
|
||||
}
|
||||
|
||||
void console_start(void)
|
||||
{
|
||||
cout_clear();
|
||||
cin_clear();
|
||||
mouse_y = 20;
|
||||
mouse_x = 20;
|
||||
register_editor_key_event_listener(console_editor_key_event_listener);
|
||||
register_mouse_event_listener(console_mouse_event_listener);
|
||||
}
|
||||
|
||||
void console_stop(void)
|
||||
|
|
@ -74,6 +110,7 @@ void console_stop(void)
|
|||
// TODO make sure that printf() doesn't result in stuff being drawn on screen
|
||||
// for as long as the console is stopped!
|
||||
unregister_editor_key_event_listener(console_editor_key_event_listener);
|
||||
unregister_mouse_event_listener(console_mouse_event_listener);
|
||||
}
|
||||
|
||||
void cout_putc(uint32_t c)
|
||||
|
|
|
|||
261
src/doom.c
Normal file
261
src/doom.c
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "ram.h"
|
||||
#include "framebuffer.h"
|
||||
#include "keyboard.h"
|
||||
#include "time.h"
|
||||
#include "std.h"
|
||||
#include "tar.h"
|
||||
#include "mouse.h"
|
||||
|
||||
#define DOOM_IMPLEMENTATION
|
||||
#include "PureDOOM.h"
|
||||
|
||||
#define WIDTH 320
|
||||
#define HEIGHT 200
|
||||
|
||||
void* my_malloc(int size) {
|
||||
// printf("malloc\n");
|
||||
struct ram_buffer_requirements req;
|
||||
req.align = 0;
|
||||
req.limit4gb = 0;
|
||||
req.size = size;
|
||||
struct ppn ppn;
|
||||
// FIX: only allocatesd 4096??? see impl
|
||||
if (!ram_alloc_buffer(&ppn, req)) {
|
||||
printf("fb: Unable to allocate backbuffer.\n");
|
||||
return 0;
|
||||
}
|
||||
return pa_to_pointer(pa_from_ppn(ppn));
|
||||
}
|
||||
|
||||
void my_free(void *ptr) {
|
||||
(void) ptr;
|
||||
}
|
||||
|
||||
void my_printf(const char *str) {
|
||||
(void) str;
|
||||
printf("%s", str);
|
||||
|
||||
// fb_damage(region.rect);
|
||||
fb_refresh();
|
||||
}
|
||||
|
||||
void my_gettime(int *sec, int *usec) {
|
||||
Time t = time_current();
|
||||
*sec = t.sec;
|
||||
*usec = TIME_TO_NS(t) / 1000;
|
||||
}
|
||||
|
||||
struct tar_header file_handles[64] = {0};
|
||||
size_t file_handles_num = 0;
|
||||
|
||||
void* my_open(const char* filename, const char* mode) {
|
||||
(void) mode;
|
||||
if (!tar_get_file(filename, &file_handles[file_handles_num]))
|
||||
return 0;
|
||||
file_handles[file_handles_num].cur = file_handles[file_handles_num].data;
|
||||
// return (void*) file_handles_num++;
|
||||
return &file_handles[file_handles_num++];
|
||||
}
|
||||
|
||||
void my_close(void* handle) {
|
||||
(void) handle;
|
||||
}
|
||||
|
||||
int my_read(void* handle, void *buf, int count) {
|
||||
memcpy(buf, ((struct tar_header*) handle)->cur, count);
|
||||
((struct tar_header*) handle)->cur += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
int my_write(void* handle, const void *buf, int count) {
|
||||
(void) handle;
|
||||
(void) buf;
|
||||
(void) count;
|
||||
return count;
|
||||
}
|
||||
|
||||
int my_seek(void* handle, int offset, doom_seek_t origin) {
|
||||
struct tar_header *file = handle;
|
||||
switch (origin) {
|
||||
case DOOM_SEEK_CUR:
|
||||
file->cur += offset;
|
||||
break;
|
||||
case DOOM_SEEK_END:
|
||||
file->cur = file->data + file->size + offset;
|
||||
break;
|
||||
case DOOM_SEEK_SET:
|
||||
file->cur = file->data + offset;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int my_tell(void* handle) {
|
||||
struct tar_header *file = handle;
|
||||
return file->cur - (char*) file->data;
|
||||
}
|
||||
|
||||
int my_eof(void* handle) {
|
||||
(void) handle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* my_getenv(const char* var) {
|
||||
(void) var;
|
||||
return "doom";
|
||||
}
|
||||
|
||||
doom_key_t key_to_doom_key[] = {
|
||||
[KEY_TAB] = DOOM_KEY_TAB,
|
||||
[KEY_ENTER] = DOOM_KEY_ENTER,
|
||||
[KEY_ESCAPE] = DOOM_KEY_ESCAPE,
|
||||
[KEY_SPACE] = DOOM_KEY_SPACE,
|
||||
[KEY_COMMA] = DOOM_KEY_COMMA,
|
||||
[KEY_MINUS] = DOOM_KEY_MINUS,
|
||||
[KEY_PERIOD] = DOOM_KEY_PERIOD,
|
||||
[KEY_0] = DOOM_KEY_0,
|
||||
[KEY_1] = DOOM_KEY_1,
|
||||
[KEY_2] = DOOM_KEY_2,
|
||||
[KEY_3] = DOOM_KEY_3,
|
||||
[KEY_4] = DOOM_KEY_4,
|
||||
[KEY_5] = DOOM_KEY_5,
|
||||
[KEY_6] = DOOM_KEY_6,
|
||||
[KEY_7] = DOOM_KEY_7,
|
||||
[KEY_8] = DOOM_KEY_8,
|
||||
[KEY_9] = DOOM_KEY_9,
|
||||
[KEY_EQUALS] = DOOM_KEY_EQUALS,
|
||||
[KEY_A] = DOOM_KEY_A,
|
||||
[KEY_B] = DOOM_KEY_B,
|
||||
[KEY_C] = DOOM_KEY_C,
|
||||
[KEY_D] = DOOM_KEY_D,
|
||||
[KEY_E] = DOOM_KEY_E,
|
||||
[KEY_F] = DOOM_KEY_F,
|
||||
[KEY_G] = DOOM_KEY_G,
|
||||
[KEY_H] = DOOM_KEY_H,
|
||||
[KEY_I] = DOOM_KEY_I,
|
||||
[KEY_J] = DOOM_KEY_J,
|
||||
[KEY_K] = DOOM_KEY_K,
|
||||
[KEY_L] = DOOM_KEY_L,
|
||||
[KEY_M] = DOOM_KEY_M,
|
||||
[KEY_N] = DOOM_KEY_N,
|
||||
[KEY_O] = DOOM_KEY_O,
|
||||
[KEY_P] = DOOM_KEY_P,
|
||||
[KEY_Q] = DOOM_KEY_Q,
|
||||
[KEY_R] = DOOM_KEY_R,
|
||||
[KEY_S] = DOOM_KEY_S,
|
||||
[KEY_T] = DOOM_KEY_T,
|
||||
[KEY_U] = DOOM_KEY_U,
|
||||
[KEY_V] = DOOM_KEY_V,
|
||||
[KEY_W] = DOOM_KEY_W,
|
||||
[KEY_X] = DOOM_KEY_X,
|
||||
[KEY_Y] = DOOM_KEY_Y,
|
||||
[KEY_Z] = DOOM_KEY_Z,
|
||||
[KEY_BACKSPACE] = DOOM_KEY_BACKSPACE,
|
||||
[KEY_ARROW_LEFT] = DOOM_KEY_LEFT_ARROW,
|
||||
[KEY_ARROW_UP] = DOOM_KEY_UP_ARROW,
|
||||
[KEY_ARROW_RIGHT] = DOOM_KEY_RIGHT_ARROW,
|
||||
[KEY_ARROW_DOWN] = DOOM_KEY_DOWN_ARROW,
|
||||
[KEY_F1] = DOOM_KEY_F1,
|
||||
[KEY_F2] = DOOM_KEY_F2,
|
||||
[KEY_F3] = DOOM_KEY_F3,
|
||||
[KEY_F4] = DOOM_KEY_F4,
|
||||
[KEY_F5] = DOOM_KEY_F5,
|
||||
[KEY_F6] = DOOM_KEY_F6,
|
||||
[KEY_F7] = DOOM_KEY_F7,
|
||||
[KEY_F8] = DOOM_KEY_F8,
|
||||
[KEY_F9] = DOOM_KEY_F9,
|
||||
[KEY_F10] = DOOM_KEY_F10,
|
||||
[KEY_F11] = DOOM_KEY_F11,
|
||||
[KEY_F12] = DOOM_KEY_F12,
|
||||
[KEY_PAUSE] = DOOM_KEY_PAUSE,
|
||||
};
|
||||
|
||||
void doom_key_event_listener(enum keycode code, bool pressed) {
|
||||
if (pressed) {
|
||||
doom_key_down(key_to_doom_key[code]);
|
||||
if (code == KEY_SPACE) doom_button_down(DOOM_LEFT_BUTTON);
|
||||
if (code == KEY_ARROW_LEFT) doom_mouse_move(-10, 0);
|
||||
if (code == KEY_ARROW_RIGHT) doom_mouse_move(10, 0);
|
||||
} else {
|
||||
doom_key_up(key_to_doom_key[code]);
|
||||
if (code == KEY_SPACE) doom_button_up(DOOM_LEFT_BUTTON);
|
||||
}
|
||||
}
|
||||
|
||||
void doom_mouse_event_listener(int8_t mouse_x, int8_t mouse_y, uint8_t buttons) {
|
||||
static uint8_t mouse_btn_left_old = 0;
|
||||
static uint8_t mouse_btn_middle_old = 0;
|
||||
static uint8_t mouse_btn_right_old = 0;
|
||||
|
||||
doom_mouse_move(mouse_x * 20, mouse_y * 20);
|
||||
if (!mouse_btn_left_old && (buttons & MOUSE_BUTTON_LEFT )) doom_button_down(DOOM_LEFT_BUTTON);
|
||||
if (!mouse_btn_middle_old && (buttons & MOUSE_BUTTON_MIDDLE)) doom_button_down(DOOM_MIDDLE_BUTTON);
|
||||
if (!mouse_btn_right_old && (buttons & MOUSE_BUTTON_RIGHT )) doom_button_down(DOOM_RIGHT_BUTTON);
|
||||
if (mouse_btn_left_old && !(buttons & MOUSE_BUTTON_LEFT )) doom_button_up(DOOM_LEFT_BUTTON);
|
||||
if (mouse_btn_middle_old && !(buttons & MOUSE_BUTTON_MIDDLE)) doom_button_up(DOOM_MIDDLE_BUTTON);
|
||||
if (mouse_btn_right_old && !(buttons & MOUSE_BUTTON_RIGHT )) doom_button_up(DOOM_RIGHT_BUTTON);
|
||||
|
||||
mouse_btn_left_old = buttons & MOUSE_BUTTON_LEFT;
|
||||
mouse_btn_middle_old = buttons & MOUSE_BUTTON_MIDDLE;
|
||||
mouse_btn_right_old = buttons & MOUSE_BUTTON_RIGHT;
|
||||
}
|
||||
|
||||
void doom_start(void)
|
||||
{
|
||||
struct fb_region region;
|
||||
struct rect desiredRect = RECT_XYWH(
|
||||
0,
|
||||
0,
|
||||
WIDTH,
|
||||
HEIGHT);
|
||||
fb_access_region(desiredRect, ®ion);
|
||||
|
||||
|
||||
register_raw_key_event_listener(doom_key_event_listener);
|
||||
register_mouse_event_listener(doom_mouse_event_listener);
|
||||
|
||||
doom_set_malloc(my_malloc, my_free);
|
||||
doom_set_print(my_printf);
|
||||
doom_set_gettime(my_gettime);
|
||||
doom_set_file_io(
|
||||
my_open,
|
||||
my_close,
|
||||
my_read,
|
||||
my_write,
|
||||
my_seek,
|
||||
my_tell,
|
||||
my_eof
|
||||
);
|
||||
doom_set_getenv(my_getenv);
|
||||
|
||||
doom_set_default_int("key_up", DOOM_KEY_W);
|
||||
doom_set_default_int("key_down", DOOM_KEY_S);
|
||||
doom_set_default_int("key_strafeleft", DOOM_KEY_A);
|
||||
doom_set_default_int("key_straferight", DOOM_KEY_D);
|
||||
doom_set_default_int("key_use", DOOM_KEY_E);
|
||||
|
||||
doom_init(0, 0, 0); // arguments have to be 0; we dont need response file
|
||||
|
||||
while (true)
|
||||
{
|
||||
doom_update();
|
||||
const uint32_t* framebuffer = (uint32_t*) doom_get_framebuffer(4 /* RGBA */);
|
||||
|
||||
|
||||
char *rowPointer = region.pointer;
|
||||
for (int y = region.rect.y1; y < region.rect.y2; y++) {
|
||||
uint32_t *pixel = (uint32_t *)rowPointer;
|
||||
for (int x = region.rect.x1; x < region.rect.x2; x++) {
|
||||
fb_set_px(x, y, *(struct color*) &framebuffer[y * WIDTH + x]);
|
||||
// *pixel = (framebuffer[y * WIDTH + x] >> 8) | 0xFF000000;
|
||||
pixel++;
|
||||
}
|
||||
rowPointer += region.stride;
|
||||
}
|
||||
fb_damage(region.rect);
|
||||
fb_refresh();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ static void interpreter_timer_callback(Timer *timer) {
|
|||
extern void (*task)(void);
|
||||
|
||||
void interpret_handle_input_line(const uint8_t *s) {
|
||||
|
||||
|
||||
printf(">>> %s\n", s);
|
||||
if (memcmp(s, "echo", 4) == 0) {
|
||||
s += 4;
|
||||
|
|
@ -91,6 +91,9 @@ void interpret_handle_input_line(const uint8_t *s) {
|
|||
} else if (memcmp(s, "city", 4) == 0) {
|
||||
extern void city_main(void);
|
||||
task = city_main;
|
||||
} else if (memcmp(s, "doom", 4) == 0) {
|
||||
extern void doom_start(void);
|
||||
task = doom_start;
|
||||
} else if (memcmp(s, "help", 4) == 0 || memcmp(s, "?", 1) == 0) {
|
||||
printf("The following commands are available:\n");
|
||||
printf("help -- Print this information to the screen\n");
|
||||
|
|
|
|||
18
src/kernel.c
18
src/kernel.c
|
|
@ -82,15 +82,15 @@ void _start() {
|
|||
console_stop();
|
||||
|
||||
// HACK Clear the screen
|
||||
struct fb_region region;
|
||||
struct rect desiredRect = RECT_XYWH(
|
||||
0, 0,
|
||||
fb_width(),
|
||||
fb_height());
|
||||
fb_access_region(desiredRect, ®ion);
|
||||
memset(region.pointer, 0, region.stride * region.rect.y2);
|
||||
fb_damage(region.rect);
|
||||
fb_refresh();
|
||||
// struct fb_region region;
|
||||
// struct rect desiredRect = RECT_XYWH(
|
||||
// 0, 0,
|
||||
// fb_width(),
|
||||
// fb_height());
|
||||
// fb_access_region(desiredRect, ®ion);
|
||||
// memset(region.pointer, 0, region.stride * region.rect.y2);
|
||||
// fb_damage(region.rect);
|
||||
// fb_refresh();
|
||||
|
||||
task();
|
||||
task = NULL;
|
||||
|
|
|
|||
31
src/mouse.c
Normal file
31
src/mouse.c
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#include "std.h"
|
||||
#include <stdint.h>
|
||||
#include "mouse.h"
|
||||
|
||||
#define NUM_LISTENERS 10
|
||||
mouse_event_listener listeners[NUM_LISTENERS];
|
||||
size_t num_listeners = 0;
|
||||
|
||||
void register_mouse_event_listener(mouse_event_listener ls) {
|
||||
ASSERT(num_listeners < NUM_LISTENERS);
|
||||
listeners[num_listeners++] = ls;
|
||||
}
|
||||
|
||||
void unregister_mouse_event_listener(mouse_event_listener ls) {
|
||||
for (size_t i = 0; i < num_listeners; i++) {
|
||||
if (listeners[i] == ls) {
|
||||
num_listeners--;
|
||||
for (size_t j = i; j < num_listeners; j++) {
|
||||
listeners[j] = listeners[j+1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void on_mouse_event(int8_t mouse_x, int8_t mouse_y, uint8_t buttons) {
|
||||
for (size_t i = 0; i < num_listeners; i++) {
|
||||
listeners[i](mouse_x, mouse_y, buttons);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
#include "std.h"
|
||||
#include "console.h"
|
||||
#include "unicode.h"
|
||||
#include "x86_64/uart.h"
|
||||
|
||||
#include "x86_64/interrupt.h"
|
||||
|
||||
|
|
@ -80,7 +81,7 @@ static void linebuf_flush(void) {
|
|||
int int_state = int_disable();
|
||||
for (unsigned int i = 0; i < current_buffer_position; i++) {
|
||||
// TODO
|
||||
// serial_write_char(linebuf[i]);
|
||||
uart_write_char(linebuf[i]);
|
||||
cout_putc(linebuf[i]);
|
||||
}
|
||||
current_buffer_position = 0;
|
||||
|
|
|
|||
47
src/window.c
47
src/window.c
|
|
@ -121,6 +121,34 @@ static struct rect display_from_font(
|
|||
}
|
||||
|
||||
// #define WINDOW_USE_REPLACEMENT_CHAR
|
||||
struct rect glyph_to_framebuffer_norefresh(struct window *win,
|
||||
unsigned int cx, unsigned int cy, glyph chr, bool invert_color) {
|
||||
struct rect rect;
|
||||
if (chr == 0) { chr = ' '; }
|
||||
struct sff_glyph_offset off = sff_find_glyph(&font_file, chr);
|
||||
if (SFF_GLYPH_FOUND(off)) {
|
||||
rect = display_from_font(win, cx, cy, off, invert_color);
|
||||
} else {
|
||||
#if defined(WINDOW_USE_REPLACEMENT_CHAR)
|
||||
off = sff_find_glyph(&font_file, UNICODE_REPLACEMENT_CHARACTER);
|
||||
ASSERT(SFF_GLYPH_FOUND(off));
|
||||
rect = display_from_font(win, cx, cy, off, invert_color);
|
||||
#else
|
||||
ASSERT(font_file.char_width >= 8 && font_file.char_height >= 18);
|
||||
rect = display_err_unicode_hex(win, cx, cy, chr, invert_color);
|
||||
#endif
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
void glyph_to_framebuffer(struct window *win,
|
||||
unsigned int cx, unsigned int cy, glyph chr, bool invert_color)
|
||||
{
|
||||
struct rect rect = glyph_to_framebuffer_norefresh(win, cx, cy, chr, invert_color);
|
||||
fb_damage(rect);
|
||||
//fb_refresh();
|
||||
}
|
||||
|
||||
|
||||
struct rect window_glyph_to_framebuffer_norefresh(struct window *win,
|
||||
unsigned int row, unsigned int col, bool invert_color)
|
||||
|
|
@ -226,3 +254,22 @@ glyph window_get(struct window *win, unsigned int row, unsigned int col) {
|
|||
return win->data[row * win->num_cols + col];
|
||||
}
|
||||
|
||||
void window_redraw(struct window *win) {
|
||||
struct fb_region region;
|
||||
fb_access_region(win->rect, ®ion);
|
||||
for (unsigned row = 0; row < RECT_HEIGHT(region.rect); row++) {
|
||||
memset((char *)region.pointer + region.stride * row, 0, 4 * RECT_WIDTH(region.rect));
|
||||
}
|
||||
fb_damage(region.rect);
|
||||
for (unsigned int row = 0; row < win->num_rows; row++) {
|
||||
for(unsigned int col = 0; col < win->num_cols; col++) {
|
||||
window_put(win, row, col, win->data[row * win->num_cols + col]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void window_get_position(unsigned int x, unsigned int y, unsigned int *row, unsigned int *col) {
|
||||
*row = y / font_file.char_height;
|
||||
*col = x / font_file.char_width;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "mouse.h"
|
||||
#include "std.h"
|
||||
#include "x86_64/apic.h"
|
||||
#include "x86_64/asm.h"
|
||||
|
|
@ -252,15 +253,57 @@ void port1_handler(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#define MOUSE_PACKET_Y_OVERFLOW 7
|
||||
#define MOUSE_PACKET_X_OVERFLOW 6
|
||||
#define MOUSE_PACKET_Y_SIGN 5
|
||||
#define MOUSE_PACKET_X_SIGN 4
|
||||
#define MOUSE_PACKET_ONE 3
|
||||
#define MOUSE_PACKET_BUTTON_MIDDLE 2
|
||||
#define MOUSE_PACKET_BUTTON_RIGHT 1
|
||||
#define MOUSE_PACKET_BUTTON_LEFT 0
|
||||
|
||||
size_t mouse_packet_byte = 0;
|
||||
union {
|
||||
uint8_t arr[3];
|
||||
struct mouse_packet {
|
||||
uint8_t buttons, x, y;
|
||||
} mouse;
|
||||
} mouse;
|
||||
|
||||
void port2_handler(void) {
|
||||
if (!ps2_can_read()) {
|
||||
// Assume spurious interrupt. Maybe from another device?
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t data = ps2_read_data();
|
||||
(void)data;
|
||||
DEBUG_PRINTF("keycode from port 2: %X8\n", data);
|
||||
uint8_t data = ps2_read_data();
|
||||
DEBUG_PRINTF("keycode from port 2: %X8\n", data);
|
||||
if ((mouse_packet_byte == 0) && ((data & (1 << MOUSE_PACKET_ONE)) == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int8_t x = mouse.mouse.x - ((mouse.mouse.buttons << 4) & 0x100);
|
||||
int8_t y = mouse.mouse.y - ((mouse.mouse.buttons << 3) & 0x100);
|
||||
|
||||
mouse.arr[mouse_packet_byte++] = data;
|
||||
if (mouse_packet_byte == 3) {
|
||||
mouse_packet_byte = 0;
|
||||
on_mouse_event(x, y, mouse.mouse.buttons & (MOUSE_BUTTON_MIDDLE | MOUSE_BUTTON_RIGHT | MOUSE_BUTTON_LEFT));
|
||||
DEBUG_PRINTF(
|
||||
"mouse event: %u %u %u %u %u %u %u, X: %d, Y: %d, [%u, %u]\n",
|
||||
mouse.mouse.buttons >> MOUSE_PACKET_Y_OVERFLOW & 1,
|
||||
mouse.mouse.buttons >> MOUSE_PACKET_X_OVERFLOW & 1,
|
||||
mouse.mouse.buttons >> MOUSE_PACKET_Y_SIGN & 1,
|
||||
mouse.mouse.buttons >> MOUSE_PACKET_X_SIGN & 1,
|
||||
mouse.mouse.buttons >> MOUSE_PACKET_BUTTON_MIDDLE & 1,
|
||||
mouse.mouse.buttons >> MOUSE_PACKET_BUTTON_RIGHT & 1,
|
||||
mouse.mouse.buttons >> MOUSE_PACKET_BUTTON_LEFT & 1,
|
||||
x,
|
||||
y,
|
||||
mouse.mouse.x,
|
||||
mouse.mouse.y
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#define PS2_INIT_PRINT
|
||||
|
|
@ -282,14 +325,14 @@ void ps2_init() {
|
|||
|
||||
/* Flush Outputbuffer */
|
||||
ps2_empty_output_buffer();
|
||||
|
||||
|
||||
/* Set Configbyte */
|
||||
config_byte = ps2_cmd_response(CMD_CONFIGBYTE_READ);
|
||||
config_byte &= ~(1 << CONFIG_BIT_PORT1_INT_ENABLED);
|
||||
config_byte &= ~(1 << CONFIG_BIT_PORT1_CLOCK_DISABLED);
|
||||
config_byte &= ~(1 << CONFIG_BIT_PORT1_TRANSLATION);
|
||||
ps2_cmd_with_data(CMD_CONFIGBYTE_WRITE, config_byte);
|
||||
|
||||
|
||||
/* Selftest */
|
||||
uint8_t test = ps2_cmd_response(CMD_TEST);
|
||||
PS2_TEST("self-test", test, 0x55);
|
||||
|
|
@ -299,7 +342,8 @@ void ps2_init() {
|
|||
config_byte = ps2_cmd_response(CMD_CONFIGBYTE_READ);
|
||||
bool port_2_enabled = ((config_byte >> 5) & 1) == 0;
|
||||
if (port_2_enabled) {
|
||||
ps2_write_cmd(CMD_PORT2_DISABLE);
|
||||
DEBUG_PRINTF("port 2 enabled\n");
|
||||
ps2_write_cmd(CMD_PORT2_DISABLE);
|
||||
config_byte = ps2_cmd_response(CMD_CONFIGBYTE_READ);
|
||||
config_byte &= ~(1 << CONFIG_BIT_PORT2_INT_ENABLED);
|
||||
config_byte &= ~(1 << CONFIG_BIT_PORT2_CLOCK_DISABLED);
|
||||
|
|
@ -338,6 +382,16 @@ void ps2_init() {
|
|||
ps2_write_data(0xFF);
|
||||
ps2_read_data();
|
||||
// TODO reset port 2
|
||||
if (port_2_enabled) {
|
||||
ps2_write_cmd(0xD4);
|
||||
ps2_write_data(0xFF);
|
||||
// ps2_read_data();
|
||||
ps2_empty_output_buffer();
|
||||
ps2_write_cmd(0xD4);
|
||||
ps2_write_data(0xF4);
|
||||
ps2_empty_output_buffer();
|
||||
// ps2_read_data();
|
||||
}
|
||||
|
||||
/* Enable interrupts */
|
||||
config_byte = ps2_cmd_response(CMD_CONFIGBYTE_READ);
|
||||
|
|
@ -348,5 +402,5 @@ void ps2_init() {
|
|||
ps2_cmd_with_data(CMD_CONFIGBYTE_WRITE, config_byte);
|
||||
|
||||
/* Flush Outputbuffer again because it doesn't work otherwise */
|
||||
//ps2_empty_output_buffer();
|
||||
ps2_empty_output_buffer();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue