mirror of
https://github.com/Metabolix/HackBGRT.git
synced 2026-04-10 12:12:18 -07:00
Allow position as a fraction of resolution
UEFI recommends y=.382 (1 - 1 / (golden ratio)), make this the default. Fractional position starts with a decimal point: x=.5 y=.382 Pixel offset relative to the center is set as before: x=123 y=456 If the coordinates were omitted, old default was: x=0 y=0
This commit is contained in:
17
config.txt
17
config.txt
@@ -8,12 +8,13 @@ boot=MS
|
||||
# Multiple image lines may be present, in which case one will be picked by random.
|
||||
# The image line may contain the following parts:
|
||||
# Any of the following:
|
||||
# - "n=(number)", a weight for this image in the randomization process. Default: n=1.
|
||||
# - "x=(number)" or "x=keep", the x offset from the center. Default: x=0.
|
||||
# - "y=(number)" or "y=keep", the y offset from the center. Default: y=0.
|
||||
# - "o=(0|90|180|270|keep)", the screen orientation, degrees anticlockwise. Default: o=keep.
|
||||
# - "x=(number) y=(number)" positions the image relative to the screen center.
|
||||
# - "x=.(decimal) y=.(decimal)" positions the image as a fraction of the resolution.
|
||||
# - "o=(0|90|180|270|keep)", the screen orientation, degrees anticlockwise.
|
||||
# - "n=(number)", a weight for this image in the randomization process.
|
||||
# - Default values: o=keep x=.5 y=.382 n=1
|
||||
# One of the following:
|
||||
# - "keep" to keep the firmware logo. Also keeps coordinates by default.
|
||||
# - "keep" to keep the firmware logo (and coordinates, unless specified).
|
||||
# - "remove" to remove the BGRT. Makes x and y meaningless.
|
||||
# - "black" to use only a black image. Makes x and y meaningless.
|
||||
# - "path=file.bmp" to read an image file.
|
||||
@@ -21,9 +22,9 @@ boot=MS
|
||||
# Examples:
|
||||
# - image=remove
|
||||
# - image=black
|
||||
# - image= x=0 y=-200 path=topimage.bmp
|
||||
# - image= x=0 y=.0 path=topimage.bmp
|
||||
# - image= n=1 o=90 path=sideways.bmp
|
||||
# - image= n=50 y=999999 o=keep path=probable.bmp
|
||||
# - image= n=50 y=999999 path=probable.bmp
|
||||
# The above examples together would produce
|
||||
# - 1/54 chance for the default OS logo
|
||||
# - 1/54 chance for black screen
|
||||
@@ -31,7 +32,7 @@ boot=MS
|
||||
# - 1/54 chance for splash.bmp, centered, orientation set to 90 degrees
|
||||
# - 50/54 chance for probable.bmp, at the bottom edge, explicitly default orientation
|
||||
# Default: just one image.
|
||||
image= y=-200 path=splash.bmp
|
||||
image= path=splash.bmp
|
||||
|
||||
# Preferred resolution. Use 0x0 for maximum and -1x-1 for original.
|
||||
resolution=0x0
|
||||
|
||||
93
src/config.c
93
src/config.c
@@ -68,54 +68,89 @@ BOOLEAN ReadConfigFile(struct HackBGRT_config* config, EFI_FILE_HANDLE base_dir,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void SetBMPWithRandom(struct HackBGRT_config* config, int weight, enum HackBGRT_action action, int x, int y, int o, const CHAR16* path) {
|
||||
static void SetBMPWithRandom(struct HackBGRT_config* config, const struct HackBGRT_image_config* image, int weight) {
|
||||
config->image_weight_sum += weight;
|
||||
UINT32 random = (((UINT64) Random() & 0xffffffff) * config->image_weight_sum) >> 32;
|
||||
UINT32 limit = ((UINT64) 0xffffffff * weight) >> 32;
|
||||
Log(config->debug, L"%s n=%d, action=%d, x=%d, y=%d, o=%d, path=%s, rand=%x/%x\n", random <= limit ? L"Using" : L"Skipping", weight, action, x, y, o, path, random, limit);
|
||||
Log(
|
||||
config->debug,
|
||||
L"image n=%d, action=%d, x=%d (mode %d), y=%d (mode %d), o=%d, path=%s, rand=%x/%x, chosen=%d\n",
|
||||
weight, image->action, image->x, image->x_mode, image->y, image->y_mode, image->orientation, image->path, random, limit, (random <= limit)
|
||||
);
|
||||
if (random <= limit) {
|
||||
config->action = action;
|
||||
config->image_path = path;
|
||||
config->orientation = o;
|
||||
config->image_x = x;
|
||||
config->image_y = y;
|
||||
config->image = *image;
|
||||
}
|
||||
}
|
||||
|
||||
static int ParseCoordinate(const CHAR16* str, enum HackBGRT_action action) {
|
||||
if (str && ((L'0' <= str[0] && str[0] <= L'9') || str[0] == L'-')) {
|
||||
return str[0] == L'-' ? -(int)Atoi(str+1) : (int)Atoi(str);
|
||||
static void ParseCoordinate(const CHAR16* str, int* out_int, enum HackBGRT_coordinate_mode* out_mode) {
|
||||
if (!str) {
|
||||
return;
|
||||
}
|
||||
if ((str && StrnCmp(str, L"keep", 4) == 0) || action == HackBGRT_KEEP) {
|
||||
return HackBGRT_coord_keep;
|
||||
if (StrnCmp(str, L"keep", 4) == 0) {
|
||||
*out_int = 0;
|
||||
*out_mode = HackBGRT_COORDINATE_MODE_KEEP;
|
||||
return;
|
||||
}
|
||||
if (str[0] == L'.' && L'0' <= str[1] && str[1] <= L'9') {
|
||||
int result = 0, i = 1, length = 0;
|
||||
for (length = 0; length < HackBGRT_FRACTION_DIGITS; ++length) {
|
||||
result = 10 * result;
|
||||
if (L'0' <= str[i] && str[i] <= L'9') {
|
||||
result += str[i] - L'0';
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
*out_mode = HackBGRT_COORDINATE_MODE_FRACTION;
|
||||
*out_int = result;
|
||||
return;
|
||||
}
|
||||
int neg = str[0] == L'-' ? 1 : 0;
|
||||
if (L'0' <= str[neg] && str[neg] <= L'9') {
|
||||
*out_int = Atoi(str + neg) * (neg ? -1 : 1);
|
||||
*out_mode = HackBGRT_COORDINATE_MODE_CENTERED;
|
||||
return;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ReadConfigImage(struct HackBGRT_config* config, const CHAR16* line) {
|
||||
const CHAR16* n = StrStrAfter(line, L"n=");
|
||||
const CHAR16* x = StrStrAfter(line, L"x=");
|
||||
const CHAR16* y = StrStrAfter(line, L"y=");
|
||||
const CHAR16* o = StrStrAfter(line, L"o=");
|
||||
const CHAR16* f = StrStrAfter(line, L"path=");
|
||||
enum HackBGRT_action action = HackBGRT_KEEP;
|
||||
if (f) {
|
||||
action = HackBGRT_REPLACE;
|
||||
struct HackBGRT_image_config image = {
|
||||
.action = HackBGRT_ACTION_KEEP,
|
||||
.orientation = HackBGRT_ORIENTATION_KEEP,
|
||||
};
|
||||
const CHAR16* tmp;
|
||||
image.path = StrStrAfter(line, L"path=");
|
||||
if (image.path) {
|
||||
image.action = HackBGRT_ACTION_REPLACE;
|
||||
// Default: x centered, y 38.2 % (= 1 - 1 / golden_ratio)
|
||||
image.x_mode = image.y_mode = HackBGRT_COORDINATE_MODE_FRACTION;
|
||||
image.x = HackBGRT_FRACTION_HALF;
|
||||
image.y = HackBGRT_FRACTION_381966011;
|
||||
} else if (StrStr(line, L"remove")) {
|
||||
action = HackBGRT_REMOVE;
|
||||
image.action = HackBGRT_ACTION_REMOVE;
|
||||
} else if (StrStr(line, L"black")) {
|
||||
action = HackBGRT_REPLACE;
|
||||
image.action = HackBGRT_ACTION_REPLACE;
|
||||
image.path = 0;
|
||||
} else if (StrStr(line, L"keep")) {
|
||||
action = HackBGRT_KEEP;
|
||||
image.action = HackBGRT_ACTION_KEEP;
|
||||
image.x_mode = image.y_mode = HackBGRT_COORDINATE_MODE_KEEP;
|
||||
} else {
|
||||
Log(1, L"Invalid image line: %s\n", line);
|
||||
return;
|
||||
}
|
||||
int weight = n && (!f || n < f) ? Atoi(n) : 1;
|
||||
int x_val = ParseCoordinate(x, action);
|
||||
int y_val = ParseCoordinate(y, action);
|
||||
int o_val = o ? ParseCoordinate(o, action) : HackBGRT_coord_keep;
|
||||
SetBMPWithRandom(config, weight, action, x_val, y_val, o_val, f);
|
||||
ParseCoordinate(StrStrAfter(line, L"x="), &image.x, &image.x_mode);
|
||||
ParseCoordinate(StrStrAfter(line, L"y="), &image.y, &image.y_mode);
|
||||
if (StrStrAfter(line, L"o=keep")) {
|
||||
image.orientation = HackBGRT_ORIENTATION_KEEP;
|
||||
} else if ((tmp = StrStrAfter(line, L"o="))) {
|
||||
// convert orientation in degrees to number 0-3 (* 90 degrees)
|
||||
int i = tmp[0] == L'-' ? -(int)Atoi(tmp+1) : (int)Atoi(tmp);
|
||||
image.orientation = (i / 90) & 3;
|
||||
}
|
||||
int weight = 1;
|
||||
if ((tmp = StrStrAfter(line, L"n="))) {
|
||||
weight = Atoi(tmp);
|
||||
}
|
||||
SetBMPWithRandom(config, &image, weight);
|
||||
}
|
||||
|
||||
static void ReadConfigResolution(struct HackBGRT_config* config, const CHAR16* line) {
|
||||
|
||||
44
src/config.h
44
src/config.h
@@ -6,15 +6,47 @@
|
||||
* Possible actions to perform on the BGRT.
|
||||
*/
|
||||
enum HackBGRT_action {
|
||||
HackBGRT_KEEP = 0, HackBGRT_REPLACE, HackBGRT_REMOVE
|
||||
HackBGRT_ACTION_KEEP = 0,
|
||||
HackBGRT_ACTION_REPLACE,
|
||||
HackBGRT_ACTION_REMOVE
|
||||
};
|
||||
|
||||
/**
|
||||
* Special values for the image coordinates.
|
||||
* @see struct HackBGRT_config
|
||||
*/
|
||||
enum HackBGRT_coordinate {
|
||||
HackBGRT_coord_keep = -1000001
|
||||
enum HackBGRT_coordinate_mode {
|
||||
HackBGRT_COORDINATE_MODE_KEEP = 0,
|
||||
HackBGRT_COORDINATE_MODE_CENTERED,
|
||||
HackBGRT_COORDINATE_MODE_FRACTION,
|
||||
};
|
||||
|
||||
/**
|
||||
* Constants for the fractional coordinates.
|
||||
*/
|
||||
enum HackBGRT_fraction {
|
||||
HackBGRT_FRACTION_DIGITS = 4,
|
||||
HackBGRT_FRACTION_ONE = 10000,
|
||||
HackBGRT_FRACTION_HALF = 5000,
|
||||
HackBGRT_FRACTION_381966011 = 3820,
|
||||
};
|
||||
|
||||
/**
|
||||
* Possible values for the orientation.
|
||||
*/
|
||||
enum HackBGRT_orientation {
|
||||
HackBGRT_ORIENTATION_KEEP = -1,
|
||||
};
|
||||
|
||||
/**
|
||||
* The configuration for one image.
|
||||
*/
|
||||
struct HackBGRT_image_config {
|
||||
enum HackBGRT_action action;
|
||||
const CHAR16* path;
|
||||
enum HackBGRT_coordinate_mode x_mode, y_mode;
|
||||
int x, y;
|
||||
int orientation;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -22,12 +54,8 @@ enum HackBGRT_coordinate {
|
||||
*/
|
||||
struct HackBGRT_config {
|
||||
int debug, log;
|
||||
enum HackBGRT_action action;
|
||||
const CHAR16* image_path;
|
||||
int image_x;
|
||||
int image_y;
|
||||
struct HackBGRT_image_config image;
|
||||
int image_weight_sum;
|
||||
int orientation;
|
||||
int resolution_x;
|
||||
int resolution_y;
|
||||
int old_resolution_x;
|
||||
|
||||
44
src/main.c
44
src/main.c
@@ -21,7 +21,6 @@ EFI_RUNTIME_SERVICES *RT;
|
||||
*/
|
||||
static struct HackBGRT_config config = {
|
||||
.log = 1,
|
||||
.action = HackBGRT_KEEP,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -163,13 +162,13 @@ static ACPI_BGRT* HandleAcpiTables(enum HackBGRT_action action, ACPI_BGRT* bgrt)
|
||||
}
|
||||
Log(config.debug, L" - ACPI table @%x: %s, revision = %d, OEM ID = %s\n", (UINTN)entry, TmpStr(entry->signature, 4), entry->revision, TmpStr(entry->oem_id, 6));
|
||||
switch (action) {
|
||||
case HackBGRT_KEEP:
|
||||
case HackBGRT_ACTION_KEEP:
|
||||
if (!bgrt) {
|
||||
Log(config.debug, L" -> Returning this one for later use.\n");
|
||||
bgrt = (ACPI_BGRT*) entry;
|
||||
}
|
||||
break;
|
||||
case HackBGRT_REMOVE:
|
||||
case HackBGRT_ACTION_REMOVE:
|
||||
Log(config.debug, L" -> Deleting.\n");
|
||||
for (int k = j+1; k < entry_arr_length; ++k) {
|
||||
entry_arr[k-1] = entry_arr[k];
|
||||
@@ -179,13 +178,13 @@ static ACPI_BGRT* HandleAcpiTables(enum HackBGRT_action action, ACPI_BGRT* bgrt)
|
||||
xsdt->length -= sizeof(entry_arr[0]);
|
||||
--j;
|
||||
break;
|
||||
case HackBGRT_REPLACE:
|
||||
case HackBGRT_ACTION_REPLACE:
|
||||
Log(config.debug, L" -> Replacing.\n");
|
||||
entry_arr[j] = (UINTN) bgrt;
|
||||
}
|
||||
bgrt_count += 1;
|
||||
}
|
||||
if (!bgrt_count && action == HackBGRT_REPLACE && bgrt) {
|
||||
if (!bgrt_count && action == HackBGRT_ACTION_REPLACE && bgrt) {
|
||||
Log(config.debug, L" - Adding missing BGRT.\n");
|
||||
xsdt = CreateXsdt(xsdt, entry_arr_length + 1);
|
||||
entry_arr = (UINT64*)&xsdt[1];
|
||||
@@ -303,13 +302,13 @@ static void CropBMP(BMP* bmp, int w, int h) {
|
||||
*/
|
||||
void HackBgrt(EFI_FILE_HANDLE base_dir) {
|
||||
// REMOVE: simply delete all BGRT entries.
|
||||
if (config.action == HackBGRT_REMOVE) {
|
||||
HandleAcpiTables(config.action, 0);
|
||||
if (config.image.action == HackBGRT_ACTION_REMOVE) {
|
||||
HandleAcpiTables(config.image.action, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// KEEP/REPLACE: first get the old BGRT entry.
|
||||
ACPI_BGRT* bgrt = HandleAcpiTables(HackBGRT_KEEP, 0);
|
||||
ACPI_BGRT* bgrt = HandleAcpiTables(HackBGRT_ACTION_KEEP, 0);
|
||||
|
||||
// Get the old BMP and position (relative to screen center), if possible.
|
||||
const int old_valid = bgrt && VerifyAcpiSdtChecksum(bgrt);
|
||||
@@ -324,7 +323,7 @@ void HackBgrt(EFI_FILE_HANDLE base_dir) {
|
||||
// Missing BGRT?
|
||||
if (!bgrt) {
|
||||
// Keep missing = do nothing.
|
||||
if (config.action == HackBGRT_KEEP) {
|
||||
if (config.image.action == HackBGRT_ACTION_KEEP) {
|
||||
return;
|
||||
}
|
||||
// Replace missing = allocate new.
|
||||
@@ -351,13 +350,13 @@ void HackBgrt(EFI_FILE_HANDLE base_dir) {
|
||||
|
||||
// Get the image (either old or new).
|
||||
BMP* new_bmp = old_bmp;
|
||||
if (config.action == HackBGRT_REPLACE) {
|
||||
new_bmp = LoadBMP(base_dir, config.image_path);
|
||||
if (config.image.action == HackBGRT_ACTION_REPLACE) {
|
||||
new_bmp = LoadBMP(base_dir, config.image.path);
|
||||
}
|
||||
|
||||
// No image = no need for BGRT.
|
||||
if (!new_bmp) {
|
||||
HandleAcpiTables(HackBGRT_REMOVE, 0);
|
||||
HandleAcpiTables(HackBGRT_ACTION_REMOVE, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -366,16 +365,23 @@ void HackBgrt(EFI_FILE_HANDLE base_dir) {
|
||||
|
||||
// Set the image address and orientation.
|
||||
bgrt->image_address = (UINTN) new_bmp;
|
||||
const int new_orientation = config.orientation == HackBGRT_coord_keep ? old_orientation : ((config.orientation / 90) & 3);
|
||||
const int new_orientation = config.image.orientation == HackBGRT_ORIENTATION_KEEP ? old_orientation : config.image.orientation;
|
||||
bgrt->status = new_orientation << 1;
|
||||
|
||||
// New center coordinates.
|
||||
const int new_x = config.image_x == HackBGRT_coord_keep ? old_x : config.image_x;
|
||||
const int new_y = config.image_y == HackBGRT_coord_keep ? old_y : config.image_y;
|
||||
const int new_swap = new_orientation & 1;
|
||||
const int new_reso_x = new_swap ? config.resolution_y : config.resolution_x;
|
||||
const int new_reso_y = new_swap ? config.resolution_x : config.resolution_y;
|
||||
|
||||
const int new_x =
|
||||
config.image.x_mode == HackBGRT_COORDINATE_MODE_KEEP ? old_x :
|
||||
config.image.x_mode == HackBGRT_COORDINATE_MODE_CENTERED ? config.image.x :
|
||||
(config.image.x - HackBGRT_FRACTION_HALF) * new_reso_x / HackBGRT_FRACTION_ONE;
|
||||
const int new_y =
|
||||
config.image.y_mode == HackBGRT_COORDINATE_MODE_KEEP ? old_y :
|
||||
config.image.y_mode == HackBGRT_COORDINATE_MODE_CENTERED ? config.image.y :
|
||||
(config.image.y - HackBGRT_FRACTION_HALF) * new_reso_y / HackBGRT_FRACTION_ONE;
|
||||
|
||||
// Calculate absolute position.
|
||||
const int max_x = new_reso_x - new_bmp->width;
|
||||
const int max_y = new_reso_y - new_bmp->height;
|
||||
@@ -383,15 +389,17 @@ void HackBgrt(EFI_FILE_HANDLE base_dir) {
|
||||
bgrt->image_offset_y = max(0, min(max_y, new_y + (new_reso_y - new_bmp->height) / 2));
|
||||
|
||||
Log(config.debug,
|
||||
L"BMP at (%d, %d), center (%d, %d), resolution (%d, %d), orientation %d.\n",
|
||||
L"Screen %dx%d, BMP %dx%d, center (%d, %d) = corner (%d, %d), orientation %d.\n",
|
||||
new_reso_x, new_reso_y,
|
||||
new_bmp->width, new_bmp->height,
|
||||
new_x, new_y,
|
||||
(int) bgrt->image_offset_x, (int) bgrt->image_offset_y,
|
||||
new_x, new_y, new_reso_x, new_reso_y,
|
||||
new_orientation * 90
|
||||
);
|
||||
|
||||
// Store this BGRT in the ACPI tables.
|
||||
SetAcpiSdtChecksum(bgrt);
|
||||
HandleAcpiTables(HackBGRT_REPLACE, bgrt);
|
||||
HandleAcpiTables(HackBGRT_ACTION_REPLACE, bgrt);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user