Skip to content

Commit

Permalink
Merge pull request #150 from jtothebell/OneOffChars
Browse files Browse the repository at this point in the history
One off chars
  • Loading branch information
jtothebell authored Jul 11, 2022
2 parents 406daff + 179d083 commit b335927
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 3 deletions.
62 changes: 62 additions & 0 deletions source/graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <string.h>
#include <string>
#include <algorithm>
#include <vector>

#include "graphics.h"
#include "hostVmShared.h"
Expand Down Expand Up @@ -1316,6 +1317,67 @@ int Graphics::drawCharacter(uint8_t ch, int x, int y, uint8_t printMode) {
return extraCharWidth;
}

std::tuple<int, int> Graphics::drawCharacterFromBytes(
uint8_t chBytes[],
int x,
int y,
uint8_t fgColor,
uint8_t bgColor,
uint8_t printMode) {

applyCameraToPoint(&x, &y);
uint8_t *screenBuffer = GetP8FrameBuffer();

int extraCharWidth = 0;
int extraCharHeight = 0;
//these may need to get passed in later when drawing normal chars
int charWidth = 8;
int charHeight = 8;
int wFactor = 1;
int hFactor = 1;
//TODO: character modes
bool evenPxOnly = false;

if ((printMode & PRINT_MODE_ON) == PRINT_MODE_ON){
if ((printMode & PRINT_MODE_WIDE) == PRINT_MODE_WIDE) {
wFactor = 2;
extraCharWidth = 8;
}
if((printMode & PRINT_MODE_TALL) == PRINT_MODE_TALL) {
hFactor = 2;
extraCharHeight = 8;
}
if((printMode & PRINT_MODE_STRIPEY) == PRINT_MODE_STRIPEY) {
//draw every other pixel-- also kinda broken on pico 8 0.2.4
evenPxOnly = true;
}
//TODO: other print modes
}

if (bgColor != 0) {
uint8_t prevPenColor = _memory->drawState.color;
rectfill(x-1, y-1, x + charWidth*wFactor - 1, y + charHeight*hFactor - 1, bgColor);
_memory->drawState.color = prevPenColor;
}

for (size_t i = 0; i < charHeight * hFactor; i++) {
for(uint8_t bitn = 0; bitn < charWidth * wFactor; bitn++) {
bool on = BITMASK(bitn / wFactor) & chBytes[i / hFactor];
on &= wFactor == 1 || !evenPxOnly || (i % 2 == 0);
on &= wFactor == 1 || !evenPxOnly || (bitn % 2 == 0);
const int pixX = x + bitn;
const int pixY = y + i;
if (on && isWithinClip(pixX, pixY)) {
setPixelNibble(pixX, pixY, fgColor, screenBuffer);
}
}
}

std::tuple<int, int> retVal (extraCharWidth, extraCharHeight);

return retVal;
}

