#181093 - 12 April, 2008 09:05 AM
Laptop files section
|
lochkartenman
 Private
Registered:
Posts: 23
Loc: Braunschweig, Germany
|
Hi everybody!
I just downloaded the source code and browsed a bit around in the different files. One (of the many things) that I cannot figure is how and where is drawing things on the screen actually done?
I am no professional programmer nor do I have much experience in c++ but I would like to contribute a bit. For me it seemed as if externalizing the laptop "files" could be a starting point for me as this would provide the possibility to dive into the topic of XML-reading and probably drawing.
My idea is based onto the following XML-file layout:
<?xml version="1.0" encoding="utf-8"?>
<DOCUMENT>
<Name>Sample Document Name</Name>
<uiListPosition>0</uiListPosition>
<uiPages>1</uiPages>
<TRIGGERS>
<!-- see forum topic on externalized Airports -->
<TRIGGER>
<SectorPlayerControlled>B13</SectorPlayerControlled>
<SpokeToNPC>
<NPCProfileNo>114</NPCProfileNO>
<DialogChoice>2</DialogChoice>
<TestLDRSkill>1</TestLDRSkill>
</SpokeToNPC>
</TRIGGER>
<TRIGGER>
<PlayerProgressAt>57</PlayerProgressAt>
</TRIGGER>
</TRIGGERS>
<PAGES>
<PAGE>
<uiIndex>0</uiIndex>
<uiBoxes>1</uiBoxes>
<BOXES>
<BOX>
<uiIndex>0</uiIndex>
<uiType>0<uiType>
<uiPositionLeft>10</uiPositionLeft>
<uiPositionTop>10</uiPositionTop>
<uiPositionWidth>150</uiPositionWidth>
<uiPositionHeight>100</uiPositionHeight>
<FontSize>15</FontSize>
<FontStyle>0</FontStyle>
<FontColor>...</FontColor>
<uiTextIndex>index of localized text entry in some other XML file</uiText>
<Image>Path to image file relative to some folder..<Image>
</BOX>
</BOXES>
</PAGE>
</PAGES>
</DOCUMENT>
A "document" in the files-browser would consists of a one or more "pages", each of which could be accessed by the well-known arrow-buttons. A "page" is divided into one or more "boxes", whereas each box can contain either formatted text or an image (placed in the same folder as the xml, png-format!).
A number of such files would be placed in some folder (for ex. "\Laptop\Files"). On opening the files section of the laptop all xml-files in this folder would be read, the specific TRIGGERS-section evaluated and finally all matching entries draw in the files list on the left.
Problem is: while I probably could figure out how to read an xml into some sort of class-hierarchy I have no clue how to draw the whole thing onto the screen. For png-decoding I would propose to use libpng.
Please comment on this idea.
best regards Arne
|
|
Top
|
|
|
|
#181100 - 12 April, 2008 09:48 AM
Re: Laptop files section
[Re: lochkartenman]
|
Tron
 JA2 Stracciatella SMP Panel
Registered:
Posts: 275
Loc: Germany
|
Drawing the "laptop files" is hard-coded in Build/Laptop/files.cpp (Build/Laptop/files.c in the vanilla source code, Build/Laptop/Files.c in JA2-Stracciatella). There's nothing spectacular, just messy code to blit some pictures and draw text.
|
|
Top
|
|
|
|
#181102 - 12 April, 2008 10:03 AM
Re: Laptop files section
[Re: Tron]
|
lochkartenman
 Private
Registered:
Posts: 23
Loc: Braunschweig, Germany
|
@Tron Thanks for pointing me to the source file.
What library is used by Ja2 for drawing basic things such as images, lines, rectangles, text? Where do I get a reference to some sort of drawing surface?
|
|
Top
|
|
|
|
#181159 - 12 April, 2008 05:03 PM
Re: Laptop files section
[Re: lochkartenman]
|
BirdFlu
 Senior Coder VFS/RII SMP Coder
Registered:
Posts: 492
Loc: Lampukistan
|
LOL. Look at the files vobject.*, vobject_blitters.*, vsurface.* in the 'Standard Gaming Platform' directory. But i warn you, you won't like what you are going to see.
|
|
Top
|
|
|
|
#181165 - 12 April, 2008 06:55 PM
Re: Laptop files section
[Re: BirdFlu]
|
lochkartenman
 Private
