diff --git a/toolbox/rm.cpp b/toolbox/rm.cpp index c6a4439..63120b8 100644 --- a/toolbox/rm.cpp +++ b/toolbox/rm.cpp @@ -2,7 +2,7 @@ #include //#include #include - +#include #include @@ -45,6 +45,9 @@ namespace // resource file and update that with the pointer. + std::map rhandle_map; + + inline uint16_t SetResError(uint16_t error) { memoryWriteWord(error, MacOS::ResErr); @@ -491,7 +494,121 @@ namespace RM return SetResError(::ResError()); } + // TODO -- update rhandle_map when loading resources + // TODO -- update rhandle_map when disposing resources. + uint16_t AddResource(uint16_t trap) + { + // PROCEDURE AddResource (theData: Handle; theType: ResType; + // theID: Integer; name: Str255); + + uint32_t theData; + uint32_t theType; + uint16_t theID; + uint32_t namePtr; + + + StackFrame<14>(theData, theType, theID, namePtr); + + std::string sname = ToolBox::ReadPString(namePtr, false); + + Log("%04x AddResource(%08x, %08x ('%s'), %04x, %s)\n", + trap, theData, theType, TypeToString(theType).c_str(), sname.c_str() + ); + + + Handle nativeHandle = NULL; + if (theData) + { + uint32_t handleSize; + MM::Native::GetHandleSize(theData, handleSize); + + if (handleSize) + { + + nativeHandle = ::NewHandle(handleSize); + if (!nativeHandle) return SetResError(MacOS::addResFailed); + + uint32_t src = memoryReadLong(theData); + + std::memcpy(*(uint8_t **)nativeHandle, memoryPointer(src), handleSize); + + rhandle_map.insert({theData, nativeHandle}); + } + } + // AddResource assumes ownership of the handle. + ::AddResource(nativeHandle, theType, theID, memoryPointer(namePtr)); + return SetResError(::ResError()); + } + + uint16_t SetResAttrs(uint16_t trap) + { + // PROCEDURE SetResAttrs (theResource: Handle; attrs: Integer); + + uint32_t theResource; + uint16_t attrs; + + StackFrame<6>(theResource, attrs); + + Log("%04x SetResAttrs(%08x, %04x)\n", trap, theResource, attrs); + + // find the native handle.. + + auto iter = rhandle_map.find(theResource); + if (iter == rhandle_map.end()) return SetResError(MacOS::resNotFound); + + Handle nativeHandle = iter->second; + + ::SetResAttrs(nativeHandle, attrs); + + return SetResError(::ResError()); + } + + + uint16_t WriteResource(uint16_t trap) + { + // PROCEDURE WriteResource (theResource: Handle); + + uint32_t theResource; + StackFrame<4>(theResource); + + Log("%04x WriteResource(%08x)\n", trap, theResource); + + + auto iter = rhandle_map.find(theResource); + if (iter == rhandle_map.end()) return SetResError(MacOS::resNotFound); + + Handle nativeHandle = iter->second; + + // todo -- need to verify handle size, re-copy handle memory? + ::WriteResource(nativeHandle); + + return SetResError(::ResError()); + } + + + + uint16_t DetachResource(uint16_t trap) + { + // PROCEDURE DetachResource (theResource: Handle); + + uint32_t theResource; + StackFrame<4>(theResource); + + Log("%04x DetachResource(%08x)\n", trap, theResource); + + + auto iter = rhandle_map.find(theResource); + if (iter == rhandle_map.end()) return SetResError(MacOS::resNotFound); + + Handle nativeHandle = iter->second; + + rhandle_map.erase(iter); + + ::ReleaseResource(nativeHandle); + + return SetResError(::ResError()); + } // todo -- move since it's not RM related. diff --git a/toolbox/rm.h b/toolbox/rm.h index 0053011..fbc8252 100644 --- a/toolbox/rm.h +++ b/toolbox/rm.h @@ -37,6 +37,10 @@ namespace RM uint16_t UpdateResFile(uint16_t trap); uint16_t GetResFileAttrs(uint16_t trap); uint16_t SetResFileAttrs(uint16_t trap); + uint16_t AddResource(uint16_t trap); + uint16_t SetResAttrs(uint16_t trap); + uint16_t WriteResource(uint16_t trap); + uint16_t DetachResource(uint16_t trap); } diff --git a/toolbox/toolbox.cpp b/toolbox/toolbox.cpp index 3a54474..10d7f50 100644 --- a/toolbox/toolbox.cpp +++ b/toolbox/toolbox.cpp @@ -284,6 +284,11 @@ namespace ToolBox { d0 = RM::Get1NamedResource(trap); break; + + case 0xa992: + d0 = RM::DetachResource(trap); + break; + case 0xa994: d0 = RM::CurResFile(trap); break; @@ -318,11 +323,23 @@ namespace ToolBox { d0 = RM::ReleaseResource(trap); break; + case 0xa9a7: + d0 = RM::SetResAttrs(trap); + break; + + case 0xa9ab: + d0 = RM::AddResource(trap); + break; + // ResError : INTEGER; case 0xa9af: d0 = RM::ResError(trap); break; + case 0xa9b0: + d0 = RM::WriteResource(trap); + break; + // CreateResFile(fileName: Str255); case 0xa9b1: d0 = RM::CreateResFile(trap);