324 lines
12 KiB
C
324 lines
12 KiB
C
// dvxCursor.h -- Embedded mouse cursor bitmaps for DVX GUI
|
|
//
|
|
// All cursor shapes are compiled in as static const data -- no external
|
|
// cursor files to load. This is intentional: the cursors are needed
|
|
// before any file I/O infrastructure is ready, and embedding them avoids
|
|
// a runtime dependency on a file path.
|
|
//
|
|
// Each cursor is a 16x16 bitmap defined as AND mask + XOR data arrays
|
|
// (one uint16_t per row). The AND/XOR encoding is the standard IBM VGA
|
|
// hardware cursor scheme: AND mask selects transparency, XOR data selects
|
|
// black vs. white for opaque pixels. See CursorT in dvxTypes.h for
|
|
// the full pixel-state truth table.
|
|
//
|
|
// The cursor table (dvxCursors[]) at the bottom provides all five shapes
|
|
// in an array indexed by CURSOR_xxx constants, with hotspot coordinates
|
|
// set appropriately (arrow hot spot at tip, resize cursors at center).
|
|
#ifndef DVX_CURSOR_H
|
|
#define DVX_CURSOR_H
|
|
|
|
#include "dvxTypes.h"
|
|
|
|
// ============================================================
|
|
// Cursor shape IDs
|
|
// ============================================================
|
|
|
|
#define CURSOR_ARROW 0
|
|
#define CURSOR_RESIZE_H 1 // left/right (horizontal)
|
|
#define CURSOR_RESIZE_V 2 // up/down (vertical)
|
|
#define CURSOR_RESIZE_DIAG_NWSE 3 // NW-SE diagonal (top-left / bottom-right)
|
|
#define CURSOR_RESIZE_DIAG_NESW 4 // NE-SW diagonal (top-right / bottom-left)
|
|
#define CURSOR_COUNT 5
|
|
|
|
// ============================================================
|
|
// Standard arrow cursor, 16x16
|
|
// ============================================================
|
|
// AND mask: 0 = draw cursor pixel, 1 = transparent
|
|
// XOR data: 0 = black, 1 = white (where AND = 0)
|
|
//
|
|
// The cursor is a left-pointing arrow with black outline and white fill.
|
|
// Hot spot is at (0, 0) -- top-left corner of the arrow tip.
|
|
|
|
static const uint16_t cursorArrowAnd[16] = {
|
|
0x3FFF, // 0011111111111111 row 0
|
|
0x1FFF, // 0001111111111111 row 1
|
|
0x0FFF, // 0000111111111111 row 2
|
|
0x07FF, // 0000011111111111 row 3
|
|
0x03FF, // 0000001111111111 row 4
|
|
0x01FF, // 0000000111111111 row 5
|
|
0x00FF, // 0000000011111111 row 6
|
|
0x007F, // 0000000001111111 row 7
|
|
0x003F, // 0000000000111111 row 8
|
|
0x001F, // 0000000000011111 row 9
|
|
0x01FF, // 0000000111111111 row 10
|
|
0x10FF, // 0001000011111111 row 11
|
|
0x30FF, // 0011000011111111 row 12
|
|
0xF87F, // 1111100001111111 row 13
|
|
0xF87F, // 1111100001111111 row 14
|
|
0xFC3F // 1111110000111111 row 15
|
|
};
|
|
|
|
static const uint16_t cursorArrowXor[16] = {
|
|
0x0000, // 0000000000000000 row 0
|
|
0x4000, // 0100000000000000 row 1
|
|
0x6000, // 0110000000000000 row 2
|
|
0x7000, // 0111000000000000 row 3
|
|
0x7800, // 0111100000000000 row 4
|
|
0x7C00, // 0111110000000000 row 5
|
|
0x7E00, // 0111111000000000 row 6
|
|
0x7F00, // 0111111100000000 row 7
|
|
0x7F80, // 0111111110000000 row 8
|
|
0x7C00, // 0111110000000000 row 9
|
|
0x6C00, // 0110110000000000 row 10
|
|
0x4600, // 0100011000000000 row 11
|
|
0x0600, // 0000011000000000 row 12
|
|
0x0300, // 0000001100000000 row 13
|
|
0x0300, // 0000001100000000 row 14
|
|
0x0000 // 0000000000000000 row 15
|
|
};
|
|
|
|
// ============================================================
|
|
// Horizontal resize cursor (left/right arrows), 16x16
|
|
// ============================================================
|
|
// Hot spot at center (7, 7)
|
|
//
|
|
// <-->
|
|
// ..XX..XX..
|
|
// .X..XX..X.
|
|
// X..XXXX..X
|
|
// ..XXXXXX..
|
|
// X..XXXX..X
|
|
// .X..XX..X.
|
|
// ..XX..XX..
|
|
|
|
// Left-right resize cursor -- exact 90 deg rotation of the vertical cursor.
|
|
// Left arrow tip at col 2, right arrow tip at col 13, 1px stem at row 7.
|
|
// Bit 15 = leftmost pixel (col 0), bit 0 = rightmost (col 15).
|
|
//
|
|
// XOR (1=white): Outline (AND=0 border):
|
|
// row 4: ....X......X.... row 3: ...XXX....XXX...
|
|
// row 5: ...XX......XX... row 4: ..XXXX....XXXX..
|
|
// row 6: ..XXX......XXX.. row 5: .XXXXX....XXXXX.
|
|
// row 7: .XXXXXXXXXXXX.. row 6: XXXXXXXXXXXXXX.. (1px border around all)
|
|
// row 8: ..XXX......XXX.. row 7: XXXXXXXXXXXXXXXX
|
|
// row 9: ...XX......XX... row 8: XXXXXXXXXXXXXX..
|
|
// row 10: ....X......X.... row 9: .XXXXX....XXXXX.
|
|
// row 10: ..XXXX....XXXX..
|
|
// row 11: ...XXX....XXX...
|
|
|
|
static const uint16_t cursorResizeHAnd[16] = {
|
|
0xFFFF, // 1111111111111111 row 0
|
|
0xFFFF, // 1111111111111111 row 1
|
|
0xFFFF, // 1111111111111111 row 2
|
|
0xF18F, // 1111000110001111 row 3 outline top
|
|
0xE187, // 1110000110000111 row 4
|
|
0xC183, // 1100000110000011 row 5
|
|
0x8001, // 1000000000000001 row 6
|
|
0x8001, // 1000000000000001 row 7 center
|
|
0x8001, // 1000000000000001 row 8
|
|
0xC183, // 1100000110000011 row 9
|
|
0xE187, // 1110000110000111 row 10
|
|
0xF18F, // 1111000110001111 row 11 outline bottom
|
|
0xFFFF, // 1111111111111111 row 12
|
|
0xFFFF, // 1111111111111111 row 13
|
|
0xFFFF, // 1111111111111111 row 14
|
|
0xFFFF // 1111111111111111 row 15
|
|
};
|
|
|
|
static const uint16_t cursorResizeHXor[16] = {
|
|
0x0000, // 0000000000000000 row 0
|
|
0x0000, // 0000000000000000 row 1
|
|
0x0000, // 0000000000000000 row 2
|
|
0x0000, // 0000000000000000 row 3
|
|
0x0420, // 0000010000100000 row 4 arrow tips
|
|
0x0C30, // 0000110000110000 row 5
|
|
0x1C38, // 0001110000111000 row 6
|
|
0x3FFC, // 0011111111111100 row 7 bases + stem
|
|
0x1C38, // 0001110000111000 row 8
|
|
0x0C30, // 0000110000110000 row 9
|
|
0x0420, // 0000010000100000 row 10 arrow tips
|
|
0x0000, // 0000000000000000 row 11
|
|
0x0000, // 0000000000000000 row 12
|
|
0x0000, // 0000000000000000 row 13
|
|
0x0000, // 0000000000000000 row 14
|
|
0x0000 // 0000000000000000 row 15
|
|
};
|
|
|
|
// ============================================================
|
|
// Vertical resize cursor (up/down arrows), 16x16
|
|
// ============================================================
|
|
// Hot spot at center (7, 7)
|
|
|
|
static const uint16_t cursorResizeVAnd[16] = {
|
|
0xFFFF, // row 0 (transparent)
|
|
0xFFFF, // row 1
|
|
0xFE7F, // 1111111001111111 row 2 top arrow
|
|
0xFC3F, // 1111110000111111 row 3
|
|
0xF81F, // 1111100000011111 row 4
|
|
0xF00F, // 1111000000001111 row 5
|
|
0xFE7F, // 1111111001111111 row 6
|
|
0xFE7F, // 1111111001111111 row 7 stem
|
|
0xFE7F, // 1111111001111111 row 8 stem
|
|
0xFE7F, // 1111111001111111 row 9
|
|
0xF00F, // 1111000000001111 row 10
|
|
0xF81F, // 1111100000011111 row 11
|
|
0xFC3F, // 1111110000111111 row 12
|
|
0xFE7F, // 1111111001111111 row 13 bottom arrow
|
|
0xFFFF, // row 14
|
|
0xFFFF // row 15
|
|
};
|
|
|
|
static const uint16_t cursorResizeVXor[16] = {
|
|
0x0000, // row 0
|
|
0x0000, // row 1
|
|
0x0100, // 0000000100000000 row 2
|
|
0x0380, // 0000001110000000 row 3
|
|
0x07C0, // 0000011111000000 row 4
|
|
0x0FE0, // 0000111111100000 row 5 full width
|
|
0x0100, // 0000000100000000 row 6 stem
|
|
0x0100, // 0000000100000000 row 7
|
|
0x0100, // 0000000100000000 row 8
|
|
0x0100, // 0000000100000000 row 9 stem
|
|
0x0FE0, // 0000111111100000 row 10 full width
|
|
0x07C0, // 0000011111000000 row 11
|
|
0x0380, // 0000001110000000 row 12
|
|
0x0100, // 0000000100000000 row 13
|
|
0x0000, // row 14
|
|
0x0000 // row 15
|
|
};
|
|
|
|
// ============================================================
|
|
// Diagonal resize cursor NW-SE (top-left / bottom-right), 16x16
|
|
// ============================================================
|
|
// Hot spot at center (7, 7)
|
|
//
|
|
// True 45-degree diagonal with filled triangular arrowheads:
|
|
//
|
|
// .XXXXX.......... NW arrowhead (right-angle triangle)
|
|
// .XXXX...........
|
|
// .XXX............
|
|
// .XX.X...........
|
|
// .X...X..........
|
|
// ......X......... diagonal shaft (one pixel per row)
|
|
// .......X........
|
|
// ........X.......
|
|
// .........X......
|
|
// ..........X...X.
|
|
// ...........X.XX.
|
|
// ............XXX.
|
|
// ...........XXXX.
|
|
// ..........XXXXX. SE arrowhead (mirror of NW)
|
|
|
|
static const uint16_t cursorResizeDiagNWSEAnd[16] = {
|
|
0x01FF, // 0000000111111111 row 0 NW outline
|
|
0x01FF, // 0000000111111111 row 1
|
|
0x01FF, // 0000000111111111 row 2
|
|
0x03FF, // 0000001111111111 row 3
|
|
0x01FF, // 0000000111111111 row 4
|
|
0x00FF, // 0000000011111111 row 5
|
|
0x107F, // 0001000001111111 row 6 shaft
|
|
0xF83F, // 1111100000111111 row 7
|
|
0xFC1F, // 1111110000011111 row 8
|
|
0xFE08, // 1111111000001000 row 9
|
|
0xFF00, // 1111111100000000 row 10 SE outline
|
|
0xFF80, // 1111111110000000 row 11
|
|
0xFFC0, // 1111111111000000 row 12
|
|
0xFF80, // 1111111110000000 row 13
|
|
0xFF80, // 1111111110000000 row 14
|
|
0xFF80 // 1111111110000000 row 15
|
|
};
|
|
|
|
static const uint16_t cursorResizeDiagNWSEXor[16] = {
|
|
0x0000, // 0000000000000000 row 0
|
|
0x7C00, // 0111110000000000 row 1 XXXXX
|
|
0x7800, // 0111100000000000 row 2 XXXX
|
|
0x7000, // 0111000000000000 row 3 XXX
|
|
0x6800, // 0110100000000000 row 4 XX.X
|
|
0x4400, // 0100010000000000 row 5 X...X
|
|
0x0200, // 0000001000000000 row 6 X
|
|
0x0100, // 0000000100000000 row 7 X
|
|
0x0080, // 0000000010000000 row 8 X
|
|
0x0040, // 0000000001000000 row 9 X
|
|
0x0022, // 0000000000100010 row 10 X...X
|
|
0x0016, // 0000000000010110 row 11 X.XX
|
|
0x000E, // 0000000000001110 row 12 XXX
|
|
0x001E, // 0000000000011110 row 13 XXXX
|
|
0x003E, // 0000000000111110 row 14 XXXXX
|
|
0x0000 // 0000000000000000 row 15
|
|
};
|
|
|
|
// ============================================================
|
|
// Diagonal resize cursor NE-SW (top-right / bottom-left), 16x16
|
|
// ============================================================
|
|
// Hot spot at center (7, 7)
|
|
//
|
|
// ..........XXXXX. NE arrowhead
|
|
// ...........XXXX.
|
|
// ............XXX.
|
|
// ...........X.XX.
|
|
// ..........X...X.
|
|
// .........X...... diagonal shaft
|
|
// ........X.......
|
|
// .......X........
|
|
// ......X.........
|
|
// .X...X..........
|
|
// .XX.X...........
|
|
// .XXX............
|
|
// .XXXX...........
|
|
// .XXXXX.......... SW arrowhead
|
|
|
|
static const uint16_t cursorResizeDiagNESWAnd[16] = {
|
|
0xFF80, // 1111111110000000 row 0 NE outline
|
|
0xFF80, // 1111111110000000 row 1
|
|
0xFF80, // 1111111110000000 row 2
|
|
0xFFC0, // 1111111111000000 row 3
|
|
0xFF80, // 1111111110000000 row 4
|
|
0xFF00, // 1111111100000000 row 5
|
|
0xFE08, // 1111111000001000 row 6 shaft
|
|
0xFC1F, // 1111110000011111 row 7
|
|
0xF83F, // 1111100000111111 row 8
|
|
0x107F, // 0001000001111111 row 9
|
|
0x00FF, // 0000000011111111 row 10 SW outline
|
|
0x01FF, // 0000000111111111 row 11
|
|
0x03FF, // 0000001111111111 row 12
|
|
0x01FF, // 0000000111111111 row 13
|
|
0x01FF, // 0000000111111111 row 14
|
|
0x01FF // 0000000111111111 row 15
|
|
};
|
|
|
|
static const uint16_t cursorResizeDiagNESWXor[16] = {
|
|
0x0000, // 0000000000000000 row 0
|
|
0x003E, // 0000000000111110 row 1 XXXXX
|
|
0x001E, // 0000000000011110 row 2 XXXX
|
|
0x000E, // 0000000000001110 row 3 XXX
|
|
0x0016, // 0000000000010110 row 4 X.XX
|
|
0x0022, // 0000000000100010 row 5 X...X
|
|
0x0040, // 0000000001000000 row 6 X
|
|
0x0080, // 0000000010000000 row 7 X
|
|
0x0100, // 0000000100000000 row 8 X
|
|
0x0200, // 0000001000000000 row 9 X
|
|
0x4400, // 0100010000000000 row 10 X...X
|
|
0x6800, // 0110100000000000 row 11 XX.X
|
|
0x7000, // 0111000000000000 row 12 XXX
|
|
0x7800, // 0111100000000000 row 13 XXXX
|
|
0x7C00, // 0111110000000000 row 14 XXXXX
|
|
0x0000 // 0000000000000000 row 15
|
|
};
|
|
|
|
// ============================================================
|
|
// Cursor table
|
|
// ============================================================
|
|
|
|
static const CursorT dvxCursors[CURSOR_COUNT] = {
|
|
{ 16, 16, 0, 0, cursorArrowAnd, cursorArrowXor }, // CURSOR_ARROW
|
|
{ 16, 16, 7, 7, cursorResizeHAnd, cursorResizeHXor }, // CURSOR_RESIZE_H
|
|
{ 16, 16, 7, 7, cursorResizeVAnd, cursorResizeVXor }, // CURSOR_RESIZE_V
|
|
{ 16, 16, 7, 7, cursorResizeDiagNWSEAnd, cursorResizeDiagNWSEXor }, // CURSOR_RESIZE_DIAG_NWSE
|
|
{ 16, 16, 7, 7, cursorResizeDiagNESWAnd, cursorResizeDiagNESWXor }, // CURSOR_RESIZE_DIAG_NESW
|
|
};
|
|
|
|
// Legacy alias -- kept for backward compatibility with code that predates
|
|
// the multi-cursor support.
|
|
static const CursorT dvxCursor = { 16, 16, 0, 0, cursorArrowAnd, cursorArrowXor };
|
|
|
|
#endif // DVX_CURSOR_H
|