Registered:
Posts: 23
Loc: Braunschweig, Germany
|
Had a look at these things. BirdFlu - you are right. I dont like it. After all: comments and structuring are totally overrated. (sarcasm!)
I will need some time to go into this. A am a bit spoiled by all this object-orientied stuff they tell you on university it seems. I'll dive into it but don't expect me back on the surface to soon.
best regards Arne
EDIT: By the way - is there any chance to get any decent GUI-toolkit (Qt, wxWidgeds, ..) incorporated into the game? For me it seems unnecessary to home-brew every thing if there are proven and well desinged libraries around.
Edited by lochkartenman (12 April, 2008 06:59 PM)
|
|
Top
|
|
|
|
#181198 - 13 April, 2008 04:15 AM
Re: Laptop files section
[Re: lochkartenman]
|
lochkartenman
 Private
Registered:
Posts: 23
Loc: Braunschweig, Germany
|
I further investigated the laptop & drawing code. I must admit: I am not amused. The whole thing a mess and if it were my code I would probably start all over and rewrite it - but I sense that this would exceed my abilities a bit.
I took the time to read some tutorials related to DirectDraw and realized that my idea of using GUI-toolkits was a bit too naive. So please pretend the comment weren't there. :-)
The question that remain is: does it make sense to put any effort into the GUI at this time or will the - hopefully - upcoming transition to an other tile engine also affect all other drawing stuff, thus making those changes done to the drawing code obsolete?
Since the game has a quite limited set of screens besides the tile engine, would it be feasible to simply rewrite the whole interface in a more streamlined manner and use the "old" tile engine beside the rewritten interface?
regards Arne
|
|
Top
|
|
|
|
#181224 - 13 April, 2008 08:16 AM
Re: Laptop files section
[Re: lochkartenman]
|
Kaiden
 Team v1.13 SMP Team Leader
Registered:
Posts: 1832
|
If all you want to do is add laptop files, web-pages, e-mails, etc... There is no need to rip everything out from the ground up. Use what's there. Expand on it, learn it. Then after you've used it repeatedly, been through it, pulled your hair out over having to use it, then think about replacing it.
|
|
Top
|
|
|
|
#181588 - 15 April, 2008 01:05 PM
Re: Laptop files section
[Re: Kaiden]
|
lochkartenman
 Private
Registered:
Posts: 23
Loc: Braunschweig, Germany
|
Hi there.
I would like to post here what I've come up with so far. Consider this a proof-of concept since drawing formatted text on the screen is obviously only part of the task. How to draw images is the next issue I will tackle.
Reading the XML-file seems quite straight forward to me since there is plenty "sample code" already.
What the code does: print a null-terminated CHAR16 array to a screen rectangle. Characters enclosed by [b] ... [/b] are printed bold. [nl] indicates a line break. Text alignment is specified for each text area.

