Pravets refactor: move all specialisations into new Pravets class. (PR #914)
Mainly for keyboard & printer specialisations.
This commit is contained in:
parent
fc3a0f57ce
commit
daa0675694
|
@ -26,6 +26,7 @@ NB. Pravets 82, 8M and 8A are Bulgarian Apple II clones;
|
||||||
TK3000 is a Brazilian //e clone;
|
TK3000 is a Brazilian //e clone;
|
||||||
Base 64A is a Taiwanese Apple II clone.<br>
|
Base 64A is a Taiwanese Apple II clone.<br>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>Pravets 8A: Use F10 for the Pravets Caps Lock (and the PC's Caps Lock key controls Cyrillic/Latin lock).
|
||||||
<li>TK3000: Use Scroll Lock for the 'mode' key. Use to switch between standard Apple II and accented characters.
|
<li>TK3000: Use Scroll Lock for the 'mode' key. Use to switch between standard Apple II and accented characters.
|
||||||
<li>Base 64A: Use Delete for the 'F2' key (eg. press F2, release F2 then press a key to auto-type a BASIC keyword).
|
<li>Base 64A: Use Delete for the 'F2' key (eg. press F2, release F2 then press a key to auto-type a BASIC keyword).
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -238,6 +238,11 @@ inline bool IsCopamBase64A(eApple2Type type) // Copam Base64A
|
||||||
return type == A2TYPE_BASE64A;
|
return type == A2TYPE_BASE64A;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool IsPravets(eApple2Type type)
|
||||||
|
{
|
||||||
|
return type == A2TYPE_PRAVETS8M || type == A2TYPE_PRAVETS82 || type == A2TYPE_PRAVETS8A;
|
||||||
|
}
|
||||||
|
|
||||||
enum eBUTTON {BUTTON0=0, BUTTON1};
|
enum eBUTTON {BUTTON0=0, BUTTON1};
|
||||||
|
|
||||||
enum eBUTTONSTATE {BUTTON_UP=0, BUTTON_DOWN};
|
enum eBUTTONSTATE {BUTTON_UP=0, BUTTON_DOWN};
|
||||||
|
|
|
@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "Mockingboard.h"
|
#include "Mockingboard.h"
|
||||||
|
#include "Pravets.h"
|
||||||
#include "Speaker.h"
|
#include "Speaker.h"
|
||||||
#include "Registry.h"
|
#include "Registry.h"
|
||||||
#include "SynchronousEventManager.h"
|
#include "SynchronousEventManager.h"
|
||||||
|
@ -295,3 +296,9 @@ bool SetCurrentImageDir(const std::string& pszImageDir)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pravets& GetPravets(void)
|
||||||
|
{
|
||||||
|
static Pravets pravets;
|
||||||
|
return pravets;
|
||||||
|
}
|
||||||
|
|
|
@ -67,6 +67,8 @@ extern bool g_bDisableDirectInput; // Cmd line switch: don't init DI (s
|
||||||
extern bool g_bDisableDirectSound; // Cmd line switch: don't init DS (so no MB/Speaker support)
|
extern bool g_bDisableDirectSound; // Cmd line switch: don't init DS (so no MB/Speaker support)
|
||||||
extern bool g_bDisableDirectSoundMockingboard; // Cmd line switch: don't init MB support
|
extern bool g_bDisableDirectSoundMockingboard; // Cmd line switch: don't init MB support
|
||||||
|
|
||||||
|
class Pravets& GetPravets(void);
|
||||||
|
|
||||||
//#define LOG_PERF_TIMINGS
|
//#define LOG_PERF_TIMINGS
|
||||||
#ifdef LOG_PERF_TIMINGS
|
#ifdef LOG_PERF_TIMINGS
|
||||||
class PerfMarker
|
class PerfMarker
|
||||||
|
|
|
@ -52,7 +52,6 @@ bool g_bAltKey = false;
|
||||||
static bool g_bTK3KModeKey = false; //TK3000 //e |Mode| key
|
static bool g_bTK3KModeKey = false; //TK3000 //e |Mode| key
|
||||||
|
|
||||||
static bool g_bCapsLock = true; //Caps lock key for Apple2 and Lat/Cyr lock for Pravets8
|
static bool g_bCapsLock = true; //Caps lock key for Apple2 and Lat/Cyr lock for Pravets8
|
||||||
static bool g_bP8CapsLock = true; //Caps lock key of Pravets 8A/C
|
|
||||||
static BYTE keycode = 0; // Current Apple keycode
|
static BYTE keycode = 0; // Current Apple keycode
|
||||||
static BOOL keywaiting = 0;
|
static BOOL keywaiting = 0;
|
||||||
static bool g_bAltGrSendsWM_CHAR = false;
|
static bool g_bAltGrSendsWM_CHAR = false;
|
||||||
|
@ -80,12 +79,6 @@ bool KeybGetCapsStatus()
|
||||||
return g_bCapsLock;
|
return g_bCapsLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
bool KeybGetP8CapsStatus()
|
|
||||||
{
|
|
||||||
return g_bP8CapsLock;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
bool KeybGetAltStatus()
|
bool KeybGetAltStatus()
|
||||||
{
|
{
|
||||||
|
@ -162,109 +155,11 @@ void KeybQueueKeypress (WPARAM key, Keystroke_e bASCII)
|
||||||
// Next apply any clone override:
|
// Next apply any clone override:
|
||||||
if (IS_CLONE())
|
if (IS_CLONE())
|
||||||
{
|
{
|
||||||
P8Shift = false;
|
|
||||||
if (g_bCapsLock && (key >= 'a') && (key <='z'))
|
|
||||||
{
|
|
||||||
P8Shift = true;
|
|
||||||
keycode = key - 32;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
keycode = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
keycode &= 0x7F; // for accented chars, eg. AltGr+A
|
keycode &= 0x7F; // for accented chars, eg. AltGr+A
|
||||||
|
|
||||||
//The latter line should be applied for Pravtes 8A/C only, but not for Pravets 82/M !!!
|
if (IsPravets(GetApple2Type()))
|
||||||
if ((g_bCapsLock == false) && (key >= 'A') && (key <='Z'))
|
keycode = GetPravets().ConvertToKeycode(key, keycode);
|
||||||
{
|
|
||||||
P8Shift = true;
|
|
||||||
if (GetApple2Type() == A2TYPE_PRAVETS8A)
|
|
||||||
keycode = key + 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Remap some keys for Pravets82/M
|
|
||||||
if (GetApple2Type() == A2TYPE_PRAVETS82)
|
|
||||||
{
|
|
||||||
if (key == 64)
|
|
||||||
keycode = 96;
|
|
||||||
if (key == '^')
|
|
||||||
keycode = '~';
|
|
||||||
|
|
||||||
if (g_bCapsLock == false) //cyrillic letters
|
|
||||||
{
|
|
||||||
if (key == '`') keycode = '^';
|
|
||||||
if (key == 92) keycode = '@'; // \ to @
|
|
||||||
if (key == 124) keycode = 92;
|
|
||||||
}
|
|
||||||
else //(g_bCapsLock == true) //latin letters
|
|
||||||
{
|
|
||||||
if (key == 91) keycode = 123;
|
|
||||||
if (key == 93) keycode = 125;
|
|
||||||
if (key == 124) keycode = 92;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (GetApple2Type() == A2TYPE_PRAVETS8M) //Pravets 8M charset is still uncertain
|
|
||||||
{
|
|
||||||
if (g_bCapsLock == false) //cyrillic letters
|
|
||||||
{
|
|
||||||
if (key == '[') keycode = '{';
|
|
||||||
if (key == ']') keycode = '}';
|
|
||||||
if (key == '`') keycode = '~'; //96= key `~
|
|
||||||
if (key == 92) keycode = 96;
|
|
||||||
}
|
|
||||||
else //latin letters
|
|
||||||
{
|
|
||||||
if (key == '`')
|
|
||||||
keycode = '^'; //96= key `~
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Remap some keys for Pravets8A/C, which has a different charset for Pravtes82/M, whose keys MUST NOT be remapped.
|
|
||||||
if (GetApple2Type() == A2TYPE_PRAVETS8A) //&& (g_bCapsLock == false))
|
|
||||||
{
|
|
||||||
if (g_bCapsLock == false) //i.e. cyrillic letters
|
|
||||||
{
|
|
||||||
if (key == '[') keycode = '{';
|
|
||||||
if (key == ']') keycode = '}';
|
|
||||||
if (key == '`') keycode = '~';
|
|
||||||
if (key == 92) keycode = 96;
|
|
||||||
if (GetCapsLockAllowed() == true)
|
|
||||||
{
|
|
||||||
if ((key == 92) || (key == 124)) keycode = 96; //Ý to Þ
|
|
||||||
//This shall be rewriten, so that enabling CAPS_LOCK (i.e. F10) will not invert these keys values)
|
|
||||||
//The same for latin letters.
|
|
||||||
if ((key == '{') || (key == '}') || (key == '~') || (key == 124) || (key == '^') || (key == 95))
|
|
||||||
P8Shift = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else //i.e. latin letters
|
|
||||||
{
|
|
||||||
if (GetCapsLockAllowed() == false)
|
|
||||||
{
|
|
||||||
if (key == '{') keycode = '[';
|
|
||||||
if (key == '}') keycode = ']';
|
|
||||||
if (key == 124)
|
|
||||||
keycode = 92;
|
|
||||||
/*if (key == 92)
|
|
||||||
keycode = 124;*/
|
|
||||||
//Characters ` and ~ cannot be generated in 7bit character mode, so they are replaced with
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (key == '{') keycode = 91;
|
|
||||||
if (key == '}') keycode = 93;
|
|
||||||
if (key == 124) keycode = 92;
|
|
||||||
if ((key == '[') || (key == ']') || (key == 92) || (key == '^') || (key == 95))
|
|
||||||
P8Shift= true;
|
|
||||||
if (key == 96) //This line shall generate sth. else i.e. ` In fact. this character is not generateable by the pravets keyboard.
|
|
||||||
{
|
|
||||||
keycode = '^';
|
|
||||||
P8Shift= true;
|
|
||||||
}
|
|
||||||
if (key == 126) keycode = '^';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Remap for the TK3000 //e, which had a special |Mode| key for displaying accented chars on screen
|
// Remap for the TK3000 //e, which had a special |Mode| key for displaying accented chars on screen
|
||||||
// Borrowed from Fábio Belavenuto's TK3000e emulator (Copyright (C) 2004) - http://code.google.com/p/tk3000e/
|
// Borrowed from Fábio Belavenuto's TK3000e emulator (Copyright (C) 2004) - http://code.google.com/p/tk3000e/
|
||||||
if (GetApple2Type() == A2TYPE_TK30002E && g_bTK3KModeKey) // We already switch this on only if the the TK3000 is currently being emulated
|
if (GetApple2Type() == A2TYPE_TK30002E && g_bTK3KModeKey) // We already switch this on only if the the TK3000 is currently being emulated
|
||||||
|
@ -285,7 +180,8 @@ void KeybQueueKeypress (WPARAM key, Keystroke_e bASCII)
|
||||||
case 0xF5: key = '#'; break; // õ
|
case 0xF5: key = '#'; break; // õ
|
||||||
case 0xFA: key = '|'; break; // ú
|
case 0xFA: key = '|'; break; // ú
|
||||||
}
|
}
|
||||||
if (key > 0x7F) return; // Get out
|
if (key > 0x7F)
|
||||||
|
return;
|
||||||
if ((key >= 'a') && (key <= 'z') && (g_bCapsLock))
|
if ((key >= 'a') && (key <= 'z') && (g_bCapsLock))
|
||||||
keycode = key - ('a'-'A');
|
keycode = key - ('a'-'A');
|
||||||
else
|
else
|
||||||
|
@ -556,15 +452,6 @@ void KeybToggleCapsLock ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
void KeybToggleP8ACapsLock ()
|
|
||||||
{
|
|
||||||
_ASSERT(GetApple2Type() == A2TYPE_PRAVETS8A);
|
|
||||||
P8CAPS_ON = !P8CAPS_ON;
|
|
||||||
GetFrame().FrameRefreshStatus(DRAW_LEDS | DRAW_DISK_STATUS);
|
|
||||||
// g_bP8CapsLock= g_bP8CapsLock?false:true; //The same as the upper, but slower
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
#define SS_YAML_KEY_LASTKEY "Last Key"
|
#define SS_YAML_KEY_LASTKEY "Last Key"
|
||||||
|
|
|
@ -7,7 +7,6 @@ void ClipboardInitiatePaste();
|
||||||
void KeybReset();
|
void KeybReset();
|
||||||
void KeybSetAltGrSendsWM_CHAR(bool state);
|
void KeybSetAltGrSendsWM_CHAR(bool state);
|
||||||
bool KeybGetCapsStatus();
|
bool KeybGetCapsStatus();
|
||||||
bool KeybGetP8CapsStatus();
|
|
||||||
bool KeybGetAltStatus();
|
bool KeybGetAltStatus();
|
||||||
bool KeybGetCtrlStatus();
|
bool KeybGetCtrlStatus();
|
||||||
bool KeybGetShiftStatus();
|
bool KeybGetShiftStatus();
|
||||||
|
|
|
@ -45,6 +45,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "MouseInterface.h"
|
#include "MouseInterface.h"
|
||||||
#include "NTSC.h"
|
#include "NTSC.h"
|
||||||
#include "NoSlotClock.h"
|
#include "NoSlotClock.h"
|
||||||
|
#include "Pravets.h"
|
||||||
#include "ParallelPrinter.h"
|
#include "ParallelPrinter.h"
|
||||||
#include "Registry.h"
|
#include "Registry.h"
|
||||||
#include "SAM.h"
|
#include "SAM.h"
|
||||||
|
@ -466,7 +467,7 @@ static BYTE __stdcall IORead_C02x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
|
||||||
|
|
||||||
static BYTE __stdcall IOWrite_C02x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles)
|
static BYTE __stdcall IOWrite_C02x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles)
|
||||||
{
|
{
|
||||||
return IO_Null(pc, addr, bWrite, d, nExecutedCycles); // $C020 TAPEOUT
|
return TapeWrite(pc, addr, bWrite, d, nExecutedCycles); // $C020 TAPEOUT
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
@ -559,11 +560,7 @@ static BYTE __stdcall IORead_C06x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
|
||||||
{
|
{
|
||||||
switch (addr & 0x7) // address bit 4 is ignored (UTAIIe:7-5)
|
switch (addr & 0x7) // address bit 4 is ignored (UTAIIe:7-5)
|
||||||
{
|
{
|
||||||
//In Pravets8A/C if SETMODE (8bit character encoding) is enabled, bit6 in $C060 is 0; Else it is 1
|
case 0x0: return TapeRead(pc, addr, bWrite, d, nExecutedCycles); //$C060 TAPEIN
|
||||||
//If (CAPS lOCK of Pravets8A/C is on or Shift is pressed) and (MODE is enabled), bit7 in $C000 is 1; Else it is 0
|
|
||||||
//Writing into $C060 sets MODE on and off. If bit 0 is 0 the the MODE is set 0, if bit 0 is 1 then MODE is set to 1 (8-bit)
|
|
||||||
|
|
||||||
case 0x0: return TapeRead(pc, addr, bWrite, d, nExecutedCycles); // $C060 TAPEIN
|
|
||||||
case 0x1: return JoyReadButton(pc, addr, bWrite, d, nExecutedCycles); //$C061 Digital input 0 (If bit 7=1 then JoyButton 0 or OpenApple is pressed)
|
case 0x1: return JoyReadButton(pc, addr, bWrite, d, nExecutedCycles); //$C061 Digital input 0 (If bit 7=1 then JoyButton 0 or OpenApple is pressed)
|
||||||
case 0x2: return JoyReadButton(pc, addr, bWrite, d, nExecutedCycles); //$C062 Digital input 1 (If bit 7=1 then JoyButton 1 or ClosedApple is pressed)
|
case 0x2: return JoyReadButton(pc, addr, bWrite, d, nExecutedCycles); //$C062 Digital input 1 (If bit 7=1 then JoyButton 1 or ClosedApple is pressed)
|
||||||
case 0x3: return JoyReadButton(pc, addr, bWrite, d, nExecutedCycles); //$C063 Digital input 2
|
case 0x3: return JoyReadButton(pc, addr, bWrite, d, nExecutedCycles); //$C063 Digital input 2
|
||||||
|
@ -582,11 +579,11 @@ static BYTE __stdcall IOWrite_C06x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULON
|
||||||
{
|
{
|
||||||
case 0x0:
|
case 0x0:
|
||||||
if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
||||||
return TapeWrite (pc, addr, bWrite, d, nExecutedCycles);
|
return GetPravets().SetCapsLockAllowed(d);
|
||||||
else
|
else
|
||||||
return IO_Null(pc, addr, bWrite, d, nExecutedCycles); //Apple2 value
|
return IO_Null(pc, addr, bWrite, d, nExecutedCycles);
|
||||||
}
|
}
|
||||||
return IO_Null(pc, addr, bWrite, d, nExecutedCycles); //Apple2 value
|
return IO_Null(pc, addr, bWrite, d, nExecutedCycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
|
@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "ParallelPrinter.h"
|
#include "ParallelPrinter.h"
|
||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
|
#include "Pravets.h"
|
||||||
#include "Registry.h"
|
#include "Registry.h"
|
||||||
#include "YamlHelper.h"
|
#include "YamlHelper.h"
|
||||||
|
|
||||||
|
@ -158,70 +159,20 @@ static BYTE __stdcall PrintStatus(WORD, WORD, BYTE, BYTE, ULONG)
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
static BYTE __stdcall PrintTransmit(WORD, WORD, BYTE, BYTE value, ULONG)
|
static BYTE __stdcall PrintTransmit(WORD, WORD, BYTE, BYTE value, ULONG)
|
||||||
{
|
{
|
||||||
char Lat8A[]= "abwgdevzijklmnoprstufhc~{}yx`q|]";
|
|
||||||
char Lat82[]= "abwgdevzijklmnoprstufhc^[]yx@q{}~`";
|
|
||||||
char Kir82[]= "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÜÞß[]^@";
|
|
||||||
char Kir8ACapital[]= "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÜÞßÝ";
|
|
||||||
char Kir8ALowerCase[]= "àáâãäåæçèéêëìíîïðñòóôõö÷øùúüþÿý";
|
|
||||||
|
|
||||||
if (!CheckPrint())
|
if (!CheckPrint())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
BYTE c = value & 0x7F;
|
||||||
|
|
||||||
|
if (IsPravets(GetApple2Type()))
|
||||||
{
|
{
|
||||||
return 0;
|
if (g_bConvertEncoding)
|
||||||
|
c = GetPravets().ConvertToPrinterChar(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
char c = 0;
|
if ((g_bFilterUnprintable == false) || (c>31) || (c==13) || (c==10) || (c>0x7F)) //c>0x7F is needed for cyrillic characters
|
||||||
if ((g_Apple2Type == A2TYPE_PRAVETS8A) && g_bConvertEncoding) //This is print conversion for Pravets 8A/C. Print conversion for Pravets82/M is still to be done.
|
fwrite(&c, 1, 1, file);
|
||||||
{
|
|
||||||
if ((value > 90) && (value < 128)) //This range shall be set more precisely
|
|
||||||
{
|
|
||||||
c = value;
|
|
||||||
int loop = 0;
|
|
||||||
while (loop < 31)
|
|
||||||
{
|
|
||||||
if (c== Lat8A[loop])
|
|
||||||
c= 0 + Kir8ALowerCase [loop] ;
|
|
||||||
loop++;
|
|
||||||
} //End loop
|
|
||||||
}//End if (value < 128)
|
|
||||||
else if ((value >64) && (value <91))
|
|
||||||
{
|
|
||||||
c = value + 32;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c = value & 0x7F;
|
|
||||||
int loop = 0;
|
|
||||||
while (loop < 31)
|
|
||||||
{
|
|
||||||
if (c== Lat8A[loop]) c= 0 + Kir8ACapital [loop];
|
|
||||||
loop++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} //End if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
|
||||||
else if (((g_Apple2Type == A2TYPE_PRAVETS82) || (g_Apple2Type == A2TYPE_PRAVETS8M)) && g_bConvertEncoding)
|
|
||||||
{
|
|
||||||
c = value & 0x7F;
|
|
||||||
int loop = 0;
|
|
||||||
while (loop < 34)
|
|
||||||
{
|
|
||||||
if (c == Lat82[loop])
|
|
||||||
c= Kir82 [loop];
|
|
||||||
loop++;
|
|
||||||
} //end while
|
|
||||||
}
|
|
||||||
else //Apple II
|
|
||||||
{
|
|
||||||
c = value & 0x7F;
|
|
||||||
}
|
|
||||||
if ((g_bFilterUnprintable == false) || (c>31) || (c==13) || (c==10) || (c<0)) //c<0 is needed for cyrillic characters
|
|
||||||
fwrite(&c, 1, 1, file); //break;
|
|
||||||
|
|
||||||
|
|
||||||
/*else
|
|
||||||
{
|
|
||||||
char c = value & 0x7F;
|
|
||||||
fwrite(&c, 1, 1, file);
|
|
||||||
}*/
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,16 +34,228 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "Keyboard.h"
|
#include "Keyboard.h"
|
||||||
#include "Tape.h"
|
#include "Tape.h"
|
||||||
|
|
||||||
//Pravets 8A/C variables
|
Pravets::Pravets(void)
|
||||||
bool P8CAPS_ON = false;
|
|
||||||
bool P8Shift = false;
|
|
||||||
|
|
||||||
void PravetsReset(void)
|
|
||||||
{
|
{
|
||||||
if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
// Pravets 8A
|
||||||
|
bool g_CapsLockAllowed = false;
|
||||||
|
|
||||||
|
// Pravets 8A/8C
|
||||||
|
P8CAPS_ON = false;
|
||||||
|
P8Shift = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pravets::Reset(void)
|
||||||
|
{
|
||||||
|
if (GetApple2Type() == A2TYPE_PRAVETS8A)
|
||||||
{
|
{
|
||||||
P8CAPS_ON = false;
|
P8CAPS_ON = false;
|
||||||
TapeWrite(0, 0, 0, 0 ,0);
|
g_CapsLockAllowed = false;
|
||||||
GetFrame().FrameRefreshStatus(DRAW_LEDS | DRAW_DISK_STATUS);
|
GetFrame().FrameRefreshStatus(DRAW_LEDS | DRAW_DISK_STATUS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//In Pravets8A/C if SETMODE (8bit character encoding) is enabled, bit6 in $C060 is 0; Else it is 1
|
||||||
|
//If (CAPS lOCK of Pravets8A/C is on or Shift is pressed) and (MODE is enabled), bit7 in $C000 is 1; Else it is 0
|
||||||
|
//Writing into $C060 sets MODE on and off. If bit 0 is 0 the the MODE is set 0, if bit 0 is 1 then MODE is set to 1 (8-bit)
|
||||||
|
|
||||||
|
BYTE Pravets::GetKeycode(BYTE floatingBus) // Read $C060
|
||||||
|
{
|
||||||
|
const BYTE uCurrentKeystroke = KeybGetKeycode();
|
||||||
|
BYTE C060 = floatingBus;
|
||||||
|
|
||||||
|
if (GetApple2Type() == A2TYPE_PRAVETS8A && g_CapsLockAllowed) //8bit keyboard mode
|
||||||
|
{
|
||||||
|
if ((!P8CAPS_ON && !P8Shift) || (P8CAPS_ON && P8Shift)) //LowerCase
|
||||||
|
{
|
||||||
|
if ((uCurrentKeystroke<65) //|| ((uCurrentKeystroke>90) && (uCurrentKeystroke<96))
|
||||||
|
|| ((uCurrentKeystroke>126) && (uCurrentKeystroke<193)))
|
||||||
|
C060 |= 1 << 7; //Sets bit 7 to 1 for special keys (arrows, return, etc) and for control+ key combinations.
|
||||||
|
else
|
||||||
|
C060 &= 0x7F; //sets bit 7 to 0
|
||||||
|
}
|
||||||
|
else //UpperCase
|
||||||
|
{
|
||||||
|
C060 |= 1 << 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //7bit keyboard mode
|
||||||
|
{
|
||||||
|
C060 &= 0xBF; //Sets bit 6 to 0; I am not sure if this shall be done, because its value is disregarded in this case.
|
||||||
|
C060 |= 1 << 7; //Sets bit 7 to 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return C060;
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE Pravets::SetCapsLockAllowed(BYTE value) // Write $C060
|
||||||
|
{
|
||||||
|
if (GetApple2Type() == A2TYPE_PRAVETS8A)
|
||||||
|
{
|
||||||
|
//If bit0 of the input byte is 0, it will forbid 8-bit characters (Default)
|
||||||
|
//If bit0 of the input byte is 1, it will allow 8-bit characters
|
||||||
|
|
||||||
|
if (value & 1)
|
||||||
|
g_CapsLockAllowed = true;
|
||||||
|
else
|
||||||
|
g_CapsLockAllowed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE Pravets::ConvertToKeycode(WPARAM key, BYTE keycode)
|
||||||
|
{
|
||||||
|
if (KeybGetCapsStatus() && (key >= 'a') && (key <='z'))
|
||||||
|
P8Shift = true;
|
||||||
|
else
|
||||||
|
P8Shift = false;
|
||||||
|
|
||||||
|
//The latter line should be applied for Pravtes 8A/C only, but not for Pravets 82/M !!!
|
||||||
|
if ((KeybGetCapsStatus() == false) && (key >= 'A') && (key <='Z'))
|
||||||
|
{
|
||||||
|
P8Shift = true;
|
||||||
|
if (GetApple2Type() == A2TYPE_PRAVETS8A)
|
||||||
|
keycode = key + 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remap some keys for Pravets82/M
|
||||||
|
if (GetApple2Type() == A2TYPE_PRAVETS82)
|
||||||
|
{
|
||||||
|
if (key == 64)
|
||||||
|
keycode = 96;
|
||||||
|
if (key == '^')
|
||||||
|
keycode = '~';
|
||||||
|
|
||||||
|
if (KeybGetCapsStatus() == false) //cyrillic letters
|
||||||
|
{
|
||||||
|
if (key == '`') keycode = '^';
|
||||||
|
if (key == 92) keycode = '@'; // \ to @
|
||||||
|
if (key == 124) keycode = 92;
|
||||||
|
}
|
||||||
|
else //(g_bCapsLock == true) //latin letters
|
||||||
|
{
|
||||||
|
if (key == 91) keycode = 123;
|
||||||
|
if (key == 93) keycode = 125;
|
||||||
|
if (key == 124) keycode = 92;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetApple2Type() == A2TYPE_PRAVETS8M) //Pravets 8M charset is still uncertain
|
||||||
|
{
|
||||||
|
if (KeybGetCapsStatus() == false) //cyrillic letters
|
||||||
|
{
|
||||||
|
if (key == '[') keycode = '{';
|
||||||
|
if (key == ']') keycode = '}';
|
||||||
|
if (key == '`') keycode = '~'; //96= key `~
|
||||||
|
if (key == 92) keycode = 96;
|
||||||
|
}
|
||||||
|
else //latin letters
|
||||||
|
{
|
||||||
|
if (key == '`')
|
||||||
|
keycode = '^'; //96= key `~
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remap some keys for Pravets8A/C, which has a different charset for Pravtes82/M, whose keys MUST NOT be remapped.
|
||||||
|
if (GetApple2Type() == A2TYPE_PRAVETS8A) //&& (g_bCapsLock == false))
|
||||||
|
{
|
||||||
|
if (KeybGetCapsStatus() == false) //i.e. cyrillic letters
|
||||||
|
{
|
||||||
|
if (key == '[') keycode = '{';
|
||||||
|
if (key == ']') keycode = '}';
|
||||||
|
if (key == '`') keycode = '~';
|
||||||
|
if (key == 92) keycode = 96;
|
||||||
|
if (g_CapsLockAllowed == true)
|
||||||
|
{
|
||||||
|
if ((key == 92) || (key == 124)) keycode = 96; //Ý to Þ
|
||||||
|
//This shall be rewriten, so that enabling CAPS_LOCK (i.e. F10) will not invert these keys values)
|
||||||
|
//The same for latin letters.
|
||||||
|
if ((key == '{') || (key == '}') || (key == '~') || (key == 124) || (key == '^') || (key == 95))
|
||||||
|
P8Shift = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //i.e. latin letters
|
||||||
|
{
|
||||||
|
if (g_CapsLockAllowed == false)
|
||||||
|
{
|
||||||
|
if (key == '{') keycode = '[';
|
||||||
|
if (key == '}') keycode = ']';
|
||||||
|
if (key == 124)
|
||||||
|
keycode = 92;
|
||||||
|
/*if (key == 92)
|
||||||
|
keycode = 124;*/
|
||||||
|
//Characters ` and ~ cannot be generated in 7bit character mode, so they are replaced with
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (key == '{') keycode = 91;
|
||||||
|
if (key == '}') keycode = 93;
|
||||||
|
if (key == 124) keycode = 92;
|
||||||
|
if ((key == '[') || (key == ']') || (key == 92) || (key == '^') || (key == 95))
|
||||||
|
P8Shift = true;
|
||||||
|
if (key == 96) //This line shall generate sth. else i.e. ` In fact. this character is not generateable by the pravets keyboard.
|
||||||
|
{
|
||||||
|
keycode = '^';
|
||||||
|
P8Shift = true;
|
||||||
|
}
|
||||||
|
if (key == 126) keycode = '^';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return keycode;
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE Pravets::ConvertToPrinterChar(BYTE value)
|
||||||
|
{
|
||||||
|
char Lat8A[]= "abwgdevzijklmnoprstufhc~{}yx`q|]";
|
||||||
|
char Lat82[]= "abwgdevzijklmnoprstufhc^[]yx@q{}~`";
|
||||||
|
char Kir82[]= "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÜÞß[]^@";
|
||||||
|
char Kir8ACapital[]= "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÜÞßÝ";
|
||||||
|
char Kir8ALowerCase[]= "àáâãäåæçèéêëìíîïðñòóôõö÷øùúüþÿý";
|
||||||
|
|
||||||
|
BYTE c = 0;
|
||||||
|
|
||||||
|
if (GetApple2Type() == A2TYPE_PRAVETS8A) //This is print conversion for Pravets 8A/C. Print conversion for Pravets82/M is still to be done.
|
||||||
|
{
|
||||||
|
if ((value > 90) && (value < 128)) //This range shall be set more precisely
|
||||||
|
{
|
||||||
|
c = value;
|
||||||
|
int loop = 0;
|
||||||
|
while (loop < 31)
|
||||||
|
{
|
||||||
|
if (c == Lat8A[loop])
|
||||||
|
c = Kir8ALowerCase[loop];
|
||||||
|
loop++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((value > 64) && (value < 91))
|
||||||
|
{
|
||||||
|
c = value + 32;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c = value & 0x7F;
|
||||||
|
int loop = 0;
|
||||||
|
while (loop < 31)
|
||||||
|
{
|
||||||
|
if (c == Lat8A[loop])
|
||||||
|
c = Kir8ACapital[loop];
|
||||||
|
loop++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (GetApple2Type() == A2TYPE_PRAVETS82 || GetApple2Type() == A2TYPE_PRAVETS8M)
|
||||||
|
{
|
||||||
|
c = value & 0x7F;
|
||||||
|
int loop = 0;
|
||||||
|
while (loop < 34)
|
||||||
|
{
|
||||||
|
if (c == Lat82[loop])
|
||||||
|
c = Kir82[loop];
|
||||||
|
loop++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,23 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
//Pravets 8A/C only variables
|
class Pravets
|
||||||
extern bool P8CAPS_ON;
|
{
|
||||||
extern bool P8Shift;
|
public:
|
||||||
|
Pravets(void);
|
||||||
|
~Pravets(void){}
|
||||||
|
|
||||||
void PravetsReset(void);
|
void Reset(void);
|
||||||
|
|
||||||
|
void ToggleP8ACapsLock(void) { P8CAPS_ON = !P8CAPS_ON; }
|
||||||
|
|
||||||
|
BYTE SetCapsLockAllowed(BYTE value);
|
||||||
|
BYTE GetKeycode(BYTE floatingBus);
|
||||||
|
|
||||||
|
BYTE ConvertToKeycode(WPARAM key, BYTE keycode);
|
||||||
|
BYTE ConvertToPrinterChar(BYTE value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool g_CapsLockAllowed;
|
||||||
|
bool P8CAPS_ON;
|
||||||
|
bool P8Shift;
|
||||||
|
};
|
||||||
|
|
|
@ -466,7 +466,7 @@ static void Snapshot_LoadState_v2(void)
|
||||||
//m_ConfigNew.m_bEnableTheFreezesF8Rom = ?; // todo: when support saving config
|
//m_ConfigNew.m_bEnableTheFreezesF8Rom = ?; // todo: when support saving config
|
||||||
|
|
||||||
MemReset(); // Also calls CpuInitialize()
|
MemReset(); // Also calls CpuInitialize()
|
||||||
PravetsReset();
|
GetPravets().Reset();
|
||||||
|
|
||||||
if (GetCardMgr().IsSSCInstalled())
|
if (GetCardMgr().IsSSCInstalled())
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,8 +21,7 @@ along with AppleWin; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Description: This module is created for emulation of the 8bit character mode (mode 1) switch,
|
/* Description: Tape interface.
|
||||||
* which is located in $c060, and so far does not intend to emulate a tape device.
|
|
||||||
*
|
*
|
||||||
* Author: Various
|
* Author: Various
|
||||||
*
|
*
|
||||||
|
@ -31,78 +30,22 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "Core.h"
|
||||||
#include "Tape.h"
|
#include "Tape.h"
|
||||||
#include "Keyboard.h"
|
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "Pravets.h"
|
#include "Pravets.h"
|
||||||
|
|
||||||
static bool g_CapsLockAllowed = false;
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
BYTE __stdcall TapeRead(WORD, WORD address, BYTE, BYTE, ULONG nExecutedCycles)
|
BYTE __stdcall TapeRead(WORD, WORD address, BYTE, BYTE, ULONG nExecutedCycles) // $C060 TAPEIN
|
||||||
{
|
{
|
||||||
/*
|
if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
||||||
If retrieving KeybGetKeycode(); causes problems uCurrentKeystroke shall be added
|
return GetPravets().GetKeycode( MemReadFloatingBus(nExecutedCycles) );
|
||||||
in the submission variables and it shall be added by the TapeRead caller
|
|
||||||
i.e. BYTE __stdcall TapeRead (WORD, WORD address, BYTE, BYTE, ULONG nExecutedCycles) shall become
|
|
||||||
BYTE __stdcall TapeRead (WORD, WORD address, BYTE, BYTE, ULONG nExecutedCycles, BYTE uCurrentKeystroke)
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
|
||||||
{
|
|
||||||
const BYTE uCurrentKeystroke = KeybGetKeycode();
|
|
||||||
BYTE C060 = MemReadFloatingBus(nExecutedCycles);
|
|
||||||
|
|
||||||
if (g_CapsLockAllowed) //8bit keyboard mode
|
|
||||||
{
|
|
||||||
if (((P8CAPS_ON == false) && (P8Shift == false)) || ((P8CAPS_ON ) && (P8Shift ))) //LowerCase
|
|
||||||
{
|
|
||||||
if ((uCurrentKeystroke<65) //|| ((uCurrentKeystroke>90) && (uCurrentKeystroke<96))
|
|
||||||
|| ((uCurrentKeystroke>126) && (uCurrentKeystroke<193)))
|
|
||||||
C060 |= 1 << 7; //Sets bit 7 to 1 for special keys (arrows, return, etc) and for control+ key combinations.
|
|
||||||
else
|
|
||||||
C060 &= 127; //sets bit 7 to 0
|
|
||||||
}
|
|
||||||
else //UpperCase
|
|
||||||
{
|
|
||||||
C060 |= 1 << 7;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else //7bit keyboard mode
|
|
||||||
{
|
|
||||||
C060 &= 191; //Sets bit 6 to 0; I am not sure if this shall be done, because its value is disregarded in this case.
|
|
||||||
C060 |= 1 << 7; //Sets bit 7 to 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return C060;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MemReadFloatingBus(1, nExecutedCycles); // TAPEIN has high bit 1 when input is low or not connected (UTAIIe page 7-5, 7-6)
|
return MemReadFloatingBus(1, nExecutedCycles); // TAPEIN has high bit 1 when input is low or not connected (UTAIIe page 7-5, 7-6)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
BYTE __stdcall TapeWrite(WORD, WORD address, BYTE, BYTE, ULONG nExecutedCycles) // $C020 TAPEOUT
|
||||||
In case s.o. decides to develop tape device emulation, this function may be renamed,
|
|
||||||
because tape is not written in $C060
|
|
||||||
*/
|
|
||||||
BYTE __stdcall TapeWrite(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nExecutedCycles)
|
|
||||||
{
|
{
|
||||||
if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
return 0;
|
||||||
{
|
|
||||||
if (value & 1)
|
|
||||||
g_CapsLockAllowed = true;
|
|
||||||
else
|
|
||||||
g_CapsLockAllowed = false;
|
|
||||||
|
|
||||||
//If bit0 of the input byte is 0, it will forbid 8-bit characters (Default)
|
|
||||||
//If bit0 of the input byte is 1, it will allow 8-bit characters
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MemReadFloatingBus(nExecutedCycles);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetCapsLockAllowed(void)
|
|
||||||
{
|
|
||||||
return g_CapsLockAllowed;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
extern BYTE __stdcall TapeRead(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles);
|
BYTE __stdcall TapeRead(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles);
|
||||||
extern BYTE __stdcall TapeWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles);
|
BYTE __stdcall TapeWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles);
|
||||||
extern bool GetCapsLockAllowed(void);
|
|
||||||
|
|
|
@ -530,7 +530,7 @@ void ResetMachineState()
|
||||||
g_bFullSpeed = 0; // Might've hit reset in middle of InternalCpuExecute() - so beep may get (partially) muted
|
g_bFullSpeed = 0; // Might've hit reset in middle of InternalCpuExecute() - so beep may get (partially) muted
|
||||||
|
|
||||||
MemReset(); // calls CpuInitialize(), CNoSlotClock.Reset()
|
MemReset(); // calls CpuInitialize(), CNoSlotClock.Reset()
|
||||||
PravetsReset();
|
GetPravets().Reset();
|
||||||
if (GetCardMgr().QuerySlot(SLOT6) == CT_Disk2)
|
if (GetCardMgr().QuerySlot(SLOT6) == CT_Disk2)
|
||||||
dynamic_cast<Disk2InterfaceCard&>(GetCardMgr().GetRef(SLOT6)).Boot();
|
dynamic_cast<Disk2InterfaceCard&>(GetCardMgr().GetRef(SLOT6)).Boot();
|
||||||
GetVideo().VideoResetState();
|
GetVideo().VideoResetState();
|
||||||
|
@ -578,7 +578,7 @@ void CtrlReset()
|
||||||
MemAnnunciatorReset();
|
MemAnnunciatorReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
PravetsReset();
|
GetPravets().Reset();
|
||||||
GetCardMgr().GetDisk2CardMgr().Reset();
|
GetCardMgr().GetDisk2CardMgr().Reset();
|
||||||
HD_Reset();
|
HD_Reset();
|
||||||
KeybReset();
|
KeybReset();
|
||||||
|
|
|
@ -39,6 +39,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
#include "Windows/DirectInput.h"
|
#include "Windows/DirectInput.h"
|
||||||
#include "NTSC.h"
|
#include "NTSC.h"
|
||||||
#include "ParallelPrinter.h"
|
#include "ParallelPrinter.h"
|
||||||
|
#include "Pravets.h"
|
||||||
#include "Registry.h"
|
#include "Registry.h"
|
||||||
#include "SaveState.h"
|
#include "SaveState.h"
|
||||||
#include "SerialComms.h"
|
#include "SerialComms.h"
|
||||||
|
@ -739,7 +740,6 @@ void Win32Frame::DrawStatusArea (HDC passdc, int drawflags)
|
||||||
int x = buttonx;
|
int x = buttonx;
|
||||||
int y = buttony+BUTTONS*BUTTONCY+1;
|
int y = buttony+BUTTONS*BUTTONCY+1;
|
||||||
const bool bCaps = KeybGetCapsStatus();
|
const bool bCaps = KeybGetCapsStatus();
|
||||||
//const bool bP8Caps = KeybGetP8CapsStatus(); // TODO: FIXME: Not used ?! Should show the LED status ...
|
|
||||||
|
|
||||||
#if HD_LED
|
#if HD_LED
|
||||||
// 1.19.0.0 Hard Disk Status/Indicator Light
|
// 1.19.0.0 Hard Disk Status/Indicator Light
|
||||||
|
@ -1168,7 +1168,7 @@ LRESULT Win32Frame::WndProc(
|
||||||
}
|
}
|
||||||
else if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
else if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
||||||
{
|
{
|
||||||
KeybToggleP8ACapsLock (); // F10: Toggles Pravets8A Capslock
|
GetPravets().ToggleP8ACapsLock(); // F10: Toggles Pravets8A Capslock
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (wparam == VK_F11 && !KeybGetCtrlStatus()) // Save state (F11)
|
else if (wparam == VK_F11 && !KeybGetCtrlStatus()) // Save state (F11)
|
||||||
|
|
Loading…
Reference in New Issue