Save, SaveAs

This commit is contained in:
tudnai 2020-06-25 19:52:23 -07:00
parent 5374c8f035
commit 73078e1a9e
5 changed files with 155 additions and 44 deletions

View File

@ -26,6 +26,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
if let menuIdentifier = sender.identifier { if let menuIdentifier = sender.identifier {
let woz_err = woz_loadFile( Bundle.main.resourcePath! + "/dsk/" + menuIdentifier.rawValue + ".woz" ) let woz_err = woz_loadFile( Bundle.main.resourcePath! + "/dsk/" + menuIdentifier.rawValue + ".woz" )
ViewController.current?.chk_woz_load(err: woz_err) ViewController.current?.chk_woz_load(err: woz_err)
woz_flags.image_file_readonly = 1
} }
} }
@ -49,14 +50,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
} }
@IBAction func saveFile(_ sender: NSMenuItem) { @IBAction func saveFile(_ sender: NSMenuItem) {
ViewController.current?.saveFile()
}
let savePanel = NSSavePanel() @IBAction func saveFileAs(_ sender: NSMenuItem) {
savePanel.begin { (result) in ViewController.current?.saveFileAs()
if result.rawValue == NSApplication.ModalResponse.OK.rawValue {
woz_saveFile( savePanel.url?.path );
}
}
} }
@IBAction func showPreferences(_ sender: NSMenuItem) { @IBAction func showPreferences(_ sender: NSMenuItem) {

View File

@ -87,11 +87,16 @@
</items> </items>
</menu> </menu>
</menuItem> </menuItem>
<menuItem title="Save" keyEquivalent="s" id="ekf-mq-Seg"> <menuItem title="Save" keyEquivalent="s" id="ekf-mq-Seg">
<connections> <connections>
<action selector="saveFile:" target="Voe-Tx-rLC" id="ACK-sm-LSp"/> <action selector="saveFile:" target="Voe-Tx-rLC" id="ACK-sm-LSp"/>
</connections> </connections>
</menuItem> </menuItem>
<menuItem title="Save As…" keyEquivalent="S" id="6Lm-1R-Xv0">
<connections>
<action selector="saveFileAs:" target="Voe-Tx-rLC" id="KbC-Ol-j6f"/>
</connections>
</menuItem>
<menuItem title="Eject" keyEquivalent="e" id="DVo-aG-piG"> <menuItem title="Eject" keyEquivalent="e" id="DVo-aG-piG">
<connections> <connections>
<action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/> <action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>

View File

@ -913,6 +913,7 @@ class ViewController: NSViewController {
let woz_err = woz_loadFile( Bundle.main.resourcePath! + "/dsk/Apple DOS 3.3 January 1983.woz" ) let woz_err = woz_loadFile( Bundle.main.resourcePath! + "/dsk/Apple DOS 3.3 January 1983.woz" )
chk_woz_load(err: woz_err) chk_woz_load(err: woz_err)
woz_flags.image_file_readonly = 1
//view.frame = CGRect(origin: CGPoint(), size: NSScreen.main!.visibleFrame.size) //view.frame = CGRect(origin: CGPoint(), size: NSScreen.main!.visibleFrame.size)
@ -1133,7 +1134,38 @@ class ViewController: NSViewController {
@objc func openDiskImage() { @objc func openDiskImage() {
let openPanel = NSOpenPanel() let openPanel = NSOpenPanel()
openPanel.title = "Disk Image" openPanel.title = "Open Disk Image"
openPanel.allowsMultipleSelection = false
openPanel.canChooseDirectories = false
openPanel.canCreateDirectories = false
openPanel.canChooseFiles = true
openPanel.allowedFileTypes = ["dsk","do","po","nib", "woz"]
openPanel.begin { (result) -> Void in
if result == NSApplication.ModalResponse.OK {
print("file:", openPanel.url!.path)
//Do what you will
//If there's only one URL, surely 'openPanel.URL'
//but otherwise a for loop works
if let filePath = openPanel.url?.path {
let woz_err = woz_loadFile( filePath )
if woz_err == WOZ_ERR_OK {
NSDocumentController.shared.noteNewRecentDocumentURL(URL(fileURLWithPath: filePath))
}
else {
self.chk_woz_load(err: woz_err)
}
}
}
}
}
@objc func saveDiskImage() {
let openPanel = NSOpenPanel()
openPanel.title = "Save Disk Image"
openPanel.allowsMultipleSelection = false openPanel.allowsMultipleSelection = false
openPanel.canChooseDirectories = false openPanel.canChooseDirectories = false
openPanel.canCreateDirectories = false openPanel.canCreateDirectories = false
@ -1178,5 +1210,48 @@ class ViewController: NSViewController {
} }
} }
func saveFile() {
if ( woz_flags.image_file_readonly != 0 ) {
// it is readonly, save it to a different file...
saveFileAs()
}
else {
// save WOZ image file overwriting the original image
woz_saveFile(nil)
}
}
func saveFileAs() {
let savePanel = NSSavePanel()
savePanel.title = "Save WOZ Disk Image As..."
savePanel.begin { (result) in
if result.rawValue == NSApplication.ModalResponse.OK.rawValue {
woz_saveFile( savePanel.url?.path );
}
else {
let a = NSAlert()
a.messageText = "Are you sure?"
a.informativeText = "Are you sure you would like to cancel and lose all modification you have made to the Disk Image?\nALERT: You will lose all new files and modified files from this Disk Image since you loaded. Your decision if permanent and irreversible!"
a.addButton(withTitle: "Save")
a.addButton(withTitle: "Cancel")
a.alertStyle = .warning
a.beginSheetModal(for: self.view.window!, completionHandler: { (modalResponse) -> Void in
if modalResponse == .alertFirstButtonReturn {
self.saveFileAs()
}
})
}
}
}
}
@_cdecl("woz_ask_to_save")
func woz_ask_to_save() {
ViewController.current?.saveFile()
} }

View File

@ -25,6 +25,8 @@ int bitOffset = 0;
uint64_t clkelpased; uint64_t clkelpased;
char woz_filename[MAXFILENAME];
woz_flags_t woz_flags = {0,0,0,0};
size_t woz_file_size = 0; size_t woz_file_size = 0;
uint8_t * woz_file_buffer = NULL; uint8_t * woz_file_buffer = NULL;
woz_header_t * woz_header; woz_header_t * woz_header;
@ -368,6 +370,8 @@ void woz_write( uint8_t data ) {
return; return;
} }
woz_flags.disk_modified = 1;
clkelpased = m6502.clktime + clkfrm - m6502.clklast; clkelpased = m6502.clktime + clkfrm - m6502.clklast;
m6502.clklast = m6502.clktime + clkfrm; m6502.clklast = m6502.clktime + clkfrm;
@ -464,6 +468,17 @@ void woz_write( uint8_t data ) {
} }
void woz_free_buffer() {
if ( woz_file_buffer ) {
free(woz_file_buffer);
woz_file_buffer = NULL;
woz_header = NULL;
woz_tmap = NULL;
woz_trks = NULL;
}
}
int woz_loadFile( const char * filename ) { int woz_loadFile( const char * filename ) {
// char fullpath[256]; // char fullpath[256];
@ -478,15 +493,17 @@ int woz_loadFile( const char * filename ) {
return WOZ_ERR_FILE_NOT_FOUND; return WOZ_ERR_FILE_NOT_FOUND;
} }
woz_eject();
// get file size // get file size
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
woz_file_size = ftell(f); woz_file_size = ftell(f);
fseek(f, 0, SEEK_SET); fseek(f, 0, SEEK_SET);
if ( woz_file_buffer ) { woz_flags.disk_modified = 0;
free(woz_file_buffer); woz_flags.disk_write_protected = 0;
woz_file_buffer = NULL; woz_flags.image_file_readonly = 0;
} woz_flags.image_loaded = 1;
woz_file_buffer = malloc(woz_file_size); woz_file_buffer = malloc(woz_file_size);
if (woz_file_buffer == NULL) { if (woz_file_buffer == NULL) {
@ -501,8 +518,7 @@ int woz_loadFile( const char * filename ) {
fread( woz_file_buffer, woz_file_size, 1, f); fread( woz_file_buffer, woz_file_size, 1, f);
fclose(f); fclose(f);
if ( woz_header->magic != WOZ1_MAGIC ) { if ( woz_header->magic != WOZ1_MAGIC ) {
free(woz_file_buffer); woz_free_buffer();
woz_file_buffer = NULL;
return WOZ_ERR_NOT_WOZ_FILE; return WOZ_ERR_NOT_WOZ_FILE;
} }
@ -511,7 +527,7 @@ int woz_loadFile( const char * filename ) {
while ( bufOffs < woz_file_size ) { while ( bufOffs < woz_file_size ) {
// beginning of the chunk, so we can skip it later // beginning of the chunk, so we can skip it later
woz_chunk_header = (woz_chunk_header_t*)(woz_file_buffer + bufOffs); woz_chunk_header = (woz_chunk_header_t*) &woz_file_buffer[bufOffs];
bufOffs += sizeof(woz_chunk_header_t); bufOffs += sizeof(woz_chunk_header_t);
@ -520,11 +536,11 @@ int woz_loadFile( const char * filename ) {
break; break;
case WOZ_TMAP_CHUNK_ID: case WOZ_TMAP_CHUNK_ID:
woz_tmap = (woz_tmap_t*)(woz_file_buffer + bufOffs); woz_tmap = (woz_tmap_t*) &woz_file_buffer[bufOffs];
break; break;
case WOZ_TRKS_CHUNK_ID: case WOZ_TRKS_CHUNK_ID:
woz_trks = (woz_trks_t*)(woz_file_buffer + bufOffs); woz_trks = (woz_trks_t*) &woz_file_buffer[bufOffs];
break; break;
case WOZ_META_CHUNK_ID: case WOZ_META_CHUNK_ID:
@ -546,8 +562,32 @@ int woz_loadFile( const char * filename ) {
return WOZ_ERR_OK; return WOZ_ERR_OK;
} }
void woz_ask_to_save(void);
void woz_eject() {
if ( woz_flags.disk_modified ) {
woz_ask_to_save();
}
woz_flags.disk_modified = 0;
woz_flags.disk_write_protected = 0;
woz_flags.image_file_readonly = 0;
woz_flags.image_loaded = 0;
woz_file_size = 0;
woz_free_buffer();
}
int woz_saveFile( const char * filename ) { int woz_saveFile( const char * filename ) {
if ( filename == NULL ) {
filename = woz_filename;
}
FILE * f = fopen( filename, "wb" ); FILE * f = fopen( filename, "wb" );
if (f == NULL) { if (f == NULL) {
perror("Failed to crete WOZ: "); perror("Failed to crete WOZ: ");
@ -557,6 +597,8 @@ int woz_saveFile( const char * filename ) {
fwrite( woz_file_buffer, woz_file_size, 1, f ); fwrite( woz_file_buffer, woz_file_size, 1, f );
fclose(f); fclose(f);
woz_flags.disk_modified = 0;
return WOZ_ERR_OK; return WOZ_ERR_OK;
} }

View File

@ -13,6 +13,8 @@
#include "common.h" #include "common.h"
#define MAXFILENAME 4096
#define DISKII_MAXTRACKS 80 #define DISKII_MAXTRACKS 80
#define DISKII_PHASES 4 #define DISKII_PHASES 4
@ -81,26 +83,6 @@ typedef woz_track_t woz_trks_t[DISKII_MAXTRACKS];
#define __NO__WOZ_REAL_SPIN2
#ifdef WOZ_REAL_SPIN
typedef union {
struct {
uint8_t next;
uint8_t data;
uint8_t prev;
uint8_t shift;
};
struct {
uint32_t lower : 31;
uint32_t valid : 1;
};
uint32_t shift32;
} WOZread_t;
#else // WOZ_REAL_SPIN
typedef union { typedef union {
struct { struct {
uint8_t data; uint8_t data;
@ -116,11 +98,19 @@ typedef union {
uint64_t shift; uint64_t shift;
} WOZread_t; } WOZread_t;
#endif // WOZ_REAL_SPIN
typedef struct woz_flags_s {
uint8_t image_loaded : 1;
uint8_t image_file_readonly : 1;
uint8_t disk_write_protected : 1;
uint8_t disk_modified : 1;
} woz_flags_t;
extern WOZread_t WOZread; extern WOZread_t WOZread;
extern uint8_t WOZlatch; extern uint8_t WOZlatch;
extern char woz_filename[MAXFILENAME];
extern woz_flags_t woz_flags;
//extern woz_header_t woz_header; //extern woz_header_t woz_header;
//extern woz_chunk_header_t woz_chunk_header; //extern woz_chunk_header_t woz_chunk_header;
@ -132,5 +122,6 @@ extern uint8_t woz_read(void);
extern void woz_write( uint8_t data ); extern void woz_write( uint8_t data );
extern int woz_loadFile( const char * filename ); extern int woz_loadFile( const char * filename );
extern int woz_saveFile( const char * filename ); extern int woz_saveFile( const char * filename );
extern void woz_eject(void);
#endif /* woz_h */ #endif /* woz_h */