For anyone interested the source code:
FormattedTextRenderer.h
#ifndef __FORMATTEDTEXTRENDERER_H
#define __FORMATTEDTEXTRENDERER_H
/******************************************************************************
Name : class FormattedTextRenderer
Created : 04/14/2008
Author : ARNE (Lochkartenman)
Class used for parsing and rendering a text string (CHAR16 array)
with embedded formatting tags similar to BB-Codes.
This class was developed for use in the laptop files screen but should
be easily adaptable to other text rendering tasks
REMARKS:
Italic-style is not yet implemented because Ja2 uses a fixed set of fonts.
If this system is ever reverted to use the appropiate Windows-API or if
italic fonts are added then this feature might be very well possible.
Coloring of Text is planned and should be possible with not too much effort.
I hold this back for now to concentrate on the actual externalizing part
for the laptop files and IMAGES.
Revision: 04/15/2008 - initial release
******************************************************************************/
class FormattedTextRenderer
{
public:
/**************************************************************************
structure representing a rectagle
*/
struct Rectangle
{
public:
UINT16 Top; // Y-coord. of upper left corner
UINT16 Left; // X-coord. of upper left corner
UINT16 Width; // width of rectangle
UINT16 Height; // height of rectangle
/**********************************************************************
contructor initializes the structure with values
UINT16 Top; - Y-coord. of upper left corner
UINT16 Left; - X-coord. of upper left corner
UINT16 Width; - width of rectangle
UINT16 Height; - height of rectangle
*/
Rectangle(UINT16 top, UINT16 left, UINT16 width, UINT16 height)
{
Top = top;
Left = left;
Width = width;
Height = height;
}
};
/**************************************************************************
enumeration of possible text alignments
*/
enum TextAlignmentEnum
{
Left,
Right,
Centered
};
/****************/
/* CONSTRUCTORS */
/****************/
FormattedTextRenderer(void);
/***********/
/* METHODS */
/***********/
void DrawFormattedTextToScreen(CHAR16 * text, Rectangle area);
/********************/
/* MEMBER ACCESSORS */
/********************/
void SetAlignment(TextAlignmentEnum alignment);
TextAlignmentEnum GetAlignment(void);
void SetNormalFont(UINT32 font);
UINT32 GetNormalFont(void);
void SetBoldFont(UINT32 font);
UINT32 GetBoldFont(void);
void SetItalicFont(UINT32 font);
UINT32 GetItalicFont(void);
void SetLineSpacing(UINT16 spacing);
UINT16 GetLineSpacing(void);
void SetLineHeight(UINT16 height);
UINT16 GetLineHeight(void);
private:
/***************/
/* DATA MEMBER */
/***************/
UINT32 NormalFont; // font for normal text
UINT32 BoldFont; // font for bold-styled text
UINT32 ItalicFont; // font for italic-styled text; NOT YET IMPLEMENTED
UINT16 LineSpacing; // additional vertical distance between lines in pixels
UINT16 LineHeight; // height of one line in pixels
TextAlignmentEnum Alignment; // alignment of the contents
/*************/
/* CONSTANTS */
/*************/
static const CHAR16 WORD_DELIMITER = 32; // Ascii-Code for word-delimiting char
static const CHAR16 TAG_START_CHAR = '['; // first character of any formatting tag
static const CHAR16 TAG_END_CHAR = ']'; // last character of any formatting tag
/***********/
/* METHODS */
/***********/
UINT16 GetLastCharacterOnLine(CHAR16 * text, UINT16 iStart, UINT16 maxLenght, UINT16 &lineLenght);
void DrawFormattedTextLineToScreen(CHAR16 * text, UINT16 iStart, UINT16 charCount, UINT16 locX, UINT16 locY);
BOOL TryMatchFormattingTag(CHAR16 * text, UINT16 iStart, CHAR16* tag, UINT16 &iResume);
BOOL IsBoldFontStartTag(CHAR16 * text, UINT16 iStart, UINT16 &iResume);
BOOL IsBoldFontEndTag(CHAR16 * text, UINT16 iStart, UINT16 &iResume);
BOOL IsNewLineTag(CHAR16 * text, UINT16 iStart, UINT16 &iResume);
};
#endif // include guard
FormattedTextRenderer.cpp
#ifdef PRECOMPILEDHEADERS
#include "Laptop All.h"
#else
#include "builddefines.h"
#include <stdio.h>
#include "laptop.h"
//#include "files.h"
//#include "Game clock.h"
//#include "Utilities.h"
//#include "WCheck.h"
#include "Debug.h"
#include "WordWrap.h"
//#include "Render Dirty.h"
//#include "Encrypted File.h"
//#include "cursors.h"
//#include "email.h"
//#include "text.h"
#endif
#include "FormattedTextRenderer.h"
/********************/
/* MEMBER ACCESSORS */
/********************/
/******************************************************************************
sets the private member 'Alignment'
*/
void FormattedTextRenderer::SetAlignment(FormattedTextRenderer::TextAlignmentEnum alignment)
{
Alignment = alignment;
}
/******************************************************************************
returns the value of the private member 'Alignment'
*/
FormattedTextRenderer::TextAlignmentEnum FormattedTextRenderer::GetAlignment(void)
{
return Alignment;
}
/******************************************************************************
sets the private member 'NormalFont'
*/
void FormattedTextRenderer::SetNormalFont(UINT32 font)
{
NormalFont = font;
}
/******************************************************************************
returns the value of the private member 'NormalFont'
*/
UINT32 FormattedTextRenderer::GetNormalFont(void)
{
return NormalFont;
}
/******************************************************************************
sets the private member 'BoldFont'
*/
void FormattedTextRenderer::SetBoldFont(UINT32 font)
{
BoldFont = font;
}
/******************************************************************************
returns the value of the private member 'BoldFont'
*/
UINT32 FormattedTextRenderer::GetBoldFont(void)
{
return BoldFont;
}
/******************************************************************************
sets the private member 'ItalicFont'
REMARK: until Ja2 supports abitrary fonts, italic style will not be
implemented.
*/
void FormattedTextRenderer::SetItalicFont(UINT32 font)
{
ItalicFont = font;
}
/******************************************************************************
returns the value of the private member 'ItalicFont'
*/
UINT32 FormattedTextRenderer::GetItalicFont(void)
{
return ItalicFont;
}
/******************************************************************************
sets the private member 'LineSpacing'
*/
void FormattedTextRenderer::SetLineSpacing(UINT16 spacing)
{
LineSpacing = spacing;
}
/******************************************************************************
returns the value of the private member 'LineSpacing'
*/
UINT16 FormattedTextRenderer::GetLineSpacing(void)
{
return LineSpacing;
}
/******************************************************************************
sets the private member 'LineHeight'
*/
void FormattedTextRenderer::SetLineHeight(UINT16 height)
{
LineHeight = height;
}
/******************************************************************************
returns the value of the private member 'LineHeight'
*/
UINT16 FormattedTextRenderer::GetLineHeight(void)
{
return LineHeight;
}
/****************/
/* CONSTRUCTORS */
/****************/
/******************************************************************************
constructor; sets default values for non-static-constant members
*/
FormattedTextRenderer::FormattedTextRenderer(void)
{
NormalFont = gp10PointArial;
BoldFont = gp10PointArialBold;
LineSpacing = 4;
LineHeight = ( WFGetFontHeight(NormalFont) + LineSpacing );
Alignment = Left;
}
/***********/
/* METHODS */
/***********/
/******************************************************************************
private GetLastCharacterOnLine(...)
returns the index of the last character in the passed string that fit onto
a line of specified width
CHAR16 * text - the text that is to be investigated
UINT16 iStart - position of starting character for this line
UINT16 maxLenght- maximum width of a line in pixels
UINT16 &lineLenght - the lenght of the fitting text in pixels
*/
UINT16 FormattedTextRenderer::GetLastCharacterOnLine(CHAR16 * text, UINT16 iStart, UINT16 maxLenght, UINT16 &lineLenght)
{
UINT16 iChar = iStart; // loop-counter; position of currently investigated character
UINT16 iLastWordDelimiter = 0; // position of last word delimiter character
UINT16 CurrentLineLenght = 0; // lenght of current line in pixels
UINT16 CurrentWordLenght = 0; // lenght of current word in pixels
CHAR16 CurrentChar[2]; // "array" holding a single char and a trailing null value
CurrentChar[1] = L'\0';
UINT16 CharWidth = 0; // width of the current character in pixels
UINT32 CurrentFont = NormalFont;// currently selected Font
/* walk over all characters in array 'text' until null-value indicates
the end of the string */
while ( text[iChar] != 0 )
{
switch( text[iChar] )
{
case TAG_START_CHAR: // start character for formatting tag found
{
if( IsBoldFontStartTag(text, iChar, iChar) == TRUE )
{
// select bold font
SetFont(BoldFont);
CurrentFont = BoldFont;
}
else if( IsBoldFontEndTag(text, iChar, iChar) == TRUE )
{
// select normal font
SetFont(NormalFont);
CurrentFont = NormalFont;
}
else if( IsNewLineTag(text, iChar, iChar) == TRUE )
{
// since a NewLine tag was found the line ends here
lineLenght = (CurrentLineLenght + CurrentWordLenght);
return iChar;
}
}
case WORD_DELIMITER: // word delimiting character found
{
/* the position of the last word delimiter found is stored
because if a character doesn't fit the line the non-complete
word is wrapped onto the following line */
iLastWordDelimiter = iChar;
}
default: // some other character found
{
/* if this case is reached then a character that needs to be
printed is reached. Measure the width of it using the
currently selected font and check whether it fits onto
the line.
if the character does not fit onto the line then all
characters until the last WORD_DELIMITER are put onto the
following line */
CurrentChar[0] = text[iChar];
CharWidth = WFStringPixLength(CurrentChar, CurrentFont);
CurrentWordLenght += CharWidth;
/* check whether the word fits onto the line */
if( (CurrentLineLenght + CurrentWordLenght) > maxLenght )
{
/* the word doesn' fit;
check whether the line has any characters on it.
If the line does have at least one character on it then
discard the last (non-fitting) word.
If the line has no characters on it then draw as many
characters as possible. */
if( CurrentLineLenght != 0 )
{
/* there are already characters on the line */
lineLenght = CurrentLineLenght;
return iLastWordDelimiter;
}
else
{
/* there are no characters on the line until now, that
is we have one word that does not fit even a full
line.
All but the last character until now are put onto
this line */
CurrentLineLenght = (CurrentWordLenght - CharWidth);
lineLenght = CurrentLineLenght;
return (iChar -1);
}
}
else
{
/* the word does fit; check whether we are at a word
ending and append the CurrentWordLenght to the
CurrentLineLenght */
if( iChar == iLastWordDelimiter )
{
CurrentLineLenght += CurrentWordLenght;
CurrentWordLenght = 0;
}
}
}
}
// never foget to increment the char-counter!
iChar++;
}
/* when we reached this point we have hit a null value indicating the end
of the array. Just return the index of the last character and the
lenght of the text so far */
lineLenght = (CurrentLineLenght + CurrentWordLenght);
return iChar;
}
/******************************************************************************
private DrawFormattedTextLineToScreen(...)
draws a line of formatted text to the screen.
CHAR16 * text - the text that should be drawn
UINT16 iStart - the position of the first character
UINT16 charCount- the number of characters to draw
UINT16 locX - vertical position of the first character in pixels
UINT16 locY - horizontal position of the first character in pixels
*/
void FormattedTextRenderer::DrawFormattedTextLineToScreen(CHAR16 * text, UINT16 iStart, UINT16 charCount, UINT16 locX, UINT16 locY)
{
UINT16 iChar = 0; // loop-counter; position of currently investigated character
CHAR16 CurrentChar[2]; // "array" holding a single char and a trailing null value
CurrentChar[1] = L'\0';
UINT16 CharWidth = 0; // width of the current character in pixels
UINT32 CurrentFont = NormalFont;// currently selected font
UINT8 CurrentColor = FONT_BLACK;// currently selected font color
for( iChar = iStart; iChar < (iStart + charCount); iChar++)
{
/* if we hit a character that might form a formatting tag, check this!
NOTE: if we have a formatting tag the value of iChar is altered
in such a way that it points to the character after the tag-closing
character! */
if( text[iChar] == TAG_START_CHAR )
{
if( IsBoldFontStartTag(text, iChar, iChar) == TRUE )
{
// select bold font
SetFont(BoldFont);
CurrentFont = BoldFont;
}
else if( IsBoldFontEndTag(text, iChar, iChar) == TRUE )
{
// select normal font
SetFont(NormalFont);
CurrentFont = NormalFont;
}
else if( IsNewLineTag(text, iChar, iChar) == TRUE )
{
return;
}
}
/* measure the width of the current character for clipping purposes */
CurrentChar[0] = text[iChar];
CharWidth = WFStringPixLength(CurrentChar, CurrentFont);
/* draw text */
DrawTextToScreen(CurrentChar, locX, locY, CharWidth, CurrentFont, CurrentColor, 0, FALSE, 0);
/* increase the vertical position by the width of the current character */
locX += CharWidth;
}
}
/*
public DrawFormattedTextToScreen(...)
draws the text given in the parameter 'text' into the screen area specified
by 'area' to the screen.
This method follows the class-property 'Alignment' and pays attention to
the formatting tags in the text.
CHAR16 * text - the text that should be drawn
Rectangle area - the area to draw the text into
*/
void FormattedTextRenderer::DrawFormattedTextToScreen(CHAR16 * text, Rectangle area)
{
UINT16 iStart = 0; // position of first character on current line
UINT16 iLast = 0; // position of last character on current line
UINT16 LineLenght = 0; // lenght of current line in pixels
UINT16 locY = area.Top; // horizontal position of first character of current line
UINT16 locX = 0; // vertical position of first character of current line
while ( text[iLast + 1] != 0 )
{
iStart = iLast;
/* if the last character of the preceeding line was a WORD_DELIMITER
then increment iStart by one to skip this WORD_DELIMITER because
we don't want to have a line begin with a WORD_DELIMITER */
if( text[iLast] == WORD_DELIMITER )
iStart++;
/* obtain the position of the last character to draw on this line */
iLast = GetLastCharacterOnLine(text, iStart, area.Width, LineLenght);
/* horizontal positioning depends on the selected text alignment */
switch ( Alignment )
{
case Left:
{
/* left alignment of text */
locX = area.Left;
break;
}
case Right:
{
/* right alignment of text */
locX = ( area.Left + (UINT16)((area.Width - LineLenght)*0.5) );
break;
}
case Centered:
{
/* centered alignment of text */
locX = ( area.Left + (area.Width - LineLenght) );
break;
}
}
/* draw the text */
DrawFormattedTextLineToScreen(text, iStart, iLast - iStart, locX, locY);
/* calculate the vertical position of the line
NOTE: we only allow fixed line height at the moment */
locY += (LineHeight + LineSpacing);
/* check whether our specified area can hold an other line.
if it can not then exit the loop */
if( locY > (area.Top + area.Height) )
break;
}
}
/******************************************************************************
private TryMatchFormattingTag(...)
compares a passed CHAR16 array 'text' with an other array 'tag' and
returns whether the two match.
CHAR16 * text - text to compare
UINT16 iStart - position to start comparision from
CHAR16 * tag - text to compare against; is evaluated from position 0.
UINT16 &iResume - position to resume parsing at
(first char after the tag if one is found)
*/
BOOL FormattedTextRenderer::TryMatchFormattingTag(CHAR16 * text, UINT16 iStart, CHAR16* tag, UINT16 &iResume)
{
UINT16 iChar = 0; // loop-counter
/* the position to resume parsing at is set when a match is found,
otherwise all chars from iStart on are considered normal characters
that should be printed normally. */
iResume = iStart;
/* walk over all characters in array 'text' until null-value indicates
the end of the string or the end of the formatting tag is reached */
while ( text[iChar + iStart] != 0 )
{
/* check whether the end of the tag array is reached; if this is the
case then return FALSE because we should have left the method
already in the previous loop circle if there were a match */
if( tag[iChar] == 0 )
return FALSE;
/* compare tag and text chars; if these do not match then we
return FALSE */
if( tag[iChar] != text[iChar + iStart] )
return FALSE;
/* if a TAG_END_CHAR is reached and the method wasn't otherwise
left then we have a match! */
if( text[iChar + iStart] == TAG_END_CHAR )
{
iResume = (iStart + iChar + 1);
return TRUE;
}
// never foget to increment the char-counter!
iChar++;
}
/* the method should be left already so this point is unlikely to be
hit but we want to shut up the compiler warning C4715
(The specified function can potentially not return a value.) */
return FALSE;
}
/******************************************************************************
private IsBoldFontStartTag(...)
checks whether there is the FONT_BOLD_START tag at the passed position
and returns TRUE or FALSE accordingly
CHAR16 * text - text to check
UINT16 iStart - suspected position
UINT16 &iResume - position to resume parsing at
(first char after the tag if one is found)
*/
BOOL FormattedTextRenderer::IsBoldFontStartTag(CHAR16 * text, UINT16 iStart, UINT16 &iResume)
{
return TryMatchFormattingTag(text, iStart, L"[b]", iResume);
}
/******************************************************************************
private IsBoldFontEndTag(...)
checks whether there is the FONT_BOLD_END tag at the passed position
and returns TRUE or FALSE accordingly
CHAR16 * text - text to check
UINT16 iStart - suspected position
UINT16 &iResume - position to resume parsing at
(first char after the tag if one is found)
*/
BOOL FormattedTextRenderer::IsBoldFontEndTag(CHAR16 * text, UINT16 iStart, UINT16 &iResume)
{
return TryMatchFormattingTag(text, iStart, L"[/b]", iResume);
}
/******************************************************************************
private IsNewLineTag(...)
checks whether there is the NEW_LINE tag at the passed position
and returns TRUE or FALSE accordingly
CHAR16 * text - text to check
UINT16 iStart - suspected position
UINT16 &iResume - position to resume parsing at
(first char after the tag if one is found)
*/
BOOL FormattedTextRenderer::IsNewLineTag(CHAR16 * text, UINT16 iStart, UINT16 &iResume)
{
return TryMatchFormattingTag(text, iStart, L"[nl]", iResume);
}
I would really appreciate some feedback.
best regards Arne
|
|
Top
|
|
|
|
#181598 - 15 April, 2008 02:17 PM
Re: Laptop files section
[Re: lochkartenman]
|
Kaiden
 Team v1.13 SMP Team Leader