void Graphics::spr(
int n,
int x,
Expand Down
7 changes: 7 additions & 0 deletions source/graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ class Graphics {
fix32 fillp(fix32 pat);

int drawCharacter(uint8_t ch, int x, int y, uint8_t printMode = 0);
std::tuple<int, int> drawCharacterFromBytes(
uint8_t chBytes[],
int x,
int y,
uint8_t fgColor,
uint8_t bgColor,
uint8_t printMode);

void spr(
int n,
Expand Down
48 changes: 45 additions & 3 deletions source/printHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ Graphics* _ph_graphics;
Vm* _ph_vm;
Audio* _ph_audio;

void oneOffCharToBytes(std::string hex, uint8_t byteBuff[]) {
char buff[3];
buff[2] = 0;
for (unsigned int i = 0; i < hex.length(); i += 2) {
buff[0] = hex[i];
buff[1] = hex[i+1];
uint8_t byte = (uint8_t) strtol(buff, NULL, 16);
byteBuff[i/2] = byte;
}
}

void initPrintHelper(PicoRam* memory, Graphics* graphics, Vm* vm, Audio* audio) {
_ph_mem = memory;
_ph_graphics = graphics;
Expand Down Expand Up @@ -86,6 +97,8 @@ int print(std::string str, int x, int y, uint8_t c) {
int charHeight = 6;
int lineHeight = 6;
uint8_t bgColor = 0;
uint8_t fgColor = _ph_mem->drawState.color;
uint8_t charBytes[8];

uint8_t printMode = _ph_mem->hwState.printAttributes;

Expand Down Expand Up @@ -242,6 +255,35 @@ int print(std::string str, int x, int y, uint8_t c) {
printMode |= PRINT_MODE_ON;
printMode |= PRINT_MODE_SOLID_BG;
}
else if (commandChar == ':' || commandChar == '.'){
lineHeight = 8;
charHeight = 8;
if (commandChar == ':') {
std::string hexStr = str.substr(n+1, 16);
n+=16;
oneOffCharToBytes(hexStr, charBytes);
}
else {
std::string binStr = str.substr(n+1, 8);
n+=8;
for(size_t i = 0; i < 8; i++) {
charBytes[i] = binStr[i];
}
}

//TODO: combine with other text rendering
auto values = _ph_graphics->drawCharacterFromBytes(
charBytes,
x,
y,
prevDrawPal[fgColor & 0x0f],
bgColor,
printMode);

x += 8 + get<0>(values);
charHeight = charHeight + get<1>(values);
lineHeight = charHeight > lineHeight ? charHeight : lineHeight;
}
else if (commandChar == '-'){
uint8_t turnOffModeChar = str[++n];
if (printMode) {
Expand Down Expand Up @@ -280,9 +322,9 @@ int print(std::string str, int x, int y, uint8_t c) {
}
else if (ch == 12) { //"\f{p0}" draw text with this foreground color
uint8_t fgColChar = str[++n];
uint8_t fgCol = p0CharToNum(fgColChar);
_ph_graphics->color(fgCol);
_ph_mem->drawState.drawPaletteMap[7] = _ph_graphics->getDrawPalMappedColor(fgCol);
fgColor = p0CharToNum(fgColChar);
_ph_graphics->color(fgColor);
_ph_mem->drawState.drawPaletteMap[7] = _ph_graphics->getDrawPalMappedColor(fgColor);
}
else if (ch == '\n') {
x = _ph_mem->drawState.text_x;
Expand Down
25 changes: 25 additions & 0 deletions test/carts/one_off_chars.p8
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
pico-8 cartridge // http://www.pico-8.com
version 35
__lua__
function _draw()
cls(1)
pal()
?"\f7\#4\^p\^:447cb67c3e7f0106"
?"\f8hey\^:0ff00000000000ff"
?"\f6wat\^:447cb67c3e7f0106"
?"\^.d|へ|>○\1\6cat"
?"\^:041f051f141f0400other string"
pal(4,14)
?"\#4\^:1f1b111b1f0e0400"
?"\f3\^:0804061f0c040200"
?"\^:081c226b221c0800"
pal(3,15)
?"\^w\^:447cb67c3e7f0106"
end
__gfx__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Binary file added test/carts/screenshots/one_off_chars_f01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions test/endtoendtests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,20 @@ TEST_CASE("Loading and running carts") {

vm->CloseCart();
}
SUBCASE("One off char printing"){
vm->LoadCart("one_off_chars.p8");

SUBCASE("No error reported"){
CHECK(vm->GetBiosError() == "");
}
SUBCASE("sceen matches screenshot"){
vm->UpdateAndDraw();

CHECK(verifyScreenshot(vm, host, "carts/screenshots/one_off_chars_f01.png"));
}

vm->CloseCart();
}

delete vm;
delete host;
Expand Down
58 changes: 58 additions & 0 deletions test/printHelperTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,64 @@ TEST_CASE("Print helper functions") {

checkPoints(graphics, expectedPoints);
}
SUBCASE("p8scii special control code for one off character(\\^:) (colored)") {
graphics->cls();

print("\x0c""2\x06"":447cb67c3e7f0106", 0, 0);

std::vector<coloredPoint> expectedPoints = {
{0, 0, 0},
{1, 0, 0},
{2, 0, 2},
{3, 0, 0},
{4, 0, 0},
{5, 0, 0},
{6, 0, 2},
{7, 0, 0},
{0, 1, 0},
{1, 1, 0},
{2, 1, 2},
{3, 1, 2},
{4, 1, 2},
{5, 1, 2},
{6, 1, 2},
{7, 1, 0},
{0, 2, 0},
{1, 2, 2},
{2, 2, 2},
{3, 2, 0},
{4, 2, 2},
{5, 2, 2},
{6, 2, 0},
{7, 2, 2},
};

checkPoints(graphics, expectedPoints);
}
SUBCASE("p8scii special control code for one off character(\\^:) (pinballed with bg)") {
graphics->cls();

print("\x02""4\x06""p\x06"":447cb67c3e7f0106", 0, 0);

std::vector<coloredPoint> expectedPoints = {
{0, 0, 4},
{1, 0, 4},
{2, 0, 4},
{3, 0, 4},
{4, 0, 6},
{5, 0, 4},
{6, 0, 4},
{7, 0, 4},
{8, 0, 4},
{9, 0, 4},
{10, 0, 4},
{11, 0, 4},
{12, 0, 6},
{13, 0, 4},
};

checkPoints(graphics, expectedPoints);
}
SUBCASE("Poke default print mode but not turned on") {
graphics->cls();

Expand Down

0 comments on commit b335927

Please sign in to comment.