/* ___________________________________________________________________________
** |*************************************************************************|
** |*|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|*|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|*|
** |*| Set TAB to 4 for best readable file layout.  |*|  C++ MaxonDev 4.0  |*|
** |*|______________________________________________|*|____________________|*|
** |*************************************************************************|
** |*|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|*|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|*|
** |*|               |*|  $Id: extradefs.h (19.03.01)                      |*|
** |*| ###### ###### |*|  RhoSigma Source based on NDK 3.1 Includes 40.15  |*|
** |*| ##  ## ##   # |*| _________________________________________________ |*|
** |*| ##  ##  ##    |*|                                                   |*|
** |*| ######   ##   |*|  The public C/C++ definitions for extra.library   |*|
** |*| ##      ##    |*|                                                   |*|
** |*| ##     ##   # |*| ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ |*|
** |*| ##     ###### |*|  Copyright © 1998-2001 RhoSigma, Roland Heyder    |*|
** |*|               |*|  All Rights Reserved.                             |*|
** |*|_______________|*|___________________________________________________|*|
** |*************************************************************************|
** ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*/

#ifndef RHOSIGMA_EXTRADEFS_H
#define RHOSIGMA_EXTRADEFS_H

#ifndef  EXEC_TYPES_H
#include <exec/types.h>
#endif
#ifndef  EXEC_LIBRARIES_H
#include <exec/libraries.h>
#endif
#ifndef  EXEC_ALERTS_H
#include <exec/alerts.h>
#endif

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

/* -------- die BufInfoBlock-Struktur von »BufInfo()« -------------------- */

struct BIBStruct {
	APTR	bib_OwnerID;	 /* Task, der diesen Puffer öffnete				   */
	ULONG	bib_MaxSize;	 /* momentane Größe des Datenbereichs in Byte	   */
	ULONG	bib_FreeSize;	 /* davon momentan noch unbenutzt				   */
	APTR	bib_DataStart;	 /* Adresse des gegenwärtigen Datenbereichs		   */
	ULONG	bib_CurPos;		 /* aktuelle Cursorposition (Zählbeginn=0 !!)	   */
	ULONG	bib_EndPos;		 /* aktuelle Anfügeposition						   */
	APTR	bib_LastFind;	 /* Zeiger auf zuletzt gesuchte Daten od. 0-PTR	   */
	ULONG	bib_FindSize;	 /* die Länge obiger Such-Daten oder null		   */
	ULONG	bib_KeyNum;		 /* der Schlüssel der o.g. Such-Daten oder -1	   */
/* ---------------------------- neu ab v2.062								   */
	ULONG	bib_DataMemType; /* Speicherflags des Datenbereichs CHIP/FAST etc. */
};

/* -------- Modes für »SeekBuf()« ---------------------------------------- */

#define SKM_Current	 0	/* Positionierung relativ zur gegenwärtigen CurPos */
#define SKM_Start	 1	/* Positionierung relativ zum Pufferanfang         */
#define SKM_End		 2	/* Positionierung relativ zum Pufferende           */
#define SKM_Bookmark 3	/* »Position« = Nummer der gewünschten Bookmark    */

/* -------- die Parameter-Struktur für »UnpackByteRun1()« ---------------- */

struct UnpackParam {
	APTR	up_InBuf;	/* Zeiger auf die gepackten Daten            */
	LONG	up_InLen;	/* die Größe des gepackten Bereichs in Byte  */
	LONG	up_Private;	/* beim ersten Aufruf unbedingt auf 0 setzen */
};

/* -------- Styles, Masken u. Flags für »SpecTextPrefs()« ---------------- */

/** Styles **/
#define STS_Plain	  0	/* normaler Text        \                              */
#define STS_Underline 1	/* unterstrichener Text |  können durch Addition oder  */
#define STS_Bold	  2	/* fettgedruckter Text	|  log. ODER kombiniert werden */
#define STS_Italic	  4	/* kursiver Text        /                              */

