Version 6.0a with support for the Music Synthesizer.

This commit is contained in:
Dave Bernazzani 2025-01-04 08:01:47 -05:00
parent d9179b7b9a
commit 58aa9907b0
8 changed files with 217 additions and 95 deletions

View File

@ -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"

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -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
@ -45,6 +45,14 @@ void ECSKeyboard::resetInputConsumer()
// 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
// 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()
{
extern UINT8 bUseECS;
@ -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;

View File

@ -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
@ -880,6 +882,89 @@ UINT8 poll_touch_screen(UINT16 ctrl_disc, UINT16 ctrl_keys, UINT16 ctrl_side)
// And, finally, if the ECS keyboard is being shown, we must check for any presses on this virtual keyboard
// ---------------------------------------------------------------------------------------------------------
else if (bShowKeyboard)
{
// --------------------------------------------------------------------------------------------------------------
// 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.py >= 1 && touch.py < 40) // Keyboard Icon - switch back to ECS style keyboard
{
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;
}
}
}
// Otherwise check for the various synth keys...
if (touch.py >= 144) // Bottom Row... lowest notes
{
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
{
@ -897,75 +982,78 @@ UINT8 poll_touch_screen(UINT16 ctrl_disc, UINT16 ctrl_keys, UINT16 ctrl_side)
}
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
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 <= 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; // ;
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 <= 40)
{
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
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.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
else if (touch.py >= 155 && touch.py < 192) // Very bottom row... Ctrl, Shift, Space and RETURN
{
if (touch.px <= 28)
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(1,22,ecs_ctrl_key?1:0,ecs_ctrl_key ? (char*)"@": (char*)" ");
dsPrintValue(4,22,ecs_ctrl_key?1:0,ecs_ctrl_key ? (char*)"@": (char*)" ");
}
}
else if (touch.px <= 55)
else if (touch.px <= 70)
{
if (!ecs_debounce_timer)
{
ecs_shift_key ^= 1; // Shift is special
ecs_debounce_timer = 20;
dsPrintValue(5,22,0,ecs_shift_key ? (char*)"@": (char*)" ");
dsPrintValue(7,22,0,ecs_shift_key ? (char*)"@": (char*)" ");
}
}
else if (touch.px <= 194) ecs_key_pressed = 41; // Space
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
{
@ -974,6 +1062,7 @@ UINT8 poll_touch_screen(UINT16 ctrl_disc, UINT16 ctrl_keys, UINT16 ctrl_side)
}
}
}
}
else if (bShowDisc) // Full touch-screen disc overlay is shown... do our best to map to the 16-position disc using approximating rectangular areas...
{
if ((touch.px >= 117) && (touch.px < 144) && (touch.py >= 16) && (touch.py < 61)) ds_disc_input[ctrl_disc][0] = 1; // North

View File

@ -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)
{
@ -773,10 +779,19 @@ void show_overlay(u8 bShowKeyboard, u8 bShowDisc)
swiWaitForVBlank();
if (bShowKeyboard) // ECS keyboard overlay
{
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));
}
@ -804,11 +819,14 @@ void show_overlay(u8 bShowKeyboard, u8 bShowDisc)
swiWaitForVBlank();
if (bShowKeyboard) // ECS keyboard overlay
{
if (!bShowSynthesizer)
{
dsPrintValue(1,22,ecs_ctrl_key?1:0,ecs_ctrl_key ? (char*)"@": (char*)" ");
dsPrintValue(5,22,0,ecs_shift_key ? (char*)"@": (char*)" ");
}
}
}
// --------------------------------------------------------------------------
// Allow the user to pick an overlay file for the current game. This overlay

View File

@ -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];

Binary file not shown.