home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-09-05 | 13.6 KB | 544 lines | [TEXT/KAHL] |
- // cheat.c
- // an excuse for a filename
-
- #include <string.h>
- #include <pascal.h>
- #include "main.h"
- #include "cheatWindow.h"
- #include "ResRefs.h"
- #include "cheat.h"
- #include "error.h"
- #include "cheatwich.h"
- #include "cheatfile.h"
-
- shortcut wichcuts[kmaxwichcuts];
- int numwichcuts = 0;
-
- // test if a char is fit to be processed by the TEManager
- int numbKey(char c) // a numb key is defined by not having feelings
- // (boy am I witty)
- {
- int res = false, i;
- char *valid = " 0123456789.-";
-
- valid[0] = (char) 8; // delete, I think
- for (i=0;valid[i];i++)
- res |= (c == valid[i]);
- return res;
- }
-
-
- // pop up a simple alert with given string as the text, one okay button
- void stdmessage(Str255 s)
- {
- ParamText(s, "\p", "\p", "\p");
- (void) Alert(rmessagealrt, nil);
- }
-
-
- // converts the text in the TE field to a longint
- long HandToLong(TEHandle h)
- {
- Str255 str;
- long l;
- int i;
-
- str[0] = (char) (**h).teLength;
- for (i=1;i<=str[0], i<200;i++)
- str[i] = ((*((char **) (**h).hText))[i-1]);
- StringToNum(str, &l);
- return l;
- }
-
- // moves the text in the TE into scratch
- static void HandToScratch(TEHandle h)
- {
- int i;
- for (i=0;i<256;i++)
- scratch[i] = ((*((char **) (**h).hText))[i]);
- scratch[i] = 0;
- if ((**h).teLength < 256)
- scratch[(**h).teLength] = 0;
- }
-
- // when the user hits a key, let's do some shit
- void HandleKey(char c)
- {
- float diff;
- int i;
-
- if (numbKey(c)) {
- }
- }
-
-
- // the user hit the search button, so let's do it
- void searchButtonHit(void)
- {
- Cell cell = {0, 0};
- int *pint, findint, temp;
- void *p;
- long endsearch, findlong, newposs, *plong, l, startsearch;
- Str255 str;
- Boolean isbolo;
-
- // get the number to search for from the text field
- GetIText(ditem[riSearchNum], str);
- StringToNum(str, &findlong);
- findint = findlong;
-
- if (LGetSelect(true, &cell, plist)) { // must have selected an app
- isbolo = *((long *) ((long) InfoRec[cell.v].processName + 1)) == 'Bolo';
-
- if (isbolo)
- gcurposs = 0;
- else {
- p = (void *) ((long) InfoRec[cell.v].processLocation + InfoRec[cell.v].processSize);
- startsearch = (long) p;
- if (!gcurposs) { // starting a new search
- // p is start of search, at the largest location in that app's partition
- endsearch = (long) InfoRec[cell.v].processLocation;
- pint = (int *) p; plong = (long *) p;
-
- switch (gvalsize) {
- case ksizelong:
- while ((long) plong >= endsearch) {
- plong = (long *) ((long) plong - 2); // only decrement two bytes
- if (*plong == findlong) { // we've found a possibility
- gposs[gcurposs++] = (Ptr) plong; // store it
- if (gcurposs>=gmaxposs) // too many values
- plong = (void *) (endsearch-4); // this will kill the search
- }
- }
- break;
- case ksizeint:
- while ((long) pint >= endsearch)
- if (*--pint == findint) { // we've found a possibility
- gposs[gcurposs++] = (Ptr) pint; // store it
- if (gcurposs>=gmaxposs) // too many values
- pint = (void *) (endsearch-4); // this will kill the search
- }
- break;
- case ksizebyte:
- while ((long) pint >= endsearch) {
- pint--;
- // first look at high-order byte
- temp = (*pint) >> 8;
- if (temp == findint) { // we've found a possibility
- gposs[gcurposs++] = (Ptr) pint; // store it
- if (gcurposs>=gmaxposs) // too many values
- pint = (void *) (endsearch-4); // this will kill the search
- }
- // now look at low-order byte
- temp = (*pint) & 0xFF;
- if (temp == findint) { // we've found a possibility
- gposs[gcurposs++] = (Ptr) ((long) pint + 1); // store it
- if (gcurposs>=gmaxposs) // too many values
- pint = (void *) (endsearch-4); // this will kill the search
- }
- }
- break;
- default: break;
- }
- }
- else { // refining a search
- newposs = 0;
- switch (gvalsize) {
- case ksizelong: // we're dealing in longints
- for (l=0;l<gcurposs;l++)
- if (*((long *)gposs[l]) == findlong)
- gposs[newposs++] = gposs[l];
- break;
- case ksizeint: // we're dealing in integers
- for (l=0;l<gcurposs;l++)
- if (*((int *)gposs[l]) == findint)
- gposs[newposs++] = gposs[l];
- break;
- case ksizebyte: // we're dealing in bytes
- for (l=0;l<gcurposs;l++)
- if ((long) gposs[l] & 1) { // some are odd
- // extract low order byte
- if ((*((int *)((long) gposs[l] - 1)) & 0xFF) == findint)
- gposs[newposs++] = gposs[l];
- }
- else if ((*((int *)gposs[l]) >> 8) == findint)
- gposs[newposs++] = gposs[l];
- break;
- default: break;
- }
- gcurposs = newposs;
- }
- }
-
- // change the text field of the possibilities item
- NumToString(gcurposs, str);
- SetIText(ditem[riPossibilities], str);
- // change the text field of the offset item
- goffset = startsearch - (long) gposs[0];
- if (gcurposs)
- NumToString(goffset, str);
- else
- str[0] = 0; // empty string
- SetIText(ditem[riOffset], str);
- }
- DrawFoundPic(); // might have narrowed, etc
- fixshortbuttz();
- }
-
-
- // called when user switches apps or hits Start Over button
- void doStartOver(void)
- {
- Str255 str = "\p0";
-
- SetIText(ditem[riPossibilities], str);
- // SetIText(ditem[riSearchNum], str);
- gcurposs = 0;
-
- // clear the offset text
- str[0] = 0;
- SetIText(ditem[riOffset], str);
- goffset = 0;
-
- DrawFoundPic(); // definitely clouds
- fixshortbuttz();
- }
-
-
- // called when user selects the size of what they're searching for
- void doSizeChange(short item)
- {
- Str255 str = "\p0";
-
- setSearchSize(item - riSizeLong);
- // we unfortunately must reset some things, but not everything
- SetIText(ditem[riPossibilities], str);
- gcurposs = 0;
-
- // clear the offset text
- str[0] = 0;
- SetIText(ditem[riOffset], str);
- goffset = 0;
-
- DrawFoundPic(); // definitely clouds
- fixshortbuttz();
- }
-
-
- // called when user selects how they want to find the process
- void doRuptOrSelect(short item)
- {
- int delta = item - riSelecting;
- Cell cell = {0, 0};
-
- if (ghowfind == delta)
- return; // no need
-
- setFindGameBy(delta);
- if (delta)
- installTMTask();
- else
- removeTMTask();
- if (LGetSelect(true, &cell, plist))
- LSetSelect(false, cell, plist);
- }
-
-
- // called when a user hits the change button
- void doChange(void)
- {
- Cell cell = {0, 0};
- Str255 str;
- long l;
- int changeto, *ip, temp;
- short res;
-
- if (goffset == 0) {
- stdmessage("\pError: offset of 0 cannot be valid");
- return;
- }
- if (LGetSelect(true, &cell, plist)) { // must have selected an app
- if (gcurposs>1) { // they have more than one piece of data they want to change
- res = Alert(rYouSureAlrt, 0); // ask them
- if (res != 1)
- return; // their mistake
- }
- GetIText(ditem[riNewValue], str);
- StringToNum(str, &l);
- changeto = l;
- switch (gvalsize) {
- case ksizelong: // we're dealing in longints
- *((long *) gposs[0]) = l; // set the place in memory!
- break;
- case ksizeint: // we're dealing in integers
- if (l > 65535) {
- stdmessage("\pError: Change To value is too large for integer.");
- return;
- }
- *((int *) gposs[0]) = changeto; // set the place in memory!
- break;
- case ksizebyte:
- if (l > 255) {
- stdmessage("\pError: Change To value is too large for byte.");
- return;
- }
- if ((long) gposs[0] & 1) { // odd address
- ip = (int *) ((long) gposs[0] - 1); // set at word right before byte
- // change the low-order byte of this word to what we want
- temp = (((*ip) >> 8) << 8) + (changeto & 0xFF);
- *ip = temp; // set it in memory
- }
- else {
- ip = (int *) gposs[0]; // treat as word pointer
- // change the high-order byte of this word to what we want
- temp = (((*ip) << 8) >> 8) + ((changeto & 0xFF) << 8);
- *ip = temp; // set it in memory
- }
- break;
- default: verify(false); break;
- }
- }
- }
-
-
- // user clicks on Add button in Cheat Sheet
- void doAddCheat(void)
- {
- shortcut newcut;
- Str255 s;
- long l;
- short id;
- Cell cell, well = {0, 0};
- Handle h;
-
- if (!gcurposs) {
- stdmessage("\pSorry, you haven't located a cheat yet.");
- return;
- }
- // if (!LGetSelect(true, &well, plist)) { // find selected app
- // stdmessage("\pYou must have a game selected when adding a cheat.");
- // return;
- // }
- // fill fields of the struct w/ appropriate values
- // damn, I should be reading Plato right now
- GetIText(ditem[riTitle], newcut.title);
- if (!newcut.title[0]) {
- stdmessage("\pYou must enter a title before adding a cheat.");
- return;
- }
- if (goffset>150000)
- stdmessage("\pWarning: value saved is reasonably likely to move about, thus saved position may not work again.");
- GetIText(ditem[riComment], newcut.comment);
- GetIText(ditem[riNewValue], s);
- StringToNum(s, &newcut.newval);
- newcut.datasize = gvalsize;
- if (LGetSelect(true, &well, plist)) {
- l = (long) InfoRec[well.v].processLocation + InfoRec[well.v].processSize;
- newcut.offset = l - (long) gposs[0];
- }
- else
- newcut.offset = goffset;
-
- // try to grow our records
- SetHandleSize((Handle) cut, sizeof(shortcut) * (gnumcuts + 1));
- if (MemError()) {
- stdmessage("\pSorry, there is not enough memory allocated to remember this cheat.");
- return;
- }
- HLock((Handle) cut);
- (*cut)[gnumcuts] = newcut;
- HUnlock((Handle) cut);
-
-
- // add a cell in the list
- cell.v = LAddRow(1, -1, slist);
- cell.h = 0;
- LSetCell((Ptr) &newcut.title[1], newcut.title[0], cell, slist);
-
- gnumcuts++;
-
- // add the resource to our file
- h = NewHandle(sizeof(shortcut));
- verify(h);
- HLock(h);
- **((shortcut **) h) = newcut;
- HUnlock(h);
- id = Unique1ID(kcheatsheettype);
- AddResource(h, kcheatsheettype, id, newcut.title);
- if (ResError())
- stdmessage("\pI was unable to save this cheat.");
- else {
- WriteResource(h);
- ReleaseResource(h);
- }
- // DisposHandle(h);
- }
-
-
- // save the shortcuts that were saved into ram during the last cheatwich
- void addwichcuts (void)
- {
- shortcut newcut;
- Str255 s;
- long l;
- short id;
- Cell cell, well = {0, 0};
- Handle h;
- int i;
-
- for (i=0;i<numwichcuts;i++) {
- newcut = wichcuts[i];
- verify(cut);
- SetHandleSize((Handle) cut, sizeof(shortcut) * (gnumcuts + 1));
- if (MemError()) {
- stdmessage("\pSorry, there is not enough memory allocated to remember this cheat.");
- return;
- }
- HLock((Handle) cut);
- (*cut)[gnumcuts] = newcut;
- HUnlock((Handle) cut);
-
- // add a cell in the list
- cell.v = LAddRow(1, -1, slist);
- cell.h = 0;
- LSetCell((Ptr) &newcut.title[1], newcut.title[0], cell, slist);
-
- gnumcuts++;
-
- // add the resource to our file
- h = NewHandle(sizeof(shortcut));
- verify(h);
- HLock(h);
- **((shortcut **) h) = newcut;
- HUnlock(h);
- id = Unique1ID(kcheatsheettype);
- AddResource(h, kcheatsheettype, id, newcut.title);
- if (ResError())
- stdmessage("\pI was unable to save this cheat.");
- else {
- WriteResource(h);
- ReleaseResource(h);
- }
- }
-
- numwichcuts = 0;
- }
-
- // called when a user hits the open cheat button or double clicks on a cell
- void doOpenCheat(void)
- {
- Cell cell = {0, 0}, well = {0, 0};
- Str255 str;
- long l;
- short res;
-
- if (!LGetSelect(true, &well, plist)) {
- stdmessage("\pYou must have a game selected before opening a cheat.");
- return;
- }
- if (LGetSelect(true, &cell, slist)) { // must have selected a shortcut
- HLock((Handle) cut);
-
- // we want to transfer data to the main window, etc.
- gcurposs = 1;
- NumToString(gcurposs, str);
- SetIText(ditem[riPossibilities], str);
- gposs[0] = (Ptr) ((long) InfoRec[well.v].processLocation +
- InfoRec[well.v].processSize - (*cut)[cell.v].offset);
- goffset = (*cut)[cell.v].offset;
- NumToString(goffset, str);
- SetIText(ditem[riOffset], str);
- NumToString((*cut)[cell.v].newval, str);
- SetIText(ditem[riNewValue], str);
- verify((*cut)[cell.v].datasize >=0 && (*cut)[cell.v].datasize <= 2);
- setSearchSize((*cut)[cell.v].datasize);
- SetIText(ditem[riTitle], (*cut)[cell.v].title);
- SetIText(ditem[riComment], (*cut)[cell.v].comment);
-
- HUnlock((Handle) cut);
-
- DrawFoundPic(); // might change
- fixshortbuttz();
- }
- }
-
- // return the length of the selection (in cells) of the slist
- static int selength(void)
- {
- Cell cell = {0, 0};
- int count = 1;
-
- if (!LGetSelect(true, &cell, slist))
- return 0;
- cell.v++;
- while (LGetSelect(false, &cell, slist)) {
- count++;
- cell.v++;
- }
- return count;
- }
-
- // user clicks on Remove button in Cheat Sheet
- void doRemoveCheat(void)
- {
- shortcut newcut;
- Str255 s;
- long l;
- short i, woop;
- Cell cell = {0, 0};
- Handle h;
- int sels = selength();
-
- if (!LGetSelect(true, &cell, slist)) { // find selected app
- stdmessage("\pYou must have a cheat selected.");
- return;
- }
-
- HLock((Handle) cut);
-
- for (woop=0; woop < sels; woop++) {
- LDelRow(1, cell.v, slist); // remove from list
- // remove from resource fork
- h = Get1NamedResource(kcheatsheettype, (*cut)[cell.v].title);
- if (h)
- RmveResource(h);
- if (ResError())
- stdmessage("\pAn error occurred, and I was unable to remove this cheat from the file.");
-
- // slide information down
- for (i = cell.v; i + 1 < gnumcuts; i++)
- (*cut)[i] = (*cut)[i+1];
- }
-
- HUnlock((Handle) cut);
- gnumcuts--;
- }
-
- void doExportShortcut(int how)
- {
- Cell cell = {0, 0};
-
- if (!LGetSelect(true, &cell, slist)) {
- stdmessage("\pYou must have a game selected before opening a cheat.");
- return;
- }
- if (LGetSelect(true, &cell, slist)) { // must have selected a shortcut
- HLock((Handle) cut);
- doSaveFile(how, &((*cut)[cell.v]), selength());
- HUnlock((Handle) cut);
- }
- }
-
- extern int wegotfile; // from cheatfile
-
- void fixshortbuttz(void)
- {
- int sels = selength();
-
- HiliteControl((ControlHandle) sitem[riExportNew], sels ? 0 : 255);
- HiliteControl((ControlHandle) sitem[riAppendToOld], (sels&&wegotfile) ? 0 : 255);
- HiliteControl((ControlHandle) sitem[riExportAppend], sels ? 0 : 255);
- HiliteControl((ControlHandle) sitem[riOpenCheat], (sels == 1) ? 0 : 255);
- HiliteControl((ControlHandle) sitem[riRemoveCheat], sels ? 0 : 255);
- HiliteControl((ControlHandle) sitem[riAddCheat], goffset ? 0 : 255);
- }