Skip to content

Commit 8ec868d

Browse files
committed
Fix per character width and font sizing edge cases
1 parent 3a81826 commit 8ec868d

5 files changed

Lines changed: 68 additions & 8 deletions

File tree

source/graphics.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,16 +1497,26 @@ int Graphics::drawCharacter(
14971497
int defaultCharHeight = useCustomFont ? _memory->data[0x5602] : 5;
14981498

14991499
if (ch > 0x0f) {
1500-
uint8_t charWidth =
1501-
ch < 0x80
1502-
? forceCharWidth > -1 && forceCharWidth < 4 ? forceCharWidth : defaultCharWidth
1503-
: forceCharWidth > -1 && forceCharWidth < 4 ? (forceCharWidth + 4) : defaultWideCharWidth;
1500+
// Determine render width:
1501+
// - If forceCharWidth is set (0-3 via \^x), use it to limit rendering
1502+
// - For custom fonts without forced width, render all 8 columns (charWidth only affects cursor)
1503+
// - For standard font, use defaultCharWidth (glyph data matches the width)
1504+
bool widthIsForced = forceCharWidth > -1 && forceCharWidth < 4;
1505+
uint8_t renderWidth;
1506+
if (widthIsForced) {
1507+
renderWidth = ch < 0x80 ? forceCharWidth : (forceCharWidth + 4);
1508+
} else if (useCustomFont) {
1509+
renderWidth = 8; // Custom fonts: render all 8 columns
1510+
} else {
1511+
renderWidth = ch < 0x80 ? defaultCharWidth : defaultWideCharWidth; // Standard font
1512+
}
15041513

15051514
if (ch >= 0x80) {
15061515
extraCharWidth = defaultWideCharWidth - defaultCharWidth;
15071516
}
15081517

1509-
uint8_t charHeight = forceCharHeight > -1 && forceCharHeight < 5 ? forceCharHeight : defaultCharHeight;
1518+
// Height: use forced height if set, otherwise use defaultCharHeight from font metadata
1519+
uint8_t renderHeight = forceCharHeight > -1 && forceCharHeight < 5 ? forceCharHeight : defaultCharHeight;
15101520

15111521
auto result = drawCharacterFromBytes(
15121522
useCustomFont ? &(_memory->data[0x5600 + ch*8]) : &(defaultFontBinaryData[ch*8]),
@@ -1515,8 +1525,8 @@ int Graphics::drawCharacter(
15151525
fgColor,
15161526
bgColor,
15171527
printMode,
1518-
charWidth,
1519-
charHeight
1528+
renderWidth,
1529+
renderHeight
15201530
);
15211531
extraCharWidth += get<0>(result);
15221532
}

source/printHelper.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,20 @@ int print(std::string str, int x, int y, uint8_t c) {
544544
printMode,
545545
forceCharWidth,
546546
forceCharHeight);
547-
x += charWidth + extraWidth;
547+
548+
// Apply per-character width adjustment if flag 0x1 is set at 0x5605
549+
int perCharWidthAdj = 0;
550+
if ((printMode & PRINT_MODE_CUSTOM_FONT) && (_ph_mem->data[0x5605] & 0x01)) {
551+
int nibbleIdx = ch - 16;
552+
if (nibbleIdx >= 0 && nibbleIdx < 240) {
553+
uint8_t adjByte = _ph_mem->data[0x5608 + nibbleIdx/2];
554+
uint8_t adjNibble = (nibbleIdx % 2 == 0) ? (adjByte & 0x0f) : (adjByte >> 4);
555+
perCharWidthAdj = (adjNibble & 0x07);
556+
if (perCharWidthAdj >= 4) perCharWidthAdj = perCharWidthAdj - 8; // convert 4,5,6,7 to -4,-3,-2,-1
557+
}
558+
}
559+
560+
x += charWidth + extraWidth + perCharWidthAdj;
548561

549562
while (framesToPause > 0){
550563
//TODO: yield here? not sure how to handle this

test/carts/per_char_width_test.p8

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
pico-8 cartridge // http://www.pico-8.com
2+
version 43
3+
__lua__
4+
-- import custom font - thank you @trog!
5+
?"\^!5600\6\8\7\0\0\1\0\0fffff@ue\6\6\0p\5\0\5\4`\0\0\0\0tv\6\0\0\0\0@\7$\0\0\0\0 \0pp\0\0\0\0\0`\0 \0\0\0\0 \0`t'\0\0`f`\0``\0`\0\0\0wf\0wgfvwvfp\0`\0\0vwgwfwwwefffgfggfvfvfvve`fwfvvgffv\5\0\0\0\0\0\0\0\0\0\0\7\7\7\0\0\0\0\0\7\5\7\0\0\0\0\0\5\2\5\0\0\0\0\0\5\0\5\0\0\0\0\0\5\5\5\0\0\0\0\4\6\7\6\4\0\0\0\1\3\7\3\1\0\0\0\7\1\1\1\0\0\0\0\0\4\4\4\7\0\0\0■\10\4\14\4\0\0\0\0\0\1\0\0\0\0\0\0\0\0\1\2\0\0\0\0\0\0\3\3\0\0\0\5\5\0\0\0\0\0\0\2\5\2\0\0\0\0\0\0\0\0\0\0\0\0\0「、\6\0\1\0\0\0\5\5\0\0\0\0\0\0\10゜\10゜\10\0\0\0゛\5\14⁘\15\0\0\0■\8\4\2■\0\0\0\2\5◀\9◀\0\0\0\2\1\0\0\0\0\0\0\2\1\1\1\2\0\0\0\1\2\2\2\1\0\0\0‖\14•\14‖\0\0\0\4\4゜\4\4\0\0\0\0\0\0\2\1\0\0\0\0\0゜\0\0\0\0\0\0\0\0\0\1\0\0\0▮\8\4\2\1\0\0\0\14」■⁙\14\0\0\0\2\3\2\2\7\0\0\0\15▮\14\1゜\0\0\0\14■\12■\14\0\0\0\12\10\9゜\8\0\0\0\15\1\15▮\15\0\0\0\14\1\15■\14\0\0\0゜■\8\4\4\0\0\0\14■\14■\14\0\0\0\14■゛▮\14\0\0\0\0\1\0\1\0\0\0\0\0\2\0\2\1\0\0\0\4\2\1\2\4\0\0\0\0\14\0\14\0\0\0\0\1\2\4\2\1\0\0\0\14■\12\0\4\0\0\0\14■⁘¥\12\0\0\0\0\14■■゛\0\0\0\1\15■■\15\0\0\0\0\14■\1\14\0\0\0▮゛■■゛\0\0\0\0\14゜\1\14\0\0\0\12□\2\7\2\0\0\0\0゛■゛▮\14\0\0\1\15■■■\0\0\0\1\0\1\1\1\0\0\0\8\0\12\8\9\6\0\0\1\1」\15」\0\0\0\1\1\1\1\1\0\0\0\0007iii\0\0\0\0\15■■■\0\0\0\0\14■■\14\0\0\0\0\15■■\15\1\0\0\0゛■■゛▮\0\0\0\13⁙\1\1\0\0\0\0゛\3「\15\0\0\0\2\15\2□\12\0\0\0\0■■■゛\0\0\0\0■■\10\4\0\0\0\0iii6\0\0\0\0■\14\14■\0\0\0\0■■゛▮\14\0\0\0゜\8\6゜\0\0\0\3\1\1\1\3\0\0\0\1\2\4\8▮\0\0\0\3\2\2\2\3\0\0\0\4\10■\0\0\0\0\0\0\0\0\0゜\0\0\0\1\2\0\0\0\0\0\0\14■■゜■\0\0\0\15■\15■\15\0\0\0\14■\1■\14\0\0\0\15■■■\15\0\0\0゜\1\15\1゜\0\0\0゜\1\15\1\1\0\0\0゛\1。■゛\0\0\0■■゜■■\0\0\0\7\2\2\2\7\0\0\0「▮▮■\14\0\0\0■\9\7\9■\0\0\0\1\1\1■゜\0\0\0acuia\0\0\0■⁙‖」■\0\0\0\14■■■\14\0\0\0\15■■\15\1\0\0\0\14■■\9◀\0\0\0\15■■\15」\0\0\0゛\1\14▮\15\0\0\0゜\4\4\4\4\0\0\0■■■■\14\0\0\0■■■\10\4\0\0\0iiii6\0\0\0■\10\4\10■\0\0\0■■\10\4\4\0\0\0゜\8\4\2゜\0\0\0\6\2\3\2\6\0\0\0\1\1\1\1\1\0\0\0\3\2\6\2\3\0\0\0\0\2‖\8\0\0\0\0\2\5\2\0\0\0\0\0○○○○○\0\0\0u*u*u\0\0\0a○]]>\0\0\0>ccw>\0\0\0■d■d■\0\0\0\2゛\14\15\8\0\0\0\14▶゜゜\14\0\0\0•゜゜\14\4\0\0\0、6w6、\0\0\0\14\14゜\14\10\0\0\0、>○*:\0\0\0>gcg>\0\0\0○]○a○\0\0\0、\4\4\7\7\0\0\0>ckc>\0\0\0\4\14゜\14\4\0\0\0\0\0u\0\0\0\0\0>scs>\0\0\0\8、○>\34\0\0\0゜\14\4\14゜\0\0\0>wcc>\0\0\0\0\5r \0\0\0\0\0■*d\0\0\0\0>kwk>\0\0\0○\0○\0○\0\0\0uuuuu\0\0\0\14\4゛-&\0\0\0■!!%\2\0\0\0\6\15▮▮\14\0\0\0\4\15\4□\13\0\0\0n\4>e&\0\0\0\34_□□\10\0\0\0゛\8<■\6\0\0\0\8\6\1\6\8\0\0\0■=■■\9\0\0\0\15▮\0\1゛\0\0\0\4゛\8\1\6\0\0\0\1\1\1■\14\0\0\0\4゜\4\6\4\0\0\0□?□\2、\0\0\0゛\8?\2、\0\0\0\2\0072\0022\0\0\0\15\2\14▮、\0\0\0゜ ▮\12\0\0\0゜\8\4\4\8\0\0\0\4、\2\1゛\0\0\0002\7□x「\0\0\0=!\1\0059\0\0\0\9>kmf\0\0\0¥'\34s2\0\0\0<jiif\0\0\0\9。\9。\13\0\0\0#b\34\34、\0\0\0\12\0\8*m\0\0\0\0\12□!@\0\0\0}y■=]\0\0\0゜゛\4\15▶\0\0\0\3□?⁙\8\0\0\0□'\2#゛\0\0\0\5゛-#「\0\0\0\15\2\15\34、\0\0\0\10゜□\4\4\0\0\0。+)「\4\0\0\0\2\14\2\15\3\0\0\0\4\1゜▮\14\0\0\0■■⁙▮\12\0\0\0゜\12□9「\0\0\0\2•◀⁙2\0\0\0゜\12□!「\0\0\0¥'\34#□\0\0\0\0072\14⁘<\0\0\0\4\2\6+」\0\0\0\0\0\7\8\4\0\0\0\0\10゜□\4\0\0\0\0\4\15‖\13\0\0\0\0\2\6\3\7\0\0\0゜▮\10\2\1\0\0\0「\4\7\4\4\0\0\0\4゜■▮\12\0\0\0゜\4\4\4゜\0\0\0\8?\12\10\9\0\0\0\2゜□■」\0\0\0\4゜\4゜\4\0\0\0゛□■\8\4\0\0\0\2>\9\8\4\0\0\0゜▮▮▮゜\0\0\0□?□▮\8\0\0\0\3▮⁙\8\6\0\0\0゜▮\8\12⁙\0\0\0\2゜□\2、\0\0\0■□▮\8\6\0\0\0>\34-0\12\0\0\0\14\4゜\4\2\0\0\0‖‖▮\8\6\0\0\0\14\0゜\4\2\0\0\0\1\1\7\9\1\0\0\0\4゜\4\4\2\0\0\0\0\14\0\0゜\0\0\0゜▮⁘\8◀\0\0\0\4゜「/\4\0\0\0▮▮▮\8\7\0\0\0\8□□\34!\0\0\0\1\15\1\1\14\0\0\0゜▮▮\8\6\0\0\0\12□!@\0\0\0\0\4゜\4‖‖\0\0\0゜▮\10\4\8\0\0\0゛\0゜\0\15\0\0\0\4\2□!?\0\0\0 ⁘\0084\3\0\0\0\15\2\15\2゛\0\0\0\2゜□\2\2\0\0\0\14\8\8\8゜\0\0\0\15\8\15\8\15\0\0\0゜\0゜▮\12\0\0\0\9\9\9\8\4\0\0\0\10\10\10*」\0\0\0\1\1■\9\7\0\0\0゜■■■゜\0\0\0゜■▮\8\6\0\0\0゜▮゛▮\12\0\0\0\3▮▮\8\7\0\0\0\0‖▮\8\6\0\0\0\0\2\15\10\2\0\0\0\0\0\6\4\15\0\0\0\0\7\6\4\7\0\0\0\8\4c▮\8\0\0\0\8▮c\4\8\0\0\0"
6+
7+
wrote=false
8+
function _draw()
9+
10+
cls()
11+
print("\14ove worm with", 13, 6, 5)
12+
--print("\14w", 13, 6, 5)
13+
14+
end
15+
__gfx__
16+
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
17+
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
18+
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
19+
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
20+
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
21+
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
291 Bytes
Loading

test/endtoendtests.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,22 @@ TEST_CASE("Loading and running carts") {
10081008

10091009
vm->CloseCart();
10101010
}
1011+
SUBCASE("Per character width adjustment test"){
1012+
vm->LoadCart("per_char_width_test.p8", false);
1013+
vm->vm_run();
1014+
vm->Step();
1015+
1016+
SUBCASE("No error reported"){
1017+
CHECK(vm->GetBiosError() == "");
1018+
}
1019+
SUBCASE("screen matches screenshot"){
1020+
vm->Step();
1021+
1022+
CHECK(verifyScreenshot(vm, host, "carts/screenshots/per_char_width_test_f01.png"));
1023+
}
1024+
1025+
vm->CloseCart();
1026+
}
10111027

10121028
delete vm;
10131029
delete host;

0 commit comments

Comments
 (0)