aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/ds/arm9/source/dsmain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/platform/ds/arm9/source/dsmain.cpp')
-rw-r--r--backends/platform/ds/arm9/source/dsmain.cpp3888
1 files changed, 3888 insertions, 0 deletions
diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
new file mode 100644
index 0000000000..b42d9ed15e
--- /dev/null
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -0,0 +1,3888 @@
+/* ScummVMDS - Scumm Interpreter DS Port
+ * Copyright (C) 2002-2004 The ScummVM project and Neil Millstone
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#include <nds.h>
+
+#include <ARM9/console.h> //basic print funcionality
+
+#include <stdlib.h>
+#include "dsmain.h"
+#include "string.h"
+#include "system.h"
+#include "osystem_ds.h"
+#include "icons_raw.h"
+#include "gba_nds_fat.h"
+#include "disc_io.h"
+#include "config-manager.h"
+#include "engines/scumm/scumm.h"
+#include "keyboard_raw.h"
+#include "keyboard_pal_raw.h"
+#define V16(a, b) ((a << 12) | b)
+#include "touchkeyboard.h"
+#include "registers_alt.h"
+//#include "compact_flash.h"
+#include "dsoptions.h"
+
+namespace DS {
+
+// From console.c in NDSLib
+
+//location of cursor
+extern u8 row;
+extern u8 col;
+
+// Mouse mode
+enum MouseMode {
+ MOUSE_LEFT, MOUSE_RIGHT, MOUSE_HOVER, MOUSE_NUM_MODES
+};
+
+// Defines
+#define FRAME_TIME 17
+#define SCUMM_GAME_HEIGHT 142
+#define SCUMM_GAME_WIDTH 232
+
+int textureID;
+u16* texture;
+
+int frameCount;
+int currentTimeMillis;
+
+// Timer Callback
+int callbackInterval;
+int callbackTimer;
+OSystem::TimerProc callback;
+
+// Scaled
+bool scaledMode;
+int scX;
+int scY;
+
+int subScX;
+int subScY;
+int subScTargetX;
+int subScTargetY;
+int subScreenWidth = SCUMM_GAME_WIDTH;
+int subScreenHeight = SCUMM_GAME_HEIGHT;
+int subScreenScale = 256;
+
+
+
+// Sound
+int bufferSize;
+s16* soundBuffer;
+int bufferFrame;
+int bufferRate;
+int bufferSamples;
+bool soundHiPart;
+
+// Events
+int lastEventFrame;
+bool indyFightState;
+bool indyFightRight;
+
+OSystem::SoundProc soundCallback;
+void* soundParam;
+int lastCallbackFrame;
+bool bufferFirstHalf;
+bool bufferSecondHalf;
+
+// Saved buffers
+u8* savedBuffer = NULL;
+bool highBuffer;
+bool displayModeIs8Bit;
+
+// Game id
+u8 gameID;
+
+bool consoleEnable = true;
+bool gameScreenSwap = false;
+
+MouseMode mouseMode;
+
+// Sprites
+SpriteEntry sprites[128];
+SpriteEntry spritesMain[128];
+int tweak;
+
+// Shake
+int shakePos = 0;
+
+// Keyboard
+bool keyboardEnable = false;
+bool leftHandedMode = false;
+bool keyboardIcon = false;
+
+// Touch
+int touchScX, touchScY, touchX, touchY;
+
+// Dragging
+int dragStartX, dragStartY;
+bool dragging = false;
+int dragScX, dragScY;
+
+// Interface styles
+char gameName[32];
+
+// 8-bit surface size
+int gameWidth = 320;
+int gameHeight = 200;
+
+enum controlType {
+ CONT_SCUMM_ORIGINAL,
+ CONT_SCUMM_SAMNMAX,
+ CONT_SKY,
+ CONT_SIMON,
+};
+
+struct gameListType {
+ char gameId[16];
+ controlType control;
+};
+
+#define NUM_SUPPORTED_GAMES 15
+
+gameListType gameList[NUM_SUPPORTED_GAMES] = {
+ // Unknown game - use normal SCUMM controls
+ {"unknown", CONT_SCUMM_ORIGINAL},
+
+ // SCUMM games
+ {"maniac", CONT_SCUMM_ORIGINAL},
+ {"zak", CONT_SCUMM_ORIGINAL},
+ {"loom", CONT_SCUMM_ORIGINAL},
+ {"indy3", CONT_SCUMM_ORIGINAL},
+ {"atlantis", CONT_SCUMM_ORIGINAL},
+ {"monkey", CONT_SCUMM_ORIGINAL},
+ {"monkey2", CONT_SCUMM_ORIGINAL},
+ {"tentacle", CONT_SCUMM_ORIGINAL},
+ {"samnmax", CONT_SCUMM_SAMNMAX},
+
+ // Non-SCUMM games
+ {"sky", CONT_SKY},
+ {"simon1", CONT_SIMON},
+ {"simon2", CONT_SIMON},
+ {"gob1", CONT_SCUMM_ORIGINAL},
+ {"queen", CONT_SCUMM_ORIGINAL}
+};
+
+gameListType* currentGame = NULL;
+
+// Stylus
+#define ABS(x) ((x)>0?(x):-(x))
+
+bool penDown;
+bool penHeld;
+bool penReleased;
+bool penDownLastFrame;
+f32 penX, penY;
+int keysDownSaved;
+int keysReleasedSaved;
+
+bool penDownSaved;
+bool penReleasedSaved;
+int penDownFrames;
+int touchXOffset = 0;
+int touchYOffset = 0;
+
+u16 savedPalEntry255 = RGB15(31, 31, 31);
+
+
+extern "C" int scummvm_main(int argc, char *argv[]);
+void updateStatus();
+
+TransferSound soundControl;
+
+//plays an 8 bit mono sample at 11025Hz
+void playSound(const void* data, u32 length, bool loop, bool adpcm, int rate)
+{
+
+ if (!IPC->soundData) {
+ soundControl.count = 0;
+ }
+
+ soundControl.data[soundControl.count].data = data;
+ soundControl.data[soundControl.count].len = length | (loop? 0x80000000: 0x00000000);
+ soundControl.data[soundControl.count].rate = rate; // 367 samples per frame
+ soundControl.data[soundControl.count].pan = 64;
+ soundControl.data[soundControl.count].vol = 127;
+ soundControl.data[soundControl.count].format = adpcm? 2: 0;
+
+ soundControl.count++;
+
+ DC_FlushAll();
+ IPC->soundData = &soundControl;
+}
+
+void stopSound(int channel) {
+ playSound(NULL, 0, false, false, -channel);
+}
+
+void updateOAM() {
+ DC_FlushAll();
+ dmaCopy(sprites, OAM_SUB, 128 * sizeof(SpriteEntry));
+ dmaCopy(spritesMain, OAM, 128 * sizeof(SpriteEntry));
+}
+
+void setGameSize(int width, int height) {
+ gameWidth = width;
+ gameHeight = height;
+}
+
+int getGameWidth() {
+ return gameWidth;
+}
+
+int getGameHeight() {
+ return gameHeight;
+}
+
+void initSprites() {
+ for(int i = 0; i < 128; i++) {
+ sprites[i].attribute[0] = ATTR0_DISABLED;
+ sprites[i].attribute[1] = 0;
+ sprites[i].attribute[2] = 0;
+ sprites[i].attribute[3] = 0;
+ }
+
+ for(int i = 0; i < 128; i++) {
+ spritesMain[i].attribute[0] = ATTR0_DISABLED;
+ spritesMain[i].attribute[1] = 0;
+ spritesMain[i].attribute[2] = 0;
+ spritesMain[i].attribute[3] = 0;
+ }
+
+ updateOAM();
+}
+
+
+void saveGameBackBuffer() {
+#ifdef DISABLE_SCUMM
+ if (savedBuffer == NULL) savedBuffer = new u8[gameWidth * gameHeight];
+ for (int r = 0; r < 200; r++) {
+ memcpy(savedBuffer + (r * gameWidth), ((u8 *) (get8BitBackBuffer())) + (r * 512), gameWidth);
+ }
+#endif
+}
+
+void restoreGameBackBuffer() {
+#ifdef DISABLE_SCUMM
+ if (savedBuffer) {
+ for (int r = 0; r < 200; r++) {
+ memcpy(((u8 *) (BG_GFX_SUB)) + (r * 512), savedBuffer + (r * gameWidth), gameWidth);
+ memcpy(((u8 *) (get8BitBackBuffer())) + (r * 512), savedBuffer + (r * gameWidth), gameWidth);
+ }
+ delete savedBuffer;
+ savedBuffer = NULL;
+ }
+#endif
+
+#ifndef DISABLE_SCUMM
+ memset(get8BitBackBuffer(), 0, 512 * 256);
+ memset(BG_GFX_SUB, 0, 512 * 256);
+ if (Scumm::g_scumm) {
+ Scumm::g_scumm->markRectAsDirty(Scumm::kMainVirtScreen, 0, gameWidth - 1, 0, gameHeight - 1, 1);
+ Scumm::g_scumm->markRectAsDirty(Scumm::kTextVirtScreen, 0, gameWidth - 1, 0, gameHeight - 1, 1);
+ Scumm::g_scumm->markRectAsDirty(Scumm::kVerbVirtScreen, 0, gameWidth - 1, 0, gameHeight - 1, 1);
+ }
+#endif
+
+}
+
+
+void initGame() {
+ // This is a good time to check for left handed mode since the mode change is done as the game starts.
+ // There's probably a better way, but hey.
+// consolePrintf("initing game\n");
+
+ setOptions();
+
+ //strcpy(gameName, ConfMan.getActiveDomain().c_str());
+ strcpy(gameName, ConfMan.get("gameid").c_str());
+// consolePrintf("\n\n\n\nCurrent game: '%s' %d\n", gameName, gameName[0]);
+
+ currentGame = &gameList[0]; // Default game
+
+ for (int r = 0; r < NUM_SUPPORTED_GAMES; r++) {
+ if (!stricmp(gameName, gameList[r].gameId)) {
+ currentGame = &gameList[r];
+// consolePrintf("Game list num: %d\n", currentGame);
+ }
+ }
+
+
+}
+
+void setLeftHanded(bool enable) {
+ leftHandedMode = enable;
+}
+
+void setTouchXOffset(int x) {
+ touchXOffset = x;
+}
+
+void setTouchYOffset(int y) {
+ touchYOffset = y;
+}
+
+void setUnscaledMode(bool enable) {
+ scaledMode = !enable;
+}
+
+void displayMode8Bit() {
+
+ u16 buffer[32 * 32];
+
+ setKeyboardEnable(false);
+
+ if (!displayModeIs8Bit) {
+ for (int r = 0; r < 32 * 32; r++) {
+ buffer[r] = ((u16 *) SCREEN_BASE_BLOCK_SUB(4))[r];
+ }
+ }
+
+
+
+ videoSetMode(MODE_5_2D | (consoleEnable? DISPLAY_BG0_ACTIVE: 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+ videoSetModeSub(MODE_3_2D /*| DISPLAY_BG0_ACTIVE*/ | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
+
+ vramSetBankA(VRAM_A_MAIN_BG_0x6000000);
+ vramSetBankB(VRAM_B_MAIN_BG_0x6020000);
+
+ vramSetBankC(VRAM_C_SUB_BG_0x6200000);
+ vramSetBankD(VRAM_D_MAIN_BG_0x6040000);
+
+ vramSetBankH(VRAM_H_LCD);
+
+ BG3_CR = BG_BMP8_512x256 | BG_BMP_BASE(8);
+
+
+
+ BG3_XDX = (int) (((float) (gameWidth) / 256.0f) * 256);
+ BG3_XDY = 0;
+ BG3_YDX = 0;
+ BG3_YDY = (int) ((200.0f / 192.0f) * 256);
+
+ SUB_BG3_CR = BG_BMP8_512x256;
+
+
+
+ SUB_BG3_XDX = (int) (subScreenWidth / 256.0f * 256);
+ SUB_BG3_XDY = 0;
+ SUB_BG3_YDX = 0;
+ SUB_BG3_YDY = (int) (subScreenHeight / 192.0f * 256);
+
+
+ // Do text stuff
+ BG0_CR = BG_MAP_BASE(0) | BG_TILE_BASE(1);
+ BG0_Y0 = 0;
+
+ // Restore palette entry used by text in the front-end
+ PALETTE_SUB[255] = savedPalEntry255;
+
+ consoleInitDefault((u16*)SCREEN_BASE_BLOCK(0), (u16*)CHAR_BASE_BLOCK(1), 16);
+ consolePrintSet(0, 23);
+
+ if (!displayModeIs8Bit) {
+ for (int r = 0; r < 32 * 32; r++) {
+ ((u16 *) SCREEN_BASE_BLOCK(0))[r] = buffer[r];
+ }
+// dmaCopyHalfWords(3, (u16 *) SCREEN_BASE_BLOCK(0), buffer, 32 * 32 * 2);
+ }
+
+
+ if (!displayModeIs8Bit) restoreGameBackBuffer();
+ displayModeIs8Bit = true;
+
+ POWER_CR &= ~POWER_SWAP_LCDS;
+
+ keyboardEnable = false;
+ initGame();
+
+}
+
+void setGameID(int id) {
+ gameID = id;
+}
+
+void dummyHandler() {
+ REG_IF = IRQ_VBLANK;
+}
+
+void checkSleepMode() {
+ if (IPC->performArm9SleepMode) {
+
+ consolePrintf("ARM9 Entering sleep mode\n");
+
+ int intSave = REG_IE;
+ irqSet(IRQ_VBLANK, dummyHandler);
+// int irqHandlerSave = (int) IRQ_HANDLER;
+ REG_IE = IRQ_VBLANK;
+ //IRQ_HANDLER = dummyHandler;
+
+ int powerSave = POWER_CR;
+ POWER_CR &= ~POWER_ALL;
+
+ while (IPC->performArm9SleepMode) {
+ swiWaitForVBlank();
+ }
+
+ POWER_CR = powerSave;
+// IRQ_HANDLER = (void (*)()) irqHandlerSave;
+ irqSet(IRQ_VBLANK, VBlankHandler);
+ REG_IE = intSave;
+
+ consolePrintf("ARM9 Waking from sleep mode\n");
+ }
+}
+
+void setCursorIcon(const u8* icon, uint w, uint h, byte keycolor) {
+ if (currentGame->control != CONT_SCUMM_SAMNMAX)
+ return;
+
+ uint16 border = RGB15(24,24,24) | 0x8000;
+
+
+ int off = 48*64;
+ memset(SPRITE_GFX_SUB+off, 0, 64*64*2);
+
+ int pos = 190 - (w+2);
+
+
+
+ // make border
+ for (uint i=0; i<w+2; i++) {
+ SPRITE_GFX_SUB[off+i] = border;
+ SPRITE_GFX_SUB[off+(31)*64+i] = border;
+ }
+ for (uint i=1; i<31; i++) {
+ SPRITE_GFX_SUB[off+(i*64)] = border;
+ SPRITE_GFX_SUB[off+(i*64)+(w+1)] = border;
+ }
+
+ int offset = (32 - h) >> 1;
+
+ for (uint y=0; y<h; y++) {
+ for (uint x=0; x<w; x++) {
+ int color = icon[y*w+x];
+ if (color == keycolor) {
+ SPRITE_GFX_SUB[off+(y+1+offset)*64+(x+1)] = 0x8000; // black background
+ } else {
+ SPRITE_GFX_SUB[off+(y+1+offset)*64+(x+1)] = BG_PALETTE[color] | 0x8000;
+ }
+ }
+ }
+
+ sprites[1].attribute[0] = ATTR0_BMP | 150;
+ sprites[1].attribute[1] = ATTR1_SIZE_64 | pos;
+ sprites[1].attribute[2] = ATTR2_ALPHA(1) | 48;
+}
+
+
+
+
+void displayMode16Bit() {
+
+ u16 buffer[32 * 32 * 2];
+
+
+ if (displayModeIs8Bit) {
+ saveGameBackBuffer();
+ for (int r = 0; r < 32 * 32; r++) {
+ buffer[r] = ((u16 *) SCREEN_BASE_BLOCK(0))[r];
+ }
+ }
+
+
+ videoSetMode(MODE_5_2D | /*DISPLAY_BG0_ACTIVE |*/ DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+ videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE |/* DISPLAY_BG1_ACTIVE |*/ DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
+
+ vramSetBankA(VRAM_A_MAIN_BG);
+ vramSetBankB(VRAM_B_MAIN_BG);
+ vramSetBankC(VRAM_C_MAIN_BG);
+ vramSetBankD(VRAM_D_MAIN_BG);
+ vramSetBankH(VRAM_H_SUB_BG);
+
+ BG3_CR = BG_BMP16_512x256;
+ highBuffer = false;
+
+ BG3_XDX = (int) (1.25f * 256);
+ BG3_XDY = 0;
+ BG3_YDX = 0;
+ BG3_YDY = (int) ((200.0f / 192.0f) * 256);
+
+ memset(BG_GFX, 0, 512 * 256 * 2);
+
+ savedPalEntry255 = PALETTE_SUB[255];
+ PALETTE_SUB[255] = RGB15(31,31,31);//by default font will be rendered with color 255
+
+ // Do text stuff
+ SUB_BG0_CR = BG_MAP_BASE(4) | BG_TILE_BASE(0);
+ SUB_BG0_Y0 = 0;
+
+ consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(4), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
+
+ if (displayModeIs8Bit) {
+ //dmaCopyHalfWords(3, (u16 *) SCREEN_BASE_BLOCK_SUB(0), buffer, 32 * 32 * 2);
+ for (int r = 0; r < 32 * 32; r++) {
+ ((u16 *) SCREEN_BASE_BLOCK_SUB(4))[r] = buffer[r];
+ }
+ }
+
+ consolePrintSet(0, 23);
+ consolePrintf("\n");
+
+ // Show keyboard
+ SUB_BG1_CR = BG_TILE_BASE(1) | BG_MAP_BASE(12);
+ //drawKeyboard(1, 12);
+
+ POWER_CR &= ~POWER_SWAP_LCDS;
+
+
+
+ displayModeIs8Bit = false;
+}
+
+
+void displayMode16BitFlipBuffer() {
+ if (!displayModeIs8Bit) {
+ u16* back = get16BitBackBuffer();
+
+// highBuffer = !highBuffer;
+// BG3_CR = BG_BMP16_512x256 | BG_BMP_RAM(highBuffer? 1: 0);
+
+ for (int r = 0; r < 512 * 256; r++) {
+ *(BG_GFX + r) = *(back + r);
+ }
+ }
+}
+
+void setShakePos(int shakePos) {
+ shakePos = shakePos;
+}
+
+
+u16* get16BitBackBuffer() {
+ return BG_GFX + 0x20000;
+}
+
+u16* get8BitBackBuffer() {
+ return BG_GFX + 0x10000; // 16bit qty!
+}
+
+void setSoundProc(OSystem::SoundProc proc, void* param) {
+// consolePrintf("Set sound callback");
+ soundCallback = proc;
+ soundParam = param;
+}
+
+// The sound system in ScummVM seems to always return stereo interleaved samples.
+// Here, I'm treating an 11Khz stereo stream as a 22Khz mono stream, which works sorta ok, but is
+// a horrible bodge. Any advice on how to change the engine to output mono would be greatly
+// appreciated.
+void doSoundCallback() {
+ if ((soundCallback)) {
+ lastCallbackFrame = frameCount;
+
+ for (int r = IPC->playingSection; r < IPC->playingSection + 4; r++) {
+ int chunk = r & 3;
+
+ if (IPC->fillNeeded[chunk]) {
+ IPC->fillNeeded[chunk] = false;
+ DC_FlushAll();
+ soundCallback(soundParam, (byte *) (soundBuffer + ((bufferSamples >> 2) * chunk)), bufferSamples >> 1);
+ IPC->fillNeeded[chunk] = false;
+ DC_FlushAll();
+ }
+
+ }
+
+ }
+}
+
+void doTimerCallback() {
+ if (callback) {
+ if (callbackTimer <= 0) {
+ callbackTimer += callbackInterval;
+ callback(callbackInterval);
+ }
+ }
+}
+
+void soundUpdate() {
+ if ((bufferFrame == 0)) {
+// playSound(soundBuffer, (bufferSamples * 2), true);
+ }
+// consolePrintf("%x\n", IPC->test);
+
+
+ if (bufferFrame == 0) {
+// bufferFirstHalf = true;
+ }
+ if (bufferFrame == bufferSize >> 1) {
+ //bufferSecondHalf = true;
+ }
+
+ bufferFrame++;
+ if (bufferFrame == bufferSize) {
+ bufferFrame = 0;
+ }
+}
+
+void memoryReport() {
+ int r = 0;
+ int* p;
+ do {
+ p = (int *) malloc(r * 8192);
+ free(p);
+ r++;
+ } while ((p) && (r < 512));
+
+ int t = -1;
+ void* block[1024];
+ do {
+ t++;
+ block[t] = (int *) malloc(4096);
+ } while ((t < 1024) && (block[t]));
+
+ for (int q = 0; q < t; q++) {
+ free(block[q]);
+ }
+
+ consolePrintf("Free: %dK, Largest: %dK\n", t * 4, r * 8);
+}
+
+
+void addIndyFightingKeys() {
+ OSystem_DS* system = OSystem_DS::instance();
+ OSystem::Event event;
+
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.flags = 0;
+
+ if ((getKeysDown() & KEY_L)) {
+ indyFightRight = false;
+ }
+
+ if ((getKeysDown() & KEY_R)) {
+ indyFightRight = true;
+ }
+
+ if ((getKeysDown() & KEY_UP)) {
+ event.kbd.keycode = '8';
+ event.kbd.ascii = '8';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_LEFT)) {
+ event.kbd.keycode = '4';
+ event.kbd.ascii = '4';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_RIGHT)) {
+ event.kbd.keycode = '6';
+ event.kbd.ascii = '6';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_DOWN)) {
+ event.kbd.keycode = '2';
+ event.kbd.ascii = '2';
+ system->addEvent(event);
+ }
+
+ if (indyFightRight) {
+
+ if ((getKeysDown() & KEY_X)) {
+ event.kbd.keycode = '9';
+ event.kbd.ascii = '9';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_A)) {
+ event.kbd.keycode = '6';
+ event.kbd.ascii = '6';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_B)) {
+ event.kbd.keycode = '3';
+ event.kbd.ascii = '3';
+ system->addEvent(event);
+ }
+
+ } else {
+
+ if ((getKeysDown() & KEY_X)) {
+ event.kbd.keycode = '7';
+ event.kbd.ascii = '7';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_A)) {
+ event.kbd.keycode = '4';
+ event.kbd.ascii = '4';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_B)) {
+ event.kbd.keycode = '1';
+ event.kbd.ascii = '1';
+ system->addEvent(event);
+ }
+
+ }
+
+
+ if ((getKeysDown() & KEY_Y)) {
+ event.kbd.keycode = '5';
+ event.kbd.ascii = '5';
+ system->addEvent(event);
+ }
+}
+
+
+void setKeyboardEnable(bool en) {
+ if (en == keyboardEnable) return;
+ keyboardEnable = en;
+ u16* backupBank = (u16 *) 0x6040000;
+
+ if (keyboardEnable) {
+
+
+ DS::drawKeyboard(1, 12, backupBank);
+
+
+ SUB_BG1_CR = BG_TILE_BASE(1) | BG_MAP_BASE(12);
+
+ if (displayModeIs8Bit) {
+ SUB_DISPLAY_CR |= DISPLAY_BG1_ACTIVE; // Turn on keyboard layer
+ SUB_DISPLAY_CR &= ~DISPLAY_BG3_ACTIVE; // Turn off game layer
+ } else {
+ SUB_DISPLAY_CR |= DISPLAY_BG1_ACTIVE; // Turn on keyboard layer
+ SUB_DISPLAY_CR &= ~DISPLAY_BG0_ACTIVE; // Turn off console layer
+ }
+ lcdSwap();
+ } else {
+
+
+ // Restore the palette that the keyboard has used
+ for (int r = 0; r < 256; r++) {
+ BG_PALETTE_SUB[r] = BG_PALETTE[r];
+ }
+
+
+ //restoreVRAM(1, 12, backupBank);
+
+ if (displayModeIs8Bit) {
+ // Copy the sub screen VRAM from the top screen - they should always be
+ // the same.
+ for (int r = 0; r < (512 * 256) >> 1; r++) {
+ BG_GFX_SUB[r] = get8BitBackBuffer()[r];
+ }
+
+ SUB_DISPLAY_CR &= ~DISPLAY_BG1_ACTIVE; // Turn off keyboard layer
+ SUB_DISPLAY_CR |= DISPLAY_BG3_ACTIVE; // Turn on game layer
+ } else {
+ SUB_DISPLAY_CR &= ~DISPLAY_BG1_ACTIVE; // Turn off keyboard layer
+ SUB_DISPLAY_CR |= DISPLAY_BG0_ACTIVE; // Turn on console layer
+ }
+
+ lcdSwap();
+ }
+}
+
+bool getKeyboardEnable() {
+ return keyboardEnable;
+}
+
+bool getIsDisplayMode8Bit() {
+ return displayModeIs8Bit;
+}
+
+void addEventsToQueue() {
+ OSystem_DS* system = OSystem_DS::instance();
+ OSystem::Event event;
+
+
+
+
+ if (system->isEventQueueEmpty()) {
+
+/*
+ if (getKeysDown() & KEY_L) {
+ tweak--;
+ consolePrintf("Tweak: %d\n", tweak);
+ IPC->tweakChanged = true;
+ }
+
+
+ if (getKeysDown() & KEY_R) {
+ tweak++;
+ consolePrintf("Tweak: %d\n", tweak);
+ IPC->tweakChanged = true;
+ }
+ */
+ if ((keysHeld() & KEY_L) && (keysHeld() & KEY_R)) {
+ memoryReport();
+ }
+
+ if (displayModeIs8Bit) {
+
+ if (!indyFightState) {
+
+
+ if ((getKeysDown() & KEY_B) && (!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
+ // consolePrintf("Pressing Esc");
+
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = 27;
+ event.kbd.ascii = 27;
+ event.kbd.flags = 0;
+ system->addEvent(event);
+ }
+
+ }
+
+
+
+ if ((!getIndyFightState()) && (getKeysDown() & KEY_Y)) {
+ consoleEnable = !consoleEnable;
+ if (displayModeIs8Bit) {
+ displayMode8Bit();
+ } else {
+ displayMode16Bit();
+ }
+ }
+
+
+ if (!((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) && (!getIndyFightState())) {
+
+ if ((getKeysDown() & KEY_A) && (!indyFightState)) {
+ gameScreenSwap = !gameScreenSwap;
+ }
+
+ if (!getPenHeld() || (mouseMode != MOUSE_HOVER)) {
+ if (getKeysDown() & KEY_LEFT) {
+ mouseMode = MOUSE_LEFT;
+ }
+ if (getKeysDown() & KEY_RIGHT) {
+ if (currentGame->control != CONT_SCUMM_SAMNMAX) {
+ mouseMode = MOUSE_RIGHT;
+ } else {
+ // If we're playing sam and max, click and release the right mouse
+ // button to change verb
+ OSystem::Event event;
+
+ event.type = OSystem::EVENT_RBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+
+ event.type = OSystem::EVENT_RBUTTONUP;
+ system->addEvent(event);
+ }
+ }
+ if (getKeysDown() & KEY_UP) {
+ mouseMode = MOUSE_HOVER;
+ }
+ }
+
+
+
+ }
+
+ if ((getKeysDown() & KEY_SELECT)) {
+ //scaledMode = !scaledMode;
+ //scY = 4;
+ showOptionsDialog();
+ }
+
+
+ }
+
+ if (!getIndyFightState() && !((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) && (getKeysDown() & KEY_X)) {
+ setKeyboardEnable(!keyboardEnable);
+ }
+
+ updateStatus();
+
+ OSystem::Event event;
+
+ if ((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
+ event.type = OSystem::EVENT_MOUSEMOVE;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ //consolePrintf("x=%d y=%d \n", getPenX(), getPenY());
+ }
+
+ if (!keyboardEnable) {
+ if ((mouseMode != MOUSE_HOVER) || (!displayModeIs8Bit)) {
+ if (getPenDown() && (!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
+ event.type = ((mouseMode == MOUSE_LEFT) || (!displayModeIs8Bit))? OSystem::EVENT_LBUTTONDOWN: OSystem::EVENT_RBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+
+ if (getPenReleased()) {
+ event.type = mouseMode == MOUSE_LEFT? OSystem::EVENT_LBUTTONUP: OSystem::EVENT_RBUTTONUP;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+ } else {
+ // In hover mode, D-pad left and right click the mouse when the pen is on the screen
+
+ if (getPenHeld()) {
+ if (getKeysDown() & KEY_LEFT) {
+ event.type = OSystem::EVENT_LBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+ /* if (getKeysReleased() & KEY_LEFT) {
+ event.type = OSystem::EVENT_LBUTTONUP;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }*/
+
+ if (getKeysDown() & KEY_RIGHT) {
+ event.type = OSystem::EVENT_RBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+ /*if (getKeysReleased() & KEY_RIGHT) {
+ event.type = OSystem::EVENT_RBUTTONUP;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }*/
+ }
+ }
+
+ if ((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R)) && (displayModeIs8Bit)) {
+ // Controls specific to the control method
+
+
+ if (currentGame->control == CONT_SKY) {
+ // Extra controls for Benieth a Steel Sky
+ if ((getKeysDown() & KEY_DOWN)) {
+ penY = 0;
+ penX = 0; // Show inventory by moving mouse onto top line
+ }
+ }
+
+ if (currentGame->control == CONT_SIMON) {
+ // Extra controls for Simon the Sorcerer
+ if ((getKeysDown() & KEY_DOWN)) {
+ OSystem::Event event;
+
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = '#'; // F10 or # - show hotspots
+ event.kbd.ascii = '#';
+ event.kbd.flags = 0;
+ system->addEvent(event);
+// consolePrintf("F10\n");
+ }
+ }
+
+ if (currentGame->control == CONT_SCUMM_ORIGINAL) {
+ // Extra controls for Scumm v1-5 games
+ if ((getKeysDown() & KEY_DOWN)) {
+ OSystem::Event event;
+
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = '.'; // Full stop - skips current dialogue line
+ event.kbd.ascii = '.';
+ event.kbd.flags = 0;
+ system->addEvent(event);
+ }
+
+ if (indyFightState) {
+ addIndyFightingKeys();
+ }
+
+ }
+
+ }
+ }
+
+ if (!displayModeIs8Bit) {
+ // Front end controls
+
+ if (leftHandedSwap(getKeysDown()) & KEY_UP) {
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = SDLK_UP;
+ event.kbd.ascii = 0;
+ event.kbd.flags = 0;
+ system->addEvent(event);
+
+ event.type = OSystem::EVENT_KEYUP;
+ system->addEvent(event);
+ }
+
+ if (leftHandedSwap(getKeysDown()) & KEY_DOWN) {
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = SDLK_DOWN;
+ event.kbd.ascii = 0;
+ event.kbd.flags = 0;
+ system->addEvent(event);
+
+ event.type = OSystem::EVENT_KEYUP;
+ system->addEvent(event);
+ }
+
+ if (leftHandedSwap(getKeysDown()) & KEY_A) {
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = SDLK_RETURN;
+ event.kbd.ascii = 0;
+ event.kbd.flags = 0;
+ system->addEvent(event);
+
+ event.type = OSystem::EVENT_KEYUP;
+ system->addEvent(event);
+ }
+
+ }
+
+
+ if ((getKeysDown() & KEY_START)) {
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = 319; // F5
+ event.kbd.ascii = 319;
+ event.kbd.flags = 0;
+ system->addEvent(event);
+/*
+ event.type = OSystem::EVENT_KEYUP;
+ event.kbd.keycode = 319; // F5
+ event.kbd.ascii = 319;
+ system->addEvent(event);*/
+
+// consolePrintf("Pressing F5");
+ }
+
+
+ if (keyboardEnable) {
+ DS::addKeyboardEvents();
+ }
+
+ consumeKeys();
+
+ consumePenEvents();
+
+ }
+}
+
+void updateStatus() {
+ int offs;
+
+ if (displayModeIs8Bit) {
+ switch (mouseMode) {
+ case MOUSE_LEFT: {
+ offs = 16;
+ break;
+ }
+ case MOUSE_RIGHT: {
+ offs = 32;
+ break;
+ }
+ case MOUSE_HOVER: {
+ offs = 0;
+ break;
+ }
+ default: {
+ // Nothing!
+ offs = 0;
+ break;
+ }
+ }
+
+
+ sprites[0].attribute[0] = ATTR0_BMP | 150;
+ sprites[0].attribute[1] = ATTR1_SIZE_32 | 208;
+ sprites[0].attribute[2] = ATTR2_ALPHA(1)| offs;
+
+ if (indyFightState) {
+ sprites[2].attribute[0] = ATTR0_BMP | 150;
+ sprites[2].attribute[1] = ATTR1_SIZE_32 | (190 - 32) | (indyFightRight? 0: ATTR1_FLIP_X);
+ sprites[2].attribute[2] = ATTR2_ALPHA(1)| 48;
+ } else {
+ sprites[2].attribute[0] = ATTR0_DISABLED;
+ sprites[2].attribute[1] = 0;
+ sprites[2].attribute[2] = 0;
+ }
+ } else {
+ sprites[0].attribute[0] = ATTR0_DISABLED;
+ sprites[1].attribute[0] = ATTR0_DISABLED;
+ sprites[2].attribute[0] = ATTR0_DISABLED;
+ sprites[3].attribute[0] = ATTR0_DISABLED;
+ }
+
+ if ((keyboardIcon) && (!keyboardEnable) && (!displayModeIs8Bit)) {
+ spritesMain[0].attribute[0] = ATTR0_BMP | 160;
+ spritesMain[0].attribute[1] = ATTR1_SIZE_32 | 0;
+ spritesMain[0].attribute[2] = ATTR2_ALPHA(1) | 64;
+ } else {
+ spritesMain[0].attribute[0] = ATTR0_DISABLED;
+ spritesMain[0].attribute[1] = 0;
+ spritesMain[0].attribute[2] = 0;
+ spritesMain[0].attribute[3] = 0;
+ }
+
+}
+
+void soundBufferEmptyHandler() {
+ REG_IF = IRQ_TIMER2;
+
+ if (soundHiPart) {
+// bufferSecondHalf = true;
+ } else {
+// bufferFirstHalf = true;
+ }
+
+ soundHiPart = !soundHiPart;
+}
+
+void setMainScreenScroll(int x, int y) {
+ if (gameScreenSwap) {
+ SUB_BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
+ SUB_BG3_CY = y;
+ } else {
+ BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
+ BG3_CY = y;
+
+ touchX = x >> 8;
+ touchY = y >> 8;
+ }
+}
+
+void setMainScreenScale(int x, int y) {
+ if (gameScreenSwap) {
+ SUB_BG3_XDX = x;
+ SUB_BG3_XDY = 0;
+ SUB_BG3_YDX = 0;
+ SUB_BG3_YDY = y;
+ } else {
+ BG3_XDX = x;
+ BG3_XDY = 0;
+ BG3_YDX = 0;
+ BG3_YDY = y;
+
+ touchScX = x;
+ touchScY = y;
+ }
+}
+
+void setZoomedScreenScroll(int x, int y) {
+ if (gameScreenSwap) {
+ BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
+ BG3_CY = y;
+
+ touchX = x >> 8;
+ touchY = y >> 8;
+ } else {
+ SUB_BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
+ SUB_BG3_CY = y;
+ }
+}
+
+void setZoomedScreenScale(int x, int y) {
+ if (gameScreenSwap) {
+ BG3_XDX = x;
+ BG3_XDY = 0;
+ BG3_YDX = 0;
+ BG3_YDY = y;
+
+ touchScX = x;
+ touchScY = y;
+ } else {
+ SUB_BG3_XDX = x;
+ SUB_BG3_XDY = 0;
+ SUB_BG3_YDX = 0;
+ SUB_BG3_YDY = y;
+ }
+}
+
+void VBlankHandler(void) {
+// BG_PALETTE[0] = RGB15(31, 31, 31);
+// if (*((int *) (0x023FFF00)) != 0xBEEFCAFE) {
+ // consolePrintf("Guard band overwritten!");
+// }
+
+// consolePri ntf("X:%d Y:%d\n", getPenX(), getPenY());
+
+
+ IPC->tweak = tweak;
+ soundUpdate();
+
+
+
+
+ if ((!gameScreenSwap) && (!(getKeysHeld() & KEY_L) && !(getKeysHeld() & KEY_R))) {
+ if (currentGame) {
+ if (currentGame->control != CONT_SCUMM_SAMNMAX) {
+ if (getPenHeld() && (getPenY() < SCUMM_GAME_HEIGHT)) {
+ setTopScreenTarget(getPenX(), getPenY());
+ }
+ } else {
+ if (getPenHeld()) {
+ setTopScreenTarget(getPenX(), getPenY());
+ }
+ }
+ }
+ }
+
+
+ penUpdate();
+ keysUpdate();
+
+
+ frameCount++;
+
+
+
+ if (callback) {
+ callbackTimer -= FRAME_TIME;
+ }
+
+ if ((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) {
+
+ if ((!dragging) && (getPenHeld()) && (penDownFrames > 5)) {
+ dragging = true;
+ dragStartX = penX;
+ dragStartY = penY;
+
+ if (gameScreenSwap) {
+ dragScX = subScTargetX;
+ dragScY = subScTargetY;
+ } else {
+ dragScX = scX;
+ dragScY = scY;
+ }
+
+
+ }
+
+ if ((dragging) && (!getPenHeld())) {
+ dragging = false;
+ }
+
+ if (dragging) {
+
+ if (gameScreenSwap) {
+ subScTargetX = dragScX + ((dragStartX - penX) << 8);
+ subScTargetY = dragScY + ((dragStartY - penY) << 8);
+ } else {
+ scX = dragScX + ((dragStartX - penX));
+ scY = dragScY + ((dragStartY - penY));
+ }
+
+// consolePrintf("X:%d Y:%d\n", dragStartX - penX, dragStartY - penY);
+ }
+ }
+
+
+/* if ((frameCount & 1) == 0) {
+ SUB_BG3_CX = subScX;
+ } else {
+ SUB_BG3_CX = subScX + 64;
+ }
+
+ SUB_BG3_CY = subScY + (shakePos << 8);*/
+
+ /*SUB_BG3_XDX = (int) (subScreenWidth / 256.0f * 256);
+ SUB_BG3_XDY = 0;
+ SUB_BG3_YDX = 0;
+ SUB_BG3_YDY = (int) (subScreenHeight / 192.0f * 256);*/
+
+
+ if ((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) {
+ if ((getKeysHeld() & KEY_A) && (subScreenScale < 256)) {
+ subScreenScale += 3;
+ }
+
+ if ((getKeysHeld() & KEY_B) && (subScreenScale > 128)) {
+ subScreenScale -=3;
+ }
+
+ int xCenter = subScTargetX + ((subScreenWidth >> 1) << 8);
+ int yCenter = subScTargetY + ((subScreenHeight >> 1) << 8);
+
+ subScreenWidth = SCUMM_GAME_WIDTH * subScreenScale >> 8;
+ subScreenHeight = SCUMM_GAME_HEIGHT * subScreenScale >> 8;
+
+ subScTargetX = xCenter - ((subScreenWidth >> 1) << 8);
+ subScTargetY = yCenter - ((subScreenHeight >> 1) << 8);
+
+
+
+
+ if (subScTargetX < 0) subScTargetX = 0;
+ if (subScTargetX > (gameWidth - subScreenWidth) << 8) subScTargetX = (gameWidth - subScreenWidth) << 8;
+
+ if (subScTargetY < 0) subScTargetY = 0;
+ if (subScTargetY > (gameHeight - subScreenHeight) << 8) subScTargetY = (gameHeight - subScreenHeight) << 8;
+ }
+
+ subScX += (subScTargetX - subScX) >> 2;
+ subScY += (subScTargetY - subScY) >> 2;
+
+ if (displayModeIs8Bit) {
+
+ if ((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) {
+
+ int offsX = 0, offsY = 0;
+
+
+ if (getKeysHeld() & KEY_LEFT) {
+ offsX -= 1;
+ }
+
+ if (getKeysHeld() & KEY_RIGHT) {
+ offsX += 1;
+ }
+
+ if (getKeysHeld() & KEY_UP) {
+ offsY -= 1;
+ }
+
+ if (getKeysHeld() & KEY_DOWN) {
+ offsY += 1;
+ }
+
+ if (((gameScreenSwap) && (getKeysHeld() & KEY_L)) || ((!gameScreenSwap) && (getKeysHeld() & KEY_R))) {
+ subScTargetX += offsX << 8;
+ subScTargetY += offsY << 8;
+ } else {
+ scX += offsX;
+ scY += offsY;
+ }
+ }
+
+ if (!scaledMode) {
+
+ if (scX + 256 > gameWidth - 1) {
+ scX = gameWidth - 1 - 256;
+ }
+
+ if (scX < 0) {
+ scX = 0;
+ }
+
+ if (scY + 192 > gameHeight - 1) {
+ scY = gameHeight - 1 - 192;
+ }
+
+ if (scY < 0) {
+ scY = 0;
+ }
+
+ setZoomedScreenScroll(subScX, subScY);
+ setZoomedScreenScale(subScreenWidth, (subScreenHeight * 256) / 192);
+
+
+ setMainScreenScroll(scX << 8, (scY << 8) + (shakePos << 8));
+ setMainScreenScale(256, 256); // 1:1 scale
+
+ } else {
+
+ if (scY > gameHeight - 192 - 1) {
+ scY = gameHeight - 192 - 1;
+ }
+
+ if (scY < 0) {
+ scY = 0;
+ }
+
+ setZoomedScreenScroll(subScX, subScY);
+ setZoomedScreenScale(subScreenWidth, (subScreenHeight * 256) / 192);
+
+ setMainScreenScroll(64, (scY << 8) + (shakePos << 8));
+ setMainScreenScale(320, 256); // 1:1 scale
+
+ }
+ } else {
+ setZoomedScreenScroll(0, 0);
+ setZoomedScreenScale(320, 256);
+
+ setMainScreenScroll(0, 0);
+ setMainScreenScale(320, 256); // 1:1 scale
+ }
+
+ // Enable on screen keyboard when pen taps icon
+ if ((keyboardIcon) && (penX < 32) && (penY > 160) && (penHeld)) {
+ setKeyboardEnable(true);
+ }
+
+ if (keyboardEnable) {
+ if (DS::getKeyboardClosed()) {
+ setKeyboardEnable(false);
+ }
+ }
+
+ updateOAM();
+
+ //PALETTE[0] = RGB15(0, 0, 0);
+ REG_IF = IRQ_VBLANK;
+}
+
+int getMillis() {
+ return currentTimeMillis;
+// return frameCount * FRAME_TIME;
+}
+
+void setTimerCallback(OSystem::TimerProc proc, int interval) {
+// consolePrintf("Set timer proc %x, int %d\n", proc, interval);
+ callback = proc;
+ callbackInterval = interval;
+ callbackTimer = interval;
+}
+
+void timerTickHandler() {
+ REG_IF = IRQ_TIMER0;
+ if ((callback) && (callbackTimer > 0)) {
+ callbackTimer--;
+ }
+ currentTimeMillis++;
+}
+
+void setTalkPos(int x, int y) {
+// if (gameID != Scumm::GID_SAMNMAX) {
+// setTopScreenTarget(x, 0);
+// } else {
+ setTopScreenTarget(x, y);
+// }
+}
+
+void setTopScreenTarget(int x, int y) {
+ subScTargetX = (x - (subScreenWidth >> 1));
+ subScTargetY = (y - (subScreenHeight >> 1));
+
+ if (subScTargetX < 0) subScTargetX = 0;
+ if (subScTargetX > gameWidth - subScreenWidth) subScTargetX = gameWidth - subScreenWidth;
+
+ if (subScTargetY < 0) subScTargetY = 0;
+ if (subScTargetY > gameHeight - subScreenHeight) subScTargetY = gameHeight - subScreenHeight;
+
+ subScTargetX <<=8;
+ subScTargetY <<=8;
+}
+
+void initHardware() {
+ // Guard band
+//((int *) (0x023FFF00)) = 0xBEEFCAFE;
+
+
+ penInit();
+
+ powerON(POWER_ALL);
+/* vramSetBankA(VRAM_A_MAIN_BG);
+ vramSetBankB(VRAM_B_MAIN_BG);
+ vramSetBankC(VRAM_C_SUB_BG); */
+ vramSetBankI(VRAM_I_SUB_SPRITE);
+ vramSetBankG(VRAM_G_MAIN_SPRITE);
+
+ currentTimeMillis = 0;
+
+
+/*
+ // Set up a millisecond counter
+ TIMER0_CR = 0;
+ TIMER0_DATA = 0xFFFF;
+ TIMER0_CR = TIMER_ENABLE | TIMER_CASCADE;
+*/
+
+
+
+ PALETTE[255] = RGB15(0,31,0);
+
+ // Allocate save buffer for game screen
+// savedBuffer = new u8[320 * 200];
+ displayMode16Bit();
+
+ memset(BG_GFX, 0, 512 * 256 * 2);
+ scaledMode = true;
+ scX = 0;
+ scY = 0;
+ subScX = 0;
+ subScY = 0;
+ subScTargetX = 0;
+ subScTargetY = 0;
+
+ //lcdSwap();
+ POWER_CR &= ~POWER_SWAP_LCDS;
+
+ frameCount = 0;
+ callback = NULL;
+
+// vramSetBankH(VRAM_H_SUB_BG);
+
+
+// // Do text stuff
+ //BG0_CR = BG_MAP_BASE(0) | BG_TILE_BASE(1);
+// BG0_Y0 = 48;
+
+ PALETTE[255] = RGB15(31,31,31);//by default font will be rendered with color 255
+
+ //consoleInit() is a lot more flexible but this gets you up and running quick
+// consoleInitDefault((u16*)SCREEN_BASE_BLOCK(0), (u16*)CHAR_BASE_BLOCK(1), 16);
+ //consolePrintSet(0, 6);
+
+ //irqs are nice
+ irqInit();
+// irqInitHandler();
+ irqSet(IRQ_VBLANK, VBlankHandler);
+ irqSet(IRQ_TIMER0, timerTickHandler);
+ irqSet(IRQ_TIMER2, soundBufferEmptyHandler);
+
+ irqEnable(IRQ_VBLANK);
+ irqEnable(IRQ_TIMER0);
+ irqEnable(IRQ_TIMER2);
+
+
+ // Set up a millisecond timer
+ TIMER0_CR = 0;
+ TIMER0_DATA = (u32) TIMER_FREQ(1000);
+ TIMER0_CR = TIMER_ENABLE | TIMER_DIV_1 | TIMER_IRQ_REQ;
+ REG_IME = 1;
+
+ PALETTE[255] = RGB15(0,0,31);
+
+ initSprites();
+
+// videoSetModeSub(MODE_3_2D | DISPLAY_BG0_ACTIVE | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
+
+ // Convert texture from 24bit 888 to 16bit 1555, remembering to set top bit!
+ u8* srcTex = (u8 *) icons_raw;
+ for (int r = 32 * 160 ; r >= 0; r--) {
+ SPRITE_GFX_SUB[r] = 0x8000 | (srcTex[r * 3] >> 3) | ((srcTex[r * 3 + 1] >> 3) << 5) | ((srcTex[r * 3 + 2] >> 3) << 10);
+ SPRITE_GFX[r] = 0x8000 | (srcTex[r * 3] >> 3) | ((srcTex[r * 3 + 1] >> 3) << 5) | ((srcTex[r * 3 + 2] >> 3) << 10);
+ }
+
+ WAIT_CR &= ~(0x0080);
+ REG_WRAM_CNT = 0;
+
+}
+
+
+void setKeyboardIcon(bool enable) {
+ keyboardIcon = enable;
+}
+
+bool getKeyboardIcon() {
+ return keyboardIcon;
+}
+
+
+////////////////////
+// Pen stuff
+////////////////////
+
+
+void penInit() {
+ penDown = false;
+ penHeld = false;
+ penReleased = false;
+ penDownLastFrame = false;
+ penDownSaved = false;
+ penReleasedSaved = false;
+ penDownFrames = 0;
+ consumeKeys();
+}
+
+void penUpdate() {
+
+// if (getKeysHeld() & KEY_L) consolePrintf("%d, %d penX=%d, penY=%d tz=%d\n", IPC->touchXpx, IPC->touchYpx, penX, penY, IPC->touchZ1);
+
+ if ((penDownFrames > 1)) { // Is this right? Dunno, but it works for me.
+
+ if ((penHeld)) {
+ penHeld = true;
+ penDown = false;
+
+ if ((IPC->touchZ1 > 0) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0)) {
+ penX = IPC->touchXpx + touchXOffset;
+ penY = IPC->touchYpx + touchYOffset;
+ }
+
+ } else {
+ penDown = true;
+ penHeld = true;
+ penDownSaved = true;
+
+ //if ( (ABS(penX - IPC->touchXpx) < 10) && (ABS(penY - IPC->touchYpx) < 10) ) {
+ if ((IPC->touchZ1 > 0) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0)) {
+ penX = IPC->touchXpx;
+ penY = IPC->touchYpx;
+ }
+ //}
+ }
+
+ } else {
+ if (penHeld) {
+ penReleased = true;
+ penReleasedSaved = true;
+ } else {
+ penReleased = false;
+ }
+
+ penDown = false;
+ penHeld = false;
+ }
+
+
+ if ((IPC->touchZ1 > 0) || ((penDownFrames == 2)) ) {
+ penDownLastFrame = true;
+ penDownFrames++;
+ } else {
+ penDownLastFrame = false;
+ penDownFrames = 0;
+ }
+
+}
+
+int leftHandedSwap(int keys) {
+ // Start and select are unchanged
+ if (leftHandedMode) {
+ int result = keys & (~(KEY_R | KEY_L | KEY_Y | KEY_A | KEY_B | KEY_X | KEY_LEFT | KEY_RIGHT | KEY_UP | KEY_DOWN));
+
+ if (keys & KEY_L) result |= KEY_R;
+ if (keys & KEY_R) result |= KEY_L;
+
+ if (keys & KEY_LEFT) result |= KEY_Y;
+ if (keys & KEY_RIGHT) result |= KEY_A;
+ if (keys & KEY_DOWN) result |= KEY_B;
+ if (keys & KEY_UP) result |= KEY_X;
+
+ if (keys & KEY_Y) result |= KEY_LEFT;
+ if (keys & KEY_A) result |= KEY_RIGHT;
+ if (keys & KEY_B) result |= KEY_DOWN;
+ if (keys & KEY_X) result |= KEY_UP;
+
+ return result;
+ } else {
+ return keys;
+ }
+}
+
+void keysUpdate() {
+ scanKeys();
+ keysDownSaved |= leftHandedSwap(keysDown());
+ keysReleasedSaved |= leftHandedSwap(keysUp());
+}
+
+int getKeysDown() {
+ return keysDownSaved;
+}
+
+int getKeysHeld() {
+ return leftHandedSwap(keysHeld());
+}
+
+int getKeysReleased() {
+ return keysReleasedSaved;
+}
+
+void consumeKeys() {
+ keysDownSaved = 0;
+ keysReleasedSaved = 0;
+}
+
+bool getPenDown() {
+ return penDownSaved;
+}
+
+bool getPenHeld() {
+ return penHeld;
+}
+
+bool getPenReleased() {
+ return penReleasedSaved;
+}
+
+void consumePenEvents() {
+ penDownSaved = false;
+ penReleasedSaved = false;
+}
+
+int getPenX() {
+ int x = ((penX * touchScX) >> 8) + touchX;
+ x = x < 0? 0: (x > gameWidth - 1? gameWidth - 1: x);
+ return x;
+}
+
+int getPenY() {
+ int y = ((penY * touchScY) >> 8) + touchY;
+ y = y < 0? 0: (y > gameHeight - 1? gameHeight - 1: y);
+ return y;
+}
+
+GLvector getPenPos() {
+ GLvector v;
+
+ v.x = (penX * inttof32(1)) / SCREEN_WIDTH;
+ v.y = (penY * inttof32(1)) / SCREEN_HEIGHT;
+
+ return v;
+}
+
+void formatSramOption() {
+ consolePrintf("The following files are present in save RAM:\n");
+ DSSaveFileManager::instance()->listFiles();
+
+ consolePrintf("\nAre you sure you want to\n");
+ consolePrintf("DELETE all files?\n");
+ consolePrintf("A = Yes, X = No\n");
+
+ while (true) {
+ if (keysHeld() & KEY_A) {
+ DSSaveFileManager::instance()->formatSram();
+ consolePrintf("SRAM cleared!\n");
+ return;
+ }
+
+ if (keysHeld() & KEY_X) {
+ consolePrintf("Whew, that was close!\n");
+ return;
+ }
+ }
+}
+
+
+void setIndyFightState(bool st) {
+ indyFightState = st;
+ indyFightRight = true;
+}
+
+bool getIndyFightState() {
+ return indyFightState;
+}
+
+/////////////////
+// GBAMP
+/////////////////
+
+bool GBAMPAvail = false;
+
+void initGBAMP() {
+ FAT_InitFiles();
+ if (disc_IsInserted()) {
+ GBAMPAvail = true;
+ consolePrintf("Found flash card reader!\n");
+ } else {
+ GBAMPAvail = false;
+ consolePrintf("Flash card reader not found!\n");
+ }
+}
+
+bool isGBAMPAvailable() {
+ return GBAMPAvail;
+}
+
+
+
+/////////////////
+// Main
+/////////////////
+
+static const Common::String test("poo", 1, 16);
+
+
+
+int main(void)
+{
+ soundCallback = NULL;
+
+
+ initHardware();
+
+ // Let arm9 read cartridge
+ *((u16 *) (0x04000204)) &= ~0x0080;
+
+ lastCallbackFrame = 0;
+ tweak = 0;
+
+ indyFightState = false;
+ indyFightRight = true;
+
+ // CPU speed = 67108864
+ // 8 frames = 2946 368.5 bytes per fr
+
+// playSound(stretch, 47619, false);
+// playSound(twang, 11010, true); // 18640
+
+// bufferSize = 10;
+ bufferRate = 22050;
+ bufferFrame = 0;
+// bufferSamples = (bufferRate * bufferSize) / 60;
+ bufferSamples = 4096;
+
+ bufferFirstHalf = false;
+ bufferSecondHalf = true;
+
+ lastEventFrame = 0;
+ mouseMode = MOUSE_LEFT;
+
+
+
+
+ int bytes = (2 * (bufferSamples)) + 100;
+
+ soundBuffer = (s16 *) malloc(bytes * 2);
+
+
+ soundHiPart = true;
+/*
+ TIMER1_CR = 0;
+ TIMER1_DATA = TIMER_FREQ(bufferRate);
+ TIMER1_CR = TIMER_ENABLE | TIMER_DIV_1;
+
+ TIMER2_CR = 0;
+ TIMER2_DATA = 0xFFFF - (bufferSamples / 2);
+ TIMER2_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
+ */
+ // 2945 - 2947
+
+
+
+// for (int r = 2946; r < 3000; r++) {
+// soundBuffer[r] = 30000;
+// }
+
+
+
+ consolePrintf("------------------------\n");
+ consolePrintf("ScummVM DS\n");
+ consolePrintf("Ported by Neil Millstone\n");
+#ifdef DS_SCUMM_BUILD
+ consolePrintf("Version 0.61 build A\n");
+#else
+ consolePrintf("Version 0.61 build B\n");
+#endif
+ consolePrintf("------------------------\n");
+ consolePrintf("L/R + D-pad/pen: Scroll view\n");
+ consolePrintf("D-pad left: Left mouse button\n");
+ consolePrintf("D-pad right: Right mouse button\n");
+ consolePrintf("D-pad up: Hover mouse\n");
+ consolePrintf("D-pad down: Skip dialog line\n");
+ consolePrintf("B button: Skip cutscenes\n");
+ consolePrintf("Select: DS Options menu\n");
+ consolePrintf("Start: Game menu\n");
+ consolePrintf("Y (in game): Toggle console\n");
+ consolePrintf("X: Toggle keyboard\n");
+ consolePrintf("A: Swap screens\n");
+ consolePrintf("L + R on bootup: Clear SRAM\n\n");
+ consolePrintf("For a complete poo list see the\n");
+ consolePrintf("help screen.\npoo\n");
+
+
+ for (int r = 0; r < bytes; r++) {
+ soundBuffer[r] = 0;
+ }
+
+ consolePrintf("length=%d str='%s'\n", test.size(), test.c_str());
+
+ swiWaitForVBlank();
+ swiWaitForVBlank();
+ playSound(soundBuffer, (bufferSamples * 2), true);
+ swiWaitForVBlank();
+ swiWaitForVBlank();
+ swiWaitForVBlank();
+
+
+
+ // Create a file system node to force search for a zip file in GBA rom space
+ DSFileSystemNode* node = new DSFileSystemNode();
+ if (!node->getZip() || (!node->getZip()->isReady())) {
+ // If not found, init CF/SD driver
+ initGBAMP();
+ }
+ delete node;
+
+
+
+ updateStatus();
+
+
+// OSystem_DS::instance();
+ g_system = new OSystem_DS();
+ assert(g_system);
+
+ if ((keysHeld() & KEY_L) && (keysHeld() & KEY_R)) {
+ formatSramOption();
+ }
+
+// printf("'%s'", Common::ConfigManager::kTransientDomain.c_str());
+ //printf("'%s'", Common::ConfigManager::kApplicationDomain.c_str());
+
+
+ char* argv[2] = {"/scummvmds", "--config=scummvmb.ini"};
+#ifdef DS_NON_SCUMM_BUILD
+
+ while (1) {
+ scummvm_main(2, (char **) &argv);
+ }
+#else
+ while (1) {
+ scummvm_main(1, (char **) &argv);
+ }
+#endif
+
+
+ return 0;
+}
+
+}
+
+int main() {
+ DS::main();
+}
+/* ScummVMDS - Scumm Interpreter DS Port
+ * Copyright (C) 2002-2004 The ScummVM project and Neil Millstone
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#include <nds.h>
+
+#include <ARM9/console.h> //basic print funcionality
+
+#include <stdlib.h>
+#include "dsmain.h"
+#include "string.h"
+#include "system.h"
+#include "osystem_ds.h"
+#include "icons_raw.h"
+#include "gba_nds_fat.h"
+#include "disc_io.h"
+#include "config-manager.h"
+#include "engines/scumm/scumm.h"
+#include "keyboard_raw.h"
+#include "keyboard_pal_raw.h"
+#define V16(a, b) ((a << 12) | b)
+#include "touchkeyboard.h"
+#include "registers_alt.h"
+//#include "compact_flash.h"
+#include "dsoptions.h"
+
+namespace DS {
+
+// From console.c in NDSLib
+
+//location of cursor
+extern u8 row;
+extern u8 col;
+
+// Mouse mode
+enum MouseMode {
+ MOUSE_LEFT, MOUSE_RIGHT, MOUSE_HOVER, MOUSE_NUM_MODES
+};
+
+// Defines
+#define FRAME_TIME 17
+#define SCUMM_GAME_HEIGHT 142
+#define SCUMM_GAME_WIDTH 232
+
+int textureID;
+u16* texture;
+
+int frameCount;
+int currentTimeMillis;
+
+// Timer Callback
+int callbackInterval;
+int callbackTimer;
+OSystem::TimerProc callback;
+
+// Scaled
+bool scaledMode;
+int scX;
+int scY;
+
+int subScX;
+int subScY;
+int subScTargetX;
+int subScTargetY;
+int subScreenWidth = SCUMM_GAME_WIDTH;
+int subScreenHeight = SCUMM_GAME_HEIGHT;
+int subScreenScale = 256;
+
+
+
+// Sound
+int bufferSize;
+s16* soundBuffer;
+int bufferFrame;
+int bufferRate;
+int bufferSamples;
+bool soundHiPart;
+
+// Events
+int lastEventFrame;
+bool indyFightState;
+bool indyFightRight;
+
+OSystem::SoundProc soundCallback;
+void* soundParam;
+int lastCallbackFrame;
+bool bufferFirstHalf;
+bool bufferSecondHalf;
+
+// Saved buffers
+u8* savedBuffer = NULL;
+bool highBuffer;
+bool displayModeIs8Bit;
+
+// Game id
+u8 gameID;
+
+bool consoleEnable = true;
+bool gameScreenSwap = false;
+
+MouseMode mouseMode;
+
+// Sprites
+SpriteEntry sprites[128];
+SpriteEntry spritesMain[128];
+int tweak;
+
+// Shake
+int shakePos = 0;
+
+// Keyboard
+bool keyboardEnable = false;
+bool leftHandedMode = false;
+bool keyboardIcon = false;
+
+// Touch
+int touchScX, touchScY, touchX, touchY;
+
+// Dragging
+int dragStartX, dragStartY;
+bool dragging = false;
+int dragScX, dragScY;
+
+// Interface styles
+char gameName[32];
+
+// 8-bit surface size
+int gameWidth = 320;
+int gameHeight = 200;
+
+enum controlType {
+ CONT_SCUMM_ORIGINAL,
+ CONT_SCUMM_SAMNMAX,
+ CONT_SKY,
+ CONT_SIMON,
+};
+
+struct gameListType {
+ char gameId[16];
+ controlType control;
+};
+
+#define NUM_SUPPORTED_GAMES 15
+
+gameListType gameList[NUM_SUPPORTED_GAMES] = {
+ // Unknown game - use normal SCUMM controls
+ {"unknown", CONT_SCUMM_ORIGINAL},
+
+ // SCUMM games
+ {"maniac", CONT_SCUMM_ORIGINAL},
+ {"zak", CONT_SCUMM_ORIGINAL},
+ {"loom", CONT_SCUMM_ORIGINAL},
+ {"indy3", CONT_SCUMM_ORIGINAL},
+ {"atlantis", CONT_SCUMM_ORIGINAL},
+ {"monkey", CONT_SCUMM_ORIGINAL},
+ {"monkey2", CONT_SCUMM_ORIGINAL},
+ {"tentacle", CONT_SCUMM_ORIGINAL},
+ {"samnmax", CONT_SCUMM_SAMNMAX},
+
+ // Non-SCUMM games
+ {"sky", CONT_SKY},
+ {"simon1", CONT_SIMON},
+ {"simon2", CONT_SIMON},
+ {"gob1", CONT_SCUMM_ORIGINAL},
+ {"queen", CONT_SCUMM_ORIGINAL}
+};
+
+gameListType* currentGame = NULL;
+
+// Stylus
+#define ABS(x) ((x)>0?(x):-(x))
+
+bool penDown;
+bool penHeld;
+bool penReleased;
+bool penDownLastFrame;
+f32 penX, penY;
+int keysDownSaved;
+int keysReleasedSaved;
+
+bool penDownSaved;
+bool penReleasedSaved;
+int penDownFrames;
+int touchXOffset = 0;
+int touchYOffset = 0;
+
+u16 savedPalEntry255 = RGB15(31, 31, 31);
+
+
+extern "C" int scummvm_main(int argc, char *argv[]);
+void updateStatus();
+
+TransferSound soundControl;
+
+//plays an 8 bit mono sample at 11025Hz
+void playSound(const void* data, u32 length, bool loop, bool adpcm, int rate)
+{
+
+ if (!IPC->soundData) {
+ soundControl.count = 0;
+ }
+
+ soundControl.data[soundControl.count].data = data;
+ soundControl.data[soundControl.count].len = length | (loop? 0x80000000: 0x00000000);
+ soundControl.data[soundControl.count].rate = rate; // 367 samples per frame
+ soundControl.data[soundControl.count].pan = 64;
+ soundControl.data[soundControl.count].vol = 127;
+ soundControl.data[soundControl.count].format = adpcm? 2: 0;
+
+ soundControl.count++;
+
+ DC_FlushAll();
+ IPC->soundData = &soundControl;
+}
+
+void stopSound(int channel) {
+ playSound(NULL, 0, false, false, -channel);
+}
+
+void updateOAM() {
+ DC_FlushAll();
+ dmaCopy(sprites, OAM_SUB, 128 * sizeof(SpriteEntry));
+ dmaCopy(spritesMain, OAM, 128 * sizeof(SpriteEntry));
+}
+
+void setGameSize(int width, int height) {
+ gameWidth = width;
+ gameHeight = height;
+}
+
+int getGameWidth() {
+ return gameWidth;
+}
+
+int getGameHeight() {
+ return gameHeight;
+}
+
+void initSprites() {
+ for(int i = 0; i < 128; i++) {
+ sprites[i].attribute[0] = ATTR0_DISABLED;
+ sprites[i].attribute[1] = 0;
+ sprites[i].attribute[2] = 0;
+ sprites[i].attribute[3] = 0;
+ }
+
+ for(int i = 0; i < 128; i++) {
+ spritesMain[i].attribute[0] = ATTR0_DISABLED;
+ spritesMain[i].attribute[1] = 0;
+ spritesMain[i].attribute[2] = 0;
+ spritesMain[i].attribute[3] = 0;
+ }
+
+ updateOAM();
+}
+
+
+void saveGameBackBuffer() {
+#ifdef DISABLE_SCUMM
+ if (savedBuffer == NULL) savedBuffer = new u8[gameWidth * gameHeight];
+ for (int r = 0; r < 200; r++) {
+ memcpy(savedBuffer + (r * gameWidth), ((u8 *) (get8BitBackBuffer())) + (r * 512), gameWidth);
+ }
+#endif
+}
+
+void restoreGameBackBuffer() {
+#ifdef DISABLE_SCUMM
+ if (savedBuffer) {
+ for (int r = 0; r < 200; r++) {
+ memcpy(((u8 *) (BG_GFX_SUB)) + (r * 512), savedBuffer + (r * gameWidth), gameWidth);
+ memcpy(((u8 *) (get8BitBackBuffer())) + (r * 512), savedBuffer + (r * gameWidth), gameWidth);
+ }
+ delete savedBuffer;
+ savedBuffer = NULL;
+ }
+#endif
+
+#ifndef DISABLE_SCUMM
+ memset(get8BitBackBuffer(), 0, 512 * 256);
+ memset(BG_GFX_SUB, 0, 512 * 256);
+ if (Scumm::g_scumm) {
+ Scumm::g_scumm->markRectAsDirty(Scumm::kMainVirtScreen, 0, gameWidth - 1, 0, gameHeight - 1, 1);
+ Scumm::g_scumm->markRectAsDirty(Scumm::kTextVirtScreen, 0, gameWidth - 1, 0, gameHeight - 1, 1);
+ Scumm::g_scumm->markRectAsDirty(Scumm::kVerbVirtScreen, 0, gameWidth - 1, 0, gameHeight - 1, 1);
+ }
+#endif
+
+}
+
+
+void initGame() {
+ // This is a good time to check for left handed mode since the mode change is done as the game starts.
+ // There's probably a better way, but hey.
+// consolePrintf("initing game\n");
+
+ setOptions();
+
+ //strcpy(gameName, ConfMan.getActiveDomain().c_str());
+ strcpy(gameName, ConfMan.get("gameid").c_str());
+// consolePrintf("\n\n\n\nCurrent game: '%s' %d\n", gameName, gameName[0]);
+
+ currentGame = &gameList[0]; // Default game
+
+ for (int r = 0; r < NUM_SUPPORTED_GAMES; r++) {
+ if (!stricmp(gameName, gameList[r].gameId)) {
+ currentGame = &gameList[r];
+// consolePrintf("Game list num: %d\n", currentGame);
+ }
+ }
+
+
+}
+
+void setLeftHanded(bool enable) {
+ leftHandedMode = enable;
+}
+
+void setTouchXOffset(int x) {
+ touchXOffset = x;
+}
+
+void setTouchYOffset(int y) {
+ touchYOffset = y;
+}
+
+void setUnscaledMode(bool enable) {
+ scaledMode = !enable;
+}
+
+void displayMode8Bit() {
+
+ u16 buffer[32 * 32];
+
+ setKeyboardEnable(false);
+
+ if (!displayModeIs8Bit) {
+ for (int r = 0; r < 32 * 32; r++) {
+ buffer[r] = ((u16 *) SCREEN_BASE_BLOCK_SUB(4))[r];
+ }
+ }
+
+
+
+ videoSetMode(MODE_5_2D | (consoleEnable? DISPLAY_BG0_ACTIVE: 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+ videoSetModeSub(MODE_3_2D /*| DISPLAY_BG0_ACTIVE*/ | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
+
+ vramSetBankA(VRAM_A_MAIN_BG_0x6000000);
+ vramSetBankB(VRAM_B_MAIN_BG_0x6020000);
+
+ vramSetBankC(VRAM_C_SUB_BG_0x6200000);
+ vramSetBankD(VRAM_D_MAIN_BG_0x6040000);
+
+ vramSetBankH(VRAM_H_LCD);
+
+ BG3_CR = BG_BMP8_512x256 | BG_BMP_BASE(8);
+
+
+
+ BG3_XDX = (int) (((float) (gameWidth) / 256.0f) * 256);
+ BG3_XDY = 0;
+ BG3_YDX = 0;
+ BG3_YDY = (int) ((200.0f / 192.0f) * 256);
+
+ SUB_BG3_CR = BG_BMP8_512x256;
+
+
+
+ SUB_BG3_XDX = (int) (subScreenWidth / 256.0f * 256);
+ SUB_BG3_XDY = 0;
+ SUB_BG3_YDX = 0;
+ SUB_BG3_YDY = (int) (subScreenHeight / 192.0f * 256);
+
+
+ // Do text stuff
+ BG0_CR = BG_MAP_BASE(0) | BG_TILE_BASE(1);
+ BG0_Y0 = 0;
+
+ // Restore palette entry used by text in the front-end
+ PALETTE_SUB[255] = savedPalEntry255;
+
+ consoleInitDefault((u16*)SCREEN_BASE_BLOCK(0), (u16*)CHAR_BASE_BLOCK(1), 16);
+ consolePrintSet(0, 23);
+
+ if (!displayModeIs8Bit) {
+ for (int r = 0; r < 32 * 32; r++) {
+ ((u16 *) SCREEN_BASE_BLOCK(0))[r] = buffer[r];
+ }
+// dmaCopyHalfWords(3, (u16 *) SCREEN_BASE_BLOCK(0), buffer, 32 * 32 * 2);
+ }
+
+
+ if (!displayModeIs8Bit) restoreGameBackBuffer();
+ displayModeIs8Bit = true;
+
+ POWER_CR &= ~POWER_SWAP_LCDS;
+
+ keyboardEnable = false;
+ initGame();
+
+}
+
+void setGameID(int id) {
+ gameID = id;
+}
+
+void dummyHandler() {
+ REG_IF = IRQ_VBLANK;
+}
+
+void checkSleepMode() {
+ if (IPC->performArm9SleepMode) {
+
+ consolePrintf("ARM9 Entering sleep mode\n");
+
+ int intSave = REG_IE;
+ irqSet(IRQ_VBLANK, dummyHandler);
+// int irqHandlerSave = (int) IRQ_HANDLER;
+ REG_IE = IRQ_VBLANK;
+ //IRQ_HANDLER = dummyHandler;
+
+ int powerSave = POWER_CR;
+ POWER_CR &= ~POWER_ALL;
+
+ while (IPC->performArm9SleepMode) {
+ swiWaitForVBlank();
+ }
+
+ POWER_CR = powerSave;
+// IRQ_HANDLER = (void (*)()) irqHandlerSave;
+ irqSet(IRQ_VBLANK, VBlankHandler);
+ REG_IE = intSave;
+
+ consolePrintf("ARM9 Waking from sleep mode\n");
+ }
+}
+
+void setCursorIcon(const u8* icon, uint w, uint h, byte keycolor) {
+ if (currentGame->control != CONT_SCUMM_SAMNMAX)
+ return;
+
+ uint16 border = RGB15(24,24,24) | 0x8000;
+
+
+ int off = 48*64;
+ memset(SPRITE_GFX_SUB+off, 0, 64*64*2);
+
+ int pos = 190 - (w+2);
+
+
+
+ // make border
+ for (uint i=0; i<w+2; i++) {
+ SPRITE_GFX_SUB[off+i] = border;
+ SPRITE_GFX_SUB[off+(31)*64+i] = border;
+ }
+ for (uint i=1; i<31; i++) {
+ SPRITE_GFX_SUB[off+(i*64)] = border;
+ SPRITE_GFX_SUB[off+(i*64)+(w+1)] = border;
+ }
+
+ int offset = (32 - h) >> 1;
+
+ for (uint y=0; y<h; y++) {
+ for (uint x=0; x<w; x++) {
+ int color = icon[y*w+x];
+ if (color == keycolor) {
+ SPRITE_GFX_SUB[off+(y+1+offset)*64+(x+1)] = 0x8000; // black background
+ } else {
+ SPRITE_GFX_SUB[off+(y+1+offset)*64+(x+1)] = BG_PALETTE[color] | 0x8000;
+ }
+ }
+ }
+
+ sprites[1].attribute[0] = ATTR0_BMP | 150;
+ sprites[1].attribute[1] = ATTR1_SIZE_64 | pos;
+ sprites[1].attribute[2] = ATTR2_ALPHA(1) | 48;
+}
+
+
+
+
+void displayMode16Bit() {
+
+ u16 buffer[32 * 32 * 2];
+
+
+ if (displayModeIs8Bit) {
+ saveGameBackBuffer();
+ for (int r = 0; r < 32 * 32; r++) {
+ buffer[r] = ((u16 *) SCREEN_BASE_BLOCK(0))[r];
+ }
+ }
+
+
+ videoSetMode(MODE_5_2D | /*DISPLAY_BG0_ACTIVE |*/ DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP);
+ videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE |/* DISPLAY_BG1_ACTIVE |*/ DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
+
+ vramSetBankA(VRAM_A_MAIN_BG);
+ vramSetBankB(VRAM_B_MAIN_BG);
+ vramSetBankC(VRAM_C_MAIN_BG);
+ vramSetBankD(VRAM_D_MAIN_BG);
+ vramSetBankH(VRAM_H_SUB_BG);
+
+ BG3_CR = BG_BMP16_512x256;
+ highBuffer = false;
+
+ BG3_XDX = (int) (1.25f * 256);
+ BG3_XDY = 0;
+ BG3_YDX = 0;
+ BG3_YDY = (int) ((200.0f / 192.0f) * 256);
+
+ memset(BG_GFX, 0, 512 * 256 * 2);
+
+ savedPalEntry255 = PALETTE_SUB[255];
+ PALETTE_SUB[255] = RGB15(31,31,31);//by default font will be rendered with color 255
+
+ // Do text stuff
+ SUB_BG0_CR = BG_MAP_BASE(4) | BG_TILE_BASE(0);
+ SUB_BG0_Y0 = 0;
+
+ consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(4), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
+
+ if (displayModeIs8Bit) {
+ //dmaCopyHalfWords(3, (u16 *) SCREEN_BASE_BLOCK_SUB(0), buffer, 32 * 32 * 2);
+ for (int r = 0; r < 32 * 32; r++) {
+ ((u16 *) SCREEN_BASE_BLOCK_SUB(4))[r] = buffer[r];
+ }
+ }
+
+ consolePrintSet(0, 23);
+ consolePrintf("\n");
+
+ // Show keyboard
+ SUB_BG1_CR = BG_TILE_BASE(1) | BG_MAP_BASE(12);
+ //drawKeyboard(1, 12);
+
+ POWER_CR &= ~POWER_SWAP_LCDS;
+
+
+
+ displayModeIs8Bit = false;
+}
+
+
+void displayMode16BitFlipBuffer() {
+ if (!displayModeIs8Bit) {
+ u16* back = get16BitBackBuffer();
+
+// highBuffer = !highBuffer;
+// BG3_CR = BG_BMP16_512x256 | BG_BMP_RAM(highBuffer? 1: 0);
+
+ for (int r = 0; r < 512 * 256; r++) {
+ *(BG_GFX + r) = *(back + r);
+ }
+ }
+}
+
+void setShakePos(int shakePos) {
+ shakePos = shakePos;
+}
+
+
+u16* get16BitBackBuffer() {
+ return BG_GFX + 0x20000;
+}
+
+u16* get8BitBackBuffer() {
+ return BG_GFX + 0x10000; // 16bit qty!
+}
+
+void setSoundProc(OSystem::SoundProc proc, void* param) {
+// consolePrintf("Set sound callback");
+ soundCallback = proc;
+ soundParam = param;
+}
+
+// The sound system in ScummVM seems to always return stereo interleaved samples.
+// Here, I'm treating an 11Khz stereo stream as a 22Khz mono stream, which works sorta ok, but is
+// a horrible bodge. Any advice on how to change the engine to output mono would be greatly
+// appreciated.
+void doSoundCallback() {
+ if ((soundCallback)) {
+ lastCallbackFrame = frameCount;
+
+ for (int r = IPC->playingSection; r < IPC->playingSection + 4; r++) {
+ int chunk = r & 3;
+
+ if (IPC->fillNeeded[chunk]) {
+ IPC->fillNeeded[chunk] = false;
+ DC_FlushAll();
+ soundCallback(soundParam, (byte *) (soundBuffer + ((bufferSamples >> 2) * chunk)), bufferSamples >> 1);
+ IPC->fillNeeded[chunk] = false;
+ DC_FlushAll();
+ }
+
+ }
+
+ }
+}
+
+void doTimerCallback() {
+ if (callback) {
+ if (callbackTimer <= 0) {
+ callbackTimer += callbackInterval;
+ callback(callbackInterval);
+ }
+ }
+}
+
+void soundUpdate() {
+ if ((bufferFrame == 0)) {
+// playSound(soundBuffer, (bufferSamples * 2), true);
+ }
+// consolePrintf("%x\n", IPC->test);
+
+
+ if (bufferFrame == 0) {
+// bufferFirstHalf = true;
+ }
+ if (bufferFrame == bufferSize >> 1) {
+ //bufferSecondHalf = true;
+ }
+
+ bufferFrame++;
+ if (bufferFrame == bufferSize) {
+ bufferFrame = 0;
+ }
+}
+
+void memoryReport() {
+ int r = 0;
+ int* p;
+ do {
+ p = (int *) malloc(r * 8192);
+ free(p);
+ r++;
+ } while ((p) && (r < 512));
+
+ int t = -1;
+ void* block[1024];
+ do {
+ t++;
+ block[t] = (int *) malloc(4096);
+ } while ((t < 1024) && (block[t]));
+
+ for (int q = 0; q < t; q++) {
+ free(block[q]);
+ }
+
+ consolePrintf("Free: %dK, Largest: %dK\n", t * 4, r * 8);
+}
+
+
+void addIndyFightingKeys() {
+ OSystem_DS* system = OSystem_DS::instance();
+ OSystem::Event event;
+
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.flags = 0;
+
+ if ((getKeysDown() & KEY_L)) {
+ indyFightRight = false;
+ }
+
+ if ((getKeysDown() & KEY_R)) {
+ indyFightRight = true;
+ }
+
+ if ((getKeysDown() & KEY_UP)) {
+ event.kbd.keycode = '8';
+ event.kbd.ascii = '8';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_LEFT)) {
+ event.kbd.keycode = '4';
+ event.kbd.ascii = '4';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_RIGHT)) {
+ event.kbd.keycode = '6';
+ event.kbd.ascii = '6';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_DOWN)) {
+ event.kbd.keycode = '2';
+ event.kbd.ascii = '2';
+ system->addEvent(event);
+ }
+
+ if (indyFightRight) {
+
+ if ((getKeysDown() & KEY_X)) {
+ event.kbd.keycode = '9';
+ event.kbd.ascii = '9';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_A)) {
+ event.kbd.keycode = '6';
+ event.kbd.ascii = '6';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_B)) {
+ event.kbd.keycode = '3';
+ event.kbd.ascii = '3';
+ system->addEvent(event);
+ }
+
+ } else {
+
+ if ((getKeysDown() & KEY_X)) {
+ event.kbd.keycode = '7';
+ event.kbd.ascii = '7';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_A)) {
+ event.kbd.keycode = '4';
+ event.kbd.ascii = '4';
+ system->addEvent(event);
+ }
+ if ((getKeysDown() & KEY_B)) {
+ event.kbd.keycode = '1';
+ event.kbd.ascii = '1';
+ system->addEvent(event);
+ }
+
+ }
+
+
+ if ((getKeysDown() & KEY_Y)) {
+ event.kbd.keycode = '5';
+ event.kbd.ascii = '5';
+ system->addEvent(event);
+ }
+}
+
+
+void setKeyboardEnable(bool en) {
+ if (en == keyboardEnable) return;
+ keyboardEnable = en;
+ u16* backupBank = (u16 *) 0x6040000;
+
+ if (keyboardEnable) {
+
+
+ DS::drawKeyboard(1, 12, backupBank);
+
+
+ SUB_BG1_CR = BG_TILE_BASE(1) | BG_MAP_BASE(12);
+
+ if (displayModeIs8Bit) {
+ SUB_DISPLAY_CR |= DISPLAY_BG1_ACTIVE; // Turn on keyboard layer
+ SUB_DISPLAY_CR &= ~DISPLAY_BG3_ACTIVE; // Turn off game layer
+ } else {
+ SUB_DISPLAY_CR |= DISPLAY_BG1_ACTIVE; // Turn on keyboard layer
+ SUB_DISPLAY_CR &= ~DISPLAY_BG0_ACTIVE; // Turn off console layer
+ }
+ lcdSwap();
+ } else {
+
+
+ // Restore the palette that the keyboard has used
+ for (int r = 0; r < 256; r++) {
+ BG_PALETTE_SUB[r] = BG_PALETTE[r];
+ }
+
+
+ //restoreVRAM(1, 12, backupBank);
+
+ if (displayModeIs8Bit) {
+ // Copy the sub screen VRAM from the top screen - they should always be
+ // the same.
+ for (int r = 0; r < (512 * 256) >> 1; r++) {
+ BG_GFX_SUB[r] = get8BitBackBuffer()[r];
+ }
+
+ SUB_DISPLAY_CR &= ~DISPLAY_BG1_ACTIVE; // Turn off keyboard layer
+ SUB_DISPLAY_CR |= DISPLAY_BG3_ACTIVE; // Turn on game layer
+ } else {
+ SUB_DISPLAY_CR &= ~DISPLAY_BG1_ACTIVE; // Turn off keyboard layer
+ SUB_DISPLAY_CR |= DISPLAY_BG0_ACTIVE; // Turn on console layer
+ }
+
+ lcdSwap();
+ }
+}
+
+bool getKeyboardEnable() {
+ return keyboardEnable;
+}
+
+bool getIsDisplayMode8Bit() {
+ return displayModeIs8Bit;
+}
+
+void addEventsToQueue() {
+ OSystem_DS* system = OSystem_DS::instance();
+ OSystem::Event event;
+
+
+
+
+ if (system->isEventQueueEmpty()) {
+
+/*
+ if (getKeysDown() & KEY_L) {
+ tweak--;
+ consolePrintf("Tweak: %d\n", tweak);
+ IPC->tweakChanged = true;
+ }
+
+
+ if (getKeysDown() & KEY_R) {
+ tweak++;
+ consolePrintf("Tweak: %d\n", tweak);
+ IPC->tweakChanged = true;
+ }
+ */
+ if ((keysHeld() & KEY_L) && (keysHeld() & KEY_R)) {
+ memoryReport();
+ }
+
+ if (displayModeIs8Bit) {
+
+ if (!indyFightState) {
+
+
+ if ((getKeysDown() & KEY_B) && (!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
+ // consolePrintf("Pressing Esc");
+
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = 27;
+ event.kbd.ascii = 27;
+ event.kbd.flags = 0;
+ system->addEvent(event);
+ }
+
+ }
+
+
+
+ if ((!getIndyFightState()) && (getKeysDown() & KEY_Y)) {
+ consoleEnable = !consoleEnable;
+ if (displayModeIs8Bit) {
+ displayMode8Bit();
+ } else {
+ displayMode16Bit();
+ }
+ }
+
+
+ if (!((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) && (!getIndyFightState())) {
+
+ if ((getKeysDown() & KEY_A) && (!indyFightState)) {
+ gameScreenSwap = !gameScreenSwap;
+ }
+
+ if (!getPenHeld() || (mouseMode != MOUSE_HOVER)) {
+ if (getKeysDown() & KEY_LEFT) {
+ mouseMode = MOUSE_LEFT;
+ }
+ if (getKeysDown() & KEY_RIGHT) {
+ if (currentGame->control != CONT_SCUMM_SAMNMAX) {
+ mouseMode = MOUSE_RIGHT;
+ } else {
+ // If we're playing sam and max, click and release the right mouse
+ // button to change verb
+ OSystem::Event event;
+
+ event.type = OSystem::EVENT_RBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+
+ event.type = OSystem::EVENT_RBUTTONUP;
+ system->addEvent(event);
+ }
+ }
+ if (getKeysDown() & KEY_UP) {
+ mouseMode = MOUSE_HOVER;
+ }
+ }
+
+
+
+ }
+
+ if ((getKeysDown() & KEY_SELECT)) {
+ //scaledMode = !scaledMode;
+ //scY = 4;
+ showOptionsDialog();
+ }
+
+
+ }
+
+ if (!getIndyFightState() && !((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) && (getKeysDown() & KEY_X)) {
+ setKeyboardEnable(!keyboardEnable);
+ }
+
+ updateStatus();
+
+ OSystem::Event event;
+
+ if ((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
+ event.type = OSystem::EVENT_MOUSEMOVE;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ //consolePrintf("x=%d y=%d \n", getPenX(), getPenY());
+ }
+
+ if (!keyboardEnable) {
+ if ((mouseMode != MOUSE_HOVER) || (!displayModeIs8Bit)) {
+ if (getPenDown() && (!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
+ event.type = ((mouseMode == MOUSE_LEFT) || (!displayModeIs8Bit))? OSystem::EVENT_LBUTTONDOWN: OSystem::EVENT_RBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+
+ if (getPenReleased()) {
+ event.type = mouseMode == MOUSE_LEFT? OSystem::EVENT_LBUTTONUP: OSystem::EVENT_RBUTTONUP;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+ } else {
+ // In hover mode, D-pad left and right click the mouse when the pen is on the screen
+
+ if (getPenHeld()) {
+ if (getKeysDown() & KEY_LEFT) {
+ event.type = OSystem::EVENT_LBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+ /* if (getKeysReleased() & KEY_LEFT) {
+ event.type = OSystem::EVENT_LBUTTONUP;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }*/
+
+ if (getKeysDown() & KEY_RIGHT) {
+ event.type = OSystem::EVENT_RBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+ /*if (getKeysReleased() & KEY_RIGHT) {
+ event.type = OSystem::EVENT_RBUTTONUP;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }*/
+ }
+ }
+
+ if ((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R)) && (displayModeIs8Bit)) {
+ // Controls specific to the control method
+
+
+ if (currentGame->control == CONT_SKY) {
+ // Extra controls for Benieth a Steel Sky
+ if ((getKeysDown() & KEY_DOWN)) {
+ penY = 0;
+ penX = 0; // Show inventory by moving mouse onto top line
+ }
+ }
+
+ if (currentGame->control == CONT_SIMON) {
+ // Extra controls for Simon the Sorcerer
+ if ((getKeysDown() & KEY_DOWN)) {
+ OSystem::Event event;
+
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = '#'; // F10 or # - show hotspots
+ event.kbd.ascii = '#';
+ event.kbd.flags = 0;
+ system->addEvent(event);
+// consolePrintf("F10\n");
+ }
+ }
+
+ if (currentGame->control == CONT_SCUMM_ORIGINAL) {
+ // Extra controls for Scumm v1-5 games
+ if ((getKeysDown() & KEY_DOWN)) {
+ OSystem::Event event;
+
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = '.'; // Full stop - skips current dialogue line
+ event.kbd.ascii = '.';
+ event.kbd.flags = 0;
+ system->addEvent(event);
+ }
+
+ if (indyFightState) {
+ addIndyFightingKeys();
+ }
+
+ }
+
+ }
+ }
+
+ if (!displayModeIs8Bit) {
+ // Front end controls
+
+ if (leftHandedSwap(getKeysDown()) & KEY_UP) {
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = SDLK_UP;
+ event.kbd.ascii = 0;
+ event.kbd.flags = 0;
+ system->addEvent(event);
+
+ event.type = OSystem::EVENT_KEYUP;
+ system->addEvent(event);
+ }
+
+ if (leftHandedSwap(getKeysDown()) & KEY_DOWN) {
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = SDLK_DOWN;
+ event.kbd.ascii = 0;
+ event.kbd.flags = 0;
+ system->addEvent(event);
+
+ event.type = OSystem::EVENT_KEYUP;
+ system->addEvent(event);
+ }
+
+ if (leftHandedSwap(getKeysDown()) & KEY_A) {
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = SDLK_RETURN;
+ event.kbd.ascii = 0;
+ event.kbd.flags = 0;
+ system->addEvent(event);
+
+ event.type = OSystem::EVENT_KEYUP;
+ system->addEvent(event);
+ }
+
+ }
+
+
+ if ((getKeysDown() & KEY_START)) {
+ event.type = OSystem::EVENT_KEYDOWN;
+ event.kbd.keycode = 319; // F5
+ event.kbd.ascii = 319;
+ event.kbd.flags = 0;
+ system->addEvent(event);
+/*
+ event.type = OSystem::EVENT_KEYUP;
+ event.kbd.keycode = 319; // F5
+ event.kbd.ascii = 319;
+ system->addEvent(event);*/
+
+// consolePrintf("Pressing F5");
+ }
+
+
+ if (keyboardEnable) {
+ DS::addKeyboardEvents();
+ }
+
+ consumeKeys();
+
+ consumePenEvents();
+
+ }
+}
+
+void updateStatus() {
+ int offs;
+
+ if (displayModeIs8Bit) {
+ switch (mouseMode) {
+ case MOUSE_LEFT: {
+ offs = 16;
+ break;
+ }
+ case MOUSE_RIGHT: {
+ offs = 32;
+ break;
+ }
+ case MOUSE_HOVER: {
+ offs = 0;
+ break;
+ }
+ default: {
+ // Nothing!
+ offs = 0;
+ break;
+ }
+ }
+
+
+ sprites[0].attribute[0] = ATTR0_BMP | 150;
+ sprites[0].attribute[1] = ATTR1_SIZE_32 | 208;
+ sprites[0].attribute[2] = ATTR2_ALPHA(1)| offs;
+
+ if (indyFightState) {
+ sprites[2].attribute[0] = ATTR0_BMP | 150;
+ sprites[2].attribute[1] = ATTR1_SIZE_32 | (190 - 32) | (indyFightRight? 0: ATTR1_FLIP_X);
+ sprites[2].attribute[2] = ATTR2_ALPHA(1)| 48;
+ } else {
+ sprites[2].attribute[0] = ATTR0_DISABLED;
+ sprites[2].attribute[1] = 0;
+ sprites[2].attribute[2] = 0;
+ }
+ } else {
+ sprites[0].attribute[0] = ATTR0_DISABLED;
+ sprites[1].attribute[0] = ATTR0_DISABLED;
+ sprites[2].attribute[0] = ATTR0_DISABLED;
+ sprites[3].attribute[0] = ATTR0_DISABLED;
+ }
+
+ if ((keyboardIcon) && (!keyboardEnable) && (!displayModeIs8Bit)) {
+ spritesMain[0].attribute[0] = ATTR0_BMP | 160;
+ spritesMain[0].attribute[1] = ATTR1_SIZE_32 | 0;
+ spritesMain[0].attribute[2] = ATTR2_ALPHA(1) | 64;
+ } else {
+ spritesMain[0].attribute[0] = ATTR0_DISABLED;
+ spritesMain[0].attribute[1] = 0;
+ spritesMain[0].attribute[2] = 0;
+ spritesMain[0].attribute[3] = 0;
+ }
+
+}
+
+void soundBufferEmptyHandler() {
+ REG_IF = IRQ_TIMER2;
+
+ if (soundHiPart) {
+// bufferSecondHalf = true;
+ } else {
+// bufferFirstHalf = true;
+ }
+
+ soundHiPart = !soundHiPart;
+}
+
+void setMainScreenScroll(int x, int y) {
+ if (gameScreenSwap) {
+ SUB_BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
+ SUB_BG3_CY = y;
+ } else {
+ BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
+ BG3_CY = y;
+
+ touchX = x >> 8;
+ touchY = y >> 8;
+ }
+}
+
+void setMainScreenScale(int x, int y) {
+ if (gameScreenSwap) {
+ SUB_BG3_XDX = x;
+ SUB_BG3_XDY = 0;
+ SUB_BG3_YDX = 0;
+ SUB_BG3_YDY = y;
+ } else {
+ BG3_XDX = x;
+ BG3_XDY = 0;
+ BG3_YDX = 0;
+ BG3_YDY = y;
+
+ touchScX = x;
+ touchScY = y;
+ }
+}
+
+void setZoomedScreenScroll(int x, int y) {
+ if (gameScreenSwap) {
+ BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
+ BG3_CY = y;
+
+ touchX = x >> 8;
+ touchY = y >> 8;
+ } else {
+ SUB_BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
+ SUB_BG3_CY = y;
+ }
+}
+
+void setZoomedScreenScale(int x, int y) {
+ if (gameScreenSwap) {
+ BG3_XDX = x;
+ BG3_XDY = 0;
+ BG3_YDX = 0;
+ BG3_YDY = y;
+
+ touchScX = x;
+ touchScY = y;
+ } else {
+ SUB_BG3_XDX = x;
+ SUB_BG3_XDY = 0;
+ SUB_BG3_YDX = 0;
+ SUB_BG3_YDY = y;
+ }
+}
+
+void VBlankHandler(void) {
+// BG_PALETTE[0] = RGB15(31, 31, 31);
+// if (*((int *) (0x023FFF00)) != 0xBEEFCAFE) {
+ // consolePrintf("Guard band overwritten!");
+// }
+
+// consolePri ntf("X:%d Y:%d\n", getPenX(), getPenY());
+
+
+ IPC->tweak = tweak;
+ soundUpdate();
+
+
+
+
+ if ((!gameScreenSwap) && (!(getKeysHeld() & KEY_L) && !(getKeysHeld() & KEY_R))) {
+ if (currentGame) {
+ if (currentGame->control != CONT_SCUMM_SAMNMAX) {
+ if (getPenHeld() && (getPenY() < SCUMM_GAME_HEIGHT)) {
+ setTopScreenTarget(getPenX(), getPenY());
+ }
+ } else {
+ if (getPenHeld()) {
+ setTopScreenTarget(getPenX(), getPenY());
+ }
+ }
+ }
+ }
+
+
+ penUpdate();
+ keysUpdate();
+
+
+ frameCount++;
+
+
+
+ if (callback) {
+ callbackTimer -= FRAME_TIME;
+ }
+
+ if ((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) {
+
+ if ((!dragging) && (getPenHeld()) && (penDownFrames > 5)) {
+ dragging = true;
+ dragStartX = penX;
+ dragStartY = penY;
+
+ if (gameScreenSwap) {
+ dragScX = subScTargetX;
+ dragScY = subScTargetY;
+ } else {
+ dragScX = scX;
+ dragScY = scY;
+ }
+
+
+ }
+
+ if ((dragging) && (!getPenHeld())) {
+ dragging = false;
+ }
+
+ if (dragging) {
+
+ if (gameScreenSwap) {
+ subScTargetX = dragScX + ((dragStartX - penX) << 8);
+ subScTargetY = dragScY + ((dragStartY - penY) << 8);
+ } else {
+ scX = dragScX + ((dragStartX - penX));
+ scY = dragScY + ((dragStartY - penY));
+ }
+
+// consolePrintf("X:%d Y:%d\n", dragStartX - penX, dragStartY - penY);
+ }
+ }
+
+
+/* if ((frameCount & 1) == 0) {
+ SUB_BG3_CX = subScX;
+ } else {
+ SUB_BG3_CX = subScX + 64;
+ }
+
+ SUB_BG3_CY = subScY + (shakePos << 8);*/
+
+ /*SUB_BG3_XDX = (int) (subScreenWidth / 256.0f * 256);
+ SUB_BG3_XDY = 0;
+ SUB_BG3_YDX = 0;
+ SUB_BG3_YDY = (int) (subScreenHeight / 192.0f * 256);*/
+
+
+ if ((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) {
+ if ((getKeysHeld() & KEY_A) && (subScreenScale < 256)) {
+ subScreenScale += 3;
+ }
+
+ if ((getKeysHeld() & KEY_B) && (subScreenScale > 128)) {
+ subScreenScale -=3;
+ }
+
+ int xCenter = subScTargetX + ((subScreenWidth >> 1) << 8);
+ int yCenter = subScTargetY + ((subScreenHeight >> 1) << 8);
+
+ subScreenWidth = SCUMM_GAME_WIDTH * subScreenScale >> 8;
+ subScreenHeight = SCUMM_GAME_HEIGHT * subScreenScale >> 8;
+
+ subScTargetX = xCenter - ((subScreenWidth >> 1) << 8);
+ subScTargetY = yCenter - ((subScreenHeight >> 1) << 8);
+
+
+
+
+ if (subScTargetX < 0) subScTargetX = 0;
+ if (subScTargetX > (gameWidth - subScreenWidth) << 8) subScTargetX = (gameWidth - subScreenWidth) << 8;
+
+ if (subScTargetY < 0) subScTargetY = 0;
+ if (subScTargetY > (gameHeight - subScreenHeight) << 8) subScTargetY = (gameHeight - subScreenHeight) << 8;
+ }
+
+ subScX += (subScTargetX - subScX) >> 2;
+ subScY += (subScTargetY - subScY) >> 2;
+
+ if (displayModeIs8Bit) {
+
+ if ((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) {
+
+ int offsX = 0, offsY = 0;
+
+
+ if (getKeysHeld() & KEY_LEFT) {
+ offsX -= 1;
+ }
+
+ if (getKeysHeld() & KEY_RIGHT) {
+ offsX += 1;
+ }
+
+ if (getKeysHeld() & KEY_UP) {
+ offsY -= 1;
+ }
+
+ if (getKeysHeld() & KEY_DOWN) {
+ offsY += 1;
+ }
+
+ if (((gameScreenSwap) && (getKeysHeld() & KEY_L)) || ((!gameScreenSwap) && (getKeysHeld() & KEY_R))) {
+ subScTargetX += offsX << 8;
+ subScTargetY += offsY << 8;
+ } else {
+ scX += offsX;
+ scY += offsY;
+ }
+ }
+
+ if (!scaledMode) {
+
+ if (scX + 256 > gameWidth - 1) {
+ scX = gameWidth - 1 - 256;
+ }
+
+ if (scX < 0) {
+ scX = 0;
+ }
+
+ if (scY + 192 > gameHeight - 1) {
+ scY = gameHeight - 1 - 192;
+ }
+
+ if (scY < 0) {
+ scY = 0;
+ }
+
+ setZoomedScreenScroll(subScX, subScY);
+ setZoomedScreenScale(subScreenWidth, (subScreenHeight * 256) / 192);
+
+
+ setMainScreenScroll(scX << 8, (scY << 8) + (shakePos << 8));
+ setMainScreenScale(256, 256); // 1:1 scale
+
+ } else {
+
+ if (scY > gameHeight - 192 - 1) {
+ scY = gameHeight - 192 - 1;
+ }
+
+ if (scY < 0) {
+ scY = 0;
+ }
+
+ setZoomedScreenScroll(subScX, subScY);
+ setZoomedScreenScale(subScreenWidth, (subScreenHeight * 256) / 192);
+
+ setMainScreenScroll(64, (scY << 8) + (shakePos << 8));
+ setMainScreenScale(320, 256); // 1:1 scale
+
+ }
+ } else {
+ setZoomedScreenScroll(0, 0);
+ setZoomedScreenScale(320, 256);
+
+ setMainScreenScroll(0, 0);
+ setMainScreenScale(320, 256); // 1:1 scale
+ }
+
+ // Enable on screen keyboard when pen taps icon
+ if ((keyboardIcon) && (penX < 32) && (penY > 160) && (penHeld)) {
+ setKeyboardEnable(true);
+ }
+
+ if (keyboardEnable) {
+ if (DS::getKeyboardClosed()) {
+ setKeyboardEnable(false);
+ }
+ }
+
+ updateOAM();
+
+ //PALETTE[0] = RGB15(0, 0, 0);
+ REG_IF = IRQ_VBLANK;
+}
+
+int getMillis() {
+ return currentTimeMillis;
+// return frameCount * FRAME_TIME;
+}
+
+void setTimerCallback(OSystem::TimerProc proc, int interval) {
+// consolePrintf("Set timer proc %x, int %d\n", proc, interval);
+ callback = proc;
+ callbackInterval = interval;
+ callbackTimer = interval;
+}
+
+void timerTickHandler() {
+ REG_IF = IRQ_TIMER0;
+ if ((callback) && (callbackTimer > 0)) {
+ callbackTimer--;
+ }
+ currentTimeMillis++;
+}
+
+void setTalkPos(int x, int y) {
+// if (gameID != Scumm::GID_SAMNMAX) {
+// setTopScreenTarget(x, 0);
+// } else {
+ setTopScreenTarget(x, y);
+// }
+}
+
+void setTopScreenTarget(int x, int y) {
+ subScTargetX = (x - (subScreenWidth >> 1));
+ subScTargetY = (y - (subScreenHeight >> 1));
+
+ if (subScTargetX < 0) subScTargetX = 0;
+ if (subScTargetX > gameWidth - subScreenWidth) subScTargetX = gameWidth - subScreenWidth;
+
+ if (subScTargetY < 0) subScTargetY = 0;
+ if (subScTargetY > gameHeight - subScreenHeight) subScTargetY = gameHeight - subScreenHeight;
+
+ subScTargetX <<=8;
+ subScTargetY <<=8;
+}
+
+void initHardware() {
+ // Guard band
+//((int *) (0x023FFF00)) = 0xBEEFCAFE;
+
+
+ penInit();
+
+ powerON(POWER_ALL);
+/* vramSetBankA(VRAM_A_MAIN_BG);
+ vramSetBankB(VRAM_B_MAIN_BG);
+ vramSetBankC(VRAM_C_SUB_BG); */
+ vramSetBankI(VRAM_I_SUB_SPRITE);
+ vramSetBankG(VRAM_G_MAIN_SPRITE);
+
+ currentTimeMillis = 0;
+
+
+/*
+ // Set up a millisecond counter
+ TIMER0_CR = 0;
+ TIMER0_DATA = 0xFFFF;
+ TIMER0_CR = TIMER_ENABLE | TIMER_CASCADE;
+*/
+
+
+
+ PALETTE[255] = RGB15(0,31,0);
+
+ // Allocate save buffer for game screen
+// savedBuffer = new u8[320 * 200];
+ displayMode16Bit();
+
+ memset(BG_GFX, 0, 512 * 256 * 2);
+ scaledMode = true;
+ scX = 0;
+ scY = 0;
+ subScX = 0;
+ subScY = 0;
+ subScTargetX = 0;
+ subScTargetY = 0;
+
+ //lcdSwap();
+ POWER_CR &= ~POWER_SWAP_LCDS;
+
+ frameCount = 0;
+ callback = NULL;
+
+// vramSetBankH(VRAM_H_SUB_BG);
+
+
+// // Do text stuff
+ //BG0_CR = BG_MAP_BASE(0) | BG_TILE_BASE(1);
+// BG0_Y0 = 48;
+
+ PALETTE[255] = RGB15(31,31,31);//by default font will be rendered with color 255
+
+ //consoleInit() is a lot more flexible but this gets you up and running quick
+// consoleInitDefault((u16*)SCREEN_BASE_BLOCK(0), (u16*)CHAR_BASE_BLOCK(1), 16);
+ //consolePrintSet(0, 6);
+
+ //irqs are nice
+ irqInit();
+// irqInitHandler();
+ irqSet(IRQ_VBLANK, VBlankHandler);
+ irqSet(IRQ_TIMER0, timerTickHandler);
+ irqSet(IRQ_TIMER2, soundBufferEmptyHandler);
+
+ irqEnable(IRQ_VBLANK);
+ irqEnable(IRQ_TIMER0);
+ irqEnable(IRQ_TIMER2);
+
+
+ // Set up a millisecond timer
+ TIMER0_CR = 0;
+ TIMER0_DATA = (u32) TIMER_FREQ(1000);
+ TIMER0_CR = TIMER_ENABLE | TIMER_DIV_1 | TIMER_IRQ_REQ;
+ REG_IME = 1;
+
+ PALETTE[255] = RGB15(0,0,31);
+
+ initSprites();
+
+// videoSetModeSub(MODE_3_2D | DISPLAY_BG0_ACTIVE | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); //sub bg 0 will be used to print text
+
+ // Convert texture from 24bit 888 to 16bit 1555, remembering to set top bit!
+ u8* srcTex = (u8 *) icons_raw;
+ for (int r = 32 * 160 ; r >= 0; r--) {
+ SPRITE_GFX_SUB[r] = 0x8000 | (srcTex[r * 3] >> 3) | ((srcTex[r * 3 + 1] >> 3) << 5) | ((srcTex[r * 3 + 2] >> 3) << 10);
+ SPRITE_GFX[r] = 0x8000 | (srcTex[r * 3] >> 3) | ((srcTex[r * 3 + 1] >> 3) << 5) | ((srcTex[r * 3 + 2] >> 3) << 10);
+ }
+
+ WAIT_CR &= ~(0x0080);
+ REG_WRAM_CNT = 0;
+
+}
+
+
+void setKeyboardIcon(bool enable) {
+ keyboardIcon = enable;
+}
+
+bool getKeyboardIcon() {
+ return keyboardIcon;
+}
+
+
+////////////////////
+// Pen stuff
+////////////////////
+
+
+void penInit() {
+ penDown = false;
+ penHeld = false;
+ penReleased = false;
+ penDownLastFrame = false;
+ penDownSaved = false;
+ penReleasedSaved = false;
+ penDownFrames = 0;
+ consumeKeys();
+}
+
+void penUpdate() {
+
+// if (getKeysHeld() & KEY_L) consolePrintf("%d, %d penX=%d, penY=%d tz=%d\n", IPC->touchXpx, IPC->touchYpx, penX, penY, IPC->touchZ1);
+
+ if ((penDownFrames > 1)) { // Is this right? Dunno, but it works for me.
+
+ if ((penHeld)) {
+ penHeld = true;
+ penDown = false;
+
+ if ((IPC->touchZ1 > 0) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0)) {
+ penX = IPC->touchXpx + touchXOffset;
+ penY = IPC->touchYpx + touchYOffset;
+ }
+
+ } else {
+ penDown = true;
+ penHeld = true;
+ penDownSaved = true;
+
+ //if ( (ABS(penX - IPC->touchXpx) < 10) && (ABS(penY - IPC->touchYpx) < 10) ) {
+ if ((IPC->touchZ1 > 0) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0)) {
+ penX = IPC->touchXpx;
+ penY = IPC->touchYpx;
+ }
+ //}
+ }
+
+ } else {
+ if (penHeld) {
+ penReleased = true;
+ penReleasedSaved = true;
+ } else {
+ penReleased = false;
+ }
+
+ penDown = false;
+ penHeld = false;
+ }
+
+
+ if ((IPC->touchZ1 > 0) || ((penDownFrames == 2)) ) {
+ penDownLastFrame = true;
+ penDownFrames++;
+ } else {
+ penDownLastFrame = false;
+ penDownFrames = 0;
+ }
+
+}
+
+int leftHandedSwap(int keys) {
+ // Start and select are unchanged
+ if (leftHandedMode) {
+ int result = keys & (~(KEY_R | KEY_L | KEY_Y | KEY_A | KEY_B | KEY_X | KEY_LEFT | KEY_RIGHT | KEY_UP | KEY_DOWN));
+
+ if (keys & KEY_L) result |= KEY_R;
+ if (keys & KEY_R) result |= KEY_L;
+
+ if (keys & KEY_LEFT) result |= KEY_Y;
+ if (keys & KEY_RIGHT) result |= KEY_A;
+ if (keys & KEY_DOWN) result |= KEY_B;
+ if (keys & KEY_UP) result |= KEY_X;
+
+ if (keys & KEY_Y) result |= KEY_LEFT;
+ if (keys & KEY_A) result |= KEY_RIGHT;
+ if (keys & KEY_B) result |= KEY_DOWN;
+ if (keys & KEY_X) result |= KEY_UP;
+
+ return result;
+ } else {
+ return keys;
+ }
+}
+
+void keysUpdate() {
+ scanKeys();
+ keysDownSaved |= leftHandedSwap(keysDown());
+ keysReleasedSaved |= leftHandedSwap(keysUp());
+}
+
+int getKeysDown() {
+ return keysDownSaved;
+}
+
+int getKeysHeld() {
+ return leftHandedSwap(keysHeld());
+}
+
+int getKeysReleased() {
+ return keysReleasedSaved;
+}
+
+void consumeKeys() {
+ keysDownSaved = 0;
+ keysReleasedSaved = 0;
+}
+
+bool getPenDown() {
+ return penDownSaved;
+}
+
+bool getPenHeld() {
+ return penHeld;
+}
+
+bool getPenReleased() {
+ return penReleasedSaved;
+}
+
+void consumePenEvents() {
+ penDownSaved = false;
+ penReleasedSaved = false;
+}
+
+int getPenX() {
+ int x = ((penX * touchScX) >> 8) + touchX;
+ x = x < 0? 0: (x > gameWidth - 1? gameWidth - 1: x);
+ return x;
+}
+
+int getPenY() {
+ int y = ((penY * touchScY) >> 8) + touchY;
+ y = y < 0? 0: (y > gameHeight - 1? gameHeight - 1: y);
+ return y;
+}
+
+GLvector getPenPos() {
+ GLvector v;
+
+ v.x = (penX * inttof32(1)) / SCREEN_WIDTH;
+ v.y = (penY * inttof32(1)) / SCREEN_HEIGHT;
+
+ return v;
+}
+
+void formatSramOption() {
+ consolePrintf("The following files are present in save RAM:\n");
+ DSSaveFileManager::instance()->listFiles();
+
+ consolePrintf("\nAre you sure you want to\n");
+ consolePrintf("DELETE all files?\n");
+ consolePrintf("A = Yes, X = No\n");
+
+ while (true) {
+ if (keysHeld() & KEY_A) {
+ DSSaveFileManager::instance()->formatSram();
+ consolePrintf("SRAM cleared!\n");
+ return;
+ }
+
+ if (keysHeld() & KEY_X) {
+ consolePrintf("Whew, that was close!\n");
+ return;
+ }
+ }
+}
+
+
+void setIndyFightState(bool st) {
+ indyFightState = st;
+ indyFightRight = true;
+}
+
+bool getIndyFightState() {
+ return indyFightState;
+}
+
+/////////////////
+// GBAMP
+/////////////////
+
+bool GBAMPAvail = false;
+
+void initGBAMP() {
+ FAT_InitFiles();
+ if (disc_IsInserted()) {
+ GBAMPAvail = true;
+ consolePrintf("Found flash card reader!\n");
+ } else {
+ GBAMPAvail = false;
+ consolePrintf("Flash card reader not found!\n");
+ }
+}
+
+bool isGBAMPAvailable() {
+ return GBAMPAvail;
+}
+
+
+
+/////////////////
+// Main
+/////////////////
+
+static const Common::String test("poo", 1, 16);
+
+
+
+int main(void)
+{
+ soundCallback = NULL;
+
+
+ initHardware();
+
+ // Let arm9 read cartridge
+ *((u16 *) (0x04000204)) &= ~0x0080;
+
+ lastCallbackFrame = 0;
+ tweak = 0;
+
+ indyFightState = false;
+ indyFightRight = true;
+
+ // CPU speed = 67108864
+ // 8 frames = 2946 368.5 bytes per fr
+
+// playSound(stretch, 47619, false);
+// playSound(twang, 11010, true); // 18640
+
+// bufferSize = 10;
+ bufferRate = 22050;
+ bufferFrame = 0;
+// bufferSamples = (bufferRate * bufferSize) / 60;
+ bufferSamples = 4096;
+
+ bufferFirstHalf = false;
+ bufferSecondHalf = true;
+
+ lastEventFrame = 0;
+ mouseMode = MOUSE_LEFT;
+
+
+
+
+ int bytes = (2 * (bufferSamples)) + 100;
+
+ soundBuffer = (s16 *) malloc(bytes * 2);
+
+
+ soundHiPart = true;
+/*
+ TIMER1_CR = 0;
+ TIMER1_DATA = TIMER_FREQ(bufferRate);
+ TIMER1_CR = TIMER_ENABLE | TIMER_DIV_1;
+
+ TIMER2_CR = 0;
+ TIMER2_DATA = 0xFFFF - (bufferSamples / 2);
+ TIMER2_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_CASCADE;
+ */
+ // 2945 - 2947
+
+
+
+// for (int r = 2946; r < 3000; r++) {
+// soundBuffer[r] = 30000;
+// }
+
+
+
+ consolePrintf("------------------------\n");
+ consolePrintf("ScummVM DS\n");
+ consolePrintf("Ported by Neil Millstone\n");
+#ifdef DS_SCUMM_BUILD
+ consolePrintf("Version 0.61 build A\n");
+#else
+ consolePrintf("Version 0.61 build B\n");
+#endif
+ consolePrintf("------------------------\n");
+ consolePrintf("L/R + D-pad/pen: Scroll view\n");
+ consolePrintf("D-pad left: Left mouse button\n");
+ consolePrintf("D-pad right: Right mouse button\n");
+ consolePrintf("D-pad up: Hover mouse\n");
+ consolePrintf("D-pad down: Skip dialog line\n");
+ consolePrintf("B button: Skip cutscenes\n");
+ consolePrintf("Select: DS Options menu\n");
+ consolePrintf("Start: Game menu\n");
+ consolePrintf("Y (in game): Toggle console\n");
+ consolePrintf("X: Toggle keyboard\n");
+ consolePrintf("A: Swap screens\n");
+ consolePrintf("L + R on bootup: Clear SRAM\n\n");
+ consolePrintf("For a complete poo list see the\n");
+ consolePrintf("help screen.\npoo\n");
+
+
+ for (int r = 0; r < bytes; r++) {
+ soundBuffer[r] = 0;
+ }
+
+ consolePrintf("length=%d str='%s'\n", test.size(), test.c_str());
+
+ swiWaitForVBlank();
+ swiWaitForVBlank();
+ playSound(soundBuffer, (bufferSamples * 2), true);
+ swiWaitForVBlank();
+ swiWaitForVBlank();
+ swiWaitForVBlank();
+
+
+
+ // Create a file system node to force search for a zip file in GBA rom space
+ DSFileSystemNode* node = new DSFileSystemNode();
+ if (!node->getZip() || (!node->getZip()->isReady())) {
+ // If not found, init CF/SD driver
+ initGBAMP();
+ }
+ delete node;
+
+
+
+ updateStatus();
+
+
+// OSystem_DS::instance();
+ g_system = new OSystem_DS();
+ assert(g_system);
+
+ if ((keysHeld() & KEY_L) && (keysHeld() & KEY_R)) {
+ formatSramOption();
+ }
+
+// printf("'%s'", Common::ConfigManager::kTransientDomain.c_str());
+ //printf("'%s'", Common::ConfigManager::kApplicationDomain.c_str());
+
+
+ char* argv[2] = {"/scummvmds", "--config=scummvmb.ini"};
+#ifdef DS_NON_SCUMM_BUILD
+
+ while (1) {
+ scummvm_main(2, (char **) &argv);
+ }
+#else
+ while (1) {
+ scummvm_main(1, (char **) &argv);
+ }
+#endif
+
+
+ return 0;
+}
+
+}
+
+int main() {
+ DS::main();
+}