#include #include #include "Starter_res.h" struct sDBHandle; static VoidPtr GetObjectPtr(Word); static void MainFormInit(FormPtr); static void MiscFormInit(FormPtr); static void AbilitiesFormInit(FormPtr); static void EquipFormInit(FormPtr); static void CharFormInit(FormPtr); static void MainFormClose(FormPtr); static void MiscFormClose(FormPtr); static void AbilitiesFormClose(FormPtr); static void EquipFormClose(FormPtr); static void CharFormClose(FormPtr); static void CloseDBHandle(struct sDBHandle *); static void SaveCurCharacter(); static void SetAttributeDB(Word, ULong); static void SetAttributeDBLong(Word, ULong); static void SetAttribute(Word, long); /*********************************************************************** * * Macros * ***********************************************************************/ #define offsetof(type, member) ((ULong) &(((type *) 0)->member)) #define dbho(member) ((ULong)member-(ULong)curchar) /*********************************************************************** * * Internal Structures * ***********************************************************************/ #define dPrefsV1 \ Int characteridx; \ UInt abilityidx; \ UInt miscidx; \ UInt abilityaction; \ UInt equipaction; \ UInt miscabilityidx; \ UInt miscsavingidx; \ UInt miscdbhidx; \ UInt miscaction; \ Byte equipmask; \ char curweapon[30]; #define dPrefsV2 \ Int numdice; \ Int sizesidx; \ Int curweaponidx; typedef struct { dPrefsV1 } tPrefsV1; typedef struct { dPrefsV1 dPrefsV2 } tPrefsV2; typedef struct { dPrefsV1 dPrefsV2 } StarterPreferenceType; typedef struct { Byte replaceme; } StarterAppInfoType; typedef StarterAppInfoType* StarterAppInfoPtr; #define WEAPON 0x01 #define ARMOR 0x02 #define READY 0x04 #define TYPEMASK 0x03 typedef struct sList { UInt count; UInt size; UInt max; Byte flags[200]; char* list[200]; char data[512]; } tList; typedef struct sDBHandle { UInt rec; VoidHand handle; tList *data; } tDBHandle; typedef struct sCharacter { char name[25]; Int str; Int estr; Int intel; Int wis; Int dex; Int con; Int chr; Int hp; Int maxhp; Int psp; Int maxpsp; Int thac0; Int hpadj; Int damageadj; Int miscabilities[10]; Int saving[5]; Int adj; Int mthac0; Int baseac; Int raceidx; Int classesidx[3]; Long exp[3]; Int level[3]; Long gold; Long silver; Long electrum; Long platinum; Long copper; UInt alignment; tDBHandle MageSpellRecord; //record is of type tList tDBHandle PriestSpellRecord; //record is of type tList tDBHandle PsionicSpellRecord; //record is of type tList tDBHandle EquipmentRecord; //record is of type tList tDBHandle WProfsRecord; //record is of type tList tDBHandle NWProfsRecord; //record is of type tList Int misccount; tDBHandle MiscDBH[8]; char miscnames[8][21]; //end of version 1 char eclass[10][15]; char erace[10][15]; //end of version 2 } tCharacter; #define VERSION 2 typedef struct sDBHdrChars { UInt rec; char name[25]; } tDBHdrChars; typedef struct sDBHeader { UInt max; UInt count; tDBHdrChars data[10]; } tDBHeader; /*********************************************************************** * * Global variables * ***********************************************************************/ static DmOpenRef dbref=0; static LocalID dbid=0; #define dbname "ADD Character DB" static VoidHand dbhdrhand=0; static tDBHeader *dbhdr=(void *)0; static VoidHand curcharhand=0; static tCharacter *curchar=(void *)0; static Boolean dbhdrdirty = false; static char *names[200]; static char *equip[200]; static int equipcount; static StarterPreferenceType prefs; static Word lastform; static tDBHandle *lastdbh; static int editmode = 0; static int edittypes = 0; static UInt lastidx; static int closeblock=0; static char *misclist[8]; static int selclass; static char *eclass[11+10]; static char *erace[7+10]; /*********************************************************************** * * Internal Constants * ***********************************************************************/ #define appFileCreator 'AddA' #define appVersionNum 0x01 #define appPrefID 0x00 #define appPrefVersionNum 0x02 #define version10 0x01000000 #define version20 0x02000000 /*********************************************************************** * * Internal Functions * ***********************************************************************/ static void LoadClass() { VoidPtr ctl; char *text; ctl = GetObjectPtr(CharRaceList); LstSetSelection(ctl,curchar->raceidx); text = LstGetSelectionText(ctl,curchar->raceidx); ctl = GetObjectPtr(CharRacePopTrigger); CtlSetLabel(ctl,text); CtlEraseControl(ctl); CtlDrawControl(ctl); ctl = GetObjectPtr(CharClassList); LstSetSelection(ctl,curchar->classesidx[selclass]); text = LstGetSelectionText(ctl,curchar->classesidx[selclass]); ctl = GetObjectPtr(CharClassPopTrigger); CtlSetLabel(ctl,text); CtlEraseControl(ctl); CtlDrawControl(ctl); ctl = GetObjectPtr(CharAlignmentList); LstSetSelection(ctl,curchar->alignment); text = LstGetSelectionText(ctl,curchar->alignment); ctl = GetObjectPtr(CharAlignmentPopTrigger); CtlSetLabel(ctl,text); CtlEraseControl(ctl); CtlDrawControl(ctl); SetAttribute(CharExpField,curchar->exp[selclass]); ctl = GetObjectPtr(CharExpField); FldEraseField(ctl); FldDrawField(ctl); SetAttribute(CharLevelField,curchar->level[selclass]); ctl = GetObjectPtr(CharLevelField); FldEraseField(ctl); FldDrawField(ctl); } static void UpdateClass() { VoidPtr ctl; Int idx; SetAttributeDBLong(CharExpField,offsetof(tCharacter,exp[selclass])); ctl = GetObjectPtr(CharClassList); idx = LstGetSelection(ctl); DmWrite(curchar,offsetof(tCharacter,classesidx[selclass]),&idx,sizeof(Int)); ctl = GetObjectPtr(CharAlignmentList); idx = LstGetSelection(ctl); DmWrite(curchar,offsetof(tCharacter,alignment),&idx,sizeof(Int)); ctl = GetObjectPtr(CharRaceList); idx = LstGetSelection(ctl); DmWrite(curchar,offsetof(tCharacter,raceidx),&idx,sizeof(Int)); SetAttributeDB(CharLevelField,offsetof(tCharacter,level[selclass])); } static UInt FindFreeRecord() { UInt i; UInt num = DmNumRecords(dbref); LocalID lid; for (i=0;irec) { //it is allocated DmDeleteRecord(dbref,dbh->rec); i = 0; DmWrite(curchar,(ULong)dbh-(ULong)curchar+offsetof(tDBHandle,rec),&i,sizeof(UInt)); } } static void GetChar(UInt idx) { curcharhand = DmGetRecord(dbref,dbhdr->data[idx].rec); curchar = MemHandleLock(curcharhand); } static void CloseChar(UInt idx) { MemHandleUnlock(curcharhand); DmReleaseRecord(dbref,dbhdr->data[idx].rec,true); curchar = 0; } static void OpenChar(UInt idx) { if (curchar) { SaveCurCharacter(); closeblock = 1; MemHandleUnlock(curcharhand); DmReleaseRecord(dbref,dbhdr->data[prefs.characteridx].rec,true); } if (idx >= dbhdr->count) idx = dbhdr->count-1; if (idx == -1) return; prefs.characteridx = idx; curcharhand = DmGetRecord(dbref,dbhdr->data[idx].rec); curchar = MemHandleLock(curcharhand); } static void DrawList(UInt idx, RectanglePtr rect, CharPtr *text) { char buf[40]; int i,l; char *item; if (lastdbh == 0) return; if (lastdbh->data->count <= idx) return; WinSetClip(rect); WinEraseRectangle(rect,0); item = text[idx]+(ULong)(lastdbh->data); l = StrLen(item); for (i=0;idata->flags[idx] & READY) WinDrawChars("*",1,rect->topLeft.x,rect->topLeft.y); WinDrawChars(buf,StrLen(buf),rect->topLeft.x+10,rect->topLeft.y); WinResetClip(); } static void ResizeDBHandle(tDBHandle *dbhandle, UInt size) { VoidPtr ptr; VoidHand hand; DmReleaseRecord(dbref,dbhandle->rec,true); MemHandleUnlock(dbhandle->handle); hand = DmResizeRecord(dbref,dbhandle->rec,size); ptr = MemHandleLock(hand); DmWrite(curchar,dbho(dbhandle)+offsetof(tDBHandle,handle),&hand,sizeof(VoidHand)); DmWrite(curchar,dbho(dbhandle)+offsetof(tDBHandle,data),&ptr,sizeof(VoidPtr)); } static void NewList(tDBHandle *dbhandle) { VoidHand hand; VoidPtr ptr1; UInt numrecs; numrecs = FindFreeRecord(); if (numrecs == 0) { numrecs = DmNumRecords(dbref); hand = DmNewRecord(dbref,&numrecs,sizeof(tList)); ErrFatalDisplayIf(!hand,"Could not create record"); } else { DmRemoveRecord(dbref,numrecs); hand = DmNewRecord(dbref,&numrecs,sizeof(tList)); ErrFatalDisplayIf(!hand,"Could not create record"); } DmWrite(curchar,dbho(dbhandle)+offsetof(tDBHandle,rec),&numrecs,sizeof(UInt)); ptr1 = MemHandleLock(hand); DmSet(ptr1,0,sizeof(tList),0); DmWrite(curchar,dbho(dbhandle)+offsetof(tDBHandle,handle),&hand,sizeof(VoidHand)); DmWrite(curchar,dbho(dbhandle)+offsetof(tDBHandle,data),&ptr1,sizeof(VoidPtr)); numrecs = 512; DmWrite(ptr1,offsetof(tList,max),&numrecs,sizeof(UInt)); } static void CloseDBHandle(struct sDBHandle *dbhandle) { if (dbhandle == 0) return; if (dbhandle->rec == 0) return; MemHandleUnlock(dbhandle->handle); DmReleaseRecord(dbref,dbhandle->rec,true); lastdbh = 0; } static void OpenDBHandle(tDBHandle *dbhandle) { Word offset; VoidPtr ptr1,ptr2; VoidHand hand; if (curchar && lastdbh) CloseDBHandle(lastdbh); if (dbhandle->rec == 0) { //need to create record NewList(dbhandle); } else { ptr1 = dbhandle->data; hand = DmGetRecord(dbref,dbhandle->rec); ptr2 = MemHandleLock(hand); DmWrite(curchar,dbho(dbhandle)+offsetof(tDBHandle,handle),&hand,sizeof(VoidHand)); DmWrite(curchar,dbho(dbhandle)+offsetof(tDBHandle,data),&ptr2,sizeof(VoidPtr)); offset = (Word)ptr2-(Word)ptr1; } lastdbh = dbhandle; } static void ResizeRecord(tDBHandle *dbhandle,UInt size) { UInt ptr; ptr = (UInt)dbhandle->data; ResizeDBHandle(dbhandle,size); } static void AddToMisc(char *item) { Int idx; if (curchar->misccount >= 8) return; idx = curchar->misccount; OpenDBHandle(&(curchar->MiscDBH[idx])); DmStrCopy(curchar,offsetof(tCharacter,miscnames[idx]),item); prefs.miscdbhidx = idx; idx++; DmWrite(curchar,offsetof(tCharacter,misccount),&idx,sizeof(Int)); } static void RemoveFromMisc(int idx) { Int i; if (idx > curchar->misccount) return; CloseDBHandle(&(curchar->MiscDBH[idx])); FreeDBHandle(&(curchar->MiscDBH[idx])); for (i=idx;i>curchar->misccount-1;i++) DmStrCopy(curchar,offsetof(tCharacter,miscnames[i]),curchar->miscnames[i+1]); i = curchar->misccount-1; DmWrite(curchar,offsetof(tCharacter,misccount),&i,sizeof(Int)); i = 0; if (i > 0) { prefs.miscdbhidx = 0; } } //Add a text item to a list static void AddToList(tDBHandle *dbhandle,char *item,Byte flags) { UInt l,size,offset; l = StrLen(item); //see if there is enough room for the new string if (dbhandle->data->size+l >= dbhandle->data->max) { size = sizeof(tList)+dbhandle->data->size+l; ResizeRecord(dbhandle,size); size = dbhandle->data->size+l+512; DmWrite(dbhandle->data,offsetof(tList,max),&size,sizeof(UInt)); } //append string to buffer offset = offsetof(tList,data)+(UInt)dbhandle->data->size; DmStrCopy(dbhandle->data,offset,item); //update buffer size; size = (UInt)dbhandle->data->size+l+1; DmWrite(dbhandle->data,offsetof(tList,size),&size,sizeof(UInt)); //update the list pointer array DmWrite(dbhandle->data,sizeof(UInt)+offsetof(tList,list[dbhandle->data->count]), &offset,sizeof(UInt)); //update ready list DmSet(dbhandle->data,offsetof(tList,flags[dbhandle->data->count]),sizeof(Byte),flags); //update the item count l = dbhandle->data->count+1; DmWrite(dbhandle->data,offsetof(tList,count),&l,sizeof(UInt)); } static void RemoveFromList(tDBHandle *dbhandle,UInt idx) { char buf[64]; char *ptr1,*ptr2; UInt count,num,i,len; Byte b; if (idx >= dbhandle->data->count) return; ptr1 = (char *)dbhandle->data->list[idx]+(ULong)(dbhandle->data); if (idx < dbhandle->data->count-1) { ptr2 = (char *)dbhandle->data->list[idx+1]+(ULong)(dbhandle->data); len = (UInt)(ptr2-ptr1); count = dbhandle->data->size-(UInt)(ptr2-dbhandle->data->data); num = 64; while (count > 0) { if (count < 64) num = count; MemMove(buf,ptr2,num); DmWrite(dbhandle->data,(ULong)ptr1-(ULong)dbhandle->data,buf,num); ptr1 += num; ptr2 += num; count -= num; } for (i=idx+1;idata->count;i++) { count = (UInt)dbhandle->data->list[i]-len; DmWrite(dbhandle->data,sizeof(UInt)+offsetof(tList,list[i-1]),&count,sizeof(UInt)); b = (UInt)dbhandle->data->flags[i]; DmWrite(dbhandle->data,offsetof(tList,flags[i-1]),&b,sizeof(Byte)); } count = dbhandle->data->size-len; DmWrite(dbhandle->data,offsetof(tList,size),&count,sizeof(UInt)); } else { if (idx > 0) { count = dbhandle->data->size-(UInt)(dbhandle->data->data+dbhandle->data->size-ptr1); DmWrite(dbhandle->data,offsetof(tList,size),&count,sizeof(UInt)); } else { count = 0; DmWrite(dbhandle->data,offsetof(tList,size),&count,sizeof(UInt)); } } count = dbhandle->data->count-1; DmWrite(dbhandle->data,offsetof(tList,count),&count,sizeof(UInt)); } static void ReadyItem(tDBHandle *dbhandle, UInt idx) { if (idx >= dbhandle->data->count) return; DmSet(dbhandle->data,offsetof(tList,flags[idx]), sizeof(Byte),dbhandle->data->flags[idx]^READY); } static void EditItem(tDBHandle *dbhandle, UInt idx, int et) { editmode = 1; edittypes = et; lastdbh = dbhandle; lastidx = idx; FrmGotoForm(EditListForm); } static void DeleteItem(tDBHandle *dbhandle, UInt idx) { RemoveFromList(dbhandle,idx); } static void InsertItem(tDBHandle *dbhandle,UInt idx,char *text,Byte flags) { char buf[64]; char *ptr1,*ptr2; UInt count,num,len; Int i; Byte b; if (idx >= dbhandle->data->count) return; len = StrLen(text)+1; if (dbhandle->data->size+len >= dbhandle->data->max) { num = sizeof(tList)+dbhandle->data->max; ResizeRecord(dbhandle,num); num = dbhandle->data->max+512; DmWrite(dbhandle->data,offsetof(tList,max),&num,sizeof(UInt)); } ptr1 = dbhandle->data->data+dbhandle->data->size; ptr2 = (char *)dbhandle->data->list[idx]+(ULong)(dbhandle->data); count = dbhandle->data->size-(UInt)(ptr2-dbhandle->data->data); num = 64; while (count > 0) { if (count < 64) num = count; ptr2 = ptr1-num; MemMove(buf,ptr2,num); ptr2 = ptr2+len; DmWrite(dbhandle->data,(ULong)ptr2-(ULong)dbhandle->data,buf,num); ptr1 -= num; count -= num; } for (i=dbhandle->data->count-1;i>=(Int)idx;i--) { count = (UInt)dbhandle->data->list[i]+len; DmWrite(dbhandle->data,sizeof(UInt)+offsetof(tList,list[i+1]),&count,sizeof(UInt)); b = (UInt)dbhandle->data->flags[i]; DmWrite(dbhandle->data,offsetof(tList,flags[i+1]),&b,sizeof(Byte)); } count = dbhandle->data->count+1; DmWrite(dbhandle->data,offsetof(tList,count),&count,sizeof(UInt)); count = dbhandle->data->size+len; DmWrite(dbhandle->data,offsetof(tList,size),&count,sizeof(UInt)); DmSet(dbhandle->data,offsetof(tList,flags[idx]),sizeof(Byte),flags); DmStrCopy(dbhandle->data,(ULong)dbhandle->data->list[idx],text); } static void ReplaceItem(tDBHandle *dbhandle,UInt idx,char *text) { } static void SetAttributeDB(Word id, ULong offset) { VoidPtr ctl; char *text; Int value; ctl = GetObjectPtr(id); text = FldGetTextPtr(ctl); if (text && curchar) { value = StrAToI(text); DmWrite(curchar,offset,&value,sizeof(Int)); } } static void SetAttributeDBLong(Word id, ULong offset) { VoidPtr ctl; char *text; Long value; ctl = GetObjectPtr(id); text = FldGetTextPtr(ctl); if (text && curchar) { value = StrAToI(text); DmWrite(curchar,offset,&value,sizeof(Long)); } } static void SetAttributesDB(Word id, ULong offset1, ULong offset2) { VoidPtr ctl; char *text; Int value,i,l; ctl = GetObjectPtr(id); text = FldGetTextPtr(ctl); if (text && curchar) { value = StrAToI(text); DmWrite(curchar,offset1,&value,sizeof(Int)); l = StrLen(text); for (i=0;istr; switch (str) { case 1: bonus = -5; break; case 2: case 3: bonus = -3; break; case 4: case 5: bonus = -2; break; case 6: case 7: bonus = -1; break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: bonus = 0; break; case 17: bonus = 1; break; case 18: if (curchar->estr == 0) bonus = 3; else if (curchar->estr <= 50) bonus = 1; else bonus = 2; break; case 19: case 20: bonus = 3; break; case 21: case 22: bonus = 4; break; case 23: bonus = 5; break; case 24: bonus = 6; break; case 25: bonus = 7; break; } return bonus; } static int ConvertWeaponBonus(char *text) { int v = 0; int sign = 0; int i,l; unsigned char temp; if (!text) return 0; l = StrLen(text); for (i=0;i= '0' && temp <= '9') v = v*10+(temp-'0'); else break; } if (sign) v = 0-v; return v; } static int ConvertWeaponSpeed(char *text) { int v = 0; int i,l; unsigned char temp; if (!text) return 0; l = StrLen(text); for (i=0;i= '0' && temp <= '9') v = v*10+(temp-'0'); else break; } return v; } static void BuildList(tDBHandle *dbh,Byte flags,Word listid, int realaddr) { int l,i,c; Byte b; VoidPtr ctl; l = dbh->data->count; c = 0; for (i=0;idata->flags[i]; if ((b & flags) == flags) if (realaddr) equip[c++] = dbh->data->list[i]+(ULong)dbh->data; else equip[c++] = dbh->data->list[i]; } ctl = GetObjectPtr(listid); LstSetListChoices(ctl,equip,c); equipcount = c; if (!realaddr) LstSetDrawFunction(ctl,(ListDrawDataFuncType *)DrawList); } static void MainFormClose(FormPtr form) { int cb = closeblock; closeblock = 0; if (cb || !curchar) return; SetAttributesDB(MainStrField,(ULong)&(curchar->str)-(ULong)curchar, (ULong)&(curchar->estr)-(ULong)curchar); SetAttributeDB(MainIntField,(ULong)&(curchar->intel)-(ULong)curchar); SetAttributeDB(MainWisField,(ULong)&(curchar->wis)-(ULong)curchar); SetAttributeDB(MainDexField,(ULong)&(curchar->dex)-(ULong)curchar); SetAttributeDB(MainConField,(ULong)&(curchar->con)-(ULong)curchar); SetAttributeDB(MainChrField,(ULong)&(curchar->chr)-(ULong)curchar); SetAttributeDB(MainHPField,(ULong)&(curchar->hp)-(ULong)curchar); SetAttributeDB(MainPSPField,(ULong)&(curchar->psp)-(ULong)curchar); SetAttributeDB(MainMaxHPField,(ULong)&(curchar->maxhp)-(ULong)curchar); SetAttributeDB(MainMaxPSPField,(ULong)&(curchar->maxpsp)-(ULong)curchar); SetAttributeDB(MainHitAdjField,(ULong)&(curchar->hpadj)-(ULong)curchar); SetAttributeDB(MainDamageAdjField,(ULong)&(curchar->damageadj)-(ULong)curchar); SetAttributeDB(MainTHAC0Field,(ULong)&(curchar->thac0)-(ULong)curchar); SetAttributeDB(MainMTHAC0Field,(ULong)&(curchar->mthac0)-(ULong)curchar); SetAttributeDB(MainACField,(ULong)&(curchar->baseac)-(ULong)curchar); } static void EquipFormClose(FormPtr form) { int cb = closeblock; closeblock = 0; if (cb || !curchar) return; // SetAttributeDBLong(EquipPPField,offsetof(tCharacter,platinum)); // SetAttributeDBLong(EquipGPField,offsetof(tCharacter,gold)); // SetAttributeDBLong(EquipEPField,offsetof(tCharacter,electrum)); // SetAttributeDBLong(EquipSPField,offsetof(tCharacter,silver)); // SetAttributeDBLong(EquipCPField,offsetof(tCharacter,copper)); // SetAttributeDBLong(EquipXPField,offsetof(tCharacter,exp)); } static void CharFormClose(FormPtr form) { int cb = closeblock; closeblock = 0; if (cb || !curchar) return; SetAttributeDBLong(CharPPField,offsetof(tCharacter,platinum)); SetAttributeDBLong(CharGPField,offsetof(tCharacter,gold)); SetAttributeDBLong(CharEPField,offsetof(tCharacter,electrum)); SetAttributeDBLong(CharSPField,offsetof(tCharacter,silver)); SetAttributeDBLong(CharCPField,offsetof(tCharacter,copper)); UpdateClass(); } static void AbilitiesFormClose(FormPtr form) { int cb = closeblock; closeblock = 0; if (cb || !curchar) return; } static void MiscFormClose(FormPtr form) { VoidPtr ctl; int idx; int cb = closeblock; closeblock = 0; if (cb || !curchar) return; ctl = GetObjectPtr(MiscAbilitiesList); idx = LstGetSelection(ctl); if (idx != -1) SetAttributeDB(MiscAbilitiesField,offsetof(tCharacter,miscabilities[idx])); ctl = GetObjectPtr(MiscSavingList); idx = LstGetSelection(ctl); if (idx != -1) SetAttributeDB(MiscSavingField,offsetof(tCharacter,saving[idx])); } static void SetAttributeString(Word id, char *buffer) { VoidPtr ctl; int l; char *text; VoidHand hand; Word size; l = StrLen(buffer); ctl = GetObjectPtr(id); hand = FldGetTextHandle(ctl); size = FldGetTextAllocatedSize(ctl); // if (l >= size) { if (hand) FldFreeMemory(ctl); hand = MemHandleNew(l+1); text = MemHandleLock(hand); StrCopy(text,buffer); MemHandleUnlock(hand); FldSetTextHandle(ctl,hand); // } } static void SetAttribute(Word id, long value) { char buffer[15]; StrIToA(buffer,value); SetAttributeString(id,buffer); } static void SetAttributes(Word id, UInt v1, Int v2) { int l; char buffer[15]; StrIToA(buffer,v1); l = StrLen(buffer); buffer[l] = '.'; StrIToA(buffer+l+1,v2); SetAttributeString(id,buffer); } static void SaveCurCharacter() { Word formid; FormPtr form; if (!curchar) return; CloseDBHandle(lastdbh); formid = FrmGetActiveFormID(); form = FrmGetActiveForm(); switch (formid) { case MainForm: MainFormClose(form); break; case EquipForm: EquipFormClose(form); break; case AbilitiesForm: AbilitiesFormClose(form); break; case MiscForm: MiscFormClose(form); break; default: break; } } static void UpdateScreen() { Word formid; FormPtr form; formid = FrmGetActiveFormID(); form = FrmGetActiveForm(); switch (formid) { case MainForm: MainFormInit(form); break; case EquipForm: EquipFormInit(form); break; case AbilitiesForm: AbilitiesFormInit(form); break; case MiscForm: MiscFormInit(form); break; default: break; } FrmDrawForm(form); } static void DeleteCharacter() { int i; UInt num; CloseDBHandle(lastdbh); if (curchar && curcharhand) { //first, free any allocated tDBHandle's FreeDBHandle(&curchar->PriestSpellRecord); FreeDBHandle(&curchar->MageSpellRecord); FreeDBHandle(&curchar->PsionicSpellRecord); FreeDBHandle(&curchar->EquipmentRecord); FreeDBHandle(&curchar->WProfsRecord); FreeDBHandle(&curchar->NWProfsRecord); for (i=0;imisccount;i++) FreeDBHandle(&(curchar->MiscDBH[i])); MemHandleUnlock(curcharhand); DmReleaseRecord(dbref,dbhdr->data[prefs.characteridx].rec,true); DmDeleteRecord(dbref,dbhdr->data[prefs.characteridx].rec); for (i=prefs.characteridx;icount-1;i++) { DmWrite(dbhdr,offsetof(tDBHeader,data[i]),&(dbhdr->data[i+1]),sizeof(tDBHdrChars)); names[i] -= sizeof(tDBHdrChars); } num = dbhdr->count-1; DmWrite(dbhdr,offsetof(tDBHeader,count),&num,sizeof(UInt)); curchar = (void *)0; curcharhand = 0; //load another char OpenChar(dbhdr->count-1); } } static void AddCharacter(char *name) { UInt rec,numrecs; VoidPtr ctl; FormPtr frmP; SaveCurCharacter(); if (dbhdr->count >= dbhdr->max) { //expand the data //release record before resize MemHandleUnlock(dbhdrhand); rec = dbhdr->max+10; //grow by 10 entries dbhdrhand = DmResizeRecord(dbref,0,4+(dbhdr->max+10)*(sizeof(tDBHdrChars))); dbhdr = MemHandleLock(dbhdrhand); //update the max count DmWrite(dbhdr,(ULong)&(dbhdr->max)-(ULong)dbhdr,&rec,sizeof(UInt)); } dbhdrdirty = true; if (prefs.characteridx >= 0) CloseChar(prefs.characteridx); //put in the new characters record index numrecs = FindFreeRecord(); if (numrecs != 0) { DmRemoveRecord(dbref,numrecs); curcharhand = DmNewRecord(dbref,&numrecs,sizeof(tCharacter)); ErrFatalDisplayIf(!curcharhand,"Could not create character record"); } else { numrecs = DmNumRecords(dbref); curcharhand = DmNewRecord(dbref,&numrecs,sizeof(tCharacter)); ErrFatalDisplayIf(!curcharhand,"Could not create character record"); } prefs.characteridx = dbhdr->count; DmWrite(dbhdr,offsetof(tDBHeader,data[dbhdr->count].rec),&numrecs,sizeof(UInt)); DmStrCopy(dbhdr,offsetof(tDBHeader,data[dbhdr->count].name),name); names[dbhdr->count] = dbhdr->data[dbhdr->count].name; //update the count of characters in the db rec = dbhdr->count+1 ; DmWrite(dbhdr,(ULong)&(dbhdr->count)-(ULong)dbhdr,&rec,sizeof(UInt)); //add the new character curchar = MemHandleLock(curcharhand); DmSet(curchar,0,sizeof(tCharacter),0); DmStrCopy(curchar,(ULong)&(curchar->name)-(ULong)curchar,name); frmP = FrmGetFormPtr(MainForm); ctl = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, MainCharactersList)); LstSetListChoices(ctl,names,dbhdr->count); ctl = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, MainCharacterPopTrigger)); CtlSetLabel(ctl,curchar->name); } static void AdjustAttribute(UInt id, UInt field, int inc) { VoidPtr ctl,fld; int value,attr; char *text; char buffer[40]; fld = GetObjectPtr(id); text = FldGetTextPtr(fld); if (text != 0) attr = StrAToI(text); else attr = 0; ctl = GetObjectPtr(field); text = FldGetTextPtr(ctl); if (text == 0) return; value = StrAToI(text); if (inc) attr += value; else attr -= value; inc = FldGetTextLength(fld); if (inc > 0) FldDelete(fld,0,inc); StrIToA(buffer,attr); FldSetInsPtPosition(fld,0); FldInsert(fld,buffer,StrLen(buffer)); FldEraseField(fld); FldDrawField(fld); } static void AdjustAttributeMain(UInt id) { VoidPtr ctl; int inc; ctl = GetObjectPtr(MainIncPushButton); inc = CtlGetValue(ctl); AdjustAttribute(id,MainAmountField,inc); } static void AdjustAttributeChar(UInt id) { VoidPtr ctl; int inc; ctl = GetObjectPtr(CharIncPushButton); inc = CtlGetValue(ctl); AdjustAttribute(id,CharAmountField,inc); } static int RollDice(int numdice,int dice) { int i,t; ULong r; FieldPtr fld; char buf[80],temp[10]; r = TimGetTicks(); fld = GetObjectPtr(MainRollsField); i = FldGetTextLength(fld); if (i > 0) FldDelete(fld,0,i); r = r%dice+1; StrIToA(buf,r); FldSetInsPtPosition(fld,0); if (numdice > 1) { t = r; for (i=1;istr,curchar->estr); SetAttribute(MainIntField,curchar->intel); SetAttribute(MainWisField,curchar->wis); SetAttribute(MainDexField,curchar->dex); SetAttribute(MainConField,curchar->con); SetAttribute(MainChrField,curchar->chr); SetAttribute(MainHPField,curchar->hp); SetAttribute(MainPSPField,curchar->psp); SetAttribute(MainMaxHPField,curchar->maxhp); SetAttribute(MainMaxPSPField,curchar->maxpsp); SetAttribute(MainHitAdjField,curchar->hpadj); SetAttribute(MainDamageAdjField,curchar->damageadj); SetAttribute(MainTHAC0Field,curchar->thac0); SetAttribute(MainMTHAC0Field,curchar->mthac0); SetAttribute(MainACField,curchar->baseac); ctl = GetObjectPtr(MainCharacterPopTrigger); CtlSetLabel(ctl,curchar->name); ctl = GetObjectPtr(MainCharactersList); LstSetListChoices(ctl,names,dbhdr->count); dbh = &(curchar->EquipmentRecord); OpenDBHandle(dbh); BuildList(dbh,WEAPON,MainWeaponsList,1); /* for (i=0;i= equipcount) { if (equipcount == 0) { ctl = GetObjectPtr(MainWeaponPopTrigger); *(prefs.curweapon) = 0; CtlSetLabel(ctl,prefs.curweapon); ctl = GetObjectPtr(MainWeaponsList); LstSetSelection(ctl,-1); } } */ if (prefs.curweaponidx >= equipcount) { if (equipcount == 0) { ctl = GetObjectPtr(MainWeaponPopTrigger); *(prefs.curweapon) = 0; prefs.curweaponidx = 0; CtlSetLabel(ctl,prefs.curweapon); ctl = GetObjectPtr(MainWeaponsList); LstSetSelection(ctl,-1); } else { ctl = GetObjectPtr(MainWeaponsList); LstSetSelection(ctl,0); text = LstGetSelectionText(ctl,0); StrCopy(prefs.curweapon,text); prefs.curweaponidx = 0; ctl = GetObjectPtr(MainWeaponPopTrigger); CtlSetLabel(ctl,text); } } else { ctl = GetObjectPtr(MainWeaponsList); LstSetSelection(ctl,prefs.curweaponidx); text = LstGetSelectionText(ctl,prefs.curweaponidx); StrCopy(prefs.curweapon,text); ctl = GetObjectPtr(MainWeaponPopTrigger); CtlSetLabel(ctl,text); } ctl = GetObjectPtr(MainNumDiceList); LstSetSelection(ctl,prefs.numdice); text = LstGetSelectionText(ctl,prefs.numdice); ctl = GetObjectPtr(MainNumDicePopTrigger); CtlSetLabel(ctl,text); ctl = GetObjectPtr(MainDiceList); LstSetSelection(ctl,prefs.sizesidx); text = LstGetSelectionText(ctl,prefs.sizesidx); ctl = GetObjectPtr(MainDicePopTrigger); CtlSetLabel(ctl,text); lastform = MainForm; } } static void MiscFormInit(FormPtr frmP) { VoidPtr ctl; char *text; int i; ctl = GetObjectPtr(MiscMiscPushButton); CtlSetValue(ctl,1); switch (prefs.miscaction) { case 1: ctl = GetObjectPtr(MiscEditPushButton); break; case 2: ctl = GetObjectPtr(MiscDeletePushButton); break; default: ctl = GetObjectPtr(MiscReadyPushButton); break; } CtlSetValue(ctl,1); ctl = GetObjectPtr(MiscCharacterPopTrigger); CtlSetLabel(ctl,curchar->name); ctl = GetObjectPtr(MiscCharactersList); LstSetListChoices(ctl,names,dbhdr->count); ctl = GetObjectPtr(MiscAbilitiesList); text = LstGetSelectionText(ctl,prefs.miscabilityidx); ctl = GetObjectPtr(MiscAbilitiesPopTrigger); CtlSetLabel(ctl,text); ctl = GetObjectPtr(MiscSavingList); text = LstGetSelectionText(ctl,prefs.miscsavingidx); ctl = GetObjectPtr(MiscSavingPopTrigger); CtlSetLabel(ctl,text); SetAttribute(MiscAbilitiesField,curchar->miscabilities[prefs.miscabilityidx]); SetAttribute(MiscSavingField,curchar->saving[prefs.miscsavingidx]); if (curchar->misccount > 0) { ctl = GetObjectPtr(MiscMiscPopTrigger); CtlSetLabel(ctl,curchar->miscnames[prefs.miscdbhidx]); ctl = GetObjectPtr(MiscMiscNamesList); LstSetListChoices(ctl,misclist,curchar->misccount); OpenDBHandle(&(curchar->MiscDBH[prefs.miscdbhidx])); for (i=0;imisccount;i++) misclist[i] = curchar->miscnames[i]; ctl = GetObjectPtr(MiscMiscList); LstSetListChoices(ctl,lastdbh->data->list,lastdbh->data->count); LstSetDrawFunction(ctl,(ListDrawDataFuncType *)DrawList); } lastform = MiscForm; } static void EditListFormInit(FormPtr frmP) { char *item; VoidPtr ctl; if (lastdbh && editmode) { item = lastdbh->data->list[lastidx]+(ULong)(lastdbh->data); SetAttributeString(EditListItemField,item); } if (edittypes) { ctl = GetObjectPtr(EditListTypePopTrigger); CtlSetUsable(ctl,1); ctl = GetObjectPtr(EditListTypeList); LstSetSelection(ctl,lastdbh->data->flags[lastidx]&TYPEMASK); item = LstGetSelectionText(ctl,lastdbh->data->flags[lastidx]&TYPEMASK); ctl = GetObjectPtr(EditListTypePopTrigger); CtlSetLabel(ctl,item); } } static void AbilitiesFormInit(FormPtr frmP) { VoidPtr ctl; tDBHandle *dbh; char *text; switch (prefs.abilityaction) { case 1: ctl = GetObjectPtr(AbilitiesEditPushButton); break; case 2: ctl = GetObjectPtr(AbilitiesDeletePushButton); break; default: ctl = GetObjectPtr(AbilitiesReadyPushButton); break; } CtlSetValue(ctl,1); ctl = GetObjectPtr(AbilitiesAbilitiesPushButton); CtlSetValue(ctl,1); switch (prefs.abilityidx) { case 1: dbh = &(curchar->NWProfsRecord); break; case 2: dbh = &(curchar->PriestSpellRecord); break; case 3: dbh = &(curchar->MageSpellRecord); break; case 4: dbh = &(curchar->PsionicSpellRecord); break; default: dbh = &(curchar->WProfsRecord); break; } OpenDBHandle(dbh); ctl = GetObjectPtr(AbilitiesAbilitiesList); LstSetListChoices(ctl,dbh->data->list,dbh->data->count); LstSetDrawFunction(ctl,(ListDrawDataFuncType *)DrawList); ctl = GetObjectPtr(AbilitiesCharacterPopTrigger); CtlSetLabel(ctl,curchar->name); ctl = GetObjectPtr(AbilitiesCharactersList); LstSetListChoices(ctl,names,dbhdr->count); ctl = GetObjectPtr(AbilitiesAbilityList); text = LstGetSelectionText(ctl,prefs.abilityidx); ctl = GetObjectPtr(AbilitiesAbilityPopTrigger); CtlSetLabel(ctl,text); lastform = AbilitiesForm; } static void EquipFormInit(FormPtr frmP) { VoidPtr ctl; tDBHandle *dbh; ctl = GetObjectPtr(EquipEquipPushButton); CtlSetValue(ctl,1); switch (prefs.equipaction) { case 1: ctl = GetObjectPtr(EquipEditPushButton); break; case 2: ctl = GetObjectPtr(EquipDeletePushButton); break; default: ctl = GetObjectPtr(EquipReadyPushButton); break; } CtlSetValue(ctl,1); dbh = &(curchar->EquipmentRecord); OpenDBHandle(dbh); BuildList(dbh,prefs.equipmask,EquipEquipList,0); ctl = GetObjectPtr(EquipCharacterPopTrigger); CtlSetLabel(ctl,curchar->name); ctl = GetObjectPtr(EquipCharactersList); LstSetListChoices(ctl,names,dbhdr->count); lastform = EquipForm; } static void CharFormInit(FormPtr frmP) { VoidPtr ctl; tDBHandle *dbh; int i; ctl = GetObjectPtr(CharCharPushButton); CtlSetValue(ctl,1); ctl = GetObjectPtr(CharIncPushButton); CtlSetValue(ctl,1); SetAttribute(CharAmountField,1); dbh = &(curchar->EquipmentRecord); OpenDBHandle(dbh); ctl = GetObjectPtr(CharCharacterPopTrigger); CtlSetLabel(ctl,curchar->name); ctl = GetObjectPtr(CharCharactersList); LstSetListChoices(ctl,names,dbhdr->count); lastform = CharForm; SetAttribute(CharPPField,curchar->platinum); SetAttribute(CharGPField,curchar->gold); SetAttribute(CharEPField,curchar->electrum); SetAttribute(CharSPField,curchar->silver); SetAttribute(CharCPField,curchar->copper); ctl = GetObjectPtr(CharClass1PushButton); CtlSetValue(ctl,1); ctl = GetObjectPtr(CharRaceList); for (i=0;i<7;i++) { erace[i] = LstGetSelectionText(ctl,i); } for (;i<17;i++) { if (*curchar->erace[i-7]) erace[i] = curchar->erace[i-7]; else erace[i] = "Other"; } LstSetListChoices(ctl,erace,17); ctl = GetObjectPtr(CharClassList); for (i=0;i<11;i++) { eclass[i] = LstGetSelectionText(ctl,i); } for (;i<21;i++) { if (*curchar->eclass[i-11]) eclass[i] = curchar->eclass[i-11]; else eclass[i] = "Other"; } LstSetListChoices(ctl,eclass,21); selclass = 0; LoadClass(); } /*********************************************************************** * * FUNCTION: MainFormDoCommand * * DESCRIPTION: This routine performs the menu command specified. * * PARAMETERS: command - menu item id * * RETURNED: nothing * * REVISION HISTORY: * * ***********************************************************************/ static Boolean MainFormDoCommand(Word command) { Boolean handled = false; switch (command) { case OptionsAboutADDAssistant: FrmAlert(AboutAlert); handled = true; break; case CharacterNew: handled = true; FrmPopupForm(NewCharForm); break; case CharacterDelete: handled = true; if (FrmAlert(VerifyAlert) == 0) { DeleteCharacter(); FrmGotoForm(MainForm); } break; default: break; } return handled; } /*********************************************************************** * * FUNCTION: MainFormHandleEvent * * DESCRIPTION: This routine is the event handler for the * "MainForm" of this application. * * PARAMETERS: eventP - a pointer to an EventType structure * * RETURNED: true if the event has handle and should not be passed * to a higher level handler. * * REVISION HISTORY: * * ***********************************************************************/ static Boolean MainFormHandleEvent(EventPtr eventP) { Boolean handled = false; FormPtr frmP; VoidPtr ctl; char *label; int numdice,dice,roll,tohit,idx; char buf[20],buf2[5]; char *temp; switch (eventP->eType) { case menuEvent: return MainFormDoCommand(eventP->data.menu.itemID); case frmOpenEvent: frmP = FrmGetActiveForm(); MainFormInit( frmP); FrmDrawForm ( frmP); handled = true; break; case frmCloseEvent: frmP = FrmGetActiveForm(); MainFormClose( frmP); break; case ctlSelectEvent: if (!curchar) { ctl = GetObjectPtr(MainStatsPushButton); CtlSetValue(ctl,1); MainFormDoCommand(CharacterNew); return false; } switch (eventP->data.ctlSelect.controlID) { case MainMiscPushButton: FrmGotoForm(MiscForm); break; case MainAbilitiesPushButton: FrmGotoForm(AbilitiesForm); break; case MainEquipPushButton: FrmGotoForm(EquipForm); break; case MainCharPushButton: FrmGotoForm(CharForm); break; case MainRollButton: ctl = GetObjectPtr(MainDicePopTrigger); label = CtlGetLabel(ctl); dice = StrAToI(label+1); ctl = GetObjectPtr(MainNumDicePopTrigger); label = CtlGetLabel(ctl); numdice = StrAToI(label); roll = RollDice(numdice,dice); break; case MainRollToHitButton: ctl = GetObjectPtr(MainTHAC0Field); temp = FldGetTextPtr(ctl); if (temp) tohit = StrAToI(temp); else tohit = 20; ctl = GetObjectPtr(MainHitAdjField); temp = FldGetTextPtr(ctl); if (temp) tohit -= StrAToI(temp); ctl = GetObjectPtr(MainWeaponPopTrigger); tohit -= ConvertWeaponBonus(CtlGetLabel(ctl)); ctl = GetObjectPtr(MainRollsField); temp = FldGetTextPtr(ctl); roll = RollDice(1,20)+CalcStrBonus(); StrCopy(buf," hits >= AC "); StrIToA(buf2,tohit-roll); StrCat(buf,buf2); FldSetInsPtPosition(ctl,FldGetTextLength(ctl)); FldInsert(ctl,buf,StrLen(buf)); FldEraseField(ctl); FldDrawField(ctl); break; case MainRollInitiativeButton: tohit = RollDice(1,10)+3; //3 is default size tohit -= curchar->miscabilities[4]; // ctl = GetObjectPtr(MainHitAdjField); // temp = FldGetTextPtr(ctl); // if (temp) // tohit -= StrAToI(temp); tohit -= CalcStrBonus(); ctl = GetObjectPtr(MainWeaponPopTrigger); tohit -= ConvertWeaponBonus(CtlGetLabel(ctl)); tohit += ConvertWeaponSpeed(CtlGetLabel(ctl)); ctl = GetObjectPtr(MainRollsField); temp = FldGetTextPtr(ctl); StrIToA(buf+2,tohit); *buf = '-'; *(buf+1) = '>'; FldSetInsPtPosition(ctl,FldGetTextLength(ctl)); FldInsert(ctl,buf,StrLen(buf)); FldEraseField(ctl); FldDrawField(ctl); break; default: break; } break; case ctlRepeatEvent: if (!curchar) { MainFormDoCommand(CharacterNew); return false; } switch (eventP->data.ctlSelect.controlID) { case MainStrRepeating: AdjustAttributeMain(MainStrField); break; case MainIntRepeating: AdjustAttributeMain(MainIntField); break; case MainChrRepeating: AdjustAttributeMain(MainChrField); break; case MainConRepeating: AdjustAttributeMain(MainConField); break; case MainWisRepeating: AdjustAttributeMain(MainWisField); break; case MainDexRepeating: AdjustAttributeMain(MainDexField); break; case MainHPRepeating: AdjustAttributeMain(MainHPField); break; case MainPSPRepeating: AdjustAttributeMain(MainPSPField); break; case MainHitAdjRepeating: AdjustAttributeMain(MainHitAdjField); break; case MainDamageAdjRepeating: AdjustAttributeMain(MainDamageAdjField); break; case MainTHAC0Repeating: AdjustAttributeMain(MainTHAC0Field); break; case MainMTHAC0Repeating: AdjustAttributeMain(MainMTHAC0Field); break; case MainMaxHPRepeating: AdjustAttributeMain(MainMaxHPField); break; case MainMaxPSPRepeating: AdjustAttributeMain(MainMaxPSPField); break; case MainACRepeating: AdjustAttributeMain(MainACField); break; default: break; } break; case popSelectEvent: if (!curchar) { MainFormDoCommand(CharacterNew); return false; } switch (eventP->data.popSelect.controlID) { case MainCharacterPopTrigger: idx = eventP->data.popSelect.selection; OpenChar(idx); FrmGotoForm(MainForm); break; case MainWeaponPopTrigger: idx = eventP->data.popSelect.selection; prefs.curweaponidx = idx; ctl = GetObjectPtr(MainWeaponsList); label = LstGetSelectionText(ctl,idx); StrCopy(prefs.curweapon,label); break; case MainNumDicePopTrigger: prefs.numdice = eventP->data.popSelect.selection; break; case MainDicePopTrigger: prefs.sizesidx = eventP->data.popSelect.selection; break; } break; default: break; } return handled; } static Boolean MiscFormHandleEvent(EventPtr eventP) { Boolean handled = false; FormPtr frmP; int idx,pidx,i; VoidPtr ctl; switch (eventP->eType) { case menuEvent: return MainFormDoCommand(eventP->data.menu.itemID); case frmOpenEvent: frmP = FrmGetActiveForm(); MiscFormInit( frmP); FrmDrawForm ( frmP); handled = true; break; case frmCloseEvent: frmP = FrmGetActiveForm(); MiscFormClose( frmP); break; case ctlSelectEvent: switch (eventP->data.ctlSelect.controlID) { case MiscStatsPushButton: FrmGotoForm(MainForm); break; case MiscAbilitiesPushButton: FrmGotoForm(AbilitiesForm); break; case MiscEquipPushButton: FrmGotoForm(EquipForm); break; case MiscCharPushButton: FrmGotoForm(CharForm); break; case MiscNewButton: handled = true; FrmPopupForm(NewMiscForm); break; case MiscDeleteButton: RemoveFromMisc(prefs.miscdbhidx); FrmGotoForm(MiscForm); break; case MiscAddButton: editmode = 0; FrmGotoForm(EditListForm); break; case MiscReadyPushButton: prefs.miscaction = 0; break; case MiscEditPushButton: prefs.miscaction = 1; break; case MiscDeletePushButton: prefs.miscaction = 2; break; default: break; } break; case popSelectEvent: switch (eventP->data.popSelect.controlID) { case MiscAbilitiesPopTrigger: idx = eventP->data.popSelect.selection; pidx = eventP->data.popSelect.priorSelection; prefs.miscabilityidx = idx; SetAttributeDB(MiscAbilitiesField,offsetof(tCharacter,miscabilities[pidx])); SetAttribute(MiscAbilitiesField,curchar->miscabilities[idx]); ctl = GetObjectPtr(MiscAbilitiesField); FldEraseField(ctl); FldDrawField(ctl); break; case MiscSavingPopTrigger: idx = eventP->data.popSelect.selection; pidx = eventP->data.popSelect.priorSelection; prefs.miscsavingidx = idx; SetAttributeDB(MiscSavingField,offsetof(tCharacter,saving[pidx])); SetAttribute(MiscSavingField,curchar->saving[idx]); ctl = GetObjectPtr(MiscSavingField); FldEraseField(ctl); FldDrawField(ctl); break; case MiscCharacterPopTrigger: ctl = GetObjectPtr(MiscAbilitiesList); idx = LstGetSelection(ctl); if (idx != -1) SetAttributeDB(MiscAbilitiesField,offsetof(tCharacter,miscabilities[idx])); ctl = GetObjectPtr(MiscSavingList); idx = LstGetSelection(ctl); if (idx != -1) SetAttributeDB(MiscSavingField,offsetof(tCharacter,saving[idx])); idx = eventP->data.popSelect.selection; OpenChar(idx); FrmGotoForm(MiscForm); break; case MiscMiscPopTrigger: idx = eventP->data.popSelect.selection; if (idx > curchar->misccount) break; prefs.miscdbhidx = idx; OpenDBHandle(&(curchar->MiscDBH[prefs.miscdbhidx])); for (i=0;imisccount;i++) misclist[i] = curchar->miscnames[i]; ctl = GetObjectPtr(MiscMiscNamesList); LstSetListChoices(ctl,misclist,curchar->misccount); ctl = GetObjectPtr(MiscMiscList); LstSetListChoices(ctl,lastdbh->data->list,lastdbh->data->count); LstSetDrawFunction(ctl,(ListDrawDataFuncType *)DrawList); LstEraseList(ctl); LstDrawList(ctl); break; } break; case lstSelectEvent: if (eventP->data.lstSelect.listID != MiscMiscList) break; handled = true; idx = eventP->data.lstSelect.selection; ctl = GetObjectPtr(MiscReadyPushButton); if (CtlGetValue(ctl)) { ReadyItem(lastdbh,idx); } else { ctl = GetObjectPtr(MiscEditPushButton); if (CtlGetValue(ctl)) { EditItem(lastdbh,idx,0); } else { ctl = GetObjectPtr(MiscDeletePushButton); if (CtlGetValue(ctl)) { DeleteItem(lastdbh,idx); } } } ctl = GetObjectPtr(MiscMiscList); LstEraseList(ctl); LstDrawList(ctl); break; default: break; } return handled; } static Boolean AbilitiesFormHandleEvent(EventPtr eventP) { Boolean handled = false; FormPtr frmP; int idx; tDBHandle *dbh; VoidPtr ctl; switch (eventP->eType) { case menuEvent: return MainFormDoCommand(eventP->data.menu.itemID); case frmOpenEvent: frmP = FrmGetActiveForm(); AbilitiesFormInit( frmP); FrmDrawForm ( frmP); handled = true; break; case frmCloseEvent: frmP = FrmGetActiveForm(); AbilitiesFormClose( frmP); break; case ctlSelectEvent: switch (eventP->data.ctlSelect.controlID) { case AbilitiesStatsPushButton: FrmGotoForm(MainForm); break; case AbilitiesMiscPushButton: FrmGotoForm(MiscForm); break; case AbilitiesEquipPushButton: FrmGotoForm(EquipForm); break; case AbilitiesCharPushButton: FrmGotoForm(CharForm); break; case AbilitiesAddAbilityButton: editmode = 0; FrmGotoForm(EditListForm); break; case AbilitiesReadyPushButton: prefs.abilityaction = 0; break; case AbilitiesEditPushButton: prefs.abilityaction = 1; break; case AbilitiesDeletePushButton: prefs.abilityaction = 2; break; default: break; } break; case popSelectEvent: switch (eventP->data.popSelect.controlID) { case AbilitiesAbilityPopTrigger: idx = eventP->data.popSelect.selection; prefs.abilityidx = idx; switch (idx) { case 0: dbh = &(curchar->WProfsRecord); break; case 1: dbh = &(curchar->NWProfsRecord); break; case 2: dbh = &(curchar->PriestSpellRecord); break; case 3: dbh = &(curchar->MageSpellRecord); break; case 4: dbh = &(curchar->PsionicSpellRecord); break; default: break; } if (!dbh) break; OpenDBHandle(dbh); ctl = GetObjectPtr(AbilitiesAbilitiesList); LstSetListChoices(ctl,dbh->data->list,dbh->data->count); LstEraseList(ctl); LstDrawList(ctl); break; case AbilitiesCharacterPopTrigger: idx = eventP->data.popSelect.selection; OpenChar(idx); FrmGotoForm(AbilitiesForm); break; } break; case lstSelectEvent: if (eventP->data.lstSelect.listID != AbilitiesAbilitiesList) break; handled = true; idx = eventP->data.lstSelect.selection; ctl = GetObjectPtr(AbilitiesReadyPushButton); if (CtlGetValue(ctl)) { ReadyItem(lastdbh,idx); } else { ctl = GetObjectPtr(AbilitiesEditPushButton); if (CtlGetValue(ctl)) { EditItem(lastdbh,idx,0); } else { ctl = GetObjectPtr(AbilitiesDeletePushButton); if (CtlGetValue(ctl)) { DeleteItem(lastdbh,idx); } } } ctl = GetObjectPtr(AbilitiesAbilitiesList); LstEraseList(ctl); LstDrawList(ctl); break; default: break; } return handled; } static Boolean EquipFormHandleEvent(EventPtr eventP) { Boolean handled = false; FormPtr frmP; int idx; VoidPtr ctl; switch (eventP->eType) { case menuEvent: return MainFormDoCommand(eventP->data.menu.itemID); case frmOpenEvent: frmP = FrmGetActiveForm(); EquipFormInit( frmP); FrmDrawForm ( frmP); handled = true; break; case frmCloseEvent: frmP = FrmGetActiveForm(); EquipFormClose( frmP); break; case lstSelectEvent: if (eventP->data.lstSelect.listID != EquipEquipList) break; handled = true; idx = eventP->data.lstSelect.selection; ctl = GetObjectPtr(EquipReadyPushButton); if (CtlGetValue(ctl)) { ReadyItem(lastdbh,idx); } else { ctl = GetObjectPtr(EquipEditPushButton); if (CtlGetValue(ctl)) { EditItem(lastdbh,idx,1); } else { ctl = GetObjectPtr(EquipDeletePushButton); if (CtlGetValue(ctl)) { DeleteItem(lastdbh,idx); } } } ctl = GetObjectPtr(EquipEquipList); LstEraseList(ctl); LstDrawList(ctl); break; case ctlSelectEvent: switch (eventP->data.ctlSelect.controlID) { case EquipStatsPushButton: FrmGotoForm(MainForm); break; case EquipAbilitiesPushButton: FrmGotoForm(AbilitiesForm); break; case EquipMiscPushButton: FrmGotoForm(MiscForm); break; case EquipCharPushButton: FrmGotoForm(CharForm); break; case EquipAddItemButton: editmode = 0; edittypes = 1; FrmGotoForm(EditListForm); break; case EquipReadyPushButton: prefs.equipaction = 0; break; case EquipEditPushButton: prefs.equipaction = 1; break; case EquipDeletePushButton: prefs.equipaction = 2; break; default: break; } break; /* case ctlRepeatEvent: switch (eventP->data.ctlSelect.controlID) { case EquipPPRepeating: AdjustAttributeEquip(EquipPPField); break; case EquipGPRepeating: AdjustAttributeEquip(EquipGPField); break; case EquipEPRepeating: AdjustAttributeEquip(EquipEPField); break; case EquipSPRepeating: AdjustAttributeEquip(EquipSPField); break; case EquipCPRepeating: AdjustAttributeEquip(EquipCPField); break; case EquipXPRepeating: AdjustAttributeEquip(EquipXPField); break; } break; */ case popSelectEvent: switch (eventP->data.popSelect.controlID) { case EquipCharacterPopTrigger: idx = eventP->data.popSelect.selection; OpenChar(idx); FrmGotoForm(EquipForm); break; } break; default: break; } return handled; } static Boolean CharFormHandleEvent(EventPtr eventP) { Boolean handled = false; FormPtr frmP; int idx; VoidPtr ctl,ctl2; char *text; switch (eventP->eType) { case menuEvent: return MainFormDoCommand(eventP->data.menu.itemID); case frmOpenEvent: frmP = FrmGetActiveForm(); CharFormInit(frmP); FrmDrawForm (frmP); handled = true; break; case frmCloseEvent: frmP = FrmGetActiveForm(); CharFormClose(frmP); break; case ctlSelectEvent: switch (eventP->data.ctlSelect.controlID) { case CharStatsPushButton: FrmGotoForm(MainForm); break; case CharAbilitiesPushButton: FrmGotoForm(AbilitiesForm); break; case CharMiscPushButton: FrmGotoForm(MiscForm); break; case CharEquipPushButton: FrmGotoForm(EquipForm); break; case CharClass1PushButton: if (selclass != 0) UpdateClass(); selclass = 0; LoadClass(); break; case CharClass2PushButton: if (selclass != 1) UpdateClass(); selclass = 1; LoadClass(); break; case CharClass3PushButton: if (selclass != 2) UpdateClass(); selclass = 2; LoadClass(); break; case CharEditRaceButton: ctl = GetObjectPtr(CharRaceList); if (LstGetSelection(ctl) >= 7) { ctl = GetObjectPtr(CharRacePopTrigger); text = CtlGetLabel(ctl); CtlHideControl(ctl); ctl = GetObjectPtr(CharRaceField); SetAttributeString(CharRaceField,text); FldSetUsable(ctl,true); FldDrawField(ctl); // FldGrabFocus(ctl); frmP = FrmGetActiveForm(); FrmSetFocus(frmP,FrmGetObjectIndex(frmP,CharRaceField)); } break; case CharEditClassButton: ctl = GetObjectPtr(CharClassList); if (LstGetSelection(ctl) >= 11) { ctl = GetObjectPtr(CharClassPopTrigger); text = CtlGetLabel(ctl); CtlHideControl(ctl); ctl = GetObjectPtr(CharClassField); SetAttributeString(CharClassField,text); FldSetUsable(ctl,true); FldDrawField(ctl); // FldGrabFocus(ctl); frmP = FrmGetActiveForm(); FrmSetFocus(frmP,FrmGetObjectIndex(frmP,CharClassField)); } break; default: break; } break; case ctlRepeatEvent: switch (eventP->data.ctlSelect.controlID) { case CharPPRepeating: AdjustAttributeChar(CharPPField); break; case CharGPRepeating: AdjustAttributeChar(CharGPField); break; case CharEPRepeating: AdjustAttributeChar(CharEPField); break; case CharSPRepeating: AdjustAttributeChar(CharSPField); break; case CharCPRepeating: AdjustAttributeChar(CharCPField); break; case CharXPRepeating: AdjustAttributeChar(CharExpField); break; case CharLevelRepeating: AdjustAttributeChar(CharLevelField); break; } break; case popSelectEvent: switch (eventP->data.popSelect.controlID) { case CharCharacterPopTrigger: idx = eventP->data.popSelect.selection; OpenChar(idx); FrmGotoForm(CharForm); break; } break; case keyDownEvent: { ctl = GetObjectPtr(CharRaceField); if (((FieldPtr)ctl)->attr.hasFocus) { if (eventP->data.keyDown.chr == 10) { text = FldGetTextPtr(ctl); ctl2 = GetObjectPtr(CharRaceList); idx = LstGetSelection(ctl2); if (StrLen(text) > 14) { DmWrite(curchar,offsetof(tCharacter,erace[idx-7]),text,14); DmSet(curchar,offsetof(tCharacter,erace[idx-7])+14,1,0); } else { DmStrCopy(curchar,offsetof(tCharacter,erace[idx-7]),text); } erace[idx] = curchar->erace[idx-7]; FldReleaseFocus(ctl); FldEraseField(ctl); FldSetUsable(ctl,false); ctl2 = GetObjectPtr(CharRacePopTrigger); CtlSetLabel(ctl2,erace[idx]); CtlShowControl(ctl2); handled = true; } break; } ctl = GetObjectPtr(CharClassField); if (((FieldPtr)ctl)->attr.hasFocus) { if (eventP->data.keyDown.chr == 10) { text = FldGetTextPtr(ctl); ctl2 = GetObjectPtr(CharClassList); idx = LstGetSelection(ctl2); if (StrLen(text) > 14) { DmWrite(curchar,offsetof(tCharacter,eclass[idx-11]),text,14); DmSet(curchar,offsetof(tCharacter,eclass[idx-11])+14,1,0); } else { DmStrCopy(curchar,offsetof(tCharacter,eclass[idx-11]),text); } eclass[idx] = curchar->eclass[idx-11]; FldReleaseFocus(ctl); FldEraseField(ctl); FldSetUsable(ctl,false); ctl2 = GetObjectPtr(CharClassPopTrigger); CtlSetLabel(ctl2,eclass[idx]); CtlShowControl(ctl2); handled = true; } break; } break; } default: break; } return handled; } static Boolean EditFormDoCommand(Word command) { Boolean handled = false; VoidPtr ctl; switch (command) { case EditCut: handled = true; ctl = GetObjectPtr(EditListItemField); FldCut(ctl); break; case EditCopy: handled = true; ctl = GetObjectPtr(EditListItemField); FldCopy(ctl); break; case EditPaste: handled = true; ctl = GetObjectPtr(EditListItemField); FldPaste(ctl); break; default: break; } return handled; } static Boolean EditListFormHandleEvent(EventPtr eventP) { Boolean handled = false; FormPtr frmP; VoidPtr ctl; Byte b; int idx; switch (eventP->eType) { case menuEvent: return EditFormDoCommand(eventP->data.menu.itemID); case frmOpenEvent: frmP = FrmGetActiveForm(); EditListFormInit( frmP); FrmDrawForm ( frmP); FrmSetFocus(frmP,FrmGetObjectIndex(frmP,EditListItemField)); handled = true; break; case ctlSelectEvent: switch (eventP->data.ctlSelect.controlID) { case EditListOKButton: ctl = GetObjectPtr(EditListItemField); if (FldGetTextPtr(ctl)) { b = 0; if (edittypes) { ctl = GetObjectPtr(EditListTypeList); idx = LstGetSelection(ctl); if (idx != -1) b = (Byte)idx; } ctl = GetObjectPtr(EditListItemField); if (!editmode) AddToList(lastdbh,FldGetTextPtr(ctl),b); else { DeleteItem(lastdbh,lastidx); if (lastidx >= lastdbh->data->count) AddToList(lastdbh,FldGetTextPtr(ctl),b); else InsertItem(lastdbh,lastidx,FldGetTextPtr(ctl),b); } } FrmGotoForm(lastform); break; case EditListCancelButton: FrmGotoForm(lastform); break; case EditListPageUpButton: ctl = GetObjectPtr(EditListItemField); FldScrollField(ctl,9,up); break; case EditListPageDownButton: ctl = GetObjectPtr(EditListItemField); FldScrollField(ctl,9,down); break; case EditListLineUpButton: ctl = GetObjectPtr(EditListItemField); FldScrollField(ctl,1,up); break; case EditListLineDownButton: ctl = GetObjectPtr(EditListItemField); FldScrollField(ctl,1,down); break; default: break; } break; default: break; } return handled; } static Boolean NewCharFormHandleEvent(EventPtr eventP) { Boolean handled = false; FormPtr frmP; VoidPtr ctl; char *text; switch (eventP->eType) { case menuEvent: handled = true; break; case frmOpenEvent: frmP = FrmGetActiveForm(); FrmDrawForm ( frmP); FrmSetFocus(frmP,FrmGetObjectIndex(frmP,NewCharNameField)); handled = true; break; case ctlSelectEvent: switch (eventP->data.ctlSelect.controlID) { case NewCharOKButton: ctl = GetObjectPtr(NewCharNameField); text = FldGetTextPtr(ctl); if (text) AddCharacter(text); FrmReturnToForm(MainForm); UpdateScreen(); break; case NewCharCancelButton: FrmReturnToForm(MainForm); break; default: break; } break; default: break; } return handled; } static Boolean NewMiscFormHandleEvent(EventPtr eventP) { Boolean handled = false; FormPtr frmP; VoidPtr ctl; char *text; switch (eventP->eType) { case menuEvent: handled = true; break; case frmOpenEvent: frmP = FrmGetActiveForm(); FrmDrawForm ( frmP); FrmSetFocus(frmP,FrmGetObjectIndex(frmP,NewMiscNameField)); handled = true; break; case ctlSelectEvent: switch (eventP->data.ctlSelect.controlID) { case NewMiscOKButton: ctl = GetObjectPtr(NewMiscNameField); text = FldGetTextPtr(ctl); if (text) { AddToMisc(text); FrmReturnToForm(MiscForm); UpdateScreen(); } else FrmReturnToForm(MiscForm); break; case NewMiscCancelButton: FrmReturnToForm(MiscForm); break; default: break; } break; default: break; } return handled; } /*********************************************************************** * * FUNCTION: AppHandleEvent * * DESCRIPTION: This routine loads form resources and set the event * handler for the form loaded. * * PARAMETERS: event - a pointer to an EventType structure * * RETURNED: true if the event has handle and should not be passed * to a higher level handler. * * REVISION HISTORY: * * ***********************************************************************/ static Boolean AppHandleEvent( EventPtr eventP) { Word formId; FormPtr frmP; if (eventP->eType == frmLoadEvent) { // Load the form resource. formId = eventP->data.frmLoad.formID; frmP = FrmInitForm(formId); FrmSetActiveForm(frmP); // Set the event handler for the form. The handler of the currently // active form is called by FrmHandleEvent each time is receives an // event. switch (formId) { case MainForm: FrmSetEventHandler(frmP, MainFormHandleEvent); break; case MiscForm: FrmSetEventHandler(frmP, MiscFormHandleEvent); break; case AbilitiesForm: FrmSetEventHandler(frmP, AbilitiesFormHandleEvent); break; case EquipForm: FrmSetEventHandler(frmP, EquipFormHandleEvent); break; case CharForm: FrmSetEventHandler(frmP, CharFormHandleEvent); break; case NewCharForm: FrmSetEventHandler(frmP, NewCharFormHandleEvent); break; case EditListForm: FrmSetEventHandler(frmP, EditListFormHandleEvent); break; case NewMiscForm: FrmSetEventHandler(frmP, NewMiscFormHandleEvent); break; default: // ErrFatalDisplay("Invalid Form Load Event"); break; } return true; } return false; } /*********************************************************************** * * FUNCTION: AppEventLoop * * DESCRIPTION: This routine is the event loop for the application. * * PARAMETERS: nothing * * RETURNED: nothing * * REVISION HISTORY: * * ***********************************************************************/ static void AppEventLoop(void) { Word error; EventType event; do { EvtGetEvent(&event, evtWaitForever); if (! SysHandleEvent(&event)) if (! MenuHandleEvent(0, &event, &error)) if (! AppHandleEvent(&event)) FrmDispatchEvent(&event); } while (event.eType != appStopEvent); } static void UpgradeVersion() { UInt rec; LocalID lid; UInt version; int i; ULong size; VoidHand hand; DmOpenDatabaseInfo(dbref,&lid,0,0,&rec,0); version = VERSION; DmSetDatabaseInfo(rec,lid,0,0,&version,0,0,0,0,0,0,0,0); for (i=0;icount;i++) { GetChar(i); size = MemPtrSize(curchar); CloseChar(i); hand = DmResizeRecord(dbref,dbhdr->data[i].rec,sizeof(tCharacter)); curchar = MemHandleLock(hand); DmSet(curchar,size,(ULong)sizeof(tCharacter)-size,0); MemHandleUnlock(hand); DmReleaseRecord(dbref,dbhdr->data[i].rec,true); } curchar = 0; } /*********************************************************************** * * FUNCTION: AppStart * * DESCRIPTION: Get the current application's preferences. * * PARAMETERS: nothing * * RETURNED: Err value 0 if nothing went wrong * * REVISION HISTORY: * * ***********************************************************************/ static Err AppStart(void) { UInt rec,i,version; Word prefsSize; LocalID lid; Err err; // Read the saved preferences / saved-state information. prefsSize = sizeof(StarterPreferenceType); MemSet(&prefs,prefsSize,0); // if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != // noPreferenceFound) { if (!PrefGetAppPreferencesV10(appFileCreator,appPrefVersionNum,&prefs,sizeof(tPrefsV2))) if (!PrefGetAppPreferencesV10(appFileCreator,1,&prefs,sizeof(tPrefsV1))) prefs.characteridx = -1; dbid = DmFindDatabase(0,dbname); if (!dbid) { err = DmCreateDatabase(0,dbname,'Kent','Data',false); ErrFatalDisplayIf(err,"Could not create database"); dbid = DmFindDatabase(0,dbname); ErrFatalDisplayIf(!dbid,"Could not load dataase"); dbref = DmOpenDatabase(0,dbid,dmModeReadWrite); DmOpenDatabaseInfo(dbref,&lid,0,0,&rec,0); i = dmHdrAttrBackup; version = VERSION; DmSetDatabaseInfo(rec,lid,0,&i,&version,(void *)0,(void *)0,(void *)0,(void *)0,(void *)0,(void *)0,(void *)0,(void *)0); rec = 0; dbhdrhand = DmNewRecord(dbref,&rec,(ULong)(sizeof(tDBHeader))); ErrFatalDisplayIf(!dbhdrhand,"Could not create record"); dbhdr = MemHandleLock(dbhdrhand); DmSet(dbhdr,0,(ULong)sizeof(tDBHeader),0); rec = 10; DmWrite(dbhdr,(ULong)&(dbhdr->max)-(ULong)dbhdr,&rec,sizeof(UInt)); dbhdrdirty = true; prefs.characteridx = -1; } else { dbref = DmOpenDatabase(0,dbid,dmModeReadWrite); rec = 0; dbhdrhand = DmGetRecord(dbref,rec); dbhdr = MemHandleLock(dbhdrhand); DmOpenDatabaseInfo(dbref,&lid,0,0,&rec,0); DmDatabaseInfo(rec,lid,0,0,&version,0,0,0,0,0,0,0,0); switch (version) { case 0: UpgradeVersion(); break; case 1: UpgradeVersion(); break; case 2: break; default: break; } if (prefs.characteridx == -1 && dbhdr->count > 0) prefs.characteridx = 0; if (prefs.characteridx != -1) OpenChar(prefs.characteridx); for (i=0;icount;i++) { names[i] = dbhdr->data[i].name; } } return 0; } /*********************************************************************** * * FUNCTION: AppStop * * DESCRIPTION: Save the current state of the application. * * PARAMETERS: nothing * * RETURNED: nothing * * REVISION HISTORY: * * ***********************************************************************/ static void AppStop(void) { CloseDBHandle(lastdbh); FrmCloseAllForms(); // Write the saved preferences / saved-state information. This data // will be backed up during a HotSync. // PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, // &prefs, sizeof (prefs), true); PrefSetAppPreferencesV10(appFileCreator,appPrefVersionNum,&prefs,sizeof(prefs)); if (curchar) { MemHandleUnlock(curcharhand); DmReleaseRecord(dbref,dbhdr->data[prefs.characteridx].rec,true); } if (dbhdr) { MemHandleUnlock(dbhdrhand); DmReleaseRecord(dbref,0,dbhdrdirty); dbhdrhand = 0; dbhdr = (void *)0; } DmCloseDatabase(dbref); } /*********************************************************************** * * FUNCTION: StarterPilotMain * * DESCRIPTION: This is the main entry point for the application. * PARAMETERS: cmd - word value specifying the launch code. * cmdPB - pointer to a structure that is associated with the launch code. * launchFlags - word value providing extra information about the launch. * * RETURNED: Result of launch * * REVISION HISTORY: * * ***********************************************************************/ static DWord StarterPilotMain(Word cmd, Ptr cmdPBP, Word launchFlags) { Err error; error = RomVersionCompatible (version10, launchFlags); if (error) return (error); switch (cmd) { case sysAppLaunchCmdNormalLaunch: error = AppStart(); if (error) return error; FrmGotoForm(MainForm); AppEventLoop(); AppStop(); break; default: break; } return 0; } /*********************************************************************** * * FUNCTION: PilotMain * * DESCRIPTION: This is the main entry point for the application. * * PARAMETERS: cmd - word value specifying the launch code. * cmdPB - pointer to a structure that is associated with the launch code. * launchFlags - word value providing extra information about the launch. * RETURNED: Result of launch * * REVISION HISTORY: * * ***********************************************************************/ DWord PilotMain( Word cmd, Ptr cmdPBP, Word launchFlags) { return StarterPilotMain(cmd, cmdPBP, launchFlags); }