Input: Added UI for family basic tape recorder
This commit is contained in:
parent
12321c48fa
commit
4b3edac310
33 changed files with 431 additions and 116 deletions
|
@ -85,7 +85,7 @@ public:
|
|||
uint8_t ReadRAM(uint16_t addr) override
|
||||
{
|
||||
if(addr == 0x4017) {
|
||||
int32_t elapsedCycles = CPU::GetCycleCount() - _insertCycle;
|
||||
int32_t elapsedCycles = CPU::GetElapsedCycles(_insertCycle);
|
||||
constexpr uint32_t cyclesPerBit = CPU::ClockRateNtsc / 1200;
|
||||
|
||||
uint32_t streamPosition = elapsedCycles / cyclesPerBit;
|
||||
|
|
|
@ -42,7 +42,8 @@ public:
|
|||
static const uint8_t ExpDevicePort = 4;
|
||||
static const uint8_t ConsoleInputPort = 5;
|
||||
static const uint8_t MapperInputPort = 6;
|
||||
static const uint8_t PortCount = MapperInputPort + 1;
|
||||
static const uint8_t ExpDevicePort2 = 7;
|
||||
static const uint8_t PortCount = ExpDevicePort2 + 1;
|
||||
|
||||
BaseControlDevice(uint8_t port, KeyMappingSet keyMappingSet = KeyMappingSet());
|
||||
virtual ~BaseControlDevice();
|
||||
|
|
11
Core/CPU.h
11
Core/CPU.h
|
@ -785,7 +785,18 @@ public:
|
|||
static const uint32_t ClockRateDendy = 1773448;
|
||||
|
||||
CPU(MemoryManager *memoryManager);
|
||||
|
||||
static int32_t GetCycleCount() { return CPU::Instance->_cycleCount; }
|
||||
|
||||
static int32_t GetElapsedCycles(int32_t prevCycleCount)
|
||||
{
|
||||
if(prevCycleCount > Instance->_cycleCount) {
|
||||
return 0xFFFFFFFF - prevCycleCount + Instance->_cycleCount + 1;
|
||||
} else {
|
||||
return Instance->_cycleCount - prevCycleCount;
|
||||
}
|
||||
}
|
||||
|
||||
static void SetNMIFlag() { CPU::Instance->_state.NMIFlag = true; }
|
||||
static void ClearNMIFlag() { CPU::Instance->_state.NMIFlag = false; }
|
||||
static void SetIRQMask(uint8_t mask) { CPU::Instance->_irqMask = mask; }
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "SystemActionManager.h"
|
||||
#include "FdsSystemActionManager.h"
|
||||
#include "VsSystemActionManager.h"
|
||||
#include "FamilyBasicDataRecorder.h"
|
||||
#include "IBarcodeReader.h"
|
||||
#include "IBattery.h"
|
||||
#include "KeyManager.h"
|
||||
|
@ -784,6 +785,10 @@ ConsoleFeatures Console::GetAvailableFeatures()
|
|||
if(std::dynamic_pointer_cast<IBarcodeReader>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort))) {
|
||||
features = (ConsoleFeatures)((int)features | (int)ConsoleFeatures::BarcodeReader);
|
||||
}
|
||||
|
||||
if(std::dynamic_pointer_cast<FamilyBasicDataRecorder>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2))) {
|
||||
features = (ConsoleFeatures)((int)features | (int)ConsoleFeatures::TapeRecorder);
|
||||
}
|
||||
}
|
||||
return features;
|
||||
}
|
||||
|
@ -799,4 +804,44 @@ void Console::InputBarcode(uint64_t barcode, uint32_t digitCount)
|
|||
if(barcodeReader) {
|
||||
barcodeReader->InputBarcode(barcode, digitCount);
|
||||
}
|
||||
}
|
||||
|
||||
void Console::LoadTapeFile(string filepath)
|
||||
{
|
||||
shared_ptr<FamilyBasicDataRecorder> dataRecorder = std::dynamic_pointer_cast<FamilyBasicDataRecorder>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2));
|
||||
if(dataRecorder) {
|
||||
Console::Pause();
|
||||
dataRecorder->LoadFromFile(filepath);
|
||||
Console::Resume();
|
||||
}
|
||||
}
|
||||
|
||||
void Console::StartRecordingTapeFile(string filepath)
|
||||
{
|
||||
shared_ptr<FamilyBasicDataRecorder> dataRecorder = std::dynamic_pointer_cast<FamilyBasicDataRecorder>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2));
|
||||
if(dataRecorder) {
|
||||
Console::Pause();
|
||||
dataRecorder->StartRecording(filepath);
|
||||
Console::Resume();
|
||||
}
|
||||
}
|
||||
|
||||
void Console::StopRecordingTapeFile()
|
||||
{
|
||||
shared_ptr<FamilyBasicDataRecorder> dataRecorder = std::dynamic_pointer_cast<FamilyBasicDataRecorder>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2));
|
||||
if(dataRecorder) {
|
||||
Console::Pause();
|
||||
dataRecorder->StopRecording();
|
||||
Console::Resume();
|
||||
}
|
||||
}
|
||||
|
||||
bool Console::IsRecordingTapeFile()
|
||||
{
|
||||
shared_ptr<FamilyBasicDataRecorder> dataRecorder = std::dynamic_pointer_cast<FamilyBasicDataRecorder>(_controlManager->GetControlDevice(BaseControlDevice::ExpDevicePort2));
|
||||
if(dataRecorder) {
|
||||
return dataRecorder->IsRecording();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -88,6 +88,11 @@ class Console
|
|||
ConsoleFeatures GetAvailableFeatures();
|
||||
void InputBarcode(uint64_t barcode, uint32_t digitCount);
|
||||
|
||||
void LoadTapeFile(string filepath);
|
||||
void StartRecordingTapeFile(string filepath);
|
||||
void StopRecordingTapeFile();
|
||||
bool IsRecordingTapeFile();
|
||||
|
||||
static std::thread::id GetEmulationThreadId();
|
||||
|
||||
static void RequestReset();
|
||||
|
|
|
@ -97,11 +97,13 @@ vector<ControlDeviceState> ControlManager::GetPortStates()
|
|||
|
||||
shared_ptr<BaseControlDevice> ControlManager::GetControlDevice(uint8_t port)
|
||||
{
|
||||
auto lock = _deviceLock.AcquireSafe();
|
||||
if(_instance) {
|
||||
auto lock = _deviceLock.AcquireSafe();
|
||||
|
||||
auto result = std::find_if(_instance->_controlDevices.begin(), _instance->_controlDevices.end(), [port](const shared_ptr<BaseControlDevice> control) { return control->GetPort() == port; });
|
||||
if(result != _instance->_controlDevices.end()) {
|
||||
return *result;
|
||||
auto result = std::find_if(_instance->_controlDevices.begin(), _instance->_controlDevices.end(), [port](const shared_ptr<BaseControlDevice> control) { return control->GetPort() == port; });
|
||||
if(result != _instance->_controlDevices.end()) {
|
||||
return *result;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -204,6 +206,11 @@ void ControlManager::UpdateControlDevices()
|
|||
if(_mapperControlDevice) {
|
||||
ControlManager::RegisterControlDevice(_mapperControlDevice);
|
||||
}
|
||||
|
||||
if(std::dynamic_pointer_cast<FamilyBasicKeyboard>(expDevice)) {
|
||||
//Automatically connect the data recorder if the keyboard is connected
|
||||
ControlManager::RegisterControlDevice(shared_ptr<FamilyBasicDataRecorder>(new FamilyBasicDataRecorder()));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ControlManager::GetOpenBusMask(uint8_t port)
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
|
||||
uint8_t GetOutput()
|
||||
{
|
||||
int32_t elapsedCycles = CPU::GetCycleCount() - _insertCycle;
|
||||
int32_t elapsedCycles = CPU::GetElapsedCycles(_insertCycle);
|
||||
int32_t bitNumber = elapsedCycles / 1000;
|
||||
if(bitNumber < (int32_t)_data.size()) {
|
||||
return _data[bitNumber];
|
||||
|
|
|
@ -1,50 +1,133 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include <deque>
|
||||
#include "../Utilities/Base64.h"
|
||||
#include "BaseControlDevice.h"
|
||||
#include "CPU.h"
|
||||
|
||||
//TODO: Integration with UI
|
||||
class FamilyBasicDataRecorder : public BaseControlDevice
|
||||
{
|
||||
private:
|
||||
static const uint32_t SamplingRate = 88;
|
||||
vector<uint8_t> _saveData;
|
||||
vector<uint8_t> _data;
|
||||
vector<uint8_t> _fileData;
|
||||
bool _enabled = false;
|
||||
int32_t _lastCycle = -1;
|
||||
int32_t _readStartCycle = -1;
|
||||
bool _isPlaying = false;
|
||||
int32_t _cycle = -1;
|
||||
|
||||
bool _isRecording = false;
|
||||
string _recordFilePath;
|
||||
|
||||
protected:
|
||||
void StreamState(bool saving) override
|
||||
{
|
||||
BaseControlDevice::StreamState(saving);
|
||||
Stream(_enabled);
|
||||
|
||||
uint32_t dataSize = _data.size();
|
||||
Stream(_enabled, _isPlaying, _cycle, dataSize);
|
||||
|
||||
if(!saving) {
|
||||
_data.resize(dataSize);
|
||||
}
|
||||
|
||||
ArrayInfo<uint8_t> data{ _data.data(), _data.size() };
|
||||
Stream(data);
|
||||
|
||||
if(!saving && _isRecording) {
|
||||
StopRecording();
|
||||
}
|
||||
}
|
||||
|
||||
bool IsRawString()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
FamilyBasicDataRecorder() : BaseControlDevice(BaseControlDevice::ExpDevicePort)
|
||||
FamilyBasicDataRecorder() : BaseControlDevice(BaseControlDevice::ExpDevicePort2)
|
||||
{
|
||||
}
|
||||
|
||||
~FamilyBasicDataRecorder()
|
||||
{
|
||||
if(_isRecording) {
|
||||
StopRecording();
|
||||
}
|
||||
}
|
||||
|
||||
void InternalSetStateFromInput()
|
||||
{
|
||||
if(_fileData.size() > 0) {
|
||||
SetTextState(Base64::Encode(_fileData));
|
||||
_fileData.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void OnAfterSetState()
|
||||
{
|
||||
if(_state.State.size() > 0) {
|
||||
_data = Base64::Decode(GetTextState());
|
||||
_cycle = CPU::GetCycleCount();
|
||||
_isPlaying = true;
|
||||
_isRecording = false;
|
||||
}
|
||||
}
|
||||
|
||||
void LoadFromFile(VirtualFile file)
|
||||
{
|
||||
if(file.IsValid()) {
|
||||
vector<uint8_t> fileData;
|
||||
file.ReadFile(fileData);
|
||||
_fileData = fileData;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsRecording()
|
||||
{
|
||||
return _isRecording;
|
||||
}
|
||||
|
||||
void StartRecording(string filePath)
|
||||
{
|
||||
_isPlaying = false;
|
||||
_recordFilePath = filePath;
|
||||
_data.clear();
|
||||
_cycle = CPU::GetCycleCount();
|
||||
_isRecording = true;
|
||||
}
|
||||
|
||||
void StopRecording()
|
||||
{
|
||||
_isRecording = false;
|
||||
|
||||
vector<uint8_t> fileData;
|
||||
|
||||
int bitPos = 0;
|
||||
uint8_t currentByte = 0;
|
||||
for(uint8_t bitValue : _data) {
|
||||
currentByte |= (bitValue & 0x01) << bitPos;
|
||||
bitPos = (bitPos + 1) % 8;
|
||||
if(bitPos == 0) {
|
||||
fileData.push_back(currentByte);
|
||||
currentByte = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ofstream out(_recordFilePath, ios::binary);
|
||||
if(out) {
|
||||
out.write((char*)fileData.data(), fileData.size());
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ReadRAM(uint16_t addr) override
|
||||
{
|
||||
if(addr == 0x4016) {
|
||||
if(EmulationSettings::CheckFlag(EmulationFlags::ShowFrameCounter)) {
|
||||
if(_readStartCycle == -1) {
|
||||
_readStartCycle = CPU::GetCycleCount();
|
||||
}
|
||||
if(addr == 0x4016 && _isPlaying) {
|
||||
int32_t readPos = CPU::GetElapsedCycles(_cycle) / FamilyBasicDataRecorder::SamplingRate;
|
||||
|
||||
int readPos = (CPU::GetCycleCount() - _readStartCycle) / FamilyBasicDataRecorder::SamplingRate;
|
||||
|
||||
if((int32_t)_saveData.size() > readPos) {
|
||||
uint8_t value = (_saveData[readPos] & 0x01) << 1;
|
||||
return _enabled ? value : 0;
|
||||
}
|
||||
if((int32_t)_data.size() > readPos / 8) {
|
||||
uint8_t value = ((_data[readPos / 8] >> (readPos % 8)) & 0x01) << 1;
|
||||
return _enabled ? value : 0;
|
||||
} else {
|
||||
if(!EmulationSettings::CheckFlag(EmulationFlags::ShowFPS)) {
|
||||
_lastCycle = -1;
|
||||
_readStartCycle = -1;
|
||||
}
|
||||
_isPlaying = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,19 +138,10 @@ public:
|
|||
{
|
||||
_enabled = (value & 0x04) != 0;
|
||||
|
||||
if(EmulationSettings::CheckFlag(EmulationFlags::ShowFPS)) {
|
||||
if(_lastCycle == -1) {
|
||||
_saveData.clear();
|
||||
_lastCycle = CPU::GetCycleCount() - 88;
|
||||
}
|
||||
while(_lastCycle < CPU::GetCycleCount()) {
|
||||
_saveData.push_back(value & 0x01);
|
||||
_lastCycle += 88;
|
||||
}
|
||||
} else {
|
||||
if(!EmulationSettings::CheckFlag(EmulationFlags::ShowFrameCounter)) {
|
||||
_lastCycle = -1;
|
||||
_readStartCycle = -1;
|
||||
if(_isRecording) {
|
||||
while(CPU::GetElapsedCycles(_cycle) > FamilyBasicDataRecorder::SamplingRate) {
|
||||
_data.push_back(value & 0x01);
|
||||
_cycle += 88;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,30 +2,11 @@
|
|||
#include <algorithm>
|
||||
#include "../Utilities/StringUtilities.h"
|
||||
#include "../Utilities/HexUtilities.h"
|
||||
#include "../Utilities/Base64.h"
|
||||
#include "ControlManager.h"
|
||||
#include "FceuxMovie.h"
|
||||
#include "Console.h"
|
||||
|
||||
vector<uint8_t> FceuxMovie::Base64Decode(string in)
|
||||
{
|
||||
vector<uint8_t> out;
|
||||
|
||||
vector<int> T(256, -1);
|
||||
for(int i = 0; i<64; i++) T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;
|
||||
|
||||
int val = 0, valb = -8;
|
||||
for(uint8_t c : in) {
|
||||
if(T[c] == -1) break;
|
||||
val = (val << 6) + T[c];
|
||||
valb += 6;
|
||||
if(valb >= 0) {
|
||||
out.push_back(val >> valb);
|
||||
valb -= 8;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
bool FceuxMovie::InitializeData(stringstream &filestream)
|
||||
{
|
||||
bool result = false;
|
||||
|
@ -39,7 +20,7 @@ bool FceuxMovie::InitializeData(stringstream &filestream)
|
|||
string line;
|
||||
std::getline(filestream, line);
|
||||
if(line.compare(0, 19, "romChecksum base64:", 19) == 0) {
|
||||
vector<uint8_t> md5array = Base64Decode(line.substr(19, line.size() - 20));
|
||||
vector<uint8_t> md5array = Base64::Decode(line.substr(19, line.size() - 20));
|
||||
HashInfo hashInfo;
|
||||
hashInfo.PrgChrMd5Hash = HexUtilities::ToHex(md5array);
|
||||
if(Console::LoadROM("", hashInfo)) {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
class FceuxMovie : public BizhawkMovie
|
||||
{
|
||||
private:
|
||||
vector<uint8_t> Base64Decode(string in);
|
||||
bool InitializeData(stringstream &filestream);
|
||||
|
||||
public:
|
||||
|
|
|
@ -250,4 +250,5 @@ enum class ConsoleFeatures
|
|||
Nsf = 2,
|
||||
VsSystem = 4,
|
||||
BarcodeReader = 8,
|
||||
TapeRecorder = 16,
|
||||
};
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
<Control ID="mnuInsertCoin1">Insereix moneda (1)</Control>
|
||||
<Control ID="mnuInsertCoin2">Insereix moneda (2)</Control>
|
||||
<Control ID="mnuInputBarcode">Input Barcode</Control>
|
||||
<Control ID="mnuTapeRecorder">Tape Recorder</Control>
|
||||
<Control ID="mnuLoadTapeFile">Load from file...</Control>
|
||||
<Control ID="mnuStartRecordTapeFile">Record to file...</Control>
|
||||
<Control ID="mnuStopRecordTapeFile">Stop recording</Control>
|
||||
<Control ID="mnuOptions">Opcions</Control>
|
||||
<Control ID="mnuEmulationSpeed">Velocitat</Control>
|
||||
<Control ID="mnuEmuSpeedNormal">Normal (100%)</Control>
|
||||
|
@ -615,6 +619,7 @@
|
|||
<Message ID="FilterTest">Fitxers de proves (*.mtp)|*.mtp|Tots els fitxers (*.*)|*.*</Message>
|
||||
<Message ID="FilterCheat">Tots els formats suportats (*.cht, *.xml)|*.cht;*.xml</Message>
|
||||
<Message ID="FilterSavestate">Partides guardades de Mesen (*.mst)|*.mst|Tots els fitxers (*.*)|*.*</Message>
|
||||
<Message ID="FilterTapeFiles">Family Basic Tape files (*.fbt)|*.fbt|Tots els fitxers (*.*)|*.*</Message>
|
||||
|
||||
<Message ID="LoadFromFile">Carrega des d'un fitxer...</Message>
|
||||
<Message ID="SaveToFile">Desa al fitxer...</Message>
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<Message ID="FilterTest">Test files (*.mtp)|*.mtp|All (*.*)|*.*</Message>
|
||||
<Message ID="FilterCheat">All supported formats (*.cht, *.xml)|*.cht;*.xml</Message>
|
||||
<Message ID="FilterSavestate">Mesen Savestates (*.mst)|*.mst|All files (*.*)|*.*</Message>
|
||||
<Message ID="FilterTapeFiles">Family Basic Tape files (*.fbt)|*.fbt|All Files (*.*)|*.*</Message>
|
||||
|
||||
<Message ID="LoadFromFile">Load from file...</Message>
|
||||
<Message ID="SaveToFile">Save to file...</Message>
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
<Control ID="mnuInsertCoin1">Insertar moneda (1)</Control>
|
||||
<Control ID="mnuInsertCoin2">Insertar moneda (2)</Control>
|
||||
<Control ID="mnuInputBarcode">Input Barcode</Control>
|
||||
<Control ID="mnuTapeRecorder">Tape Recorder</Control>
|
||||
<Control ID="mnuLoadTapeFile">Load from file...</Control>
|
||||
<Control ID="mnuStartRecordTapeFile">Record to file...</Control>
|
||||
<Control ID="mnuStopRecordTapeFile">Stop recording</Control>
|
||||
<Control ID="mnuOptions">Opciones</Control>
|
||||
<Control ID="mnuEmulationSpeed">Velocidad</Control>
|
||||
<Control ID="mnuEmuSpeedNormal">Normal (100%)</Control>
|
||||
|
@ -634,6 +638,7 @@
|
|||
<Message ID="FilterTest">Archivos de test (*.mtp)|*.mtp|Todos los archivos (*.*)|*.*</Message>
|
||||
<Message ID="FilterCheat">Todos los formatos soportados (*.cht, *.xml)|*.cht;*.xml</Message>
|
||||
<Message ID="FilterSavestate">Partidas de juegos de Mesen (*.mst)|*.mst|Todos los archivos (*.*)|*.*</Message>
|
||||
<Message ID="FilterTapeFiles">Family Basic Tape files (*.fbt)|*.fbt|Todos los archivos (*.*)|*.*</Message>
|
||||
|
||||
<Message ID="LoadFromFile">Cargar desde archivo...</Message>
|
||||
<Message ID="SaveToFile">Guardar en archivo...</Message>
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
<Control ID="mnuInsertCoin1">Insérer une pièce (1)</Control>
|
||||
<Control ID="mnuInsertCoin2">Insérer une pièce (2)</Control>
|
||||
<Control ID="mnuInputBarcode">Entrer un code-barres</Control>
|
||||
<Control ID="mnuTapeRecorder">Enregistreur de données</Control>
|
||||
<Control ID="mnuLoadTapeFile">Charger un fichier...</Control>
|
||||
<Control ID="mnuStartRecordTapeFile">Enregistrer dans un fichier...</Control>
|
||||
<Control ID="mnuStopRecordTapeFile">Arrêter l'enregistrement</Control>
|
||||
<Control ID="mnuOptions">Options</Control>
|
||||
<Control ID="mnuEmulationSpeed">Vitesse</Control>
|
||||
<Control ID="mnuEmuSpeedNormal">Normale (100%)</Control>
|
||||
|
@ -647,6 +651,7 @@
|
|||
<Message ID="FilterTest">Fichiers de test (*.mtp)|*.mtp|Tous les fichiers (*.*)|*.*</Message>
|
||||
<Message ID="FilterCheat">Tous les formats supportés (*.cht, *.xml)|*.cht;*.xml</Message>
|
||||
<Message ID="FilterSavestate">Sauvegardes d'états Mesen (*.mst)|*.mst|Tous les fichiers (*.*)|*.*</Message>
|
||||
<Message ID="FilterTapeFiles">Fichiers de cassettes Family Basic (*.fbt)|*.fbt|Tous les fichiers (*.*)|*.*</Message>
|
||||
|
||||
<Message ID="LoadFromFile">Charger à partir d'un fichier...</Message>
|
||||
<Message ID="SaveToFile">Sauvegarder dans un fichier...</Message>
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
<Control ID="mnuVsGameConfig">VSゲームの設定</Control>
|
||||
<Control ID="mnuInsertCoin1">インサートコイン 1</Control>
|
||||
<Control ID="mnuInsertCoin2">インサートコイン 2</Control>
|
||||
<Control ID="mnuInputCode">バーコードを入力</Control>
|
||||
<Control ID="mnuInputBarcode">バーコードを入力</Control>
|
||||
<Control ID="mnuTapeRecorder">テープレコーダー</Control>
|
||||
<Control ID="mnuLoadTapeFile">ファイルから再生する</Control>
|
||||
<Control ID="mnuStartRecordTapeFile">ファイルに録音する</Control>
|
||||
<Control ID="mnuStopRecordTapeFile">録音を停止する</Control>
|
||||
<Control ID="mnuOptions">設定</Control>
|
||||
<Control ID="mnuEmulationSpeed">速度</Control>
|
||||
<Control ID="mnuEmuSpeedNormal">通常 (100%)</Control>
|
||||
|
@ -631,6 +635,7 @@
|
|||
<Message ID="FilterTest">テストファイル (*.mtp)|*.mtp|すべてのファイル (*.*)|*.*</Message>
|
||||
<Message ID="FilterCheat">対応するすべてのファイル (*.cht, *.xml)|*.cht;*.xml</Message>
|
||||
<Message ID="FilterSavestate">Mesenのクイックセーブデータ (*.mst)|*.mst|すべてのファイル (*.*)|*.*</Message>
|
||||
<Message ID="FilterTapeFiles">Family Basicテープファイル (*.fbt)|*.fbt|すべてのファイル (*.*)|*.*</Message>
|
||||
|
||||
<Message ID="LoadFromFile">ファイルからロードする…</Message>
|
||||
<Message ID="SaveToFile">ファイルに保存する…</Message>
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
<Control ID="mnuInsertCoin1">Inserir moeda (1)</Control>
|
||||
<Control ID="mnuInsertCoin2">Inserir moeda (2)</Control>
|
||||
<Control ID="mnuInputBarcode">Input Barcode</Control>
|
||||
<Control ID="mnuTapeRecorder">Tape Recorder</Control>
|
||||
<Control ID="mnuLoadTapeFile">Load from file...</Control>
|
||||
<Control ID="mnuStartRecordTapeFile">Record to file...</Control>
|
||||
<Control ID="mnuStopRecordTapeFile">Stop recording</Control>
|
||||
<Control ID="mnuOptions">Opções</Control>
|
||||
<Control ID="mnuEmulationSpeed">Velocidade</Control>
|
||||
<Control ID="mnuEmuSpeedNormal">Normal (100%)</Control>
|
||||
|
@ -632,6 +636,7 @@
|
|||
<Message ID="FilterTest">Arquivos de teste (*.mtp)|*.mtp|Todos os arquivos (*.*)|*.*</Message>
|
||||
<Message ID="FilterCheat">Todos os formatos suportados (*.cht, *.xml)|*.cht;*.xml</Message>
|
||||
<Message ID="FilterSavestate">Estados salvos do Mesen (*.mst)|*.mst|Todos os arquivos (*.*)|*.*</Message>
|
||||
<Message ID="FilterTapeFiles">Family Basic Tape files (*.fbt)|*.fbt|Todos os arquivos (*.*)|*.*</Message>
|
||||
|
||||
<Message ID="LoadFromFile">Carregar de um arquivo...</Message>
|
||||
<Message ID="SaveToFile">Salvar para arquivo...</Message>
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
<Control ID="mnuInsertCoin1">Вставить монету в слот 1</Control>
|
||||
<Control ID="mnuInsertCoin2">Вставить монету в слот 2</Control>
|
||||
<Control ID="mnuInputBarcode">Input Barcode</Control>
|
||||
<Control ID="mnuTapeRecorder">Tape Recorder</Control>
|
||||
<Control ID="mnuLoadTapeFile">Load from file...</Control>
|
||||
<Control ID="mnuStartRecordTapeFile">Record to file...</Control>
|
||||
<Control ID="mnuStopRecordTapeFile">Stop recording</Control>
|
||||
<Control ID="mnuOptions">Опции</Control>
|
||||
<Control ID="mnuEmulationSpeed">Скорость эмуляции</Control>
|
||||
<Control ID="mnuEmuSpeedNormal">Нормальная (100%)</Control>
|
||||
|
@ -636,6 +640,7 @@
|
|||
<Message ID="FilterTest">Test files (*.mtp)|*.mtp|All (*.*)|*.*</Message>
|
||||
<Message ID="FilterCheat">Все поддерживаемые форматы (*.cht, *.xml)|*.cht;*.xml</Message>
|
||||
<Message ID="FilterSavestate">Mesen Savestates (*.mst)|*.mst|All Files (*.*)|*.*</Message>
|
||||
<Message ID="FilterTapeFiles">Family Basic Tape files (*.fbt)|*.fbt|All Files (*.*)|*.*</Message>
|
||||
|
||||
<Message ID="LoadFromFile">Load from file...</Message>
|
||||
<Message ID="SaveToFile">Save to file...</Message>
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
<Control ID="mnuInsertCoin1">Вставити монету в слот 1</Control>
|
||||
<Control ID="mnuInsertCoin2">Вставити монету в слот 2</Control>
|
||||
<Control ID="mnuInputBarcode">Input Barcode</Control>
|
||||
<Control ID="mnuTapeRecorder">Tape Recorder</Control>
|
||||
<Control ID="mnuLoadTapeFile">Load from file...</Control>
|
||||
<Control ID="mnuStartRecordTapeFile">Record to file...</Control>
|
||||
<Control ID="mnuStopRecordTapeFile">Stop recording</Control>
|
||||
<Control ID="mnuOptions">Опції</Control>
|
||||
<Control ID="mnuEmulationSpeed">Швидкість емуляції</Control>
|
||||
<Control ID="mnuEmuSpeedNormal">Нормальна (100%)</Control>
|
||||
|
@ -636,6 +640,7 @@
|
|||
<Message ID="FilterTest">Test files (*.mtp)|*.mtp|All (*.*)|*.*</Message>
|
||||
<Message ID="FilterCheat">Всі підтримувані формати (*.cht, *.xml)|*.cht;*.xml</Message>
|
||||
<Message ID="FilterSavestate">Mesen Savestates (*.mst)|*.mst|All Files (*.*)|*.*</Message>
|
||||
<Message ID="FilterTapeFiles">Family Basic Tape files (*.fbt)|*.fbt|All Files (*.*)|*.*</Message>
|
||||
|
||||
<Message ID="LoadFromFile">Завантажитти з файлу...</Message>
|
||||
<Message ID="SaveToFile">Зберегти в файл...</Message>
|
||||
|
|
49
GUI.NET/Forms/frmMain.Designer.cs
generated
49
GUI.NET/Forms/frmMain.Designer.cs
generated
|
@ -66,6 +66,10 @@ namespace Mesen.GUI.Forms
|
|||
this.mnuInsertCoin2 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.sepBarcode = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuInputBarcode = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuTapeRecorder = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuLoadTapeFile = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuStartRecordTapeFile = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuStopRecordTapeFile = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuOptions = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuEmulationSpeed = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuEmuSpeedNormal = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -403,10 +407,12 @@ namespace Mesen.GUI.Forms
|
|||
this.mnuInsertCoin1,
|
||||
this.mnuInsertCoin2,
|
||||
this.sepBarcode,
|
||||
this.mnuInputBarcode});
|
||||
this.mnuInputBarcode,
|
||||
this.mnuTapeRecorder});
|
||||
this.mnuGame.Name = "mnuGame";
|
||||
this.mnuGame.Size = new System.Drawing.Size(50, 20);
|
||||
this.mnuGame.Text = "Game";
|
||||
this.mnuGame.DropDownOpening += new System.EventHandler(this.mnuGame_DropDownOpening);
|
||||
//
|
||||
// mnuPause
|
||||
//
|
||||
|
@ -507,12 +513,47 @@ namespace Mesen.GUI.Forms
|
|||
//
|
||||
// mnuInputBarcode
|
||||
//
|
||||
this.mnuInputBarcode.Image = global::Mesen.GUI.Properties.Resources.CheatCode;
|
||||
this.mnuInputBarcode.Image = global::Mesen.GUI.Properties.Resources.Barcode;
|
||||
this.mnuInputBarcode.Name = "mnuInputBarcode";
|
||||
this.mnuInputBarcode.Size = new System.Drawing.Size(182, 22);
|
||||
this.mnuInputBarcode.Text = "Input Barcode...";
|
||||
this.mnuInputBarcode.Visible = false;
|
||||
//
|
||||
// mnuTapeRecorder
|
||||
//
|
||||
this.mnuTapeRecorder.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuLoadTapeFile,
|
||||
this.mnuStartRecordTapeFile,
|
||||
this.mnuStopRecordTapeFile});
|
||||
this.mnuTapeRecorder.Image = global::Mesen.GUI.Properties.Resources.Tape;
|
||||
this.mnuTapeRecorder.Name = "mnuTapeRecorder";
|
||||
this.mnuTapeRecorder.Size = new System.Drawing.Size(182, 22);
|
||||
this.mnuTapeRecorder.Text = "Tape Recorder";
|
||||
//
|
||||
// mnuLoadTapeFile
|
||||
//
|
||||
this.mnuLoadTapeFile.Image = global::Mesen.GUI.Properties.Resources.Import;
|
||||
this.mnuLoadTapeFile.Name = "mnuLoadTapeFile";
|
||||
this.mnuLoadTapeFile.Size = new System.Drawing.Size(179, 22);
|
||||
this.mnuLoadTapeFile.Text = "Load from file...";
|
||||
this.mnuLoadTapeFile.Click += new System.EventHandler(this.mnuLoadTapeFile_Click);
|
||||
//
|
||||
// mnuStartRecordTapeFile
|
||||
//
|
||||
this.mnuStartRecordTapeFile.Image = global::Mesen.GUI.Properties.Resources.Export;
|
||||
this.mnuStartRecordTapeFile.Name = "mnuStartRecordTapeFile";
|
||||
this.mnuStartRecordTapeFile.Size = new System.Drawing.Size(179, 22);
|
||||
this.mnuStartRecordTapeFile.Text = "Record to file...";
|
||||
this.mnuStartRecordTapeFile.Click += new System.EventHandler(this.mnuStartRecordTapeFile_Click);
|
||||
//
|
||||
// mnuStopRecordTapeFile
|
||||
//
|
||||
this.mnuStopRecordTapeFile.Image = global::Mesen.GUI.Properties.Resources.Stop;
|
||||
this.mnuStopRecordTapeFile.Name = "mnuStopRecordTapeFile";
|
||||
this.mnuStopRecordTapeFile.Size = new System.Drawing.Size(179, 22);
|
||||
this.mnuStopRecordTapeFile.Text = "Stop recording";
|
||||
this.mnuStopRecordTapeFile.Click += new System.EventHandler(this.mnuStopRecordTapeFile_Click);
|
||||
//
|
||||
// mnuOptions
|
||||
//
|
||||
this.mnuOptions.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
|
@ -1759,6 +1800,10 @@ namespace Mesen.GUI.Forms
|
|||
private System.Windows.Forms.ToolStripSeparator sepBarcode;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuInputBarcode;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNetPlayPlayer5;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuTapeRecorder;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuLoadTapeFile;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuStartRecordTapeFile;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuStopRecordTapeFile;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,57 +11,52 @@ namespace Mesen.GUI.Forms
|
|||
{
|
||||
public partial class frmMain
|
||||
{
|
||||
private void mnuGame_DropDownOpening(object sender, EventArgs e)
|
||||
{
|
||||
InitializeVsSystemMenu();
|
||||
InitializeFdsDiskMenu();
|
||||
|
||||
bool hasBarcodeReader = InteropEmu.GetAvailableFeatures().HasFlag(ConsoleFeatures.BarcodeReader);
|
||||
mnuInputBarcode.Visible = hasBarcodeReader;
|
||||
|
||||
bool hasTapeRecorder = InteropEmu.GetAvailableFeatures().HasFlag(ConsoleFeatures.TapeRecorder);
|
||||
mnuTapeRecorder.Visible = hasTapeRecorder;
|
||||
|
||||
sepBarcode.Visible = hasBarcodeReader || hasTapeRecorder;
|
||||
}
|
||||
|
||||
private void InitializeFdsDiskMenu()
|
||||
{
|
||||
if(this.InvokeRequired) {
|
||||
this.BeginInvoke((MethodInvoker)(() => this.InitializeFdsDiskMenu()));
|
||||
} else {
|
||||
UInt32 sideCount = InteropEmu.FdsGetSideCount();
|
||||
UInt32 sideCount = InteropEmu.FdsGetSideCount();
|
||||
|
||||
mnuSelectDisk.DropDownItems.Clear();
|
||||
mnuSelectDisk.DropDownItems.Clear();
|
||||
|
||||
if(sideCount > 0) {
|
||||
for(UInt32 i = 0; i < sideCount; i++) {
|
||||
UInt32 diskNumber = i;
|
||||
ToolStripItem item = mnuSelectDisk.DropDownItems.Add(ResourceHelper.GetMessage("FdsDiskSide", (diskNumber/2+1).ToString(), (diskNumber % 2 == 0 ? "A" : "B")));
|
||||
item.Click += (object sender, EventArgs args) => {
|
||||
InteropEmu.FdsInsertDisk(diskNumber);
|
||||
};
|
||||
}
|
||||
sepFdsDisk.Visible = true;
|
||||
mnuSelectDisk.Visible = true;
|
||||
mnuEjectDisk.Visible = true;
|
||||
mnuSwitchDiskSide.Visible = sideCount > 1;
|
||||
} else {
|
||||
sepFdsDisk.Visible = false;
|
||||
mnuSelectDisk.Visible = false;
|
||||
mnuEjectDisk.Visible = false;
|
||||
mnuSwitchDiskSide.Visible = false;
|
||||
if(sideCount > 0) {
|
||||
for(UInt32 i = 0; i < sideCount; i++) {
|
||||
UInt32 diskNumber = i;
|
||||
ToolStripItem item = mnuSelectDisk.DropDownItems.Add(ResourceHelper.GetMessage("FdsDiskSide", (diskNumber/2+1).ToString(), (diskNumber % 2 == 0 ? "A" : "B")));
|
||||
item.Click += (object sender, EventArgs args) => {
|
||||
InteropEmu.FdsInsertDisk(diskNumber);
|
||||
};
|
||||
}
|
||||
sepFdsDisk.Visible = true;
|
||||
mnuSelectDisk.Visible = true;
|
||||
mnuEjectDisk.Visible = true;
|
||||
mnuSwitchDiskSide.Visible = sideCount > 1;
|
||||
} else {
|
||||
sepFdsDisk.Visible = false;
|
||||
mnuSelectDisk.Visible = false;
|
||||
mnuEjectDisk.Visible = false;
|
||||
mnuSwitchDiskSide.Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeVsSystemMenu()
|
||||
{
|
||||
if(this.InvokeRequired) {
|
||||
this.BeginInvoke((MethodInvoker)(() => InitializeVsSystemMenu()));
|
||||
} else {
|
||||
sepVsSystem.Visible = InteropEmu.IsVsSystem();
|
||||
mnuInsertCoin1.Visible = InteropEmu.IsVsSystem();
|
||||
mnuInsertCoin2.Visible = InteropEmu.IsVsSystem();
|
||||
mnuVsGameConfig.Visible = InteropEmu.IsVsSystem();
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeBarcodeReaderMenu()
|
||||
{
|
||||
if(this.InvokeRequired) {
|
||||
this.BeginInvoke((MethodInvoker)(() => InitializeBarcodeReaderMenu()));
|
||||
} else {
|
||||
bool hasBarcodeReader = InteropEmu.GetAvailableFeatures().HasFlag(ConsoleFeatures.BarcodeReader);
|
||||
sepBarcode.Visible = hasBarcodeReader;
|
||||
mnuInputBarcode.Visible = hasBarcodeReader;
|
||||
}
|
||||
sepVsSystem.Visible = InteropEmu.IsVsSystem();
|
||||
mnuInsertCoin1.Visible = InteropEmu.IsVsSystem();
|
||||
mnuInsertCoin2.Visible = InteropEmu.IsVsSystem();
|
||||
mnuVsGameConfig.Visible = InteropEmu.IsVsSystem();
|
||||
}
|
||||
|
||||
private void ShowVsGameConfig()
|
||||
|
@ -78,5 +73,34 @@ namespace Mesen.GUI.Forms
|
|||
{
|
||||
ShowVsGameConfig();
|
||||
}
|
||||
|
||||
private void mnuLoadTapeFile_Click(object sender, EventArgs e)
|
||||
{
|
||||
using(OpenFileDialog ofd = new OpenFileDialog()) {
|
||||
ofd.SetFilter(ResourceHelper.GetMessage("FilterTapeFiles"));
|
||||
ofd.InitialDirectory = ConfigManager.SaveFolder;
|
||||
ofd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".fbt";
|
||||
if(ofd.ShowDialog() == DialogResult.OK) {
|
||||
InteropEmu.LoadTapeFile(ofd.FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuStartRecordTapeFile_Click(object sender, EventArgs e)
|
||||
{
|
||||
using(SaveFileDialog sfd = new SaveFileDialog()) {
|
||||
sfd.SetFilter(ResourceHelper.GetMessage("FilterTapeFiles"));
|
||||
sfd.InitialDirectory = ConfigManager.SaveFolder;
|
||||
sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".fbt";
|
||||
if(sfd.ShowDialog() == DialogResult.OK) {
|
||||
InteropEmu.StartRecordingTapeFile(sfd.FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuStopRecordTapeFile_Click(object sender, EventArgs e)
|
||||
{
|
||||
InteropEmu.StopRecordingTapeFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,6 @@ namespace Mesen.GUI.Forms
|
|||
ResourceHelper.ApplyResources(this);
|
||||
UpdateMenus();
|
||||
UpdateRecentFiles();
|
||||
InitializeFdsDiskMenu();
|
||||
InitializeNsfMode(true);
|
||||
ctrlRecentGames.UpdateGameInfo();
|
||||
} else {
|
||||
|
|
|
@ -156,10 +156,7 @@ namespace Mesen.GUI.Forms
|
|||
_overrideWindowSize = true;
|
||||
}
|
||||
|
||||
InitializeVsSystemMenu();
|
||||
InitializeFdsDiskMenu();
|
||||
InitializeEmulationSpeedMenu();
|
||||
InitializeBarcodeReaderMenu();
|
||||
|
||||
UpdateVideoSettings();
|
||||
|
||||
|
@ -426,9 +423,6 @@ namespace Mesen.GUI.Forms
|
|||
_currentGame = InteropEmu.GetRomInfo().GetRomName();
|
||||
InteropEmu.SetNesModel(ConfigManager.Config.Region);
|
||||
InitializeNsfMode(false, true);
|
||||
InitializeFdsDiskMenu();
|
||||
InitializeVsSystemMenu();
|
||||
InitializeBarcodeReaderMenu();
|
||||
CheatInfo.ApplyCheats();
|
||||
VsConfigInfo.ApplyConfig();
|
||||
UpdateStateMenu(mnuSaveState, true);
|
||||
|
@ -874,6 +868,12 @@ namespace Mesen.GUI.Forms
|
|||
mnuTestRecordTest.Enabled = !netPlay && !moviePlaying && !movieRecording;
|
||||
mnuTestRecordFrom.Enabled = (mnuTestRecordStart.Enabled || mnuTestRecordNow.Enabled || mnuTestRecordMovie.Enabled || mnuTestRecordTest.Enabled);
|
||||
|
||||
bool tapeRecording = InteropEmu.IsRecordingTapeFile();
|
||||
mnuTapeRecorder.Enabled = !isNetPlayClient;
|
||||
mnuLoadTapeFile.Enabled = !isNetPlayClient;
|
||||
mnuStartRecordTapeFile.Enabled = !tapeRecording && !isNetPlayClient;
|
||||
mnuStopRecordTapeFile.Enabled = tapeRecording;
|
||||
|
||||
mnuDebugger.Visible = !devMode;
|
||||
mnuHdPackEditor.Enabled = !netPlay && running;
|
||||
|
||||
|
|
|
@ -861,6 +861,7 @@
|
|||
<Compile Include="ResourceManager.cs" />
|
||||
<Compile Include="RuntimeChecker.cs" />
|
||||
<Compile Include="SingleInstance.cs" />
|
||||
<None Include="Resources\Tape.png" />
|
||||
<None Include="Resources\DownArrowWin10.png" />
|
||||
<None Include="app.manifest" />
|
||||
<None Include="Resources\Exclamation.png" />
|
||||
|
@ -1275,6 +1276,7 @@
|
|||
<None Include="Resources\BreakpointDisabled.png" />
|
||||
<None Include="Resources\BreakpointEnableDisable.png" />
|
||||
<None Include="Resources\ArrowKeys.png" />
|
||||
<None Include="Resources\Barcode.png" />
|
||||
<Content Include="Resources\coins.png" />
|
||||
<None Include="Resources\DipSwitches.png" />
|
||||
<None Include="Resources\MesenIcon.png" />
|
||||
|
|
|
@ -140,6 +140,11 @@ namespace Mesen.GUI
|
|||
|
||||
[DllImport(DLLPath)] public static extern void InputBarcode(UInt64 barcode, Int32 digitCount);
|
||||
|
||||
[DllImport(DLLPath)] public static extern void LoadTapeFile([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filepath);
|
||||
[DllImport(DLLPath)] public static extern void StartRecordingTapeFile([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filepath);
|
||||
[DllImport(DLLPath)] public static extern void StopRecordingTapeFile();
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsRecordingTapeFile();
|
||||
|
||||
[DllImport(DLLPath)] public static extern void SetCheats([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]InteropCheatInfo[] cheats, UInt32 length);
|
||||
|
||||
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool CheckFlag(EmulationFlags flag);
|
||||
|
@ -1836,6 +1841,7 @@ namespace Mesen.GUI
|
|||
Nsf = 2,
|
||||
VsSystem = 4,
|
||||
BarcodeReader = 8,
|
||||
TapeRecorder = 16,
|
||||
}
|
||||
|
||||
public enum ScreenRotation
|
||||
|
|
22
GUI.NET/Properties/Resources.Designer.cs
generated
22
GUI.NET/Properties/Resources.Designer.cs
generated
|
@ -19,7 +19,7 @@ namespace Mesen.GUI.Properties {
|
|||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
@ -100,6 +100,16 @@ namespace Mesen.GUI.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap Barcode {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Barcode", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
@ -790,6 +800,16 @@ namespace Mesen.GUI.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap Tape {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Tape", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
|
|
@ -358,4 +358,10 @@
|
|||
<data name="DownArrowWin10" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\DownArrowWin10.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Barcode" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Barcode.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Tape" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Tape.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
BIN
GUI.NET/Resources/Barcode.png
Normal file
BIN
GUI.NET/Resources/Barcode.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 273 B |
BIN
GUI.NET/Resources/Tape.png
Normal file
BIN
GUI.NET/Resources/Tape.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 247 B |
|
@ -460,6 +460,11 @@ namespace InteropEmu {
|
|||
|
||||
DllExport void __stdcall InputBarcode(uint64_t barCode, int32_t digitCount) { Console::GetInstance()->InputBarcode(barCode, digitCount); }
|
||||
|
||||
DllExport void __stdcall LoadTapeFile(char *filepath) { Console::GetInstance()->LoadTapeFile(filepath); }
|
||||
DllExport void __stdcall StartRecordingTapeFile(char *filepath) { Console::GetInstance()->StartRecordingTapeFile(filepath); }
|
||||
DllExport void __stdcall StopRecordingTapeFile() { Console::GetInstance()->StopRecordingTapeFile(); }
|
||||
DllExport bool __stdcall IsRecordingTapeFile() { return Console::GetInstance()->IsRecordingTapeFile(); }
|
||||
|
||||
DllExport ConsoleFeatures __stdcall GetAvailableFeatures() { return Console::GetInstance()->GetAvailableFeatures(); }
|
||||
|
||||
//NSF functions
|
||||
|
|
44
Utilities/Base64.h
Normal file
44
Utilities/Base64.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
class Base64
|
||||
{
|
||||
public:
|
||||
static string Encode(const vector<uint8_t> data)
|
||||
{
|
||||
std::string out;
|
||||
|
||||
int val = 0, valb = -6;
|
||||
for(uint8_t c : data) {
|
||||
val = (val << 8) + c;
|
||||
valb += 8;
|
||||
while(valb >= 0) {
|
||||
out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(val >> valb) & 0x3F]);
|
||||
valb -= 6;
|
||||
}
|
||||
}
|
||||
if(valb>-6) out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[((val << 8) >> (valb + 8)) & 0x3F]);
|
||||
while(out.size() % 4) out.push_back('=');
|
||||
return out;
|
||||
}
|
||||
|
||||
static vector<uint8_t> Decode(string in)
|
||||
{
|
||||
vector<uint8_t> out;
|
||||
|
||||
vector<int> T(256, -1);
|
||||
for(int i = 0; i < 64; i++) T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;
|
||||
|
||||
int val = 0, valb = -8;
|
||||
for(uint8_t c : in) {
|
||||
if(T[c] == -1) break;
|
||||
val = (val << 6) + T[c];
|
||||
valb += 6;
|
||||
if(valb >= 0) {
|
||||
out.push_back(val >> valb);
|
||||
valb -= 8;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
|
@ -323,6 +323,7 @@
|
|||
<ItemGroup>
|
||||
<ClInclude Include="ArchiveReader.h" />
|
||||
<ClInclude Include="AviWriter.h" />
|
||||
<ClInclude Include="Base64.h" />
|
||||
<ClInclude Include="blip_buf.h" />
|
||||
<ClInclude Include="BpsPatcher.h" />
|
||||
<ClInclude Include="CamstudioCodec.h" />
|
||||
|
|
|
@ -161,6 +161,9 @@
|
|||
<ClInclude Include="stb_vorbis.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Base64.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
|
Loading…
Add table
Reference in a new issue