diff --git a/A2Mac.xcodeproj/project.pbxproj b/A2Mac.xcodeproj/project.pbxproj index 8fe457d..1877dae 100644 --- a/A2Mac.xcodeproj/project.pbxproj +++ b/A2Mac.xcodeproj/project.pbxproj @@ -14,6 +14,11 @@ 323D043024898AB70086A901 /* PreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 323D042F24898AB70086A901 /* PreferencesViewController.swift */; }; 323D04332489BFD80086A901 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 323D04312489BFD80086A901 /* PreferencesWindowController.swift */; }; 323D0437248B6BEA0086A901 /* 6502.c in Sources */ = {isa = PBXBuildFile; fileRef = 32439F7422ECD8AD0077AAE0 /* 6502.c */; }; + 323D043E248F70930086A901 /* diskmotor.raw in Resources */ = {isa = PBXBuildFile; fileRef = 323D043D248F70930086A901 /* diskmotor.raw */; }; + 323D0440248F70A10086A901 /* diskioerr.raw in Resources */ = {isa = PBXBuildFile; fileRef = 323D043F248F70A10086A901 /* diskioerr.raw */; }; + 323D0442248F711F0086A901 /* diskarm.raw in Resources */ = {isa = PBXBuildFile; fileRef = 323D0441248F711F0086A901 /* diskarm.raw */; }; + 323D04442490B3930086A901 /* dotmatrix_effect.png in Resources */ = {isa = PBXBuildFile; fileRef = 323D04432490B3930086A901 /* dotmatrix_effect.png */; }; + 323D04462490BA1E0086A901 /* scanlines.png in Resources */ = {isa = PBXBuildFile; fileRef = 323D04452490BA1E0086A901 /* scanlines.png */; }; 323E2DCE245531E600156805 /* Apple2e_Enhanced.rom in Resources */ = {isa = PBXBuildFile; fileRef = 323E2DCC245531E500156805 /* Apple2e_Enhanced.rom */; }; 323E2DCF245531E600156805 /* Apple2e_Enhanced.rom in Resources */ = {isa = PBXBuildFile; fileRef = 323E2DCC245531E500156805 /* Apple2e_Enhanced.rom */; }; 323E2DD0245531E600156805 /* Apple2e.rom in Resources */ = {isa = PBXBuildFile; fileRef = 323E2DCD245531E500156805 /* Apple2e.rom */; }; @@ -91,8 +96,6 @@ 325EB6AA2401118300C6B4A4 /* Sneakers.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB69A2401118300C6B4A4 /* Sneakers.woz */; }; 325EB6AB2401118300C6B4A4 /* Xonix.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB69B2401118300C6B4A4 /* Xonix.woz */; }; 325EB6AC2401118300C6B4A4 /* Xonix.woz in Resources */ = {isa = PBXBuildFile; fileRef = 325EB69B2401118300C6B4A4 /* Xonix.woz */; }; - 32A9F72C24668D26004902A1 /* apple-rainbow.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 32A9F72B24668D26004902A1 /* apple-rainbow.jpg */; }; - 32A9F72D24668D26004902A1 /* apple-rainbow.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 32A9F72B24668D26004902A1 /* apple-rainbow.jpg */; }; 32A9F74A2467B60B004902A1 /* speaker.c in Sources */ = {isa = PBXBuildFile; fileRef = 32A9F7492467B60B004902A1 /* speaker.c */; }; 32A9F74B2467B60B004902A1 /* speaker.c in Sources */ = {isa = PBXBuildFile; fileRef = 32A9F7492467B60B004902A1 /* speaker.c */; }; 32BFFB5B22EACC630003B53F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32BFFB5A22EACC630003B53F /* AppDelegate.swift */; }; @@ -116,6 +119,8 @@ 32C4532E233345430000EBA1 /* MonitorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C4532D233345420000EBA1 /* MonitorView.swift */; }; 32C4532F233345820000EBA1 /* MonitorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C4532D233345420000EBA1 /* MonitorView.swift */; }; 32C45330233345820000EBA1 /* MonitorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C4532D233345420000EBA1 /* MonitorView.swift */; }; + 32E21BE72491BF8C006C0C72 /* apple-rainbow.png in Resources */ = {isa = PBXBuildFile; fileRef = 32E21BE62491BF8B006C0C72 /* apple-rainbow.png */; }; + 32F2C145249218A400FDC61B /* locksmith_v6.0.woz in Resources */ = {isa = PBXBuildFile; fileRef = 32F2C144249218A400FDC61B /* locksmith_v6.0.woz */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -155,6 +160,11 @@ 323D042F24898AB70086A901 /* PreferencesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesViewController.swift; sourceTree = ""; }; 323D04312489BFD80086A901 /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = ""; }; 323D0435248B20F20086A901 /* 6502_instr_undoc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 6502_instr_undoc.h; sourceTree = ""; }; + 323D043D248F70930086A901 /* diskmotor.raw */ = {isa = PBXFileReference; lastKnownFileType = file; path = diskmotor.raw; sourceTree = ""; }; + 323D043F248F70A10086A901 /* diskioerr.raw */ = {isa = PBXFileReference; lastKnownFileType = file; path = diskioerr.raw; sourceTree = ""; }; + 323D0441248F711F0086A901 /* diskarm.raw */ = {isa = PBXFileReference; lastKnownFileType = file; path = diskarm.raw; sourceTree = ""; }; + 323D04432490B3930086A901 /* dotmatrix_effect.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dotmatrix_effect.png; sourceTree = ""; }; + 323D04452490BA1E0086A901 /* scanlines.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = scanlines.png; sourceTree = ""; }; 323E2DCC245531E500156805 /* Apple2e_Enhanced.rom */ = {isa = PBXFileReference; lastKnownFileType = file; path = Apple2e_Enhanced.rom; sourceTree = ""; }; 323E2DCD245531E500156805 /* Apple2e.rom */ = {isa = PBXFileReference; lastKnownFileType = file; path = Apple2e.rom; sourceTree = ""; }; 32439F7222ECD8AC0077AAE0 /* A2Mac-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "A2Mac-Bridging-Header.h"; sourceTree = ""; }; @@ -242,7 +252,6 @@ 326426112328ADF4008B615F /* Apple_II_ROM.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = Apple_II_ROM.s; sourceTree = ""; }; 3268E68E2474E24900047474 /* paddle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = paddle.h; sourceTree = ""; }; 326ED2EE232D7A0000A41337 /* 6502_functional_test.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = 6502_functional_test.bin; sourceTree = SOURCE_ROOT; }; - 32A9F72B24668D26004902A1 /* apple-rainbow.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "apple-rainbow.jpg"; sourceTree = ""; }; 32A9F7482467B60B004902A1 /* speaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = speaker.h; sourceTree = ""; }; 32A9F7492467B60B004902A1 /* speaker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = speaker.c; sourceTree = ""; }; 32B18435233F10BC00DBB4AB /* Shaders.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = Shaders.metal; sourceTree = ""; }; @@ -269,7 +278,9 @@ 32C4532D233345420000EBA1 /* MonitorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonitorView.swift; sourceTree = ""; }; 32DBF7632334657900DD50E7 /* HiRes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HiRes.swift; sourceTree = ""; }; 32DBF76723373FB400DD50E7 /* disassembler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = disassembler.h; sourceTree = ""; }; + 32E21BE62491BF8B006C0C72 /* apple-rainbow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "apple-rainbow.png"; sourceTree = ""; }; 32EDB7A123272CA80073AF2D /* fail1.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = fail1.txt; sourceTree = ""; }; + 32F2C144249218A400FDC61B /* locksmith_v6.0.woz */ = {isa = PBXFileReference; lastKnownFileType = file; path = locksmith_v6.0.woz; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -343,6 +354,9 @@ 323D0439248F6E670086A901 /* disk */ = { isa = PBXGroup; children = ( + 323D043D248F70930086A901 /* diskmotor.raw */, + 323D0441248F711F0086A901 /* diskarm.raw */, + 323D043F248F70A10086A901 /* diskioerr.raw */, ); path = disk; sourceTree = ""; @@ -385,6 +399,7 @@ 32440B87247F86D5000F9DA1 /* XPS Diagnostic IIe 1.0.5.woz */, 32440B8B247F86D5000F9DA1 /* XPS Diagnostic IIe.woz */, 32440BA0247F9F99000F9DA1 /* LOCKSMITH_V7_REV_B.woz */, + 32F2C144249218A400FDC61B /* locksmith_v6.0.woz */, ); path = dsk; sourceTree = ""; @@ -536,7 +551,9 @@ 323D043A248F6E840086A901 /* dsk */, 323D043B248F6EBE0086A901 /* rom */, 323D0438248F6E560086A901 /* sfx */, - 32A9F72B24668D26004902A1 /* apple-rainbow.jpg */, + 32E21BE62491BF8B006C0C72 /* apple-rainbow.png */, + 323D04432490B3930086A901 /* dotmatrix_effect.png */, + 323D04452490BA1E0086A901 /* scanlines.png */, ); path = Resources; sourceTree = ""; @@ -859,7 +876,6 @@ 325EB68D23FDDFD200C6B4A4 /* Merlin-8 v2.48 (DOS 3.3).woz in Resources */, 325EB6A62401118300C6B4A4 /* ProDOS_312.woz in Resources */, 325EB6AC2401118300C6B4A4 /* Xonix.woz in Resources */, - 32A9F72D24668D26004902A1 /* apple-rainbow.jpg in Resources */, 323E2DCF245531E600156805 /* Apple2e_Enhanced.rom in Resources */, 325EB67D23FBD43800C6B4A4 /* PrintChar21.ttf in Resources */, 325EB6A42401118300C6B4A4 /* Qbit.woz in Resources */, @@ -889,8 +905,10 @@ 3213936624079C30007F5C4A /* Main.storyboard in Resources */, 32440B8F247F86D6000F9DA1 /* Apple II+ Dealer Diagnostics.woz in Resources */, 325EB6A12401118300C6B4A4 /* Wavy Navy.woz in Resources */, + 323D04462490BA1E0086A901 /* scanlines.png in Resources */, 32440B90247F86D6000F9DA1 /* XPS Diagnostic IIe 1.0.5.woz in Resources */, 32440B75247CAA00000F9DA1 /* Merlin Pro v2.23 DOS3.3 (The Yegg-Men Crack).woz in Resources */, + 323D04442490B3930086A901 /* dotmatrix_effect.png in Resources */, 32440B66247C9C9C000F9DA1 /* merlin_assembler_3.woz in Resources */, 32440B7C247CB649000F9DA1 /* Merlin Macroassembler Side 2 (SDS, 1983).woz in Resources */, 325EB68023FBDF8F00C6B4A4 /* Apple2Plus.rom in Resources */, @@ -903,10 +921,11 @@ 32440B76247CAA00000F9DA1 /* Merlin Pro 2.45 (DOS) Disk 1-2.woz in Resources */, 32089E4824556DBD0036E667 /* PRNumber3.ttf in Resources */, 32440B94247F86D6000F9DA1 /* XPS Diagnostic IIe.woz in Resources */, + 32F2C145249218A400FDC61B /* locksmith_v6.0.woz in Resources */, 325EB6A92401118300C6B4A4 /* Sneakers.woz in Resources */, - 32A9F72C24668D26004902A1 /* apple-rainbow.jpg in Resources */, 325EB6A72401118300C6B4A4 /* ProDOS_402_System.woz in Resources */, 32440B96247F86D6000F9DA1 /* Apple II+ Products diagnostic 652-0334.woz in Resources */, + 323D0440248F70A10086A901 /* diskioerr.raw in Resources */, 325EB69023FE028800C6B4A4 /* Donkey Kong.woz in Resources */, 325EB68923FDDF6200C6B4A4 /* Hard Hat Mack - Disk 1, Side A.woz in Resources */, 325EB69F2401118300C6B4A4 /* Crossfire.woz in Resources */, @@ -920,8 +939,11 @@ 32440B65247C9C9C000F9DA1 /* merlin_assembler_2.woz in Resources */, 32440B92247F86D6000F9DA1 /* Apple IIc - Diagnostic diskette Program service 077-8125-A.woz in Resources */, 32440B79247CB2B2000F9DA1 /* Merlin Pro v1.34.woz in Resources */, + 32E21BE72491BF8C006C0C72 /* apple-rainbow.png in Resources */, 325EB68C23FDDFD200C6B4A4 /* Merlin-8 v2.48 (DOS 3.3).woz in Resources */, + 323D043E248F70930086A901 /* diskmotor.raw in Resources */, 32440B91247F86D6000F9DA1 /* COMPUTER_CHECKUP.woz in Resources */, + 323D0442248F711F0086A901 /* diskarm.raw in Resources */, 325EB6A52401118300C6B4A4 /* ProDOS_312.woz in Resources */, 325EB6AB2401118300C6B4A4 /* Xonix.woz in Resources */, 323E2DCE245531E600156805 /* Apple2e_Enhanced.rom in Resources */, diff --git a/A2Mac.xcodeproj/project.xcworkspace/xcuserdata/trudnai.xcuserdatad/xcdebugger/Expressions.xcexplist b/A2Mac.xcodeproj/project.xcworkspace/xcuserdata/trudnai.xcuserdatad/xcdebugger/Expressions.xcexplist index bc11d7e..54242f7 100644 --- a/A2Mac.xcodeproj/project.xcworkspace/xcuserdata/trudnai.xcuserdatad/xcdebugger/Expressions.xcexplist +++ b/A2Mac.xcodeproj/project.xcworkspace/xcuserdata/trudnai.xcuserdatad/xcdebugger/Expressions.xcexplist @@ -14,10 +14,13 @@ + contextName = "BRA:6502_instr_branch.h"> + value = ""> + + @@ -64,7 +67,7 @@ contextName = "closure #1 in ViewController.Update():ViewController.swift"> + value = "MEMcfg.is_80STORE"> @@ -76,7 +79,7 @@ value = "MEMcfg.txt_page_2"> + value = "txtArr"> @@ -114,6 +117,14 @@ + + + + + + @@ -210,13 +221,13 @@ contextName = "spkr_update:speaker.c"> + value = "(uint8_t)spkr_samples[452]"> + value = "(uint8_t)spkr_samples[455]"> @@ -264,7 +275,7 @@ value = "pdl_value[pdl]"> + value = "normalized_time"> @@ -276,7 +287,7 @@ value = "1 * 512 * (1 - ( 3300 / 3300.0 ))"> + value = "normalized_time >= pdl_value[pdl] ? 255 : 0"> @@ -293,13 +304,13 @@ value = "textLines"> + value = "hires.frame"> + value = "hires.layer"> @@ -315,7 +326,7 @@ contextName = "LoRes.Update():LoRes.swift"> + value = "UInt8( (block >> 4) & 0x0F )"> @@ -324,7 +335,7 @@ value = "UInt8(block & 4)"> + value = "blockChanged[ screenIdx ]"> @@ -343,10 +354,10 @@ contextName = "set_flags_NZC:common.h"> + value = "(unsigned)0xFF"> + value = "(unsigned)test "> @@ -388,6 +399,9 @@ + + + value = "HiRes.blockCols"> + value = "ctx?.data"> + + @@ -505,24 +522,21 @@ - - + + + + - - - - + value = "UnsafeRawBufferPointer(result)"> + value = "computePipelineState.maxTotalThreadsPerThreadgroup"> @@ -569,10 +583,10 @@ value = "mouseLocation"> + value = "txtArr"> + value = "clkfrm"> @@ -633,10 +647,10 @@ value = "Apple2_64K_AUX + 0xC600"> + value = "Apple2_64K_RAM + 0xC600"> + value = "(void*)rom"> @@ -661,13 +675,10 @@ + contextName = "specialized closure #1 in ViewController.Update():ViewController.swift"> - - + value = "self.HiRes.frame"> diff --git a/A2Mac/ViewController.swift b/A2Mac/ViewController.swift index c4e1f68..c585e59 100644 --- a/A2Mac/ViewController.swift +++ b/A2Mac/ViewController.swift @@ -779,6 +779,8 @@ class ViewController: NSViewController { hires.clearScreen(); + spkr_load_sfx( Bundle.main.resourcePath! ) + let woz_err = woz_loadFile( Bundle.main.resourcePath! + "/Apple DOS 3.3 January 1983.woz" ) chk_woz_load(err: woz_err) diff --git a/Resources/sfx/disk/diskarm.raw b/Resources/sfx/disk/diskarm.raw new file mode 100644 index 0000000..41ad727 Binary files /dev/null and b/Resources/sfx/disk/diskarm.raw differ diff --git a/Resources/sfx/disk/diskioerr.raw b/Resources/sfx/disk/diskioerr.raw new file mode 100644 index 0000000..b8b5c58 Binary files /dev/null and b/Resources/sfx/disk/diskioerr.raw differ diff --git a/Resources/sfx/disk/diskmotor.raw b/Resources/sfx/disk/diskmotor.raw new file mode 100644 index 0000000..4401c46 Binary files /dev/null and b/Resources/sfx/disk/diskmotor.raw differ diff --git a/src/cpu/6502.c b/src/cpu/6502.c index ef76684..810b3ca 100644 --- a/src/cpu/6502.c +++ b/src/cpu/6502.c @@ -598,6 +598,8 @@ void m6502_Run() { // play the entire sound buffer for this frame spkr_update(); + // this will take care of turning off disk motor sound when time is up + spkr_update_disk_sfx(); } void read_rom( const char * bundlePath, const char * filename, uint8_t * rom, const uint16_t addr ) { diff --git a/src/dev/audio/speaker.c b/src/dev/audio/speaker.c index 4b2220f..9589850 100644 --- a/src/dev/audio/speaker.c +++ b/src/dev/audio/speaker.c @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include "speaker.h" #include "6502.h" @@ -54,7 +52,7 @@ const char* al_err_str(ALenum err) { ALCdevice *dev = NULL; ALCcontext *ctx = NULL; ALuint spkr_buf = 0; -ALuint spkr_src = 0; +ALuint spkr_src [4] = { 0, 0, 0, 0 }; int spkr_level = SPKR_LEVEL_ZERO; @@ -64,11 +62,15 @@ int spkr_level = SPKR_LEVEL_ZERO; #define SOURCES_COUNT 1 ALuint spkr_buffers[BUFFER_COUNT]; +ALuint spkr_disk_motor_buf = 0; +ALuint spkr_disk_arm_buf = 0; +ALuint spkr_disk_ioerr_buf = 0; const int spkr_fps = fps; const int spkr_seconds = 1; const unsigned spkr_sample_rate = 44100; +const unsigned sfx_sample_rate = 22050; unsigned spkr_extra_buf = 800 / spkr_fps; const unsigned spkr_buf_size = spkr_seconds * spkr_sample_rate * 2 / spkr_fps; int16_t spkr_samples [ spkr_buf_size * spkr_fps * BUFFER_COUNT * 2]; // stereo @@ -76,9 +78,19 @@ unsigned spkr_sample_idx = 0; const unsigned spkr_play_timeout = 8; // increase to 32 for 240 fps unsigned spkr_play_time = 0; +unsigned spkr_play_disk_motor_time = 0; +unsigned spkr_play_disk_arm_time = 0; +unsigned spkr_play_disk_ioerr_time = 0; + +uint8_t * diskmotor_sfx = NULL; +int diskmotor_sfx_len = 0; +uint8_t * diskarm_sfx = NULL; +int diskarm_sfx_len = 0; +uint8_t * diskioerr_sfx = NULL; +int diskioerr_sfx_len = 0; -static uint8_t* load_sfx( const char * bundlePath, const char * filename ) { +static int load_sfx( const char * bundlePath, const char * filename, uint8_t ** buf ) { char fullPath[256]; strcpy( fullPath, bundlePath ); @@ -88,7 +100,7 @@ static uint8_t* load_sfx( const char * bundlePath, const char * filename ) { FILE * f = fopen(fullPath, "rb"); if (f == NULL) { perror("Failed to read SFX: "); - return NULL; + return -1; } fseek(f, 0L, SEEK_END); @@ -97,32 +109,34 @@ static uint8_t* load_sfx( const char * bundlePath, const char * filename ) { if (flen <= 0) { printf("Failed to read SFX or 0 size\n"); - return NULL; + return -1; } - uint8_t * buffer = malloc(flen); + *buf = malloc(flen); - if (buffer == NULL) { + if ( *buf == NULL ) { printf("Not enough memory for SFX\n"); - return NULL; + return -1; } - fread( buffer, 1, flen, f); + fread( *buf, 1, flen, f); fclose(f); if ( flen == 0 ) { printf("Error loading SFX file\n"); - free(buffer); - return NULL; // there was an error + free( *buf ); + return -1; // there was an error } // everything seems to be ok - return buffer; + return flen; } void spkr_load_sfx( const char * bundlePath ) { - + diskmotor_sfx_len = load_sfx(bundlePath, "diskmotor.raw", &diskmotor_sfx); + diskarm_sfx_len = load_sfx(bundlePath, "diskarm.raw", &diskarm_sfx); + diskioerr_sfx_len = load_sfx(bundlePath, "diskioerr.raw", &diskioerr_sfx); } @@ -143,22 +157,65 @@ void spkr_init() { // Create buffer to store samples alGenBuffers(BUFFER_COUNT, spkr_buffers); + alGenBuffers(1, &spkr_disk_motor_buf); + alGenBuffers(1, &spkr_disk_arm_buf); + alGenBuffers(1, &spkr_disk_ioerr_buf); al_check_error(); // Set-up sound source and play buffer - alGenSources(1, &spkr_src); + alGenSources(4, spkr_src); al_check_error(); - alSourcei(spkr_src, AL_LOOPING, AL_FALSE); + alSourcei(spkr_src[0], AL_LOOPING, AL_FALSE); al_check_error(); - alSourcef(spkr_src, AL_ROLLOFF_FACTOR, 0); + alSourcef(spkr_src[0], AL_ROLLOFF_FACTOR, 0); al_check_error(); - alSource3f(spkr_src, AL_POSITION, 0.0, 8.0, 0.0); + alSource3f(spkr_src[0], AL_POSITION, 0.0, 8.0, 0.0); al_check_error(); alListener3f(AL_POSITION, 0.0, 0.0, 0.0); al_check_error(); alListener3f(AL_ORIENTATION, 0.0, -16.0, 0.0); al_check_error(); + + // Set-up disk motor sound source and play buffer + alSourcei(spkr_src[1], AL_LOOPING, AL_TRUE); + al_check_error(); + alSourcef(spkr_src[1], AL_ROLLOFF_FACTOR, 0); + al_check_error(); + alSource3f(spkr_src[1], AL_POSITION, 0.0, 8.0, 0.0); + al_check_error(); + alListener3f(AL_POSITION, 0.0, 0.0, 0.0); + al_check_error(); + alListener3f(AL_ORIENTATION, 0.0, -16.0, 0.0); + al_check_error(); + + + // Set-up disk arm sound source and play buffer + alSourcei(spkr_src[2], AL_LOOPING, AL_TRUE); + al_check_error(); + alSourcef(spkr_src[2], AL_ROLLOFF_FACTOR, 0); + al_check_error(); + alSource3f(spkr_src[2], AL_POSITION, 0.0, 8.0, 0.0); + al_check_error(); + alListener3f(AL_POSITION, 0.0, 0.0, 0.0); + al_check_error(); + alListener3f(AL_ORIENTATION, 0.0, -16.0, 0.0); + al_check_error(); + + + // Set-up disk io error sound source and play buffer + alSourcei(spkr_src[3], AL_LOOPING, AL_FALSE); + al_check_error(); + alSourcef(spkr_src[3], AL_ROLLOFF_FACTOR, 0); + al_check_error(); + alSource3f(spkr_src[3], AL_POSITION, 0.0, 8.0, 0.0); + al_check_error(); + alListener3f(AL_POSITION, 0.0, 0.0, 0.0); + al_check_error(); + alListener3f(AL_ORIENTATION, 0.0, -16.0, 0.0); + al_check_error(); + + // start from the beginning spkr_sample_idx = 0; @@ -168,7 +225,7 @@ void spkr_init() { // Dealloc OpenAL void spkr_exit() { - if ( spkr_src ) { + if ( spkr_src[0] ) { ALCdevice *dev = NULL; ALCcontext *ctx = NULL; ctx = alcGetCurrentContext(); @@ -180,7 +237,7 @@ void spkr_exit() { al_check_error(); - spkr_src = 0; + spkr_src[0] = 0; } } @@ -264,11 +321,11 @@ void spkr_update() { // printf("freeBuffers:%d queued:%d processed:%d\n", freeBuffers, queued,processed); do { - alGetSourcei (spkr_src, AL_BUFFERS_PROCESSED, &processed); + alGetSourcei (spkr_src[0], AL_BUFFERS_PROCESSED, &processed); // al_check_error(); if ( processed ) { - alSourceUnqueueBuffers( spkr_src, processed, &spkr_buffers[freeBuffers]); + alSourceUnqueueBuffers( spkr_src[0], processed, &spkr_buffers[freeBuffers]); // al_check_error(); freeBuffers += processed; } @@ -280,7 +337,7 @@ void spkr_update() { // printf("freeBuffers2: %d processed: %d\n", freeBuffers, processed); ALenum state; - alGetSourcei( spkr_src, AL_SOURCE_STATE, &state ); + alGetSourcei( spkr_src[0], AL_SOURCE_STATE, &state ); // al_check_error(); ////////// check if there is no sound generated for long time, and fade out speaker level to avoid pops and crackles @@ -310,7 +367,7 @@ void spkr_update() { freeBuffers--; alBufferData(spkr_buffers[freeBuffers], AL_FORMAT_STEREO16, spkr_samples, spkr_sample_idx * sizeof(spkr_samples[0]), spkr_sample_rate); al_check_error(); - alSourceQueueBuffers(spkr_src, 1, &spkr_buffers[freeBuffers]); + alSourceQueueBuffers(spkr_src[0], 1, &spkr_buffers[freeBuffers]); al_check_error(); } } @@ -318,13 +375,13 @@ void spkr_update() { freeBuffers--; alBufferData(spkr_buffers[freeBuffers], AL_FORMAT_STEREO16, spkr_samples, (spkr_buf_size + spkr_extra_buf) * sizeof(spkr_samples[0]), spkr_sample_rate); al_check_error(); - alSourceQueueBuffers(spkr_src, 1, &spkr_buffers[freeBuffers]); + alSourceQueueBuffers(spkr_src[0], 1, &spkr_buffers[freeBuffers]); al_check_error(); } switch (state) { case AL_PAUSED: - alSourcePlay(spkr_src); + alSourcePlay(spkr_src[0]); break; case AL_PLAYING: @@ -332,8 +389,8 @@ void spkr_update() { break; default: - alSourcePlay(spkr_src); - alSourcePause(spkr_src); + alSourcePlay(spkr_src[0]); + alSourcePause(spkr_src[0]); break; } @@ -347,6 +404,128 @@ void spkr_update() { spkr_sample_idx = 0; } + + } +void spkr_playqueue_sfx( ALuint src, ALuint * buf, uint8_t * sfx, int len ) { + + alBufferData( *buf, AL_FORMAT_STEREO16, sfx, len, sfx_sample_rate ); + al_check_error(); + alSourceQueueBuffers( src, 1, buf ); + al_check_error(); + + ALenum state; + alGetSourcei( src, AL_SOURCE_STATE, &state ); +// al_check_error(); + + switch (state) { + case AL_PLAYING: + // already playing + break; + + default: + alSourcePlay( src ); + break; + } +} + + +void spkr_play_sfx( ALuint src, ALuint * buf, uint8_t * sfx, int len ) { + + ALenum state; + alGetSourcei( src, AL_SOURCE_STATE, &state ); +// al_check_error(); + + switch (state) { + case AL_PAUSED: + alSourcePlay( src ); + break; + + case AL_PLAYING: + // already playing + break; + + default: + alBufferData( *buf, AL_FORMAT_STEREO16, sfx, len, sfx_sample_rate ); + al_check_error(); + alSourceQueueBuffers( src, 1, buf ); + al_check_error(); + + alSourcePlay( src ); + break; + } +} + + +void spkr_stop_sfx( ALuint src, ALuint * buf ) { + + ALenum state; + alGetSourcei( src, AL_SOURCE_STATE, &state ); +// al_check_error(); + + switch (state) { + case AL_PAUSED: + case AL_PLAYING: + alSourceStop( src ); + alSourceUnqueueBuffers( src, 1, buf ); + break; + + default: + break; + } +} + + +void spkr_play_disk_motor() { + if ( diskAccelerator_count == 0 ) { + spkr_play_sfx( spkr_src[1], &spkr_disk_motor_buf, diskmotor_sfx, diskmotor_sfx_len ); + } +} + +void spkr_stop_disk_motor( int time ) { + if ( diskAccelerator_count == 0 ) { + spkr_play_disk_motor_time = time; + } +} + + +void spkr_play_disk_arm() { + if ( diskAccelerator_count == 0 ) { + if ( spkr_play_disk_ioerr_time == 0 ) { + spkr_play_sfx( spkr_src[2], &spkr_disk_arm_buf, diskarm_sfx, diskarm_sfx_len ); + spkr_play_disk_arm_time = 2; +// spkr_play_disk_ioerr_time = 2; + } + } +} + + +void spkr_play_disk_ioerr() { +// spkr_stop_sfx( spkr_src[3], &spkr_disk_ioerr_buf ); + if ( diskAccelerator_count == 0 ) { + spkr_playqueue_sfx( spkr_src[3], &spkr_disk_ioerr_buf, diskioerr_sfx, diskioerr_sfx_len ); + spkr_play_disk_ioerr_time = 6; + } +} + + +void update_disk_sfx( unsigned * time, ALuint src, ALuint * buf ) { + if ( diskAccelerator_count == 0 ) { + if ( *time ) { + if ( --*time == 0 ) { + spkr_stop_sfx( src, buf ); + } + } + } +} + +void spkr_update_disk_sfx() { + if ( diskAccelerator_count == 0 ) { + update_disk_sfx( &spkr_play_disk_motor_time, spkr_src[1], &spkr_disk_motor_buf ); + update_disk_sfx( &spkr_play_disk_arm_time, spkr_src[2], &spkr_disk_arm_buf ); + update_disk_sfx( &spkr_play_disk_ioerr_time, spkr_src[3], &spkr_disk_ioerr_buf ); + } +} + diff --git a/src/dev/audio/speaker.h b/src/dev/audio/speaker.h index 82541e0..08b629a 100644 --- a/src/dev/audio/speaker.h +++ b/src/dev/audio/speaker.h @@ -10,9 +10,25 @@ #define speaker_h #include +#include +#include + +// very loud +//#define SPKR_LEVEL_MIN (-28000) +//#define SPKR_LEVEL_MAX (+28000) + +// loud +//#define SPKR_LEVEL_MIN (-5000) +//#define SPKR_LEVEL_MAX (+5000) + +// medium +#define SPKR_LEVEL_MIN (-3000) +#define SPKR_LEVEL_MAX (+3000) + +// quiet +//#define SPKR_LEVEL_MIN (-1000) +//#define SPKR_LEVEL_MAX (+1000) -#define SPKR_LEVEL_MIN (-28000) -#define SPKR_LEVEL_MAX (+28000) #define SPKR_LEVEL_ZERO 0 // as defined in OpenAL documentation for 8bit PCM @@ -34,5 +50,13 @@ extern void spkr_exit(void); extern void spkr_update(void); extern void spkr_toggle(void); +extern void spkr_load_sfx( const char * bundlePath ); + +extern void spkr_play_disk_motor(void); +extern void spkr_stop_disk_motor( int time ); +extern void spkr_update_disk_sfx(void); + +extern void spkr_play_disk_arm(void); +extern void spkr_play_disk_ioerr(void); #endif /* speaker_h */ diff --git a/src/dev/disk/disk.c b/src/dev/disk/disk.c index 2968dc0..7cbdb1d 100644 --- a/src/dev/disk/disk.c +++ b/src/dev/disk/disk.c @@ -85,10 +85,15 @@ void disk_phase() { disk.phase.count += direction; if( disk.phase.count < minDiskPhaseNum ) { disk.phase.count = minDiskPhaseNum; + spkr_play_disk_ioerr(); } else if( disk.phase.count > maxDiskPhaseNum ) { disk.phase.count = maxDiskPhaseNum; + spkr_play_disk_ioerr(); + } + else { + spkr_play_disk_arm(); } // TODO: Add track positioning sfx @@ -103,6 +108,8 @@ void disk_phase() { // invalid magnet config } + + // printf("\n"); } @@ -118,6 +125,14 @@ void disk_phase_off( uint8_t currentMagnet ) { disk_phase(); } +void disk_motor_on() { + spkr_play_disk_motor(); + spkr_stop_disk_motor( -1 ); +} + +void disk_motor_off() { + spkr_stop_disk_motor( 3 * fps ); // 3 second delay +} uint8_t disk_read() { dbgPrintf("io_DISK_READ (S%u)\n", 6); diff --git a/src/dev/disk/disk.h b/src/dev/disk/disk.h index 5ea4009..5d6e178 100644 --- a/src/dev/disk/disk.h +++ b/src/dev/disk/disk.h @@ -68,5 +68,8 @@ extern void disk_phase_on( uint8_t currentMagnet ); extern void disk_phase_off( uint8_t currentMagnet ); extern uint8_t disk_read(void); +extern void disk_motor_on(void); +extern void disk_motor_off(void); + #endif /* disk_h */ diff --git a/src/dev/mem/mmio.h b/src/dev/mem/mmio.h index 14bf13f..997e5a1 100644 --- a/src/dev/mem/mmio.h +++ b/src/dev/mem/mmio.h @@ -720,10 +720,12 @@ INLINE uint8_t ioRead( uint16_t addr ) { case (uint8_t)io_DISK_POWER_OFF + SLOT6: dbgPrintf2("io_DISK_POWER_OFF (S%u)\n", 6); + disk_motor_off(); return 0; case (uint8_t)io_DISK_POWER_ON + SLOT6: dbgPrintf2("io_DISK_POWER_ON (S%u)\n", 6); + disk_motor_on(); return 0; case (uint8_t)io_DISK_SELECT_1 + SLOT6: