From a2f557fe4a648bc42adde1b97c36cf56e919e46e Mon Sep 17 00:00:00 2001 From: ejaquay Date: Sat, 14 Feb 2026 10:07:34 -0500 Subject: [PATCH 01/14] Add new DLL export to get menu items New scheme for building the cartridge menu uses an export to fetch DLL menu items. Replaces previous add_menu_item callback. When DLL wishes to change it's menu it sends a notification to the Vcc main window which causes the entire menu to be rebuilt. Notification message and menu rebuilding has been added to vcc.exe Export has been added to mpi.dll for testing Still to do: add export to other DLL's --- CartridgeMenu.h | 11 +- Vcc.cpp | 42 ++++-- Vcc.vcxproj | 2 +- libcommon/include/vcc/bus/basic_cartridge.h | 3 +- libcommon/include/vcc/bus/cartridge.h | 4 +- libcommon/include/vcc/bus/cartridge_loader.h | 2 - libcommon/include/vcc/bus/cartridge_menu.h | 126 ++++++++++++++++++ .../include/vcc/bus/cartridge_menuitem.h | 21 +++ .../include/vcc/bus/cartridge_messages.h | 9 ++ libcommon/include/vcc/bus/cpak_cartridge.h | 5 +- .../vcc/bus/cpak_cartridge_definitions.h | 3 +- libcommon/libcommon.vcxproj | 2 + libcommon/src/bus/CartridgeInterface.txt | 4 +- libcommon/src/bus/basic_cartridge.cpp | 4 + libcommon/src/bus/cartridge_menu.cpp | 110 +++++++++++++++ libcommon/src/bus/cpak_cartridge.cpp | 52 ++++++-- mpi/mpi.cpp | 7 + mpi/multipak_cartridge.cpp | 27 ++++ mpi/multipak_cartridge.h | 2 + pakinterface.cpp | 44 +++++- pakinterface.h | 3 +- resource.h | 7 + 22 files changed, 441 insertions(+), 49 deletions(-) create mode 100644 libcommon/include/vcc/bus/cartridge_menu.h create mode 100644 libcommon/include/vcc/bus/cartridge_menuitem.h create mode 100644 libcommon/include/vcc/bus/cartridge_messages.h create mode 100644 libcommon/src/bus/cartridge_menu.cpp diff --git a/CartridgeMenu.h b/CartridgeMenu.h index 1111d9bd..a7908377 100644 --- a/CartridgeMenu.h +++ b/CartridgeMenu.h @@ -21,6 +21,7 @@ #include #include #include +#include // for menu item type // A menu ID is either a small unsigned integer less than or equal to 50 used // to identify cart menu functions with control id in the range 5000 - 5050. @@ -46,16 +47,6 @@ constexpr auto MID_CONTROL = 5000; // constexpr to convert menu id number to control id constexpr int ControlId(int id) { return MID_CONTROL + id; }; -// Menu item types, one of the following. -enum MenuItemType -{ - MIT_Head, // Menu header with no associated control, may have slave items - MIT_Slave, // Slave items with associated control in header submenu. - MIT_StandAlone, // Menu item with an associated control - MIT_Seperator, // Draws a horizontal line to seperate groups of menu items -}; - - struct CartMenuItem { std::string name; unsigned int menu_id; diff --git a/Vcc.cpp b/Vcc.cpp index 1585e005..be438159 100644 --- a/Vcc.cpp +++ b/Vcc.cpp @@ -78,6 +78,9 @@ #include "MMUMonitor.h" #include "ExecutionTrace.h" +#include +#include + #if USE_DEBUG_MOUSE #include "IDisplayDebug.h" #endif @@ -119,6 +122,7 @@ void raise_saved_keys(); void FunctionHelpBox(HWND); void SetupClock(); HMENU GetConfMenu(); +HMENU DrawCartMenu(HWND hWnd); // Globals static HANDLE hEMUThread ; @@ -133,7 +137,8 @@ static unsigned char FlagEmuStop=TH_RUNNING; bool IsShiftKeyDown(); -CartridgeMenu CartMenu; +CartridgeMenu CartMenu; //OLD +using VCC::Bus::gCartMenu; //NEW static bool gHasFocus {}; @@ -144,6 +149,7 @@ int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) { + MSG Msg; EmuState.WindowInstance = hInstance; @@ -164,6 +170,10 @@ int APIENTRY WinMain(_In_ HINSTANCE hInstance, LoadConfig(&EmuState); EmuState.ResetPending=2; // after LoadConfig pls InitInstance(hInstance, nCmdShow); + + // Fill initial cartridge menu before main win starts? + BuildCartMenu(); + if ((CmdArg.NoOutput && !CreateNullWindow(&EmuState)) || (!CmdArg.NoOutput && !CreateDDWindow(&EmuState))) { @@ -171,9 +181,9 @@ int APIENTRY WinMain(_In_ HINSTANCE hInstance, exit(0); } - // Set up the cartridge menu. This gets drawn after modules are loaded - CartMenu.init(); - BeginCartMenu(); + // initial set up the cartridge menu. + CartMenu.init(); //old + BeginCartMenu(); //old InitSound(); LoadModule(); @@ -303,7 +313,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) // Parse the menu selections: // Check if ID is in cartridge menu range - if ( (wmId >= MID_CONTROL) & (wmId < MID_CONTROL + 250) ) + if ( (wmId >= MID_CONTROL) & (wmId < MID_CONTROL + 200) ) { CartMenuActivated(wmId-MID_CONTROL); break; @@ -352,10 +362,16 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) break; case ID_FILE_RESET: + case IDC_MSG_CPU_RESET: if (EmuState.EmulationRunning) EmuState.ResetPending=2; break; + case IDC_MSG_UPD_MENU: + BuildCartMenu(); + DrawCartMenu(hWnd); + break; + case ID_FILE_RUN: EmuState.EmulationRunning=TRUE; InvalidateBoarder(); @@ -432,13 +448,14 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } break; -#ifdef _LEGACY_VCC case WM_CREATE: + DrawCartMenu(hWnd); +#ifdef _LEGACY_VCC { char title[80] = "Legacy "; strncat(title,g_szAppName,80); SetWindowTextA(hWnd,title); } - break; #endif + break; case WM_SETCURSOR: // Hide mouse cursor @@ -568,7 +585,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) if ( IsShiftKeyDown() ) { hMenu = GetConfMenu(); } else { - hMenu = CartMenu.draw(); + hMenu = DrawCartMenu(hWnd); } if (hMenu && EmuState.FullScreen) { RECT r; @@ -687,6 +704,15 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) return DefWindowProc(hWnd, message, wParam, lParam); } +//-------------------------------------------------------------------------- +// Draw the cartridge menu +//-------------------------------------------------------------------------- +HMENU DrawCartMenu (HWND hWnd) +{ + gCartMenu.log(); + return gCartMenu.draw(hWnd,5,"Cartridge"); +} + //-------------------------------------------------------------------------- // When the main window is about to lose keyboard focus there are one // or two keys down in the emulation that must be raised. These routines diff --git a/Vcc.vcxproj b/Vcc.vcxproj index 4c55ce8b..f1938c6e 100644 --- a/Vcc.vcxproj +++ b/Vcc.vcxproj @@ -303,4 +303,4 @@ - \ No newline at end of file + diff --git a/libcommon/include/vcc/bus/basic_cartridge.h b/libcommon/include/vcc/bus/basic_cartridge.h index e6d90932..ec390938 100644 --- a/libcommon/include/vcc/bus/basic_cartridge.h +++ b/libcommon/include/vcc/bus/basic_cartridge.h @@ -48,12 +48,11 @@ namespace VCC::Core void status(char* text_buffer, size_t buffer_size) override; unsigned short sample_audio() override; void menu_item_clicked(unsigned char menu_item_id) override; - + bool get_menu_item(menu_item_entry* item, size_t index) override; protected: virtual void initialize_pak(); virtual void initialize_bus(); }; - } diff --git a/libcommon/include/vcc/bus/cartridge.h b/libcommon/include/vcc/bus/cartridge.h index da92f934..422b99de 100644 --- a/libcommon/include/vcc/bus/cartridge.h +++ b/libcommon/include/vcc/bus/cartridge.h @@ -17,15 +17,14 @@ //////////////////////////////////////////////////////////////////////////////// #pragma once #include // defines LIBCOMMON_EXPORT if libcommon is a DLL +#include #include namespace VCC::Core { - struct LIBCOMMON_EXPORT cartridge { public: - // In Chet's workd strings get a typedef because that keeps things opaque using name_type = std::string; using catalog_id_type = std::string; using description_type = std::string; @@ -52,6 +51,7 @@ namespace VCC::Core virtual void status(char* text_buffer, size_t buffer_size) = 0; virtual unsigned short sample_audio() = 0; virtual void menu_item_clicked(unsigned char menu_item_id) = 0; + virtual bool get_menu_item(menu_item_entry* item, size_t index) = 0; }; } diff --git a/libcommon/include/vcc/bus/cartridge_loader.h b/libcommon/include/vcc/bus/cartridge_loader.h index e5d61729..1325bad4 100644 --- a/libcommon/include/vcc/bus/cartridge_loader.h +++ b/libcommon/include/vcc/bus/cartridge_loader.h @@ -68,7 +68,6 @@ namespace VCC::Core LIBCOMMON_EXPORT cartridge_loader_result load_cpak_cartridge( const std::string& filename, std::unique_ptr cartridge_context, -// void* const pakContainer, slot_id_type SlotId, const std::string& iniPath, HWND hVccWnd, @@ -77,7 +76,6 @@ namespace VCC::Core LIBCOMMON_EXPORT cartridge_loader_result load_cartridge( const std::string& filename, // Cartridge filename std::unique_ptr cartridge_context, // Loader context -// void* const pakContainer, // Pak container object slot_id_type SlotId, const std::string& iniPath, // Path of ini file HWND hVccWnd, // handle to main window diff --git a/libcommon/include/vcc/bus/cartridge_menu.h b/libcommon/include/vcc/bus/cartridge_menu.h new file mode 100644 index 00000000..b1705be1 --- /dev/null +++ b/libcommon/include/vcc/bus/cartridge_menu.h @@ -0,0 +1,126 @@ +//====================================================================== +// This file is part of VCC (Virtual Color Computer). +// Vcc is Copyright 2015 by Joseph Forgione +// +// VCC (Virtual Color Computer) is free software, you can redistribute +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see +// . +//====================================================================== + +#pragma once + +#include +#include +#include +#include +#include + +//----------------------------------------------------------------------- +// cartridge_menu objects hold cartridge menu lists. +// +// Every cartridge DLL that uses menu items holds a cartridge_menu +// list for it's items. When it modifies what is in it's list it posts +// a menu changed message to Vcc main. +// +// Menu building and drawing is controlled by the PakInterface and +// is initiated by VCC startup or by a menu changed message from +// one of the catridge DLL's. +// +// PakInterface builds the master cartridge_menu starting with it's +// own items. It then calls PakGetMenuItems to get and append items +// from the DLL in slot 0 (AKA the boot or side slot). +// +// If the MPI is in slot 0 it responds with it's own list plus the +// lists from each cartridge it has loaded, each via PakGetMenuItems +// calls to them. +//----------------------------------------------------------------------- + +namespace VCC::Bus { + +// menu_id is an unsigned int between 0 and 49 that can be used by +// a cart to identify menus it adds. Multipak will bias the Menu ID +// by 50 times SlotId to as mechanism to determine which slot a +// message is for. Control ID is used in windows messages to detect +// menu button pushes. 5000 is added to menu_id to generate these +// control messages. + +//----------------------------------------------------- +// Message ID 5000 - 5249 are reserved for cartridge menus +// Message ID 5251 - 5299 are reseverd for cartridge messaging +//----------------------------------------------------- + +// Menu ID <-> Command ID mapping +constexpr auto MID_CONTROL = 5000; +constexpr int ControlId(int id) { return MID_CONTROL + id; } + +// A single menu entry +struct CartMenuItem { + std::string name; + size_t menu_id; + MenuItemType type; +}; + +class cartridge_menu { + +private: + std::vector menu_; + +public: + + // Constructor maybe logs + cartridge_menu() { + PrintLogC("Construct\n"); + } + + // Clear all items + void clear() + { + PrintLogC("Clear\n"); + menu_.clear(); + } + + // Reserve capacity (for deterministic growth) + void reserve(size_t count) { menu_.reserve(count); } + + // Add a single item + void add(const std::string& name, unsigned int menu_id, MenuItemType type) + { + menu_.push_back({ name, menu_id, type }); + } + + CartMenuItem& operator[](size_t i) + { + return menu_[i]; + } + + // Number of items in list + size_t size() const { return menu_.size(); } + + // debug logging + void log() + { + for (size_t i = 0; i < menu_.size(); ++i) { + PrintLogC("%s %d %d\n", menu_[i].name.c_str(),menu_[i].menu_id,menu_[i].type); + } + } + + // Draw the menu (implemented in catridge_menu.cpp) + HMENU draw(HWND hWnd, + int position=3, + const std::string& title="Cartridge"); +}; + +// create global instance for Vcc.cpp and pakinterface to use. +extern cartridge_menu gCartMenu; + +} // namespace VCC::Bus diff --git a/libcommon/include/vcc/bus/cartridge_menuitem.h b/libcommon/include/vcc/bus/cartridge_menuitem.h new file mode 100644 index 00000000..b6264595 --- /dev/null +++ b/libcommon/include/vcc/bus/cartridge_menuitem.h @@ -0,0 +1,21 @@ +#pragma once + +enum MenuItemType +{ + MIT_Head, // Menu header, should have slave items + MIT_Slave, // Slave items with associated control in header submenu. + MIT_StandAlone, // Menu item with an associated control + MIT_Seperator, // Draws a horizontal line to seperate groups of menu items +}; + +// Define a C API safe struct for DLL ItemList export +// PakGetMenuItem(menu_item_entry* items, size_t* count) +struct menu_item_entry +{ + char name[256]; + size_t menu_id; + MenuItemType type; +}; + +// Sanity check maximum menu items +constexpr auto MAX_MENU_ITEMS = 200u; diff --git a/libcommon/include/vcc/bus/cartridge_messages.h b/libcommon/include/vcc/bus/cartridge_messages.h new file mode 100644 index 00000000..4912b660 --- /dev/null +++ b/libcommon/include/vcc/bus/cartridge_messages.h @@ -0,0 +1,9 @@ +// Messages sent to VCC main message loop + +//----------------------------------------------------- +// ID 5000 - 5249 are reserved for cartridge menus +// ID 5250 - 5299 are reseverd for cartridge messaging +//----------------------------------------------------- + +#define IDC_MSG_CPU_RESET 5260 +#define IDC_MSG_UPD_MENU 5261 diff --git a/libcommon/include/vcc/bus/cpak_cartridge.h b/libcommon/include/vcc/bus/cpak_cartridge.h index 666fe870..a342fcda 100644 --- a/libcommon/include/vcc/bus/cpak_cartridge.h +++ b/libcommon/include/vcc/bus/cpak_cartridge.h @@ -18,10 +18,10 @@ #pragma once #include #include +#include #include #include - namespace VCC::Core { @@ -55,7 +55,7 @@ namespace VCC::Core LIBCOMMON_EXPORT unsigned char read_memory_byte(unsigned short memory_address) override; LIBCOMMON_EXPORT unsigned short sample_audio() override; LIBCOMMON_EXPORT void menu_item_clicked(unsigned char menu_item_id) override; - + LIBCOMMON_EXPORT bool get_menu_item(menu_item_entry* item, size_t index) override; private: @@ -79,6 +79,7 @@ namespace VCC::Core const PakReadMemoryByteModuleFunction read_memory_byte_; const PakSampleAudioModuleFunction sample_audio_; const PakMenuItemClickedModuleFunction menu_item_clicked_; + const PakGetMenuItemFunction get_menu_item_; }; } diff --git a/libcommon/include/vcc/bus/cpak_cartridge_definitions.h b/libcommon/include/vcc/bus/cpak_cartridge_definitions.h index ead0739a..e5c39349 100644 --- a/libcommon/include/vcc/bus/cpak_cartridge_definitions.h +++ b/libcommon/include/vcc/bus/cpak_cartridge_definitions.h @@ -22,6 +22,7 @@ #pragma once #include +#include // for MenuItemType #include // for std::size_t #include @@ -74,5 +75,5 @@ extern "C" using PakReadPortModuleFunction = unsigned char (*)(unsigned char port); using PakSampleAudioModuleFunction = unsigned short (*)(); using PakMenuItemClickedModuleFunction = void (*)(unsigned char itemId); - + using PakGetMenuItemFunction = bool (*)(menu_item_entry* item, size_t index); } diff --git a/libcommon/libcommon.vcxproj b/libcommon/libcommon.vcxproj index 70dae6ae..bcf3d6f2 100644 --- a/libcommon/libcommon.vcxproj +++ b/libcommon/libcommon.vcxproj @@ -111,6 +111,7 @@ + @@ -127,6 +128,7 @@ + diff --git a/libcommon/src/bus/CartridgeInterface.txt b/libcommon/src/bus/CartridgeInterface.txt index c8a265dc..def960ba 100644 --- a/libcommon/src/bus/CartridgeInterface.txt +++ b/libcommon/src/bus/CartridgeInterface.txt @@ -103,8 +103,8 @@ DLL's can export any of the following calls Initiate pack (REQUIRED) PakInitialize (SLotId, settings_path, hVccWnd, &callbacks); - Retrieve cart menu (NEW) - PakGetMenuItems(menu_items, count); + Retrieve cart menu item + PakGetMenuItem(item, index); Get cart capabilities (PROPOSED) PakGetCapabilities (void); diff --git a/libcommon/src/bus/basic_cartridge.cpp b/libcommon/src/bus/basic_cartridge.cpp index c00ff288..9143b48f 100644 --- a/libcommon/src/bus/basic_cartridge.cpp +++ b/libcommon/src/bus/basic_cartridge.cpp @@ -84,4 +84,8 @@ namespace VCC::Core void basic_cartridge::initialize_bus() {} + bool basic_cartridge::get_menu_item( menu_item_entry* item, size_t index) + { + return false; + } } diff --git a/libcommon/src/bus/cartridge_menu.cpp b/libcommon/src/bus/cartridge_menu.cpp new file mode 100644 index 00000000..6edcf7da --- /dev/null +++ b/libcommon/src/bus/cartridge_menu.cpp @@ -0,0 +1,110 @@ +//#define USE_LOGGING +//====================================================================== +// This file is part of VCC (Virtual Color Computer). +// Vcc is Copyright 2015 by Joseph Forgione +// +// VCC (Virtual Color Computer) is free software, you can redistribute +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see +// . +//====================================================================== + +#include +#include + +namespace VCC::Bus { + +// Global cart menu for vcc.exe use +cartridge_menu gCartMenu; + +// ------------------------------------------------------------ +// Draw the menu. DLL's should not call this +// ------------------------------------------------------------ +HMENU cartridge_menu::draw(HWND hWnd, int position, const std::string& title) +{ + PrintLogC("Draw\n"); + auto hMenuBar = GetMenu(hWnd); + + // Erase the Existing Cartridge Menu. Vcc.rc defines + // a dummy Cartridge menu to preserve it's place. + DeleteMenu(hMenuBar,position,MF_BYPOSITION); + + // Create first sub menu item + HMENU hMenu = CreatePopupMenu(); + HMENU hMenu0 = hMenu; + + MENUITEMINFO Mii{}; + memset(&Mii,0,sizeof(MENUITEMINFO)); + Mii.cbSize= sizeof(MENUITEMINFO); + + // Create title bar item + Mii.fMask = MIIM_TYPE | MIIM_SUBMENU | MIIM_ID; // setting the submenu id + Mii.fType = MFT_STRING; // Type is a string + Mii.hSubMenu = hMenu; + Mii.dwTypeData = const_cast(title.c_str()); + Mii.cch = title.size(); + InsertMenuItem(hMenuBar,position,TRUE,&Mii); + + // Create sub menus in order + unsigned int pos = 0u; + for (CartMenuItem item : menu_) { + DLOG_C("%4d %d '%s'\n",item.menu_id,item.type,item.name.c_str()); +// should this also be done inside the loop? +// memset(&Mii,0,sizeof(MENUITEMINFO)); +// Mii.cbSize= sizeof(MENUITEMINFO); + switch (item.type) { + case MIT_Head: + hMenu = CreatePopupMenu(); + Mii.fMask = MIIM_TYPE | MIIM_SUBMENU | MIIM_ID; + Mii.fType = MFT_STRING; + Mii.hSubMenu = hMenu; + Mii.dwTypeData = const_cast(item.name.c_str()); + Mii.cch = item.name.size(); + InsertMenuItem(hMenu0,pos,TRUE,&Mii); + pos++; + break; + case MIT_Slave: + Mii.fMask = MIIM_TYPE | MIIM_ID; + Mii.fType = MFT_STRING; + Mii.wID = item.menu_id; + Mii.hSubMenu = hMenu; + Mii.dwTypeData = const_cast(item.name.c_str()); + Mii.cch=item.name.size(); + InsertMenuItem(hMenu,0,FALSE,&Mii); + break; + case MIT_Seperator: + Mii.fMask = MIIM_TYPE; + Mii.hSubMenu = hMenuBar; + Mii.dwTypeData = ""; + Mii.cch=0; + Mii.fType = MF_SEPARATOR; + InsertMenuItem(hMenu0,pos,TRUE,&Mii); + pos++; + break; + case MIT_StandAlone: + Mii.fMask = MIIM_TYPE | MIIM_ID; + Mii.wID = item.menu_id; + Mii.hSubMenu = hMenuBar; + Mii.dwTypeData = const_cast(item.name.c_str()); + Mii.cch=item.name.size(); + Mii.fType = MFT_STRING; + InsertMenuItem(hMenu0,pos,TRUE,&Mii); + pos++; + break; + } + } + DrawMenuBar(hWnd); + return hMenu0; +} + +} // namespace VCC::Bus + diff --git a/libcommon/src/bus/cpak_cartridge.cpp b/libcommon/src/bus/cpak_cartridge.cpp index 4c590f3c..105f3306 100644 --- a/libcommon/src/bus/cpak_cartridge.cpp +++ b/libcommon/src/bus/cpak_cartridge.cpp @@ -19,6 +19,7 @@ // TODO: Rename this to hardware_cartridge (cpak_cartridge?) #include +#include #include namespace VCC::Core @@ -75,6 +76,11 @@ namespace VCC::Core return ""; } + bool default_get_menu_item(menu_item_entry*, size_t) + { + return false; + } + } @@ -90,19 +96,34 @@ namespace VCC::Core configuration_path_(move(configuration_path)), hVccWnd_(hVccWnd), cpak_callbacks_(cpak_callbacks), - initialize_(GetImportedProcAddress(module_handle, "PakInitialize", nullptr)), - terminate_(GetImportedProcAddress(module_handle, "PakTerminate", default_stop)), - get_name_(GetImportedProcAddress(module_handle, "PakGetName", default_get_empty_string)), - get_catalog_id_(GetImportedProcAddress(module_handle, "PakGetCatalogId", default_get_empty_string)), - get_description_(GetImportedProcAddress(module_handle, "PakGetDescription", default_get_empty_string)), - reset_(GetImportedProcAddress(module_handle, "PakReset", default_reset)), - heartbeat_(GetImportedProcAddress(module_handle, "PakProcessHorizontalSync", default_heartbeat)), - status_(GetImportedProcAddress(module_handle, "PakGetStatus", default_status)), - write_port_(GetImportedProcAddress(module_handle, "PakWritePort", default_write_port)), - read_port_(GetImportedProcAddress(module_handle, "PakReadPort", default_read_port)), - read_memory_byte_(GetImportedProcAddress(module_handle, "PakReadMemoryByte", default_read_memory_byte)), - sample_audio_(GetImportedProcAddress(module_handle, "PakSampleAudio", default_sample_audio)), - menu_item_clicked_(GetImportedProcAddress(module_handle, "PakMenuItemClicked", default_menu_item_clicked)) + initialize_(GetImportedProcAddress( + module_handle, "PakInitialize", nullptr)), + terminate_(GetImportedProcAddress( + module_handle, "PakTerminate", default_stop)), + get_name_(GetImportedProcAddress( + module_handle, "PakGetName", default_get_empty_string)), + get_catalog_id_(GetImportedProcAddress( + module_handle, "PakGetCatalogId", default_get_empty_string)), + get_description_(GetImportedProcAddress( + module_handle, "PakGetDescription", default_get_empty_string)), + reset_(GetImportedProcAddress( + module_handle, "PakReset", default_reset)), + heartbeat_(GetImportedProcAddress( + module_handle, "PakProcessHorizontalSync", default_heartbeat)), + status_(GetImportedProcAddress( + module_handle, "PakGetStatus", default_status)), + write_port_(GetImportedProcAddress( + module_handle, "PakWritePort", default_write_port)), + read_port_(GetImportedProcAddress( + module_handle, "PakReadPort", default_read_port)), + read_memory_byte_(GetImportedProcAddress( + module_handle, "PakReadMemoryByte", default_read_memory_byte)), + sample_audio_(GetImportedProcAddress( + module_handle, "PakSampleAudio", default_sample_audio)), + menu_item_clicked_(GetImportedProcAddress( + module_handle, "PakMenuItemClicked", default_menu_item_clicked)), + get_menu_item_(GetImportedProcAddress( + module_handle, "PakGetMenuItem", default_get_menu_item)) { if (initialize_ == nullptr) { @@ -175,4 +196,9 @@ namespace VCC::Core menu_item_clicked_(menu_item_id); } + bool cpak_cartridge::get_menu_item(menu_item_entry* item, size_t index) + { + return get_menu_item_(item, index); + } + } diff --git a/mpi/mpi.cpp b/mpi/mpi.cpp index 9389ae6d..f822c1f3 100644 --- a/mpi/mpi.cpp +++ b/mpi/mpi.cpp @@ -23,6 +23,7 @@ #include #include #include +#include // for MenuItemType HINSTANCE gModuleInstance = nullptr; static std::string gConfigurationFilename; @@ -87,6 +88,12 @@ extern "C" gMultiPakInterface.menu_item_clicked(menu_item_id); } + // Fetch menu item list for MPI and carts it has loaded + __declspec(dllexport) bool PakGetMenuItem(menu_item_entry* item, size_t count) + { + return gMultiPakInterface.get_menu_item(item, count); + } + // Write to port __declspec(dllexport) void PakWritePort(unsigned char port_id,unsigned char value) { diff --git a/mpi/multipak_cartridge.cpp b/mpi/multipak_cartridge.cpp index 301df45a..a9a9f3c7 100644 --- a/mpi/multipak_cartridge.cpp +++ b/mpi/multipak_cartridge.cpp @@ -260,6 +260,33 @@ void multipak_cartridge::menu_item_clicked(unsigned char menu_item_id) } } +bool multipak_cartridge::get_menu_item( + menu_item_entry* item, size_t index) +{ + +// build list +// for (int mpi_slot = 3; mpi_slot >= 0; mpi_slot--) +// { +// return false; +// } + + // Test + switch (index) { + case 0: + strcpy(item->name,""); + item->menu_id = 0; + item->type = MIT_Seperator; + return true; + case 1: + strcpy(item->name,"MPI Config"); + item->menu_id = ControlId(19); + item->type = MIT_StandAlone; + return true; + default: + return false; + } +} + multipak_cartridge::label_type multipak_cartridge::slot_label(slot_id_type mpi_slot) const { diff --git a/mpi/multipak_cartridge.h b/mpi/multipak_cartridge.h index 874e2f5d..8d4a3dec 100644 --- a/mpi/multipak_cartridge.h +++ b/mpi/multipak_cartridge.h @@ -20,6 +20,7 @@ #include "multipak_configuration.h" #include #include +#include #include #include "../CartridgeMenu.h" #include @@ -67,6 +68,7 @@ class multipak_cartridge : public ::VCC::Core::cartridge void status(char* text_buffer, size_t buffer_size) override; unsigned short sample_audio() override; void menu_item_clicked(unsigned char menu_item_id) override; + bool get_menu_item(menu_item_entry* item, size_t index) override; // Multi-pak implementation label_type slot_label(slot_id_type slot) const; diff --git a/pakinterface.cpp b/pakinterface.cpp index 0509a8be..3a6c1768 100644 --- a/pakinterface.cpp +++ b/pakinterface.cpp @@ -19,13 +19,15 @@ #include "defines.h" #include "tcc1014mmu.h" #include "tcc1014registers.h" -#include "CartridgeMenu.h" +#include "CartridgeMenu.h" //OLD #include "pakinterface.h" #include "config.h" #include "Vcc.h" #include "mc6821.h" #include "resource.h" #include +#include +#include #include #include #include @@ -69,7 +71,7 @@ struct vcc_cartridge_context : public ::VCC::Core::cartridge_context void reset() override { - //SendMessage(EmuState.WindowHandle,WM_COMMAND,(WPARAM) ID_FILE_RESET,(LPARAM) 0); + //SendMessage(EmuState.WindowHandle,WM_COMMAND,(WPARAM) IDC_MSG_CPU_RESET,(LPARAM) 0); EmuState.ResetPending = 2; } @@ -188,8 +190,38 @@ unsigned short PackAudioSample() return gActiveCartrige->sample_audio(); } +// Temporary bridge from old to new + + +// Build entries for cartridge menu. +void BuildCartMenu() +{ + // lock goes into program paks, not needed here + //VCC::Util::section_locker lock(gPakMutex); + using VCC::Bus::gCartMenu; + gCartMenu.clear(); + gCartMenu.add("Cartridge", 0, MIT_Head); + if (!gActiveCartrige->name().empty()) { + std::string tmp = "Eject " + gActiveCartrige->name(); + gCartMenu.add(tmp, ControlId(2), MIT_Slave); + // Add items from loaded pak + menu_item_entry item; + for (size_t index=0;indexget_menu_item(&item,index)) { + gCartMenu.add(item.name,item.menu_id,item.type); + } else { + break; + } + } + } else { + gCartMenu.add("Load MPI", ControlId(3), MIT_Slave); + gCartMenu.add("Load DLL", ControlId(1), MIT_Slave); + gCartMenu.add("Load ROM", ControlId(4), MIT_Slave); + } +} + // Create entries for cartridge menu. The rest will be for MPI -// ControlId(MenuId) set what control does +// ControlId(MenuId) set what control does **OLD*** void BeginCartMenu() { VCC::Util::section_locker lock(gPakMutex); @@ -321,7 +353,8 @@ static cartridge_loader_status load_any_cartridge(const char *filename, const ch strcpy(DllPath, filename); gActiveCartrige = move(loadedCartridge.cartridge); gActiveModule = move(loadedCartridge.handle); - BeginCartMenu(); + BeginCartMenu(); // OLD + SendMessage(EmuState.WindowHandle,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); // initialize the cartridge gActiveCartrige->start(); @@ -342,7 +375,8 @@ void UnloadDll() gActiveCartrige = std::make_unique(); gActiveModule.reset(); - BeginCartMenu(); + BeginCartMenu(); //OLD + SendMessage(EmuState.WindowHandle,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); gActiveCartrige->start(); } diff --git a/pakinterface.h b/pakinterface.h index d82fc7cd..93888a6e 100644 --- a/pakinterface.h +++ b/pakinterface.h @@ -32,6 +32,7 @@ void GetCurrentModule(char *); void UpdateBusPointer(); void UnloadDll(); void UnloadPack(); -void BeginCartMenu(); +void BeginCartMenu(); //Remove this after testing +void BuildCartMenu(); void CartMenuActivated(unsigned int); diff --git a/resource.h b/resource.h index a01e7243..ebd4d8a0 100644 --- a/resource.h +++ b/resource.h @@ -412,6 +412,12 @@ #define IDC_EDIT_RANGE_BEG 2152 #define IDC_EDIT_RANGE_END 2153 #define IDC_EDIT_RANGE_SEP 2154 + +//----------------------------------------------------- +// ID 5000 - 5249 are reserved for cartridge menus +// ID 5251 - 5299 are reseverd for cartridge messaging +//----------------------------------------------------- + #define IDM_USER_WIKI 40001 #define ID_FILE_EXIT 40002 #define IDM_HELP_ABOUT 40003 @@ -464,6 +470,7 @@ #define ID_BITBANGER_CONFIG 40057 #define ID_SWAP_JOYSTICKS 40058 #define IDM_HELP_FUNKEY 40059 + #define ID_CONFIGURE_OPTIONS 65535 From 1c994cc1fe645d8ec8cfe8e3ae9b0f90a266351a Mon Sep 17 00:00:00 2001 From: ejaquay Date: Sat, 14 Feb 2026 13:16:31 -0500 Subject: [PATCH 02/14] Update CartridgeMenuSystem document --- libcommon/include/vcc/bus/cartridge_menu.h | 12 +-- libcommon/src/bus/CartridgeMenuSystem.txt | 87 ++++++++++------------ libcommon/src/bus/cartridge_menu.cpp | 1 - 3 files changed, 43 insertions(+), 57 deletions(-) diff --git a/libcommon/include/vcc/bus/cartridge_menu.h b/libcommon/include/vcc/bus/cartridge_menu.h index b1705be1..8d48afc7 100644 --- a/libcommon/include/vcc/bus/cartridge_menu.h +++ b/libcommon/include/vcc/bus/cartridge_menu.h @@ -77,17 +77,11 @@ class cartridge_menu { public: - // Constructor maybe logs - cartridge_menu() { - PrintLogC("Construct\n"); - } + // Constructor + cartridge_menu() {} // Clear all items - void clear() - { - PrintLogC("Clear\n"); - menu_.clear(); - } + void clear() { menu_.clear(); } // Reserve capacity (for deterministic growth) void reserve(size_t count) { menu_.reserve(count); } diff --git a/libcommon/src/bus/CartridgeMenuSystem.txt b/libcommon/src/bus/CartridgeMenuSystem.txt index c2fa2326..0269f5b6 100644 --- a/libcommon/src/bus/CartridgeMenuSystem.txt +++ b/libcommon/src/bus/CartridgeMenuSystem.txt @@ -1,80 +1,73 @@ -# **VCC Cartridge Export Based Menu System** +# VCC Export Based Cartridge Menu System -This replaces per‑item callbacks with a single export‑based model for exchanging menu +This replaces per‑item callbacks with a export‑based model for exchanging menu items between cartridge DLLs, Multipak (MPI), and the PakInterface host. Concept: -- Each cartridge DLL maintains its own internal list of menu items. -- Each DLL exposes **one export** that returns its entire menu list on demand. +- Each cartridge DLL creates an internal list of it's menu items as needed. +- DLL's expose an export that returns menu items from the list on demand. - MPI aggregates child cartridge menus, applies slot‑based ID biasing, and returns a - unified list to the host. -- The host rebuilds the UI menu from the aggregated list. + unified list to the host. +- The host pakinterface rebuilds the UI menu from the aggregated list. - DLLs notify the host of menu changes using a single Windows message. - -Benefits: - -- Menu state is always derived from a **single export call**, not a sequence of callbacks. -- DLLs do not depend on host internals, callback tables, or routing logic. - Clear separation of responsibilities: - - DLLs own their menu state. - - MPI aggregates and biases. - - Host renders. -- The export signature and struct layout remain stable even if internal implementations change. + - DLLs own their menu state. + - MPI aggregates and biases. + - Host renders. +- The export signature remains stable even if internal implementations change. --- -## **Component Details** - -### **Cartridge DLL** +## Cartridge DLL -A cartridge DLL: +- Sends IDC_MSG_UPD_MENU to the host on internal state changes that affect its menu. +- Keeps a static list of menu items that represents it's internal state. +- Implements a GetMenuItemList(item,index) export that: + - Updates the list as required (see note) + - Accepts a index that indicate which entry is desired. + - Returns the entry at that index in the item buffer. + - Returns false if the entry does not exist. -- Maintains a **static internal list** of its menu items. -- Updates this list whenever its internal state changes. -- Sends **WM_VCC_MENU_CHANGED** to the host after updating its list. -- Implements a single GetMenuItemList export that: - - Accepts a pointer to a buffer of menu items (or `nullptr` for size query). - - Accepts a pointer to a count value. - - Interprets the count as: - - **Input:** maximum number of items the host can accept. - - **Output:** total number of items the DLL has (or number copied). -- Never copies more items than the host indicates. -- Returns failure if not all items could be copied. -- Protects the list from export access while it is being updated. +Notes: -If the buffer pointer is `nullptr`, the DLL sets count to the number of items it has. -If the buffer pointer is not `nullptr`, the DLL copies up to the specified count. +If the item buffer is a nullptr the DLL returns false. +If the index is above MAX_MENU_ITEMS DLL returns false. +An index of zero indicates the DLL's internal list should be refreshed. + - DLL updates / recreates it's internal list as required. + - DLL returns the first item if it exists, otherwise false. +For indexes above zero the DLL simply returns the item or false. +Cartridge plumbing guarantees that DLL's who don't expose the actual +export will return false when call is attempted. --- -### **Multipak (MPI)** +## Multipak (MPI) -MPI acts as an **aggregator** and applies deterministic slot‑based menu ID biasing. +MPI acts as an aggregator and applies deterministic slot‑based menu ID biasing. The MPI is only permitted to be installed in the boot slot. (Coco side slot) MPI: -- Maintains references to each child cartridge’s menu export. +- Maintains references to each child cartridge’s menu export. - When its export is called: - - Generates MPI’s own menu items. - - Calls each child cartridge’s export to retrieve their items. - - Applies **slot‑based menu ID biasing**: - - Each slot receives a unique bias range. - - Biasing is applied only by MPI. - - DLLs remain unaware of slot numbers or bias rules. - - Merges all items into a single unified list. -- Returns the unified list to the host using the same export pattern as cartridges. + - If index is zero it refreshes it's own menu items. + - Calls each child cartridge’s export to retrieve their items. + - Applies slot‑based menu ID biasing: + - Merges all items into a single unified list. +- Returns item from the list indicated by the index. --- -### **PakInterface Host** +## PakInterface (Host) The host: -- Listens for **WM_VCC_MENU_CHANGED** from any DLL including the MPI. -- On receiving the message, calls the boot slot's export and rebuilds the menu. +- Creates the master menu item list from which the cartridge menu is drawn +- Listens for IDC_MSG_UPD_MENU from any DLL including the MPI. +- On receiving the message, updates it's list using calls to the boot slot's + (slot 0) export and rebuilds the menu. The host only sees a flat, final list of menu items. diff --git a/libcommon/src/bus/cartridge_menu.cpp b/libcommon/src/bus/cartridge_menu.cpp index 6edcf7da..94effa15 100644 --- a/libcommon/src/bus/cartridge_menu.cpp +++ b/libcommon/src/bus/cartridge_menu.cpp @@ -31,7 +31,6 @@ cartridge_menu gCartMenu; // ------------------------------------------------------------ HMENU cartridge_menu::draw(HWND hWnd, int position, const std::string& title) { - PrintLogC("Draw\n"); auto hMenuBar = GetMenu(hWnd); // Erase the Existing Cartridge Menu. Vcc.rc defines From 54b01e3040ce66bd690a48f734c36748bf59c933 Mon Sep 17 00:00:00 2001 From: ejaquay Date: Sat, 14 Feb 2026 22:39:56 -0500 Subject: [PATCH 03/14] Add code to MPI to fetch menus of carts in child slots Also added a method to cartridge_menu to copy item to API menu item struct --- Vcc.cpp | 6 +- libcommon/include/vcc/bus/cartridge_menu.h | 14 ++-- libcommon/src/bus/cartridge_menu.cpp | 30 +++++++- mpi/cartridge_slot.h | 7 +- mpi/multipak_cartridge.cpp | 82 ++++++++++++---------- pakinterface.cpp | 21 +++--- 6 files changed, 101 insertions(+), 59 deletions(-) diff --git a/Vcc.cpp b/Vcc.cpp index be438159..4cdfea85 100644 --- a/Vcc.cpp +++ b/Vcc.cpp @@ -138,7 +138,7 @@ static unsigned char FlagEmuStop=TH_RUNNING; bool IsShiftKeyDown(); CartridgeMenu CartMenu; //OLD -using VCC::Bus::gCartMenu; //NEW +using VCC::Bus::gVccCartMenu; //NEW static bool gHasFocus {}; @@ -709,8 +709,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) //-------------------------------------------------------------------------- HMENU DrawCartMenu (HWND hWnd) { - gCartMenu.log(); - return gCartMenu.draw(hWnd,5,"Cartridge"); + gVccCartMenu.log(); + return gVccCartMenu.draw(hWnd,5,"Cartridge"); } //-------------------------------------------------------------------------- diff --git a/libcommon/include/vcc/bus/cartridge_menu.h b/libcommon/include/vcc/bus/cartridge_menu.h index 8d48afc7..dc88277a 100644 --- a/libcommon/include/vcc/bus/cartridge_menu.h +++ b/libcommon/include/vcc/bus/cartridge_menu.h @@ -83,15 +83,13 @@ class cartridge_menu { // Clear all items void clear() { menu_.clear(); } - // Reserve capacity (for deterministic growth) - void reserve(size_t count) { menu_.reserve(count); } - // Add a single item void add(const std::string& name, unsigned int menu_id, MenuItemType type) { menu_.push_back({ name, menu_id, type }); } + // fetch an item CartMenuItem& operator[](size_t i) { return menu_[i]; @@ -100,6 +98,9 @@ class cartridge_menu { // Number of items in list size_t size() const { return menu_.size(); } + // copy an item to API structure + bool copy_item(menu_item_entry& out, size_t index) const; + // debug logging void log() { @@ -114,7 +115,10 @@ class cartridge_menu { const std::string& title="Cartridge"); }; -// create global instance for Vcc.cpp and pakinterface to use. -extern cartridge_menu gCartMenu; +// instance for Vcc.cpp and pakinterface to use. Host only! +extern cartridge_menu gVccCartMenu; + +// instance for dll's to use. DLL's only! +extern cartridge_menu gDllCartMenu; } // namespace VCC::Bus diff --git a/libcommon/src/bus/cartridge_menu.cpp b/libcommon/src/bus/cartridge_menu.cpp index 94effa15..76e0b351 100644 --- a/libcommon/src/bus/cartridge_menu.cpp +++ b/libcommon/src/bus/cartridge_menu.cpp @@ -19,12 +19,38 @@ //====================================================================== #include +#include #include namespace VCC::Bus { -// Global cart menu for vcc.exe use -cartridge_menu gCartMenu; +// Global cart menu for vcc.exe +// DLL's should never use this +cartridge_menu gVccCartMenu; + +// Cart menu for DLL use +// Vcc or pakinterface should not use this +cartridge_menu gDllCartMenu; + +// ------------------------------------------------------------ +// Copy a menu item to the API safe structure +// ------------------------------------------------------------ +bool cartridge_menu::copy_item(menu_item_entry& out, size_t index) const +{ + if (index >= menu_.size() || index >= MAX_MENU_ITEMS) + return false; + + const auto& src = menu_[index]; + + size_t n = std::min(src.name.size(), sizeof(out.name) - 1); + memcpy(out.name, src.name.data(), n); + out.name[n] = '\0'; + + out.menu_id = src.menu_id; + out.type = src.type; + + return true; +} // ------------------------------------------------------------ // Draw the menu. DLL's should not call this diff --git a/mpi/cartridge_slot.h b/mpi/cartridge_slot.h index 42d00d9b..a413fe7f 100644 --- a/mpi/cartridge_slot.h +++ b/mpi/cartridge_slot.h @@ -18,9 +18,9 @@ #pragma once #include #include +#include #include "../CartridgeMenu.h" - namespace VCC::Core { @@ -147,6 +147,11 @@ namespace VCC::Core menu_items_.push_back(item); } + bool get_menu_item(menu_item_entry* item, size_t index) + { + return cartridge_->get_menu_item(item, index); + } + void enumerate_menu_items(context_type& context) const { for (const auto& item : menu_items_) diff --git a/mpi/multipak_cartridge.cpp b/mpi/multipak_cartridge.cpp index a9a9f3c7..d7b6f732 100644 --- a/mpi/multipak_cartridge.cpp +++ b/mpi/multipak_cartridge.cpp @@ -23,7 +23,8 @@ #include #include #include - +#include +#include namespace { @@ -86,7 +87,7 @@ void multipak_cartridge::start() } } - // Build the dynamic menu + // Build the dynamic menu **OLD** build_menu(); } @@ -236,55 +237,63 @@ void multipak_cartridge::menu_item_clicked(unsigned char menu_item_id) gConfigurationDialog.open(); } + // Each slot is allocated 50 menu items and items were + // biased by SlotId * 50 so MPI knows which slot the item is for + if (menu_item_id < 50) return; // Nothing more for SlotId 0 + VCC::Util::section_locker lock(mutex_); - // Menu items for loaded carts. Each slot is allocated 50. - if (menu_item_id >= 50 && menu_item_id <= 100) - { + if (menu_item_id < 100) { slots_[0].menu_item_clicked(menu_item_id - 50); + return; } - if (menu_item_id > 100 && menu_item_id <= 150) - { + if (menu_item_id < 150) { slots_[1].menu_item_clicked(menu_item_id - 100); + return; } - if (menu_item_id > 150 && menu_item_id <= 200) - { + if (menu_item_id < 200) { slots_[2].menu_item_clicked(menu_item_id - 150); + return; } - if (menu_item_id > 200 && menu_item_id <= 250) - { + if (menu_item_id < 250) { slots_[3].menu_item_clicked(menu_item_id - 200); + return; } } -bool multipak_cartridge::get_menu_item( - menu_item_entry* item, size_t index) +// returns menu item from DLL item list +bool multipak_cartridge::get_menu_item(menu_item_entry* item, size_t index) { - -// build list -// for (int mpi_slot = 3; mpi_slot >= 0; mpi_slot--) -// { -// return false; -// } - - // Test - switch (index) { - case 0: - strcpy(item->name,""); - item->menu_id = 0; - item->type = MIT_Seperator; - return true; - case 1: - strcpy(item->name,"MPI Config"); - item->menu_id = ControlId(19); - item->type = MIT_StandAlone; - return true; - default: - return false; + using VCC::Bus::gDllCartMenu; + + if (!item) return false; + + // index 0 is special, it indicates DLL should refresh it's menus + if (index == 0) { + // Rebuild MPI menu + gDllCartMenu.clear(); + gDllCartMenu.add("", 0, MIT_Seperator); + gDllCartMenu.add("MPI Config", ControlId(19), MIT_StandAlone); + // Append child menus + for (int SlotId = 4; SlotId > 0; SlotId--) { + menu_item_entry pakitm; + for (int ndx = 0; ndx < MAX_MENU_ITEMS; ndx++) { + if (slots_[SlotId-1].get_menu_item(&pakitm,ndx)) { + // bias control_ids per slot + if (pakitm.menu_id >= MID_CONTROL) + pakitm.menu_id += (SlotId * 50); + gDllCartMenu.add(pakitm.name,pakitm.menu_id,pakitm.type); + } else { + break; + } + } + } + if (gDllCartMenu.size() == 0) return 0; } + return gDllCartMenu.copy_item( *item, index); } @@ -422,7 +431,7 @@ multipak_cartridge::slot_id_type multipak_cartridge::selected_scs_slot() const return cached_scs_slot_; } -// Save cart Menu items into containers per slot +// *OLD* Save cart Menu items into containers per slot **OLD** void multipak_cartridge::append_menu_item(slot_id_type SlotId, menu_item_type item) { DLOG_C("menu_item %d %d \n",SlotId,item.menu_id); @@ -452,7 +461,8 @@ void multipak_cartridge::append_menu_item(slot_id_type SlotId, menu_item_type it } } -// This gets called any time a cartridge menu is changed. It draws the entire menu. + +// *OLD* This gets called any time a cartridge menu is changed. It draws the entire menu. void multipak_cartridge::build_menu() { // do we really need this here? menu draw should be async diff --git a/pakinterface.cpp b/pakinterface.cpp index 3a6c1768..b85aec25 100644 --- a/pakinterface.cpp +++ b/pakinterface.cpp @@ -190,37 +190,34 @@ unsigned short PackAudioSample() return gActiveCartrige->sample_audio(); } -// Temporary bridge from old to new - - // Build entries for cartridge menu. void BuildCartMenu() { // lock goes into program paks, not needed here //VCC::Util::section_locker lock(gPakMutex); - using VCC::Bus::gCartMenu; - gCartMenu.clear(); - gCartMenu.add("Cartridge", 0, MIT_Head); + using VCC::Bus::gVccCartMenu; + gVccCartMenu.clear(); + gVccCartMenu.add("Cartridge", 0, MIT_Head); if (!gActiveCartrige->name().empty()) { std::string tmp = "Eject " + gActiveCartrige->name(); - gCartMenu.add(tmp, ControlId(2), MIT_Slave); + gVccCartMenu.add(tmp, ControlId(2), MIT_Slave); // Add items from loaded pak menu_item_entry item; for (size_t index=0;indexget_menu_item(&item,index)) { - gCartMenu.add(item.name,item.menu_id,item.type); + gVccCartMenu.add(item.name,item.menu_id,item.type); } else { break; } } } else { - gCartMenu.add("Load MPI", ControlId(3), MIT_Slave); - gCartMenu.add("Load DLL", ControlId(1), MIT_Slave); - gCartMenu.add("Load ROM", ControlId(4), MIT_Slave); + gVccCartMenu.add("Load MPI", ControlId(3), MIT_Slave); + gVccCartMenu.add("Load DLL", ControlId(1), MIT_Slave); + gVccCartMenu.add("Load ROM", ControlId(4), MIT_Slave); } } -// Create entries for cartridge menu. The rest will be for MPI +// OLD Create entries for cartridge menu. The rest will be for MPI // ControlId(MenuId) set what control does **OLD*** void BeginCartMenu() { From cd1c46efe8744aebd121a4c552dc517e7f030f27 Mon Sep 17 00:00:00 2001 From: ejaquay Date: Sun, 15 Feb 2026 09:11:31 -0500 Subject: [PATCH 04/14] Convert fd502 to export based menu updates Started with the hardest one. Old menu system left in place for parallel testing, these will be be removed after all DLL's are converted --- FD502/fd502.cpp | 86 +++++++++++++++++++++++++++++++------- Vcc.cpp | 17 ++++---- mpi/mpi.cpp | 4 +- mpi/multipak_cartridge.cpp | 4 +- resource.h | 2 +- 5 files changed, 83 insertions(+), 30 deletions(-) diff --git a/FD502/fd502.cpp b/FD502/fd502.cpp index 818dd195..72efd34c 100644 --- a/FD502/fd502.cpp +++ b/FD502/fd502.cpp @@ -40,6 +40,9 @@ #include #include #include +#include +#include +#include //include becker code if COMBINE_BECKER is defined in fd502.h #ifdef COMBINE_BECKER @@ -74,6 +77,7 @@ LRESULT CALLBACK NewDisk(HWND,UINT, WPARAM, LPARAM); void LoadConfig(); void SaveConfig(); long CreateDiskHeader(const char *,unsigned char,unsigned char,unsigned char); +void Unload_Disk(unsigned char); void Load_Disk(unsigned char); static HWND g_hConfDlg = nullptr; @@ -83,10 +87,14 @@ long CreateDisk (unsigned char); static char gSelectedDiskFile[MAX_PATH]=""; unsigned char LoadExtRom( unsigned char, const char *); +bool get_menu_item(menu_item_entry*, size_t index); + int BeckerEnabled=0; char BeckerAddr[MAX_PATH]=""; char BeckerPort[32]=""; +static HWND gVccWnd = nullptr; + //---------------------------------------------------------------------------- extern "C" { @@ -126,6 +134,7 @@ extern "C" { DLOG_C("FDC %p %p %p %p %p\n",*callbacks); gSlotId = SlotId; + gVccWnd = hVccWnd; CartMenuCallback = callbacks->add_menu_item; AssertInt = callbacks->assert_interrupt; strcpy(IniFile, configuration_path); @@ -133,6 +142,8 @@ extern "C" RealDisks = InitController(); LoadConfig(); BuildCartridgeMenu(); + // Request menu rebuild + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); } __declspec(dllexport) void PakReset() @@ -152,6 +163,11 @@ extern "C" } } + __declspec(dllexport) bool PakGetMenuItem(menu_item_entry* item, size_t index) + { + return get_menu_item(item, index); + } + __declspec(dllexport) void PakMenuItemClicked(unsigned char MenuID) { HWND h_own = GetActiveWindow(); @@ -161,37 +177,35 @@ extern "C" Load_Disk(0); break; case 11: - unmount_disk_image(0); - SaveConfig(); + Unload_Disk(0); break; case 12: Load_Disk(1); break; case 13: - unmount_disk_image(1); - SaveConfig(); + Unload_Disk(1); break; case 14: Load_Disk(2); break; case 15: - unmount_disk_image(2); - SaveConfig(); - break; - case 16: - if (g_hConfDlg == nullptr) - g_hConfDlg = CreateDialog(gModuleInstance,(LPCTSTR)IDD_CONFIG,h_own,(DLGPROC)Config); - ShowWindow(g_hConfDlg,1); + Unload_Disk(2); break; case 17: Load_Disk(3); break; case 18: - unmount_disk_image(3); - SaveConfig(); + Unload_Disk(3); + break; + case 16: + if (g_hConfDlg == nullptr) + g_hConfDlg = CreateDialog( + gModuleInstance,(LPCTSTR)IDD_CONFIG,h_own,(DLGPROC)Config); + ShowWindow(g_hConfDlg,1); break; } - BuildCartridgeMenu(); + //FIXME: Menu rebuild should not be here + BuildCartridgeMenu(); //OLD REMOVE return; } @@ -400,6 +414,12 @@ LRESULT CALLBACK Config(HWND hDlg, UINT message, WPARAM wParam, LPARAM /*lParam* return FALSE; } +void Unload_Disk(unsigned char disk) { + unmount_disk_image(disk); + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); + SaveConfig(); +} + void Load_Disk(unsigned char disk) { HWND h_own = GetActiveWindow(); @@ -430,6 +450,7 @@ void Load_Disk(unsigned char disk) MessageBox(g_hConfDlg,"Can't open file","Error",0); } else { dlg.getdir(FloppyPath); + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); SaveConfig(); } } @@ -444,6 +465,39 @@ unsigned char SetChip(unsigned char Tmp) return SelectRom; } +// Return items for cartridge menu. Called for each item +bool get_menu_item(menu_item_entry* item, size_t index) +{ + using VCC::Bus::gDllCartMenu; + std::string disk; + if (!item) return false; + // request zero rebuilds the menu list + if (index == 0) { + gDllCartMenu.clear(); + gDllCartMenu.add("", 0, MIT_Seperator); + gDllCartMenu.add("FD-502 Drive 0",MID_ENTRY,MIT_Head); + gDllCartMenu.add("Insert",ControlId(10),MIT_Slave); + disk = VCC::Util::GetFileNamePart(gVirtualDrive[0].ImageName); + gDllCartMenu.add("Eject: "+disk,ControlId(11),MIT_Slave); + gDllCartMenu.add("FD-502 Drive 1",MID_ENTRY,MIT_Head); + gDllCartMenu.add("Insert",ControlId(12),MIT_Slave); + disk = VCC::Util::GetFileNamePart(gVirtualDrive[1].ImageName); + gDllCartMenu.add("Eject: "+disk,ControlId(13),MIT_Slave); + gDllCartMenu.add("FD-502 Drive 2",MID_ENTRY,MIT_Head); + gDllCartMenu.add("Insert",ControlId(14),MIT_Slave); + disk = VCC::Util::GetFileNamePart(gVirtualDrive[2].ImageName); + gDllCartMenu.add("Eject: "+disk,ControlId(15),MIT_Slave); + gDllCartMenu.add("FD-502 Drive 3",MID_ENTRY,MIT_Head); + gDllCartMenu.add("Insert",ControlId(17),MIT_Slave); + disk = VCC::Util::GetFileNamePart(gVirtualDrive[3].ImageName); + gDllCartMenu.add("Eject: "+disk,ControlId(18),MIT_Slave); + gDllCartMenu.add("FD-502 Config",ControlId(16),MIT_StandAlone); + } + // return requested list item or false + return gDllCartMenu.copy_item(*item, index); +} + +// Following is OLD depreciated void BuildCartridgeMenu() { char TempMsg[MAX_PATH]=""; @@ -713,7 +767,9 @@ void LoadConfig() // Called on SetIniPath ClockEnabled=GetPrivateProfileInt(ModName,"ClkEnable",1,IniFile); SetTurboDisk(GetPrivateProfileInt(ModName, "TurboDisk", 1, IniFile)); - BuildCartridgeMenu(); + BuildCartridgeMenu(); //OLD + // Request menu rebuild + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); return; } diff --git a/Vcc.cpp b/Vcc.cpp index 4cdfea85..b2134ece 100644 --- a/Vcc.cpp +++ b/Vcc.cpp @@ -171,9 +171,6 @@ int APIENTRY WinMain(_In_ HINSTANCE hInstance, EmuState.ResetPending=2; // after LoadConfig pls InitInstance(hInstance, nCmdShow); - // Fill initial cartridge menu before main win starts? - BuildCartMenu(); - if ((CmdArg.NoOutput && !CreateNullWindow(&EmuState)) || (!CmdArg.NoOutput && !CreateDDWindow(&EmuState))) { @@ -312,8 +309,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) // Parse the menu selections: - // Check if ID is in cartridge menu range - if ( (wmId >= MID_CONTROL) & (wmId < MID_CONTROL + 200) ) + // Check if ID is in cartridge menu range. Control ID's are + // biased by SlotNum, there are five slots each gets 50 + if ( (wmId >= MID_CONTROL) & (wmId < MID_CONTROL + 250) ) { CartMenuActivated(wmId-MID_CONTROL); break; @@ -367,11 +365,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) EmuState.ResetPending=2; break; - case IDC_MSG_UPD_MENU: - BuildCartMenu(); - DrawCartMenu(hWnd); - break; - case ID_FILE_RUN: EmuState.EmulationRunning=TRUE; InvalidateBoarder(); @@ -380,6 +373,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case ID_FILE_RESET_SFT: if (EmuState.EmulationRunning) EmuState.ResetPending=1; + + case IDC_MSG_UPD_MENU: + BuildCartMenu(); + DrawCartMenu(hWnd); break; case ID_FILE_LOAD: diff --git a/mpi/mpi.cpp b/mpi/mpi.cpp index f822c1f3..ca49c753 100644 --- a/mpi/mpi.cpp +++ b/mpi/mpi.cpp @@ -89,9 +89,9 @@ extern "C" } // Fetch menu item list for MPI and carts it has loaded - __declspec(dllexport) bool PakGetMenuItem(menu_item_entry* item, size_t count) + __declspec(dllexport) bool PakGetMenuItem(menu_item_entry* item, size_t index) { - return gMultiPakInterface.get_menu_item(item, count); + return gMultiPakInterface.get_menu_item(item, index); } // Write to port diff --git a/mpi/multipak_cartridge.cpp b/mpi/multipak_cartridge.cpp index d7b6f732..252929c0 100644 --- a/mpi/multipak_cartridge.cpp +++ b/mpi/multipak_cartridge.cpp @@ -232,6 +232,7 @@ unsigned short multipak_cartridge::sample_audio() void multipak_cartridge::menu_item_clicked(unsigned char menu_item_id) { + if (menu_item_id == 19) //MPI Config { gConfigurationDialog.open(); @@ -291,7 +292,6 @@ bool multipak_cartridge::get_menu_item(menu_item_entry* item, size_t index) } } } - if (gDllCartMenu.size() == 0) return 0; } return gDllCartMenu.copy_item( *item, index); } @@ -434,7 +434,6 @@ multipak_cartridge::slot_id_type multipak_cartridge::selected_scs_slot() const // *OLD* Save cart Menu items into containers per slot **OLD** void multipak_cartridge::append_menu_item(slot_id_type SlotId, menu_item_type item) { - DLOG_C("menu_item %d %d \n",SlotId,item.menu_id); auto mpi_slot = SlotId - 1; @@ -459,6 +458,7 @@ void multipak_cartridge::append_menu_item(slot_id_type SlotId, menu_item_type it break; } } + DLOG_C("menu_item %d %d \n",SlotId,item.menu_id); } diff --git a/resource.h b/resource.h index ebd4d8a0..96e640ea 100644 --- a/resource.h +++ b/resource.h @@ -414,7 +414,7 @@ #define IDC_EDIT_RANGE_SEP 2154 //----------------------------------------------------- -// ID 5000 - 5249 are reserved for cartridge menus +// ID 5000 - 5250 are reserved for cartridge menus // ID 5251 - 5299 are reseverd for cartridge messaging //----------------------------------------------------- From 77084e05a22462e06321e77eac92a35aac3508da Mon Sep 17 00:00:00 2001 From: ejaquay Date: Sun, 15 Feb 2026 15:14:43 -0500 Subject: [PATCH 05/14] Convert harddisk and SuperIDE to export based menu updates Still leaving old menu system running in parallel --- FD502/fd502.cpp | 6 ++ HardDisk/harddisk.cpp | 101 +++++++++++++++------ SuperIDE/IdeBus.cpp | 58 +++++++----- SuperIDE/IdeBus.h | 4 + SuperIDE/SuperIDE.cpp | 87 ++++++++++++++---- SuperIDE/logger.cpp | 57 ------------ SuperIDE/logger.h | 27 ------ libcommon/include/vcc/bus/cartridge_menu.h | 33 +++---- mpi/multipak_cartridge.cpp | 3 + 9 files changed, 206 insertions(+), 170 deletions(-) delete mode 100644 SuperIDE/logger.cpp delete mode 100644 SuperIDE/logger.h diff --git a/FD502/fd502.cpp b/FD502/fd502.cpp index 72efd34c..ff258f4e 100644 --- a/FD502/fd502.cpp +++ b/FD502/fd502.cpp @@ -40,6 +40,7 @@ #include #include #include +// Three includes added for PakGetMenuItem #include #include #include @@ -87,12 +88,14 @@ long CreateDisk (unsigned char); static char gSelectedDiskFile[MAX_PATH]=""; unsigned char LoadExtRom( unsigned char, const char *); +// Added for PakGetMenuItem export bool get_menu_item(menu_item_entry*, size_t index); int BeckerEnabled=0; char BeckerAddr[MAX_PATH]=""; char BeckerPort[32]=""; +// Added for PakGetMenuItem export static HWND gVccWnd = nullptr; //---------------------------------------------------------------------------- @@ -142,6 +145,7 @@ extern "C" RealDisks = InitController(); LoadConfig(); BuildCartridgeMenu(); + // Added for PakGetMenuItem export // Request menu rebuild SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); } @@ -163,6 +167,7 @@ extern "C" } } + //PakGetMenuItem export __declspec(dllexport) bool PakGetMenuItem(menu_item_entry* item, size_t index) { return get_menu_item(item, index); @@ -465,6 +470,7 @@ unsigned char SetChip(unsigned char Tmp) return SelectRom; } +// Added for PakGetMenuItem export // Return items for cartridge menu. Called for each item bool get_menu_item(menu_item_entry* item, size_t index) { diff --git a/HardDisk/harddisk.cpp b/HardDisk/harddisk.cpp index 511dcd64..50a95b12 100644 --- a/HardDisk/harddisk.cpp +++ b/HardDisk/harddisk.cpp @@ -1,22 +1,23 @@ -/* -Copyright 2015 by Joseph Forgione -This file is part of VCC (Virtual Color Computer). - - VCC (Virtual Color Computer) 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 3 of the License, or - (at your option) any later version. - - VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see . -*/ - -// hardisk.cpp : Defines the entry point for the DLL application. +//#define USE_LOGGING +//====================================================================== +// This file is part of VCC (Virtual Color Computer). +// Vcc is Copyright 2015 by Joseph Forgione +// +// VCC (Virtual Color Computer) is free software, you can redistribute +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see +// . +// +//====================================================================== #include #include @@ -29,6 +30,10 @@ This file is part of VCC (Virtual Color Computer). #include "../CartridgeMenu.h" #include #include +// Three includes added for PakGetMenuItem +#include +#include +#include #include constexpr auto DEF_HD_SIZE = 132480u; @@ -53,13 +58,21 @@ LRESULT CALLBACK NewDisk(HWND,UINT, WPARAM, LPARAM); void LoadHardDisk(int drive); void LoadConfig(); void SaveConfig(); -void BuildCartridgeMenu(); +void BuildCartridgeMenu(); //OLD int CreateDisk(HWND,int); static HINSTANCE gModuleInstance; static HWND hConfDlg = nullptr; LRESULT CALLBACK Config(HWND, UINT, WPARAM, LPARAM ); +// Added for PakGetMenuItem export +bool get_menu_item(menu_item_entry*, size_t index); + +// Added for PakGetMenuItem export +static HWND gVccWnd = nullptr; + +//================================================================================= + using namespace std; void MemWrite(unsigned char Data, unsigned short Address) @@ -110,7 +123,8 @@ extern "C" const cpak_callbacks* const callbacks) { gSlotId = SlotId; - CartMenuCallback = callbacks->add_menu_item; + gVccWnd = hVccWnd; + CartMenuCallback = callbacks->add_menu_item; //OLD MemRead8 = callbacks->read_memory_byte; MemWrite8 = callbacks->write_memory_byte; strcpy(IniFile, configuration_path); @@ -119,6 +133,14 @@ extern "C" cloud9_rtc.set_read_only(ClockReadOnly); VhdReset(); // Selects drive zero BuildCartridgeMenu(); + // Added for PakGetMenuItem export + // Request menu rebuild + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); + } + + __declspec(dllexport) bool PakGetMenuItem(menu_item_entry* item, size_t index) + { + return get_menu_item(item, index); } __declspec(dllexport) void PakTerminate() @@ -127,10 +149,8 @@ extern "C" UnmountHD(0); UnmountHD(1); } - } - // Configure the hard drive(s). Called from menu // Mount or dismount a hard drive and save config // MountHD and UnmountHD are defined in cc3vhd @@ -166,7 +186,9 @@ extern "C" return; } SaveConfig(); - BuildCartridgeMenu(); + // FIXME should only rebuild menus if drive is changed + BuildCartridgeMenu(); // Old + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); return; } } @@ -349,7 +371,9 @@ void LoadConfig() ClockReadOnly = GetPrivateProfileInt(ModName, "ClkRdOnly", 1, IniFile) != 0; // Create config menu - BuildCartridgeMenu(); + BuildCartridgeMenu(); //OLD + // Added for PakGetMenuItem + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); return; } @@ -372,7 +396,32 @@ void SaveConfig() return; } -// Generate menu for mounting the drives +// Added for PakGetMenuItem export +// Return items for cartridge menu. Called for each item +bool get_menu_item(menu_item_entry* item, size_t index) +{ + using VCC::Bus::gDllCartMenu; + std::string disk; + if (!item) return false; + // request zero rebuilds the menu list + if (index == 0) { + gDllCartMenu.clear(); + gDllCartMenu.add("", 0, MIT_Seperator); + gDllCartMenu.add("HD Drive 0",MID_ENTRY,MIT_Head); + gDllCartMenu.add("Insert",ControlId(10),MIT_Slave); + disk = VCC::Util::GetFileNamePart(VHDfile0); + gDllCartMenu.add("Eject: "+disk,ControlId(11),MIT_Slave); + gDllCartMenu.add("HD Drive 1",MID_ENTRY,MIT_Head); + gDllCartMenu.add("Insert",ControlId(12),MIT_Slave); + disk = VCC::Util::GetFileNamePart(VHDfile1); + gDllCartMenu.add("Eject: "+disk,ControlId(13),MIT_Slave); + gDllCartMenu.add("HD Config",ControlId(14),MIT_StandAlone); + } + // return requested list item or false + return gDllCartMenu.copy_item(*item, index); +} + +// OLD Generate menu for mounting the drives OLD void BuildCartridgeMenu() { char TempMsg[512] = ""; diff --git a/SuperIDE/IdeBus.cpp b/SuperIDE/IdeBus.cpp index a35c0320..23dadb6f 100644 --- a/SuperIDE/IdeBus.cpp +++ b/SuperIDE/IdeBus.cpp @@ -1,28 +1,31 @@ -/* -Copyright 2015 by Joseph Forgione -This file is part of VCC (Virtual Color Computer). +//#define USE_LOGGING +//====================================================================== +// This file is part of VCC (Virtual Color Computer). +// Vcc is Copyright 2015 by Joseph Forgione +// +// VCC (Virtual Color Computer) is free software, you can redistribute +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see +// . +// +//====================================================================== - VCC (Virtual Color Computer) 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 3 of the License, or - (at your option) any later version. - - VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see . -*/ - -#include "logger.h" +#include #include "IdeBus.h" #include #include +#include static unsigned int Lba=0,LastLba; -char Message[256]=""; //DEBUG static unsigned char XferBuffer[512]=""; static unsigned int BufferIndex=0; @@ -31,7 +34,7 @@ static unsigned char CurrentCommand=0; void ExecuteCommand(); void ByteSwap (char *); static IDEINTERFACE Registers; -static HANDLE hDiskFile[2]; +static HANDLE hDiskFile[2] {}; static unsigned char DiskSelect=0,LbaEnabled=0; unsigned long BytesMoved=0; unsigned char BusyCounter=BUSYWAIT; @@ -40,11 +43,9 @@ static unsigned short IDBlock[2][256]; static unsigned char Mounted=0,ScanCount=0; static char CurrStatus[32]="IDE:Idle "; static char FileNames[2][MAX_PATH]={"",""}; + void IdeInit() { - - hDiskFile[MASTER]=INVALID_HANDLE_VALUE; - hDiskFile[SLAVE]=INVALID_HANDLE_VALUE; Registers.Command=0; Registers.Cylinderlsb=0; Registers.Cylindermsb=0; @@ -342,11 +343,13 @@ unsigned char MountDisk(const char *FileName,unsigned char DiskNumber) return FALSE; strcpy(FileNames[DiskNumber],FileName); Mounted=1; + DLOG_C(">>>MountDisk %d %d<<<\n",DiskNumber,hDiskFile[DiskNumber]); return TRUE; } unsigned char DropDisk(unsigned char DiskNumber) { + DLOG_C(">>>DropDisk %d %d<<<\n",DiskNumber,hDiskFile[DiskNumber]); CloseHandle(hDiskFile[DiskNumber]); hDiskFile[DiskNumber]=INVALID_HANDLE_VALUE; strcpy(FileNames[DiskNumber],""); @@ -358,4 +361,11 @@ void QueryDisk(unsigned char DiskNumber,char *Name) { strcpy(Name,FileNames[DiskNumber]); return; -} \ No newline at end of file +} + +std::string QueryDisk(unsigned char DiskNumber) +{ + return FileNames[DiskNumber]; +} + + diff --git a/SuperIDE/IdeBus.h b/SuperIDE/IdeBus.h index 56fbde3e..ef52a23a 100644 --- a/SuperIDE/IdeBus.h +++ b/SuperIDE/IdeBus.h @@ -17,6 +17,8 @@ This file is part of VCC (Virtual Color Computer). You should have received a copy of the GNU General Public License along with VCC (Virtual Color Computer). If not, see . */ +#include + struct IDEINTERFACE { unsigned short Data; unsigned char Error[2]; @@ -36,6 +38,8 @@ void DiskStatus(char* text_buffer, size_t buffer_size); unsigned char MountDisk(const char *,unsigned char ); unsigned char DropDisk(unsigned char); void QueryDisk(unsigned char,char *); +std::string QueryDisk(unsigned char); + //Status #define ERR 1 //Previous command ended in an error #define IDX 2 //Unused diff --git a/SuperIDE/SuperIDE.cpp b/SuperIDE/SuperIDE.cpp index 9341479f..92eb2554 100644 --- a/SuperIDE/SuperIDE.cpp +++ b/SuperIDE/SuperIDE.cpp @@ -1,21 +1,23 @@ -/* -Copyright 2015 by Joseph Forgione -This file is part of VCC (Virtual Color Computer). - - VCC (Virtual Color Computer) 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 3 of the License, or - (at your option) any later version. - - VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see . -*/ //#define USE_LOGGING +//====================================================================== +// This file is part of VCC (Virtual Color Computer). +// Vcc is Copyright 2015 by Joseph Forgione +// +// VCC (Virtual Color Computer) is free software, you can redistribute +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see +// . +// +//====================================================================== #include #include "stdio.h" @@ -23,13 +25,16 @@ This file is part of VCC (Virtual Color Computer). #include "resource.h" #include "IdeBus.h" #include -#include "logger.h" #include #include "../CartridgeMenu.h" #include #include #include #include +// Three includes added for PakGetMenuItem +#include +#include +#include static char FileName[MAX_PATH] { 0 }; static char IniFile[MAX_PATH] { 0 }; @@ -43,6 +48,7 @@ void Select_Disk(unsigned char); void SaveConfig(); void LoadConfig(); unsigned char BaseTable[4]={0x40,0x50,0x60,0x70}; +bool get_menu_item(menu_item_entry*, size_t index); static unsigned char BaseAddr=1; static bool ClockEnabled = true; @@ -52,9 +58,12 @@ static HINSTANCE gModuleInstance; static HWND hConfDlg = nullptr; static slot_id_type gSlotId {}; +static HWND gVccWnd = nullptr; + using namespace std; +//---------------------------------------------------------------------------- extern "C" { @@ -92,13 +101,15 @@ extern "C" const cpak_callbacks* const callbacks) { gSlotId = SlotId; + gVccWnd = hVccWnd; CartMenuCallback = callbacks->add_menu_item; strcpy(IniFile, configuration_path); LoadConfig(); IdeInit(); - BuildCartridgeMenu(); + BuildCartridgeMenu(); // REMOVE THIS + //SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); } __declspec(dllexport) void PakTerminate() @@ -161,7 +172,13 @@ extern "C" DiskStatus(text_buffer, buffer_size); } - + + //PakGetMenuItem export + __declspec(dllexport) bool PakGetMenuItem(menu_item_entry* item, size_t index) + { + return get_menu_item(item, index); + } + __declspec(dllexport) void PakMenuItemClicked(unsigned char MenuID) { switch (MenuID) @@ -170,24 +187,28 @@ extern "C" Select_Disk(MASTER); BuildCartridgeMenu(); SaveConfig(); + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); break; case 11: DropDisk(MASTER); BuildCartridgeMenu(); SaveConfig(); + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); break; case 12: Select_Disk(SLAVE); BuildCartridgeMenu(); SaveConfig(); + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); break; case 13: DropDisk(SLAVE); BuildCartridgeMenu(); SaveConfig(); + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); break; case 14: @@ -216,6 +237,31 @@ BOOL WINAPI DllMain( return TRUE; } +// Added for PakGetMenuItem export +// Return items for cartridge menu. Called for each item +bool get_menu_item(menu_item_entry* item, size_t index) +{ + using VCC::Bus::gDllCartMenu; + std::string disk; + if (!item) return false; + // request zero rebuilds the menu list + if (index == 0) { + gDllCartMenu.clear(); + gDllCartMenu.add("", 0, MIT_Seperator); + gDllCartMenu.add("IDE Master",MID_ENTRY,MIT_Head); + gDllCartMenu.add("Insert",ControlId(10),MIT_Slave); + disk = VCC::Util::GetFileNamePart(QueryDisk(MASTER)); + gDllCartMenu.add("Eject: "+disk,ControlId(11),MIT_Slave); + gDllCartMenu.add("IDE Slave",MID_ENTRY,MIT_Head); + gDllCartMenu.add("Insert",ControlId(12),MIT_Slave); + disk = VCC::Util::GetFileNamePart(QueryDisk(SLAVE)); + gDllCartMenu.add("Eject: "+disk,ControlId(13),MIT_Slave); + gDllCartMenu.add("IDE Config",ControlId(14),MIT_StandAlone); + } + // return requested list item or false + return gDllCartMenu.copy_item(*item, index); +} + void BuildCartridgeMenu() { char TempMsg[512]=""; @@ -363,5 +409,6 @@ void LoadConfig() cloud9_rtc.set_read_only(ClockReadOnly); MountDisk(FileName ,SLAVE); BuildCartridgeMenu(); + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); return; } diff --git a/SuperIDE/logger.cpp b/SuperIDE/logger.cpp deleted file mode 100644 index ea738f17..00000000 --- a/SuperIDE/logger.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2015 by Joseph Forgione -This file is part of VCC (Virtual Color Computer). - - VCC (Virtual Color Computer) 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 3 of the License, or - (at your option) any later version. - - VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see . -*/ -#include -#include - -#include "logger.h" - -void WriteLog(char *Message,unsigned char Type) -{ - static unsigned int Counter=1; - static HANDLE hout=nullptr; - static FILE *disk_handle=nullptr; - unsigned long dummy; - char cTemp[512]=""; - switch (Type) - { - case TOCONS: - if (hout==nullptr) - { - AllocConsole(); - hout=GetStdHandle(STD_OUTPUT_HANDLE); - SetConsoleTitle("Logging Window"); - } - sprintf(cTemp,"%s",Message); - WriteConsole(hout,cTemp,strlen(cTemp),&dummy,nullptr); - Counter++; - break; - - case TOFILE: - if (disk_handle ==nullptr) - disk_handle=fopen("c:\\VccLog.txt","w"); - - fprintf(disk_handle,"%s\r\n",Message); - fflush(disk_handle); - break; - } - -} - - - - diff --git a/SuperIDE/logger.h b/SuperIDE/logger.h deleted file mode 100644 index 2591c483..00000000 --- a/SuperIDE/logger.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __LOGGER_H__ -#define __LOGGER_H__ -/* -Copyright 2015 by Joseph Forgione -This file is part of VCC (Virtual Color Computer). - - VCC (Virtual Color Computer) 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 3 of the License, or - (at your option) any later version. - - VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see . -*/ - -void WriteLog(char *,unsigned char); - -// FIXME: These should be a scoped enum -#define TOCONS 0 -#define TOFILE 1 - -#endif diff --git a/libcommon/include/vcc/bus/cartridge_menu.h b/libcommon/include/vcc/bus/cartridge_menu.h index dc88277a..2df8f8e2 100644 --- a/libcommon/include/vcc/bus/cartridge_menu.h +++ b/libcommon/include/vcc/bus/cartridge_menu.h @@ -1,3 +1,4 @@ +//#define USE_LOGGING //====================================================================== // This file is part of VCC (Virtual Color Computer). // Vcc is Copyright 2015 by Joseph Forgione @@ -65,9 +66,9 @@ constexpr int ControlId(int id) { return MID_CONTROL + id; } // A single menu entry struct CartMenuItem { - std::string name; - size_t menu_id; - MenuItemType type; + std::string name; + size_t menu_id; + MenuItemType type; }; class cartridge_menu { @@ -80,14 +81,14 @@ class cartridge_menu { // Constructor cartridge_menu() {} - // Clear all items - void clear() { menu_.clear(); } + // Clear all items + void clear() { menu_.clear(); } - // Add a single item - void add(const std::string& name, unsigned int menu_id, MenuItemType type) - { - menu_.push_back({ name, menu_id, type }); - } + // Add a single item + void add(const std::string& name, unsigned int menu_id, MenuItemType type) + { + menu_.push_back({ name, menu_id, type }); + } // fetch an item CartMenuItem& operator[](size_t i) @@ -95,8 +96,8 @@ class cartridge_menu { return menu_[i]; } - // Number of items in list - size_t size() const { return menu_.size(); } + // Number of items in list + size_t size() const { return menu_.size(); } // copy an item to API structure bool copy_item(menu_item_entry& out, size_t index) const; @@ -104,12 +105,12 @@ class cartridge_menu { // debug logging void log() { - for (size_t i = 0; i < menu_.size(); ++i) { - PrintLogC("%s %d %d\n", menu_[i].name.c_str(),menu_[i].menu_id,menu_[i].type); - } + for (size_t i = 0; i < menu_.size(); ++i) { + DLOG_C("%s %d %d\n", menu_[i].name.c_str(),menu_[i].menu_id,menu_[i].type); + } } - // Draw the menu (implemented in catridge_menu.cpp) + // Draw the menu (implemented in catridge_menu.cpp) HMENU draw(HWND hWnd, int position=3, const std::string& title="Cartridge"); diff --git a/mpi/multipak_cartridge.cpp b/mpi/multipak_cartridge.cpp index 252929c0..29cf8474 100644 --- a/mpi/multipak_cartridge.cpp +++ b/mpi/multipak_cartridge.cpp @@ -25,6 +25,7 @@ #include #include #include +#include namespace { @@ -326,6 +327,7 @@ void multipak_cartridge::eject_cartridge(slot_id_type mpi_slot) slots_[mpi_slot] = {}; if (mpi_slot == cached_cts_slot_ || mpi_slot == switch_slot_) SendMessage(gVccWnd,WM_COMMAND,(WPARAM) ID_FILE_RESET,(LPARAM) 0); + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); } // create cartridge object and load cart DLL @@ -412,6 +414,7 @@ multipak_cartridge::mount_status_type multipak_cartridge::mount_cartridge( slots_[mpi_slot].start(); slots_[mpi_slot].reset(); + SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); return loadedCartridge.load_result; } From d7e410701d27b9dba2a3b7d46fa403a487aa3db5 Mon Sep 17 00:00:00 2001 From: ejaquay Date: Sun, 15 Feb 2026 16:40:28 -0500 Subject: [PATCH 06/14] Convert GMC to export based menu updates Wandering through the weeds that is GMC overriding cartridges overriding cartridges Simpson style. --- GMC/Cartridge.cpp | 15 ++++----------- GMC/Cartridge.h | 3 ++- GMC/CartridgeTrampolines.cpp | 9 ++++++--- GMC/CartridgeTrampolines.h | 1 + GMC/GMC.h | 1 + GMC/GMCCartridge.cpp | 19 +++++++++++++++++++ GMC/GMCCartridge.h | 5 ++--- 7 files changed, 35 insertions(+), 18 deletions(-) diff --git a/GMC/Cartridge.cpp b/GMC/Cartridge.cpp index f92d73b3..2da1d422 100644 --- a/GMC/Cartridge.cpp +++ b/GMC/Cartridge.cpp @@ -82,35 +82,28 @@ void Cartridge::SetMenuBuilderCallback(PakAppendCartridgeMenuHostCallback callba AddMenuItemPtr = callback; } - - std::string Cartridge::GetStatusMessage() const { return std::string(); } - void Cartridge::OnMenuItemSelected(unsigned char /*menuId*/) { } - - - void Cartridge::OnReset() {} - - - unsigned short Cartridge::UpdateAudio() { return 0; } - - +bool Cartridge::GetMenuItem(menu_item_entry* /*item*/, size_t /*index*/) +{ + return false; +} unsigned char Cartridge::OnReadMemory(unsigned short /*address*/) const { diff --git a/GMC/Cartridge.h b/GMC/Cartridge.h index 1bab6b66..0fa68303 100644 --- a/GMC/Cartridge.h +++ b/GMC/Cartridge.h @@ -33,7 +33,7 @@ class Cartridge virtual unsigned char OnReadMemory(unsigned short address) const; virtual void OnWritePort(unsigned char port, unsigned char data); virtual unsigned char OnReadPort(unsigned char port) const; - + virtual bool GetMenuItem(menu_item_entry* item, size_t index); protected: @@ -66,6 +66,7 @@ class Cartridge friend void PakWritePort(unsigned char port, unsigned char data); friend unsigned char PakReadPort(unsigned char port); friend unsigned short PakSampleAudio(); + friend bool PakGetMenuItem(menu_item_entry* item, size_t index); private: diff --git a/GMC/CartridgeTrampolines.cpp b/GMC/CartridgeTrampolines.cpp index 7dceab99..a61d7c78 100644 --- a/GMC/CartridgeTrampolines.cpp +++ b/GMC/CartridgeTrampolines.cpp @@ -83,9 +83,6 @@ GMC_EXPORT unsigned char PakReadMemoryByte(unsigned short address) return Cartridge::m_Singleton->OnReadMemory(address); } - - - GMC_EXPORT void PakWritePort(unsigned char port, unsigned char data) { Cartridge::m_Singleton->OnWritePort(port, data); @@ -104,3 +101,9 @@ GMC_EXPORT unsigned short PakSampleAudio() return Cartridge::m_Singleton->UpdateAudio(); } +// Return menu +GMC_EXPORT bool PakGetMenuItem(menu_item_entry* item, size_t index) +{ + return Cartridge::m_Singleton->GetMenuItem(item, index); +} + diff --git a/GMC/CartridgeTrampolines.h b/GMC/CartridgeTrampolines.h index 4fdb5961..2ec64889 100644 --- a/GMC/CartridgeTrampolines.h +++ b/GMC/CartridgeTrampolines.h @@ -16,3 +16,4 @@ GMC_EXPORT unsigned char PakReadMemoryByte(unsigned short address); GMC_EXPORT void PakWritePort(unsigned char port, unsigned char data); GMC_EXPORT unsigned char PakReadPort(unsigned char port); GMC_EXPORT unsigned short PakSampleAudio(); +GMC_EXPORT bool PakGetMenuItem(menu_item_entry* item, size_t index); diff --git a/GMC/GMC.h b/GMC/GMC.h index 09fdd0bd..f5f5ad19 100644 --- a/GMC/GMC.h +++ b/GMC/GMC.h @@ -2,6 +2,7 @@ #include #include "../CartridgeMenu.h" #include +#include #ifdef GMC_EXPORTS #define GMC_EXPORT extern "C" __declspec(dllexport) diff --git a/GMC/GMCCartridge.cpp b/GMC/GMCCartridge.cpp index bdf52d31..ae404803 100644 --- a/GMC/GMCCartridge.cpp +++ b/GMC/GMCCartridge.cpp @@ -1,6 +1,9 @@ #include "GMCCartridge.h" #include +#include +#include +static VCC::Bus::cartridge_menu GMCMenu {}; void GMCCartridge::LoadConfiguration(const std::string& filename) { @@ -8,14 +11,30 @@ void GMCCartridge::LoadConfiguration(const std::string& filename) m_Configuration = Configuration(filename); } +// OLD REMOVE THIS AND THE CALLBACK TOO SOMEWHERE IN THESE WEEDS void GMCCartridge::LoadMenuItems() { + // AddMenuItem is depreciated AddMenuItem("",MID_BEGIN,MIT_Head); AddMenuItem("",MID_ENTRY, MIT_Seperator); AddMenuItem("Select GMC ROM", ControlId(MenuItems::SelectRom), MIT_StandAlone); AddMenuItem("",MID_FINISH,MIT_Head); } +bool GMCCartridge::GetMenuItem(menu_item_entry* item, size_t index) +{ + if (!item) return false; + // request zero rebuilds the menu list but does it ever change? + // leave it incase we want to show the loaded rom in the menu + if (index == 0) { + GMCMenu.clear(); + GMCMenu.add("", 0, MIT_Seperator); + GMCMenu.add("Select GMC ROM", ControlId(MenuItems::SelectRom), MIT_StandAlone); + } + // return requested list item or false + return GMCMenu.copy_item(*item, index); +} + std::string GMCCartridge::GetStatusMessage() const { std::string message("GMC Active"); diff --git a/GMC/GMCCartridge.h b/GMC/GMCCartridge.h index 6fa2bc96..b8887e2b 100644 --- a/GMC/GMCCartridge.h +++ b/GMC/GMCCartridge.h @@ -18,13 +18,12 @@ class GMCCartridge : public Cartridge unsigned char OnReadMemory(unsigned short address) const override; void OnWritePort(unsigned char port, unsigned char data) override; unsigned char OnReadPort(unsigned char port) const override; - + bool GetMenuItem(menu_item_entry* item, size_t index) override; protected: - + // probably not needed void LoadMenuItems() override; - private: struct MenuItems From 3788b7a9bbe1daf022aa262ff118bc92c4a423e6 Mon Sep 17 00:00:00 2001 From: ejaquay Date: Sun, 15 Feb 2026 18:12:26 -0500 Subject: [PATCH 07/14] Convert HardDisk,acia,becker,and sdc to export menu updates New cartridge menu system based on get_menu_item exports and windows messaging is complete. Old and new systems are running in parallel for testing. Next remove old menu system, including the AddMenuItem callbacks from packinterface and DLL's. Remove CartridgeMenu.cpp and any thing that uses it and a bit of code clean up. Finalize API/ABI --- HardDisk/harddisk.cpp | 2 +- acia/acia.cpp | 20 ++++++++++++++++++++ becker/becker.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ sdc/sdc.cpp | 39 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 99 insertions(+), 3 deletions(-) diff --git a/HardDisk/harddisk.cpp b/HardDisk/harddisk.cpp index 50a95b12..b36c3ecd 100644 --- a/HardDisk/harddisk.cpp +++ b/HardDisk/harddisk.cpp @@ -66,7 +66,7 @@ static HWND hConfDlg = nullptr; LRESULT CALLBACK Config(HWND, UINT, WPARAM, LPARAM ); // Added for PakGetMenuItem export -bool get_menu_item(menu_item_entry*, size_t index); +bool get_menu_item(menu_item_entry* item, size_t index); // Added for PakGetMenuItem export static HWND gVccWnd = nullptr; diff --git a/acia/acia.cpp b/acia/acia.cpp index 28ab5a22..8fbb2df3 100644 --- a/acia/acia.cpp +++ b/acia/acia.cpp @@ -1,3 +1,4 @@ +//#define USE_LOGGING //------------------------------------------------------------------ // Copyright E J Jaquay 2022 // @@ -26,6 +27,7 @@ #include #include #include +#include //------------------------------------------------------------------------ // Local Functions @@ -74,6 +76,9 @@ char AciaFileWrPath[MAX_PATH]; // Path for file writes static unsigned char Rom[8192]; unsigned char LoadExtRom(const char *); +static VCC::Bus::cartridge_menu AciaMenu {}; +bool get_menu_item(menu_item_entry* item, size_t index); + //------------------------------------------------------------------------ // DLL Entry point //------------------------------------------------------------------------ @@ -141,6 +146,11 @@ extern "C" AciaStat[0]='\0'; } + __declspec(dllexport) bool PakGetMenuItem(menu_item_entry* item, size_t index) + { + return get_menu_item(item, index); + } + } //----------------------------------------------------------------------- @@ -248,6 +258,16 @@ void BuildCartridgeMenu() CartMenuCallback(gSlotId, "", MID_FINISH, MIT_Head); } +bool get_menu_item(menu_item_entry* item, size_t index) { + if (!item) return false; + if (index == 0) { + AciaMenu.clear(); + AciaMenu.add("", 0, MIT_Seperator); + AciaMenu.add("ACIA Config", ControlId(16), MIT_StandAlone); + } + return AciaMenu.copy_item(*item, index); +} + //----------------------------------------------------------------------- // Load saved config from ini file //---------------------------------------------------------------------- diff --git a/becker/becker.cpp b/becker/becker.cpp index 25dbb4fb..e85c4f2c 100644 --- a/becker/becker.cpp +++ b/becker/becker.cpp @@ -1,3 +1,24 @@ +//#define USE_LOGGING +//====================================================================== +// This file is part of VCC (Virtual Color Computer). +// Vcc is Copyright 2015 by Joseph Forgione +// +// VCC (Virtual Color Computer) is free software, you can redistribute +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see +// . +// +//====================================================================== + #define _WINSOCK_DEPRECATED_NO_WARNINGS #include @@ -12,6 +33,7 @@ #include #include #include +#include // socket static SOCKET dwSocket = 0; @@ -67,6 +89,9 @@ void BuildCartridgeMenu(); void LoadConfig(); void SaveConfig(); +static VCC::Bus::cartridge_menu BeckerMenu {}; +bool get_menu_item(menu_item_entry* item, size_t index); + // dll entry hook BOOL APIENTRY DllMain( HINSTANCE hinstDLL, @@ -430,6 +455,12 @@ extern "C" SetDWTCPConnectionEnable(1); BuildCartridgeMenu(); } + + __declspec(dllexport) bool PakGetMenuItem(menu_item_entry* item, size_t index) + { + return get_menu_item(item, index); + } + } @@ -533,7 +564,17 @@ extern "C" __declspec(dllexport) void PakGetStatus(char* text_buffer, size_t buf return; } +bool get_menu_item(menu_item_entry* item, size_t index) { + if (!item) return false; + if (index == 0) { + BeckerMenu.clear(); + BeckerMenu.add("", 0, MIT_Seperator); + BeckerMenu.add("DriveWire Server..", ControlId(16), MIT_StandAlone); + } + return BeckerMenu.copy_item(*item, index); +} +// Following is depreciated - remove void BuildCartridgeMenu() { CartMenuCallback(gSlotId, "", MID_BEGIN, MIT_Head); diff --git a/sdc/sdc.cpp b/sdc/sdc.cpp index 33e0f7c2..e47352fc 100644 --- a/sdc/sdc.cpp +++ b/sdc/sdc.cpp @@ -137,12 +137,14 @@ #include #include #include -#include "../CartridgeMenu.h" +#include "../CartridgeMenu.h" //REMOVE THIS OLD #include #include #include #include +#include +#include #include "sdc.h" @@ -227,6 +229,9 @@ static int UPDBTNS[8] = {ID_UPDATE0,ID_UPDATE1,ID_UPDATE2,ID_UPDATE3, static std::string gRomPath {}; +static VCC::Bus::cartridge_menu SdcMenu {}; +bool get_menu_item(menu_item_entry* item, size_t index); + //====================================================================== // Functions //====================================================================== @@ -386,6 +391,7 @@ extern "C" break; case 11: SDCMountNext (0); + SendMessage(gVccWindow,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); break; } BuildCartridgeMenu(); @@ -415,6 +421,13 @@ extern "C" return(PakRom[adr]); } } + + // Return SDC menu + __declspec(dllexport) bool PakGetMenuItem(menu_item_entry* item, size_t index) + { + return get_menu_item(item, index); + } + } BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID rsvd) @@ -434,7 +447,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID rsvd) //------------------------------------------------------------- // Generate menu for configuring the SDC //------------------------------------------------------------- -void BuildCartridgeMenu() +void BuildCartridgeMenu() //OBSOLETE REMOVE OLD { CartMenuCallback(gSlotId, "", MID_BEGIN, MIT_Head); CartMenuCallback(gSlotId, "", MID_ENTRY, MIT_Seperator); @@ -455,6 +468,28 @@ void BuildCartridgeMenu() CartMenuCallback(gSlotId, "", MID_FINISH, MIT_Head); } +// Return items for cartridge menu. Called for each item +bool get_menu_item(menu_item_entry* item, size_t index) +{ + if (!item) return false; + if (index == 0) { + std::string tmp = gCocoDisk[0].name; + if (tmp.empty()) { + tmp = "empty"; + } else if (gFileList.nextload_flag) { + tmp = tmp + " (load next)"; + } else { + tmp = tmp + " (no next)"; + } + SdcMenu.clear(); + SdcMenu.add("", 0, MIT_Seperator); + SdcMenu.add("SDC Drive 0",MID_ENTRY,MIT_Head); + SdcMenu.add(tmp, ControlId(11),MIT_Slave); + SdcMenu.add("SDC Config", ControlId(10), MIT_StandAlone); + } + return SdcMenu.copy_item(*item, index); +} + //------------------------------------------------------------ // Configure the SDC //------------------------------------------------------------ From 404ec4273756f7bc0bbf8f86c00410d69f41a404 Mon Sep 17 00:00:00 2001 From: ejaquay Date: Sun, 15 Feb 2026 23:15:28 -0500 Subject: [PATCH 08/14] Remove cartmenu callbacks from acia --- CartridgeMenu.cpp | 4 +++- CartridgeMenu.h | 6 ++--- Vcc.cpp | 2 +- acia/acia.cpp | 19 ++------------- libcommon/include/vcc/bus/cartridge_menu.h | 16 ------------- .../include/vcc/bus/cartridge_menuitem.h | 24 +++++++++++++++++++ 6 files changed, 33 insertions(+), 38 deletions(-) diff --git a/CartridgeMenu.cpp b/CartridgeMenu.cpp index 8c8f718f..862e168f 100644 --- a/CartridgeMenu.cpp +++ b/CartridgeMenu.cpp @@ -53,7 +53,9 @@ void CartridgeMenu::add(const char * name, unsigned int menu_id, MenuItemType ty // Some older DLLs used message type MIT_Head with an empty name for a seperator. // To support those here is a check for MIT_Head with an empty name. if (type == MIT_Head && strcmp(name,"") == 0) type = MIT_Seperator; - menu_.push_back({name,menu_id,type}); +std::string s = "~" + std::string(name); +menu_.push_back({s,menu_id,type}); +// menu_.push_back({name,menu_id,type}); break; } } diff --git a/CartridgeMenu.h b/CartridgeMenu.h index a7908377..13ebefe3 100644 --- a/CartridgeMenu.h +++ b/CartridgeMenu.h @@ -42,10 +42,10 @@ constexpr auto MID_ENTRY = 2; // A menu item with no control // it to call the control in the cartridge dll. This allows dynamic cartridge menus to // work properly regardless of which slot they are in. -constexpr auto MID_CONTROL = 5000; +//constexpr auto MID_CONTROL = 5000; // constexpr to convert menu id number to control id -constexpr int ControlId(int id) { return MID_CONTROL + id; }; +//constexpr int ControlId(int id) { return MID_CONTROL + id; }; struct CartMenuItem { std::string name; @@ -67,7 +67,7 @@ class CartridgeMenu { CartridgeMenu(); // Title is menu bar title, position is location menu will be placed on the menu bar. - void init(const char * title="Cartridge", int position=3); + void init(const char * title="Cartridge", int position=5); // Reserve cartmenu items. The reserve value allows the 'Cartridge' menu item and // it's submenu to remain intact when DLL's append items to the menu. The reserve diff --git a/Vcc.cpp b/Vcc.cpp index b2134ece..1c6e6be8 100644 --- a/Vcc.cpp +++ b/Vcc.cpp @@ -707,7 +707,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) HMENU DrawCartMenu (HWND hWnd) { gVccCartMenu.log(); - return gVccCartMenu.draw(hWnd,5,"Cartridge"); + return gVccCartMenu.draw(hWnd,3,"Cartridge"); } //-------------------------------------------------------------------------- diff --git a/acia/acia.cpp b/acia/acia.cpp index 8fbb2df3..79354fe6 100644 --- a/acia/acia.cpp +++ b/acia/acia.cpp @@ -23,7 +23,6 @@ //------------------------------------------------------------------ #include "acia.h" -#include "../CartridgeMenu.h" #include #include #include @@ -33,8 +32,6 @@ // Local Functions //------------------------------------------------------------------------ -void BuildCartridgeMenu(); - LRESULT CALLBACK Config(HWND, UINT, WPARAM, LPARAM); void LoadConfig(); void SaveConfig(); @@ -44,7 +41,6 @@ void SaveConfig(); //------------------------------------------------------------------------ slot_id_type gSlotId; -static PakAppendCartridgeMenuHostCallback CartMenuCallback = nullptr; PakAssertInteruptHostCallback AssertInt = nullptr; //------------------------------------------------------------------------ @@ -130,12 +126,10 @@ extern "C" const cpak_callbacks* const callbacks) { gSlotId = SlotId; - CartMenuCallback = callbacks->add_menu_item; AssertInt = callbacks->assert_interrupt; strcpy(IniFile, configuration_path); LoadConfig(); - BuildCartridgeMenu(); LoadExtRom("RS232.ROM"); sc6551_init(); } @@ -246,18 +240,9 @@ __declspec(dllexport) void PakMenuItemClicked(unsigned char /*MenuID*/) return; } - //----------------------------------------------------------------------- -// Add config option to Cartridge menu -//---------------------------------------------------------------------- -void BuildCartridgeMenu() -{ - CartMenuCallback(gSlotId, "", MID_BEGIN, MIT_Head); - CartMenuCallback(gSlotId, "", MID_ENTRY, MIT_Seperator); - CartMenuCallback(gSlotId, "ACIA Config", ControlId(16), MIT_StandAlone); - CartMenuCallback(gSlotId, "", MID_FINISH, MIT_Head); -} - +// Return acia menu items +//----------------------------------------------------------------------- bool get_menu_item(menu_item_entry* item, size_t index) { if (!item) return false; if (index == 0) { diff --git a/libcommon/include/vcc/bus/cartridge_menu.h b/libcommon/include/vcc/bus/cartridge_menu.h index 2df8f8e2..9b4172e5 100644 --- a/libcommon/include/vcc/bus/cartridge_menu.h +++ b/libcommon/include/vcc/bus/cartridge_menu.h @@ -48,22 +48,6 @@ namespace VCC::Bus { -// menu_id is an unsigned int between 0 and 49 that can be used by -// a cart to identify menus it adds. Multipak will bias the Menu ID -// by 50 times SlotId to as mechanism to determine which slot a -// message is for. Control ID is used in windows messages to detect -// menu button pushes. 5000 is added to menu_id to generate these -// control messages. - -//----------------------------------------------------- -// Message ID 5000 - 5249 are reserved for cartridge menus -// Message ID 5251 - 5299 are reseverd for cartridge messaging -//----------------------------------------------------- - -// Menu ID <-> Command ID mapping -constexpr auto MID_CONTROL = 5000; -constexpr int ControlId(int id) { return MID_CONTROL + id; } - // A single menu entry struct CartMenuItem { std::string name; diff --git a/libcommon/include/vcc/bus/cartridge_menuitem.h b/libcommon/include/vcc/bus/cartridge_menuitem.h index b6264595..ece4548d 100644 --- a/libcommon/include/vcc/bus/cartridge_menuitem.h +++ b/libcommon/include/vcc/bus/cartridge_menuitem.h @@ -1,3 +1,22 @@ +//====================================================================== +// This file is part of VCC (Virtual Color Computer). +// Vcc is Copyright 2015 by Joseph Forgione +// +// VCC (Virtual Color Computer) is free software, you can redistribute +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see +// . +//====================================================================== + #pragma once enum MenuItemType @@ -19,3 +38,8 @@ struct menu_item_entry // Sanity check maximum menu items constexpr auto MAX_MENU_ITEMS = 200u; + +// MenuItem ID <-> Command ID mapping +constexpr auto MID_CONTROL = 5000; +constexpr int ControlId(int id) { return MID_CONTROL + id; } + From bbc3dce48ca0e51ad60b97a8a5d908ecfc670c33 Mon Sep 17 00:00:00 2001 From: ejaquay Date: Sun, 15 Feb 2026 23:24:59 -0500 Subject: [PATCH 09/14] Disable cart menu callback for becker --- becker/becker.cpp | 21 --------------------- becker/becker.h | 1 - 2 files changed, 22 deletions(-) diff --git a/becker/becker.cpp b/becker/becker.cpp index e85c4f2c..ba1ad7ad 100644 --- a/becker/becker.cpp +++ b/becker/becker.cpp @@ -27,7 +27,6 @@ #include #include "becker.h" #include "resource.h" -#include "../CartridgeMenu.h" #include #include #include @@ -41,7 +40,6 @@ static SOCKET dwSocket = 0; // vcc stuff static HINSTANCE gModuleInstance; slot_id_type gSlotId {}; -static PakAppendCartridgeMenuHostCallback CartMenuCallback = nullptr; static PakAssertCartridgeLineHostCallback PakSetCart = nullptr; LRESULT CALLBACK Config(HWND, UINT, WPARAM, LPARAM); static char IniFile[MAX_PATH]=""; @@ -85,7 +83,6 @@ unsigned char LoadExtRom(const char *); void SetDWTCPConnectionEnable(unsigned int enable); int dw_setaddr(const char *bufdwaddr); int dw_setport(const char *bufdwport); -void BuildCartridgeMenu(); void LoadConfig(); void SaveConfig(); @@ -120,11 +117,6 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL, return TRUE; } - - - - - // coco checks for data unsigned char dw_status( void ) { @@ -446,14 +438,12 @@ extern "C" const cpak_callbacks* const callbacks) { gSlotId = SlotId; - CartMenuCallback = callbacks->add_menu_item; PakSetCart = callbacks->assert_cartridge_line; strcpy(IniFile, configuration_path); LastStats = GetTickCount(); LoadConfig(); SetDWTCPConnectionEnable(1); - BuildCartridgeMenu(); } __declspec(dllexport) bool PakGetMenuItem(menu_item_entry* item, size_t index) @@ -574,21 +564,11 @@ bool get_menu_item(menu_item_entry* item, size_t index) { return BeckerMenu.copy_item(*item, index); } -// Following is depreciated - remove -void BuildCartridgeMenu() -{ - CartMenuCallback(gSlotId, "", MID_BEGIN, MIT_Head); - CartMenuCallback(gSlotId, "", MID_ENTRY, MIT_Seperator); - CartMenuCallback(gSlotId, "DriveWire Server..", ControlId(16), MIT_StandAlone); - CartMenuCallback(gSlotId, "", MID_FINISH, MIT_Head); -} - extern "C" __declspec(dllexport) void PakMenuItemClicked(unsigned char MenuID) { HWND h_own = GetActiveWindow(); CreateDialog(gModuleInstance,(LPCTSTR)IDD_PROPPAGE,h_own,(DLGPROC)Config); ShowWindow(g_hConfigDlg,1); - BuildCartridgeMenu(); return; } @@ -688,7 +668,6 @@ void LoadConfig() dw_setport("65504"); - BuildCartridgeMenu(); GetModuleFileName(NULL, DiskRomPath, MAX_PATH); PathRemoveFileSpec(DiskRomPath); strcat( DiskRomPath, "hdbdwbck.rom"); diff --git a/becker/becker.h b/becker/becker.h index 51d38c7e..e2f5a786 100644 --- a/becker/becker.h +++ b/becker/becker.h @@ -10,7 +10,6 @@ // functions void MemWrite(unsigned char,unsigned short ); unsigned char MemRead(unsigned short ); -void BuildCartridgeMenu(); extern const unsigned char Rom[8192]; From 096db8a33c0b859aca4e9b3130ea638fcffa8b88 Mon Sep 17 00:00:00 2001 From: ejaquay Date: Sun, 15 Feb 2026 23:41:32 -0500 Subject: [PATCH 10/14] Remove cart menu callback from FD502 --- FD502/fd502.cpp | 66 +++--------------------------------------------- FD502/fd502.h | 1 - FD502/wd1793.cpp | 1 - 3 files changed, 4 insertions(+), 64 deletions(-) diff --git a/FD502/fd502.cpp b/FD502/fd502.cpp index ff258f4e..9a5e7add 100644 --- a/FD502/fd502.cpp +++ b/FD502/fd502.cpp @@ -35,7 +35,6 @@ #include "wd1793.h" #include "distortc.h" #include "fd502.h" -#include "../CartridgeMenu.h" #include #include #include @@ -63,7 +62,6 @@ static char RomFileName[MAX_PATH]=""; static char TempRomFileName[MAX_PATH]=""; slot_id_type gSlotId {}; PakAssertInteruptHostCallback AssertInt = nullptr; -static PakAppendCartridgeMenuHostCallback CartMenuCallback = nullptr; unsigned char PhysicalDriveA=0,PhysicalDriveB=0,OldPhysicalDriveA=0,OldPhysicalDriveB=0; static unsigned char *RomPointer[3]={ExternalRom,DiskRom,RGBDiskRom}; static unsigned char SelectRom=0; @@ -138,15 +136,11 @@ extern "C" DLOG_C("FDC %p %p %p %p %p\n",*callbacks); gSlotId = SlotId; gVccWnd = hVccWnd; - CartMenuCallback = callbacks->add_menu_item; AssertInt = callbacks->assert_interrupt; strcpy(IniFile, configuration_path); RealDisks = InitController(); LoadConfig(); - BuildCartridgeMenu(); - // Added for PakGetMenuItem export - // Request menu rebuild SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); } @@ -209,8 +203,6 @@ extern "C" ShowWindow(g_hConfDlg,1); break; } - //FIXME: Menu rebuild should not be here - BuildCartridgeMenu(); //OLD REMOVE return; } @@ -481,19 +473,19 @@ bool get_menu_item(menu_item_entry* item, size_t index) if (index == 0) { gDllCartMenu.clear(); gDllCartMenu.add("", 0, MIT_Seperator); - gDllCartMenu.add("FD-502 Drive 0",MID_ENTRY,MIT_Head); + gDllCartMenu.add("FD-502 Drive 0",0,MIT_Head); gDllCartMenu.add("Insert",ControlId(10),MIT_Slave); disk = VCC::Util::GetFileNamePart(gVirtualDrive[0].ImageName); gDllCartMenu.add("Eject: "+disk,ControlId(11),MIT_Slave); - gDllCartMenu.add("FD-502 Drive 1",MID_ENTRY,MIT_Head); + gDllCartMenu.add("FD-502 Drive 1",0,MIT_Head); gDllCartMenu.add("Insert",ControlId(12),MIT_Slave); disk = VCC::Util::GetFileNamePart(gVirtualDrive[1].ImageName); gDllCartMenu.add("Eject: "+disk,ControlId(13),MIT_Slave); - gDllCartMenu.add("FD-502 Drive 2",MID_ENTRY,MIT_Head); + gDllCartMenu.add("FD-502 Drive 2",0,MIT_Head); gDllCartMenu.add("Insert",ControlId(14),MIT_Slave); disk = VCC::Util::GetFileNamePart(gVirtualDrive[2].ImageName); gDllCartMenu.add("Eject: "+disk,ControlId(15),MIT_Slave); - gDllCartMenu.add("FD-502 Drive 3",MID_ENTRY,MIT_Head); + gDllCartMenu.add("FD-502 Drive 3",0,MIT_Head); gDllCartMenu.add("Insert",ControlId(17),MIT_Slave); disk = VCC::Util::GetFileNamePart(gVirtualDrive[3].ImageName); gDllCartMenu.add("Eject: "+disk,ControlId(18),MIT_Slave); @@ -503,53 +495,6 @@ bool get_menu_item(menu_item_entry* item, size_t index) return gDllCartMenu.copy_item(*item, index); } -// Following is OLD depreciated -void BuildCartridgeMenu() -{ - char TempMsg[MAX_PATH]=""; - char TempBuf[MAX_PATH]=""; - if (CartMenuCallback ==nullptr) - MessageBox(g_hConfDlg,"No good","Ok",0); - - CartMenuCallback(gSlotId, "", MID_BEGIN, MIT_Head); - CartMenuCallback(gSlotId, "", MID_ENTRY, MIT_Seperator); - - CartMenuCallback(gSlotId, "FD-502 Drive 0",MID_ENTRY,MIT_Head); - CartMenuCallback(gSlotId, "Insert",ControlId(10),MIT_Slave); - strncpy(TempMsg,"Eject: ",MAX_PATH); - strncpy(TempBuf,gVirtualDrive[0].ImageName,MAX_PATH); - PathStripPath(TempBuf); - strncat(TempMsg,TempBuf,MAX_PATH); - CartMenuCallback(gSlotId, TempMsg,ControlId(11),MIT_Slave); - - CartMenuCallback(gSlotId, "FD-502 Drive 1",MID_ENTRY,MIT_Head); - CartMenuCallback(gSlotId, "Insert",ControlId(12),MIT_Slave); - strncpy(TempMsg,"Eject: ",MAX_PATH); - strncpy(TempBuf,gVirtualDrive[1].ImageName,MAX_PATH); - PathStripPath(TempBuf); - strncat(TempMsg,TempBuf,MAX_PATH); - CartMenuCallback(gSlotId, TempMsg,ControlId(13),MIT_Slave); - - CartMenuCallback(gSlotId, "FD-502 Drive 2",MID_ENTRY,MIT_Head); - CartMenuCallback(gSlotId, "Insert",ControlId(14),MIT_Slave); - strncpy(TempMsg,"Eject: ",MAX_PATH); - strncpy(TempBuf,gVirtualDrive[2].ImageName,MAX_PATH); - PathStripPath(TempBuf); - strncat(TempMsg,TempBuf,MAX_PATH); - CartMenuCallback(gSlotId, TempMsg,ControlId(15),MIT_Slave); - - CartMenuCallback(gSlotId, "FD-502 Drive 3",MID_ENTRY,MIT_Head); - CartMenuCallback(gSlotId, "Insert",ControlId(17),MIT_Slave); - strncpy(TempMsg,"Eject: ",MAX_PATH); - strncpy(TempBuf,gVirtualDrive[3].ImageName,MAX_PATH); - PathStripPath(TempBuf); - strncat(TempMsg,TempBuf,MAX_PATH); - CartMenuCallback(gSlotId, TempMsg,ControlId(18),MIT_Slave); - - CartMenuCallback(gSlotId, "FD-502 Config",ControlId(16),MIT_StandAlone); - CartMenuCallback(gSlotId,"", MID_FINISH, MIT_Head); -} - long CreateDisk (unsigned char Disk) { NewDiskNumber=Disk; @@ -772,9 +717,6 @@ void LoadConfig() // Called on SetIniPath } ClockEnabled=GetPrivateProfileInt(ModName,"ClkEnable",1,IniFile); SetTurboDisk(GetPrivateProfileInt(ModName, "TurboDisk", 1, IniFile)); - - BuildCartridgeMenu(); //OLD - // Request menu rebuild SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); return; } diff --git a/FD502/fd502.h b/FD502/fd502.h index 17cd9b61..5d5f5cdc 100644 --- a/FD502/fd502.h +++ b/FD502/fd502.h @@ -21,7 +21,6 @@ This file is part of VCC (Virtual Color Computer). extern slot_id_type gSlotId; extern PakAssertInteruptHostCallback AssertInt; -void BuildCartridgeMenu(); // DO NOT REMOVE until becker.dll is retired. Then FD502 becker becomes permanant. #define COMBINE_BECKER diff --git a/FD502/wd1793.cpp b/FD502/wd1793.cpp index 506e6c05..08481076 100644 --- a/FD502/wd1793.cpp +++ b/FD502/wd1793.cpp @@ -248,7 +248,6 @@ int mount_disk_image(const char *filename,unsigned char drive) { unsigned int Temp=0; Temp=MountDisk(filename,drive); - BuildCartridgeMenu(); return(!Temp); } From 9989dce28eec473da16e4453bb716b67a18a9a4f Mon Sep 17 00:00:00 2001 From: ejaquay Date: Mon, 16 Feb 2026 00:00:13 -0500 Subject: [PATCH 11/14] Remove menu item callback from GMC cart --- GMC/Cartridge.cpp | 7 ------- GMC/Cartridge.h | 8 -------- GMC/CartridgeTrampolines.cpp | 1 - GMC/GMC.h | 1 - GMC/GMCCartridge.cpp | 10 ---------- GMC/GMCCartridge.h | 4 ---- 6 files changed, 31 deletions(-) diff --git a/GMC/Cartridge.cpp b/GMC/Cartridge.cpp index 2da1d422..28801003 100644 --- a/GMC/Cartridge.cpp +++ b/GMC/Cartridge.cpp @@ -22,7 +22,6 @@ namespace detail { void NullAssetCartridgeLine(slot_id_type, bool) {} - void NullAddMenuItem(slot_id_type, const char *, int, MenuItemType) {} } @@ -76,12 +75,6 @@ void Cartridge::SetConfigurationPath(std::string path) LoadMenuItems(); } - -void Cartridge::SetMenuBuilderCallback(PakAppendCartridgeMenuHostCallback callback) -{ - AddMenuItemPtr = callback; -} - std::string Cartridge::GetStatusMessage() const { return std::string(); diff --git a/GMC/Cartridge.h b/GMC/Cartridge.h index 0fa68303..c59626f1 100644 --- a/GMC/Cartridge.h +++ b/GMC/Cartridge.h @@ -5,7 +5,6 @@ namespace detail { void NullAssetCartridgeLine(slot_id_type, bool); - void NullAddMenuItem(slot_id_type, const char*, int, MenuItemType); } class Cartridge @@ -22,7 +21,6 @@ class Cartridge virtual void SetSlotId(slot_id_type SlotId); virtual void SetCartLineAssertCallback(PakAssertCartridgeLineHostCallback callback); - virtual void SetMenuBuilderCallback(PakAppendCartridgeMenuHostCallback addMenuCallback); virtual void SetConfigurationPath(std::string path); virtual std::string GetStatusMessage() const; @@ -42,11 +40,6 @@ class Cartridge AssetCartridgeLinePtr(m_SlotId, state); } - void AddMenuItem(const char * name, int id, MenuItemType type) - { - AddMenuItemPtr(m_SlotId, name, id, type); - } - virtual void LoadConfiguration(const std::string& filename); virtual void LoadMenuItems(); @@ -77,6 +70,5 @@ class Cartridge std::string m_CatalogId; std::string m_ConfigurationPath; PakAssertCartridgeLineHostCallback AssetCartridgeLinePtr = detail::NullAssetCartridgeLine; - PakAppendCartridgeMenuHostCallback AddMenuItemPtr = detail::NullAddMenuItem; }; diff --git a/GMC/CartridgeTrampolines.cpp b/GMC/CartridgeTrampolines.cpp index a61d7c78..b2a46d41 100644 --- a/GMC/CartridgeTrampolines.cpp +++ b/GMC/CartridgeTrampolines.cpp @@ -48,7 +48,6 @@ GMC_EXPORT void PakInitialize( callbacks->add_menu_item); Cartridge::m_Singleton->SetSlotId(SlotId); - Cartridge::m_Singleton->SetMenuBuilderCallback(callbacks->add_menu_item); Cartridge::m_Singleton->SetCartLineAssertCallback(callbacks->assert_cartridge_line); Cartridge::m_Singleton->SetConfigurationPath(configuration_path); } diff --git a/GMC/GMC.h b/GMC/GMC.h index f5f5ad19..44c6e5a8 100644 --- a/GMC/GMC.h +++ b/GMC/GMC.h @@ -1,6 +1,5 @@ #pragma once #include -#include "../CartridgeMenu.h" #include #include diff --git a/GMC/GMCCartridge.cpp b/GMC/GMCCartridge.cpp index ae404803..86468ddc 100644 --- a/GMC/GMCCartridge.cpp +++ b/GMC/GMCCartridge.cpp @@ -11,16 +11,6 @@ void GMCCartridge::LoadConfiguration(const std::string& filename) m_Configuration = Configuration(filename); } -// OLD REMOVE THIS AND THE CALLBACK TOO SOMEWHERE IN THESE WEEDS -void GMCCartridge::LoadMenuItems() -{ - // AddMenuItem is depreciated - AddMenuItem("",MID_BEGIN,MIT_Head); - AddMenuItem("",MID_ENTRY, MIT_Seperator); - AddMenuItem("Select GMC ROM", ControlId(MenuItems::SelectRom), MIT_StandAlone); - AddMenuItem("",MID_FINISH,MIT_Head); -} - bool GMCCartridge::GetMenuItem(menu_item_entry* item, size_t index) { if (!item) return false; diff --git a/GMC/GMCCartridge.h b/GMC/GMCCartridge.h index b8887e2b..a5b80833 100644 --- a/GMC/GMCCartridge.h +++ b/GMC/GMCCartridge.h @@ -20,10 +20,6 @@ class GMCCartridge : public Cartridge unsigned char OnReadPort(unsigned char port) const override; bool GetMenuItem(menu_item_entry* item, size_t index) override; -protected: - // probably not needed - void LoadMenuItems() override; - private: struct MenuItems From 2a821745760e481190e60ea68a1a52e26d4f4e2c Mon Sep 17 00:00:00 2001 From: ejaquay Date: Mon, 16 Feb 2026 00:32:52 -0500 Subject: [PATCH 12/14] Remove menu item callback from HardDisk, SuperIDE, and sdc --- HardDisk/harddisk.cpp | 42 ++---------------------------------------- SuperIDE/SuperIDE.cpp | 40 ++-------------------------------------- sdc/sdc.cpp | 43 +++++++++---------------------------------- 3 files changed, 13 insertions(+), 112 deletions(-) diff --git a/HardDisk/harddisk.cpp b/HardDisk/harddisk.cpp index b36c3ecd..d93cddac 100644 --- a/HardDisk/harddisk.cpp +++ b/HardDisk/harddisk.cpp @@ -27,7 +27,6 @@ #include #include #include -#include "../CartridgeMenu.h" #include #include // Three includes added for PakGetMenuItem @@ -49,7 +48,6 @@ static ::VCC::Device::rtc::cloud9 cloud9_rtc; static slot_id_type gSlotId {}; static PakReadMemoryByteHostCallback MemRead8 = nullptr; static PakWriteMemoryByteHostCallback MemWrite8 = nullptr; -static PakAppendCartridgeMenuHostCallback CartMenuCallback = nullptr; static bool ClockEnabled = true; static bool ClockReadOnly = true; LRESULT CALLBACK NewDisk(HWND,UINT, WPARAM, LPARAM); @@ -58,7 +56,6 @@ LRESULT CALLBACK NewDisk(HWND,UINT, WPARAM, LPARAM); void LoadHardDisk(int drive); void LoadConfig(); void SaveConfig(); -void BuildCartridgeMenu(); //OLD int CreateDisk(HWND,int); static HINSTANCE gModuleInstance; @@ -124,7 +121,6 @@ extern "C" { gSlotId = SlotId; gVccWnd = hVccWnd; - CartMenuCallback = callbacks->add_menu_item; //OLD MemRead8 = callbacks->read_memory_byte; MemWrite8 = callbacks->write_memory_byte; strcpy(IniFile, configuration_path); @@ -132,8 +128,6 @@ extern "C" LoadConfig(); cloud9_rtc.set_read_only(ClockReadOnly); VhdReset(); // Selects drive zero - BuildCartridgeMenu(); - // Added for PakGetMenuItem export // Request menu rebuild SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); } @@ -187,7 +181,6 @@ extern "C" } SaveConfig(); // FIXME should only rebuild menus if drive is changed - BuildCartridgeMenu(); // Old SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); return; } @@ -371,8 +364,6 @@ void LoadConfig() ClockReadOnly = GetPrivateProfileInt(ModName, "ClkRdOnly", 1, IniFile) != 0; // Create config menu - BuildCartridgeMenu(); //OLD - // Added for PakGetMenuItem SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); return; } @@ -407,11 +398,11 @@ bool get_menu_item(menu_item_entry* item, size_t index) if (index == 0) { gDllCartMenu.clear(); gDllCartMenu.add("", 0, MIT_Seperator); - gDllCartMenu.add("HD Drive 0",MID_ENTRY,MIT_Head); + gDllCartMenu.add("HD Drive 0",0,MIT_Head); gDllCartMenu.add("Insert",ControlId(10),MIT_Slave); disk = VCC::Util::GetFileNamePart(VHDfile0); gDllCartMenu.add("Eject: "+disk,ControlId(11),MIT_Slave); - gDllCartMenu.add("HD Drive 1",MID_ENTRY,MIT_Head); + gDllCartMenu.add("HD Drive 1",0,MIT_Head); gDllCartMenu.add("Insert",ControlId(12),MIT_Slave); disk = VCC::Util::GetFileNamePart(VHDfile1); gDllCartMenu.add("Eject: "+disk,ControlId(13),MIT_Slave); @@ -421,35 +412,6 @@ bool get_menu_item(menu_item_entry* item, size_t index) return gDllCartMenu.copy_item(*item, index); } -// OLD Generate menu for mounting the drives OLD -void BuildCartridgeMenu() -{ - char TempMsg[512] = ""; - char TempBuf[MAX_PATH] = ""; - - CartMenuCallback(gSlotId, "", MID_BEGIN, MIT_Head); - CartMenuCallback(gSlotId, "", MID_ENTRY, MIT_Seperator); - - CartMenuCallback(gSlotId, "HD Drive 0", MID_ENTRY, MIT_Head); - CartMenuCallback(gSlotId, "Insert", ControlId(10), MIT_Slave); - strcpy(TempMsg, "Eject: "); - strcpy(TempBuf, VHDfile0); - PathStripPath(TempBuf); - strcat(TempMsg, TempBuf); - CartMenuCallback(gSlotId, TempMsg, ControlId(11), MIT_Slave); - - CartMenuCallback(gSlotId, "HD Drive 1", MID_ENTRY, MIT_Head); - CartMenuCallback(gSlotId, "Insert", ControlId(12), MIT_Slave); - strcpy(TempMsg, "Eject: "); - strcpy(TempBuf, VHDfile1); - PathStripPath(TempBuf); - strcat(TempMsg, TempBuf); - CartMenuCallback(gSlotId, TempMsg, ControlId(13), MIT_Slave); - - CartMenuCallback(gSlotId, "HD Config", ControlId(14), MIT_StandAlone); - CartMenuCallback(gSlotId, "", MID_FINISH, MIT_Head); -} - // Dialog for creating a new hard disk LRESULT CALLBACK NewDisk(HWND hDlg, UINT message, WPARAM wParam, LPARAM /*lParam*/) { diff --git a/SuperIDE/SuperIDE.cpp b/SuperIDE/SuperIDE.cpp index 92eb2554..69913dc2 100644 --- a/SuperIDE/SuperIDE.cpp +++ b/SuperIDE/SuperIDE.cpp @@ -26,12 +26,10 @@ #include "IdeBus.h" #include #include -#include "../CartridgeMenu.h" #include #include #include #include -// Three includes added for PakGetMenuItem #include #include #include @@ -40,9 +38,7 @@ static char FileName[MAX_PATH] { 0 }; static char IniFile[MAX_PATH] { 0 }; static char SuperIDEPath[MAX_PATH]; static ::VCC::Device::rtc::cloud9 cloud9_rtc; -static PakAppendCartridgeMenuHostCallback CartMenuCallback = nullptr; static unsigned char BaseAddress=0x50; -void BuildCartridgeMenu(); LRESULT CALLBACK IDE_Config(HWND, UINT, WPARAM, LPARAM ); void Select_Disk(unsigned char); void SaveConfig(); @@ -102,13 +98,10 @@ extern "C" { gSlotId = SlotId; gVccWnd = hVccWnd; - CartMenuCallback = callbacks->add_menu_item; strcpy(IniFile, configuration_path); LoadConfig(); IdeInit(); - - BuildCartridgeMenu(); // REMOVE THIS //SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); } @@ -185,28 +178,24 @@ extern "C" { case 10: Select_Disk(MASTER); - BuildCartridgeMenu(); SaveConfig(); SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); break; case 11: DropDisk(MASTER); - BuildCartridgeMenu(); SaveConfig(); SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); break; case 12: Select_Disk(SLAVE); - BuildCartridgeMenu(); SaveConfig(); SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); break; case 13: DropDisk(SLAVE); - BuildCartridgeMenu(); SaveConfig(); SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); break; @@ -248,11 +237,11 @@ bool get_menu_item(menu_item_entry* item, size_t index) if (index == 0) { gDllCartMenu.clear(); gDllCartMenu.add("", 0, MIT_Seperator); - gDllCartMenu.add("IDE Master",MID_ENTRY,MIT_Head); + gDllCartMenu.add("IDE Master",0,MIT_Head); gDllCartMenu.add("Insert",ControlId(10),MIT_Slave); disk = VCC::Util::GetFileNamePart(QueryDisk(MASTER)); gDllCartMenu.add("Eject: "+disk,ControlId(11),MIT_Slave); - gDllCartMenu.add("IDE Slave",MID_ENTRY,MIT_Head); + gDllCartMenu.add("IDE Slave",0,MIT_Head); gDllCartMenu.add("Insert",ControlId(12),MIT_Slave); disk = VCC::Util::GetFileNamePart(QueryDisk(SLAVE)); gDllCartMenu.add("Eject: "+disk,ControlId(13),MIT_Slave); @@ -262,30 +251,6 @@ bool get_menu_item(menu_item_entry* item, size_t index) return gDllCartMenu.copy_item(*item, index); } -void BuildCartridgeMenu() -{ - char TempMsg[512]=""; - char TempBuf[MAX_PATH]=""; - CartMenuCallback(gSlotId, "", MID_BEGIN, MIT_Head); - CartMenuCallback(gSlotId, "", MID_ENTRY, MIT_Seperator); - CartMenuCallback(gSlotId, "IDE Master",MID_ENTRY,MIT_Head); - CartMenuCallback(gSlotId, "Insert",ControlId(10),MIT_Slave); - QueryDisk(MASTER,TempBuf); - strcpy(TempMsg,"Eject: "); - PathStripPath (TempBuf); - strcat(TempMsg,TempBuf); - CartMenuCallback(gSlotId, TempMsg,ControlId(11),MIT_Slave); - CartMenuCallback(gSlotId, "IDE Slave",MID_ENTRY,MIT_Head); - CartMenuCallback(gSlotId, "Insert",ControlId(12),MIT_Slave); - QueryDisk(SLAVE,TempBuf); - strcpy(TempMsg,"Eject: "); - PathStripPath (TempBuf); - strcat(TempMsg,TempBuf); - CartMenuCallback(gSlotId, TempMsg,ControlId(13),MIT_Slave); - CartMenuCallback(gSlotId, "IDE Config",ControlId(14),MIT_StandAlone); - CartMenuCallback(gSlotId, "", MID_FINISH, MIT_Head); -} - LRESULT CALLBACK IDE_Config(HWND hDlg, UINT message, WPARAM wParam, LPARAM /*lParam*/) { unsigned char BTemp=0; @@ -408,7 +373,6 @@ void LoadConfig() BaseAddress=BaseTable[BaseAddr]; cloud9_rtc.set_read_only(ClockReadOnly); MountDisk(FileName ,SLAVE); - BuildCartridgeMenu(); SendMessage(gVccWnd,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); return; } diff --git a/sdc/sdc.cpp b/sdc/sdc.cpp index e47352fc..1f273adf 100644 --- a/sdc/sdc.cpp +++ b/sdc/sdc.cpp @@ -137,7 +137,6 @@ #include #include #include -#include "../CartridgeMenu.h" //REMOVE THIS OLD #include #include @@ -170,7 +169,6 @@ static slot_id_type gSlotId {}; // Callback pointers static PakAssertInteruptHostCallback AssertIntCallback = nullptr; -static PakAppendCartridgeMenuHostCallback CartMenuCallback = nullptr; // Settings static char IniFile[MAX_PATH] = {}; @@ -239,7 +237,6 @@ bool get_menu_item(menu_item_entry* item, size_t index); LRESULT CALLBACK SDC_Configure(HWND, UINT, WPARAM, LPARAM); void LoadConfig(); bool SaveConfig(HWND); -void BuildCartridgeMenu(); void SelectCardBox(); void UpdateFlashItem(int); void InitCardBox(); @@ -315,11 +312,9 @@ extern "C" gVccWindow = hVccWnd; DLOG_C("SDC %p %p %p %p %p\n",*callbacks); gSlotId = SlotId; - CartMenuCallback = callbacks->add_menu_item; AssertIntCallback = callbacks->assert_interrupt; strcpy(IniFile, configuration_path); LoadConfig(); - BuildCartridgeMenu(); } __declspec(dllexport) const char* PakGetName() @@ -394,7 +389,6 @@ extern "C" SendMessage(gVccWindow,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); break; } - BuildCartridgeMenu(); return; } @@ -445,30 +439,8 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID rsvd) //====================================================================== //------------------------------------------------------------- -// Generate menu for configuring the SDC -//------------------------------------------------------------- -void BuildCartridgeMenu() //OBSOLETE REMOVE OLD -{ - CartMenuCallback(gSlotId, "", MID_BEGIN, MIT_Head); - CartMenuCallback(gSlotId, "", MID_ENTRY, MIT_Seperator); - CartMenuCallback(gSlotId, "SDC Drive 0",MID_ENTRY,MIT_Head); - char tmp[64]={}; - if (strcmp(gCocoDisk[0].name,"") == 0) { - strcpy(tmp,"empty"); - } else { - strcpy(tmp,gCocoDisk[0].name); - if (gFileList.nextload_flag) { - strcat(tmp," (load next)"); - } else { - strcat(tmp," (no next)"); - } - } - CartMenuCallback(gSlotId, tmp, ControlId(11),MIT_Slave); - CartMenuCallback(gSlotId, "SDC Config", ControlId(10), MIT_StandAlone); - CartMenuCallback(gSlotId, "", MID_FINISH, MIT_Head); -} - // Return items for cartridge menu. Called for each item +//------------------------------------------------------------- bool get_menu_item(menu_item_entry* item, size_t index) { if (!item) return false; @@ -483,7 +455,7 @@ bool get_menu_item(menu_item_entry* item, size_t index) } SdcMenu.clear(); SdcMenu.add("", 0, MIT_Seperator); - SdcMenu.add("SDC Drive 0",MID_ENTRY,MIT_Head); + SdcMenu.add("SDC Drive 0",0,MIT_Head); SdcMenu.add(tmp, ControlId(11),MIT_Slave); SdcMenu.add("SDC Config", ControlId(10), MIT_StandAlone); } @@ -1913,7 +1885,8 @@ void SDCMountDisk (int drive, const char * path, int raw) if (*path == '\0') { DLOG_C("SDCMountDisk unload %d %s\n",drive,path); IFace.status = STA_NORMAL; - if (drive == 0) BuildCartridgeMenu(); + if (drive == 0) + SendMessage(gVccWindow,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); return; } @@ -2099,7 +2072,8 @@ void SDCOpenFound (int drive,int raw) DLOG_C("SDCOpenFound %s directory initiate\n",pattern.c_str()); if (SDCInitiateDir(pattern.c_str())) { SDCOpenFound(drive, 0); - if (drive == 0) BuildCartridgeMenu(); + if (drive == 0) + SendMessage(gVccWindow,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); } return; } @@ -2230,7 +2204,8 @@ void SDCOpenFound (int drive,int raw) } } - if (drive == 0) BuildCartridgeMenu(); + if (drive == 0) + SendMessage(gVccWindow,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); IFace.status = STA_NORMAL; return; @@ -2556,7 +2531,7 @@ bool SearchFile(const std::string& pat) // Fill gFileList with files found. GetFileList(pat); // Update menu to show next disk status - BuildCartridgeMenu(); + SendMessage(gVccWindow,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); // Return true if something found return (gFileList.files.size() > 0); } From 98fcc744c0073a2975e09267e029db3af29b5dcd Mon Sep 17 00:00:00 2001 From: ejaquay Date: Mon, 16 Feb 2026 12:56:42 -0500 Subject: [PATCH 13/14] Remove all remnants of add_cart_menu and init callbacks removed from all cartridge classes removed from all vcc and dll code removed old CartridgeMenu class --- CartridgeMenu.cpp | 139 ------------------ CartridgeMenu.h | 86 ----------- GMC/CartridgeTrampolines.cpp | 5 +- Vcc.cpp | 30 ++-- Vcc.vcxproj | 8 - .../include/vcc/bus/cartridge_callbacks.h | 12 +- .../vcc/bus/cpak_cartridge_definitions.h | 3 - libcommon/src/bus/CartridgeInterface.txt | 87 +++-------- mpi/cartridge_slot.cpp | 1 - mpi/cartridge_slot.h | 25 +--- mpi/configuration_dialog.cpp | 3 +- mpi/configuration_dialog.h | 1 - mpi/host_cartridge_context.h | 30 ++-- mpi/mpi.cpp | 1 - mpi/multipak_cartridge.cpp | 64 +------- mpi/multipak_cartridge.h | 8 - mpi/multipak_cartridge_context.h | 10 -- mpi/multipak_configuration.cpp | 1 - mpi/multipak_configuration.h | 2 - pakinterface.cpp | 104 ++++--------- pakinterface.h | 36 ++--- 21 files changed, 98 insertions(+), 558 deletions(-) delete mode 100644 CartridgeMenu.cpp delete mode 100644 CartridgeMenu.h diff --git a/CartridgeMenu.cpp b/CartridgeMenu.cpp deleted file mode 100644 index 862e168f..00000000 --- a/CartridgeMenu.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* -Copyright 2015 by Joseph Forgione -This file is part of VCC (Virtual Color Computer). - - VCC (Virtual Color Computer) 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 3 of the License, or - (at your option) any later version. - - VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see . -*/ - -// TODO: move this to libcommon - -#include "CartridgeMenu.h" -#include -#include "defines.h" - -CartridgeMenu::CartridgeMenu() {}; - -// Init. Title is menu bar title. Position is where the menu is placed on title bar -void CartridgeMenu::init(const char * title,int position) { - MenuBarTitle_ = title; - MenuPosition_ = position; - reserve_ = 0; -} - -// Menu add requests come from both the pakinterface and carts via config calls; -// pakinterface entries should always be first, followed by carts in slot 4 to 1 in -// that order. pakinterface can set the reserve to keep it's menu items from being -// overwritten from the mpi scan of the slots. -// Set the number of entries to reserve for cartridge menu -void CartridgeMenu::reserve(const unsigned int count) { - reserve_ = count; -}; - -// Add menu entry. -void CartridgeMenu::add(const char * name, unsigned int menu_id, MenuItemType type) { - switch (menu_id) { - case MID_BEGIN: - if (menu_.size() > reserve_) menu_.resize(reserve_); - break; - case MID_FINISH: - draw(); - break; - default: - // Some older DLLs used message type MIT_Head with an empty name for a seperator. - // To support those here is a check for MIT_Head with an empty name. - if (type == MIT_Head && strcmp(name,"") == 0) type = MIT_Seperator; -std::string s = "~" + std::string(name); -menu_.push_back({s,menu_id,type}); -// menu_.push_back({name,menu_id,type}); - break; - } -} - -// Draw the menu -HMENU CartridgeMenu::draw() { - - // Fullscreen toggle changes the WindowHandle - if (hMenuBar_ == nullptr || hMainWin_ != EmuState.WindowHandle) { - hMainWin_ = EmuState.WindowHandle; - hMenuBar_ = GetMenu(hMainWin_); - } - - // Erase the Existing Cartridge Menu. Vcc.rc defines a dummy Cartridge menu to - // preserve it's place. - DeleteMenu(hMenuBar_,MenuPosition_,MF_BYPOSITION); - - // Create first sub menu item - HMENU hMenu = CreatePopupMenu(); - HMENU hMenu0 = hMenu; - - MENUITEMINFO Mii{}; - memset(&Mii,0,sizeof(MENUITEMINFO)); - - // Create title bar item - Mii.cbSize= sizeof(MENUITEMINFO); - Mii.fMask = MIIM_TYPE | MIIM_SUBMENU | MIIM_ID; // setting the submenu id - Mii.fType = MFT_STRING; // Type is a string - Mii.hSubMenu = hMenu; - Mii.dwTypeData = const_cast(MenuBarTitle_.c_str()); - Mii.cch = MenuBarTitle_.size(); - InsertMenuItem(hMenuBar_,MenuPosition_,TRUE,&Mii); - - // Create sub menus in order - unsigned int pos = 0u; - for (CartMenuItem item : menu_) { - DLOG_C("%4d %d '%s'\n",item.menu_id,item.type,item.name.c_str()); - switch (item.type) { - case MIT_Head: - hMenu = CreatePopupMenu(); - Mii.fMask = MIIM_TYPE | MIIM_SUBMENU | MIIM_ID; - Mii.fType = MFT_STRING; - Mii.hSubMenu = hMenu; - Mii.dwTypeData = const_cast(item.name.c_str()); - InsertMenuItem(hMenu0,pos,TRUE,&Mii); - pos++; - break; - case MIT_Slave: - Mii.fMask = MIIM_TYPE | MIIM_ID; - Mii.fType = MFT_STRING; - Mii.wID = item.menu_id; - Mii.hSubMenu = hMenu; - Mii.dwTypeData = const_cast(item.name.c_str()); - Mii.cch=item.name.size(); - InsertMenuItem(hMenu,0,FALSE,&Mii); - break; - case MIT_Seperator: - Mii.fMask = MIIM_TYPE | MIIM_ID; - Mii.hSubMenu = hMenuBar_; - Mii.dwTypeData = ""; - Mii.cch=0; - Mii.fType = MF_SEPARATOR; - InsertMenuItem(hMenu0,pos,TRUE,&Mii); - pos++; - break; - case MIT_StandAlone: - Mii.fMask = MIIM_TYPE | MIIM_ID; - Mii.wID = item.menu_id; - Mii.hSubMenu = hMenuBar_; - Mii.dwTypeData = const_cast(item.name.c_str()); - Mii.cch=item.name.size(); - Mii.fType = MFT_STRING; - InsertMenuItem(hMenu0,pos,TRUE,&Mii); - pos++; - break; - } - } - DrawMenuBar(hMainWin_); - return hMenu0; -} - diff --git a/CartridgeMenu.h b/CartridgeMenu.h deleted file mode 100644 index 13ebefe3..00000000 --- a/CartridgeMenu.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright 2015 by Joseph Forgione - This file is part of VCC (Virtual Color Computer). - - VCC (Virtual Color Computer) 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 3 of the License, or - (at your option) any later version. - - VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see . -*/ - -#pragma once - -#include -#include -#include -#include // for menu item type - -// A menu ID is either a small unsigned integer less than or equal to 50 used -// to identify cart menu functions with control id in the range 5000 - 5050. -// Menu ID's map directly to control id's by adding 5000. The ControlId() -// constexpr should be used to get the control id from a menu id. There are three -// "special" message IDs as follows: - -constexpr auto MID_BEGIN = 0; // Clears the menu, optionally reserving some entries. -constexpr auto MID_FINISH = 1; // Draws the menu -constexpr auto MID_ENTRY = 2; // A menu item with no control - -// Menu IDs other than the above special ones must be converted to control IDs -// using the ControlId() constexpr. These reference controls that are activated -// when the menu item is selected. - -// The MPI adds 50 times the slot number (1-4) to the ID when a cartridge is loaded in -// an mpi slot, then subtracts this value when the item is activated before using -// it to call the control in the cartridge dll. This allows dynamic cartridge menus to -// work properly regardless of which slot they are in. - -//constexpr auto MID_CONTROL = 5000; - -// constexpr to convert menu id number to control id -//constexpr int ControlId(int id) { return MID_CONTROL + id; }; - -struct CartMenuItem { - std::string name; - unsigned int menu_id; - MenuItemType type; -}; - -class CartridgeMenu { - -private: - std::vector menu_ {}; - HWND hMainWin_; - HMENU hMenuBar_; - std::string MenuBarTitle_; - int MenuPosition_; - unsigned int reserve_; - -public: - CartridgeMenu(); - -// Title is menu bar title, position is location menu will be placed on the menu bar. - void init(const char * title="Cartridge", int position=5); - -// Reserve cartmenu items. The reserve value allows the 'Cartridge' menu item and -// it's submenu to remain intact when DLL's append items to the menu. The reserve -// value is only used whwn MID_BEGIN items are encountered. - void reserve(const unsigned int count); - -// Add menu entry. name is the item text, menu_id and type per above. Reserve is the -// number of menu items to kept before MID_BEGIN. - void add(const char * name, unsigned int menu_id, MenuItemType type); - -// Draw refreshes the menu - HMENU draw(); -}; - -// Make CartridgeMenu Object global; -extern CartridgeMenu CartMenu; diff --git a/GMC/CartridgeTrampolines.cpp b/GMC/CartridgeTrampolines.cpp index b2a46d41..58b7dba9 100644 --- a/GMC/CartridgeTrampolines.cpp +++ b/GMC/CartridgeTrampolines.cpp @@ -40,12 +40,11 @@ GMC_EXPORT void PakInitialize( HWND hVccWnd, const cpak_callbacks* const callbacks) { - DLOG_C("GMC %p %p %p %p %p\n", + DLOG_C("GMC %p %p %p %p\n", callbacks->assert_interrupt, callbacks->assert_cartridge_line, callbacks->write_memory_byte, - callbacks->read_memory_byte, - callbacks->add_menu_item); + callbacks->read_memory_byte); Cartridge::m_Singleton->SetSlotId(SlotId); Cartridge::m_Singleton->SetCartLineAssertCallback(callbacks->assert_cartridge_line); diff --git a/Vcc.cpp b/Vcc.cpp index 1c6e6be8..87c2ecac 100644 --- a/Vcc.cpp +++ b/Vcc.cpp @@ -56,7 +56,7 @@ #include "mc6821.h" #include "keyboard.h" #include "coco3.h" -#include "CartridgeMenu.h" +//#include "CartridgeMenu.h" #include "pakinterface.h" #include "audio.h" #include "config.h" @@ -137,13 +137,15 @@ static unsigned char FlagEmuStop=TH_RUNNING; bool IsShiftKeyDown(); -CartridgeMenu CartMenu; //OLD -using VCC::Bus::gVccCartMenu; //NEW +using VCC::Bus::gVccCartMenu; static bool gHasFocus {}; //static CRITICAL_SECTION FrameRender; -/*--------------------------------------------------------------------------*/ + +//--------------------------------------------------------------------------// +// Main entry +//--------------------------------------------------------------------------// int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, @@ -178,10 +180,6 @@ int APIENTRY WinMain(_In_ HINSTANCE hInstance, exit(0); } - // initial set up the cartridge menu. - CartMenu.init(); //old - BeginCartMenu(); //old - InitSound(); LoadModule(); SetClockSpeed(1); //Default clock speed .89 MHZ @@ -277,8 +275,10 @@ void CloseApp() UnloadDll(); } -/*--------------------------------------------------------------------------*/ -// The Window Procedure +//--------------------------------------------------------------------------// +// VCC Main Window messaging loop +//--------------------------------------------------------------------------// + LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; @@ -702,12 +702,14 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } //-------------------------------------------------------------------------- -// Draw the cartridge menu +// Refresh the cartridge menu from the menu item list //-------------------------------------------------------------------------- HMENU DrawCartMenu (HWND hWnd) { - gVccCartMenu.log(); - return gVccCartMenu.draw(hWnd,3,"Cartridge"); + //gVccCartMenu.log(); + + // window handle, zero based position on menu bar, name on bar. + return gVccCartMenu.draw( hWnd, 3, "Cartridge"); } //-------------------------------------------------------------------------- @@ -1114,7 +1116,7 @@ void FullScreenToggle() exit(0); } InvalidateBoarder(); - CartMenu.draw(); +// CartMenu.draw(); EmuState.ConfigDialog=nullptr; PauseAudio(false); diff --git a/Vcc.vcxproj b/Vcc.vcxproj index f1938c6e..117321db 100644 --- a/Vcc.vcxproj +++ b/Vcc.vcxproj @@ -150,14 +150,6 @@ - - Level4 - true - Level4 - Level4 - true - true - Level4 true diff --git a/libcommon/include/vcc/bus/cartridge_callbacks.h b/libcommon/include/vcc/bus/cartridge_callbacks.h index 56a12a5b..d6d86501 100644 --- a/libcommon/include/vcc/bus/cartridge_callbacks.h +++ b/libcommon/include/vcc/bus/cartridge_callbacks.h @@ -22,29 +22,19 @@ enum MenuItemType; -// TODO: Where cartridge_context is used make it explicit; It should not be passed as void *; -// Defines the callbacks a cartridge can make namespace VCC::Core { - struct LIBCOMMON_EXPORT cartridge_context { using path_type = std::string; - virtual ~cartridge_context() = default; - virtual path_type configuration_path() const = 0; - virtual void reset() = 0; - virtual void assert_cartridge_line(bool line_state) = 0; virtual void assert_interrupt(Interrupt interrupt, InterruptSource interrupt_source) = 0; - virtual void write_memory_byte(unsigned char value, unsigned short address) = 0; virtual unsigned char read_memory_byte(unsigned short address) = 0; - - virtual void add_menu_item(const char* menu_name, int menu_id, MenuItemType menu_type) = 0; }; - } + diff --git a/libcommon/include/vcc/bus/cpak_cartridge_definitions.h b/libcommon/include/vcc/bus/cpak_cartridge_definitions.h index e5c39349..9bd033ba 100644 --- a/libcommon/include/vcc/bus/cpak_cartridge_definitions.h +++ b/libcommon/include/vcc/bus/cpak_cartridge_definitions.h @@ -43,8 +43,6 @@ extern "C" (slot_id_type SlotId, bool lineState); using PakAssertInteruptHostCallback = void (*) (slot_id_type SlotId, Interrupt interrupt, InterruptSource interrupt_source); - using PakAppendCartridgeMenuHostCallback = void (*) - (slot_id_type SlotId, const char* menu_name, int menu_id, MenuItemType menu_type); // Cartridge Callbacks struct cpak_callbacks @@ -53,7 +51,6 @@ extern "C" const PakAssertCartridgeLineHostCallback assert_cartridge_line; const PakWriteMemoryByteHostCallback write_memory_byte; const PakReadMemoryByteHostCallback read_memory_byte; - const PakAppendCartridgeMenuHostCallback add_menu_item; }; // Cartridge exports. At least PakInitilizeModuleFunction must be implimented diff --git a/libcommon/src/bus/CartridgeInterface.txt b/libcommon/src/bus/CartridgeInterface.txt index def960ba..eb95ea93 100644 --- a/libcommon/src/bus/CartridgeInterface.txt +++ b/libcommon/src/bus/CartridgeInterface.txt @@ -149,41 +149,31 @@ DLL's can export any of the following calls #Callbacks -Callbacks are used by cartridge DLL's to initiate host (or MPI) actions. The -following callbacks currently exist: +There are two ways a cartridge can initiate host actions: - assert_cartridge_line (SlotId, line_state) - - assert_interrupt (SlotId, interrupt, interrupt_source) - - write_memory_byte (SlotId, value, address) - - read_memory_byte (SlotId, unsigned short address) - - add_menu_item (SlotId, menu_name, menu_id, menu_type) **depreciated** - -SlotId is used by the MPI to filter assert_cartridge_line and to bias menu items. - -There are two type of callbacks: +1) Notifications initiated by cartridge UI events like adding menu items or inserting +cartridges in slots. These are asyncronous and can rely on DLL exports for details. +The mechanism for these is Vcc's main window message loop. The window handle (hVccWnd) +has been added to PakInitialize() for this purpose. Two notification messages are +defined, one to initiate a VCC reset and another to initiate cartridge menu rebuilds. -- Fast callbacks initiated by 6x09 code running inside the CPU loop such as asserting +2) Callbacks initiated by 6x09 code running inside the CPU loop such as asserting interrupts, cart lines, or reading and writing memory to handle DMA requests. These -are syncronous and must return quickly to not affect emulator timing. Fast callbacks -are determined by Coco3's physical bus and are not likely to change. +are syncronous and must return quickly to not affect emulator timing. Callbacks are +determined by Coco3's physical bus and are not likely to change. There are four +callbacks: -- Notifications initiated by cartridge UI events like adding menu items or inserting -cartridges in slots. These are asyncronous and can rely on DLL exports for details. -A good mechanism for these is Vcc's main window message loop. The main window handle -(hVccWnd) has been added to PakInitialize() and a message to it is used by the MPI to -initiate a VCC reset. + void assert_cartridge_line (SlotId, line_state) + void assert_interrupt (SlotId, interrupt, interrupt_source) + void write_memory_byte (SlotId, value, address) + unsigned char read_memory_byte (SlotId, unsigned short address) -The add_menu_item callback is not tied to the CPU loop and qualifies as a slow callback. -This callback is being replaced by windows menu item change message and a new export. -See **CartridgeMenuSystem.txt** for a description of this change. +SlotId is used by the MPI to filter assert_cartridge_line. DLL's are passed their slot +location in PakInitialize(). --- -#A New Design Philosophy For The MPI (In progress) +#Proposed New Design Philosophy For The MPI (under consideration) VCC and forks of VCC use run-time loading and unloading of dynamic libraries to simulate the inserting and removing of Cartridges. @@ -204,53 +194,18 @@ The pakinterface slot management concept: - The pakinterface maintains a list indexed by slot number of loaded cartridges. -- Slots are numbered 0-4. Slot 0 is the Boot slot. Slots 1-4 only loaded if MPI is in the Boot slot. - -- The pakinterface maintains the cartridge menu and dynamic menu items +- Slots are numbered 0-4. Slot 0 is the Boot slot. Slots 1-4 loaded if MPI is in the Boot slot. - The pakInterface routes I/O to slots per CTS/SCS using existing capability / callcacks - The pakinterface saves slot content to settings. - Any change to current CTS triggers a reset. This is detected and effected by the pakinterface - -- Reset stops the CPU, unloads all cartridges, reloads the basic rom, reloads cartridges + Reset stops the CPU, unloads all cartridges, reloads the basic rom, reloads cartridges per settings, and then restarts the CPU. -- pakInterface sends MPI changes to CTS/SCS via a new MPI export - -- The opaque slot_context is renamed to SlotId (0-4) and is made transparent. Some carts - don't work right if they are not a specific slot. They can use SlotId to verify the slot - they are in is right for them. (This has been completed) - -- On request pakInterface sends MPI active cart description via a new MPI export - -- On request pakInterface sends MPI slot contents - -- Then MPI should never call a cartridge DLL directly. It should always request actions through - messages to the pakInterface using the WinMain message loop. - -- The MPI saves the startup slot setting. Changing this causes no changes to running CPU +- MPI sends changes to startup CTS/SCS via a notification message. Startup CTS/SCS does not + affect the running CPU, a reset is required for them to take effect. - The MPI requests cartridge loads / unloads by sending messages to WinMain. -- The MPI requests slot and cartridge information by sending messages to WinMain. - -- The MPI has new exports to recieve results from slot changes and cartridge information requests. - -- The MPI "Reset VCC" button sends a reset message to VCC main. - -- With the exception of add_menu_item() all other exports and callbacks remain the same. - ---- - -Implementation Plan - -1. Replace opaque slot_context pointer in init export with transparent SlotId. Cartridges can - use SlotId or simply return it in callbacks. (This is complete) - -2. Replace the AddCartMenu callback with a message and modify pakinterface to maintain the - cartridge dynamic menus. See **CartridgeMenuSystem.txt** for more description. - -3. Move slot maintenance, cartridge loading, and cartidge calls from MPI to pakinterface. - diff --git a/mpi/cartridge_slot.cpp b/mpi/cartridge_slot.cpp index 7fc65b96..d0dc2598 100644 --- a/mpi/cartridge_slot.cpp +++ b/mpi/cartridge_slot.cpp @@ -45,7 +45,6 @@ namespace VCC::Core path_ = move(other.path_); handle_ = move(other.handle_); cartridge_ = move(other.cartridge_); - menu_items_ = move(other.menu_items_); line_state_ = other.line_state_; other.line_state_ = false; diff --git a/mpi/cartridge_slot.h b/mpi/cartridge_slot.h index a413fe7f..0347cd4a 100644 --- a/mpi/cartridge_slot.h +++ b/mpi/cartridge_slot.h @@ -19,7 +19,7 @@ #include #include #include -#include "../CartridgeMenu.h" +//#include "../CartridgeMenu.h" namespace VCC::Core { @@ -35,11 +35,8 @@ namespace VCC::Core using label_type = std::string; using handle_type = ::VCC::Core::cartridge_loader_result::handle_type; using cartridge_ptr_type = std::unique_ptr<::VCC::Core::cartridge>; - using menu_item_type = CartMenuItem; - using menu_item_collection_type = std::vector; using context_type = ::VCC::Core::cartridge_context; - public: cartridge_slot(); @@ -137,36 +134,16 @@ namespace VCC::Core return line_state_; } - void reset_menu() - { - menu_items_.clear(); - } - - void append_menu_item(const menu_item_type& item) - { - menu_items_.push_back(item); - } - bool get_menu_item(menu_item_entry* item, size_t index) { return cartridge_->get_menu_item(item, index); } - void enumerate_menu_items(context_type& context) const - { - for (const auto& item : menu_items_) - { - context.add_menu_item(item.name.c_str(), item.menu_id, item.type); - } - } - - private: path_type path_; handle_type handle_; cartridge_ptr_type cartridge_; - menu_item_collection_type menu_items_; bool line_state_ = false; }; diff --git a/mpi/configuration_dialog.cpp b/mpi/configuration_dialog.cpp index 44ff0d74..72f6bcd5 100644 --- a/mpi/configuration_dialog.cpp +++ b/mpi/configuration_dialog.cpp @@ -116,7 +116,7 @@ void configuration_dialog::select_new_cartridge(unsigned int item) } update_slot_details(slot); - mpi_.build_menu(); +// mpi_.build_menu(); } void configuration_dialog::set_selected_slot(size_t slot) @@ -217,7 +217,6 @@ void configuration_dialog::eject_or_select_new_cartridge(unsigned int Button) mpi_.eject_cartridge(slot); configuration_.slot_cartridge_path(slot, {}); update_slot_details(slot); - mpi_.build_menu(); } else { diff --git a/mpi/configuration_dialog.h b/mpi/configuration_dialog.h index 9c6756a9..7535bfdc 100644 --- a/mpi/configuration_dialog.h +++ b/mpi/configuration_dialog.h @@ -20,7 +20,6 @@ #include "multipak_configuration.h" #include -//TODO: ELiminate this useless class BS. It gains nothing but obscurity class configuration_dialog { public: diff --git a/mpi/host_cartridge_context.h b/mpi/host_cartridge_context.h index 9f831214..8ade2f21 100644 --- a/mpi/host_cartridge_context.h +++ b/mpi/host_cartridge_context.h @@ -31,10 +31,8 @@ class host_cartridge_context : public ::VCC::Core::cartridge_context { public: - // FIXME: Remove this when we derive from cartridge_context using path_type = std::string; - public: explicit host_cartridge_context(slot_id_type SlotId, const path_type& configuration_filename) @@ -48,11 +46,6 @@ class host_cartridge_context : public ::VCC::Core::cartridge_context return configuration_filename_; } - void reset() override - { - // FIXME-CHET: this needs to do something - } - void write_memory_byte(unsigned char value, unsigned short address) override { write_memory_byte_(SlotId_, value, address); @@ -73,11 +66,6 @@ class host_cartridge_context : public ::VCC::Core::cartridge_context assert_interrupt_(SlotId_, interrupt, interrupt_source); } - void add_menu_item(const char* menu_name, int menu_id, MenuItemType menu_type) override - { - add_menu_item_(SlotId_, menu_name, menu_id, menu_type); - } - private: friend void PakInitialize( @@ -90,11 +78,15 @@ class host_cartridge_context : public ::VCC::Core::cartridge_context private: - slot_id_type SlotId_; - const path_type& configuration_filename_; - PakWriteMemoryByteHostCallback write_memory_byte_ = [](slot_id_type, unsigned char, unsigned short) {}; - PakReadMemoryByteHostCallback read_memory_byte_ = [](slot_id_type, unsigned short) -> unsigned char { return 0; }; - PakAssertCartridgeLineHostCallback assert_cartridge_line_ = [](slot_id_type, bool) {}; - PakAssertInteruptHostCallback assert_interrupt_ = [](slot_id_type, Interrupt, InterruptSource) {}; - PakAppendCartridgeMenuHostCallback add_menu_item_ = [](slot_id_type, const char*, int, MenuItemType) {}; + slot_id_type SlotId_; + const path_type& configuration_filename_; + PakWriteMemoryByteHostCallback write_memory_byte_ = [] + (slot_id_type, unsigned char, unsigned short) {}; + PakReadMemoryByteHostCallback read_memory_byte_ = [] + (slot_id_type, unsigned short) -> unsigned char { return 0; }; + PakAssertCartridgeLineHostCallback assert_cartridge_line_ = [] + (slot_id_type, bool) {}; + PakAssertInteruptHostCallback assert_interrupt_ = [] + (slot_id_type, Interrupt, InterruptSource) {}; }; + diff --git a/mpi/mpi.cpp b/mpi/mpi.cpp index ca49c753..65fe3f8b 100644 --- a/mpi/mpi.cpp +++ b/mpi/mpi.cpp @@ -69,7 +69,6 @@ extern "C" gMultiPakConfiguration.configuration_path(configuration_path); gConfigurationFilename = configuration_path; gVccWnd = hVccWnd; - gHostCallbacks->add_menu_item_ = callbacks->add_menu_item; gHostCallbacks->read_memory_byte_ = callbacks->read_memory_byte; gHostCallbacks->write_memory_byte_ = callbacks->write_memory_byte; gHostCallbacks->assert_interrupt_ = callbacks->assert_interrupt; diff --git a/mpi/multipak_cartridge.cpp b/mpi/multipak_cartridge.cpp index 29cf8474..7cb23ab0 100644 --- a/mpi/multipak_cartridge.cpp +++ b/mpi/multipak_cartridge.cpp @@ -87,9 +87,6 @@ void multipak_cartridge::start() } } } - - // Build the dynamic menu **OLD** - build_menu(); } @@ -346,23 +343,12 @@ multipak_cartridge::mount_status_type multipak_cartridge::mount_cartridge( self->assert_cartridge_line(SlotId, line_state); }; - static auto append_menu_item_thunk = - +[](slot_id_type SlotId, - const char* menu_name, - int menu_id, - MenuItemType menu_type) - { - menu_item_type item {menu_name, (unsigned int)menu_id, menu_type}; - self->append_menu_item(SlotId, item); - }; - // Build callback table for carts loaded on MPI cpak_callbacks callbacks { gHostCallbacks->assert_interrupt_, assert_cartridge_line_thunk, gHostCallbacks->write_memory_byte_, - gHostCallbacks->read_memory_byte_, - append_menu_item_thunk + gHostCallbacks->read_memory_byte_//, }; DLOG_C("%3d %p %p %p %p %p\n",mpi_slot,callbacks); @@ -434,54 +420,6 @@ multipak_cartridge::slot_id_type multipak_cartridge::selected_scs_slot() const return cached_scs_slot_; } -// *OLD* Save cart Menu items into containers per slot **OLD** -void multipak_cartridge::append_menu_item(slot_id_type SlotId, menu_item_type item) -{ - - auto mpi_slot = SlotId - 1; - - switch (item.menu_id) { - case MID_BEGIN: - { - VCC::Util::section_locker lock(mutex_); - slots_[mpi_slot].reset_menu(); - break; - } - case MID_FINISH: - build_menu(); - break; - default: - { - // Add 50 times the slot_id to menu_ids so WinMain knows who is calling - if (item.menu_id >= MID_CONTROL) { - item.menu_id += SlotId * 50; - } - VCC::Util::section_locker lock(mutex_); - slots_[mpi_slot].append_menu_item(item); - break; - } - } - DLOG_C("menu_item %d %d \n",SlotId,item.menu_id); -} - - -// *OLD* This gets called any time a cartridge menu is changed. It draws the entire menu. -void multipak_cartridge::build_menu() -{ - // do we really need this here? menu draw should be async - VCC::Util::section_locker lock(mutex_); - - // Init the menu, establish MPI config control, build slot menus, then draw it. - context_->add_menu_item("", MID_BEGIN, MIT_Head); - context_->add_menu_item("", MID_ENTRY, MIT_Seperator); - context_->add_menu_item("MPI Config", ControlId(19), MIT_StandAlone); - for (int mpi_slot = 3; mpi_slot >= 0; mpi_slot--) - { - slots_[mpi_slot].enumerate_menu_items(*context_); - } - context_->add_menu_item("", MID_FINISH, MIT_Head); // Finish draws the entire menu -} - void multipak_cartridge::assert_cartridge_line(slot_id_type SlotId, bool line_state) { DLOG_C("cart line %d %d \n",SlotId,line_state); diff --git a/mpi/multipak_cartridge.h b/mpi/multipak_cartridge.h index 8d4a3dec..860cb561 100644 --- a/mpi/multipak_cartridge.h +++ b/mpi/multipak_cartridge.h @@ -22,10 +22,8 @@ #include #include #include -#include "../CartridgeMenu.h" #include - constexpr size_t NUMSLOTS = 4u; class multipak_cartridge : public ::VCC::Core::cartridge @@ -38,8 +36,6 @@ class multipak_cartridge : public ::VCC::Core::cartridge using path_type = std::string; using label_type = std::string; using description_type = std::string; - using menu_item_type = CartMenuItem; - public: @@ -83,12 +79,8 @@ class multipak_cartridge : public ::VCC::Core::cartridge slot_id_type selected_switch_slot() const; slot_id_type selected_scs_slot() const; - void build_menu(); - // Make automatic when mounting, ejecting, selecting slot, etc. void assert_cartridge_line(slot_id_type slot, bool line_state); - void append_menu_item(slot_id_type slot, menu_item_type item); - private: diff --git a/mpi/multipak_cartridge_context.h b/mpi/multipak_cartridge_context.h index 34fdf247..c89f1511 100644 --- a/mpi/multipak_cartridge_context.h +++ b/mpi/multipak_cartridge_context.h @@ -36,16 +36,6 @@ class multipak_cartridge_context : public ::VCC::Core::cartridge_context return parent_context_.configuration_path(); } - void reset() override - { - parent_context_.reset(); - } - - void add_menu_item(const char* menu_name, int menu_id, MenuItemType menu_type) override - { - multipak_.append_menu_item(slot_id_, { menu_name, static_cast(menu_id), menu_type }); - } - void write_memory_byte(unsigned char value, unsigned short address) override { parent_context_.write_memory_byte(value, address); diff --git a/mpi/multipak_configuration.cpp b/mpi/multipak_configuration.cpp index 1e1415f7..26918e3a 100644 --- a/mpi/multipak_configuration.cpp +++ b/mpi/multipak_configuration.cpp @@ -60,7 +60,6 @@ multipak_configuration::path_type multipak_configuration::last_accessed_dll_path return settings(configuration_path()).read("DefaultPaths", "MPIPath"); } -// selected slot FIXME:: it is not clear that slot is an int void multipak_configuration::selected_slot(slot_id_type slot) const { settings(configuration_path()).write(section_, "SWPOSITION", slot); diff --git a/mpi/multipak_configuration.h b/mpi/multipak_configuration.h index 37b3be7e..039ade09 100644 --- a/mpi/multipak_configuration.h +++ b/mpi/multipak_configuration.h @@ -37,7 +37,6 @@ class multipak_configuration void configuration_path(path_type path); path_type configuration_path() const; - //void last_accessed_module_type(const path_type& path) const; path_type last_accessed_module_type() const; void last_accessed_rom_path(const path_type& path) const; @@ -57,7 +56,6 @@ class multipak_configuration string_type get_slot_path_key(slot_id_type slot) const; - private: const string_type section_; diff --git a/pakinterface.cpp b/pakinterface.cpp index b85aec25..fa6c7112 100644 --- a/pakinterface.cpp +++ b/pakinterface.cpp @@ -1,25 +1,26 @@ -/* - Copyright 2015 by Joseph Forgione - This file is part of VCC (Virtual Color Computer). - - VCC (Virtual Color Computer) 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 3 of the License, or - (at your option) any later version. - - VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see . -*/ +//#define USE_LOGGING +//====================================================================== +// This file is part of VCC (Virtual Color Computer). +// Vcc is Copyright 2015 by Joseph Forgione +// +// VCC (Virtual Color Computer) is free software, you can redistribute +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see +// . +//====================================================================== #include "defines.h" #include "tcc1014mmu.h" #include "tcc1014registers.h" -#include "CartridgeMenu.h" //OLD #include "pakinterface.h" #include "config.h" #include "Vcc.h" @@ -38,11 +39,9 @@ #include #include - using cartridge_loader_status = VCC::Core::cartridge_loader_status; using cartridge_loader_result = VCC::Core::cartridge_loader_result; - // Storage for Pak ROMs extern SystemState EmuState; @@ -69,12 +68,6 @@ struct vcc_cartridge_context : public ::VCC::Core::cartridge_context return path_buffer; } - void reset() override - { - //SendMessage(EmuState.WindowHandle,WM_COMMAND,(WPARAM) IDC_MSG_CPU_RESET,(LPARAM) 0); - EmuState.ResetPending = 2; - } - void write_memory_byte(unsigned char value, unsigned short address) override { MemWrite8(value, address); @@ -95,10 +88,6 @@ struct vcc_cartridge_context : public ::VCC::Core::cartridge_context PakAssertInterupt(interrupt, interrupt_source); } - void add_menu_item(const char* menu_name, int menu_id, MenuItemType menu_type) override - { - CartMenuCallBack(menu_name, menu_id, menu_type); - } }; static void PakAssertCartrigeLine(slot_id_type /*SlotId*/, bool line_state) @@ -121,11 +110,6 @@ static void PakAssertInterupt(slot_id_type /*SlotId*/, Interrupt interrupt, Inte PakAssertInterupt(interrupt, source); } -static void PakAddMenuItem(slot_id_type /*SlotId*/, const char* name, int menu_id, MenuItemType type) -{ - CartMenuCallBack(name, menu_id, type); -} - void PakTimer() { VCC::Util::section_locker lock(gPakMutex); @@ -193,7 +177,6 @@ unsigned short PackAudioSample() // Build entries for cartridge menu. void BuildCartMenu() { - // lock goes into program paks, not needed here //VCC::Util::section_locker lock(gPakMutex); using VCC::Bus::gVccCartMenu; gVccCartMenu.clear(); @@ -217,38 +200,6 @@ void BuildCartMenu() } } -// OLD Create entries for cartridge menu. The rest will be for MPI -// ControlId(MenuId) set what control does **OLD*** -void BeginCartMenu() -{ - VCC::Util::section_locker lock(gPakMutex); - - CartMenu.reserve(0); - CartMenu.add("", MID_BEGIN, MIT_Head); - CartMenu.add("Cartridge", MID_ENTRY, MIT_Head); - if (!gActiveCartrige->name().empty()) - { - char tmp[64] = {}; - snprintf(tmp, 64, "Eject %s", gActiveCartrige->name().c_str()); - CartMenu.add(tmp, ControlId(2), MIT_Slave); - CartMenu.add("", MID_FINISH, MIT_Head); - CartMenu.reserve(2); - } else { - CartMenu.add("Load MPI", ControlId(3), MIT_Slave); - CartMenu.add("Load DLL", ControlId(1), MIT_Slave); - CartMenu.add("Load ROM", ControlId(4), MIT_Slave); - CartMenu.add("", MID_FINISH, MIT_Head); - CartMenu.reserve(3); - } -} - -// Callback for loaded cart DLLs. -void CartMenuCallBack(const char *name, int menu_id, MenuItemType type) -{ - CartMenu.add(name, menu_id, type); -} - - void PakLoadCartridgeUI(int type) { char inifile[MAX_PATH]; @@ -259,11 +210,13 @@ static char cartDir[MAX_PATH] = ""; FileDialog dlg; if (type == 0) { dlg.setTitle(TEXT("Load Program Pack")); - dlg.setFilter("Hardware Packs\0*.dll\0All Supported Formats (*.dll;*.ccc;*.rom)\0*.dll;*.ccc;*.rom\0\0"); + dlg.setFilter("Hardware Packs\0*.dll\0" + "All Supported Formats (*.dll;*.ccc;*.rom)\0*.dll;*.ccc;*.rom\0\0"); Setting().read("DefaultPaths", "MPIPath", "", cartDir, MAX_PATH); } else { dlg.setTitle(TEXT("Load ROM")); - dlg.setFilter("Rom Packs(*.ccc;*.rom)\0*.ccc;*.rom\0All Supported Formats (*.dll;*.ccc;*.rom)\0*.dll;*.ccc;*.rom\0\0"); + dlg.setFilter("Rom Packs(*.ccc;*.rom)\0*.ccc;*.rom\0" + "All Supported Formats (*.dll;*.ccc;*.rom)\0*.dll;*.ccc;*.rom\0\0"); Setting().read("DefaultPaths", "PakPath", "", cartDir, MAX_PATH); } dlg.setInitialDir(cartDir); @@ -323,8 +276,7 @@ static cartridge_loader_status load_any_cartridge(const char *filename, const ch PakAssertInterupt, PakAssertCartrigeLine, PakWriteMemoryByte, - PakReadMemoryByte, - PakAddMenuItem + PakReadMemoryByte }; slot_id_type SlotId = 0; @@ -350,13 +302,10 @@ static cartridge_loader_status load_any_cartridge(const char *filename, const ch strcpy(DllPath, filename); gActiveCartrige = move(loadedCartridge.cartridge); gActiveModule = move(loadedCartridge.handle); - BeginCartMenu(); // OLD SendMessage(EmuState.WindowHandle,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); - // initialize the cartridge + // initialize the cartridge and reset the CPU gActiveCartrige->start(); - - // Reset if enabled. TODO: Send DoHardReset message instead EmuState.ResetPending = 2; return loadedCartridge.load_result; @@ -372,7 +321,6 @@ void UnloadDll() gActiveCartrige = std::make_unique(); gActiveModule.reset(); - BeginCartMenu(); //OLD SendMessage(EmuState.WindowHandle,WM_COMMAND,(WPARAM) IDC_MSG_UPD_MENU,(LPARAM) 0); gActiveCartrige->start(); } @@ -385,7 +333,7 @@ void GetCurrentModule(char *DefaultModule) void UpdateBusPointer() { - // Do nothing for now. No clue given what the plan for this was. + // Do nothing for now. What the plan was for this is unknown. } void UnloadPack() diff --git a/pakinterface.h b/pakinterface.h index 93888a6e..acf05118 100644 --- a/pakinterface.h +++ b/pakinterface.h @@ -1,20 +1,21 @@ -/* -Copyright 2015 by Joseph Forgione -This file is part of VCC (Virtual Color Computer). - - VCC (Virtual Color Computer) 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 3 of the License, or - (at your option) any later version. - - VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see . -*/ +//====================================================================== +// This file is part of VCC (Virtual Color Computer). +// Vcc is Copyright 2015 by Joseph Forgione +// +// VCC (Virtual Color Computer) is free software, you can redistribute +// and/or modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation, either version 3 of +// the License, or (at your option) any later version. +// +// VCC (Virtual Color Computer) 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 VCC (Virtual Color Computer). If not, see +// . +//====================================================================== #pragma once #include @@ -32,7 +33,6 @@ void GetCurrentModule(char *); void UpdateBusPointer(); void UnloadDll(); void UnloadPack(); -void BeginCartMenu(); //Remove this after testing void BuildCartMenu(); void CartMenuActivated(unsigned int); From 58b36693fda2e67d905a0a8088d7f41598e99fbe Mon Sep 17 00:00:00 2001 From: ejaquay Date: Mon, 16 Feb 2026 13:45:26 -0500 Subject: [PATCH 14/14] Initial build empty cartridge menu on startup If there are no carts loaded at startup the interface never fires an update menu message to init the menu. This change forces an empty menu at startup so the menu button still functions. --- Vcc.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Vcc.cpp b/Vcc.cpp index 87c2ecac..58df4ffa 100644 --- a/Vcc.cpp +++ b/Vcc.cpp @@ -56,7 +56,6 @@ #include "mc6821.h" #include "keyboard.h" #include "coco3.h" -//#include "CartridgeMenu.h" #include "pakinterface.h" #include "audio.h" #include "config.h" @@ -446,6 +445,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_CREATE: + // Create initial cartridge menu. If no carts are loaded at startup + // build and draw here are needed to bootstrap the cartridge menu + BuildCartMenu(); DrawCartMenu(hWnd); #ifdef _LEGACY_VCC { char title[80] = "Legacy "; @@ -706,7 +708,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) //-------------------------------------------------------------------------- HMENU DrawCartMenu (HWND hWnd) { - //gVccCartMenu.log(); + gVccCartMenu.log(); // window handle, zero based position on menu bar, name on bar. return gVccCartMenu.draw( hWnd, 3, "Cartridge");