static int isowavParseCueFile() { TCHAR szLine[1024]; TCHAR szFile[1024]; TCHAR* s; TCHAR* t; FILE* h; int track = 0; int length; isowavTOC->FirstTrack = 1; isowavTOC->LastTrack = 1; isowavTOC->TrackData[0].Address[1] = 0; isowavTOC->TrackData[0].Address[2] = 2; isowavTOC->TrackData[0].Address[3] = 0; h = _tfopen(CDEmuImage, _T("rt")); if (h == NULL) { return 1; } while (1) { if (_fgetts(szLine, sizeof(szLine), h) == NULL) { break; } length = _tcslen(szLine); // get rid of the linefeed at the end while (length && (szLine[length - 1] == _T('\r') || szLine[length - 1] == _T('\n'))) { szLine[length - 1] = 0; length--; } s = szLine; // file info if ((t = LabelCheck(s, _T("FILE"))) != 0) { s = t; TCHAR* szQuote; // read filename QuoteRead(&szQuote, NULL, s); _sntprintf(szFile, ExtractFilename(CDEmuImage) - CDEmuImage, _T("%s"), CDEmuImage); _sntprintf(szFile + (ExtractFilename(CDEmuImage) - CDEmuImage), 1024 - (ExtractFilename(CDEmuImage) - CDEmuImage), _T("/%s"), szQuote); continue; } // track info if ((t = LabelCheck(s, _T("TRACK"))) != 0) { s = t; // track number track = _tcstol(s, &t, 10); if (track < 1 || track > MAXIMUM_NUMBER_TRACKS) { fclose(h); return 1; } if (track < isowavTOC->FirstTrack) { isowavTOC->FirstTrack = track; } if (track > isowavTOC->LastTrack) { isowavTOC->LastTrack = track; } isowavTOC->TrackData[track - 1].TrackNumber = track; isowavTOC->TrackData[track - 1].Filename = (TCHAR*)malloc((_tcslen(szFile) + 1) * sizeof(TCHAR)); if (isowavTOC->TrackData[track - 1].Filename == NULL) { fclose(h); return 1; } _tcscpy(isowavTOC->TrackData[track - 1].Filename, szFile); s = t; // type of track if ((t = LabelCheck(s, _T("MODE1/2048"))) != 0) { isowavTOC->TrackData[track - 1].Control = 4; continue; } if ((t = LabelCheck(s, _T("AUDIO"))) != 0) { isowavTOC->TrackData[track - 1].Control = 0; continue; } fclose(h); return 1; } // pregap if ((t = LabelCheck(s, _T("PREGAP"))) != 0) { s = t; int M, S, F; // pregap M M = _tcstol(s, &t, 10); s = t + 1; // pregap S S = _tcstol(s, &t, 10); s = t + 1; // pregap F F = _tcstol(s, &t, 10); if (M < 0 || M > 100 || S < 0 || S > 59 || F < 0 || F > 74) { fclose(h); return 1; } isowavTOC->TrackData[track - 1].Address[1] = M; isowavTOC->TrackData[track - 1].Address[2] = S; isowavTOC->TrackData[track - 1].Address[3] = F; continue; } } fclose(h); return isowavGetTrackSizes(); }
static int ConfigParseFile(TCHAR* pszFilename) { #define INSIDE_NOTHING (0xFFFF & (1 << ((sizeof(TCHAR) * 8) - 1))) TCHAR szLine[1024]; TCHAR* s; TCHAR* t; int nLen; int nLine = 0; TCHAR nInside = INSIDE_NOTHING; CheatInfo* pCurrentCheat = NULL; FILE* h = _tfopen(pszFilename, _T("rt")); if (h == NULL) { return 1; } while (1) { if (_fgetts(szLine, sizeof(szLine), h) == NULL) { break; } nLine++; nLen = _tcslen(szLine); // Get rid of the linefeed at the end while (szLine[nLen - 1] == 0x0A || szLine[nLen - 1] == 0x0D) { szLine[nLen - 1] = 0; nLen--; } s = szLine; // Start parsing if (s[0] == _T('/') && s[1] == _T('/')) { // Comment continue; } if ((t = LabelCheck(s, _T("include"))) != 0) { // Include a file s = t; TCHAR szFilename[MAX_PATH] = _T(""); // Read name of the cheat file TCHAR* szQuote = NULL; QuoteRead(&szQuote, NULL, s); _stprintf(szFilename, _T("%s%s.dat"), szAppCheatsPath, szQuote); if (ConfigParseFile(szFilename)) { _stprintf(szFilename, _T("%s%s.ini"), szAppCheatsPath, szQuote); if (ConfigParseFile(szFilename)) { CheatError(pszFilename, nLine, NULL, _T("included file doesn't exist"), szLine); } } continue; } if ((t = LabelCheck(s, _T("cheat"))) != 0) { // Add new cheat s = t; // Read cheat name TCHAR* szQuote = NULL; TCHAR* szEnd = NULL; QuoteRead(&szQuote, &szEnd, s); s = szEnd; if ((t = LabelCheck(s, _T("advanced"))) != 0) { // Advanced cheat s = t; } SKIP_WS(s); if (nInside == _T('{')) { CheatError(pszFilename, nLine, pCurrentCheat, _T("missing closing bracket"), NULL); break; } #if 0 if (*s != _T('\0') && *s != _T('{')) { CheatError(pszFilename, nLine, NULL, _T("malformed cheat declaration"), szLine); break; } #endif nInside = *s; // Link new node into the list CheatInfo* pPreviousCheat = pCurrentCheat; pCurrentCheat = (CheatInfo*)malloc(sizeof(CheatInfo)); if (pCheatInfo == NULL) { pCheatInfo = pCurrentCheat; } memset(pCurrentCheat, 0, sizeof(CheatInfo)); pCurrentCheat->pPrevious = pPreviousCheat; if (pPreviousCheat) { pPreviousCheat->pNext = pCurrentCheat; } // Fill in defaults pCurrentCheat->nType = 0; // Default to cheat type 0 (apply each frame) pCurrentCheat->nStatus = -1; // Disable cheat memcpy(pCurrentCheat->szCheatName, szQuote, QUOTE_MAX); continue; } if ((t = LabelCheck(s, _T("type"))) != 0) { // Cheat type if (nInside == INSIDE_NOTHING || pCurrentCheat == NULL) { CheatError(pszFilename, nLine, pCurrentCheat, _T("rogue cheat type"), szLine); break; } s = t; // Set type pCurrentCheat->nType = _tcstol(s, NULL, 0); continue; } if ((t = LabelCheck(s, _T("default"))) != 0) { // Default option if (nInside == INSIDE_NOTHING || pCurrentCheat == NULL) { CheatError(pszFilename, nLine, pCurrentCheat, _T("rogue default"), szLine); break; } s = t; // Set default option pCurrentCheat->nDefault = _tcstol(s, NULL, 0); continue; } int n = _tcstol(s, &t, 0); if (t != s) { // New option if (nInside == INSIDE_NOTHING || pCurrentCheat == NULL) { CheatError(pszFilename, nLine, pCurrentCheat, _T("rogue option"), szLine); break; } // Link a new Option structure to the cheat if (n < CHEAT_MAX_OPTIONS) { s = t; // Read option name TCHAR* szQuote = NULL; TCHAR* szEnd = NULL; if (QuoteRead(&szQuote, &szEnd, s)) { CheatError(pszFilename, nLine, pCurrentCheat, _T("option name omitted"), szLine); break; } s = szEnd; if (pCurrentCheat->pOption[n] == NULL) { pCurrentCheat->pOption[n] = (CheatOption*)malloc(sizeof(CheatOption)); } memset(pCurrentCheat->pOption[n], 0, sizeof(CheatOption)); memcpy(pCurrentCheat->pOption[n]->szOptionName, szQuote, QUOTE_MAX * sizeof(TCHAR)); int nCurrentAddress = 0; bool bOK = true; while (nCurrentAddress < CHEAT_MAX_ADDRESS) { int nCPU = 0, nAddress = 0, nValue = 0; if (SkipComma(&s)) { nCPU = _tcstol(s, &t, 0); // CPU number if (t == s) { CheatError(pszFilename, nLine, pCurrentCheat, _T("CPU number omitted"), szLine); bOK = false; break; } s = t; SkipComma(&s); nAddress = _tcstol(s, &t, 0); // Address if (t == s) { bOK = false; CheatError(pszFilename, nLine, pCurrentCheat, _T("address omitted"), szLine); break; } s = t; SkipComma(&s); nValue = _tcstol(s, &t, 0); // Value if (t == s) { bOK = false; CheatError(pszFilename, nLine, pCurrentCheat, _T("value omitted"), szLine); break; } } else { if (nCurrentAddress) { // Only the first option is allowed no address break; } if (n) { bOK = false; CheatError(pszFilename, nLine, pCurrentCheat, _T("CPU / address / value omitted"), szLine); break; } } pCurrentCheat->pOption[n]->AddressInfo[nCurrentAddress].nCPU = nCPU; pCurrentCheat->pOption[n]->AddressInfo[nCurrentAddress].nAddress = nAddress; pCurrentCheat->pOption[n]->AddressInfo[nCurrentAddress].nValue = nValue; nCurrentAddress++; } if (!bOK) { break; } } continue; } SKIP_WS(s); if (*s == _T('}')) { if (nInside != _T('{')) { CheatError(pszFilename, nLine, pCurrentCheat, _T("missing opening bracket"), NULL); break; } nInside = INSIDE_NOTHING; } // Line isn't (part of) a valid cheat #if 0 if (*s) { CheatError(pszFilename, nLine, NULL, _T("rogue line"), szLine); break; } #endif } if (h) { fclose(h); } return 0; }