Registered:
Posts: 1832
|
I can definitely see a use for this once a scripting system has been developed.
|
|
Top
|
|
|
|
#181750 - 16 April, 2008 12:46 PM
Re: Laptop files section
[Re: Will Gates]
|
lochkartenman
 Private
Registered:
Posts: 23
Loc: Braunschweig, Germany
|
I spend this evening fiddling around with the XML-code because I thought it might be the easier part compared with image loading & blitting.
Now I realized that most (if not all) XMLs are simple lists with one top item containing a set of identical structured subitems. There is no deeper nesting. Problem is: if you dare to look into my first post you will clearly see that this does not hold true for the XML design of mine. That's a bit of a problem since I think such a "tree" with rather arbitrary sub nodes (PAGES and BOXES) is the most logical way of setting things up for the Laptop files.
The alternative would be introducing a set of say 2 or 3 XMLs - a step I would like to avoid.
By the way: is there a way to determine the number of subitems in a list? This would come in handy to allocate the array.
Please comment
regards
|
|
Top
|
|
|
|
#181755 - 16 April, 2008 01:10 PM
Re: Laptop files section
[Re: lochkartenman]
|
lochkartenman
 Private
Registered:
Posts: 23
Loc: Braunschweig, Germany
|
To circumvent the nesting of element collections I could imagine a set of XML files as follows:
LaptopFiles.xml: stores only the number of entries in subsidiary files to ease the array allocation
<LAPTOPFILES>
<FILE>
<uiIndex>0</uiIndex>
<uiPages>5</uiPages>
<uiBoxes>25</uiBoxes>
<uiTriggers>10</uiTriggers>
</FILE>
<FILE>
<uiIndex>1</uiIndex>
<uiPages>2</uiPages>
<uiBoxes>25</uiBoxes>
<uiTriggers>10</uiTriggers>
</FILE>
</LAPTOPFILES>
LaptopFilesNames.xml: stores localized strings.
<LAPTOPFILESNAME>
<NAME>
<uiFile>0</uiFile>
<ubName>Recon report</ubName>
</NAME>
<NAME>
<uiFile>1</uiFile>
<ubName>Terrorists</ubName>
</NAME>
</LAPTOPFILESNAME>
LaptopFilesContents.xml: holds the localized texts & images and where to put these.
<LAPTOPBOXES>
<BOX>
<uiFile>0</uiFile>
<uiPage>0</uiPage>
<uiLeft>25</uiLeft>
<uiTop>25</uiTop>
<uiHeight>150</uiHeight>
<uiWidth>60</uiWidth>
<uiType>0</uiType>
<ubContents>This is some text</ubContents>
</BOX>
<BOX>
<uiFile>0</uiFile>
<uiPage>0</uiPage>
<uiLeft>100</uiLeft>
<uiTop>50</uiTop>
<uiHeight>150</uiHeight>
<uiWidth>60</uiWidth>
<uiType>1</uiType>
<ubContents>Image1.sti</ubContents>
</BOX>
</LAPTOPBOXES>
The connection between the "master file" LaptopFiles.xml and the other files is the value of uiIndex (in LaptopFiles.xml) and uiFile (in all other files).
Triggers could probably done the same way. Or someone implements LUA-scripting..
This approach would "spread" the data out into more files but makes things easier to program. It might also be easier to tweak the XML-editor to work with these simpler files.
regards
|
|
Top
|
|
|
|
#181760 - 16 April, 2008 02:55 PM
Re: Laptop files section
[Re: lochkartenman]
|
BirdFlu
 Senior Coder VFS/RII SMP Coder
