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 {
let woz_err = woz_loadFile( Bundle.main.resourcePath! + "/dsk/" + menuIdentifier.rawValue + ".woz" )
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) {
let savePanel = NSSavePanel()
savePanel.begin { (result) in
if result.rawValue == NSApplication.ModalResponse.OK.rawValue {
woz_saveFile( savePanel.url?.path );
}
}
ViewController.current?.saveFile()
}
@IBAction func saveFileAs(_ sender: NSMenuItem) {
ViewController.current?.saveFileAs()
}
@IBAction func showPreferences(_ sender: NSMenuItem) {

View File

@ -87,11 +87,16 @@
</items>
</menu>
</menuItem>
<menuItem title="Save" keyEquivalent="s" id="ekf-mq-Seg">
<menuItem title="Save" keyEquivalent="s" id="ekf-mq-Seg">
<connections>
<action selector="saveFile:" target="Voe-Tx-rLC" id="ACK-sm-LSp"/>
</connections>
</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">
<connections>
<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" )
chk_woz_load(err: woz_err)
woz_flags.image_file_readonly = 1
//view.frame = CGRect(origin: CGPoint(), size: NSScreen.main!.visibleFrame.size)
@ -1133,7 +1134,7 @@ class ViewController: NSViewController {
@objc func openDiskImage() {
let openPanel = NSOpenPanel()
openPanel.title = "Disk Image"
openPanel.title = "Open Disk Image"
openPanel.allowsMultipleSelection = false
openPanel.canChooseDirectories = false
openPanel.canCreateDirectories = false
@ -1162,6 +1163,37 @@ class ViewController: NSViewController {
}
@objc func saveDiskImage() {
let openPanel = NSOpenPanel()
openPanel.title = "Save 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)
}
}
}
}
}
@IBAction func openDocument(_ sender: Any?) {
openDiskImage()
}
@ -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;
char woz_filename[MAXFILENAME];
woz_flags_t woz_flags = {0,0,0,0};
size_t woz_file_size = 0;
uint8_t * woz_file_buffer = NULL;
woz_header_t * woz_header;
@ -368,6 +370,8 @@ void woz_write( uint8_t data ) {
return;
}
woz_flags.disk_modified = 1;
clkelpased = m6502.clktime + clkfrm - m6502.clklast;
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 ) {
// char fullpath[256];
@ -478,16 +493,18 @@ int woz_loadFile( const char * filename ) {
return WOZ_ERR_FILE_NOT_FOUND;
}
woz_eject();
// get file size
fseek(f, 0, SEEK_END);
woz_file_size = ftell(f);
fseek(f, 0, SEEK_SET);
if ( woz_file_buffer ) {
free(woz_file_buffer);
woz_file_buffer = NULL;
}
woz_flags.disk_modified = 0;
woz_flags.disk_write_protected = 0;
woz_flags.image_file_readonly = 0;
woz_flags.image_loaded = 1;
woz_file_buffer = malloc(woz_file_size);
if (woz_file_buffer == NULL) {
perror("Not Enough Memory: ");
@ -501,8 +518,7 @@ int woz_loadFile( const char * filename ) {
fread( woz_file_buffer, woz_file_size, 1, f);
fclose(f);
if ( woz_header->magic != WOZ1_MAGIC ) {
free(woz_file_buffer);
woz_file_buffer = NULL;
woz_free_buffer();
return WOZ_ERR_NOT_WOZ_FILE;
}
@ -510,21 +526,21 @@ int woz_loadFile( const char * filename ) {
while ( bufOffs < woz_file_size ) {
// 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);
switch ( woz_chunk_header->magic ) {
case WOZ_INFO_CHUNK_ID:
break;
case WOZ_TMAP_CHUNK_ID:
woz_tmap = (woz_tmap_t*)(woz_file_buffer + bufOffs);
woz_tmap = (woz_tmap_t*) &woz_file_buffer[bufOffs];
break;
case WOZ_TRKS_CHUNK_ID:
woz_trks = (woz_trks_t*)(woz_file_buffer + bufOffs);
woz_trks = (woz_trks_t*) &woz_file_buffer[bufOffs];
break;
case WOZ_META_CHUNK_ID:
@ -546,8 +562,32 @@ int woz_loadFile( const char * filename ) {
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 ) {
if ( filename == NULL ) {
filename = woz_filename;
}
FILE * f = fopen( filename, "wb" );
if (f == NULL) {
perror("Failed to crete WOZ: ");
@ -557,6 +597,8 @@ int woz_saveFile( const char * filename ) {
fwrite( woz_file_buffer, woz_file_size, 1, f );
fclose(f);
woz_flags.disk_modified = 0;
return WOZ_ERR_OK;
}

View File

@ -13,6 +13,8 @@
#include "common.h"
#define MAXFILENAME 4096
#define DISKII_MAXTRACKS 80
#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 {
struct {
uint8_t data;
@ -116,11 +98,19 @@ typedef union {
uint64_t shift;
} 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 uint8_t WOZlatch;
extern char woz_filename[MAXFILENAME];
extern woz_flags_t woz_flags;
//extern woz_header_t woz_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 int woz_loadFile( const char * filename );
extern int woz_saveFile( const char * filename );
extern void woz_eject(void);
#endif /* woz_h */