/** Masken **/
#define STM_Normal	0x00	/* keine Umrandung, d.h. normale Textausgabe  */
#define STM_Outline	0xff	/* volle Umrandung                            */
#define STM_Shadow	0x1c	/* Schatten unten/rechts sichtbar             */
#define STM_Ghost	0xc1	/* dies wirkt am besten, wenn Sie als »MPen«  */
							/* die selbe Farbe verwenden, wie der Hinter- */
							/* grund hat                                  */

/** Flags **/
#define STB_FJAM2 0   /* Normalerweise benutzt »SpecText()« den DrawMode JAM1, */
#define STF_FJAM2 1   /* mit diesem Flag wird jedoch JAM2 erzwungen.           */

#define STB_AP2MP 1   /* immer der gerade eingestellte »APen« des RastPorts */
#define STF_AP2MP 2   /* soll als »MainPen« (MPen) verwendet werden         */

#define STB_BP2TL 2   /* immer der gerade eingestellte »BPen« des RastPorts */
#define STF_BP2TL 4   /* soll als »TopLeftPen« (TLPen) verwendet werden     */

#define STB_OP2BR 3   /* immer der gerade eingestellte »OPen« des RastPorts */
#define STF_OP2BR 8   /* soll als »BottomRightPen« (BRPen) verwendet werden */

#define STB_PSWAP 4   /* vertauscht »TLPen« u. »BRPen«, d.h. »TLPen« wird für */
#define STF_PSWAP 16  /* un./re. und »BRPen« für ob./li. verwendet            */

/*
** Die folgenden Flags haben keinen Einfluß auf die Arbeitsweise der Funk-
** tion »SpecText()«. Sie dienen nur dazu, »SpecTextPrefs()« mitzuteilen,
** welche Parameter neu eingestellt werden sollen. Damit soll überflüssiges
** Register-retten verhindert werden, da Sie nicht jedem Register, welches
** von »SpecTextPrefs()« erwartet wird, zwangsläufig einen sinnvollen Wert
** zuweisen müssen. Wenn Sie z.B. mit D0-D5 irgendwelche Berechnungen machen,
** oder sie als Schleifenzähler benutzen, und wollen dann den »MPen« ver-
** ändern, dann brauchen Sie nur D0 mit diesem zu initialisieren und D5 das
** entsprechende Flag (STF_CMPEN) zuweisen, während Sie sich um D1-D4 nicht
** sorgen müssen, da diese bei jenem Aufruf vollkommen unberührt und unver-
** ändert bleiben, d.h. sie müssen weder gerettet noch initialisiert werden.
**
** ACHTUNG: Wenn keines der folgenden Flags angegeben wird, dann heißt das
** ¯¯¯¯¯¯¯¯ nicht, daß KEIN Wert geändert werden soll, sondern daß ALLE Werte
**          zu ändern sind !! (In diesem Falle müssen dann logischer Weise
**							  auch alle Register initialisiert werden.)
*/

#define STB_CMPEN 10	/* Nur den »MPen« auf den angegebenen Wert ändern. */
#define STF_CMPEN 1024

#define STB_TLPEN 11	/* Nur den »TLPen« auf den angegebenen Wert ändern. */
#define STF_TLPEN 2048

#define STB_BRPEN 12	/* Nur den »BRPen« auf den angegebenen Wert ändern. */
#define STF_BRPEN 4096

#define STB_STYLE 13	/* Nur den SoftStyle auf den angegebenen Wert ändern. */
#define STF_STYLE 8162

#define STB_CMASK 14	/* Nur die Maske auf den angegebenen Wert ändern. */
#define STF_CMASK 16384

#define STB_FLAGS 15	/* Nur die Flags auf den angegebenen Wert ändern. */
#define STF_FLAGS 32768

/*
** Es können auch alle Kombinationen der obigen Flags angegeben werden. Die
** Funktion »SpecTextPrefs()« wird dann alles das, was Sie wünschen, ändern.
*/

