2007-03-23 22:26:35 +00:00
/*
AppleWin : An Apple //e emulator for Windows
Copyright ( C ) 1994 - 1996 , Michael O ' Brien
Copyright ( C ) 1999 - 2001 , Oliver Schmidt
Copyright ( C ) 2002 - 2005 , Tom Charlesworth
2007-04-01 15:24:52 +00:00
Copyright ( C ) 2006 - 2007 , Tom Charlesworth , Michael Pohoreski , Nick Westgate
2007-03-23 22:26:35 +00:00
AppleWin 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 2 of the License , or
( at your option ) any later version .
AppleWin 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 AppleWin ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
/* Description: Parallel Printer Interface Card emulation
*
2009-01-17 15:10:00 +00:00
* Author : Nick Westgate , Stannev
2007-03-23 22:26:35 +00:00
*/
# include "StdAfx.h"
2014-08-13 20:30:35 +00:00
2020-11-11 21:15:27 +00:00
# include "ParallelPrinter.h"
2020-11-26 21:50:06 +00:00
# include "Core.h"
2014-08-13 20:30:35 +00:00
# include "Memory.h"
2021-01-17 10:48:06 +00:00
# include "Pravets.h"
2014-08-13 20:30:35 +00:00
# include "Registry.h"
2015-12-05 16:50:27 +00:00
# include "YamlHelper.h"
2021-01-19 20:37:43 +00:00
# include "Interface.h"
2014-08-13 20:30:35 +00:00
2018-02-24 15:12:40 +00:00
# include "../resource/resource.h"
2007-03-23 22:26:35 +00:00
static DWORD inactivity = 0 ;
2016-02-24 21:51:20 +00:00
static unsigned int g_PrinterIdleLimit = 10 ;
2007-03-23 22:26:35 +00:00
static FILE * file = NULL ;
2008-09-04 16:41:17 +00:00
DWORD const PRINTDRVR_SIZE = APPLE_SLOT_SIZE ;
2009-01-09 21:59:22 +00:00
# define DEFAULT_PRINT_FILENAME "Printer.txt"
2019-09-06 16:34:25 +00:00
static std : : string g_szPrintFilename ;
2009-01-09 21:59:22 +00:00
bool g_bDumpToPrinter = false ;
bool g_bConvertEncoding = true ;
bool g_bFilterUnprintable = true ;
bool g_bPrinterAppend = false ;
2009-01-17 15:10:00 +00:00
bool g_bEnableDumpToRealPrinter = false ;
2007-03-23 22:26:35 +00:00
//===========================================================================
2007-05-28 11:16:42 +00:00
static BYTE __stdcall PrintStatus ( WORD , WORD , BYTE , BYTE , ULONG ) ;
static BYTE __stdcall PrintTransmit ( WORD , WORD , BYTE , BYTE value , ULONG ) ;
2009-01-09 21:59:22 +00:00
2007-05-28 11:16:42 +00:00
VOID PrintLoadRom ( LPBYTE pCxRomPeripheral , const UINT uSlot )
2007-03-23 22:26:35 +00:00
{
2021-01-19 20:37:43 +00:00
BYTE * pData = GetFrame ( ) . GetResource ( IDR_PRINTDRVR_FW , " FIRMWARE " , PRINTDRVR_SIZE ) ;
2007-03-23 22:26:35 +00:00
if ( pData = = NULL )
return ;
2007-05-28 11:16:42 +00:00
memcpy ( pCxRomPeripheral + uSlot * 256 , pData , PRINTDRVR_SIZE ) ;
//
RegisterIoHandler ( uSlot , PrintStatus , PrintTransmit , NULL , NULL , NULL , NULL ) ;
2007-03-23 22:26:35 +00:00
}
//===========================================================================
static BOOL CheckPrint ( )
{
inactivity = 0 ;
if ( file = = NULL )
{
2009-01-09 21:59:22 +00:00
//TCHAR filepath[MAX_PATH * 2];
//_tcsncpy(filepath, g_sProgramDir, MAX_PATH);
//_tcsncat(filepath, _T("Printer.txt"), MAX_PATH);
//file = fopen(filepath, "wb");
if ( g_bPrinterAppend )
2019-09-06 16:34:25 +00:00
file = fopen ( Printer_GetFilename ( ) . c_str ( ) , " ab " ) ;
2009-01-09 21:59:22 +00:00
else
2019-09-06 16:34:25 +00:00
file = fopen ( Printer_GetFilename ( ) . c_str ( ) , " wb " ) ;
2007-03-23 22:26:35 +00:00
}
return ( file ! = NULL ) ;
}
//===========================================================================
static void ClosePrint ( )
{
if ( file ! = NULL )
{
fclose ( file ) ;
file = NULL ;
2014-08-13 20:30:35 +00:00
std : : string ExtendedFileName = " copy \" " ;
2009-01-09 21:59:22 +00:00
ExtendedFileName . append ( Printer_GetFilename ( ) ) ;
ExtendedFileName . append ( " \" prn " ) ;
//if (g_bDumpToPrinter) ShellExecute(NULL, "print", Printer_GetFilename(), NULL, NULL, 0); //Print through Notepad
if ( g_bDumpToPrinter )
system ( ExtendedFileName . c_str ( ) ) ; //Print through console. This is supposed to be the better way, because it shall print images (with older printers only).
2007-03-23 22:26:35 +00:00
}
2009-01-06 22:02:31 +00:00
inactivity = 0 ;
2007-03-23 22:26:35 +00:00
}
//===========================================================================
void PrintDestroy ( )
{
ClosePrint ( ) ;
}
//===========================================================================
void PrintUpdate ( DWORD totalcycles )
{
if ( file = = NULL )
{
return ;
}
2009-01-09 21:59:22 +00:00
// if ((inactivity += totalcycles) > (Printer_GetIdleLimit () * 1000 * 1000)) //This line seems to give a very big deviation
if ( ( inactivity + = totalcycles ) > ( Printer_GetIdleLimit ( ) * 710000 ) )
2007-03-23 22:26:35 +00:00
{
2009-01-09 21:59:22 +00:00
// inactive, so close the file (next print will overwrite or append to it, according to the settings made)
2007-03-23 22:26:35 +00:00
ClosePrint ( ) ;
}
}
//===========================================================================
void PrintReset ( )
{
ClosePrint ( ) ;
}
//===========================================================================
2007-05-28 11:16:42 +00:00
static BYTE __stdcall PrintStatus ( WORD , WORD , BYTE , BYTE , ULONG )
2007-03-23 22:26:35 +00:00
{
CheckPrint ( ) ;
return 0xFF ; // status - TODO?
}
//===========================================================================
2022-02-11 20:57:09 +00:00
static BYTE __stdcall PrintTransmit ( WORD , WORD address , BYTE , BYTE value , ULONG )
2007-03-23 22:26:35 +00:00
{
2020-10-11 16:14:03 +00:00
if ( ! CheckPrint ( ) )
2021-01-17 10:48:06 +00:00
return 0 ;
2022-02-11 20:57:09 +00:00
// only allow writes to the load output port (i.e., $C090)
if ( ( address & 0xF ) ! = 0 )
return 0 ;
2021-01-17 10:48:06 +00:00
BYTE c = value & 0x7F ;
if ( IsPravets ( GetApple2Type ( ) ) )
2020-10-11 16:14:03 +00:00
{
2021-01-17 10:48:06 +00:00
if ( g_bConvertEncoding )
c = GetPravets ( ) . ConvertToPrinterChar ( value ) ;
2020-10-11 16:14:03 +00:00
}
2021-01-17 10:48:06 +00:00
if ( ( g_bFilterUnprintable = = false ) | | ( c > 31 ) | | ( c = = 13 ) | | ( c = = 10 ) | | ( c > 0x7F ) ) //c>0x7F is needed for cyrillic characters
fwrite ( & c , 1 , 1 , file ) ;
2009-01-09 21:59:22 +00:00
return 0 ;
2007-03-23 22:26:35 +00:00
}
//===========================================================================
2009-01-09 21:59:22 +00:00
2019-09-06 16:34:25 +00:00
const std : : string & Printer_GetFilename ( )
2009-01-09 21:59:22 +00:00
{
return g_szPrintFilename ;
}
2019-09-06 16:34:25 +00:00
void Printer_SetFilename ( const std : : string & prtFilename )
2009-01-09 21:59:22 +00:00
{
2019-09-06 16:34:25 +00:00
if ( ! prtFilename . empty ( ) )
2018-08-12 11:48:08 +00:00
{
2019-09-06 16:34:25 +00:00
g_szPrintFilename = prtFilename ;
2018-08-12 11:48:08 +00:00
}
2009-01-09 21:59:22 +00:00
else //No registry entry is available
{
2019-09-06 16:34:25 +00:00
g_szPrintFilename = g_sProgramDir + DEFAULT_PRINT_FILENAME ;
2019-09-07 18:37:19 +00:00
RegSaveString ( REG_CONFIG , REGVALUE_PRINTER_FILENAME , 1 , g_szPrintFilename ) ;
2009-01-09 21:59:22 +00:00
}
}
unsigned int Printer_GetIdleLimit ( )
{
2016-02-24 21:51:20 +00:00
return g_PrinterIdleLimit ;
2009-01-09 21:59:22 +00:00
}
void Printer_SetIdleLimit ( unsigned int Duration )
{
2016-02-24 21:51:20 +00:00
g_PrinterIdleLimit = Duration ;
2009-01-09 21:59:22 +00:00
}
2015-02-13 22:40:53 +00:00
//===========================================================================
2015-12-05 16:50:27 +00:00
# define SS_YAML_VALUE_CARD_PRINTER "Generic Printer"
# define SS_YAML_KEY_INACTIVITY "Inactivity"
# define SS_YAML_KEY_IDLELIMIT "Printer Idle Limit"
# define SS_YAML_KEY_FILENAME "Print Filename"
# define SS_YAML_KEY_FILEOPEN "Is File Open"
# define SS_YAML_KEY_DUMPTOPRINTER "Dump To Printer"
# define SS_YAML_KEY_CONVERTENCODING "Convert Encoding"
# define SS_YAML_KEY_FILTERUNPRINTABLE "Filter Unprintable"
# define SS_YAML_KEY_APPEND "Printer Append"
# define SS_YAML_KEY_DUMPTOREALPRINTER "Enable Dump To Real Printer"
std : : string Printer_GetSnapshotCardName ( void )
{
static const std : : string name ( SS_YAML_VALUE_CARD_PRINTER ) ;
return name ;
}
2021-11-25 20:23:21 +00:00
void Printer_SaveSnapshot ( class YamlSaveHelper & yamlSaveHelper , const UINT uSlot )
2015-12-05 16:50:27 +00:00
{
2021-11-25 20:23:21 +00:00
YamlSaveHelper : : Slot slot ( yamlSaveHelper , Printer_GetSnapshotCardName ( ) , uSlot , 1 ) ;
2015-12-05 16:50:27 +00:00
YamlSaveHelper : : Label state ( yamlSaveHelper , " %s: \n " , SS_YAML_KEY_STATE ) ;
2016-02-24 21:51:20 +00:00
yamlSaveHelper . SaveUint ( SS_YAML_KEY_INACTIVITY , inactivity ) ;
yamlSaveHelper . SaveUint ( SS_YAML_KEY_IDLELIMIT , g_PrinterIdleLimit ) ;
yamlSaveHelper . SaveString ( SS_YAML_KEY_FILENAME , g_szPrintFilename ) ;
2016-03-01 22:31:17 +00:00
yamlSaveHelper . SaveBool ( SS_YAML_KEY_FILEOPEN , ( file ! = NULL ) ? true : false ) ;
2016-02-24 21:51:20 +00:00
yamlSaveHelper . SaveBool ( SS_YAML_KEY_DUMPTOPRINTER , g_bDumpToPrinter ) ;
yamlSaveHelper . SaveBool ( SS_YAML_KEY_CONVERTENCODING , g_bConvertEncoding ) ;
yamlSaveHelper . SaveBool ( SS_YAML_KEY_FILTERUNPRINTABLE , g_bFilterUnprintable ) ;
yamlSaveHelper . SaveBool ( SS_YAML_KEY_APPEND , g_bPrinterAppend ) ;
yamlSaveHelper . SaveBool ( SS_YAML_KEY_DUMPTOREALPRINTER , g_bEnableDumpToRealPrinter ) ;
2015-12-05 16:50:27 +00:00
}
bool Printer_LoadSnapshot ( class YamlLoadHelper & yamlLoadHelper , UINT slot , UINT version )
{
if ( slot ! = 1 ) // fixme
2022-01-30 21:25:40 +00:00
Card : : ThrowErrorInvalidSlot ( CT_GenericPrinter , slot ) ;
2015-12-05 16:50:27 +00:00
if ( version ! = 1 )
2022-01-30 21:25:40 +00:00
Card : : ThrowErrorInvalidVersion ( CT_GenericPrinter , version ) ;
2015-12-05 16:50:27 +00:00
2016-02-24 22:38:59 +00:00
inactivity = yamlLoadHelper . LoadUint ( SS_YAML_KEY_INACTIVITY ) ;
g_PrinterIdleLimit = yamlLoadHelper . LoadUint ( SS_YAML_KEY_IDLELIMIT ) ;
2019-09-06 16:34:25 +00:00
g_szPrintFilename = yamlLoadHelper . LoadString ( SS_YAML_KEY_FILENAME ) ;
2015-12-05 16:50:27 +00:00
2016-02-24 22:38:59 +00:00
if ( yamlLoadHelper . LoadBool ( SS_YAML_KEY_FILEOPEN ) )
2015-12-05 16:50:27 +00:00
{
2016-02-24 22:38:59 +00:00
yamlLoadHelper . LoadBool ( SS_YAML_KEY_APPEND ) ; // Consume
2015-12-05 16:50:27 +00:00
g_bPrinterAppend = true ; // Re-open print-file in append mode
BOOL bRes = CheckPrint ( ) ;
if ( ! bRes )
2021-12-18 16:37:28 +00:00
throw std : : runtime_error ( " Printer Card: Unable to resume printing to file " ) ;
2015-12-05 16:50:27 +00:00
}
else
{
2016-02-24 22:38:59 +00:00
g_bPrinterAppend = yamlLoadHelper . LoadBool ( SS_YAML_KEY_APPEND ) ;
2015-12-05 16:50:27 +00:00
}
2016-02-24 22:38:59 +00:00
g_bDumpToPrinter = yamlLoadHelper . LoadBool ( SS_YAML_KEY_DUMPTOPRINTER ) ;
g_bConvertEncoding = yamlLoadHelper . LoadBool ( SS_YAML_KEY_CONVERTENCODING ) ;
g_bFilterUnprintable = yamlLoadHelper . LoadBool ( SS_YAML_KEY_FILTERUNPRINTABLE ) ;
g_bEnableDumpToRealPrinter = yamlLoadHelper . LoadBool ( SS_YAML_KEY_DUMPTOREALPRINTER ) ;
2015-12-05 16:50:27 +00:00
return true ;
}