mirror of
https://github.com/trudnai/Steve2.git
synced 2024-12-21 14:30:09 +00:00
Save, SaveAs
This commit is contained in:
parent
5374c8f035
commit
73078e1a9e
@ -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) {
|
||||||
|
@ -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"/>
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user