Skip to content
Open
Show file tree
Hide file tree
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
126 changes: 89 additions & 37 deletions LanguageBarrier/GameText.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,12 @@ static rnDrawTextHookProc rnDrawTextReal = NULL;

static rnDrawTextHookProc sgpDrawText = NULL;
static rnDrawTextHookProc sgpDrawTextReal = NULL;

unsigned int sglbpGlyphMask(int textureId, int a2, float glyphInTextureStartX,
float glyphInTextureStartY,
float glyphInTextureWidth,
float glyphInTextureHeight, float a7, float a8,
float a9, float a10, float a11, float a12,
signed int inColor, signed int opacity);
namespace {
lb::Hook<drawMde_t>* g_drawMde = nullptr;
lb::Hook<helpDisp_t>* g_helpDisp = nullptr;
Expand Down Expand Up @@ -225,18 +230,12 @@ using Sg0DrawGlyph3_Float_t = unsigned int(__cdecl*)(
static Sg0DrawGlyph3Proc gameExeSg0DrawGlyph3 = NULL;
static Sg0DrawGlyph3Proc gameExeSg0DrawGlyph3Real = NULL;



static Sg0DrawGlyph3_Int_t gameExeSg0DrawGlyph3_Int_Real = nullptr;
static Sg0DrawGlyph3_Float_t gameExeSg0DrawGlyph3_Float_Real = nullptr;



static Sg0DrawGlyph3_Int_t gameExeSg0DrawGlyph3_Int = nullptr;
static Sg0DrawGlyph3_Float_t gameExeSg0DrawGlyph3_Float = nullptr;



typedef unsigned int(__cdecl* DrawSpriteMaskInternalProc)(float* a1, int a2,
float* a3, float* a4,
void* a5, float a6,
Expand Down Expand Up @@ -421,6 +420,9 @@ static std::string* fontBuffers[3] = {0};

static char* tipContent;




// MSVC doesn't like having these inside namespaces
__declspec(naked) void dialogueLayoutWidthLookup1Hook() {
__asm {
Expand All @@ -447,8 +449,6 @@ extern "C" void GetOriginalAddress() {
originalHookHelpDispAddress = (uintptr_t)g_helpDisp->original;
}



__declspec(naked) void helpDispAlphaFixHook(int a1) {
__asm {
push eax
Expand Down Expand Up @@ -626,6 +626,14 @@ int __cdecl getSc3StringLineCountHook(int lineLength, char* sc3string,
unsigned int baseGlyphSize);
int __cdecl getRineInputRectangleHook(int* lineLength, char* text,
unsigned int baseGlyphSize);

unsigned int sglbpGlyphMask(int textureId, int a2, float glyphInTextureStartX,
float glyphInTextureStartY,
float glyphInTextureWidth,
float glyphInTextureHeight, float a7, float a8,
float a9, float a10, float a11, float a12,
signed int inColor, signed int opacity);

int __cdecl sg0DrawGlyphHook(int textureId, float glyphInTextureStartX,
float glyphInTextureStartY,
float glyphInTextureWidth,
Expand Down Expand Up @@ -659,7 +667,7 @@ unsigned int sg0DrawGlyph3HookInt(int textureId, int maskTextureId,
int textureStartX, int textureStartY,
int textureSizeX, int textureSizeY,
int startPosX, int startPosY, int EndPosX,
int EndPosY, int color, int opacity);
int EndPosY, int color, int opacity);

int __cdecl setTipContentHook(char* sc3string);
void __cdecl drawTipContentHook(int textureId, int maskId, int startX,
Expand Down Expand Up @@ -742,17 +750,21 @@ GameID currentGame;
bool UseNewTextSystem = false;

void gameTextInit() {
auto& gameName = configGetGameName();
if (gameName == std::string("STEINS;GATE")) currentGame = SG;

if (config["gamedef"].count("dialoguePageVersion") == 1) {
if (config["gamedef"]["dialoguePageVersion"].get<std::string>() == "rn") {
auto& dialoguePageVersion =
config["gamedef"]["dialoguePageVersion"].get<std::string>();
if (dialoguePageVersion == "rn") {
currentGame = RNE;
} else if (config["gamedef"]["dialoguePageVersion"].get<std::string>() ==
"rnd") {
} else if (dialoguePageVersion == "rnd") {
currentGame = RND;
} else if (config["gamedef"]["dialoguePageVersion"].get<std::string>() ==
"sgmde") {
} else if (dialoguePageVersion == "sgmde") {
currentGame = SGMDE;
}
}

if (config["patch"].count("useNewTextSystem") == 1)
UseNewTextSystem = config["patch"]["useNewTextSystem"].get<bool>();

Expand Down Expand Up @@ -833,12 +845,10 @@ void gameTextInit() {
scanCreateEnableHook(
"game", "sg0DrawGlyph2", (uintptr_t*)&gameExeSg0DrawGlyph2,
(LPVOID)sg0DrawGlyph2Hook, (LPVOID*)&gameExeSg0DrawGlyph2Real);

scanCreateEnableHook("game", "sg0DrawGlyph3",
(uintptr_t*)&gameExeSg0DrawGlyph3_Int,
(LPVOID)sg0DrawGlyph3HookInt,
(LPVOID*)&gameExeSg0DrawGlyph3_Int_Real);


scanCreateEnableHook(
"game", "sg0DrawGlyph3", (uintptr_t*)&gameExeSg0DrawGlyph3_Int,
(LPVOID)sg0DrawGlyph3HookInt, (LPVOID*)&gameExeSg0DrawGlyph3_Int_Real);

} else if (config["gamedef"]["drawGlyphVersion"].get<std::string>() == "rn") {
scanCreateEnableHook("game", "drawGlyph", (uintptr_t*)&gameExeDrawGlyph,
Expand All @@ -848,8 +858,6 @@ void gameTextInit() {
"game", "sg0DrawGlyph2", (uintptr_t*)&gameExeSg0DrawGlyph2,
(LPVOID)sg0DrawGlyph2Hook, (LPVOID*)&gameExeSg0DrawGlyph2Real);



GameExeDrawSpriteMaskInternal =
(DrawSpriteMaskInternalProc)sigScan("game", "drawSpriteMaskInternal");
GameExeGetShader = (GetShaderProc)sigScan("game", "getShader");
Expand All @@ -869,9 +877,17 @@ void gameTextInit() {
if (currentGame != SGMDE) currentGame = SGLBP;
gameExeDrawLbpGlyphMask =
(DrawLbpGlyphMaskProc)sigScan("game", "lbpDrawGlyph2");
} else if (currentGame == SG) {

scanCreateEnableHook(
"game", "lbpDrawGlyph2", (uintptr_t*)&gameExeDrawLbpGlyphMask,
(LPVOID)sglbpGlyphMask, (LPVOID*)&gameExeDrawLbpGlyphMaskReal);

}



if (currentGame == SGE || currentGame == SGLBP) {
if (currentGame == SGE || currentGame == SGLBP || currentGame == SG) {
scanCreateEnableHook("game", "sg0DrawGlyph3",
(uintptr_t*)&gameExeSg0DrawGlyph3_Float,
(LPVOID)sg0DrawGlyph3HookFloat,
Expand All @@ -883,9 +899,7 @@ void gameTextInit() {
(LPVOID*)&gameExeSg0DrawGlyph3_Int_Real);
}

scanCreateEnableHook(
"game", "sg0DrawGlyph3", (uintptr_t*)&gameExeSg0DrawGlyph3,
(LPVOID)sg0DrawGlyph3Hook, (LPVOID*)&gameExeSg0DrawGlyph3Real);


uintptr_t gameExeSgpDrawMailTextHook;
scanCreateEnableHook("game", "sgpDrawMailText",
Expand Down Expand Up @@ -2539,9 +2553,9 @@ float addCharacter(ProcessedSc3String_t* result, int baseGlyphSize, int glyphId,
result->linkNumber[i] = curLinkNumber;
result->glyph[i] = glyphId;
result->textureStartX[i] =
FONT_CELL_WIDTH * multiplier * (glyphId % FONT_ROW_LENGTH);
FONT_CELL_WIDTH * multiplier * (glyphId % FONT_ROW_LENGTH) + FONT_X_OFFSET;
result->textureStartY[i] =
FONT_CELL_HEIGHT * multiplier * (glyphId / FONT_ROW_LENGTH);
FONT_CELL_HEIGHT * multiplier * (glyphId / FONT_ROW_LENGTH) + FONT_Y_OFFSET;
result->textureWidth[i] = widths[glyphId] * multiplier;
result->textureHeight[i] = FONT_CELL_HEIGHT * multiplier;
result->displayStartX[i] =
Expand Down Expand Up @@ -3130,16 +3144,27 @@ int __cdecl getRineInputRectangleHook(int* lineLength, char* text,
*lineLength = str.usedLineLength;
return str.lines + 1;
}

unsigned int sglbpGlyphMask(int textureId, int a2, float glyphInTextureStartX,
float glyphInTextureStartY,
float glyphInTextureWidth,
float glyphInTextureHeight, float a7, float a8,
float a9, float a10, float a11, float a12,
signed int inColor, signed int opacity) {
return gameExeDrawLbpGlyphMaskReal(
textureId, a2, glyphInTextureStartX + FONT_X_OFFSET,
glyphInTextureStartY + FONT_Y_OFFSET, glyphInTextureWidth,
glyphInTextureHeight, a7, a8, a9, a10, a11, a12, inColor, opacity);
}


int sg0DrawGlyphHook(int textureId, float glyphInTextureStartX,
float glyphInTextureStartY, float glyphInTextureWidth,
float glyphInTextureHeight, float displayStartX,
float displayStartY, float displayEndX, float displayEndY,
int color, uint32_t opacity) {
if (!HAS_SPLIT_FONT) {
if (glyphInTextureStartY > 4080.0) {
glyphInTextureStartY += 4080.0;
--textureId;
}

} else if (textureId == OUTLINE_TEXTURE_ID) {
float origStartY = glyphInTextureStartY;
// undo the game's splitting
Expand All @@ -3154,12 +3179,29 @@ int sg0DrawGlyphHook(int textureId, float glyphInTextureStartX,
}
}

return gameExeDrawGlyphReal(
textureId, glyphInTextureStartX, glyphInTextureStartY,
glyphInTextureWidth, glyphInTextureHeight, displayStartX, displayStartY,
displayEndX, displayEndY, color, opacity);
float x = glyphInTextureStartX + FONT_X_OFFSET;
float y = glyphInTextureStartY + FONT_Y_OFFSET;
float w = glyphInTextureWidth;
float h = glyphInTextureHeight;

if (w >= 1.0f) {
x += 0.5f;
w += 1.0f;
}
if (h >= 1.0f) {
y += 0.5f;
h += 1.0f;
}

return gameExeDrawGlyphReal(textureId, x, y, w, h, displayStartX,
displayStartY, displayEndX, displayEndY, color,
opacity);
}





int rnDrawGlyphHook(int textureId, float glyphInTextureStartX,
float glyphInTextureStartY, float glyphInTextureWidth,
float glyphInTextureHeight, float displayStartX,
Expand Down Expand Up @@ -3290,6 +3332,7 @@ int __cdecl rnDrawTextHook(signed int textureId, int a2, signed int startY,
return 1;
}


unsigned int sg0DrawGlyph2Hook(int textureId, int a2,
float glyphInTextureStartX,
float glyphInTextureStartY,
Expand Down Expand Up @@ -3347,6 +3390,8 @@ unsigned int sg0DrawGlyph3HookInt(int textureId, int maskTextureId,
int startPosX, int startPosY, int EndPosX,
int EndPosY, int color,
int opacity) {
textureStartX += FONT_X_OFFSET;
textureStartY += FONT_Y_OFFSET;
return gameExeSg0DrawGlyph3_Int_Real(
textureId, maskTextureId, textureStartX, textureStartY, textureSizeX,
textureSizeY, startPosX, startPosY, EndPosX, EndPosY, color, opacity);
Expand All @@ -3357,6 +3402,8 @@ unsigned int sg0DrawGlyph3HookFloat(int textureId, int maskTextureId,
float textureSizeX, float textureSizeY,
float startPosX, float startPosY, float EndPosX,
float EndPosY, int color, int opacity) {
textureStartX += FONT_X_OFFSET;
textureStartY += FONT_Y_OFFSET;
return gameExeSg0DrawGlyph3_Float_Real(
textureId, maskTextureId, textureStartX, textureStartY, textureSizeX,
textureSizeY, startPosX, startPosY, EndPosX, EndPosY, color, opacity);
Expand All @@ -3365,6 +3412,8 @@ unsigned int sg0DrawGlyph3HookFloat(int textureId, int maskTextureId,
unsigned int sg0DrawGlyph3Hook(int textureId, int maskTextureId, float tx,
float ty, float tw, float th, float sx, float sy,
float ex, float ey, int color, int opacity) {


if (currentGame == SGLBP || currentGame == SGE) {
return gameExeSg0DrawGlyph3_Float_Real(textureId, maskTextureId, tx, ty, tw,
th, sx, sy, ex, ey, color, opacity);
Expand Down Expand Up @@ -3666,6 +3715,9 @@ int drawSpriteHook(int textureId, float spriteX, float spriteY,
shaderId);
}




void __cdecl sgpDrawMailTextHook(int startX, int startY, char* sc3String,
unsigned int lineLength, int opacity) {
char* currentSc3; // edi
Expand Down
3 changes: 3 additions & 0 deletions LanguageBarrier/GameText.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
namespace lb {
LB_GLOBAL uint8_t FIRST_FONT_ID;
LB_GLOBAL float COORDS_MULTIPLIER;
LB_GLOBAL float FONT_X_OFFSET;
LB_GLOBAL float FONT_Y_OFFSET;
LB_GLOBAL uint8_t FONT_CELL_WIDTH;
LB_GLOBAL uint8_t FONT_CELL_HEIGHT;

LB_GLOBAL uint8_t FONT_ROW_LENGTH;
static const uint16_t TOTAL_NUM_FONT_CELLS = 8000;
LB_GLOBAL uint16_t GLYPH_RANGE_FULLWIDTH_START;
Expand Down
9 changes: 9 additions & 0 deletions LanguageBarrier/LanguageBarrier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ void loadJsonConstants() {
// GameText.h
FIRST_FONT_ID = config["gamedef"]["firstFontId"].get<uint8_t>();
COORDS_MULTIPLIER = config["gamedef"]["coordsMultiplier"].get<float>();
FONT_X_OFFSET = 0.0f;
if (config["gamedef"].count("fontXOffset") == 1) {
FONT_X_OFFSET = config["gamedef"]["fontXOffset"].get<float>();
}
FONT_Y_OFFSET = 0.0f;
if (config["gamedef"].count("fontYOffset") == 1) {
FONT_Y_OFFSET = config["gamedef"]["fontYOffset"].get<float>();
}
FONT_CELL_WIDTH = config["gamedef"]["fontCellWidth"].get<uint8_t>();
FONT_CELL_HEIGHT = config["gamedef"]["fontCellHeight"].get<uint8_t>();
FONT_ROW_LENGTH = config["gamedef"]["fontRowLength"].get<uint8_t>();
Expand All @@ -130,6 +138,7 @@ void loadJsonConstants() {
SGHD_LINK_UNDERLINE_GLYPH_Y =
config["gamedef"]["sghdLinkUnderlineGlyphY"].get<float>();
SGHD_PHONE_X_PADDING = config["patch"]["sghdPhoneXPadding"].get<int>();
SGHD_PHONE_X_PADDING += FONT_X_OFFSET;
}
// these are default true for backwards compatibility with S;G0 patch config
HAS_DOUBLE_GET_SC3_STRING_DISPLAY_WIDTH = true;
Expand Down