/* -------- Fehlernummern von »LastError()« ------------------------------ */

#define NoError 0		  /* bis jetzt ist kein Fehler aufgetreten */

/** DBS-Funktionen **/
#define BufInvalid    10  /* die angegebene Adresse war kein BufHandle */
#define NotOwner      11  /* nur der Task, der den Puffer öffnete, darf ihn auch wieder schließen */
#define NoBufMemory   12  /* nicht mehr genügend Speicher frei (PUBLIC) */
#define NoDOSProcess  13  /* die aufrufende Anwendung war kein DOS-Prozess */
#define IoErrRequired 14  /* ein DOS-Error ist aufgetreten (»IoErr()« der dos.library aufrufen) */
#define SeekBadMode   15  /* der angegebene »SeekMode« ist unbekannt */
#define SeekOffsetErr 16  /* gewünschte »Position« unter-/überschreitet den Pufferanfang bzw. das Pufferende */
#define NoFindMem     17  /* kein Speicher für Zwischenspeicherung der zu suchenden Daten (PUBLIC) */
#define FindTooLong   18  /* von CurPos bis EndPos bzw. Pufferanfang sind nur noch weniger Daten, als gesucht werden sollen */
#define NoFindAvail   19  /* für »FindNext()/FindPrev()« ist mindestens ein »FindData()« erforderlich (gilt für jeden möglichen Schlüssel) */
#define InvalidKey    20  /* ein angegebener Schlüssel liegt außerhalb des gültigen Bereichs (bei Find-Funktionen max. 8 (0-7) / bei Bookmarks max. 16 (0-15)) */
#define MarkNotSet    21  /* die angegebene Bookmark ist noch nicht gesetzt */
#define MarkCleared   22  /* die Daten an der angegebenen Bookmark wurden durch »Clear()« gelöscht */

/** StringToLong() **/
#define ResultValid 30  /* alles in Ordnung (das Ergebnis ist gültig)        */
#define InvalidChar 31  /* im String wurde ein illegales Zeichen gefunden    */
#define Overflow    32  /* repräsentierte Zahl wäre größer als 32 Bit (LONG) */

/** FillMem() **/
#define OddAddress 35  /* ungerade Startadresse bei WORD- oder LONG-Modus */
#define NotFilled  36  /* keine Füllung wegen Abrundung (Bereich zu klein, um wenigstens 1 Wert aufzunehmen) */

/** ShowMsg() **/
#define BadHeight    40  /* angegebene Höhe war größer als 200 Videozeilen      */
#define NoStructMem  41  /* kein Speicher für benötigte Gfx-Strukturen (ANY)    */
#define NoChipMemory 42  /* nicht genügend Speicher für die BitPlanes (CHIP)    */
#define SpecTextErr  43  /* die Funktion »SpecText()« hat einen Fehler gemeldet */

/* -------- die Basis-Struktur der extra.library ------------------------- */

struct XtraBase {
	struct Library xb_LibStuff;		/* standardmäßige Library-Struktur      */
	STRPTR		   xb_Copyright;	/* ein einzeiliger Copyrightvermerk(+0) */
	BYTE		   xb_Private[54];	/* privater Datenbereich der Library    */
};

/* -------- von der extra.library erzeugte Alert's ----------------------- */

#define EL_AlertD AT_DeadEnd|AN_Unknown
#define EL_AlertR AT_Recovery|AN_Unknown
/* Typen-Kennungen der extra.library ($B5000000=DeadEnd/$35000000=Recovery) */

#define EL_NoDfo EL_AlertD|AG_OpenLib|AO_DiskfontLib
/* konnte diskfont.library V33+ (bzw. V36+ für CGX-Version) nicht öffnen ($B503800B) */

#define EL_NoDOS EL_AlertD|AG_OpenLib|AO_DOSLib
/* konnte dos.library V33+ (bzw. V36+ für CGX-Version) nicht öffnen ($B5038007) */

