diff --git a/Makefile b/Makefile index a476a3e..b8d3421 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ include $(DEVKITARM)/ds_rules export TARGET := NINTV-DS export TOPDIR := $(CURDIR) -export VERSION := 6.0 +export VERSION := 6.0a ICON := -b $(CURDIR)/logo.bmp "NINTV-DS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/NINTV-DS" diff --git a/NINTV-DS.nds b/NINTV-DS.nds index 4e6ef3a..db67be9 100644 Binary files a/NINTV-DS.nds and b/NINTV-DS.nds differ diff --git a/arm9/gfx/bgBottom-ECS.png b/arm9/gfx/bgBottom-ECS.png index c048f6b..bf02a2d 100644 Binary files a/arm9/gfx/bgBottom-ECS.png and b/arm9/gfx/bgBottom-ECS.png differ diff --git a/arm9/source/emucore/ECSKeyboard.cpp b/arm9/source/emucore/ECSKeyboard.cpp index 50f281c..d853a41 100644 --- a/arm9/source/emucore/ECSKeyboard.cpp +++ b/arm9/source/emucore/ECSKeyboard.cpp @@ -1,5 +1,5 @@ // ===================================================================================== -// Copyright (c) 2021-2024 Dave Bernazzani (wavemotion-dave) +// Copyright (c) 2021-2025 Dave Bernazzani (wavemotion-dave) // // Copying and distribution of this emulator, its source code and associated // readme files, with or without modification, are permitted in any medium without @@ -43,7 +43,15 @@ void ECSKeyboard::resetInputConsumer() // 3 | v, c, f, r, 5, 4, t, g // 4 | x, z, s, w, 3, 2, e, d // 5 | space, down, up, q, 1, right, ctl, a -// 6 | [n/a], [n/a], [n/a], [n/a], [n/a], [n/a], [n/a], shift +// 6 | [n/a], [n/a], [n/a], [n/a], [n/a], [n/a], [n/a], shift + +// The music synth is much simpler... the lowest key on the synthesizer +// is left arrow (row 0, lowest bit). The highest key on the synth is +// row 6, lowest bit. This gives a total of 49 keys. Our emulation only +// handles a subset of these notes in the middle of the keyboard and +// we map the virtual synth overlay to the corresponding ECS keyboard +// key for simplicity. There isn't much software that uses the music +// synth - the only commercial game was Melody Blaster. void ECSKeyboard::evaluateInputs() { @@ -108,6 +116,12 @@ void ECSKeyboard::evaluateInputs() } +// ------------------------------------------------------------------------------------------------- +// There are two ways to read the keyboard from software... it can be read in normal key scanning +// fashion (row/column... write on 0xE and read on 0xF) or it can be 'transposed' which is done +// as column/row (write on 0xF and read on 0xE). Sometimes clever software will do both kinds of +// reads to try and eliminate key ghosting... we handle both flavors below to ensure compatibility. +// ------------------------------------------------------------------------------------------------- UINT16 ECSKeyboard::getInputValue(UINT8 port) { UINT16 inputValue = 0; diff --git a/arm9/source/nintv-ds.cpp b/arm9/source/nintv-ds.cpp index 2f6b20c..606ff2a 100644 --- a/arm9/source/nintv-ds.cpp +++ b/arm9/source/nintv-ds.cpp @@ -28,6 +28,7 @@ #include "bgTop.h" #include "bgMenu-Green.h" #include "bgMenu-White.h" +#include "inty-synth.h" #include "Emulator.h" #include "Rip.h" #include "highscore.h" @@ -57,6 +58,7 @@ UINT8 bGameLoaded __attribute__((section(".dtcm"))) = false; UINT8 bMetaSpeedup __attribute__((section(".dtcm"))) = false; UINT8 bShowDisc __attribute__((section(".dtcm"))) = false; UINT8 bShowKeyboard __attribute__((section(".dtcm"))) = false; +UINT8 bShowSynthesizer __attribute__((section(".dtcm"))) = false; // -------------------------------------------------- // A few variables that are not accessed frequently @@ -881,96 +883,183 @@ UINT8 poll_touch_screen(UINT16 ctrl_disc, UINT16 ctrl_keys, UINT16 ctrl_side) // --------------------------------------------------------------------------------------------------------- else if (bShowKeyboard) { - if (touch.py >= 14 && touch.py < 50) // Row: 1 2 3 4 5 6 7 8 9 0 ESC + // -------------------------------------------------------------------------------------------------------------- + // The Music Synth has 49 keys but due to the limitations of the DS screen and the fact that Melody Blaster + // only utilizes the middle part of the keyboard, we only handle 34 of the keys here... this is good + // enough to use the Synth for that one game... given that the touch screen can't press more than one key + // at a time (unlike a real piano/keyboard), and there isn't much software to support it... this is good enough. + // -------------------------------------------------------------------------------------------------------------- + if (bShowSynthesizer) { - if (touch.px <= 24) ecs_key_pressed = 1; - else if (touch.px <= 47) ecs_key_pressed = 2; - else if (touch.px <= 70) ecs_key_pressed = 3; - else if (touch.px <= 93) ecs_key_pressed = 4; - else if (touch.px <= 116) ecs_key_pressed = 5; - else if (touch.px <= 139) ecs_key_pressed = 6; - else if (touch.px <= 162) ecs_key_pressed = 7; - else if (touch.px <= 185) ecs_key_pressed = 8; - else if (touch.px <= 207) ecs_key_pressed = 9; - else if (touch.px <= 237) ecs_key_pressed = 10; - else if (touch.px <= 255) ecs_key_pressed = 43; - } - else if (touch.py >= 50 && touch.py < 85) // Row: QWERTY (top row) - { - if (touch.px <= 10) ecs_key_pressed = ecs_key_pressed; // Nothing here - if (touch.px <= 35) ecs_key_pressed = 27; // Q - else if (touch.px <= 58) ecs_key_pressed = 33; // W - else if (touch.px <= 81) ecs_key_pressed = 15; // E - else if (touch.px <= 103) ecs_key_pressed = 28; // R - else if (touch.px <= 127) ecs_key_pressed = 30; // T - else if (touch.px <= 150) ecs_key_pressed = 35; // Y - else if (touch.px <= 173) ecs_key_pressed = 31; // U - else if (touch.px <= 196) ecs_key_pressed = 19; // I - else if (touch.px <= 219) ecs_key_pressed = 25; // O - else if (touch.px <= 243) ecs_key_pressed = 26; // P - } - else if (touch.py >= 85 && touch.py < 120) // Row: ASDF (home row) - { - if (touch.px <= 18) ecs_key_pressed = ecs_key_pressed; // Nothing here - else if (touch.px <= 44) ecs_key_pressed = 11; // A - else if (touch.px <= 67) ecs_key_pressed = 29; // S - else if (touch.px <= 90) ecs_key_pressed = 14; // D - else if (touch.px <= 113) ecs_key_pressed = 16; // F - else if (touch.px <= 136) ecs_key_pressed = 17; // G - else if (touch.px <= 159) ecs_key_pressed = 18; // H - else if (touch.px <= 182) ecs_key_pressed = 20; // J - else if (touch.px <= 205) ecs_key_pressed = 21; // K - else if (touch.px <= 228) ecs_key_pressed = 22; // L - else if (touch.px <= 251) ecs_key_pressed = 44; // ; - } - else if (touch.py >= 120 && touch.py < 155) // Row: ZXCV (bottom row) - { - if (touch.px <= 40) + if (touch.py >= 1 && touch.py < 40) // Keyboard Icon - switch back to ECS style keyboard { - if ((touch.px <= 20) && (touch.py < 139)) ecs_key_pressed = 39; // UP - else if ((touch.px <= 40) && (touch.py < 139)) ecs_key_pressed = 37; // LEFT - else - if ((touch.px <= 20) && (touch.py < 155)) ecs_key_pressed = 38; // DOWN - else if ((touch.px <= 40) && (touch.py < 155)) ecs_key_pressed = 40; // RIGHT - } - else if (touch.px <= 64) ecs_key_pressed = 36; // Z - else if (touch.px <= 87) ecs_key_pressed = 34; // X - else if (touch.px <= 110) ecs_key_pressed = 13; // C - else if (touch.px <= 133) ecs_key_pressed = 32; // V - else if (touch.px <= 156) ecs_key_pressed = 12; // B - else if (touch.px <= 179) ecs_key_pressed = 24; // N - else if (touch.px <= 202) ecs_key_pressed = 23; // M - else if (touch.px <= 225) ecs_key_pressed = 45; // Comma - else if (touch.px <= 250) ecs_key_pressed = 46; // Period - } - else if (touch.py >= 155 && touch.py < 192) // Very bottom row... Shift, Space and RETURN - { - if (touch.px <= 28) - { - if (!ecs_debounce_timer) - { - ecs_ctrl_key ^= 1; // Ctrl is special - ecs_debounce_timer = 20; - - dsPrintValue(1,22,ecs_ctrl_key?1:0,ecs_ctrl_key ? (char*)"@": (char*)" "); + if (touch.px >= 213) + { + if (!ecs_debounce_timer) + { + bShowSynthesizer = 0; + ecs_debounce_timer = 20; + show_overlay(bShowKeyboard, bShowDisc); + return pad_pressed; + } + } + else if (touch.px >= 185) + { + if (!ecs_debounce_timer) + { + bShowKeyboard = 0; + ecs_debounce_timer = 20; + show_overlay(bShowKeyboard, bShowDisc); + return pad_pressed; + } } } - else if (touch.px <= 55) - { - if (!ecs_debounce_timer) - { - ecs_shift_key ^= 1; // Shift is special - ecs_debounce_timer = 20; - - dsPrintValue(5,22,0,ecs_shift_key ? (char*)"@": (char*)" "); - } - } - else if (touch.px <= 194) ecs_key_pressed = 41; // Space - else if (touch.px <= 231) ecs_key_pressed = 42; // Return - else if (touch.px <= 254) // Switch to Hand Controller + + // Otherwise check for the various synth keys... + + if (touch.py >= 144) // Bottom Row... lowest notes { - bShowKeyboard = 0; - show_overlay(bShowKeyboard, bShowDisc); + if (touch.px < 25) ecs_key_pressed = 9; + else if (touch.px < 51) ecs_key_pressed = 25; + else if (touch.px < 76) ecs_key_pressed = 24; + else if (touch.px < 102) ecs_key_pressed = 12; + else if (touch.px < 128) ecs_key_pressed = 35; + else if (touch.px < 153) ecs_key_pressed = 6; + else if (touch.px < 179) ecs_key_pressed = 20; + else if (touch.px < 204) ecs_key_pressed = 32; + else if (touch.px < 230) ecs_key_pressed = 16; + else if (touch.px < 254) ecs_key_pressed = 5; + } + else if (touch.py >= 114) // Bottom Row... black keys + { + if ((touch.px >= 14) && (touch.px < 38)) ecs_key_pressed = 8; + else if ((touch.px >= 38) && (touch.px < 64)) ecs_key_pressed = 22; + else if ((touch.px >= 90) && (touch.px < 114)) ecs_key_pressed = 18; + else if ((touch.px >= 114) && (touch.px < 140)) ecs_key_pressed = 7; + else if ((touch.px >= 140) && (touch.px < 164)) ecs_key_pressed = 31; + else if ((touch.px >= 192) && (touch.px < 216)) ecs_key_pressed = 13; + else if ((touch.px >= 216) && (touch.px < 242)) ecs_key_pressed = 28; + } + else if (touch.py >= 69) // Top Row... higher notes + { + if (touch.px < 25) ecs_key_pressed = 4; + else if (touch.px < 51) ecs_key_pressed = 17; + else if (touch.px < 76) ecs_key_pressed = 36; + else if (touch.px < 102) ecs_key_pressed = 33; + else if (touch.px < 128) ecs_key_pressed = 3; + else if (touch.px < 153) ecs_key_pressed = 15; + else if (touch.px < 179) ecs_key_pressed = 41; + else if (touch.px < 204) ecs_key_pressed = 38; + else if (touch.px < 230) ecs_key_pressed = 27; + else if (touch.px < 254) ecs_key_pressed = 40; + } + else if (touch.py >= 41) // Top Row... black keys + { + if ((touch.px >= 14) && (touch.px < 38)) ecs_key_pressed = 30; + else if ((touch.px >= 38) && (touch.px < 64)) ecs_key_pressed = 34; + else if ((touch.px >= 64) && (touch.px < 90)) ecs_key_pressed = 29; + else if ((touch.px >= 114) && (touch.px < 140)) ecs_key_pressed = 2; + else if ((touch.px >= 140) && (touch.px < 164)) ecs_key_pressed = 14; + else if ((touch.px >= 192) && (touch.px < 216)) ecs_key_pressed = 39; + else if ((touch.px >= 216) && (touch.px < 239)) ecs_key_pressed = 1; + } + } + else // This is a standard ECS keyboard + { + if (touch.py >= 14 && touch.py < 50) // Row: 1 2 3 4 5 6 7 8 9 0 ESC + { + if (touch.px <= 24) ecs_key_pressed = 1; + else if (touch.px <= 47) ecs_key_pressed = 2; + else if (touch.px <= 70) ecs_key_pressed = 3; + else if (touch.px <= 93) ecs_key_pressed = 4; + else if (touch.px <= 116) ecs_key_pressed = 5; + else if (touch.px <= 139) ecs_key_pressed = 6; + else if (touch.px <= 162) ecs_key_pressed = 7; + else if (touch.px <= 185) ecs_key_pressed = 8; + else if (touch.px <= 207) ecs_key_pressed = 9; + else if (touch.px <= 237) ecs_key_pressed = 10; + else if (touch.px <= 255) ecs_key_pressed = 43; + } + else if (touch.py >= 50 && touch.py < 85) // Row: QWERTY (top row) + { + if (touch.px <= 24) ecs_key_pressed = 39; // UP + else if (touch.px <= 47) ecs_key_pressed = 27; // Q + else if (touch.px <= 70) ecs_key_pressed = 33; // W + else if (touch.px <= 93) ecs_key_pressed = 15; // E + else if (touch.px <= 116) ecs_key_pressed = 28; // R + else if (touch.px <= 139) ecs_key_pressed = 30; // T + else if (touch.px <= 162) ecs_key_pressed = 35; // Y + else if (touch.px <= 185) ecs_key_pressed = 31; // U + else if (touch.px <= 207) ecs_key_pressed = 19; // I + else if (touch.px <= 237) ecs_key_pressed = 25; // O + else if (touch.px <= 255) ecs_key_pressed = 26; // P + } + else if (touch.py >= 85 && touch.py < 120) // Row: ASDF (home row) + { + if (touch.px <= 24) ecs_key_pressed = 38; // DOWN + else if (touch.px <= 47) ecs_key_pressed = 11; // A + else if (touch.px <= 70) ecs_key_pressed = 29; // S + else if (touch.px <= 93) ecs_key_pressed = 14; // D + else if (touch.px <= 116) ecs_key_pressed = 16; // F + else if (touch.px <= 139) ecs_key_pressed = 17; // G + else if (touch.px <= 162) ecs_key_pressed = 18; // H + else if (touch.px <= 185) ecs_key_pressed = 20; // J + else if (touch.px <= 207) ecs_key_pressed = 21; // K + else if (touch.px <= 237) ecs_key_pressed = 22; // L + else if (touch.px <= 255) ecs_key_pressed = 44; // ; + } + else if (touch.py >= 120 && touch.py < 155) // Row: ZXCV (bottom row) + { + if (touch.px <= 24) ecs_key_pressed = 37; // LEFT + else if (touch.px <= 47) ecs_key_pressed = 40; // RIGHT + else if (touch.px <= 70) ecs_key_pressed = 36; // Z + else if (touch.px <= 93) ecs_key_pressed = 34; // X + else if (touch.px <= 116) ecs_key_pressed = 13; // C + else if (touch.px <= 139) ecs_key_pressed = 32; // V + else if (touch.px <= 162) ecs_key_pressed = 12; // B + else if (touch.px <= 185) ecs_key_pressed = 24; // N + else if (touch.px <= 207) ecs_key_pressed = 23; // M + else if (touch.px <= 237) ecs_key_pressed = 45; // Comma + else if (touch.px <= 255) ecs_key_pressed = 46; // Period + } + else if (touch.py >= 155 && touch.py < 192) // Very bottom row... Ctrl, Shift, Space and RETURN + { + if (touch.px <= 24) // Musical Note swaps in the internal Music Synth keyboard overlay + { + if (!ecs_debounce_timer) + { + bShowSynthesizer = 1; + ecs_debounce_timer = 20; + show_overlay(bShowKeyboard, bShowDisc); + } + } + else if (touch.px <= 47) + { + if (!ecs_debounce_timer) + { + ecs_ctrl_key ^= 1; // Ctrl is special + ecs_debounce_timer = 20; + + dsPrintValue(4,22,ecs_ctrl_key?1:0,ecs_ctrl_key ? (char*)"@": (char*)" "); + } + } + else if (touch.px <= 70) + { + if (!ecs_debounce_timer) + { + ecs_shift_key ^= 1; // Shift is special + ecs_debounce_timer = 20; + + dsPrintValue(7,22,0,ecs_shift_key ? (char*)"@": (char*)" "); + } + } + else if (touch.px <= 193) ecs_key_pressed = 41; // Space + else if (touch.px <= 231) ecs_key_pressed = 42; // Return + else if (touch.px <= 254) // Switch to Hand Controller + { + bShowKeyboard = 0; + show_overlay(bShowKeyboard, bShowDisc); + } } } } diff --git a/arm9/source/overlay.cpp b/arm9/source/overlay.cpp index 5f3ad52..741ed96 100644 --- a/arm9/source/overlay.cpp +++ b/arm9/source/overlay.cpp @@ -27,6 +27,7 @@ #include "bgBottom.h" #include "bgBottom-ECS.h" #include "bgBottom-disc.h" +#include "inty-synth.h" #include "bgTop.h" #include "Emulator.h" #include "Rip.h" @@ -550,6 +551,11 @@ void load_custom_overlay(bool bCustomGeneric) // If we have a game (RIP) loaded, try to find a matching overlay if (currentRip != NULL) { + if (currentRip->GetCRC() == 0xFF68AA22) // Melody Blaster is the only game to want the Music Synth keyboard + { + bShowSynthesizer = 1; + } + // If user picked the special 'Generic Overlay' we force the generic overlay to be used instead... if (strcmp(currentRip->GetOverlayName(), "--Generic Overlay--") != 0) { @@ -774,11 +780,20 @@ void show_overlay(u8 bShowKeyboard, u8 bShowDisc) if (bShowKeyboard) // ECS keyboard overlay { - decompress(bgBottom_ECSTiles, bgGetGfxPtr(bg0b), LZ77Vram); - decompress(bgBottom_ECSMap, (void*) bgGetMapPtr(bg0b), LZ77Vram); - dmaCopy((void *) bgBottom_ECSPal,(u16*) BG_PALETTE_SUB,256*2); - // ECS Overlay... - memcpy(&myOverlay, &ecsOverlay, sizeof(myOverlay)); + if (bShowSynthesizer) + { + decompress(inty_synthTiles, bgGetGfxPtr(bg0b), LZ77Vram); + decompress(inty_synthMap, (void*) bgGetMapPtr(bg0b), LZ77Vram); + dmaCopy((void *) inty_synthPal,(u16*) BG_PALETTE_SUB,256*2); + } + else + { + decompress(bgBottom_ECSTiles, bgGetGfxPtr(bg0b), LZ77Vram); + decompress(bgBottom_ECSMap, (void*) bgGetMapPtr(bg0b), LZ77Vram); + dmaCopy((void *) bgBottom_ECSPal,(u16*) BG_PALETTE_SUB,256*2); + } + // ECS Overlay... + memcpy(&myOverlay, &ecsOverlay, sizeof(myOverlay)); } else // Default Overlay... which might be custom!! { @@ -805,8 +820,11 @@ void show_overlay(u8 bShowKeyboard, u8 bShowDisc) if (bShowKeyboard) // ECS keyboard overlay { - dsPrintValue(1,22,ecs_ctrl_key?1:0,ecs_ctrl_key ? (char*)"@": (char*)" "); - dsPrintValue(5,22,0,ecs_shift_key ? (char*)"@": (char*)" "); + if (!bShowSynthesizer) + { + dsPrintValue(1,22,ecs_ctrl_key?1:0,ecs_ctrl_key ? (char*)"@": (char*)" "); + dsPrintValue(5,22,0,ecs_shift_key ? (char*)"@": (char*)" "); + } } } diff --git a/arm9/source/overlay.h b/arm9/source/overlay.h index 78ba28b..b1b405b 100644 --- a/arm9/source/overlay.h +++ b/arm9/source/overlay.h @@ -78,6 +78,7 @@ struct Overlay_t #define CONTROLLER_DUAL_ACTION_A 2 #define CONTROLLER_DUAL_ACTION_B 3 +extern UINT8 bShowSynthesizer; extern struct Overlay_t myOverlay[OVL_MAX]; extern struct Overlay_t myDisc[DISC_MAX]; diff --git a/extras.zip b/extras.zip index 48e5d4c..d18b0d9 100644 Binary files a/extras.zip and b/extras.zip differ