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
# include "AppleWin.h"
# include "Memory.h"
# include "ParallelPrinter.h"
# include "Registry.h"
2015-12-05 16:50:27 +00:00
# include "YamlHelper.h"
2014-08-13 20:30:35 +00:00
2007-03-23 22:26:35 +00:00
# include "..\resource\resource.h"
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"
static char g_szPrintFilename [ MAX_PATH ] = { 0 } ;
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
2015-02-13 22:40:53 +00:00
static UINT g_uSlot = 0 ;
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
{
2007-05-28 11:16:42 +00:00
HRSRC hResInfo = FindResource ( NULL , MAKEINTRESOURCE ( IDR_PRINTDRVR_FW ) , " FIRMWARE " ) ;
2007-03-23 22:26:35 +00:00
if ( hResInfo = = NULL )
return ;
DWORD dwResSize = SizeofResource ( NULL , hResInfo ) ;
if ( dwResSize ! = PRINTDRVR_SIZE )
return ;
HGLOBAL hResData = LoadResource ( NULL , hResInfo ) ;
if ( hResData = = NULL )
return ;
BYTE * pData = ( BYTE * ) LockResource ( hResData ) ; // NB. Don't need to unlock resource
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 ) ;
2015-02-13 22:40:53 +00:00
g_uSlot = uSlot ;
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 )
file = fopen ( Printer_GetFilename ( ) , " ab " ) ;
else
file = fopen ( Printer_GetFilename ( ) , " 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?
}
//===========================================================================
2007-05-28 11:16:42 +00:00
static BYTE __stdcall PrintTransmit ( WORD , WORD , BYTE , BYTE value , ULONG )
2007-03-23 22:26:35 +00:00
{
2009-01-09 21:59:22 +00:00
char Lat8A [ ] = " abwgdevzijklmnoprstufhc~{}yx`q|] " ;
char Lat82 [ ] = " abwgdevzijklmnoprstufhc^[]yx@q{}~` " ;
char Kir82 [ ] = " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> []^@" ;
char Kir8ACapital [ ] = " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ;
char Kir8ALowerCase [ ] = " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ;
bool Pres = false ;
2007-03-23 22:26:35 +00:00
if ( ! CheckPrint ( ) )
{
return 0 ;
}
2009-01-09 21:59:22 +00:00
char c = NULL ;
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.
{
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 ;
2007-03-23 22:26:35 +00:00
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
char * Printer_GetFilename ( )
{
return g_szPrintFilename ;
}
void Printer_SetFilename ( char * prtFilename )
{
if ( * prtFilename )
strcpy ( g_szPrintFilename , ( const char * ) prtFilename ) ;
else //No registry entry is available
{
_tcsncpy ( g_szPrintFilename , g_sProgramDir , MAX_PATH ) ;
_tcsncat ( g_szPrintFilename , _T ( DEFAULT_PRINT_FILENAME ) , MAX_PATH ) ;
RegSaveString ( TEXT ( " Configuration " ) , REGVALUE_PRINTER_FILENAME , 1 , g_szPrintFilename ) ;
}
}
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 ;
}
void Printer_SaveSnapshot ( class YamlSaveHelper & yamlSaveHelper )
{
YamlSaveHelper : : Slot slot ( yamlSaveHelper , Printer_GetSnapshotCardName ( ) , g_uSlot , 1 ) ;
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
throw std : : string ( " Card: wrong slot " ) ;
if ( version ! = 1 )
throw std : : string ( " Card: wrong version " ) ;
2016-02-24 22:38:59 +00:00
inactivity = yamlLoadHelper . LoadUint ( SS_YAML_KEY_INACTIVITY ) ;
g_PrinterIdleLimit = yamlLoadHelper . LoadUint ( SS_YAML_KEY_IDLELIMIT ) ;
strncpy ( g_szPrintFilename , yamlLoadHelper . LoadString ( SS_YAML_KEY_FILENAME ) . c_str ( ) , sizeof ( g_szPrintFilename ) ) ;
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 )
throw std : : string ( " Printer Card: Unable to resume printing to file " ) ;
}
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 ;
}