Serious-Engine/Sources/GameMP/CompMessage.cpp
Ryan C. Gordon 24cb244d43 First attempt to hand-merge Ryan's Linux and Mac OS X port.
This was a _ton_ of changes, made 15 years ago, so there are probably some
problems to work out still.

Among others: Engine/Base/Stream.* was mostly abandoned and will need to be
re-ported.

Still, this is a pretty good start, and probably holds a world record for
lines of changes or something.  :)
2016-03-28 23:46:13 -04:00

219 lines
5.0 KiB
C++

/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "StdAfx.h"
#include "CompMessage.h"
extern CTString _strStatsDetails;
CCompMessage::CCompMessage(void)
{
Clear();
}
void CCompMessage::Clear(void)
{
UnprepareMessage();
cm_fnmFileName.Clear();
cm_pcmiOriginal = NULL;
cm_bRead = FALSE;
}
// constructs message with a filename
void CCompMessage::SetMessage(CCompMessageID *pcmi)
{
cm_fnmFileName = pcmi->cmi_fnmFileName;
cm_bRead = pcmi->cmi_bRead;
cm_pcmiOriginal = pcmi;
}
// load a message from file
void CCompMessage::Load_t(void)
{
// if already loaded
if (cm_bLoaded) {
// do nothing
return;
}
// open file
CTFileStream strm;
strm.Open_t(cm_fnmFileName);
// read subject line
strm.ExpectKeyword_t("SUBJECT\r\n");
strm.GetLine_t(cm_strSubject);
// rea image type
strm.ExpectKeyword_t("IMAGE\r\n");
CTString strImage;
strm.GetLine_t(strImage);
if (strImage=="none") {
cm_itImage = IT_NONE;
} else if (strImage=="statistics") {
cm_itImage = IT_STATISTICS;
} else if (strImage=="picture") {
cm_itImage = IT_PICTURE;
cm_fnmPicture.ReadFromText_t(strm);
} else if (strImage=="model") {
cm_itImage = IT_MODEL;
cm_strModel.ReadFromText_t(strm, "");
} else {
throw TRANS("Unknown image type!");
}
// read text until end of file
strm.ExpectKeyword_t("TEXT\r\n");
cm_strText.ReadUntilEOF_t(strm);
cm_ctFormattedWidth = 0;
cm_ctFormattedLines = 0;
cm_strFormattedText = "";
cm_bLoaded = TRUE;
}
// format message for given line width
void CCompMessage::Format(INDEX ctCharsPerLine)
{
// if already formatted in needed size
if (cm_ctFormattedWidth == ctCharsPerLine) {
// do nothing
return;
}
// remember width
cm_ctFormattedWidth = ctCharsPerLine;
// get text
const char *strText = cm_strText;
if (strncmp(strText, "$STAT", 5)==0) {
strText = _strStatsDetails;
cm_strFormattedText = strText;
cm_ctFormattedLines = 1;
for (INDEX i=0; i<cm_strFormattedText.Length(); i++) {
if (cm_strFormattedText[i]=='\n') {
cm_ctFormattedLines++;
}
}
return;
}
// allocate overestimated buffer
SLONG slMaxBuffer = strlen(strText)*2;
char *pchBuffer = (char *)AllocMemory(slMaxBuffer);
// start at the beginning of text and buffer
const char *pchSrc = strText;
char *pchDst = pchBuffer;
cm_ctFormattedLines = 1;
INDEX ctChars = 0;
// while not end of text
while(*pchSrc!=0) {
// copy one char
char chLast = *pchDst++ = *pchSrc++;
// if it was line break
if (chLast=='\n') {
// new line
ctChars=0;
cm_ctFormattedLines++;
continue;
}
ctChars++;
// if out of row
if (ctChars>ctCharsPerLine) {
// start backtracking
const char *pchSrcBck = pchSrc-1;
char *pchDstBck = pchDst-1;
// while not start of row and not space
while (pchSrcBck>pchSrc-ctChars && *pchSrcBck!=' ') {
// go one char back
pchSrcBck--;
pchDstBck--;
}
// if start of row hit (cannot word-wrap)
if (pchSrcBck<pchSrc-ctChars) {
// just go to next line
pchSrc--;
pchDst--;
*pchDst++='\n';
ctChars=0;
cm_ctFormattedLines++;
continue;
}
// if can word-wrap, insert break before the last word
pchSrc = pchSrcBck+1;
pchDst = pchDstBck;
*pchDst++='\n';
ctChars=0;
cm_ctFormattedLines++;
}
}
// add end marker
*pchDst=0;
cm_strFormattedText = pchBuffer;
FreeMemory(pchBuffer);
}
// prepare message for using (load, format, etc.)
void CCompMessage::PrepareMessage(INDEX ctCharsPerLine)
{
// if not loaded
if (!cm_bLoaded) {
// try to
try {
// load it
Load_t();
// if failed
} catch (char *strError) {
// report warning
CPrintF("Cannot load message'%s': %s\n", (const char *) (const CTString &)cm_fnmFileName, strError);
// do nothing else
return;
}
}
// format it for new width
Format(ctCharsPerLine);
}
// free memory used by message, but keep message filename
void CCompMessage::UnprepareMessage(void)
{
// clear everything except filename
cm_bLoaded = FALSE;
cm_strSubject.Clear();
cm_strText.Clear();
cm_strModel.Clear();
cm_fnmPicture.Clear();
cm_itImage = IT_NONE;
cm_strFormattedText.Clear();
cm_ctFormattedWidth = 0;
cm_ctFormattedLines = 0;
}
// mark message as read
void CCompMessage::MarkRead(void)
{
cm_bRead = TRUE;
cm_pcmiOriginal->cmi_bRead = TRUE;
}
// get one formatted line
CTString CCompMessage::GetLine(INDEX iLine)
{
const char *strText = cm_strFormattedText;
// find first line
INDEX i = 0;
while (i<iLine) {
strText = strchr(strText, '\n');
if (strText==NULL) {
return "";
} else {
i++;
strText++;
}
}
// find end of line
CTString strLine = strText;
char *pchEndOfLine = strchr(strLine, '\n');
// if found
if (pchEndOfLine!=NULL) {
// cut there
*pchEndOfLine = 0;
}
return strLine;
}