From d85754fa6c0d26020bc45dd94c794b187e8867ea Mon Sep 17 00:00:00 2001 From: Wolfgang Thaller Date: Sat, 20 Sep 2014 02:18:58 +0200 Subject: [PATCH] Launcher: A utility program for mini vMac --- CMakeLists.txt | 1 + Launcher/CMakeLists.txt | 11 +++ Launcher/Launcher.c | 151 ++++++++++++++++++++++++++++++++++++++++ libretro/glue.c | 29 ++++++++ types.txt | 1 + 5 files changed, 193 insertions(+) create mode 100644 Launcher/CMakeLists.txt create mode 100644 Launcher/Launcher.c diff --git a/CMakeLists.txt b/CMakeLists.txt index b6deafc860..3a375c3a98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,7 @@ if(CMAKE_SYSTEM_NAME MATCHES Retro68) add_subdirectory(libretro) add_subdirectory(App2) add_subdirectory(Raytracer) +add_subdirectory(Launcher) else() add_subdirectory(MakeAPPL) add_subdirectory(ASFilter) diff --git a/Launcher/CMakeLists.txt b/Launcher/CMakeLists.txt new file mode 100644 index 0000000000..ca72ea0710 --- /dev/null +++ b/Launcher/CMakeLists.txt @@ -0,0 +1,11 @@ +set(CMAKE_C_FLAGS "-Wno-multichar") +add_executable(Launcher + Launcher.c + ) + +target_link_libraries(Launcher RetroConsole retrocrt) +add_custom_command( + OUTPUT Launcher.bin + COMMAND ${MAKE_APPL} -c Launcher -o Launcher + DEPENDS Launcher) +add_custom_target(LauncherAPPL ALL DEPENDS Launcher.bin) diff --git a/Launcher/Launcher.c b/Launcher/Launcher.c new file mode 100644 index 0000000000..e6a96191d1 --- /dev/null +++ b/Launcher/Launcher.c @@ -0,0 +1,151 @@ +/* + Copyright 2014 Wolfgang Thaller. + + This file is part of Retro68. + + Retro68 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 3 of the License, or + (at your option) any later version. + + Retro68 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 Retro68. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +#include + +void Explain() +{ + printf("*********************************************************\n"); + printf("This program is intended to make developing software\n"); + printf("using Retro68K and Mini vMac a little more convenient.\n"); + printf("\n"); + printf("If you insert a disk that contains a single application\n"); + printf("(= drag a disk image created by Retro68K to this window),\n"); + printf("the application will be automatically launched and the\n"); + printf("disk image unmounted again afterwards.\n"); + printf("\n"); + printf("It just saves a few repetitive clicks.\n"); + printf("*********************************************************\n"); +} + +void EjectOldDisk() +{ + Handle h = GetResource('LNCH', 128); + if(h) + { + short refNum = **(short**)h; + printf("Ejecting disk (refNum = %d)\n", refNum); + + Eject(NULL, refNum); + UnmountVol(NULL, refNum); + RemoveResource(h); + } +} + +int main() +{ + Explain(); + EjectOldDisk(); + printf("Insert a disk or hit any key to abort.\n"); + + FlushEvents(everyEvent, 0); + + for(;;) + { + EventRecord e; + GetNextEvent(everyEvent, &e); + + switch(e.what) + { + case keyDown: + return 0; + break; + + case diskEvt: + { + short refNum = LoWord(e.message); + short err = HiWord(e.message); + printf("Disk Inserted (refNum = %d, error = %d)\n", refNum, err); + if(err == 0) + { + { + Handle h = NewHandle(2); + **(short**)h = refNum; + AddResource(h, 'LNCH', 128, ""); + } + SetVol(NULL, refNum); + + CInfoPBRec cpb; + unsigned char name[257]; + int i, nApps = 0; + unsigned char bestName[257]; + for(i = 1;; i++) + { + memset(&cpb, 0, sizeof(cpb)); + cpb.dirInfo.ioVRefNum = refNum; + cpb.dirInfo.ioFDirIndex = i; + cpb.dirInfo.ioNamePtr = name; + err = PBGetCatInfoSync(&cpb); + + if(err != noErr) + break; + + name[name[0]+1] = 0; + if(cpb.hFileInfo.ioFlFndrInfo.fdType == 'APPL') + { + printf("Application: %s\n", &name[1]); + memcpy(bestName, name, sizeof(bestName)); + ++nApps; + } + } + + if(nApps == 0) + { + printf("No applications found on disk.\n"); + EjectOldDisk(); + } + else if(nApps > 1) + { + printf("Multiple applications found on disk.\n"); + EjectOldDisk(); + } + else + { + LaunchParamBlockRec lpb; + memset(&lpb, 0, sizeof(lpb)); + + lpb.reserved1 = (unsigned long) bestName; + lpb.reserved2 = 0; + lpb.launchBlockID = extendedBlock; + lpb.launchEPBLength = 6; + lpb.launchFileFlags = 0; + lpb.launchControlFlags = 0xC000; + + printf("Launching...\n"); + err = LaunchApplication(&lpb); + printf("Still here after launch (err = %d). Press Enter to exit.\n"); + getchar(); + return 0; + } + } + else + Eject(NULL, refNum); + } + break; + } + } + return 0; +} diff --git a/libretro/glue.c b/libretro/glue.c index f6ebabae7c..bfe51d95bd 100644 --- a/libretro/glue.c +++ b/libretro/glue.c @@ -18,6 +18,8 @@ */ #include +#include +#include Size GetPtrSize(Ptr ptr) { @@ -32,3 +34,30 @@ Size GetPtrSize(Ptr ptr) else return 0; } + +OSErr SetVol (ConstStr63Param volName, short vRefNum) +{ + ParamBlockRec pb; + memset(&pb, 0, sizeof(pb)); + pb.volumeParam.ioNamePtr = (StringPtr)volName; + pb.volumeParam.ioVRefNum = vRefNum; + return PBSetVolSync(&pb); +} + +OSErr UnmountVol (ConstStr63Param volName, short vRefNum) +{ + ParamBlockRec pb; + memset(&pb, 0, sizeof(pb)); + pb.volumeParam.ioNamePtr = (StringPtr)volName; + pb.volumeParam.ioVRefNum = vRefNum; + return PBUnmountVolImmed(&pb); +} + +OSErr Eject (ConstStr63Param volName, short vRefNum) +{ + ParamBlockRec pb; + memset(&pb, 0, sizeof(pb)); + pb.volumeParam.ioNamePtr = (StringPtr)volName; + pb.volumeParam.ioVRefNum = vRefNum; + return PBEject(&pb); +} diff --git a/types.txt b/types.txt index 7e74a06441..f2d20bdf03 100644 --- a/types.txt +++ b/types.txt @@ -1,6 +1,7 @@ L Size B Boolean P ConstStr255Param +P ConstStr63Param P Str255 W CharParameter W OSErr