Registered:
Posts: 492
Loc: Lampukistan
|
By the way: is there a way to determine the number of subitems in a list? This would come in handy to allocate the array. Just write the number into the file when you create it.
Why are you dropping the nested xml files in favor of the flat xml files? Since you have to parse the files anyway, you can use any structure you like.
Since you are fiddling with graphics, have you read this thread? http://www.ja-galaxy-forum.com/board/ubbthreads.php?ubb=showflat&Number=163777&page=1#Post163777
|
|
Top
|
|
|
|
#181872 - 17 April, 2008 08:21 AM
Re: Laptop files section
[Re: BirdFlu]
|
lochkartenman
 Private
Registered:
Posts: 23
Loc: Braunschweig, Germany
|
@BirdFlu: Of course the nested xml is much "nicer" than a set of flat files because things that belong together should go into one file. My (personal) problem is that I am not too fluent with the C-style approach of writing code (lots and lots of #defines, flat code files, no classes..) and as such some aspects of the xml-parser code are still not entirely clear to me. Therefore the easier approach would be to simply copy'n'paste for example the XML_AmmoStrings file and rename things according to my purpose - not the most elegant way of doing things and probably also a bit opportunistic but even then it just works. 
Yes, I followed the "Improving Original JA2 graphics – Sprites" thread quite carefully. I even had the hope that the whole idea would lead to overall streamlined graphics handling - which would hopefully make the rendering part of my project a lot easier. Unfortunately the discussion cooled down the last days and progress - code wise - is not to be expected in the near future, as far as I can tell.
While googling around and using the search function of this board quite excessively I stumbled over the "ja2-stracciatella" project. As I understood this port uses the SDL (Simple DirectMedia Layer ) library for drawing stuff. This would probably a huge improvement since at least there is a broad community and code base available. Could the current code be merged with ja2-stracciatella?
regards
|
|
Top
|
|
|
|
#182210 - 19 April, 2008 08:07 AM
Re: Laptop files section
[Re: lochkartenman]
|
lochkartenman
 Private
Registered:
Posts: 23
Loc: Braunschweig, Germany
|
Hi again.
I finally managed to read in a deeply nested xml. The question that rises is: should I adapt to the C-style currently used in the code base, that's one single .cpp-file with static methods, OR should I design some sort of class (probably singleton in this case). Both ways should work equally well and achieve exactly the same but are of different "philosophy".
regards Arne
|
|
Top
|
|
|
|
#182252 - 19 April, 2008 02:49 PM
Re: Laptop files section
[Re: lochkartenman]
|
Tron
 JA2 Stracciatella SMP Panel
Registered:
Posts: 275
Loc: Germany
|
While googling around and using the search function of this board quite excessively I stumbled over the "ja2-stracciatella" project. As I understood this port uses the SDL (Simple DirectMedia Layer) library for drawing stuff. This would probably a huge improvement since at least there is a broad community and code base available. Could the current code be merged with ja2-stracciatella?
While I do not fully understand the part about "broad community and code base", I can tell you that SDL is mainly used for providing a frame buffer in JA2-Stracciatella. JA2 requires more specific blitting functions than SDL provides. I rewrote the JA2 blitters in C.
|
|
Top
|
|
|
|
#182281 - 20 April, 2008 03:15 AM
Re: Laptop files section
[Re: Tron]
|
lochkartenman
 Private
Registered:
Posts: 23
Loc: Braunschweig, Germany
|
@Tron: by "borad community and code base" I meant that for SDL there is a least some sort of documentation, tutorials and people to ask questions. Things that come in handy if you do not have much experience in graphics programming.
One question still remains: what "style" should I follow? Procedural C style OR C++ classes?
regards
|
|
Top
|
|
|
|
#182288 - 20 April, 2008 05:17 AM
Re: Laptop files section
[Re: lochkartenman]
|
Tron
 JA2 Stracciatella SMP Panel
Registered:
Posts: 275
Loc: Germany
|
From the perspective of game mechanics you do not encounter SDL functions (or any other system specific functions, for that matter) in JA2-Stracciatella, so this point is rather moot. On the other hand I have sanitised several in-game interfaces, which get used. Here's a simple example:
original
#define VOBJECT_CREATE_DEFAULT 0x00000020 // Creates and empty object of given width, height and BPP
#define VOBJECT_CREATE_FROMFILE 0x00000040 // Creates a video object from a file ( using HIMAGE )
#define VOBJECT_CREATE_FROMHIMAGE 0x00000080 // Creates a video object from a pre-loaded hImage
typedef struct
{
UINT32 fCreateFlags; // Specifies creation flags like from file or not
union
{
struct
{
SGPFILENAME ImageFile; // Filename of image data to use
};
struct
{
HIMAGE hImage;
};
};
UINT8 ubBitDepth; // BPP, ignored if given from file
} VOBJECT_DESC;
BOOLEAN AddStandardVideoObject( VOBJECT_DESC *VObjectDesc, UINT32 *uiIndex );
BOOLEAN GetVideoObject( HVOBJECT *hVObject, UINT32 uiIndex );
BOOLEAN BltVideoObject( UINT32 uiDestVSurface, HVOBJECT hVSrcObject, UINT16 usRegionIndex, INT32 iDestX, INT32 iDestY, UINT32 fBltFlags, blt_fx *pBltFx );
now
SGPVObject* AddStandardVideoObjectFromHImage(HIMAGE hImage);
SGPVObject* AddStandardVideoObjectFromFile(const char* ImageFile);
BOOLEAN BltVideoObject(SGPVSurface* dst, const SGPVObject* src, UINT16 usRegionIndex, INT32 iDestX, INT32 iDestY);
IMO it's pretty obvious, which of the two is easier to use, even disregarding that there was plain broken stuff (VOBJECT_CREATE_DEFAULT - where's width and height?) and unused parameters (pBltFx). Especially the cumbersome out-parameter-with-boolean-return is gone.
|
|
Top
|
|
|
|
#182351 - 21 April, 2008 03:49 AM
Re: Laptop files section
[Re: Tron]
|
lochkartenman
 Private
