graphics, kernel: update cursor pos on kMain hlt hit
This commit is contained in:
parent
def2c3bf7a
commit
dfce649314
@ -1,6 +1,7 @@
|
||||
|
||||
|
||||
#include "graphics.h"
|
||||
#include "color.h"
|
||||
#include "unifont.h"
|
||||
#include "../runtime/stdio.h"
|
||||
#include <efiprot.h>
|
||||
@ -26,14 +27,17 @@ static EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
|
||||
static EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
|
||||
static UINTN sizeofInfo, nModes, nativeMode;
|
||||
static HelosGraphics_Mode modes[128];
|
||||
HelosGraphics_Mode graphics_SystemVideoMode;
|
||||
|
||||
void *graphics_DeviceFramebuffer;
|
||||
|
||||
void * graphics_Framebuffer;
|
||||
uint64_t graphics_FramebufferSize;
|
||||
|
||||
uint32_t graphics_Doublebuffer[2048 * 1024];
|
||||
|
||||
xcursor_ChunkHeader_Image *graphics_Cursor;
|
||||
int graphics_MouseCursorX, graphics_MouseCursorY;
|
||||
|
||||
|
||||
void graphics_Init() {
|
||||
assert(sizeof(HelosGraphics_Color) == sizeof(uint32_t) && "HelosGraphics_Color not packed to be 32-bit(4 bytes)");
|
||||
@ -99,8 +103,12 @@ void graphics_Init() {
|
||||
}
|
||||
#undef CASE
|
||||
|
||||
graphics_Framebuffer = (void *)graphics_Doublebuffer;
|
||||
graphics_SystemVideoMode = modes[nativeMode];
|
||||
graphics_Framebuffer = (void *)graphics_Doublebuffer;
|
||||
graphics_CursorX = graphics_CursorY = 0;
|
||||
|
||||
graphics_MouseCursorX = graphics_SystemVideoMode.Width / 2;
|
||||
graphics_MouseCursorY = graphics_SystemVideoMode.Height / 2;
|
||||
}
|
||||
|
||||
|
||||
@ -112,17 +120,17 @@ void graphics_SetPixel_RGB(int posX, int posY, const HelosGraphics_Color *color)
|
||||
uint8_t A;
|
||||
} colorRGB = {color->R, color->G, color->B, 0};
|
||||
|
||||
*((uint32_t *)(graphics_Framebuffer + modes[nativeMode].PixelsPerLine * 4 * posY + 4 * posX)) = (*((uint32_t *)&colorRGB));
|
||||
*((uint32_t *)(graphics_Framebuffer + graphics_SystemVideoMode.PixelsPerLine * 4 * posY + 4 * posX)) = (*((uint32_t *)&colorRGB));
|
||||
}
|
||||
|
||||
void graphics_SetPixel_BGR(int posX, int posY, const HelosGraphics_Color *color) {
|
||||
*((uint32_t *)(graphics_Framebuffer + modes[nativeMode].PixelsPerLine * 4 * posY + 4 * posX)) = (*((uint32_t *)color)) & 0x00ffffffu;
|
||||
*((uint32_t *)(graphics_Framebuffer + graphics_SystemVideoMode.PixelsPerLine * 4 * posY + 4 * posX)) = (*((uint32_t *)color)) & 0x00ffffffu;
|
||||
}
|
||||
|
||||
|
||||
void graphics_GetSize(int *sizeX, int *sizeY, int *bitsPerPixel) {
|
||||
*sizeX = modes[nativeMode].Width;
|
||||
*sizeY = modes[nativeMode].Height;
|
||||
*sizeX = graphics_SystemVideoMode.Width;
|
||||
*sizeY = graphics_SystemVideoMode.Height;
|
||||
*bitsPerPixel = 24;
|
||||
}
|
||||
|
||||
@ -134,13 +142,13 @@ void graphics_ClearBuffer(const HelosGraphics_Color *color) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (modes[nativeMode].PixelFormat == PixelRedGreenBlueReserved8BitPerColor) {
|
||||
if (graphics_SystemVideoMode.PixelFormat == PixelRedGreenBlueReserved8BitPerColor) {
|
||||
struct {
|
||||
uint8_t R, G, B;
|
||||
uint8_t A;
|
||||
} colorRGB = {color->R, color->G, color->B, 0};
|
||||
data = (*(uint32_t *)&colorRGB) & 0x00ffffffu;
|
||||
} else if (modes[nativeMode].PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
|
||||
} else if (graphics_SystemVideoMode.PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
|
||||
data = (*(uint32_t *)color) & 0x00ffffffu;
|
||||
}
|
||||
|
||||
@ -151,17 +159,47 @@ void graphics_ClearBuffer(const HelosGraphics_Color *color) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline size_t min(size_t x, size_t y) {
|
||||
return x < y ? x : y;
|
||||
}
|
||||
|
||||
void graphics_SwapBuffer() {
|
||||
memcpy(graphics_DeviceFramebuffer, graphics_Framebuffer, graphics_FramebufferSize);
|
||||
|
||||
if (graphics_Cursor) {
|
||||
// TODO Optimize mouse cursor overlay render
|
||||
/*if (graphics_SystemVideoMode.PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
|
||||
for (int i = 0; i < graphics_Cursor->height; i++) {
|
||||
if (graphics_MouseCursorY + i >= graphics_SystemVideoMode.Height)
|
||||
break;
|
||||
memcpy(
|
||||
graphics_DeviceFramebuffer + graphics_SystemVideoMode.PixelsPerLine * 4 * graphics_CursorY + 4 * graphics_CursorX,
|
||||
&graphics_Cursor->pixels[i * graphics_Cursor->width],
|
||||
min(graphics_Cursor->width, graphics_SystemVideoMode.Width - graphics_MouseCursorX) * 4);
|
||||
}
|
||||
} else {*/
|
||||
for (int y = 0; y < graphics_Cursor->height; y++) {
|
||||
if (graphics_MouseCursorY + y >= graphics_SystemVideoMode.Height)
|
||||
break;
|
||||
for (int x = 0; x < min(graphics_Cursor->width, graphics_SystemVideoMode.Width - graphics_MouseCursorX); x++) {
|
||||
//graphics_SetPixel_RGB(x + graphics_MouseCursorX, y + graphics_MouseCursorY, &graphics_Cursor->pixels[y * graphics_Cursor->width + x]);
|
||||
HelosGraphics_Color *pixel = &graphics_Cursor->pixels[y * graphics_Cursor->width + x];
|
||||
if (pixel->A <= 0x7f)
|
||||
continue;
|
||||
*((uint32_t *)(graphics_DeviceFramebuffer + graphics_SystemVideoMode.PixelsPerLine * 4 * (y + graphics_MouseCursorY) + 4 * (x + graphics_MouseCursorX))) = (*((uint32_t *)&graphics_Cursor->pixels[y * graphics_Cursor->width + x])) & 0x00ffffffu;
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
void graphics_FillPixel(int startX, int startY, int endX, int endY, const HelosGraphics_Color *color) {
|
||||
// TODO Optimize this! This is too sloooow
|
||||
if (gop->Mode->Info->PixelFormat == PixelBlueGreenRedReserved8BitPerColor)
|
||||
if (graphics_SystemVideoMode.PixelFormat == PixelBlueGreenRedReserved8BitPerColor)
|
||||
for (int i = startX; i < endX; i++)
|
||||
for (int j = startY; j < endY; j++)
|
||||
*((uint32_t *)(graphics_Framebuffer + modes[nativeMode].PixelsPerLine * 4 * j + 4 * i)) = (*((uint32_t *)color)) & 0x00ffffffu;
|
||||
else if (gop->Mode->Info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor)
|
||||
*((uint32_t *)(graphics_Framebuffer + graphics_SystemVideoMode.PixelsPerLine * 4 * j + 4 * i)) = (*((uint32_t *)color)) & 0x00ffffffu;
|
||||
else if (graphics_SystemVideoMode.PixelFormat == PixelRedGreenBlueReserved8BitPerColor)
|
||||
for (int i = startX; i < endX; i++)
|
||||
for (int j = startY; j < endY; j++) {
|
||||
struct {
|
||||
@ -169,7 +207,7 @@ void graphics_FillPixel(int startX, int startY, int endX, int endY, const HelosG
|
||||
uint8_t A;
|
||||
} colorRGB = {color->B, color->G, color->R, 0};
|
||||
|
||||
*((uint32_t *)(graphics_Framebuffer + modes[nativeMode].PixelsPerLine * 4 * j + 4 * i)) = (*((uint32_t *)&colorRGB));
|
||||
*((uint32_t *)(graphics_Framebuffer + graphics_SystemVideoMode.PixelsPerLine * 4 * j + 4 * i)) = (*((uint32_t *)&colorRGB));
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,24 +216,24 @@ int graphics_CursorX, graphics_CursorY;
|
||||
void graphics_Scroll(int scrollY) {
|
||||
memmove(
|
||||
graphics_Doublebuffer,
|
||||
graphics_Doublebuffer + modes[nativeMode].PixelsPerLine * scrollY,
|
||||
sizeof(uint32_t) * (modes[nativeMode].PixelsPerLine * (modes[nativeMode].Height - scrollY)));
|
||||
graphics_Doublebuffer + graphics_SystemVideoMode.PixelsPerLine * scrollY,
|
||||
sizeof(uint32_t) * (graphics_SystemVideoMode.PixelsPerLine * (graphics_SystemVideoMode.Height - scrollY)));
|
||||
// TODO proper memset instead of this sloooow FillPixel
|
||||
/*memset(
|
||||
graphics_Doublebuffer + modes[nativeMode].PixelsPerLine * (modes[nativeMode].Height - scrollY),
|
||||
graphics_Doublebuffer + graphics_SystemVideoMode.PixelsPerLine * (graphics_SystemVideoMode.Height - scrollY),
|
||||
0,
|
||||
sizeof(uint32_t) * modes[nativeMode].PixelsPerLine * (scrollY));*/
|
||||
graphics_FillPixel(0, modes[nativeMode].Height - scrollY, modes[nativeMode].Width, modes[nativeMode].Height, &HelosGraphics_Color_Black);
|
||||
sizeof(uint32_t) * graphics_SystemVideoMode.PixelsPerLine * (scrollY));*/
|
||||
graphics_FillPixel(0, graphics_SystemVideoMode.Height - scrollY, graphics_SystemVideoMode.Width, graphics_SystemVideoMode.Height, &HelosGraphics_Color_Black);
|
||||
}
|
||||
|
||||
void graphics_ElementSize(int sizeX, int sizeY) {
|
||||
if (graphics_CursorX + sizeX >= modes[nativeMode].Width) { // line breaking required
|
||||
if (graphics_CursorX + sizeX >= graphics_SystemVideoMode.Width) { // line breaking required
|
||||
graphics_CursorY += sizeY;
|
||||
graphics_CursorX = 0;
|
||||
}
|
||||
if (graphics_CursorY + sizeY >= modes[nativeMode].Height) { // scrolling required
|
||||
graphics_Scroll(sizeY + graphics_CursorY - modes[nativeMode].Height);
|
||||
graphics_CursorY = modes[nativeMode].Height - sizeY;
|
||||
if (graphics_CursorY + sizeY >= graphics_SystemVideoMode.Height) { // scrolling required
|
||||
graphics_Scroll(sizeY + graphics_CursorY - graphics_SystemVideoMode.Height);
|
||||
graphics_CursorY = graphics_SystemVideoMode.Height - sizeY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include "../main.h"
|
||||
#include "efiprot.h"
|
||||
|
||||
#include "color.h"
|
||||
#include "xcursor/xcursor.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -12,22 +14,6 @@ extern "C" {
|
||||
#define HELOS_GRAPHICS_TARGET_MODE_WIDTH 1600
|
||||
#define HELOS_GRAPHICS_TARGET_MODE_HEIGHT 900
|
||||
|
||||
// HelosGraphics_Color is in ARGB little-endian packed format
|
||||
// (B,G,R,A in byte order)
|
||||
typedef struct {
|
||||
uint8_t B, G, R;
|
||||
uint8_t A;
|
||||
} PACKED HelosGraphics_Color;
|
||||
|
||||
extern const HelosGraphics_Color
|
||||
HelosGraphics_Color_Black,
|
||||
HelosGraphics_Color_White,
|
||||
HelosGraphics_Color_Red,
|
||||
HelosGraphics_Color_Green,
|
||||
HelosGraphics_Color_Blue,
|
||||
HelosGraphics_Color_Cyan,
|
||||
HelosGraphics_Color_Magenta,
|
||||
HelosGraphics_Color_Yellow;
|
||||
|
||||
typedef struct {
|
||||
int Width, Height;
|
||||
@ -37,9 +23,13 @@ typedef struct {
|
||||
} HelosGraphics_Mode;
|
||||
|
||||
|
||||
extern void * graphics_DeviceFramebuffer; // this is the framebuffer directly for the device via memory mapping.
|
||||
extern void * graphics_Framebuffer; // this is the double-buffered framebuffer (back buffer)
|
||||
extern uint64_t graphics_FramebufferSize;
|
||||
extern void * graphics_DeviceFramebuffer; // this is the framebuffer directly for the device via memory mapping.
|
||||
extern void * graphics_Framebuffer; // this is the double-buffered framebuffer (back buffer)
|
||||
extern uint64_t graphics_FramebufferSize;
|
||||
extern HelosGraphics_Mode graphics_SystemVideoMode; // system video mode
|
||||
|
||||
extern xcursor_ChunkHeader_Image *graphics_Cursor; // mouse cursor image
|
||||
extern int graphics_MouseCursorX, graphics_MouseCursorY;
|
||||
|
||||
|
||||
// Init() must be called prior to ExitBootServices()
|
||||
|
@ -15,6 +15,10 @@
|
||||
#include "../execformat/pe/reloc.h"
|
||||
void execformat_pe_ReadSystemHeader(execformat_pe_PortableExecutable *pe);
|
||||
|
||||
#include "../graphics/graphics.h"
|
||||
#include "../graphics/xcursor/xcursor.h"
|
||||
#include "../embed/files.h"
|
||||
|
||||
static void tellRIP() {
|
||||
uint64_t a, b;
|
||||
asm volatile("leaq (%%rip), %0\n\tleaq runtime_InitPaging(%%rip), %1"
|
||||
@ -22,6 +26,14 @@ static void tellRIP() {
|
||||
io_Printf("tellRIP(): Stack position: %llx, RIP=%llx, kMain_StackPosition:%llx(%llx), interrupt_Int128: %llx\n", &a, a, (uint64_t)&kMain_StackPosition, b, (uint64_t)interrupt_Int128);
|
||||
}
|
||||
|
||||
static inline int minmax(int val, int min, int max) {
|
||||
if (val > max)
|
||||
return max;
|
||||
if (val < min)
|
||||
return min;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
SYSV_ABI void kMain() {
|
||||
io_WriteConsoleASCII("Yes! kMain survived!\n");
|
||||
@ -44,8 +56,43 @@ SYSV_ABI void kMain() {
|
||||
irq_pic_ps2_Init();
|
||||
io_WriteConsoleASCII("PIC PS/2 OK\n");
|
||||
|
||||
xcursor_Xcursor cursor;
|
||||
xcursor_LoadMemory(&cursor, (void *)embed_Xcursor_Default_Data, embed_Xcursor_Default_Data_End - embed_Xcursor_Default_Data);
|
||||
if (cursor.header) {
|
||||
for (int i = 0; i < cursor.n; i++) {
|
||||
if (cursor.toc[i].type == XCURSOR_CHUNKTYPE_IMAGE /*&& ((xcursor_ChunkHeader_Image *)(embed_Xcursor_Default_Data + cursor.toc[i].offset))->subtype == 24*/) {
|
||||
xcursor_ChunkHeader_Image *image = (xcursor_ChunkHeader_Image *)(embed_Xcursor_Default_Data + cursor.toc[i].offset);
|
||||
io_Printf("xcursor_Default: Loading size=%dx%d\n", image->width, image->height);
|
||||
graphics_Cursor = image;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
io_WriteConsoleASCII("xcursor_Default: failed to load\n");
|
||||
|
||||
for (;;) {
|
||||
asm volatile("hlt");
|
||||
io_WriteConsoleASCII("kMain: Interrupt hit\n");
|
||||
|
||||
while (queue_Size(&irq_pic_ps2_QueueMouse) >= (irq_pic_ps2_Mouse4Bytes ? 4 : 3)) {
|
||||
unsigned int moveX, moveY, state;
|
||||
|
||||
do {
|
||||
state = queue_PopByte(&irq_pic_ps2_QueueMouse);
|
||||
} while (!(state & (1u << 3)));
|
||||
|
||||
unsigned int d = queue_PopByte(&irq_pic_ps2_QueueMouse);
|
||||
moveX = d - ((state << 4) & 0x100);
|
||||
d = queue_PopByte(&irq_pic_ps2_QueueMouse);
|
||||
moveY = d - ((state << 3) & 0x100);
|
||||
|
||||
graphics_MouseCursorX = minmax(graphics_MouseCursorX + *((int *)&moveX), 0, graphics_SystemVideoMode.Width - 1);
|
||||
graphics_MouseCursorY = minmax(graphics_MouseCursorY - *((int *)&moveY), 0, graphics_SystemVideoMode.Height - 1);
|
||||
|
||||
if (irq_pic_ps2_Mouse4Bytes)
|
||||
queue_PopByte(&irq_pic_ps2_QueueMouse);
|
||||
}
|
||||
|
||||
//io_WriteConsoleASCII("kMain: Interrupt hit\n");
|
||||
graphics_SwapBuffer();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user