home *** CD-ROM | disk | FTP | other *** search
- #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;
- }
-
- ULONG BGH_Load(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);
- }
- return (ULONG) Head;
- }
-
- void BGH_Free(ULONG BGH_ID)
- {
- if(BGH_ID) Mfree(BGH_ID); /* Speicher freigeben */
- }
-
- char* BGH_GetHelpString(ULONG BGH_ID, WORD Type, WORD Gruppe, WORD Index)
- {
- BGH_Gruppe** Sectionen = (BGH_Gruppe**) BGH_ID;
- 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 = BGH_GetHelpString(BGH_ID, 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 = BGH_GetHelpString(BGH_ID, 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(ULONG BGH_ID, WORD Mx, WORD My, WORD Typ, WORD Gruppe, WORD Index)
- {
- WORD BubbleId;
- WORD Msg[8];
-
- char* HelpString = BGH_GetHelpString(BGH_ID, 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 */
- }
- }
- }
- }
-