home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ST-Computer Leser 1998 October
/
STC_CD_10_1998.iso
/
BASE
/
BGH
/
C___1
/
BGH.CXX
< prev
next >
Wrap
C/C++ Source or Header
|
1998-09-26
|
10KB
|
386 lines
#include <aes.h>
#include <stdlib.h>
#include <stdio.h>
#include <osbind.h>
#include <string.h>
#include <portab.h>
#include "bgh.h"
#define BGH_MAGIC 0x23424748
typedef struct
{
LONG Magic; /* #BGH */
LONG resvd[3];
} BGH_Head;
typedef struct bgh_gruppe
{
WORD Index;
struct bgh_gruppe* Next;
WORD First;
BYTE StringTyp;
} BGH_Gruppe;
typedef struct bgh_object
{
WORD Index;
WORD Next;
BYTE StringTyp;
BYTE Link;
} BGH_Object;
static WORD WPEEK(void* Word)
{
register UBYTE* wordp = (UBYTE*)Word;
return (wordp[0] << 8 | wordp[1]);
}
static inline void WPOKE(void* Word, WORD Wert)
{
register UBYTE* wordp = (UBYTE*)Word;
wordp[0] = Wert >> 8;
wordp[1] = Wert;
}
static LONG LPEEK(void* Long)
{
register UBYTE* longp = (UBYTE*)Long;
return (longp[0] << 24 | longp[1] << 16 | longp[2] << 8 | longp[3]);
}
static inline void LPOKE(void* Long, LONG Wert)
{
register UBYTE* longp = (UBYTE*)Long;
longp[0] = Wert >> 24;
longp[1] = Wert >> 16;
longp[2] = Wert >> 8;
longp[3] = Wert;
}
static void* MyMxalloc(LONG Ammount, WORD Mode)
{
void* result = 0;
void *svStack; /* Supervisorstack */
LONG sRAM, sRAMg; /* ST-RAM */
LONG aRAM, aRAMg; /* Alternate RAM */
/*
// Beispieltabelle moeglicher Werte:
// | newfashion | oldfashion
// sRAM aRAM | sRAMg aRAMg | sRAMg aRAMg
// 1 0 | 1 0 | 1 1
// 0 2 | 0 2 | 2 2
// 1 2 | 1 2 | 3 3
*/
svStack = (void*)Super(0); /* unterbinde Taskwechsel */
sRAM = (LONG) Mxalloc( -1, 0);
sRAMg = (LONG) Mxalloc( -1, 0x40); /* im Fehlerfall Mxalloc( -1, 3) */
aRAM = (LONG) Mxalloc( -1, 1);
aRAMg = (LONG) Mxalloc( -1, 0x41); /* im Fehlerfall Mxalloc( -1, 3) */
Super( svStack); /* erlaube Taskwechsel */
if(sRAM == -32)
result = (void*)Malloc(Ammount); /* Mxalloc() ist nicht implementiert */
else
{
if (((sRAM + aRAM) == sRAMg) && ((sRAM + aRAM) == aRAMg))
result = (void*)Mxalloc(Ammount, Mode & 3); /* oldfashion Mxalloc() */
else
result = (void*)Mxalloc(Ammount, Mode);
}
return result;
}
BGH::BGH(const char* Name)
{
char Char, * Read, * LastText=0, * egal;
WORD i, Section, LastTextTyp=0;
LONG FileHandle, FileLen;
BGH_Head* Head = 0;
BGH_Gruppe* LastGruppen[4]; /* für Gruppen-Verkettung */
BGH_Gruppe* LastGruppe = 0; /* für 1.Objekt */
BGH_Object* LastObject = 0; /* für Objekt-Verkettung */
BGH_Gruppe** Sectionen;
BGH_Gruppe* NewGruppe;
BGH_Object* NewObject;
FileHandle = Fopen(Name, 0); /* Datei öffnen */
if(FileHandle > 0)
{
FileLen = Fseek(0, FileHandle, 2); /* Dateilänge ermitteln */
Fseek(0, FileHandle, 0);
if(FileLen > sizeof(BGH_Head)) /* Filelänge > Headerlänge */
{
Read = (char*) MyMxalloc(FileLen+1, 0x43); /* Speicher anforderm */
if(Read && FileLen == Fread(FileHandle, FileLen, Read)) /* Datei laden */
{
Read[FileLen] = 0; /* Eine NULL anhängen */
Head = (BGH_Head*) Read;
if(Head->Magic == BGH_MAGIC) /* ist es eine BGH-Datei ? */
{
Sectionen = (BGH_Gruppe**)Head;
for(i=0; i<4; i++)
{
Sectionen[i] = /* Verkettungen zurücksetzen */
LastGruppen[i] = 0;
}
Read += sizeof(BGH_Head); /* Header überspringen */
while(*Read) /* solange NULL nicht erreicht */
{
while(*Read && *Read != 0xa && *Read != 0xd)
Read++; /* CR oder LF suchen */
while(*Read == 0xa || *Read == 0xd)
*Read++ = 0; /* CR und LF ausNULLen */
if(*Read == '#') /* ist 1.Zeichen nach CR/LF = '#' */
{
i = 0;
switch(*++Read) /* dann teste 2.Zeichen */
{
case 'M': /* vergleichs SectionsID */
egal = "More "; /* vergleiche mit "More " */
i = 5;
Section = 0;
break;
case 'D':
egal = "Dial "; /* vergleiche mit "Dial " */
i = 5;
Section = 1;
break;
case 'A':
egal = "Alert "; /* vergleiche mit "Alert " */
i = 6;
Section = 2;
break;
case 'U':
egal = "User "; /* vergleiche mit "User " */
i = 5;
Section = 3;
break;
}
if(i && !strncmp(Read, egal, i)) /* SectionsId gefundeen */
{
LastGruppe = 0; /* wenn Fehler keine Objekte */
Read += i; /* SectionsId überspringen */
egal = Read; /* Position 1. Ziffer merken */
while(*Read >= '0' && *Read <= '9')
Read++; /* Ende der Zahl suchen */
if(*Read == 0xa || *Read == ' ' || *Read == 0xd || !*Read)
{
if(*Read) *Read++ = 0; /* Zahl mit NULL abschlie₧en */
if(Read - egal >= 3) /* mindestens 3 Ziffern */
{
NewGruppe = (BGH_Gruppe*) ((ULONG)Read - sizeof(BGH_Gruppe));
/* GruppenStructur initialisieren */
WPOKE(&NewGruppe->Index, atoi(egal));
LPOKE(&NewGruppe->Next, 0);
WPOKE(&NewGruppe->First, 0);
if(*Read == '>' && Read[1] >= '0' && Read[1] <= '9')
{
LastTextTyp = 1;
WPOKE(LastText, atoi(&Read[1]));
WPOKE(Read, atoi(&Read[1]));
NewGruppe->StringTyp = 2;
Read += 2;
}
else
{
LastTextTyp = 0;
LastText = Read;
NewGruppe->StringTyp = 0;
}
/* GruppenStructur verketten */
if(LastGruppen[Section])
LPOKE(&LastGruppen[Section]->Next, (LONG)NewGruppe);
else
Sectionen[Section] = NewGruppe;
LastGruppen[Section] =
LastGruppe = NewGruppe;
LastObject = 0;
}
}
}
else
{
if(LastGruppe) /* war schon eine Gruppe ? */
{
egal = ++Read; /* ObjektStructur initialisieren */
while(*Read >= '0' && *Read <= '9')
Read++;
if(*Read == ' ' && Read - egal >= 3)
{
*Read++ = 0;
NewObject = (BGH_Object*) ((ULONG)Read - sizeof(BGH_Object));
WPOKE(&NewObject->Index, atoi(egal));
WPOKE(&NewObject->Next, 0);
NewObject->StringTyp = 0;
switch(*Read)
{
case '^':
if(Read[1] == 0xa || Read[1] == 0xd || !Read[1])
{
if(LastTextTyp)
{
WPOKE(&NewObject->Link, WPEEK(LastText));
NewObject->StringTyp = 2;
}
else
{
WPOKE(&NewObject->Link, (ULONG)LastText - (ULONG)NewObject);
NewObject->StringTyp = 1;
}
Read++;
}
break;
case '>':
if(Read[1] >= '0' && Read[1] <= '9')
{
LastTextTyp = 1;
WPOKE(LastText, atoi(&Read[1]));
WPOKE(&NewObject->Link, atoi(&Read[1]));
NewObject->StringTyp = 2;
Read++;
}
break;
default:
break;
}
if(!NewObject->StringTyp)
{
LastTextTyp = 0;
LastText = Read;
}
/* ObjektStructur verketten */
if(LastObject)
WPOKE(&LastObject->Next, (ULONG)NewObject - (ULONG)LastObject);
else
WPOKE(&LastGruppe->First, (ULONG)NewObject - (ULONG)LastGruppe);
LastObject = NewObject;
}
}
}
}
}
}
}
}
Fclose(FileHandle);
}
MemoryBase = (void*) Head;
}
BGH::~BGH()
{
if(MemoryBase) Mfree(MemoryBase); /* Speicher freigeben */
}
LONG BGH::operator signed()
{
return (LONG) MemoryBase;
}
char* BGH::GetHelpString(WORD Type, WORD Gruppe, WORD Index)
{
BGH_Gruppe** Sectionen = (BGH_Gruppe**) MemoryBase;
char* result = 0;
BGH_Gruppe* GruppeP;
BGH_Object* ObjectP;
if(Sectionen && Type >= 0 && Type <= 3)
{
GruppeP = Sectionen[Type]; /* 1. Gruppe */
while(GruppeP) /* Gruppe testen */
{
if(WPEEK(&GruppeP->Index) == Gruppe) /* Gruppe gefunden */
{
if(Index == -1) /* ist Index = -1 dann */
{
result = ((char*)GruppeP + sizeof(BGH_Gruppe)); /* Gruppen-Help */
if(GruppeP->StringTyp)
result = GetHelpString(0, 0, WPEEK(result));
}
else /* sonst */
{
if(WPEEK(&GruppeP->First))
ObjectP = (BGH_Object*)((LONG)GruppeP + WPEEK(&GruppeP->First));
else
ObjectP = 0; /* 1. Objekt */
while(ObjectP) /* Objekt testen */
{
if(WPEEK(&ObjectP->Index) == Index) /* Objekt gefunden */
{
switch(ObjectP->StringTyp)
{
case 1:
result = ((char*)ObjectP + WPEEK(&ObjectP->Link));
break;
case 2:
result = GetHelpString(0, 0, WPEEK(&ObjectP->Link));
break;
default:
result = ((char*)ObjectP + sizeof(BGH_Object));
break;
}
break;
}
if(WPEEK(&ObjectP->Next)) /* nächstes Objekt */
ObjectP = (BGH_Object*)((LONG)ObjectP + WPEEK(&ObjectP->Next));
else
ObjectP = 0;
}
}
break;
}
if(LPEEK(&GruppeP->Next)) /* nächste Gruppe */
GruppeP = (BGH_Gruppe*)LPEEK(&GruppeP->Next);
else
GruppeP = 0;
}
}
return result;
}
void BGH::Action(WORD Mx, WORD My, WORD Typ, WORD Gruppe, WORD Index)
{
WORD BubbleId;
WORD Msg[8];
char* HelpString = GetHelpString(Typ, Gruppe, Index);
if(HelpString)
{
BubbleId = appl_find("BUBBLE ");
if(BubbleId >= 0)
{
Msg[0] = 0xbabb; /*BUBBLEGEM_SHOW;*/
Msg[1] = gl_apid;
Msg[2] = 0;
Msg[3] = Mx;
Msg[4] = My;
Msg[5] = (WORD)(((LONG)HelpString >> 16) & 0x0000ffff);
Msg[6] = (WORD)((LONG)HelpString & 0x0000ffff);
Msg[7] = 0;
if (appl_write(BubbleId, 16, Msg) == 0)
{
/* Fehler */
}
}
}
}