// VBA-specific quest-driving code #include #include "vbaq.h" //#include "quest.h" #include "GBA.h" #include "GBAInline.h" extern GlobalQuestInfo* GlobalQ; extern int emulating; void QuestExitGame() { printf("QuestExitGame!\n"); emulating = 0; } void QuestComplete(int CompletionType) { if (!GlobalQ->CurrentQuest) // wtf? { return; } switch (CompletionType) { case QUEST_STATE_GOLD: systemScreenMessage("Complete! (Gold)"); break; case QUEST_STATE_SILVER: systemScreenMessage("Complete! (Silver)"); break; case QUEST_STATE_BRONZE: systemScreenMessage("Complete! (Bronze)"); break; case QUEST_STATE_FAILURE: systemScreenMessage("(Quest failed)"); break; } } // Just handle setting single-byte values. void QMemlocSetValue(QMemloc* Info, int Value) { int Multiplier = Info->Multiplier; // A multiplier of 0 is silly, so we'll assume that what's wanted is 1: if (Multiplier == 0) { Multiplier = 1; } CPUWriteByte(Info->MemoryLocation, Value); } // Look up the value of a game parameter. Usually it's just a matter // of asking the CPU for the byte stored at a memory location. // Sometimes we must read several bytes (mostly for SCORES) int QMemlocGetValue(QMemloc* Info) { int Value; int Byte; int BitIndex; int Scaling; // if (!Info) { printf("QMemlocGetValue(NULL)\n"); return 0; } int Multiplier = Info->Multiplier; // A multiplier of 0 is silly, so we'll assume that what's wanted is 1: if (Multiplier == 0) { Multiplier = 1; } switch (Info->StorageMethod) { case evStorageByte: Value = CPUReadByteQuick(Info->MemoryLocation); return Value * Multiplier; case evStorage2Byte: Value = CPUReadByteQuick(Info->MemoryLocation) * 256; Value += CPUReadByteQuick(Info->MemoryLocation + 1); return Value * Multiplier; case evStorage2ByteLE: Value = CPUReadByteQuick(Info->MemoryLocation); Value += CPUReadByteQuick(Info->MemoryLocation + 1) * 256; return Value * Multiplier; case evStorage4Byte: Value = CPUReadByteQuick(Info->MemoryLocation) * 256 * 256 * 256; Value += CPUReadByteQuick(Info->MemoryLocation + 1) * 256 * 256; Value += CPUReadByteQuick(Info->MemoryLocation + 2) * 256; Value += CPUReadByteQuick(Info->MemoryLocation + 3); return Value * Multiplier; case evStorage4ByteLE: Value = CPUReadByteQuick(Info->MemoryLocation); Value += CPUReadByteQuick(Info->MemoryLocation + 1) * 256; Value += CPUReadByteQuick(Info->MemoryLocation + 2) * 256 * 256; Value += CPUReadByteQuick(Info->MemoryLocation + 3) * 256 * 256 * 256; return Value * Multiplier; case evStorageScoreOnes: // Score is stored like this: // Score of 123, width 3: // 0x?1 0x?2 0x?3 Scaling = 1; for (BitIndex = 0; BitIndex < Info->Width - 1; BitIndex++) { Scaling *= 10; } Value = 0; for (BitIndex = 0; BitIndex < Info->Width; BitIndex++) { Byte = CPUReadByteQuick(Info->MemoryLocation + BitIndex); Value += (Byte % 16) * Scaling; Scaling /= 10; } return Value * Multiplier; break; case evStorageScoreOnesLE: // Score is stored like this: // Score of 123, width 3: // 0x?3 0x?2 0x?1 Scaling = 1; Value = 0; for (BitIndex = 0; BitIndex < Info->Width; BitIndex++) { Byte = CPUReadByteQuick(Info->MemoryLocation + BitIndex); Value += (Byte % 16) * Scaling; Scaling *= 10; } return Value * Multiplier; break; case evStorageScoreOnesOnlyLE: // Score is stored like this: // Score of 123, width 3: // 0x03 0x02 0x01 // If we encounter a value of 0x10 or larger, we STOP early. // (This is a weird storage format; it's used by galaga) Scaling = 1; Value = 0; for (BitIndex = 0; BitIndex < Info->Width; BitIndex++) { Byte = CPUReadByteQuick(Info->MemoryLocation + BitIndex); if (Byte >= 0x10) { break; } Value += (Byte % 16) * Scaling; Scaling *= 10; } return Value * Multiplier; break; case evStorageScoreLE: // Little-endian score Scaling = 1; Value = 0; for (BitIndex = 0; BitIndex < Info->Width; BitIndex++) { Byte = CPUReadByteQuick(Info->MemoryLocation + BitIndex); Value += (Byte / 16) * Scaling * 10; Value += (Byte % 16) * Scaling; Scaling *= 100; } return Value * Multiplier; case evStorageScore: // Scores are stored like this: // Score of 18625, width 3: // 0x01 0x86 0x25 Value = 0; // Read bits, from most to least significant: Scaling = 1; for (BitIndex = 0; BitIndex < Info->Width - 1; BitIndex++) { Scaling *= 100; } for (BitIndex = 0; BitIndex < Info->Width; BitIndex++) { Byte = CPUReadByteQuick(Info->MemoryLocation + BitIndex); Value += (Byte / 16) * Scaling * 10; Value += (Byte % 16) * Scaling; Scaling /= 100; } return Value * Multiplier; case evStorageScoreReverse: // Reversed scores are stored like this: // Score of 1625, width 2: // 0x61 0x52 Value = 0; // Read bits, from most to least significant: Scaling = 1; for (BitIndex = 0; BitIndex < Info->Width - 1; BitIndex++) { Scaling *= 100; } for (BitIndex = 0; BitIndex < Info->Width; BitIndex++) { Byte = CPUReadByteQuick(Info->MemoryLocation + BitIndex); Value += (Byte / 16) * Scaling; Value += (Byte % 16) * Scaling * 10; Scaling /= 100; } return Value * Multiplier; case evStorageFlag: Value = CPUReadByteQuick(Info->MemoryLocation); if (Value & (1 << Info->Width)) { return 1; } return 0; default: return 0; } return 0; } void ShowQuestTimer() { } void DebugPrintKeysPressed() { }