Registered:
Posts: 23
Loc: Braunschweig, Germany
|
@Tron: How difficult could it be to merge your changes with the current v1.13 sources?
|
|
Top
|
|
|
|
#182487 - 22 April, 2008 09:57 AM
Re: Laptop files section
[Re: lochkartenman]
|
Tron
 JA2 Stracciatella SMP Panel
Registered:
Posts: 275
Loc: Germany
|
I'd rather do it the other way round: Add modifications to the JA2-Stracciatella source code. It's more than 140.000 lines shorter than the vanilla source code, several internal interfaces have been cleaned up, many bugs have been fixed (see Changelog), many brittle constructs have been replaced by more robust code to facilitate the detection of errors. Further it works not only on x86 Windows, but all 32bit little endian(*) platforms, for which SDL is available. Therefore I deem it more sensible to use JA2-Stracciatella as code base and add extensions there.
(*) removing the 32bit and little endian restrictions is still work in progress
|
|
Top
|
|
|
|
#182531 - 22 April, 2008 01:23 PM
Re: Laptop files section
[Re: Tron]
|
lochkartenman
 Private
Registered:
Posts: 23
Loc: Braunschweig, Germany
|
That sounds promising. I guess the sheer amount of work/time prevented the merge..
I managed to identify the patterns for buttons, displaying text and graphics files so far and although there is some "beauty" in some of these constructs I can hardly get used to it.
What I have achieved so far: - reading nested XML into a structure - display formatted text on the screen - identify the interaction between laptop screens (work in progress)
I have a rather good feeling about the whole thing now. What I am a bit puzzled about is how the "new" files could be triggered. It would be quite a hassle to implement my own set of triggers in the form of XML-files (see first post) since there would be "one" missing trigger all the time.. plus if every single coder implements his/her own trigger system things are likely to become as messy as the "legacy" code.
So I would really appreciate if someone came up with some tips on how to design "LUA-ready" code since I suspect this to be the easiest and most flexible approach even if there is currently no one working on the matter.
regards
|
|
Top
|
|
|
|
Moderator: Marlboro Man, Kaiden, Madd Mugsy, lockie, Tbird94lx, Dieter
|
|