/* 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 Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski 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: main * * Author: Various */ /* Adaptation for SDL and POSIX (l) by beom beotiger, Nov-Dec 2007, krez beotiger March 2012 AD */ /* Linappple-pie was adapted in OCT 2015 for use with Retropie. By Mark Ormond. */ #include "stdafx.h" //#pragma hdrstop #include "MouseInterface.h" // for time logging #include #include #include #include #include #include #include //char VERSIONSTRING[] = "xx.yy.zz.ww"; TCHAR *g_pAppTitle = TITLE_APPLE_2E_ENHANCED; eApple2Type g_Apple2Type = A2TYPE_APPLE2EEHANCED; int opt; bool argdisks = false; bool argdisks2 = false; bool autoboot = false; bool fullscreenboot = false; bool disablecursor = false; BOOL behind = 0; // Redundant DWORD cumulativecycles = 0; // Wraps after ~1hr 9mins DWORD cyclenum = 0; // Used by SpkrToggle() for non-wave sound DWORD emulmsec = 0; static DWORD emulmsec_frac = 0; bool g_bFullSpeed = false; bool hddenabled = false; static bool g_uMouseInSlot4 = false; // not any mouse in slot4??--bb //char *MASTER_DISK="/opt/retropie/emulators/linapple/Master.dsk"; char *Disk1="blank.dsk"; char *Disk2="blank.dsk"; // Win32 //HINSTANCE g_hInstance = (HINSTANCE)0; AppMode_e g_nAppMode = MODE_LOGO; // Default screen sizes // SCREEN_WIDTH & SCREEN_HEIGHT defined in Frame.h UINT g_ScreenWidth = SCREEN_WIDTH; UINT g_ScreenHeight = SCREEN_HEIGHT; //static int lastmode = MODE_LOGO; -- not used??? DWORD needsprecision = 0; // Redundant //TCHAR g_sProgramDir[MAX_PATH] = TEXT(""); TCHAR g_sCurrentDir[MAX_PATH] = TEXT(""); // Also Starting Dir for Slot6 disk images?? --bb TCHAR g_sHDDDir[MAX_PATH] = TEXT(""); // starting dir for HDV (Apple][ HDD) images?? --bb TCHAR g_sSaveStateDir[MAX_PATH] = TEXT(""); // starting dir for states --bb TCHAR g_sParallelPrinterFile[MAX_PATH] = TEXT("Printer.txt"); // default file name for Parallel printer // FTP Variables TCHAR g_sFTPLocalDir[MAX_PATH] = TEXT(""); // FTP Local Dir, see linapple.conf for details TCHAR g_sFTPServer[MAX_PATH] = TEXT(""); // full path to default FTP server TCHAR g_sFTPServerHDD[MAX_PATH] = TEXT(""); // full path to default FTP server //TCHAR g_sFTPUser[256] = TEXT("anonymous"); // user name //TCHAR g_sFTPPass[256] = TEXT("mymail@hotmail.com"); // password TCHAR g_sFTPUserPass[512] = TEXT("anonymous:mymail@hotmail.com"); // full login line bool g_bResetTiming = false; // Redundant BOOL restart = 0; // several parameters affecting the speed of emulated CPU DWORD g_dwSpeed = SPEED_NORMAL; // Affected by Config dialog's speed slider bar double g_fCurrentCLK6502 = CLK_6502; // Affected by Config dialog's speed slider bar static double g_fMHz = 1.0; // Affected by Config dialog's speed slider bar int g_nCpuCyclesFeedback = 0; DWORD g_dwCyclesThisFrame = 0; FILE* g_fh = NULL; // file for logging, let's use stderr instead? bool g_bDisableDirectSound = false; // direct sound, use SDL Sound, or SDL_mixer??? CSuperSerialCard sg_SSC; CMouseInterface sg_Mouse; UINT g_Slot4 = CT_Mockingboard; // CT_Mockingboard or CT_MouseInterface CURL *g_curl = NULL; // global easy curl resourse //=========================================================================== // ???? what is DBG_CALC_FREQ??? O_O --bb #define DBG_CALC_FREQ 0 #if DBG_CALC_FREQ const UINT MAX_CNT = 256; double g_fDbg[MAX_CNT]; UINT g_nIdx = 0; double g_fMeanPeriod,g_fMeanFreq; ULONG g_nPerfFreq = 0; #endif //--------------------------------------------------------------------------- void ContinueExecution() { static BOOL pageflipping = 0; //? const double fUsecPerSec = 1.e6; const UINT nExecutionPeriodUsec = 1000; // 1.0ms const double fExecutionPeriodClks = g_fCurrentCLK6502 * ((double)nExecutionPeriodUsec / fUsecPerSec); bool bScrollLock_FullSpeed = g_bScrollLock_FullSpeed; //g_uScrollLockToggle; g_bFullSpeed = ( (g_dwSpeed == SPEED_MAX) || bScrollLock_FullSpeed || (DiskIsSpinning() && enhancedisk && !Spkr_IsActive() && !MB_IsActive()) ); if(g_bFullSpeed) { // Don't call Spkr_Mute() - will get speaker clicks MB_Mute(); SysClk_StopTimer(); g_nCpuCyclesFeedback = 0; // For the case when this is a big -ve number // SetPriorityNormal(); } else { // Don't call Spkr_Demute() MB_Demute(); SysClk_StartTimerUsec(nExecutionPeriodUsec); // Switch to higher priority, eg. for audio (BUG #015394) // SetPriorityAboveNormal(); } // int nCyclesToExecute = (int) fExecutionPeriodClks + g_nCpuCyclesFeedback; if(nCyclesToExecute < 0) nCyclesToExecute = 0; DWORD dwExecutedCycles = CpuExecute(nCyclesToExecute); g_dwCyclesThisFrame += dwExecutedCycles; // cyclenum = dwExecutedCycles; DiskUpdatePosition(dwExecutedCycles); JoyUpdatePosition(); // the next call does not present in current Applewin as on March 2012?? VideoUpdateVbl(g_dwCyclesThisFrame); SpkrUpdate(cyclenum); sg_SSC.CommUpdate(cyclenum); PrintUpdate(cyclenum); // const DWORD CLKS_PER_MS = (DWORD)g_fCurrentCLK6502 / 1000; emulmsec_frac += dwExecutedCycles; if(emulmsec_frac > CLKS_PER_MS) { emulmsec += emulmsec_frac / CLKS_PER_MS; emulmsec_frac %= CLKS_PER_MS; } // // DETERMINE WHETHER THE SCREEN WAS UPDATED, THE DISK WAS SPINNING, // OR THE KEYBOARD I/O PORTS WERE BEING EXCESSIVELY QUERIED THIS CLOCKTICK VideoCheckPage(0); BOOL screenupdated = VideoHasRefreshed(); BOOL systemidle = 0; //(KeybGetNumQueries() > (clockgran << 2)); // && (!ranfinegrain); // TO DO if(screenupdated) pageflipping = 3; // if(g_dwCyclesThisFrame >= dwClksPerFrame) { g_dwCyclesThisFrame -= dwClksPerFrame; if(g_nAppMode != MODE_LOGO) { VideoUpdateFlash(); static BOOL anyupdates = 0; static DWORD lastcycles = 0; static BOOL lastupdates[2] = {0,0}; anyupdates |= screenupdated; // lastcycles = cumulativecycles; if ((!anyupdates) && (!lastupdates[0]) && (!lastupdates[1]) && VideoApparentlyDirty()) { VideoCheckPage(1); static DWORD lasttime = 0; DWORD currtime = GetTickCount(); if ((!g_bFullSpeed) || (currtime-lasttime >= (DWORD)((graphicsmode || !systemidle) ? 100 : 25))) { VideoRefreshScreen(); lasttime = currtime; } screenupdated = 1; } lastupdates[1] = lastupdates[0]; lastupdates[0] = anyupdates; anyupdates = 0; if (pageflipping) pageflipping--; } MB_EndOfVideoFrame(); } // if(!g_bFullSpeed) { SysClk_WaitTimer(); #if DBG_CALC_FREQ if(g_nPerfFreq) { //QueryPerformanceCounter((LARGE_INTEGER*)&nTime1); QueryPerformanceFrequency LONG nTime1 = GetTickCount();//no QueryPerformanceCounter and alike LONG nTimeDiff = nTime1 - nTime0; double fTime = (double)nTimeDiff / (double)(LONG)g_nPerfFreq; g_fDbg[g_nIdx] = fTime; g_nIdx = (g_nIdx+1) & (MAX_CNT-1); g_fMeanPeriod = 0.0; for(UINT n=0; n= A2TYPE_MAX) dwComputerType = A2TYPE_APPLE2EEHANCED; g_Apple2Type = (eApple2Type) dwComputerType; } else {*/ LOAD(TEXT("Computer Emulation"),&dwComputerType); switch (dwComputerType) { // NB. No A2TYPE_APPLE2E case 0: g_Apple2Type = A2TYPE_APPLE2;break; case 1: g_Apple2Type = A2TYPE_APPLE2PLUS;break; case 2: g_Apple2Type = A2TYPE_APPLE2EEHANCED;break; default: g_Apple2Type = A2TYPE_APPLE2EEHANCED;break; } // } // determine Apple type and set appropriate caption -- should be in (F9)switching modes? switch (g_Apple2Type) { case A2TYPE_APPLE2: g_pAppTitle = TITLE_APPLE_2; break; case A2TYPE_APPLE2PLUS: g_pAppTitle = TITLE_APPLE_2_PLUS; break; case A2TYPE_APPLE2E: g_pAppTitle = TITLE_APPLE_2E; break; case A2TYPE_APPLE2EEHANCED: g_pAppTitle = TITLE_APPLE_2E_ENHANCED; break; } // Load Joystick values joytype[0] = 2; joytype[1] = 0; LOAD(TEXT("Joystick 0"),&joytype[0]); LOAD(TEXT("Joystick 1"),&joytype[1]); LOAD(TEXT("Joy0Index"),&joy1index); LOAD(TEXT("Joy1Index"),&joy2index); LOAD(TEXT("Joy0Button1"),&joy1button1); LOAD(TEXT("Joy0Button2"),&joy1button2); LOAD(TEXT("Joy1Button1"),&joy2button1); LOAD(TEXT("Joy0Axis0"),&joy1axis0); LOAD(TEXT("Joy0Axis1"),&joy1axis1); LOAD(TEXT("Joy1Axis0"),&joy2axis0); LOAD(TEXT("Joy1Axis1"),&joy2axis1); LOAD(TEXT("JoyExitEnable"),&joyexitenable); LOAD(TEXT("JoyExitButton0"),&joyexitbutton0); LOAD(TEXT("JoyExitButton1"),&joyexitbutton1); if (joytype[0]==1 ) printf ("Joystick 1 Index # = %i, Name = %s \nButton 1 = %i, Button 2 = %i \nAxis 0 = %i,Axis 1 = %i\n",joy1index,SDL_JoystickName(joy1index),joy1button1, joy1button2,joy1axis0,joy1axis1); if (joytype[1]==1 )printf ("Joystick 2 Index # = %i, Name = %s \nButton 1 = %i \nAxis 0 = %i,Axis 1 = %i\n",joy2index,SDL_JoystickName(joy2index),joy2button1,joy2axis0,joy2axis1); LOAD(TEXT("Sound Emulation") ,&soundtype); DWORD dwSerialPort; LOAD(TEXT("Serial Port") ,&dwSerialPort); sg_SSC.SetSerialPort(dwSerialPort); // ----------- why it is here???? LOAD(TEXT("Emulation Speed") ,&g_dwSpeed); LOAD(TEXT("Enhance Disk Speed"),(DWORD *)&enhancedisk);// LOAD(TEXT("Video Emulation") ,&videotype); // printf("Video Emulation = %d\n", videotype); DWORD dwTmp = 0; // temp var LOAD(TEXT("Fullscreen") ,&dwTmp); // load fullscreen flag fullscreen = (BOOL) dwTmp; if (fullscreenboot) fullscreen = true; LOAD(TEXT("DisableCursor") ,&dwTmp); // load Disable Cursor Flag disablecursor = (BOOL) dwTmp; dwTmp = 1; LOAD(TEXT(REGVALUE_SHOW_LEDS) ,&dwTmp); // load Show Leds flag g_ShowLeds = (BOOL) dwTmp; //printf("Fullscreen = %d\n", fullscreen); // LOAD(TEXT("Uthernet Active") ,(DWORD *)&tfe_enabled); SetCurrentCLK6502(); // set up real speed // if(LOAD(TEXT(REGVALUE_MOUSE_IN_SLOT4), &dwTmp)) g_uMouseInSlot4 = dwTmp; g_Slot4 = g_uMouseInSlot4 ? CT_MouseInterface : CT_Mockingboard; // if(LOAD(TEXT(REGVALUE_SPKR_VOLUME), &dwTmp)) // SpkrSetVolume(dwTmp, 100); // volume by default? // // if(LOAD(TEXT(REGVALUE_MB_VOLUME), &dwTmp)) // MB_SetVolume(dwTmp, 100); // volume by default?? --bb if(LOAD(TEXT(REGVALUE_SOUNDCARD_TYPE), &dwTmp)) MB_SetSoundcardType((eSOUNDCARDTYPE)dwTmp); if(LOAD(TEXT(REGVALUE_SAVE_STATE_ON_EXIT), &dwTmp)) g_bSaveStateOnExit = dwTmp ? true : false; if(LOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp)) hddenabled = (bool) dwTmp;// after MemInitialize // HD_SetEnabled(dwTmp ? true : false); // printf("g_bHD_Enabled = %d\n", g_bHD_Enabled); char *szHDFilename = NULL; if(RegLoadString(TEXT("Configuration"), TEXT("Monochrome Color"), 1, &szHDFilename, 10)) { if (!sscanf(szHDFilename, "#%X", &monochrome)) monochrome = 0xC0C0C0; free(szHDFilename); szHDFilename = NULL; } dwTmp = 0; LOAD(TEXT("Boot at Startup") ,&dwTmp); // if ((dwTmp) || (autoboot)) { // autostart SDL_Event user_ev; user_ev.type = SDL_USEREVENT; user_ev.user.code = 1; //restart? SDL_PushEvent(&user_ev); } dwTmp = 0; LOAD(TEXT("Slot 6 Autoload") ,&dwTmp); // load autoinsert for Slot 6 flag if(dwTmp &&!autoboot) { // Load floppy disk images and insert it automatically in slot 6 drive 1 and 2 if(RegLoadString(TEXT("Configuration"), TEXT(REGVALUE_DISK_IMAGE1), 1, &szHDFilename, MAX_PATH)) { DoDiskInsert(0, szHDFilename); free(szHDFilename); szHDFilename = NULL; } if(RegLoadString(TEXT("Configuration"), TEXT(REGVALUE_DISK_IMAGE2), 1, &szHDFilename, MAX_PATH)) { DoDiskInsert(1, szHDFilename); free(szHDFilename); szHDFilename = NULL; } } else { if (argdisks) { DoDiskInsert(0, Disk1); } else { const char* home = getenv("HOME"); std::string MASTER_DISKstr(home); MASTER_DISKstr += "/.linapple/Master.dsk"; const char * MasterDiskLocation = MASTER_DISKstr.c_str(); ifstream ifile2 (MasterDiskLocation); if (ifile2) { char *MasterDisk= new char[MASTER_DISKstr.length() + 1]; strcpy(MasterDisk, MASTER_DISKstr.c_str()); DoDiskInsert(0, MasterDisk); } else { char *MasterDisk = "Master.dsk"; DoDiskInsert(0, MasterDisk); } } if (argdisks2) DoDiskInsert(1, Disk2); } // Load hard disk images and insert it automatically in slot 7 if(RegLoadString(TEXT("Configuration"), TEXT(REGVALUE_HDD_IMAGE1), 1, &szHDFilename, MAX_PATH)) { // printf("LoadConfiguration: returned string is: %s\n", szHDFilename); HD_InsertDisk2(0, szHDFilename); free(szHDFilename); szHDFilename = NULL; } if(RegLoadString(TEXT("Configuration"), TEXT(REGVALUE_HDD_IMAGE2), 1, &szHDFilename, MAX_PATH)) { // printf("LoadConfiguration: returned string is: %s\n", szHDFilename); HD_InsertDisk2(1, szHDFilename); free(szHDFilename); szHDFilename = NULL; } // file name for Parallel Printer if(RegLoadString(TEXT("Configuration"), TEXT(REGVALUE_PPRINTER_FILENAME), 1, &szHDFilename, MAX_PATH)) { if(strlen(szHDFilename) > 1) strncpy(g_sParallelPrinterFile, szHDFilename, MAX_PATH); free(szHDFilename); szHDFilename = NULL; } // for joysticks use default Y-,X-trims // if(LOAD(TEXT(REGVALUE_PDL_XTRIM), &dwTmp)) // JoySetTrim((short)dwTmp, true); // if(LOAD(TEXT(REGVALUE_PDL_YTRIM), &dwTmp)) // JoySetTrim((short)dwTmp, false); // we do not use this, scroll lock ever toggling full-speed??? // if(LOAD(TEXT(REGVALUE_SCROLLLOCK_TOGGLE), &dwTmp)) // g_uScrollLockToggle = dwTmp; // char *szFilename = NULL; double scrFactor = 0.0; // Define screen sizes if (RegLoadString(TEXT("Configuration"),TEXT("Screen factor"),1, &szFilename,16)) { scrFactor = atof(szFilename); if(scrFactor > 0.1) { g_ScreenWidth = UINT(g_ScreenWidth * scrFactor); g_ScreenHeight = UINT(g_ScreenHeight * scrFactor); } free(szFilename); szFilename = NULL; } else { // Try to set Screen Width & Height directly dwTmp = 0; LOAD(TEXT("Screen Width") ,&dwTmp); if(dwTmp > 0) g_ScreenWidth = dwTmp; dwTmp = 0; LOAD(TEXT("Screen Height") ,&dwTmp); if(dwTmp > 0) g_ScreenHeight = dwTmp; } if (RegLoadString(TEXT("Configuration"),TEXT(REGVALUE_SAVESTATE_FILENAME),1, &szFilename,MAX_PATH)) { Snapshot_SetFilename(szFilename); // If not in Registry than default will be used free(szFilename); szFilename = NULL; } // Current/Starting Dir is the "root" of where the user keeps his disk images RegLoadString(TEXT("Preferences"), REGVALUE_PREF_START_DIR, 1, &szFilename, MAX_PATH); if (szFilename) { strcpy(g_sCurrentDir, szFilename); free(szFilename); szFilename = NULL; } // SetCurrentDirectory(g_sCurrentDir); if(strlen(g_sCurrentDir) == 0 || g_sCurrentDir[0] != '/') //something is wrong in dir name? {// char *tmp = getenv("HOME"); /* we don't have HOME? ^_^ 0_0 $_$ */ if(tmp == NULL) strcpy(g_sCurrentDir, "/"); //begin from the root, then else strcpy(g_sCurrentDir, tmp); } // Load starting directory for HDV (Apple][ HDD) images RegLoadString(TEXT("Preferences"), REGVALUE_PREF_HDD_START_DIR, 1, &szFilename, MAX_PATH); if (szFilename) { strcpy(g_sHDDDir, szFilename); free(szFilename); szFilename = NULL; } // SetCurrentDirectory(g_sCurrentDir); if(strlen(g_sHDDDir) == 0 || g_sHDDDir[0] != '/') //something is wrong in dir name? { char *tmp = getenv("HOME"); /* we don't have HOME? ^_^ 0_0 $_$ */ if(tmp == NULL) strcpy(g_sHDDDir, "/"); //begin from the root, then else strcpy(g_sHDDDir, tmp); } // Load starting directory for saving current states RegLoadString(TEXT("Preferences"), REGVALUE_PREF_SAVESTATE_DIR, 1, &szFilename, MAX_PATH); if (szFilename) { strcpy(g_sSaveStateDir, szFilename); free(szFilename); szFilename = NULL; } if(strlen(g_sSaveStateDir) == 0 || g_sSaveStateDir[0] != '/') //something is wrong in dir name? { char *tmp = getenv("HOME"); /* we don't have HOME? ^_^ 0_0 $_$ */ if(tmp == NULL) strcpy(g_sSaveStateDir, "/"); //begin from the root, then else strcpy(g_sSaveStateDir, tmp); } // Read and fill FTP variables - server, local dir, user name and password RegLoadString(TEXT("Preferences"), REGVALUE_FTP_DIR, 1, &szFilename, MAX_PATH); if (szFilename) { strcpy(g_sFTPServer, szFilename); free(szFilename); szFilename = NULL; } RegLoadString(TEXT("Preferences"), REGVALUE_FTP_HDD_DIR, 1, &szFilename, MAX_PATH); if (szFilename) { strcpy(g_sFTPServerHDD, szFilename); free(szFilename); szFilename = NULL; } RegLoadString(TEXT("Preferences"), REGVALUE_FTP_LOCAL_DIR, 1, &szFilename, MAX_PATH); if (szFilename) { strcpy(g_sFTPLocalDir, szFilename); free(szFilename); szFilename = NULL; } RegLoadString(TEXT("Preferences"), REGVALUE_FTP_USERPASS, 1, &szFilename, 512); if (szFilename) { strcpy(g_sFTPUserPass, szFilename); free(szFilename); szFilename = NULL; } // Print some debug strings printf("Ready login = %s\n",g_sFTPUserPass); // // ****By now we deal without Uthernet interface! --bb**** // char szUthernetInt[MAX_PATH] = {0}; // RegLoadString(TEXT("Configuration"),TEXT("Uthernet Interface"),1,szUthernetInt,MAX_PATH); // update_tfe_interface(szUthernetInt,NULL); } //=========================================================================== void RegisterExtensions () { // TO DO: register extensions for KDE or GNOME desktops?? Do not know, if it is sane idea. He-he. --bb // TCHAR szCommandTmp[MAX_PATH]; // GetModuleFileName((HMODULE)0,szCommandTmp,MAX_PATH); // // TCHAR command[MAX_PATH]; // wsprintf(command, "\"%s\"", szCommandTmp); // Wrap path & filename in quotes & null terminate // // TCHAR icon[MAX_PATH]; // wsprintf(icon,TEXT("%s,1"),(LPCTSTR)command); // // _tcscat(command,TEXT(" \"%1\"")); // Append "%1" // // RegSetValue(HKEY_CLASSES_ROOT,".bin",REG_SZ,"DiskImage",10); // RegSetValue(HKEY_CLASSES_ROOT,".do" ,REG_SZ,"DiskImage",10); // RegSetValue(HKEY_CLASSES_ROOT,".dsk",REG_SZ,"DiskImage",10); // RegSetValue(HKEY_CLASSES_ROOT,".nib",REG_SZ,"DiskImage",10); // RegSetValue(HKEY_CLASSES_ROOT,".po" ,REG_SZ,"DiskImage",10); // // RegSetValue(HKEY_CLASSES_ROOT,".aws",REG_SZ,"DiskImage",10); // TO DO // // RegSetValue(HKEY_CLASSES_ROOT,".hdv",REG_SZ,"DiskImage",10); // TO DO // // RegSetValue(HKEY_CLASSES_ROOT, // "DiskImage", // REG_SZ,"Disk Image",21); // // RegSetValue(HKEY_CLASSES_ROOT, // "DiskImage\\DefaultIcon", // REG_SZ,icon,_tcslen(icon)+1); // // RegSetValue(HKEY_CLASSES_ROOT, // "DiskImage\\shell\\open\\command", // REG_SZ,command,_tcslen(command)+1); // // RegSetValue(HKEY_CLASSES_ROOT, // "DiskImage\\shell\\open\\ddeexec", // REG_SZ,"%1",3); // // RegSetValue(HKEY_CLASSES_ROOT, // "DiskImage\\shell\\open\\ddeexec\\application", // REG_SZ,"applewin",9); // // RegSetValue(HKEY_CLASSES_ROOT, // "DiskImage\\shell\\open\\ddeexec\\topic", // REG_SZ,"system",7); } //=========================================================================== //LPSTR GetNextArg(LPSTR lpCmdLine) //{ // Sane idea: use getoptlong as command-line parameter preprocessor. Use it at your health. Ha. --bb /* int bInQuotes = 0; while(*lpCmdLine) { if(*lpCmdLine == '\"') { bInQuotes ^= 1; if(!bInQuotes) { *lpCmdLine++ = 0x00; // Assume end-quote is end of this arg continue; } } if((*lpCmdLine == ' ') && !bInQuotes) { *lpCmdLine++ = 0x00; break; } lpCmdLine++; } return lpCmdLine; */ //} //FILE *spMono, *spStereo; //--------------------------------------------------------------------------- int main(int argc, char * lpCmdLine[]) { // reading FullScreen and Boot from conf file? // bool bSetFullScreen = false; // bool bBoot = false; // // Find Home Directory and assign linapple.conf to ~/.linapple/linapple.conf // if not found set default name in current directory const char* home = getenv("HOME"); std::string linappleconfstr(home); linappleconfstr += "/.linapple/linapple.conf"; const char * linappleconf = linappleconfstr.c_str(); ifstream ifile (linappleconf); if (ifile) { registry = fopen(linappleconf , "a+t"); // open conf file (linapple.conf by default) } else { registry = fopen("linapple.conf" , "a+t"); // open conf file (linapple.conf by default) } // spMono = fopen("speakersmono.pcm","wb"); // spStereo = fopen("speakersstereo.pcm","wb"); // LPSTR szImageName_drive1 = NULL; // file names for images of drive1 and drive2 // LPSTR szImageName_drive2 = NULL; bool bBenchMark = false; // bool bBenchMark = (argc > 1 && // !strcmp(lpCmdLine[1],"-b")); // if we should start benchmark (-b in command line string) while ((opt = getopt (argc, lpCmdLine, "1:2:rbhf")) != -1) { switch (opt) { case '1': Disk1 = optarg; argdisks = true; break; case '2': Disk2 = optarg; argdisks2 = true; break; case 'r': autoboot = true; break; case 'b': bBenchMark = true; printf("benchmark"); break; case 'h': printf("Linapple command options..\n\n -h Show this help message\n -1 Mount disk image in first drive\n -2 Mount disk image in second drive\n -r Auto start emulation\n -b Benchmark and quit\n\n"); return 0; break; case 'f': fullscreenboot =true; break; } } // I will remake this using getopt and getoptlong! /* while(*lpCmdLine) { LPSTR lpNextArg = GetNextArg(lpCmdLine); if(strcmp(lpCmdLine, "-d1") == 0) { lpCmdLine = lpNextArg; lpNextArg = GetNextArg(lpCmdLine); szImageName_drive1 = lpCmdLine; if(*szImageName_drive1 == '\"') szImageName_drive1++; } else if(strcmp(lpCmdLine, "-d2") == 0) { lpCmdLine = lpNextArg; lpNextArg = GetNextArg(lpCmdLine); szImageName_drive2 = lpCmdLine; if(*szImageName_drive2 == '\"') szImageName_drive2++; } else if(strcmp(lpCmdLine, "-f") == 0) { bSetFullScreen = true; } else if((strcmp(lpCmdLine, "-l") == 0) && (g_fh == NULL)) { g_fh = fopen("AppleWin.log", "a+t"); // Open log file (append & text g_nAppMode) // Start of Unix(tm) specific code struct timeval tv; struct tm * ptm; char time_str[40]; gettimeofday(&tv, NULL); ptm = localtime(&tv.tvsec); strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", ptm); // end of Unix(tm) specific code fprintf(g_fh,"*** Logging started: %s\n",time_str); } else if(strcmp(lpCmdLine, "-m") == 0) { g_bDisableDirectSound = true; // without direct sound? U-u-u-u-uuuuuuuhhhhhhhhh --bb } #ifdef RAMWORKS else if(strcmp(lpCmdLine, "-r") == 0) // RamWorks size [1..127] { lpCmdLine = lpNextArg; lpNextArg = GetNextArg(lpCmdLine); g_uMaxExPages = atoi(lpCmdLine); if (g_uMaxExPages > 127) g_uMaxExPages = 128; else if (g_uMaxExPages < 1) g_uMaxExPages = 1; } #endif lpCmdLine = lpNextArg; } */ // What is it???? RIFF support for sound saving during emulation in RIFF format. // Currently not used? #if 0 #ifdef RIFF_SPKR RiffInitWriteFile("Spkr.wav", SPKR_SAMPLE_RATE, 1); #endif #ifdef RIFF_MB RiffInitWriteFile("Mockingboard.wav", 44100, 2); #endif #endif //----- // char szPath[_MAX_PATH]; // // if(0 == GetModuleFileName(NULL, szPath, sizeof(szPath))) // { // strcpy(szPath, __argv[0]); // } // Extract application version and store in a global variable // DWORD dwHandle, dwVerInfoSize; // // dwVerInfoSize = GetFileVersionInfoSize(szPath, &dwHandle); // // if(dwVerInfoSize > 0) // { // char* pVerInfoBlock = new char[dwVerInfoSize]; // // if(GetFileVersionInfo(szPath, NULL, dwVerInfoSize, pVerInfoBlock)) // { // VS_FIXEDFILEINFO* pFixedFileInfo; // UINT pFixedFileInfoLen; // // VerQueryValue(pVerInfoBlock, TEXT("\\"), (LPVOID*) &pFixedFileInfo, (PUINT) &pFixedFileInfoLen); // // // Construct version string from fixed file info block // // unsigned long major = pFixedFileInfo->dwFileVersionMS >> 16; // unsigned long minor = pFixedFileInfo->dwFileVersionMS & 0xffff; // unsigned long fix = pFixedFileInfo->dwFileVersionLS >> 16; // unsigned long fix_minor = pFixedFileInfo->dwFileVersionLS & 0xffff; // // sprintf(VERSIONSTRING, "%d.%d.%d.%d", major, minor, fix, fix_minor); // } // } #if DBG_CALC_FREQ //QueryPerformanceFrequency((LARGE_INTEGER*)&g_nPerfFreq); g_nPerfFreq = 1000;//milliseconds? if(g_fh) fprintf(g_fh, "Performance frequency = %d\n",g_nPerfFreq); #endif //----- // Initialize COM // . NB. DSInit() is done when g_hFrameWindow is created (WM_CREATE) if(InitSDL()) return 1; // init SDL subsystems, set icon // CoInitialize( NULL ); ------- what is it initializing?---------------------------------------- // CURL routines curl_global_init(CURL_GLOBAL_DEFAULT); g_curl = curl_easy_init(); if(!g_curl) { printf("Could not initialize CURL easy interface"); return 1; } /* Set user name and password to access FTP server */ curl_easy_setopt(g_curl, CURLOPT_USERPWD, g_sFTPUserPass); // // just do not see why we need this timer??? /*bool bSysClkOK =*/ SysClk_InitTimer(); // DO ONE-TIME INITIALIZATION // g_hInstance = passinstance; MemPreInitialize(); // Call before any of the slot devices are initialized // GdiSetBatchLimit(512); // GetProgramDirectory(); // RegisterExtensions(); // FrameRegisterClass(); ImageInitialize(); DiskInitialize(); CreateColorMixMap(); // For tv emulation g_nAppMode // int nError = 0; // if(szImageName_drive1) // { // nError = DoDiskInsert(0, szImageName_drive1); // bBoot = true; // } // if(szImageName_drive2) // { // nError |= DoDiskInsert(1, szImageName_drive2); // } // do { // DO INITIALIZATION THAT MUST BE REPEATED FOR A RESTART restart = 0; g_nAppMode = MODE_LOGO; fullscreen = false; LoadConfiguration(); FrameCreateWindow(); if (!DSInit()) soundtype = SOUND_NONE; // Direct Sound and Stuff MB_Initialize(); // Mocking board SpkrInitialize(); // Speakers - of Apple][ ...grrrrrrrrrrr, I love them!--bb DebugInitialize(); JoyInitialize(); MemInitialize(); HD_SetEnabled(hddenabled ? true : false); //printf("g_bHD_Enabled = %d\n", g_bHD_Enabled); VideoInitialize(); // if (!bSysClkOK) // { // MessageBox(g_hFrameWindow, "DirectX failed to create SystemClock instance", TEXT("AppleWin Error"), MB_OK); // PostMessage(g_hFrameWindow, WM_DESTROY, 0, 0); // Close everything down // } // tfe_init(); Snapshot_Startup(); // Do this after everything has been init'ed /* ------Will be fullscreened and booted later. I promise. --bb */ // if(bSetFullScreen) // { // PostMessage(g_hFrameWindow, WM_KEYDOWN, VK_F1+BTN_FULLSCR, 0); // PostMessage(g_hFrameWindow, WM_KEYUP, VK_F1+BTN_FULLSCR, 0); // bSetFullScreen = false; // } // // if(bBoot) // { // PostMessage(g_hFrameWindow, WM_KEYDOWN, VK_F1+BTN_RUN, 0); // PostMessage(g_hFrameWindow, WM_KEYUP, VK_F1+BTN_RUN, 0); // bBoot = false; // } JoyReset(); SetUsingCursor(0); if (disablecursor) SDL_ShowCursor(SDL_DISABLE); // trying fullscreen if (!fullscreen) SetNormalMode(); else SetFullScreenMode(); DrawFrameWindow(); // we do not have WM_PAINT? // ENTER THE MAIN MESSAGE LOOP if(bBenchMark) VideoBenchmark(); // start VideoBenchmark and exit else EnterMessageLoop(); // else we just start game // on WM_DESTROY event: Snapshot_Shutdown(); DebugDestroy(); // printf("Quitting. Snapshot_Shutdown-ed!\n"); if (!restart) { DiskDestroy(); ImageDestroy(); HD_Cleanup(); } // printf("Quitting. DiskDestroy, ImageDestroy and HD_Cleanup!\n"); PrintDestroy(); sg_SSC.CommDestroy(); CpuDestroy(); MemDestroy(); // printf("Quitting. PrintDestroy, sg_SSC.CommDestroy, CPU-MEMDestroy!\n"); SpkrDestroy(); // printf("Quitting. SpkrDestroy!!\n"); VideoDestroy(); // printf("Quitting. VideoDestroy!!\n"); MB_Destroy(); // printf("Quitting. MB_Destroy!\n"); // end of WM_DESTROY event MB_Reset(); // printf("Quitting. MB_Reset!\n"); sg_Mouse.Uninitialize(); // Maybe restarting due to switching slot-4 card from mouse to MB // printf("Quitting. Mouse.Uninitialize!!!\n"); JoyShutDown(); // close opened (if any) joysticks } while (restart); // Release COM DSUninit(); SysClk_UninitTimer(); // CoUninitialize();------------------------------- what is it uninitializing?-------------------------- // tfe_shutdown(); if(g_fh) { fprintf(g_fh,"*** Logging ended\n\n"); fclose(g_fh); } RiffFinishWriteFile(); fclose(registry); //close conf file (linapple.conf by default) // fclose(spMono); // fclose(spStereo); SDL_Quit(); // CURL routines curl_easy_cleanup(g_curl); curl_global_cleanup(); // printf("Linapple: successfully exited!\n"); return 0; }