76 lines
2.3 KiB
C++
76 lines
2.3 KiB
C++
#include <devices/cursor.h>
|
||
#include <devices/mouse.h>
|
||
#include <graphics/draw.h>
|
||
#include <graphics/context.h>
|
||
#include <memory/heap.h>
|
||
#include <common.h>
|
||
|
||
// 经典箭头光标位图 (12x16)
|
||
// 0=透明, 1=白色填充, 2=黑色轮廓
|
||
static const SUINT8 g_cursor_bitmap[CURSOR_H][CURSOR_W] = {
|
||
{2,0,0,0,0,0,0,0,0,0,0,0},
|
||
{2,2,0,0,0,0,0,0,0,0,0,0},
|
||
{2,1,2,0,0,0,0,0,0,0,0,0},
|
||
{2,1,1,2,0,0,0,0,0,0,0,0},
|
||
{2,1,1,1,2,0,0,0,0,0,0,0},
|
||
{2,1,1,1,1,2,0,0,0,0,0,0},
|
||
{2,1,1,1,1,1,2,0,0,0,0,0},
|
||
{2,1,1,1,1,1,1,2,0,0,0,0},
|
||
{2,1,1,1,1,1,1,1,2,0,0,0},
|
||
{2,1,1,1,1,1,1,1,1,2,0,0},
|
||
{2,1,1,1,1,1,2,2,2,2,2,0},
|
||
{2,1,1,2,1,2,0,0,0,0,0,0},
|
||
{2,1,2,0,0,2,0,0,0,0,0,0},
|
||
{2,2,0,0,0,0,2,0,0,0,0,0},
|
||
{2,0,0,0,0,0,2,0,0,0,0,0},
|
||
{0,0,0,0,0,0,0,0,0,0,0,0},
|
||
};
|
||
|
||
static layer_t* g_cursor_layer = NULL;
|
||
|
||
void cursor_init(void) {
|
||
g_cursor_layer = layer_create("cursor", LAYER_TYPE_MOUSE, CURSOR_W, CURSOR_H);
|
||
if (!g_cursor_layer) return;
|
||
|
||
layer_set_z(g_cursor_layer, 9999);
|
||
|
||
// 将位图写入图层缓冲区,Reserved 用作 alpha(0=透明, 255=不透明)
|
||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* buf = g_cursor_layer->buffer;
|
||
for (UINT32 y = 0; y < CURSOR_H; y++) {
|
||
for (UINT32 x = 0; x < CURSOR_W; x++) {
|
||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* dst = &buf[y * CURSOR_W + x];
|
||
SUINT8 px = g_cursor_bitmap[y][x];
|
||
if (px == 1) {
|
||
dst->Blue = 255; dst->Green = 255; dst->Red = 255; dst->Reserved = 255;
|
||
} else if (px == 2) {
|
||
dst->Blue = 0; dst->Green = 0; dst->Red = 0; dst->Reserved = 255;
|
||
} else {
|
||
dst->Blue = 0; dst->Green = 0; dst->Red = 0; dst->Reserved = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 初始位置:屏幕中心
|
||
layer_set_pos(g_cursor_layer,
|
||
(SSINT32)(g_gfx.hr / 2),
|
||
(SSINT32)(g_gfx.vr / 2));
|
||
}
|
||
|
||
void cursor_update(void) {
|
||
if (!g_cursor_layer) return;
|
||
|
||
SSINT32 cx = (SSINT32)(g_gfx.hr / 2) + mouse_get_x();
|
||
SSINT32 cy = (SSINT32)(g_gfx.vr / 2) + mouse_get_y();
|
||
|
||
if (cx < 0) cx = 0;
|
||
if (cy < 0) cy = 0;
|
||
if (cx + (SSINT32)CURSOR_W > (SSINT32)g_gfx.hr) cx = (SSINT32)g_gfx.hr - CURSOR_W;
|
||
if (cy + (SSINT32)CURSOR_H > (SSINT32)g_gfx.vr) cy = (SSINT32)g_gfx.vr - CURSOR_H;
|
||
|
||
layer_set_pos(g_cursor_layer, cx, cy);
|
||
}
|
||
|
||
layer_t* cursor_get_layer(void) {
|
||
return g_cursor_layer;
|
||
}
|