Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 20 additions & 21 deletions src/features/plate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,40 +252,39 @@ bool LicensePlate::CCustomCarPlateMgr_RenderLicenseplateTextToRaster(const char
if (!charsRasterStride)
return false;

// Copy each character from charset raster to plate raster
// Going from left to right
// Size of a pixel (texel) in `pCharsetLockedData`. It's in 32 bit BGRA format
constexpr auto texelSize = 4;

auto plateRasterCharIter = lockedPlateRaster; // Always points to the top left corner of each character
// Pre-calculate character source pointers to improve memory locality and avoid redundant calculations
RwUInt8* charRasterBases[MAX_TEXT_LENGTH];
for (auto letter = 0; letter < MAX_TEXT_LENGTH; letter++)
{
Comment on lines +259 to 261
unsigned int charCol, charRow;
auto t = GetCharacterPositionInCharSet(text[letter]);
charCol = t.first;
charRow = t.second;
charRasterBases[letter] = &pCharsetLockedData[(CHARSET_COL_WIDTH * CHARSET_ROW_HEIGHT * charRow + CHARSET_CHAR_WIDTH * charCol) * texelSize];
}

// Copy specific character from charset raster to plate raster

// Size of a pixel (texel) in `pCharsetLockedData`. It's in 32 bit BGRA format
constexpr auto texelSize = 4;

// Character's top left corner in charset raster
auto charRasterIt = &pCharsetLockedData[(CHARSET_COL_WIDTH * CHARSET_ROW_HEIGHT * charRow + CHARSET_CHAR_WIDTH * charCol) * texelSize];

// Character's top left corner in target (plate) raster
auto plateRasterIt = plateRasterCharIter;
// Copy characters row by row (outer loop) to improve cache locality on destination raster
auto plateRasterRowIter = lockedPlateRaster;
for (auto r = 0u; r < CHARSET_CHAR_HEIGHT; r++)
{
auto plateRasterIt = plateRasterRowIter;

// Copy character row by row (going from top to bottom) to target (plate) raster
for (auto r = 0u; r < CHARSET_CHAR_HEIGHT; r++)
for (auto letter = 0; letter < MAX_TEXT_LENGTH; letter++)
{
memcpy(plateRasterIt, charRasterIt, CHARSET_CHAR_WIDTH * texelSize); // Copy row
memcpy(plateRasterIt, charRasterBases[letter], CHARSET_CHAR_WIDTH * texelSize); // Copy row for this character

// Advance character raster base to next row
charRasterBases[letter] += charsRasterStride;

// Advance to next row
plateRasterIt += plateRasterStride;
charRasterIt += charsRasterStride;
// Advance plate raster pointer to next character's column
plateRasterIt += CHARSET_CHAR_WIDTH * texelSize;
}

// Advance to next character's column
plateRasterCharIter += CHARSET_CHAR_WIDTH * texelSize;
// Advance to next row in target (plate) raster
plateRasterRowIter += plateRasterStride;
}

RwRasterUnlock(plateRaster);
Expand Down
Loading