#define EL_NoGfx EL_AlertD|AG_OpenLib|AO_GraphicsLib
/* konnte graphics.library V33+ (bzw. V36+ für CGX-Version) nicht öffnen ($B5038002) */

#define EL_NoInt EL_AlertD|AG_OpenLib|AO_Intuition
/* konnte intuition.library V33+ (bzw. V36+ für CGX-Version) nicht öffnen ($B5038004) */

#define EL_Trespassed EL_AlertD|AG_IOError|AO_Unknown
/* Task hat Library benutzt, ohne sie vorher zu öffnen ($B5068035) */

/* -------- mit extra.library verwendbare MACROS & Funktionen ------------ */

#define SMTPOS_C -1		/* Text zentrieren   */
#define SMTPOS_L -2		/* Text linksbündig  */
#define SMTPOS_R -3		/* Text rechtsbündig */

/*** extra.library / SMCOLOR() ***
*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
* Dieses Macro erstellt einen Farbeintrag für die optional anzugebende Farb-
* tabelle der Funktion »ShowMsg()«.
*-----------------------------------------------------------------------------
* Definiert:	extradefs.h  (Copyright © 1998-2001 RhoSigma, Roland Heyder)
*
* Schablone:	Name/A, Pen/A/N, Red/A/N, Green/A/N, Blue/A/N, EndFlag/N/S
*
* Parameter:	Name	--> ein deklariertes Element des Typs STRPTR
*
*				Pen		--> Nr. des zu ändernden Farbstiftes (3-15)
*								(0-2 sind reserviert u. werden ignoriert)
*
*				Red		--> Rot-Anteil der neuen Farbe (0-15)
*				Green	--> Grün-Anteil der neuen Farbe (0-15)
*				Blue	--> Blau-Anteil der neuen Farbe (0-15)
*
*				EndFlag	--> - TRUE , dann endet hier die Farbtabelle
*							- FALSE, dann MUSS noch ein weiterer Farbeintrag
*									 (Macro-Aufruf) folgen.
*
* Bemerkung:	Dieses Macro kann NUR innerhalb von Funktion verwendet werden,
*				da es ausführbaren Code generiert, d.h. es ist nicht möglich
*				alle benötigten Farbeinträge gleich am Programmanfang auf
*				Dateiebene global zu deklarieren.
*
*				Leider kann man sich bei C/C++ auch nicht darauf verlassen, daß
*				direkt nacheinander deklarierte konstante Zeichenketten im fer-
*				tigen Programmcode dann auch noch direkt hintereinander im
*				Speicher liegen. Aus diesem Grunde ist es in C/C++ erforder-
*				lich, die einzelnen Strings vor der Benutzung noch mittels der
*				ebenfalls hier definierten Funktion »SMCJOIN()« zusammenzufügen.
*
*				Ein Beispiel für die Benutzung dieses Macros finden Sie in
*				der Datei »demo/ShowMsgDemo.CPP«.
*
* Siehe auch:	»SMCJOIN()«, »SMCFREE()«
*«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/

#define SMCOLOR(Name, Pen, Red, Green, Blue, EndFlag)	\
			Name	= "    "#Name;						\
			Name[0] = (Pen);							\
			Name[1] = (((Red*256)+(Green*16)+Blue)>>8);	\
			Name[2] = (((Red*256)+(Green*16)+Blue)&255);\
			Name[3] = (!EndFlag)

/*** extra.library / SMCJOIN() ***
*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
* Diese Funktion dient zum Zusammenfügen der, zuvor mittels »SMCOLOR()« initia-
* lisierten, Farbeinträge zur fertigen Farbtabelle. Idealer Weise sollte man
* diese Funktion unmittelbar vor dem »ShowMsg()«-Aufruf, in dem man die Farb-
* tabelle verwenden will, aufrufen.
*-----------------------------------------------------------------------------
* Synopsis:		Param = SMCJOIN (Count, ...)
*
* Eingaben:		Count	-->	(UWORD)  Anzahl der zusammenzufügenden Farbeinträge
*
*				...		--> (STRPTR) nacheinander in der richtigen Reihenfolge
*									 die Zeiger der einzelnen Farbeinträge
*
* Ergebnis:		Param	--> (STRPTR) Zeiger auf die komplett generierte Farb-
*									 tabelle, die direkt an »ShowMsg()«
*									 übergeben werden kann, bzw. NULL, wenn
*									 nicht mehr genügend Speicher frei ist.
*
* Bemerkung:	Die Farbtabelle wird erstellt, indem alle Farbeinträge nach-
*				einander in einen neuen zusammenhängenden Speicherblock
*				kopiert werden. Dieser Speicherblock sollte, wenn die Farb-
*				tabelle nicht mehr benötigt wird, spätestens jedoch vor
*				Programmende, wieder freigegeben werden. Bitte benutzen Sie
*				dazu das ebenfalls hier definierte Macro »SMCFREE()«.
*
*				Ein Beispiel für die Benutzung dieser Funktion finden Sie in
*				der Datei »demo/ShowMsgDemo.CPP«.
*
*   ACHTUNG:	Diese Funktion muß auch dann aufgerufen werden, wenn nur ein
*	¯¯¯¯¯¯¯¯	einziger Farbeintrag benutzt wird, da das Macro »SMCOLOR()«
*				keine vollständige Initialisierung des gleichen vornimmt. Das
*				wird alles erst durch »SMCJOIN()« erledigt !!
*
* Siehe auch:	»SMCOLOR()«, »SMCFREE()«
*«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/

STRPTR SMCJOIN(UWORD Count, ...)
{
	STRPTR  ColPtr, MemPtr;
	UWORD   MemPos=NULL, ArgCnt, LenCnt;
	va_list ArgPtr;

	MemPtr = (STRPTR) malloc(Count*4);
	if (!MemPtr)      return NULL;

	va_start(ArgPtr, Count);
	for (ArgCnt=NULL; ArgCnt<Count; ArgCnt++)
	{
		ColPtr = va_arg(ArgPtr, STRPTR);

		for (LenCnt=NULL; LenCnt<4; LenCnt++)
		{
			MemPtr[MemPos+LenCnt] = ColPtr[LenCnt];
		}
		MemPos += 4;
	}
	return MemPtr;
}

/*** extra.library / SMCFREE() ***
*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
* Dieses Macro dient zur Freigabe des Speichers einer mittels »SMCJOIN()« gene-
* rierten Farbtabelle. Die Farbeinträge selbst, welche mittels des Macros
* »SMCOLOR()« deklariert wurden, bleiben jedoch erhalten, d.h. Sie können sich
* die Farbtabelle jeder Zeit mit »SMCJOIN()« neu generieren lassen.
*-----------------------------------------------------------------------------
* Definiert:	extradefs.h  (Copyright © 1998-2001 RhoSigma, Roland Heyder)
*
* Schablone:	Address/A
*
* Parameter:	Address	-->	der STRPTR, den Sie von »SMCJOIN()« als Ergebnis
*							erhalten haben
*
* Bemerkung:	Ein Beispiel für die Benutzung dieses Macros finden Sie in
*				der Datei »demo/ShowMsgDemo.CPP«.
*
* Siehe auch:	»SMCOLOR()«, »SMCJOIN()«
*«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/

#define SMCFREE(Address) free((APTR) Address)

/*** extra.library / SMTEXTP() ***
*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
* Dieses Macro erstellt einen Teilstring des Parameterstrings der ExtraLib-
* Routine »ShowMsg()«. Wahlweise kann der Text automatisch zentriert, oder
* links- bzw. rechtsbündig ausgerichtet werden.
*-----------------------------------------------------------------------------
* Definiert:	extradefs.h  (Copyright © 1998-2001 RhoSigma, Roland Heyder)
*
* Schablone:	Name/A, xPos/A/N, yPos/A/N, MPen/A/N, TLPen/A/N, BRPen/A/N,
*				Style/A/N, Mask/A/N, String/A, EndFlag/N/S
*
* Parameter:	Name	--> ein deklariertes Element des Typs STRPTR
*
*				xPos	--> x-Position des Textes,
*								oder einer der oben definierten SMTPOS-Werte
*
*				yPos	--> y-Position des Textes,
*								Ausrichtung erfolgt an der Oberkante des Fonts
*
*				MPen	--> gewünschter MPen		\
*				TLPen	--> gewünschter TLPen		|
*				BRPen	--> gewünschter BRPen		| (s.a. »SpecTextPrefs()«
*				Style	--> gewünschter SoftStyle	|
*				Mask	--> gewünschte  Rand-Maske	/
*
*				String	--> der Text selbst als Konstante (z.B. "Test")
*
*				EndFlag	--> - TRUE , dann endet hier der Parameterstring
*							- FALSE, dann MUSS noch ein weiterer Teilstring
*									 (Macro-Aufruf) folgen.
*
* Bemerkung:	Dieses Macro kann NUR innerhalb von Funktion verwendet werden,
*				da es ausführbaren Code generiert, d.h. es ist nicht möglich
*				alle benötigten Parameterstrings gleich am Programmanfang auf
*				Dateiebene global zu deklarieren.
*
*				Leider kann man sich bei C/C++ auch nicht darauf verlassen, daß
*				direkt nacheinander deklarierte konstante Zeichenketten im fer-
*				tigen Programmcode dann auch noch direkt hintereinander im
*				Speicher liegen. Aus diesem Grunde ist es in C/C++ erforder-
*				lich, die einzelnen Strings vor der Benutzung noch mittels der
*				ebenfalls hier definierten Funktion »SMTJOIN()« zusammenzufügen.
*
*				Dieses Macro sollten Sie außerdem nur dann verwenden, wenn Sie
*				für diesen Teilstring neue Einstellungen für Farben etc. machen
*				wollen. Wenn dieser Teilstring jedoch mit den gleichen Ein-
*				stellungen ausgegeben werden soll, wie der vorhergehende bzw.
*				Sie die Default-Einstellungen verwenden wollen, dann müssen
*				Sie stattdessen das Macro »SMTEXT()« verwenden.
*
*				Ein Beispiel für die Benutzung dieses Macros finden Sie in
*				der Datei »demo/ShowMsgDemo.CPP«.
*
* Siehe auch:	»SMTEXT()«, »SMTJOIN()«, »SMTFREE()«
*«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/

#define SMTEXTP(Name, xPos, yPos, MPen, TLPen, BRPen, Style, Mask, String, EndFlag)	\
						Name	= "         "#String"  ";	\
						Name[0] = ((xPos)>>8);				\
						Name[1] = ((xPos)&255);				\
						Name[2] = (yPos);					\
						Name[3]	= (TRUE);					\
						Name[4]	= (MPen);					\
						Name[5]	= (TLPen);					\
						Name[6]	= (BRPen);					\
						Name[7]	= (Style);					\
						Name[8]	= (Mask);					\
		Name[sizeof(#String)+8] = 0;						\
		Name[sizeof(#String)+9] = (!EndFlag)

/*** extra.library / SMTEXT() ***
*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
* Dieses Macro erstellt einen Teilstring des Parameterstrings der ExtraLib-
* Routine »ShowMsg()«. Wahlweise kann der Text automatisch zentriert, oder
* links- bzw. rechtsbündig ausgerichtet werden.
*-----------------------------------------------------------------------------
* Definiert:	extradefs.h  (Copyright © 1998-2001 RhoSigma, Roland Heyder)
*
* Schablone:	Name/A, xPos/A/N, yPos/A/N, String/A, EndFlag/N/S
*
* Parameter:	Name	--> ein deklariertes Element des Typs STRPTR
*
*				xPos	--> x-Position des Textes,
*								oder einer der oben definierten SMTPOS-Werte
*
*				yPos	--> y-Position des Textes,
*								Ausrichtung erfolgt an der Oberkante des Fonts
*
*				String	--> der Text selbst als Konstante (z.B. "Test")
*
*				EndFlag	--> - TRUE , dann endet hier der Parameterstring
*							- FALSE, dann MUSS noch ein weiterer Teilstring
*									 (Macro-Aufruf) folgen.
*
* Bemerkung:	Dieses Macro kann NUR innerhalb von Funktion verwendet werden,
*				da es ausführbaren Code generiert, d.h. es ist nicht möglich
*				alle benötigten Parameterstrings gleich am Programmanfang auf
*				Dateiebene global zu deklarieren.
*
*				Leider kann man sich bei C/C++ auch nicht darauf verlassen, daß
*				direkt nacheinander deklarierte konstante Zeichenketten im fer-
*				tigen Programmcode dann auch noch direkt hintereinander im
*				Speicher liegen. Aus diesem Grunde ist es in C/C++ erforder-
*				lich, die einzelnen Strings vor der Benutzung noch mittels der
*				ebenfalls hier definierten Funktion »SMTJOIN()« zusammenzufügen.
*
*				Dieses Macro sollten Sie außerdem nur dann verwenden, wenn Sie
*				für diesen Teilstring die gleichen Einstellungen wie für den
*				vorhergehenden Teilstring verwenden wollen. Wenn dieser Teil-
*				string jedoch neue Einstellungen für Farben etc. erhalten
*				soll, dann müssen Sie stattdessen das Macro »SMTEXTP()« ver-
*				wenden.
*
*				Ein Beispiel für die Benutzung dieses Macros finden Sie in
*				der Datei »demo/ShowMsgDemo.CPP«.
*
* Siehe auch:	»SMTEXTP()«, »SMTJOIN()«, »SMTFREE()«
*«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/

#define SMTEXT(Name, xPos, yPos, String, EndFlag)	\
						Name	= "    "#String"  ";\
						Name[0] = ((xPos)>>8);		\
						Name[1] = ((xPos)&255);		\
						Name[2] = (yPos);			\
						Name[3]	= (FALSE);			\
		Name[sizeof(#String)+3] = 0;				\
		Name[sizeof(#String)+4] = (!EndFlag)

/*** extra.library / SMTJOIN() ***
*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
* Diese Funktion dient zum Zusammenfügen der, zuvor mittels »SMTEXT()« und/oder
* »SMTEXTP()« initialisierten, Teilstrings zum fertigen Parameterstring. Idealer
* Weise sollte man diese Funktion unmittelbar vor dem »ShowMsg()«-Aufruf, in dem
* man den Parameterstring verwenden will, aufrufen.
*-----------------------------------------------------------------------------
* Synopsis:		Param = SMTJOIN (Count, ...)
*
* Eingaben:		Count	-->	(UWORD)  Anzahl der zusammenzufügenden Teilstrings
*
*				...		--> (STRPTR) nacheinander in der richtigen Reihenfolge
*									 die Zeiger der einzelnen Teilstrings
*
* Ergebnis:		Param	--> (STRPTR) Zeiger auf den komplett generierten Para-
*									 meterstring, der direkt an »ShowMsg()«
*									 übergeben werden kann, bzw. NULL, wenn
*									 nicht mehr genügend Speicher frei ist.
*
* Bemerkung:	Der Parameterstring wird erstellt, indem alle Teilstrings
*				nacheinander in einen neuen zusammenhängenden Speicherblock
*				kopiert werden. Dieser Speicherblock sollte, wenn der Para-
*				meterstring nicht mehr benötigt wird, spätestens jedoch vor
*				Programmende, wieder freigegeben werden. Bitte benutzen Sie
*				dazu das ebenfalls hier definierte Macro »SMTFREE()«.
*
*				Ein Beispiel für die Benutzung dieser Funktion finden Sie in
*				der Datei »demo/ShowMsgDemo.CPP«.
*
*   ACHTUNG:	Diese Funktion muß auch dann aufgerufen werden, wenn nur ein
*	¯¯¯¯¯¯¯¯	einziger Teilstring benutzt wird, da das Macro »SMTEXT()« bzw.
*				»SMTEXTP()« keine vollständige Initialisierung des gleichen
*				vornimmt. Das wird alles erst durch »SMTJOIN()« erledigt !!
*
* Siehe auch:	»SMTEXT()«, »SMTEXTP()«, »SMTFREE()«
*«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/

STRPTR SMTJOIN(UWORD Count, ...)
{
	STRPTR  TxtPtr, MemPtr;
	UWORD   TxtLen, MemNeed=NULL, MemPos=NULL, ArgCnt, LenCnt;
	va_list ArgPtr;

	va_start(ArgPtr, Count);
	for (ArgCnt=NULL; ArgCnt<Count; ArgCnt++)
	{
		TxtPtr = va_arg(ArgPtr, STRPTR);
		if (!TxtPtr[3]) MemNeed += strlen(TxtPtr+4)+6;
		else            MemNeed += strlen(TxtPtr+9)+11;
	}

	MemPtr = (STRPTR) malloc(MemNeed);
	if (!MemPtr)      return NULL;

	va_start(ArgPtr, Count);
	for (ArgCnt=NULL; ArgCnt<Count; ArgCnt++)
	{
		TxtPtr = va_arg(ArgPtr, STRPTR);
		if (!TxtPtr[3]) TxtLen = strlen(TxtPtr+4);
		else            TxtLen = strlen(TxtPtr+9);

		if ((UBYTE) TxtPtr[0] == 0xff)
		{
			if ((UBYTE) TxtPtr[1] == 0xff) LenCnt = (640-(TxtLen*8))/2;
			if ((UBYTE) TxtPtr[1] == 0xfe) LenCnt = 12;
			if ((UBYTE) TxtPtr[1] == 0xfd) LenCnt = (640-(TxtLen*8))-12;
			TxtPtr[0] = (LenCnt)>>8;
			TxtPtr[1] = (LenCnt)&255;
		}
		if (!TxtPtr[3]) TxtLen += 4+2;
		else            TxtLen += 9+2;

		for (LenCnt=NULL; LenCnt<TxtLen; LenCnt++)
		{
			MemPtr[MemPos+LenCnt] = TxtPtr[LenCnt];
		}
		MemPos += TxtLen;
	}
	return MemPtr;
}

/*** extra.library / SMTFREE() ***
*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
* Dieses Macro dient zur Freigabe des Speichers eines mittels »SMTJOIN()« gene-
* rierten Parameterstrings. Die Teilstrings selbst, welche mittels des Macros
* »SMTEXT()« bzw. »SMTEXTP()« deklariert wurden, bleiben jedoch erhalten, d.h.
* Sie können sich den Parameterstring jeder Zeit mit »SMTJOIN()« neu generieren
* lassen.
*-----------------------------------------------------------------------------
* Definiert:	extradefs.h  (Copyright © 1998-2001 RhoSigma, Roland Heyder)
*
* Schablone:	Address/A
*
* Parameter:	Address	-->	der STRPTR, den Sie von »SMTJOIN()« als Ergebnis
*							erhalten haben
*
* Bemerkung:	Ein Beispiel für die Benutzung dieses Macros finden Sie in
*				der Datei »demo/ShowMsgDemo.CPP«.
*
* Siehe auch:	»SMTEXT()«, »SMTEXTP()«, »SMTJOIN()«
*«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/

#define SMTFREE(Address) free((APTR) Address)

#endif	/* RHOSIGMA_EXTRADEFS_H */

