├── .gitignore
├── Square Wave
    ├── Podfile
    ├── Square Wave.xcworkspace
    │   ├── contents.xcworkspacedata
    │   ├── xcshareddata
    │   │   └── IDEWorkspaceChecks.plist
    │   └── xcuserdata
    │   │   └── abusman.xcuserdatad
    │   │       └── xcdebugger
    │   │           └── Breakpoints_v2.xcbkptlist
    ├── Square Wave
    │   ├── AddToPlaylistView.swift
    │   ├── AppDelegate.swift
    │   ├── ArtistsView.swift
    │   ├── Assets.xcassets
    │   │   ├── AppIcon.appiconset
    │   │   │   ├── Contents.json
    │   │   │   ├── icon20x20.png
    │   │   │   ├── icon20x20@2x-1.png
    │   │   │   ├── icon20x20@2x-2.png
    │   │   │   ├── icon20x20@2x.png
    │   │   │   ├── icon20x20@3x.png
    │   │   │   ├── icon29x29.png
    │   │   │   ├── icon29x29@2x-1.png
    │   │   │   ├── icon29x29@2x.png
    │   │   │   ├── icon29x29@3x.png
    │   │   │   ├── icon40x40@2x-1.png
    │   │   │   ├── icon40x40@2x.png
    │   │   │   ├── icon60x60@2x-1.png
    │   │   │   ├── icon60x60@2x.png
    │   │   │   ├── icon60x60@3x.png
    │   │   │   ├── icon76x76.png
    │   │   │   ├── icon76x76@2x.png
    │   │   │   ├── icon83.5x83.5@2x.png
    │   │   │   └── itunes-icon.png
    │   │   ├── Consoles
    │   │   │   ├── Contents.json
    │   │   │   ├── atari.imageset
    │   │   │   │   ├── Contents.json
    │   │   │   │   ├── atari.png
    │   │   │   │   ├── atari@2x.png
    │   │   │   │   └── atari@3x.png
    │   │   │   ├── gameboy.imageset
    │   │   │   │   ├── Contents.json
    │   │   │   │   ├── gameboy.png
    │   │   │   │   ├── gameboy@2x.png
    │   │   │   │   └── gameboy@3x.png
    │   │   │   ├── master-system.imageset
    │   │   │   │   ├── Contents.json
    │   │   │   │   ├── master-system.png
    │   │   │   │   ├── master-system@2x.png
    │   │   │   │   └── master-system@3x.png
    │   │   │   ├── megadrive.imageset
    │   │   │   │   ├── Contents.json
    │   │   │   │   ├── megadrive.png
    │   │   │   │   ├── megadrive@2x.png
    │   │   │   │   └── megadrive@3x.png
    │   │   │   ├── msx.imageset
    │   │   │   │   ├── Contents.json
    │   │   │   │   ├── msx.png
    │   │   │   │   ├── msx@2x.png
    │   │   │   │   └── msx@3x.png
    │   │   │   ├── nes.imageset
    │   │   │   │   ├── Contents.json
    │   │   │   │   ├── nes.png
    │   │   │   │   ├── nes@2x.png
    │   │   │   │   └── nes@3x.png
    │   │   │   ├── snes.imageset
    │   │   │   │   ├── Contents.json
    │   │   │   │   ├── snes.png
    │   │   │   │   ├── snes@2x.png
    │   │   │   │   └── snes@3x.png
    │   │   │   ├── spectrum.imageset
    │   │   │   │   ├── Contents.json
    │   │   │   │   ├── spectrum.png
    │   │   │   │   ├── spectrum@2x.png
    │   │   │   │   └── spectrum@3x.png
    │   │   │   └── turbografx.imageset
    │   │   │   │   ├── Contents.json
    │   │   │   │   ├── turbografx.png
    │   │   │   │   ├── turbografx@2x.png
    │   │   │   │   └── turbografx@3x.png
    │   │   ├── Contents.json
    │   │   ├── placeholder-art.imageset
    │   │   │   ├── Contents.json
    │   │   │   ├── placeholder-note.png
    │   │   │   ├── placeholder-note@2x.png
    │   │   │   └── placeholder-note@3x.png
    │   │   └── placeholder-playlist.imageset
    │   │   │   ├── Contents.json
    │   │   │   ├── new_playlist@1x.png
    │   │   │   ├── new_playlist@2x.png
    │   │   │   └── new_playlist@3x.png
    │   ├── Base.lproj
    │   │   └── LaunchScreen.storyboard
    │   ├── BlurView.swift
    │   ├── Engine
    │   │   ├── AudioEngine.h
    │   │   ├── AudioEngine.m
    │   │   ├── FileEngine.h
    │   │   ├── FileEngine.m
    │   │   ├── Square Wave-Bridging-Header.h
    │   │   └── gme
    │   │   │   ├── Ay_Apu.cpp
    │   │   │   ├── Ay_Apu.h
    │   │   │   ├── Ay_Cpu.cpp
    │   │   │   ├── Ay_Cpu.h
    │   │   │   ├── Ay_Emu.cpp
    │   │   │   ├── Ay_Emu.h
    │   │   │   ├── Blip_Buffer.cpp
    │   │   │   ├── Blip_Buffer.h
    │   │   │   ├── Classic_Emu.cpp
    │   │   │   ├── Classic_Emu.h
    │   │   │   ├── Data_Reader.cpp
    │   │   │   ├── Data_Reader.h
    │   │   │   ├── Dual_Resampler.cpp
    │   │   │   ├── Dual_Resampler.h
    │   │   │   ├── Effects_Buffer.cpp
    │   │   │   ├── Effects_Buffer.h
    │   │   │   ├── Fir_Resampler.cpp
    │   │   │   ├── Fir_Resampler.h
    │   │   │   ├── Gb_Apu.cpp
    │   │   │   ├── Gb_Apu.h
    │   │   │   ├── Gb_Cpu.cpp
    │   │   │   ├── Gb_Cpu.h
    │   │   │   ├── Gb_Oscs.cpp
    │   │   │   ├── Gb_Oscs.h
    │   │   │   ├── Gbs_Emu.cpp
    │   │   │   ├── Gbs_Emu.h
    │   │   │   ├── Gme_File.cpp
    │   │   │   ├── Gme_File.h
    │   │   │   ├── Gym_Emu.cpp
    │   │   │   ├── Gym_Emu.h
    │   │   │   ├── Hes_Apu.cpp
    │   │   │   ├── Hes_Apu.h
    │   │   │   ├── Hes_Cpu.cpp
    │   │   │   ├── Hes_Cpu.h
    │   │   │   ├── Hes_Emu.cpp
    │   │   │   ├── Hes_Emu.h
    │   │   │   ├── Kss_Cpu.cpp
    │   │   │   ├── Kss_Cpu.h
    │   │   │   ├── Kss_Emu.cpp
    │   │   │   ├── Kss_Emu.h
    │   │   │   ├── Kss_Scc_Apu.cpp
    │   │   │   ├── Kss_Scc_Apu.h
    │   │   │   ├── M3u_Playlist.cpp
    │   │   │   ├── M3u_Playlist.h
    │   │   │   ├── Multi_Buffer.cpp
    │   │   │   ├── Multi_Buffer.h
    │   │   │   ├── Music_Emu.cpp
    │   │   │   ├── Music_Emu.h
    │   │   │   ├── Nes_Apu.cpp
    │   │   │   ├── Nes_Apu.h
    │   │   │   ├── Nes_Cpu.cpp
    │   │   │   ├── Nes_Cpu.h
    │   │   │   ├── Nes_Fme7_Apu.cpp
    │   │   │   ├── Nes_Fme7_Apu.h
    │   │   │   ├── Nes_Namco_Apu.cpp
    │   │   │   ├── Nes_Namco_Apu.h
    │   │   │   ├── Nes_Oscs.cpp
    │   │   │   ├── Nes_Oscs.h
    │   │   │   ├── Nes_Vrc6_Apu.cpp
    │   │   │   ├── Nes_Vrc6_Apu.h
    │   │   │   ├── Nsf_Emu.cpp
    │   │   │   ├── Nsf_Emu.h
    │   │   │   ├── Nsfe_Emu.cpp
    │   │   │   ├── Nsfe_Emu.h
    │   │   │   ├── Sap_Apu.cpp
    │   │   │   ├── Sap_Apu.h
    │   │   │   ├── Sap_Cpu.cpp
    │   │   │   ├── Sap_Cpu.h
    │   │   │   ├── Sap_Emu.cpp
    │   │   │   ├── Sap_Emu.h
    │   │   │   ├── Sms_Apu.cpp
    │   │   │   ├── Sms_Apu.h
    │   │   │   ├── Sms_Oscs.h
    │   │   │   ├── Snes_Spc.cpp
    │   │   │   ├── Snes_Spc.h
    │   │   │   ├── Spc_Cpu.cpp
    │   │   │   ├── Spc_Cpu.h
    │   │   │   ├── Spc_Dsp.cpp
    │   │   │   ├── Spc_Dsp.h
    │   │   │   ├── Spc_Emu.cpp
    │   │   │   ├── Spc_Emu.h
    │   │   │   ├── Spc_Filter.cpp
    │   │   │   ├── Spc_Filter.h
    │   │   │   ├── Vgm_Emu.cpp
    │   │   │   ├── Vgm_Emu.h
    │   │   │   ├── Vgm_Emu_Impl.cpp
    │   │   │   ├── Vgm_Emu_Impl.h
    │   │   │   ├── Ym2413_Emu.cpp
    │   │   │   ├── Ym2413_Emu.h
    │   │   │   ├── Ym2612_Emu.h
    │   │   │   ├── Ym2612_GENS.cpp
    │   │   │   ├── Ym2612_GENS.h
    │   │   │   ├── Ym2612_MAME.cpp
    │   │   │   ├── Ym2612_MAME.h
    │   │   │   ├── Ym2612_Nuked.cpp
    │   │   │   ├── Ym2612_Nuked.h
    │   │   │   ├── blargg_common.h
    │   │   │   ├── blargg_config.h
    │   │   │   ├── blargg_endian.h
    │   │   │   ├── blargg_source.h
    │   │   │   ├── gb_cpu_io.h
    │   │   │   ├── gme.cpp
    │   │   │   ├── gme.h
    │   │   │   ├── gme_types.h
    │   │   │   ├── hes_cpu_io.h
    │   │   │   ├── nes_cpu_io.h
    │   │   │   └── sap_cpu_io.h
    │   ├── FilePicker.swift
    │   ├── GamesView.swift
    │   ├── GoogleService-Info.plist
    │   ├── IAPManager.swift
    │   ├── IAP_ProductIDs.plist
    │   ├── Info.plist
    │   ├── LibraryView.swift
    │   ├── ListArtView.swift
    │   ├── ListSectionIndexView.swift
    │   ├── Main.storyboard
    │   ├── NewPlaylistView.swift
    │   ├── NowPlayingMiniView.swift
    │   ├── NowPlayingView.swift
    │   ├── PlatformsView.swift
    │   ├── PlaybackState.swift
    │   ├── PlaylistView.swift
    │   ├── PlaylistsView.swift
    │   ├── Preview Content
    │   │   └── Preview Assets.xcassets
    │   │   │   └── Contents.json
    │   ├── Receipts
    │   │   ├── AppleIncRootCertificate.cer
    │   │   ├── ReceiptFetcher.swift
    │   │   ├── SwiftyLocalReceiptValidator.swift
    │   │   ├── pkcs7_union_accessors.c
    │   │   └── pkcs7_union_accessors.h
    │   ├── RootViewController.swift
    │   ├── SceneDelegate.swift
    │   ├── SettingsView.swift
    │   ├── SongTableViewCell.swift
    │   ├── SongTableViewCell.xib
    │   ├── SongsView.swift
    │   ├── Square Wave.entitlements
    │   ├── Square_Wave.xcdatamodeld
    │   │   └── Model.xcdatamodel
    │   │   │   └── contents
    │   ├── TextView.swift
    │   ├── UIListView.swift
    │   ├── Util.swift
    │   ├── VisualEffectView.swift
    │   ├── en.lproj
    │   │   └── Localizable.strings
    │   └── fr-CA.lproj
    │   │   ├── LaunchScreen.storyboard
    │   │   └── Localizable.strings
    ├── Square WaveTests
    │   ├── Info.plist
    │   └── Square_WaveTests.swift
    ├── Square WaveUITests
    │   ├── Info.plist
    │   └── Square_WaveUITests.swift
    ├── Square Waves.xcodeproj
    │   ├── project.pbxproj
    │   ├── project.xcworkspace
    │   │   ├── contents.xcworkspacedata
    │   │   └── xcshareddata
    │   │   │   └── IDEWorkspaceChecks.plist
    │   ├── xcshareddata
    │   │   └── xcschemes
    │   │   │   └── Square Wave.xcscheme
    │   └── xcuserdata
    │   │   └── abusman.xcuserdatad
    │   │       └── xcschemes
    │   │           └── xcschememanagement.plist
    └── Square Waves.xcworkspace
    │   └── contents.xcworkspacedata
└── privacy_policy.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.xcuserstate
3 | *.nsf
4 | 
--------------------------------------------------------------------------------
/Square Wave/Podfile:
--------------------------------------------------------------------------------
 1 | # Uncomment the next line to define a global platform for your project
 2 | platform :ios, '13'
 3 | 
 4 | target 'Square Waves' do
 5 |   # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
 6 |   use_frameworks!
 7 | 
 8 |   # Pods for Square Waves
 9 |   pod 'SSZipArchive'
10 |   pod 'UnrarKit'
11 |   pod 'LzmaSDK-ObjC', :inhibit_warnings => true
12 |   pod 'Firebase/Analytics'
13 |   pod 'Firebase/Crashlytics'
14 |   pod 'openssl-ios-bitcode'
15 | end
16 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 4 |    
 6 |    
 7 |    
 9 |    
10 | 
11 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 | 
2 | 
3 | 
4 | 
5 | 	IDEDidComputeMac32BitWarning
6 | 	
7 | 
8 | 
9 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave.xcworkspace/xcuserdata/abusman.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 | 
2 | 
6 | 
7 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/ArtistsView.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  ArtistsView.swift
 3 | //  Square Waves
 4 | //
 5 | //  Created by Alex Busman on 8/8/20.
 6 | //  Copyright © 2020 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | import SwiftUI
10 | 
11 | struct ArtistsView: View {
12 |     @FetchRequest(entity: Artist.entity(), sortDescriptors: []) var artists: FetchedResults
13 | 
14 |     var body: some View {
15 |         UIListView(rows: Binding(get: {
16 |             Array(self.artists)
17 |         }, set: { _ in
18 |             
19 |         }),
20 |         sortType: Binding(get: {
21 |             SortType.title.rawValue
22 |         }, set: { _ in
23 |             
24 |         }), isEditing: .constant(false), rowType: Artist.self, keypaths: UIListViewCellKeypaths(title: \Artist.name), showSearch: false, showsHeader: false)
25 |             .navigationBarTitle(Text(NSLocalizedString("Artists", comment: "Artists")), displayMode: .inline)
26 |         .edgesIgnoringSafeArea(.vertical)
27 |     }
28 | }
29 | 
30 | struct ArtistsView_Previews: PreviewProvider {
31 |     static var previews: some View {
32 |         ArtistsView()
33 |     }
34 | }
35 | 
36 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
  1 | {
  2 |   "images" : [
  3 |     {
  4 |       "size" : "20x20",
  5 |       "idiom" : "iphone",
  6 |       "filename" : "icon20x20@2x.png",
  7 |       "scale" : "2x"
  8 |     },
  9 |     {
 10 |       "size" : "20x20",
 11 |       "idiom" : "iphone",
 12 |       "filename" : "icon20x20@3x.png",
 13 |       "scale" : "3x"
 14 |     },
 15 |     {
 16 |       "size" : "29x29",
 17 |       "idiom" : "iphone",
 18 |       "filename" : "icon29x29@2x.png",
 19 |       "scale" : "2x"
 20 |     },
 21 |     {
 22 |       "size" : "29x29",
 23 |       "idiom" : "iphone",
 24 |       "filename" : "icon29x29@3x.png",
 25 |       "scale" : "3x"
 26 |     },
 27 |     {
 28 |       "size" : "40x40",
 29 |       "idiom" : "iphone",
 30 |       "filename" : "icon40x40@2x-1.png",
 31 |       "scale" : "2x"
 32 |     },
 33 |     {
 34 |       "size" : "40x40",
 35 |       "idiom" : "iphone",
 36 |       "filename" : "icon60x60@2x-1.png",
 37 |       "scale" : "3x"
 38 |     },
 39 |     {
 40 |       "size" : "60x60",
 41 |       "idiom" : "iphone",
 42 |       "filename" : "icon60x60@2x.png",
 43 |       "scale" : "2x"
 44 |     },
 45 |     {
 46 |       "size" : "60x60",
 47 |       "idiom" : "iphone",
 48 |       "filename" : "icon60x60@3x.png",
 49 |       "scale" : "3x"
 50 |     },
 51 |     {
 52 |       "size" : "20x20",
 53 |       "idiom" : "ipad",
 54 |       "filename" : "icon20x20.png",
 55 |       "scale" : "1x"
 56 |     },
 57 |     {
 58 |       "size" : "20x20",
 59 |       "idiom" : "ipad",
 60 |       "filename" : "icon20x20@2x-2.png",
 61 |       "scale" : "2x"
 62 |     },
 63 |     {
 64 |       "size" : "29x29",
 65 |       "idiom" : "ipad",
 66 |       "filename" : "icon29x29.png",
 67 |       "scale" : "1x"
 68 |     },
 69 |     {
 70 |       "size" : "29x29",
 71 |       "idiom" : "ipad",
 72 |       "filename" : "icon29x29@2x-1.png",
 73 |       "scale" : "2x"
 74 |     },
 75 |     {
 76 |       "size" : "40x40",
 77 |       "idiom" : "ipad",
 78 |       "filename" : "icon20x20@2x-1.png",
 79 |       "scale" : "1x"
 80 |     },
 81 |     {
 82 |       "size" : "40x40",
 83 |       "idiom" : "ipad",
 84 |       "filename" : "icon40x40@2x.png",
 85 |       "scale" : "2x"
 86 |     },
 87 |     {
 88 |       "size" : "76x76",
 89 |       "idiom" : "ipad",
 90 |       "filename" : "icon76x76.png",
 91 |       "scale" : "1x"
 92 |     },
 93 |     {
 94 |       "size" : "76x76",
 95 |       "idiom" : "ipad",
 96 |       "filename" : "icon76x76@2x.png",
 97 |       "scale" : "2x"
 98 |     },
 99 |     {
100 |       "size" : "83.5x83.5",
101 |       "idiom" : "ipad",
102 |       "filename" : "icon83.5x83.5@2x.png",
103 |       "scale" : "2x"
104 |     },
105 |     {
106 |       "size" : "1024x1024",
107 |       "idiom" : "ios-marketing",
108 |       "filename" : "itunes-icon.png",
109 |       "scale" : "1x"
110 |     }
111 |   ],
112 |   "info" : {
113 |     "version" : 1,
114 |     "author" : "xcode"
115 |   }
116 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon20x20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon20x20.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon20x20@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon20x20@2x-1.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon20x20@2x-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon20x20@2x-2.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon20x20@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon20x20@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon29x29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon29x29.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon29x29@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon29x29@2x-1.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon29x29@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon29x29@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon40x40@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon40x40@2x-1.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon40x40@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon60x60@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon60x60@2x-1.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon60x60@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon60x60@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon76x76.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon76x76@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/icon83.5x83.5@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/itunes-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/AppIcon.appiconset/itunes-icon.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 |   "info" : {
3 |     "version" : 1,
4 |     "author" : "xcode"
5 |   }
6 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/atari.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "atari.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "atari@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "atari@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   },
23 |   "properties" : {
24 |     "template-rendering-intent" : "original"
25 |   }
26 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/atari.imageset/atari.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/atari.imageset/atari.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/atari.imageset/atari@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/atari.imageset/atari@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/atari.imageset/atari@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/atari.imageset/atari@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/gameboy.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "gameboy.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "gameboy@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "gameboy@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   },
23 |   "properties" : {
24 |     "template-rendering-intent" : "original"
25 |   }
26 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/gameboy.imageset/gameboy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/gameboy.imageset/gameboy.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/gameboy.imageset/gameboy@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/gameboy.imageset/gameboy@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/gameboy.imageset/gameboy@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/gameboy.imageset/gameboy@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/master-system.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "master-system.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "master-system@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "master-system@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   },
23 |   "properties" : {
24 |     "template-rendering-intent" : "original"
25 |   }
26 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/master-system.imageset/master-system.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/master-system.imageset/master-system.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/master-system.imageset/master-system@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/master-system.imageset/master-system@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/master-system.imageset/master-system@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/master-system.imageset/master-system@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/megadrive.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "megadrive.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "megadrive@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "megadrive@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   },
23 |   "properties" : {
24 |     "template-rendering-intent" : "original"
25 |   }
26 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/megadrive.imageset/megadrive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/megadrive.imageset/megadrive.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/megadrive.imageset/megadrive@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/megadrive.imageset/megadrive@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/megadrive.imageset/megadrive@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/megadrive.imageset/megadrive@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/msx.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "msx.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "msx@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "msx@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   },
23 |   "properties" : {
24 |     "template-rendering-intent" : "original"
25 |   }
26 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/msx.imageset/msx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/msx.imageset/msx.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/msx.imageset/msx@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/msx.imageset/msx@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/msx.imageset/msx@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/msx.imageset/msx@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/nes.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "nes.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "nes@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "nes@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   },
23 |   "properties" : {
24 |     "template-rendering-intent" : "original"
25 |   }
26 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/nes.imageset/nes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/nes.imageset/nes.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/nes.imageset/nes@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/nes.imageset/nes@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/nes.imageset/nes@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/nes.imageset/nes@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/snes.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "snes.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "snes@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "snes@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   },
23 |   "properties" : {
24 |     "template-rendering-intent" : "original"
25 |   }
26 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/snes.imageset/snes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/snes.imageset/snes.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/snes.imageset/snes@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/snes.imageset/snes@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/snes.imageset/snes@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/snes.imageset/snes@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/spectrum.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "spectrum.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "spectrum@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "spectrum@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   },
23 |   "properties" : {
24 |     "template-rendering-intent" : "original"
25 |   }
26 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/spectrum.imageset/spectrum.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/spectrum.imageset/spectrum.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/spectrum.imageset/spectrum@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/spectrum.imageset/spectrum@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/spectrum.imageset/spectrum@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/spectrum.imageset/spectrum@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/turbografx.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "turbografx.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "turbografx@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "turbografx@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   },
23 |   "properties" : {
24 |     "template-rendering-intent" : "original"
25 |   }
26 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/turbografx.imageset/turbografx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/turbografx.imageset/turbografx.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/turbografx.imageset/turbografx@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/turbografx.imageset/turbografx@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Consoles/turbografx.imageset/turbografx@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/Consoles/turbografx.imageset/turbografx@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 |   "info" : {
3 |     "version" : 1,
4 |     "author" : "xcode"
5 |   }
6 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/placeholder-art.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "placeholder-note.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "placeholder-note@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "placeholder-note@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   }
23 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/placeholder-art.imageset/placeholder-note.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/placeholder-art.imageset/placeholder-note.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/placeholder-art.imageset/placeholder-note@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/placeholder-art.imageset/placeholder-note@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/placeholder-art.imageset/placeholder-note@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/placeholder-art.imageset/placeholder-note@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/placeholder-playlist.imageset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "universal",
 5 |       "filename" : "new_playlist@1x.png",
 6 |       "scale" : "1x"
 7 |     },
 8 |     {
 9 |       "idiom" : "universal",
10 |       "filename" : "new_playlist@2x.png",
11 |       "scale" : "2x"
12 |     },
13 |     {
14 |       "idiom" : "universal",
15 |       "filename" : "new_playlist@3x.png",
16 |       "scale" : "3x"
17 |     }
18 |   ],
19 |   "info" : {
20 |     "version" : 1,
21 |     "author" : "xcode"
22 |   },
23 |   "properties" : {
24 |     "template-rendering-intent" : "original"
25 |   }
26 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/placeholder-playlist.imageset/new_playlist@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/placeholder-playlist.imageset/new_playlist@1x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/placeholder-playlist.imageset/new_playlist@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/placeholder-playlist.imageset/new_playlist@2x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Assets.xcassets/placeholder-playlist.imageset/new_playlist@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Assets.xcassets/placeholder-playlist.imageset/new_playlist@3x.png
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 |     
 4 |     
 5 |         
 6 |         
 7 |     
 8 |     
 9 |         
10 |         
11 |             
12 |                 
13 |                     
14 |                         
15 |                         
16 |                         
17 |                         
18 |                         
19 |                             
20 |                             
21 |                         
22 |                     
23 |                     
24 |                         
25 |                         
26 |                             
27 |                             
28 |                         
29 |                     
30 |                 
31 |                 
32 |             
33 |             
34 |         
35 |         
36 |         
37 |             
38 |                 
39 |                     
40 |                         
41 |                         
42 |                     
43 |                     
44 |                         
45 |                     
46 |                 
47 |                 
48 |             
49 |             
50 |         
51 |     
52 | 
53 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/AudioEngine.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  AudioEngine.h
 3 | //  Square Wave
 4 | //
 5 | //  Created by Alex Busman on 5/6/18.
 6 | //  Copyright © 2018 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | #ifndef AudioEngine_h
10 | #define AudioEngine_h
11 | 
12 | #import 
13 | 
14 | @class AppDelegate;
15 | 
16 | @interface TrackInfo : NSObject
17 | 
18 | @property NSString *title;
19 | @property NSString *artist;
20 | @property NSString *system;
21 | @property NSString *game;
22 | @property int play_length;
23 | @property int length;
24 | @property int intro_length;
25 | @property int loop_length;
26 | @end
27 | 
28 | @interface AudioEngine : NSObject
29 | 
30 | + (AudioEngine *)sharedInstance;
31 | - (void)setFileName:(NSString *)fileName;
32 | - (void)setTrack:(int)track;
33 | - (void)setMuteVoices:(int)mask;
34 | - (int)getVoiceCount;
35 | - (const char *)getVoiceName:(int)index;
36 | - (void)play;
37 | - (void)pause;
38 | - (void)stop;
39 | - (void)nextTrack;
40 | - (void)prevTrack;
41 | - (TrackInfo *)getCurrentTrackInfo;
42 | - (int)getElapsedTime;
43 | - (BOOL)getTrackEnded;
44 | - (void)fadeOutCurrentTrack;
45 | - (void)setFadeTime:(int)msec;
46 | - (void)setTempo:(double)tempo;
47 | - (void)ignoreSilence;
48 | - (void)resetFadeTime;
49 | 
50 | @end
51 | #endif /* AudioEngine_h */
52 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/FileEngine.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  FileEngine.h
 3 | //  Square Wave
 4 | //
 5 | //  Created by Alex Busman on 5/8/18.
 6 | //  Copyright © 2018 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | #define __DEBUG_FILE_ENGINE
10 | 
11 | #if defined(__DEBUG_FILE_ENGINE)
12 | #define __DEBUG_FE(m, ...) NSLog((m), __VA_ARGS__)
13 | #else
14 | #define __DEBUG_FE(m, ...)
15 | #endif
16 | 
17 | @class AppDelegate;
18 | @class Track;
19 | @class Game;
20 | @class System;
21 | @class Song;
22 | @class Artist;
23 | 
24 | @protocol FileEngineDelegate
25 | - (void)progress:(NSUInteger)currentIndex total:(NSUInteger)total;
26 | - (void)complete;
27 | - (void)failed:(NSError *_Nonnull)error;
28 | @end
29 | 
30 | @interface FileEngine : NSObject
31 | + (BOOL) removeGame:(Game *_Nonnull)game;
32 | + (BOOL) removeTrack:(Track *_Nonnull)track;
33 | + (void) reloadFromCloudWith:(id_Nonnull)delegate;
34 | + (BOOL) addFile:(nonnull NSURL *)url removeOriginal:(BOOL)removeOriginal;
35 | + (void) refreshDatabase;
36 | + (NSString *_Nonnull) getMusicDirectory;
37 | + (BOOL) clearAll;
38 | + (BOOL) clearDatabase;
39 | @end
40 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/Square Wave-Bridging-Header.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Use this file to import your target's public headers that you would like to expose to Swift.
 3 | //
 4 | 
 5 | #include "pkcs7_union_accessors.h"
 6 | #import "AudioEngine.h"
 7 | #import "FileEngine.h"
 8 | 
 9 | #import 
10 | #import 
11 | #import 
12 | #import 
13 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Ay_Apu.h:
--------------------------------------------------------------------------------
  1 | // AY-3-8910 sound chip emulator
  2 | 
  3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
  4 | #ifndef AY_APU_H
  5 | #define AY_APU_H
  6 | 
  7 | #include "blargg_common.h"
  8 | #include "Blip_Buffer.h"
  9 | 
 10 | class Ay_Apu {
 11 | public:
 12 | 	// Set buffer to generate all sound into, or disable sound if NULL
 13 | 	void output( Blip_Buffer* );
 14 | 	
 15 | 	// Reset sound chip
 16 | 	void reset();
 17 | 	
 18 | 	// Write to register at specified time
 19 | 	enum { reg_count = 16 };
 20 | 	void write( blip_time_t time, int addr, int data );
 21 | 	
 22 | 	// Run sound to specified time, end current time frame, then start a new
 23 | 	// time frame at time 0. Time frames have no effect on emulation and each
 24 | 	// can be whatever length is convenient.
 25 | 	void end_frame( blip_time_t length );
 26 | 	
 27 | // Additional features
 28 | 	
 29 | 	// Set sound output of specific oscillator to buffer, where index is
 30 | 	// 0, 1, or 2. If buffer is NULL, the specified oscillator is muted.
 31 | 	enum { osc_count = 3 };
 32 | 	void osc_output( int index, Blip_Buffer* );
 33 | 	
 34 | 	// Set overall volume (default is 1.0)
 35 | 	void volume( double );
 36 | 	
 37 | 	// Set treble equalization (see documentation)
 38 | 	void treble_eq( blip_eq_t const& );
 39 | 	
 40 | public:
 41 | 	Ay_Apu();
 42 | 	typedef unsigned char byte;
 43 | private:
 44 | 	struct osc_t
 45 | 	{
 46 | 		blip_time_t period;
 47 | 		blip_time_t delay;
 48 | 		short last_amp;
 49 | 		short phase;
 50 | 		Blip_Buffer* output;
 51 | 	} oscs [osc_count];
 52 | 	blip_time_t last_time;
 53 | 	byte regs [reg_count];
 54 | 	
 55 | 	struct {
 56 | 		blip_time_t delay;
 57 | 		blargg_ulong lfsr;
 58 | 	} noise;
 59 | 	
 60 | 	struct {
 61 | 		blip_time_t delay;
 62 | 		byte const* wave;
 63 | 		int pos;
 64 | 		byte modes [8] [48]; // values already passed through volume table
 65 | 	} env;
 66 | 	
 67 | 	void run_until( blip_time_t );
 68 | 	void write_data_( int addr, int data );
 69 | public:
 70 | 	enum { amp_range = 255 };
 71 | 	Blip_Synth synth_;
 72 | };
 73 | 
 74 | inline void Ay_Apu::volume( double v ) { synth_.volume( 0.7 / osc_count / amp_range * v ); }
 75 | 
 76 | inline void Ay_Apu::treble_eq( blip_eq_t const& eq ) { synth_.treble_eq( eq ); }
 77 | 
 78 | inline void Ay_Apu::write( blip_time_t time, int addr, int data )
 79 | {
 80 | 	run_until( time );
 81 | 	write_data_( addr, data );
 82 | }
 83 | 
 84 | inline void Ay_Apu::osc_output( int i, Blip_Buffer* buf )
 85 | {
 86 | 	assert( (unsigned) i < osc_count );
 87 | 	oscs [i].output = buf;
 88 | }
 89 | 
 90 | inline void Ay_Apu::output( Blip_Buffer* buf )
 91 | {
 92 | 	osc_output( 0, buf );
 93 | 	osc_output( 1, buf );
 94 | 	osc_output( 2, buf );
 95 | }
 96 | 
 97 | inline void Ay_Apu::end_frame( blip_time_t time )
 98 | {
 99 | 	if ( time > last_time )
100 | 		run_until( time );
101 | 	
102 | 	assert( last_time >= time );
103 | 	last_time -= time;
104 | }
105 | 
106 | #endif
107 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Ay_Cpu.h:
--------------------------------------------------------------------------------
 1 | // Z80 CPU emulator
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef AY_CPU_H
 5 | #define AY_CPU_H
 6 | 
 7 | #include "blargg_endian.h"
 8 | 
 9 | typedef blargg_long cpu_time_t;
10 | 
11 | // must be defined by caller
12 | void ay_cpu_out( class Ay_Cpu*, cpu_time_t, unsigned addr, int data );
13 | int ay_cpu_in( class Ay_Cpu*, unsigned addr );
14 | 
15 | class Ay_Cpu {
16 | public:
17 | 	// Clear all registers and keep pointer to 64K memory passed in
18 | 	void reset( void* mem_64k );
19 | 	
20 | 	// Run until specified time is reached. Returns true if suspicious/unsupported
21 | 	// instruction was encountered at any point during run.
22 | 	bool run( cpu_time_t end_time );
23 | 	
24 | 	// Time of beginning of next instruction
25 | 	cpu_time_t time() const             { return state->time + state->base; }
26 | 	
27 | 	// Alter current time. Not supported during run() call.
28 | 	void set_time( cpu_time_t t )       { state->time = t - state->base; }
29 | 	void adjust_time( int delta )       { state->time += delta; }
30 | 	
31 | 	#if BLARGG_BIG_ENDIAN
32 | 		struct regs_t { uint8_t b, c, d, e, h, l, flags, a; };
33 | 	#else
34 | 		struct regs_t { uint8_t c, b, e, d, l, h, a, flags; };
35 | 	#endif
36 | 	BOOST_STATIC_ASSERT( sizeof (regs_t) == 8 );
37 | 	
38 | 	struct pairs_t { uint16_t bc, de, hl, fa; };
39 | 	
40 | 	// Registers are not updated until run() returns
41 | 	struct registers_t {
42 | 		uint16_t pc;
43 | 		uint16_t sp;
44 | 		uint16_t ix;
45 | 		uint16_t iy;
46 | 		union {
47 | 			regs_t b; //  b.b, b.c, b.d, b.e, b.h, b.l, b.flags, b.a
48 | 			pairs_t w; // w.bc, w.de, w.hl. w.fa
49 | 		};
50 | 		union {
51 | 			regs_t b;
52 | 			pairs_t w;
53 | 		} alt;
54 | 		uint8_t iff1;
55 | 		uint8_t iff2;
56 | 		uint8_t r;
57 | 		uint8_t i;
58 | 		uint8_t im;
59 | 	};
60 | 	//registers_t r; (below for efficiency)
61 | 	
62 | 	// can read this far past end of memory
63 | 	enum { cpu_padding = 0x100 };
64 | 	
65 | public:
66 | 	Ay_Cpu();
67 | private:
68 | 	uint8_t szpc [0x200];
69 | 	uint8_t* mem;
70 | 	cpu_time_t end_time_;
71 | 	struct state_t {
72 | 		cpu_time_t base;
73 | 		cpu_time_t time;
74 | 	};
75 | 	state_t* state; // points to state_ or a local copy within run()
76 | 	state_t state_;
77 | 	void set_end_time( cpu_time_t t );
78 | public:
79 | 	registers_t r;
80 | };
81 | 
82 | inline void Ay_Cpu::set_end_time( cpu_time_t t )
83 | {
84 | 	cpu_time_t delta = state->base - t;
85 | 	state->base = t;
86 | 	state->time += delta;
87 | }
88 | 
89 | #endif
90 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Ay_Emu.h:
--------------------------------------------------------------------------------
 1 | // Sinclair Spectrum AY music file emulator
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef AY_EMU_H
 5 | #define AY_EMU_H
 6 | 
 7 | #include "Classic_Emu.h"
 8 | #include "Ay_Apu.h"
 9 | #include "Ay_Cpu.h"
10 | 
11 | class Ay_Emu : private Ay_Cpu, public Classic_Emu {
12 | 	typedef Ay_Cpu cpu;
13 | public:
14 | 	// AY file header
15 | 	enum { header_size = 0x14 };
16 | 	struct header_t
17 | 	{
18 | 		byte tag [8];
19 | 		byte vers;
20 | 		byte player;
21 | 		byte unused [2];
22 | 		byte author [2];
23 | 		byte comment [2];
24 | 		byte max_track;
25 | 		byte first_track;
26 | 		byte track_info [2];
27 | 	};
28 | 	
29 | 	static gme_type_t static_type() { return gme_ay_type; }
30 | public:
31 | 	Ay_Emu();
32 | 	~Ay_Emu();
33 | 	struct file_t {
34 | 		header_t const* header;
35 | 		byte const* end;
36 | 		byte const* tracks;
37 | 	};
38 | protected:
39 | 	blargg_err_t track_info_( track_info_t*, int track ) const;
40 | 	blargg_err_t load_mem_( byte const*, long );
41 | 	blargg_err_t start_track_( int );
42 | 	blargg_err_t run_clocks( blip_time_t&, int );
43 | 	void set_tempo_( double );
44 | 	void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
45 | 	void update_eq( blip_eq_t const& );
46 | private:
47 | 	file_t file;
48 | 	
49 | 	cpu_time_t play_period;
50 | 	cpu_time_t next_play;
51 | 	Blip_Buffer* beeper_output;
52 | 	int beeper_delta;
53 | 	int last_beeper;
54 | 	int apu_addr;
55 | 	int cpc_latch;
56 | 	bool spectrum_mode;
57 | 	bool cpc_mode;
58 | 	
59 | 	// large items
60 | 	struct {
61 | 		byte padding1 [0x100];
62 | 		byte ram [0x10000 + 0x100];
63 | 	} mem;
64 | 	Ay_Apu apu;
65 | 	friend void ay_cpu_out( Ay_Cpu*, cpu_time_t, unsigned addr, int data );
66 | 	void cpu_out_misc( cpu_time_t, unsigned addr, int data );
67 | };
68 | 
69 | #endif
70 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Classic_Emu.h:
--------------------------------------------------------------------------------
  1 | // Common aspects of emulators which use Blip_Buffer for sound output
  2 | 
  3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
  4 | #ifndef CLASSIC_EMU_H
  5 | #define CLASSIC_EMU_H
  6 | 
  7 | #include "blargg_common.h"
  8 | #include "Blip_Buffer.h"
  9 | #include "Music_Emu.h"
 10 | 
 11 | class Classic_Emu : public Music_Emu {
 12 | public:
 13 | 	Classic_Emu();
 14 | 	~Classic_Emu();
 15 | 	void set_buffer( Multi_Buffer* );
 16 | 	blargg_err_t set_multi_channel( bool is_enabled ) override;
 17 | protected:
 18 | 	// Services
 19 | 	enum { wave_type = 0x100, noise_type = 0x200, mixed_type = wave_type | noise_type };
 20 | 	void set_voice_types( int const* t ) { voice_types = t; }
 21 | 	blargg_err_t setup_buffer( long clock_rate );
 22 | 	long clock_rate() const { return clock_rate_; }
 23 | 	void change_clock_rate( long ); // experimental
 24 | 	
 25 | 	// Overridable
 26 | 	virtual void set_voice( int index, Blip_Buffer* center,
 27 | 			Blip_Buffer* left, Blip_Buffer* right ) = 0;
 28 | 	virtual void update_eq( blip_eq_t const& ) = 0;
 29 | 	virtual blargg_err_t start_track_( int track ) = 0;
 30 | 	virtual blargg_err_t run_clocks( blip_time_t& time_io, int msec ) = 0;
 31 | protected:
 32 | 	blargg_err_t set_sample_rate_( long sample_rate );
 33 | 	void mute_voices_( int );
 34 | 	void set_equalizer_( equalizer_t const& );
 35 | 	blargg_err_t play_( long, sample_t* );
 36 | private:
 37 | 	Multi_Buffer* buf;
 38 | 	Multi_Buffer* stereo_buffer; // NULL if using custom buffer
 39 | 	long clock_rate_;
 40 | 	unsigned buf_changed_count;
 41 | 	int const* voice_types;
 42 | };
 43 | 
 44 | inline void Classic_Emu::set_buffer( Multi_Buffer* new_buf )
 45 | {
 46 | 	assert( !buf && new_buf );
 47 | 	buf = new_buf;
 48 | }
 49 | 
 50 | // ROM data handler, used by several Classic_Emu derivitives. Loads file data
 51 | // with padding on both sides, allowing direct use in bank mapping. The main purpose
 52 | // is to allow all file data to be loaded with only one read() call (for efficiency).
 53 | 
 54 | class Rom_Data_ {
 55 | public:
 56 | 	typedef unsigned char byte;
 57 | protected:
 58 | 	enum { pad_extra = 8 };
 59 | 	blargg_vector rom;
 60 | 	long file_size_;
 61 | 	blargg_long rom_addr;
 62 | 	blargg_long mask;
 63 | 	blargg_long size_; // TODO: eliminate
 64 | 	
 65 | 	blargg_err_t load_rom_data_( Data_Reader& in, int header_size, void* header_out,
 66 | 			int fill, long pad_size );
 67 | 	void set_addr_( long addr, int unit );
 68 | };
 69 | 
 70 | template
 71 | class Rom_Data : public Rom_Data_ {
 72 | 	enum { pad_size = unit + pad_extra };
 73 | public:
 74 | 	// Load file data, using already-loaded header 'h' if not NULL. Copy header
 75 | 	// from loaded file data into *out and fill unmapped bytes with 'fill'.
 76 | 	blargg_err_t load( Data_Reader& in, int header_size, void* header_out, int fill )
 77 | 	{
 78 | 		return load_rom_data_( in, header_size, header_out, fill, pad_size );
 79 | 	}
 80 | 	
 81 | 	// Size of file data read in (excluding header)
 82 | 	long file_size() const { return file_size_; }
 83 | 	
 84 | 	// Pointer to beginning of file data
 85 | 	byte* begin() const { return rom.begin() + pad_size; }
 86 | 	
 87 | 	// Set address that file data should start at
 88 | 	void set_addr( long addr ) { set_addr_( addr, unit ); }
 89 | 	
 90 | 	// Free data
 91 | 	void clear() { rom.clear(); }
 92 | 	
 93 | 	// Size of data + start addr, rounded to a multiple of unit
 94 | 	long size() const { return size_; }
 95 | 	
 96 | 	// Pointer to unmapped page filled with same value
 97 | 	byte* unmapped() { return rom.begin(); }
 98 | 	
 99 | 	// Mask address to nearest power of two greater than size()
100 | 	blargg_long mask_addr( blargg_long addr ) const
101 | 	{
102 | 		#ifdef check
103 | 			check( addr <= mask );
104 | 		#endif
105 | 		return addr & mask;
106 | 	}
107 | 	
108 | 	// Pointer to page starting at addr. Returns unmapped() if outside data.
109 | 	byte* at_addr( blargg_long addr )
110 | 	{
111 | 		blargg_ulong offset = mask_addr( addr ) - rom_addr;
112 | 		if ( offset > blargg_ulong (rom.size() - pad_size) )
113 | 			offset = 0; // unmapped
114 | 		return &rom [offset];
115 | 	}
116 | };
117 | 
118 | #ifndef GME_APU_HOOK
119 | 	#define GME_APU_HOOK( emu, addr, data ) ((void) 0)
120 | #endif
121 | 
122 | #ifndef GME_FRAME_HOOK
123 | 	#define GME_FRAME_HOOK( emu ) ((void) 0)
124 | #else
125 | 	#define GME_FRAME_HOOK_DEFINED 1
126 | #endif
127 | 
128 | #endif
129 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Data_Reader.h:
--------------------------------------------------------------------------------
  1 | // Data reader interface for uniform access
  2 | 
  3 | // File_Extractor 0.4.0
  4 | #ifndef DATA_READER_H
  5 | #define DATA_READER_H
  6 | 
  7 | #include "blargg_common.h"
  8 | 
  9 | #ifdef HAVE_ZLIB_H
 10 | #include 
 11 | #endif
 12 | 
 13 | // Supports reading and finding out how many bytes are remaining
 14 | class Data_Reader {
 15 | public:
 16 | 	virtual ~Data_Reader() { }
 17 | 	
 18 | 	static const char eof_error []; // returned by read() when request goes beyond end
 19 | 	
 20 | 	// Read at most count bytes and return number actually read, or <= 0 if error
 21 | 	virtual long read_avail( void*, long n ) = 0;
 22 | 	
 23 | 	// Read exactly count bytes and return error if they couldn't be read
 24 | 	virtual blargg_err_t read( void*, long count );
 25 | 	
 26 | 	// Number of bytes remaining until end of file
 27 | 	virtual long remain() const = 0;
 28 | 	
 29 | 	// Read and discard count bytes
 30 | 	virtual blargg_err_t skip( long count );
 31 | 	
 32 | public:
 33 | 	Data_Reader() { }
 34 | 	typedef blargg_err_t error_t; // deprecated
 35 | private:
 36 | 	// noncopyable
 37 | 	Data_Reader( const Data_Reader& );
 38 | 	Data_Reader& operator = ( const Data_Reader& );
 39 | };
 40 | 
 41 | // Supports seeking in addition to Data_Reader operations
 42 | class File_Reader : public Data_Reader {
 43 | public:
 44 | 	// Size of file
 45 | 	virtual long size() const = 0;
 46 | 	
 47 | 	// Current position in file
 48 | 	virtual long tell() const = 0;
 49 | 	
 50 | 	// Go to new position
 51 | 	virtual blargg_err_t seek( long ) = 0;
 52 | 	
 53 | 	long remain() const;
 54 | 	blargg_err_t skip( long n );
 55 | };
 56 | 
 57 | // Disk file reader
 58 | class Std_File_Reader : public File_Reader {
 59 | public:
 60 | 	blargg_err_t open( const char* path );
 61 | 	void close();
 62 | 	
 63 | public:
 64 | 	Std_File_Reader();
 65 | 	~Std_File_Reader();
 66 | 	long size() const;
 67 | 	blargg_err_t read( void*, long );
 68 | 	long read_avail( void*, long );
 69 | 	long tell() const;
 70 | 	blargg_err_t seek( long );
 71 | private:
 72 | 	void* file_; // Either FILE* or zlib's gzFile
 73 | #ifdef HAVE_ZLIB_H
 74 | 	long size_; // TODO: Fix ABI compat
 75 | #endif /* HAVE_ZLIB_H */
 76 | };
 77 | 
 78 | // Treats range of memory as a file
 79 | class Mem_File_Reader : public File_Reader {
 80 | public:
 81 | 	Mem_File_Reader( const void*, long size );
 82 | #ifdef HAVE_ZLIB_H
 83 | 	~Mem_File_Reader( );
 84 | #endif /* HAVE_ZLIB_H */
 85 | 
 86 | public:
 87 | 	long size() const;
 88 | 	long read_avail( void*, long );
 89 | 	long tell() const;
 90 | 	blargg_err_t seek( long );
 91 | private:
 92 | #ifdef HAVE_ZLIB_H
 93 | 	bool gz_decompress();
 94 | #endif /* HAVE_ZLIB_H */
 95 | 
 96 | 	const char* m_begin;
 97 | 	long m_size;
 98 | 	long m_pos;
 99 | #ifdef HAVE_ZLIB_H
100 | 	bool m_ownedPtr = false; // set if we must free m_begin
101 | #endif /* HAVE_ZLIB_H */
102 | };
103 | 
104 | 
105 | // Makes it look like there are only count bytes remaining
106 | class Subset_Reader : public Data_Reader {
107 | public:
108 | 	Subset_Reader( Data_Reader*, long count );
109 | 
110 | public:
111 | 	long remain() const;
112 | 	long read_avail( void*, long );
113 | private:
114 | 	Data_Reader* in;
115 | 	long remain_;
116 | };
117 | 
118 | // Joins already-read header and remaining data into original file (to avoid seeking)
119 | class Remaining_Reader : public Data_Reader {
120 | public:
121 | 	Remaining_Reader( void const* header, long size, Data_Reader* );
122 | 
123 | public:
124 | 	long remain() const;
125 | 	long read_avail( void*, long );
126 | 	blargg_err_t read( void*, long );
127 | private:
128 | 	char const* header;
129 | 	char const* header_end;
130 | 	Data_Reader* in;
131 | 	long read_first( void* out, long count );
132 | };
133 | 
134 | // Invokes callback function to read data. Size of data must be specified in advance.
135 | class Callback_Reader : public Data_Reader {
136 | public:
137 | 	typedef const char* (*callback_t)( void* data, void* out, int count );
138 | 	Callback_Reader( callback_t, long size, void* data = 0 );
139 | public:
140 | 	long read_avail( void*, long );
141 | 	blargg_err_t read( void*, long );
142 | 	long remain() const;
143 | private:
144 | 	callback_t const callback;
145 | 	void* const data;
146 | 	long remain_;
147 | };
148 | 
149 | #endif
150 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Dual_Resampler.cpp:
--------------------------------------------------------------------------------
  1 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
  2 | 
  3 | #include "Dual_Resampler.h"
  4 | 
  5 | #include 
  6 | #include 
  7 | 
  8 | /* Copyright (C) 2003-2006 Shay Green. This module is free software; you
  9 | can redistribute it and/or modify it under the terms of the GNU Lesser
 10 | General Public License as published by the Free Software Foundation; either
 11 | version 2.1 of the License, or (at your option) any later version. This
 12 | module is distributed in the hope that it will be useful, but WITHOUT ANY
 13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 14 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 15 | details. You should have received a copy of the GNU Lesser General Public
 16 | License along with this module; if not, write to the Free Software Foundation,
 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
 18 | 
 19 | #include "blargg_source.h"
 20 | 
 21 | unsigned const resampler_extra = 256;
 22 | 
 23 | Dual_Resampler::Dual_Resampler() :
 24 | 	sample_buf_size(0),
 25 | 	oversamples_per_frame(-1),
 26 | 	buf_pos(-1),
 27 | 	resampler_size(0)
 28 | {
 29 | }
 30 | 
 31 | Dual_Resampler::~Dual_Resampler() { }
 32 | 
 33 | blargg_err_t Dual_Resampler::reset( int pairs )
 34 | {
 35 | 	// expand allocations a bit
 36 | 	RETURN_ERR( sample_buf.resize( (pairs + (pairs >> 2)) * 2 ) );
 37 | 	resize( pairs );
 38 | 	resampler_size = oversamples_per_frame + (oversamples_per_frame >> 2);
 39 | 	return resampler.buffer_size( resampler_size );
 40 | }
 41 | 
 42 | void Dual_Resampler::resize( int pairs )
 43 | {
 44 | 	int new_sample_buf_size = pairs * 2;
 45 | 	if ( sample_buf_size != new_sample_buf_size )
 46 | 	{
 47 | 		if ( (unsigned) new_sample_buf_size > sample_buf.size() )
 48 | 		{
 49 | 			check( false );
 50 | 			return;
 51 | 		}
 52 | 		sample_buf_size = new_sample_buf_size;
 53 | 		oversamples_per_frame = int (pairs * resampler.ratio()) * 2 + 2;
 54 | 		clear();
 55 | 	}
 56 | }
 57 | 
 58 | void Dual_Resampler::play_frame_( Blip_Buffer& blip_buf, dsample_t* out )
 59 | {
 60 | 	long pair_count = sample_buf_size >> 1;
 61 | 	blip_time_t blip_time = blip_buf.count_clocks( pair_count );
 62 | 	int sample_count = oversamples_per_frame - resampler.written();
 63 | 	
 64 | 	int new_count = play_frame( blip_time, sample_count, resampler.buffer() );
 65 | 	assert( new_count < resampler_size );
 66 | 	
 67 | 	blip_buf.end_frame( blip_time );
 68 | 	assert( blip_buf.samples_avail() == pair_count );
 69 | 	
 70 | 	resampler.write( new_count );
 71 | 
 72 | #ifdef	NDEBUG // Avoid warning when asserts are disabled
 73 | 	resampler.read( sample_buf.begin(), sample_buf_size );
 74 | #else
 75 | 	long count = resampler.read( sample_buf.begin(), sample_buf_size );
 76 | 	assert( count == (long) sample_buf_size );
 77 | #endif
 78 | 	
 79 | 	mix_samples( blip_buf, out );
 80 | 	blip_buf.remove_samples( pair_count );
 81 | }
 82 | 
 83 | void Dual_Resampler::dual_play( long count, dsample_t* out, Blip_Buffer& blip_buf )
 84 | {
 85 | 	// empty extra buffer
 86 | 	long remain = sample_buf_size - buf_pos;
 87 | 	if ( remain )
 88 | 	{
 89 | 		if ( remain > count )
 90 | 			remain = count;
 91 | 		count -= remain;
 92 | 		memcpy( out, &sample_buf [buf_pos], remain * sizeof *out );
 93 | 		out += remain;
 94 | 		buf_pos += remain;
 95 | 	}
 96 | 	
 97 | 	// entire frames
 98 | 	while ( count >= (long) sample_buf_size )
 99 | 	{
100 | 		play_frame_( blip_buf, out );
101 | 		out += sample_buf_size;
102 | 		count -= sample_buf_size;
103 | 	}
104 | 	
105 | 	// extra
106 | 	if ( count )
107 | 	{
108 | 		play_frame_( blip_buf, sample_buf.begin() );
109 | 		buf_pos = count;
110 | 		memcpy( out, sample_buf.begin(), count * sizeof *out );
111 | 		out += count;
112 | 	}
113 | }
114 | 
115 | void Dual_Resampler::mix_samples( Blip_Buffer& blip_buf, dsample_t* out )
116 | {
117 | 	Blip_Reader sn;
118 | 	int bass = sn.begin( blip_buf );
119 | 	const dsample_t* in = sample_buf.begin();
120 | 	
121 | 	for ( int n = sample_buf_size >> 1; n--; )
122 | 	{
123 | 		int s = sn.read();
124 | 		blargg_long l = (blargg_long) in [0] * 2 + s;
125 | 		if ( (int16_t) l != l )
126 | 			l = 0x7FFF - (l >> 24);
127 | 		
128 | 		sn.next( bass );
129 | 		blargg_long r = (blargg_long) in [1] * 2 + s;
130 | 		if ( (int16_t) r != r )
131 | 			r = 0x7FFF - (r >> 24);
132 | 		
133 | 		in += 2;
134 | 		out [0] = l;
135 | 		out [1] = r;
136 | 		out += 2;
137 | 	}
138 | 	
139 | 	sn.end( blip_buf );
140 | }
141 | 
142 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Dual_Resampler.h:
--------------------------------------------------------------------------------
 1 | // Combination of Fir_Resampler and Blip_Buffer mixing. Used by Sega FM emulators.
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef DUAL_RESAMPLER_H
 5 | #define DUAL_RESAMPLER_H
 6 | 
 7 | #include "Fir_Resampler.h"
 8 | #include "Blip_Buffer.h"
 9 | 
10 | class Dual_Resampler {
11 | public:
12 | 	Dual_Resampler();
13 | 	virtual ~Dual_Resampler();
14 | 	
15 | 	typedef short dsample_t;
16 | 	
17 | 	double setup( double oversample, double rolloff, double gain );
18 | 	blargg_err_t reset( int max_pairs );
19 | 	void resize( int pairs_per_frame );
20 | 	void clear();
21 | 	
22 | 	void dual_play( long count, dsample_t* out, Blip_Buffer& );
23 | 	
24 | protected:
25 | 	virtual int play_frame( blip_time_t, int pcm_count, dsample_t* pcm_out ) = 0;
26 | private:
27 | 	
28 | 	blargg_vector sample_buf;
29 | 	int sample_buf_size;
30 | 	int oversamples_per_frame;
31 | 	int buf_pos;
32 | 	int resampler_size;
33 | 	
34 | 	Fir_Resampler<12> resampler;
35 | 	void mix_samples( Blip_Buffer&, dsample_t* );
36 | 	void play_frame_( Blip_Buffer&, dsample_t* );
37 | };
38 | 
39 | inline double Dual_Resampler::setup( double oversample, double rolloff, double gain )
40 | {
41 | 	return resampler.time_ratio( oversample, rolloff, gain * 0.5 );
42 | }
43 | 
44 | inline void Dual_Resampler::clear()
45 | {
46 | 	buf_pos = sample_buf_size;
47 | 	resampler.clear();
48 | }
49 | 
50 | #endif
51 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Effects_Buffer.h:
--------------------------------------------------------------------------------
 1 | // Multi-channel effects buffer with panning, echo and reverb
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef EFFECTS_BUFFER_H
 5 | #define EFFECTS_BUFFER_H
 6 | 
 7 | #include "Multi_Buffer.h"
 8 | 
 9 | #include 
10 | 
11 | // Effects_Buffer uses several buffers and outputs stereo sample pairs.
12 | class Effects_Buffer : public Multi_Buffer {
13 | public:
14 | 	// nVoices indicates the number of voices for which buffers will be allocated
15 | 	// to make Effects_Buffer work as "mix everything to one", nVoices will be 1
16 | 	// If center_only is true, only center buffers are created and
17 | 	// less memory is used.
18 | 	Effects_Buffer( int nVoices = 1, bool center_only = false );
19 | 	
20 | 	// Channel  Effect    Center Pan
21 | 	// ---------------------------------
22 | 	//    0,5    reverb       pan_1
23 | 	//    1,6    reverb       pan_2
24 | 	//    2,7    echo         -
25 | 	//    3      echo         -
26 | 	//    4      echo         -
27 | 	
28 | 	// Channel configuration
29 | 	struct config_t {
30 | 		double pan_1;           // -1.0 = left, 0.0 = center, 1.0 = right
31 | 		double pan_2;
32 | 		double echo_delay;      // msec
33 | 		double echo_level;      // 0.0 to 1.0
34 | 		double reverb_delay;    // msec
35 | 		double delay_variance;  // difference between left/right delays (msec)
36 | 		double reverb_level;    // 0.0 to 1.0
37 | 		bool effects_enabled;   // if false, use optimized simple mixer
38 | 		config_t();
39 | 	};
40 | 	
41 | 	// Set configuration of buffer
42 | 	virtual void config( const config_t& );
43 | 	void set_depth( double );
44 | 	
45 | public:
46 | 	~Effects_Buffer();
47 | 	blargg_err_t set_sample_rate( long samples_per_sec, int msec = blip_default_length );
48 | 	void clock_rate( long );
49 | 	void bass_freq( int );
50 | 	void clear();
51 | 	channel_t channel( int, int );
52 | 	void end_frame( blip_time_t );
53 | 	long read_samples( blip_sample_t*, long );
54 | 	long samples_avail() const;
55 | private:
56 | 	typedef long fixed_t;
57 | 	int max_voices;
58 | 	enum { max_buf_count = 7 };
59 | 	std::vector bufs;
60 | 	enum { chan_types_count = 3 };
61 | 	std::vector chan_types;
62 | 	config_t config_;
63 | 	long stereo_remain;
64 | 	long effect_remain;
65 | 	int buf_count;
66 | 	bool effects_enabled;
67 | 	
68 | 	std::vector > reverb_buf;
69 | 	std::vector > echo_buf;
70 | 	std::vector reverb_pos;
71 | 	std::vector echo_pos;
72 | 	
73 | 	struct {
74 | 		fixed_t pan_1_levels [2];
75 | 		fixed_t pan_2_levels [2];
76 | 		int echo_delay_l;
77 | 		int echo_delay_r;
78 | 		fixed_t echo_level;
79 | 		int reverb_delay_l;
80 | 		int reverb_delay_r;
81 | 		fixed_t reverb_level;
82 | 	} chans;
83 | 	
84 | 	void mix_mono( blip_sample_t*, blargg_long );
85 | 	void mix_stereo( blip_sample_t*, blargg_long );
86 | 	void mix_enhanced( blip_sample_t*, blargg_long );
87 | 	void mix_mono_enhanced( blip_sample_t*, blargg_long );
88 | };
89 | 
90 | #endif
91 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Gb_Apu.h:
--------------------------------------------------------------------------------
 1 | // Nintendo Game Boy PAPU sound chip emulator
 2 | 
 3 | // Gb_Snd_Emu 0.1.5
 4 | #ifndef GB_APU_H
 5 | #define GB_APU_H
 6 | 
 7 | #include "Gb_Oscs.h"
 8 | 
 9 | class Gb_Apu {
10 | public:
11 | 	
12 | 	// Set overall volume of all oscillators, where 1.0 is full volume
13 | 	void volume( double );
14 | 	
15 | 	// Set treble equalization
16 | 	void treble_eq( const blip_eq_t& );
17 | 	
18 | 	// Outputs can be assigned to a single buffer for mono output, or to three
19 | 	// buffers for stereo output (using Stereo_Buffer to do the mixing).
20 | 	
21 | 	// Assign all oscillator outputs to specified buffer(s). If buffer
22 | 	// is NULL, silences all oscillators.
23 | 	void output( Blip_Buffer* mono );
24 | 	void output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
25 | 	
26 | 	// Assign single oscillator output to buffer(s). Valid indicies are 0 to 3,
27 | 	// which refer to Square 1, Square 2, Wave, and Noise. If buffer is NULL,
28 | 	// silences oscillator.
29 | 	enum { osc_count = 4 };
30 | 	void osc_output( int index, Blip_Buffer* mono );
31 | 	void osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
32 | 	
33 | 	// Reset oscillators and internal state
34 | 	void reset();
35 | 	
36 | 	// Reads and writes at addr must satisfy start_addr <= addr <= end_addr
37 | 	enum { start_addr = 0xFF10 };
38 | 	enum { end_addr   = 0xFF3F };
39 | 	enum { register_count = end_addr - start_addr + 1 };
40 | 	
41 | 	// Write 'data' to address at specified time
42 | 	void write_register( blip_time_t, unsigned addr, int data );
43 | 	
44 | 	// Read from address at specified time
45 | 	int read_register( blip_time_t, unsigned addr );
46 | 	
47 | 	// Run all oscillators up to specified time, end current time frame, then
48 | 	// start a new frame at time 0.
49 | 	void end_frame( blip_time_t );
50 | 	
51 | 	void set_tempo( double );
52 | 	
53 | public:
54 | 	Gb_Apu();
55 | private:
56 | 	// noncopyable
57 | 	Gb_Apu( const Gb_Apu& );
58 | 	Gb_Apu& operator = ( const Gb_Apu& );
59 | 	
60 | 	Gb_Osc*     oscs [osc_count];
61 | 	blip_time_t   next_frame_time;
62 | 	blip_time_t   last_time;
63 | 	blip_time_t frame_period;
64 | 	double      volume_unit;
65 | 	int         frame_count;
66 | 	
67 | 	Gb_Square   square1;
68 | 	Gb_Square   square2;
69 | 	Gb_Wave     wave;
70 | 	Gb_Noise    noise;
71 | 	uint8_t regs [register_count];
72 | 	Gb_Square::Synth square_synth; // used by squares
73 | 	Gb_Wave::Synth   other_synth;  // used by wave and noise
74 | 	
75 | 	void update_volume();
76 | 	void run_until( blip_time_t );
77 | 	void write_osc( int index, int reg, int data );
78 | };
79 | 
80 | inline void Gb_Apu::output( Blip_Buffer* b ) { output( b, b, b ); }
81 | 	
82 | inline void Gb_Apu::osc_output( int i, Blip_Buffer* b ) { osc_output( i, b, b, b ); }
83 | 
84 | inline void Gb_Apu::volume( double vol )
85 | {
86 | 	volume_unit = 0.60 / osc_count / 15 /*steps*/ / 2 /*?*/ / 8 /*master vol range*/ * vol;
87 | 	update_volume();
88 | }
89 | 
90 | #endif
91 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Gb_Cpu.h:
--------------------------------------------------------------------------------
 1 | // Nintendo Game Boy CPU emulator
 2 | // Treats every instruction as taking 4 cycles
 3 | 
 4 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 5 | #ifndef GB_CPU_H
 6 | #define GB_CPU_H
 7 | 
 8 | #include "blargg_common.h"
 9 | #include "blargg_endian.h"
10 | 
11 | typedef unsigned gb_addr_t; // 16-bit CPU address
12 | 
13 | class Gb_Cpu {
14 | 	enum { clocks_per_instr = 4 };
15 | public:
16 | 	// Clear registers and map all pages to unmapped
17 | 	void reset( void* unmapped = 0 );
18 | 	
19 | 	// Map code memory (memory accessed via the program counter). Start and size
20 | 	// must be multiple of page_size.
21 | 	enum { page_size = 0x2000 };
22 | 	void map_code( gb_addr_t start, unsigned size, void* code );
23 | 	
24 | 	uint8_t* get_code( gb_addr_t );
25 | 	
26 | 	// Push a byte on the stack
27 | 	void push_byte( int );
28 | 	
29 | 	// Game Boy Z80 registers. *Not* kept updated during a call to run().
30 | 	struct core_regs_t {
31 | 	#if BLARGG_BIG_ENDIAN
32 | 		uint8_t b, c, d, e, h, l, flags, a;
33 | 	#else
34 | 		uint8_t c, b, e, d, l, h, a, flags;
35 | 	#endif
36 | 	};
37 | 	
38 | 	struct registers_t : core_regs_t {
39 | 		long pc; // more than 16 bits to allow overflow detection
40 | 		uint16_t sp;
41 | 	};
42 | 	registers_t r;
43 | 	
44 | 	// Interrupt enable flag set by EI and cleared by DI
45 | 	//bool interrupts_enabled; // unused
46 | 	
47 | 	// Base address for RST vectors (normally 0)
48 | 	gb_addr_t rst_base;
49 | 	
50 | 	// If CPU executes opcode 0xFF at this address, it treats as illegal instruction
51 | 	enum { idle_addr = 0xF00D };
52 | 	
53 | 	// Run CPU for at least 'count' cycles and return false, or return true if
54 | 	// illegal instruction is encountered.
55 | 	bool run( blargg_long count );
56 | 	
57 | 	// Number of clock cycles remaining for most recent run() call
58 | 	blargg_long remain() const { return state->remain * clocks_per_instr; }
59 | 	
60 | 	// Can read this many bytes past end of a page
61 | 	enum { cpu_padding = 8 };
62 | 	
63 | public:
64 | 	Gb_Cpu() : rst_base( 0 ) { state = &state_; }
65 | 	enum { page_shift = 13 };
66 | 	enum { page_count = 0x10000 >> page_shift };
67 | private:
68 | 	// noncopyable
69 | 	Gb_Cpu( const Gb_Cpu& );
70 | 	Gb_Cpu& operator = ( const Gb_Cpu& );
71 | 	
72 | 	struct state_t {
73 | 		uint8_t* code_map [page_count + 1];
74 | 		blargg_long remain;
75 | 	};
76 | 	state_t* state; // points to state_ or a local copy within run()
77 | 	state_t state_;
78 | 	
79 | 	void set_code_page( int, uint8_t* );
80 | };
81 | 
82 | inline uint8_t* Gb_Cpu::get_code( gb_addr_t addr )
83 | {
84 | 	return state->code_map [addr >> page_shift] + addr
85 | 	#if !BLARGG_NONPORTABLE
86 | 		% (unsigned) page_size
87 | 	#endif
88 | 	;
89 | }
90 | 
91 | #endif
92 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Gb_Oscs.h:
--------------------------------------------------------------------------------
 1 | // Private oscillators used by Gb_Apu
 2 | 
 3 | // Gb_Snd_Emu 0.1.5
 4 | #ifndef GB_OSCS_H
 5 | #define GB_OSCS_H
 6 | 
 7 | #include "blargg_common.h"
 8 | #include "Blip_Buffer.h"
 9 | 
10 | struct Gb_Osc
11 | {
12 | 	enum { trigger = 0x80 };
13 | 	enum { len_enabled_mask = 0x40 };
14 | 	
15 | 	Blip_Buffer* outputs [4]; // NULL, right, left, center
16 | 	Blip_Buffer* output;
17 | 	int output_select;
18 | 	uint8_t* regs; // osc's 5 registers
19 | 	
20 | 	int delay;
21 | 	int last_amp;
22 | 	int volume;
23 | 	int length;
24 | 	int enabled;
25 | 	
26 | 	void reset();
27 | 	void clock_length();
28 | 	int frequency() const { return (regs [4] & 7) * 0x100 + regs [3]; }
29 | };
30 | 
31 | struct Gb_Env : Gb_Osc
32 | {
33 | 	int env_delay;
34 | 	
35 | 	void reset();
36 | 	void clock_envelope();
37 | 	bool write_register( int, int );
38 | };
39 | 
40 | struct Gb_Square : Gb_Env
41 | {
42 | 	enum { period_mask = 0x70 };
43 | 	enum { shift_mask  = 0x07 };
44 | 	
45 | 	typedef Blip_Synth Synth;
46 | 	Synth const* synth;
47 | 	int sweep_delay;
48 | 	int sweep_freq;
49 | 	int phase;
50 | 	
51 | 	void reset();
52 | 	void clock_sweep();
53 | 	void run( blip_time_t, blip_time_t, int playing );
54 | };
55 | 
56 | struct Gb_Noise : Gb_Env
57 | {
58 | 	typedef Blip_Synth Synth;
59 | 	Synth const* synth;
60 | 	unsigned bits;
61 | 	
62 | 	void run( blip_time_t, blip_time_t, int playing );
63 | };
64 | 
65 | struct Gb_Wave : Gb_Osc
66 | {
67 | 	typedef Blip_Synth Synth;
68 | 	Synth const* synth;
69 | 	int wave_pos;
70 | 	enum { wave_size = 32 };
71 | 	uint8_t wave [wave_size];
72 | 	
73 | 	void write_register( int, int );
74 | 	void run( blip_time_t, blip_time_t, int playing );
75 | };
76 | 
77 | inline void Gb_Env::reset()
78 | {
79 | 	env_delay = 0;
80 | 	Gb_Osc::reset();
81 | }
82 | 
83 | #endif
84 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Gbs_Emu.h:
--------------------------------------------------------------------------------
 1 | // Nintendo Game Boy GBS music file emulator
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef GBS_EMU_H
 5 | #define GBS_EMU_H
 6 | 
 7 | #include "Classic_Emu.h"
 8 | #include "Gb_Apu.h"
 9 | #include "Gb_Cpu.h"
10 | 
11 | class Gbs_Emu : private Gb_Cpu, public Classic_Emu {
12 | 	typedef Gb_Cpu cpu;
13 | public:
14 | 	// Equalizer profiles for Game Boy Color speaker and headphones
15 | 	static equalizer_t const handheld_eq;
16 | 	static equalizer_t const headphones_eq;
17 | 	
18 | 	// GBS file header
19 | 	enum { header_size = 112 };
20 | 	struct header_t
21 | 	{
22 | 		char tag [3];
23 | 		byte vers;
24 | 		byte track_count;
25 | 		byte first_track;
26 | 		byte load_addr [2];
27 | 		byte init_addr [2];
28 | 		byte play_addr [2];
29 | 		byte stack_ptr [2];
30 | 		byte timer_modulo;
31 | 		byte timer_mode;
32 | 		char game [32];
33 | 		char author [32];
34 | 		char copyright [32];
35 | 	};
36 | 	
37 | 	// Header for currently loaded file
38 | 	header_t const& header() const { return header_; }
39 | 	
40 | 	static gme_type_t static_type() { return gme_gbs_type; }
41 | 	
42 | public:
43 | 	// deprecated
44 | 	using Music_Emu::load;
45 | 	blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
46 | 			{ return load_remaining_( &h, sizeof h, in ); }
47 | 
48 | public:
49 | 	Gbs_Emu();
50 | 	~Gbs_Emu();
51 | protected:
52 | 	blargg_err_t track_info_( track_info_t*, int track ) const;
53 | 	blargg_err_t load_( Data_Reader& );
54 | 	blargg_err_t start_track_( int );
55 | 	blargg_err_t run_clocks( blip_time_t&, int );
56 | 	void set_tempo_( double );
57 | 	void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
58 | 	void update_eq( blip_eq_t const& );
59 | 	void unload();
60 | private:
61 | 	// rom
62 | 	enum { bank_size = 0x4000 };
63 | 	Rom_Data rom;
64 | 	void set_bank( int );
65 | 	
66 | 	// timer
67 | 	blip_time_t cpu_time;
68 | 	blip_time_t play_period;
69 | 	blip_time_t next_play;
70 | 	void update_timer();
71 | 	
72 | 	header_t header_;
73 | 	void cpu_jsr( gb_addr_t );
74 | 	
75 | public: private: friend class Gb_Cpu;
76 | 	blip_time_t clock() const { return cpu_time - cpu::remain(); }
77 | 	
78 | 	enum { joypad_addr = 0xFF00 };
79 | 	enum { ram_addr = 0xA000 };
80 | 	enum { hi_page = 0xFF00 - ram_addr };
81 | 	byte ram [0x4000 + 0x2000 + Gb_Cpu::cpu_padding];
82 | 	Gb_Apu apu;
83 | 	
84 | 	int cpu_read( gb_addr_t );
85 | 	void cpu_write( gb_addr_t, int );
86 | };
87 | 
88 | #endif
89 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Gym_Emu.h:
--------------------------------------------------------------------------------
 1 | // Sega Genesis/Mega Drive GYM music file emulator
 2 | // Includes with PCM timing recovery to improve sample quality.
 3 | 
 4 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 5 | #ifndef GYM_EMU_H
 6 | #define GYM_EMU_H
 7 | 
 8 | #include "Dual_Resampler.h"
 9 | #include "Ym2612_Emu.h"
10 | #include "Music_Emu.h"
11 | #include "Sms_Apu.h"
12 | 
13 | class Gym_Emu : public Music_Emu, private Dual_Resampler {
14 | public:
15 | 	// GYM file header
16 | 	enum { header_size = 428 };
17 | 	struct header_t
18 | 	{
19 | 	    char tag [4];
20 | 	    char song [32];
21 | 	    char game [32];
22 | 	    char copyright [32];
23 | 	    char emulator [32];
24 | 	    char dumper [32];
25 | 	    char comment [256];
26 | 	    byte loop_start [4]; // in 1/60 seconds, 0 if not looped
27 | 	    byte packed [4];
28 | 	};
29 | 	
30 | 	// Header for currently loaded file
31 | 	header_t const& header() const { return header_; }
32 | 	
33 | 	static gme_type_t static_type() { return gme_gym_type; }
34 | 	
35 | public:
36 | 	// deprecated
37 | 	using Music_Emu::load;
38 | 	blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
39 | 			{ return load_remaining_( &h, sizeof h, in ); }
40 | 	enum { gym_rate = 60 }; 
41 | 	long track_length() const; // use track_info()
42 | 
43 | public:
44 | 	Gym_Emu();
45 | 	~Gym_Emu();
46 | protected:
47 | 	blargg_err_t load_mem_( byte const*, long );
48 | 	blargg_err_t track_info_( track_info_t*, int track ) const;
49 | 	blargg_err_t set_sample_rate_( long sample_rate );
50 | 	blargg_err_t start_track_( int );
51 | 	blargg_err_t play_( long count, sample_t* );
52 | 	void mute_voices_( int );
53 | 	void set_tempo_( double );
54 | 	int play_frame( blip_time_t blip_time, int sample_count, sample_t* buf );
55 | private:
56 | 	// sequence data begin, loop begin, current position, end
57 | 	const byte* data;
58 | 	const byte* loop_begin;
59 | 	const byte* pos;
60 | 	const byte* data_end;
61 | 	blargg_long loop_remain; // frames remaining until loop beginning has been located
62 | 	header_t header_;
63 | 	double fm_sample_rate;
64 | 	blargg_long clocks_per_frame;
65 | 	void parse_frame();
66 | 	
67 | 	// dac (pcm)
68 | 	int dac_amp;
69 | 	int prev_dac_count;
70 | 	bool dac_enabled;
71 | 	bool dac_muted;
72 | 	void run_dac( int );
73 | 	
74 | 	// sound
75 | 	Blip_Buffer blip_buf;
76 | 	Ym2612_Emu fm;
77 | 	Blip_Synth dac_synth;
78 | 	Sms_Apu apu;
79 | 	byte dac_buf [1024];
80 | };
81 | 
82 | #endif
83 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Hes_Apu.h:
--------------------------------------------------------------------------------
 1 | // Turbo Grafx 16 (PC Engine) PSG sound chip emulator
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef HES_APU_H
 5 | #define HES_APU_H
 6 | 
 7 | #include "blargg_common.h"
 8 | #include "Blip_Buffer.h"
 9 | 
10 | struct Hes_Osc
11 | {
12 | 	unsigned char wave [32];
13 | 	short volume [2];
14 | 	int last_amp [2];
15 | 	int delay;
16 | 	int period;
17 | 	unsigned char noise;
18 | 	unsigned char phase;
19 | 	unsigned char balance;
20 | 	unsigned char dac;
21 | 	blip_time_t last_time;
22 | 	
23 | 	Blip_Buffer* outputs [2];
24 | 	Blip_Buffer* chans [3];
25 | 	unsigned noise_lfsr;
26 | 	unsigned char control;
27 | 	
28 | 	enum { amp_range = 0x8000 };
29 | 	typedef Blip_Synth synth_t;
30 | 	
31 | 	void run_until( synth_t& synth, blip_time_t );
32 | };
33 | 
34 | class Hes_Apu {
35 | public:
36 | 	void treble_eq( blip_eq_t const& );
37 | 	void volume( double );
38 | 	
39 | 	enum { osc_count = 6 };
40 | 	void osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
41 | 	
42 | 	void reset();
43 | 	
44 | 	enum { start_addr = 0x0800 };
45 | 	enum { end_addr   = 0x0809 };
46 | 	void write_data( blip_time_t, int addr, int data );
47 | 	
48 | 	void end_frame( blip_time_t );
49 | 	
50 | public:
51 | 	Hes_Apu();
52 | private:
53 | 	Hes_Osc oscs [osc_count];
54 | 	int latch;
55 | 	int balance;
56 | 	Hes_Osc::synth_t synth;
57 | 	
58 | 	void balance_changed( Hes_Osc& );
59 | 	void recalc_chans();
60 | };
61 | 
62 | inline void Hes_Apu::volume( double v ) { synth.volume( 1.8 / osc_count / Hes_Osc::amp_range * v ); }
63 | 
64 | inline void Hes_Apu::treble_eq( blip_eq_t const& eq ) { synth.treble_eq( eq ); }
65 | 
66 | #endif
67 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Hes_Cpu.h:
--------------------------------------------------------------------------------
  1 | // PC Engine CPU emulator for use with HES music files
  2 | 
  3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
  4 | #ifndef HES_CPU_H
  5 | #define HES_CPU_H
  6 | 
  7 | #include "blargg_common.h"
  8 | 
  9 | typedef blargg_long hes_time_t; // clock cycle count
 10 | typedef unsigned hes_addr_t; // 16-bit address
 11 | enum { future_hes_time = INT_MAX / 2 + 1 };
 12 | 
 13 | class Hes_Cpu {
 14 | public:
 15 | 	void reset();
 16 | 	
 17 | 	enum { page_size = 0x2000 };
 18 | 	enum { page_shift = 13 };
 19 | 	enum { page_count = 8 };
 20 | 	void set_mmr( int reg, int bank );
 21 | 	
 22 | 	uint8_t const* get_code( hes_addr_t );
 23 | 	
 24 | 	uint8_t ram [page_size];
 25 | 	
 26 | 	// not kept updated during a call to run()
 27 | 	struct registers_t {
 28 | 		uint16_t pc;
 29 | 		uint8_t a;
 30 | 		uint8_t x;
 31 | 		uint8_t y;
 32 | 		uint8_t status;
 33 | 		uint8_t sp;
 34 | 	};
 35 | 	registers_t r;
 36 | 	
 37 | 	// page mapping registers
 38 | 	uint8_t mmr [page_count + 1];
 39 | 	
 40 | 	// Set end_time and run CPU from current time. Returns true if any illegal
 41 | 	// instructions were encountered.
 42 | 	bool run( hes_time_t end_time );
 43 | 	
 44 | 	// Time of beginning of next instruction to be executed
 45 | 	hes_time_t time() const             { return state->time + state->base; }
 46 | 	void set_time( hes_time_t t )       { state->time = t - state->base; }
 47 | 	void adjust_time( int delta )       { state->time += delta; }
 48 | 	
 49 | 	hes_time_t irq_time() const         { return irq_time_; }
 50 | 	void set_irq_time( hes_time_t );
 51 | 	
 52 | 	hes_time_t end_time() const         { return end_time_; }
 53 | 	void set_end_time( hes_time_t );
 54 | 	
 55 | 	void end_frame( hes_time_t );
 56 | 	
 57 | 	// Attempt to execute instruction here results in CPU advancing time to
 58 | 	// lesser of irq_time() and end_time() (or end_time() if IRQs are
 59 | 	// disabled)
 60 | 	enum { idle_addr = 0x1FFF };
 61 | 	
 62 | 	// Can read this many bytes past end of a page
 63 | 	enum { cpu_padding = 8 };
 64 | 	
 65 | public:
 66 | 	Hes_Cpu() { state = &state_; }
 67 | 	enum { irq_inhibit = 0x04 };
 68 | private:
 69 | 	// noncopyable
 70 | 	Hes_Cpu( const Hes_Cpu& );
 71 | 	Hes_Cpu& operator = ( const Hes_Cpu& );
 72 | 	
 73 | 	struct state_t {
 74 | 		uint8_t const* code_map [page_count + 1];
 75 | 		hes_time_t base;
 76 | 		blargg_long time;
 77 | 	};
 78 | 	state_t* state; // points to state_ or a local copy within run()
 79 | 	state_t state_;
 80 | 	hes_time_t irq_time_;
 81 | 	hes_time_t end_time_;
 82 | 	
 83 | 	void set_code_page( int, void const* );
 84 | 	inline int update_end_time( hes_time_t end, hes_time_t irq );
 85 | };
 86 | 
 87 | inline uint8_t const* Hes_Cpu::get_code( hes_addr_t addr )
 88 | {
 89 | 	return state->code_map [addr >> page_shift] + addr
 90 | 	#if !BLARGG_NONPORTABLE
 91 | 		% (unsigned) page_size
 92 | 	#endif
 93 | 	;
 94 | }
 95 | 
 96 | inline int Hes_Cpu::update_end_time( hes_time_t t, hes_time_t irq )
 97 | {
 98 | 	if ( irq < t && !(r.status & irq_inhibit) ) t = irq;
 99 | 	int delta = state->base - t;
100 | 	state->base = t;
101 | 	return delta;
102 | }
103 | 
104 | inline void Hes_Cpu::set_irq_time( hes_time_t t )
105 | {
106 | 	state->time += update_end_time( end_time_, (irq_time_ = t) );
107 | }
108 | 
109 | inline void Hes_Cpu::set_end_time( hes_time_t t )
110 | {
111 | 	state->time += update_end_time( (end_time_ = t), irq_time_ );
112 | }
113 | 
114 | inline void Hes_Cpu::end_frame( hes_time_t t )
115 | {
116 | 	assert( state == &state_ );
117 | 	state_.base -= t;
118 | 	if ( irq_time_ < future_hes_time ) irq_time_ -= t;
119 | 	if ( end_time_ < future_hes_time ) end_time_ -= t;
120 | }
121 | 
122 | #endif
123 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Hes_Emu.h:
--------------------------------------------------------------------------------
 1 | // TurboGrafx-16/PC Engine HES music file emulator
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef HES_EMU_H
 5 | #define HES_EMU_H
 6 | 
 7 | #include "Classic_Emu.h"
 8 | #include "Hes_Apu.h"
 9 | #include "Hes_Cpu.h"
10 | 
11 | class Hes_Emu : private Hes_Cpu, public Classic_Emu {
12 | 	typedef Hes_Cpu cpu;
13 | public:
14 | 	// HES file header
15 | 	enum { header_size = 0x20 };
16 | 	struct header_t
17 | 	{
18 | 		byte tag [4];
19 | 		byte vers;
20 | 		byte first_track;
21 | 		byte init_addr [2];
22 | 		byte banks [8];
23 | 		byte data_tag [4];
24 | 		byte size [4];
25 | 		byte addr [4];
26 | 		byte unused [4];
27 | 	};
28 | 	
29 | 	// Header for currently loaded file
30 | 	header_t const& header() const { return header_; }
31 | 	
32 | 	static gme_type_t static_type() { return gme_hes_type; }
33 | 
34 | public:
35 | 	Hes_Emu();
36 | 	~Hes_Emu();
37 | protected:
38 | 	blargg_err_t track_info_( track_info_t*, int track ) const;
39 | 	blargg_err_t load_( Data_Reader& );
40 | 	blargg_err_t start_track_( int );
41 | 	blargg_err_t run_clocks( blip_time_t&, int );
42 | 	void set_tempo_( double );
43 | 	void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
44 | 	void update_eq( blip_eq_t const& );
45 | 	void unload();
46 | public: private: friend class Hes_Cpu;
47 | 	byte* write_pages [page_count + 1]; // 0 if unmapped or I/O space
48 | 	
49 | 	int cpu_read_( hes_addr_t );
50 | 	int cpu_read( hes_addr_t );
51 | 	void cpu_write_( hes_addr_t, int data );
52 | 	void cpu_write( hes_addr_t, int );
53 | 	void cpu_write_vdp( int addr, int data );
54 | 	byte const* cpu_set_mmr( int page, int bank );
55 | 	int cpu_done();
56 | private:
57 | 	Rom_Data rom;
58 | 	header_t header_;
59 | 	hes_time_t play_period;
60 | 	hes_time_t last_frame_hook;
61 | 	int timer_base;
62 | 	
63 | 	struct {
64 | 		hes_time_t last_time;
65 | 		blargg_long count;
66 | 		blargg_long load;
67 | 		int raw_load;
68 | 		byte enabled;
69 | 		byte fired;
70 | 	} timer;
71 | 	
72 | 	struct {
73 | 		hes_time_t next_vbl;
74 | 		byte latch;
75 | 		byte control;
76 | 	} vdp;
77 | 	
78 | 	struct {
79 | 		hes_time_t timer;
80 | 		hes_time_t vdp;
81 | 		byte disables;
82 | 	} irq;
83 | 	
84 | 	void recalc_timer_load();
85 | 	
86 | 	// large items
87 | 	Hes_Apu apu;
88 | 	byte sgx [3 * page_size + cpu_padding];
89 | 	
90 | 	void irq_changed();
91 | 	void run_until( hes_time_t );
92 | };
93 | 
94 | #endif
95 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Kss_Cpu.h:
--------------------------------------------------------------------------------
  1 | // Z80 CPU emulator
  2 | 
  3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
  4 | #ifndef KSS_CPU_H
  5 | #define KSS_CPU_H
  6 | 
  7 | #include "blargg_endian.h"
  8 | 
  9 | typedef blargg_long cpu_time_t;
 10 | 
 11 | // must be defined by caller
 12 | void kss_cpu_out( class Kss_Cpu*, cpu_time_t, unsigned addr, int data );
 13 | int  kss_cpu_in( class Kss_Cpu*, cpu_time_t, unsigned addr );
 14 | void kss_cpu_write( class Kss_Cpu*, unsigned addr, int data );
 15 | 
 16 | class Kss_Cpu {
 17 | public:
 18 | 	// Clear registers and map all pages to unmapped
 19 | 	void reset( void* unmapped_write, void const* unmapped_read );
 20 | 	
 21 | 	// Map memory. Start and size must be multiple of page_size.
 22 | 	enum { page_size = 0x2000 };
 23 | 	void map_mem( unsigned addr, blargg_ulong size, void* write, void const* read );
 24 | 	
 25 | 	// Map address to page
 26 | 	uint8_t* write( unsigned addr );
 27 | 	uint8_t const* read( unsigned addr );
 28 | 	
 29 | 	// Run until specified time is reached. Returns true if suspicious/unsupported
 30 | 	// instruction was encountered at any point during run.
 31 | 	bool run( cpu_time_t end_time );
 32 | 	
 33 | 	// Time of beginning of next instruction
 34 | 	cpu_time_t time() const             { return state->time + state->base; }
 35 | 	
 36 | 	// Alter current time. Not supported during run() call.
 37 | 	void set_time( cpu_time_t t )       { state->time = t - state->base; }
 38 | 	void adjust_time( int delta )       { state->time += delta; }
 39 | 	
 40 | 	#if BLARGG_BIG_ENDIAN
 41 | 		struct regs_t { uint8_t b, c, d, e, h, l, flags, a; };
 42 | 	#else
 43 | 		struct regs_t { uint8_t c, b, e, d, l, h, a, flags; };
 44 | 	#endif
 45 | 	BOOST_STATIC_ASSERT( sizeof (regs_t) == 8 );
 46 | 	
 47 | 	struct pairs_t { uint16_t bc, de, hl, fa; };
 48 | 	
 49 | 	// Registers are not updated until run() returns
 50 | 	struct registers_t {
 51 | 		uint16_t pc;
 52 | 		uint16_t sp;
 53 | 		uint16_t ix;
 54 | 		uint16_t iy;
 55 | 		union {
 56 | 			regs_t b; //  b.b, b.c, b.d, b.e, b.h, b.l, b.flags, b.a
 57 | 			pairs_t w; // w.bc, w.de, w.hl. w.fa
 58 | 		};
 59 | 		union {
 60 | 			regs_t b;
 61 | 			pairs_t w;
 62 | 		} alt;
 63 | 		uint8_t iff1;
 64 | 		uint8_t iff2;
 65 | 		uint8_t r;
 66 | 		uint8_t i;
 67 | 		uint8_t im;
 68 | 	};
 69 | 	//registers_t r; (below for efficiency)
 70 | 	
 71 | 	enum { idle_addr = 0xFFFF };
 72 | 	
 73 | 	// can read this far past end of a page
 74 | 	enum { cpu_padding = 0x100 };
 75 | 	
 76 | public:
 77 | 	Kss_Cpu();
 78 | 	enum { page_shift = 13 };
 79 | 	enum { page_count = 0x10000 >> page_shift };
 80 | private:
 81 | 	uint8_t szpc [0x200];
 82 | 	cpu_time_t end_time_;
 83 | 	struct state_t {
 84 | 		uint8_t const* read  [page_count + 1];
 85 | 		uint8_t      * write [page_count + 1];
 86 | 		cpu_time_t base;
 87 | 		cpu_time_t time;
 88 | 	};
 89 | 	state_t* state; // points to state_ or a local copy within run()
 90 | 	state_t state_;
 91 | 	void set_end_time( cpu_time_t t );
 92 | 	void set_page( int i, void* write, void const* read );
 93 | public:
 94 | 	registers_t r;
 95 | };
 96 | 
 97 | #if BLARGG_NONPORTABLE
 98 | 	#define KSS_CPU_PAGE_OFFSET( addr ) (addr)
 99 | #else
100 | 	#define KSS_CPU_PAGE_OFFSET( addr ) ((addr) & (page_size - 1))
101 | #endif
102 | 
103 | inline uint8_t* Kss_Cpu::write( unsigned addr )
104 | {
105 | 	return state->write [addr >> page_shift] + KSS_CPU_PAGE_OFFSET( addr );
106 | }
107 | 
108 | inline uint8_t const* Kss_Cpu::read( unsigned addr )
109 | {
110 | 	return state->read [addr >> page_shift] + KSS_CPU_PAGE_OFFSET( addr );
111 | }
112 | 
113 | inline void Kss_Cpu::set_end_time( cpu_time_t t )
114 | {
115 | 	cpu_time_t delta = state->base - t;
116 | 	state->base = t;
117 | 	state->time += delta;
118 | }
119 | 
120 | #endif
121 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Kss_Emu.h:
--------------------------------------------------------------------------------
 1 | // MSX computer KSS music file emulator
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef KSS_EMU_H
 5 | #define KSS_EMU_H
 6 | 
 7 | #include "Classic_Emu.h"
 8 | #include "Kss_Scc_Apu.h"
 9 | #include "Kss_Cpu.h"
10 | #include "Sms_Apu.h"
11 | #include "Ay_Apu.h"
12 | 
13 | class Kss_Emu : private Kss_Cpu, public Classic_Emu {
14 | 	typedef Kss_Cpu cpu;
15 | public:
16 | 	// KSS file header
17 | 	enum { header_size = 0x10 };
18 | 	struct header_t
19 | 	{
20 | 		byte tag [4];
21 | 		byte load_addr [2];
22 | 		byte load_size [2];
23 | 		byte init_addr [2];
24 | 		byte play_addr [2];
25 | 		byte first_bank;
26 | 		byte bank_mode;
27 | 		byte extra_header;
28 | 		byte device_flags;
29 | 	};
30 | 	
31 | 	enum { ext_header_size = 0x10 };
32 | 	struct ext_header_t
33 | 	{
34 | 		byte data_size [4];
35 | 		byte unused [4];
36 | 		byte first_track [2];
37 | 		byte last_tack [2];
38 | 		byte psg_vol;
39 | 		byte scc_vol;
40 | 		byte msx_music_vol;
41 | 		byte msx_audio_vol;
42 | 	};
43 | 	
44 | 	struct composite_header_t : header_t, ext_header_t { };
45 | 	
46 | 	// Header for currently loaded file
47 | 	composite_header_t const& header() const { return header_; }
48 | 	
49 | 	static gme_type_t static_type() { return gme_kss_type; }
50 | public:
51 | 	Kss_Emu();
52 | 	~Kss_Emu();
53 | protected:
54 | 	blargg_err_t track_info_( track_info_t*, int track ) const;
55 | 	blargg_err_t load_( Data_Reader& );
56 | 	blargg_err_t start_track_( int );
57 | 	blargg_err_t run_clocks( blip_time_t&, int );
58 | 	void set_tempo_( double );
59 | 	void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
60 | 	void update_eq( blip_eq_t const& );
61 | 	void unload();
62 | private:
63 | 	Rom_Data rom;
64 | 	composite_header_t header_;
65 | 	
66 | 	bool scc_accessed;
67 | 	bool gain_updated;
68 | 	void update_gain();
69 | 	
70 | 	unsigned scc_enabled; // 0 or 0xC000
71 | 	int bank_count;
72 | 	void set_bank( int logical, int physical );
73 | 	blargg_long bank_size() const { return (16 * 1024L) >> (header_.bank_mode >> 7 & 1); }
74 | 	
75 | 	blip_time_t play_period;
76 | 	blip_time_t next_play;
77 | 	int ay_latch;
78 | 	
79 | 	friend void kss_cpu_out( class Kss_Cpu*, cpu_time_t, unsigned addr, int data );
80 | 	friend int  kss_cpu_in( class Kss_Cpu*, cpu_time_t, unsigned addr );
81 | 	void cpu_write( unsigned addr, int data );
82 | 	friend void kss_cpu_write( class Kss_Cpu*, unsigned addr, int data );
83 | 	
84 | 	// large items
85 | 	enum { mem_size = 0x10000 };
86 | 	byte ram [mem_size + cpu_padding];
87 | 	
88 | 	Ay_Apu ay;
89 | 	Scc_Apu scc;
90 | 	Sms_Apu* sn;
91 | 	byte unmapped_read  [0x100];
92 | 	byte unmapped_write [page_size];
93 | };
94 | 
95 | #endif
96 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Kss_Scc_Apu.cpp:
--------------------------------------------------------------------------------
 1 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 2 | 
 3 | #include "Kss_Scc_Apu.h"
 4 | 
 5 | /* Copyright (C) 2006 Shay Green. This module is free software; you
 6 | can redistribute it and/or modify it under the terms of the GNU Lesser
 7 | General Public License as published by the Free Software Foundation; either
 8 | version 2.1 of the License, or (at your option) any later version. This
 9 | module is distributed in the hope that it will be useful, but WITHOUT ANY
10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 | details. You should have received a copy of the GNU Lesser General Public
13 | License along with this module; if not, write to the Free Software Foundation,
14 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
15 | 
16 | #include "blargg_source.h"
17 | 
18 | // Tones above this frequency are treated as disabled tone at half volume.
19 | // Power of two is more efficient (avoids division).
20 | unsigned const inaudible_freq = 16384;
21 | 
22 | int const wave_size = 0x20;
23 | 
24 | void Scc_Apu::run_until( blip_time_t end_time )
25 | {
26 | 	for ( int index = 0; index < osc_count; index++ )
27 | 	{
28 | 		osc_t& osc = oscs [index];
29 | 		
30 | 		Blip_Buffer* const output = osc.output;
31 | 		if ( !output )
32 | 			continue;
33 | 		output->set_modified();
34 | 		
35 | 		blip_time_t period = (regs [0x80 + index * 2 + 1] & 0x0F) * 0x100 +
36 | 				regs [0x80 + index * 2] + 1;
37 | 		int volume = 0;
38 | 		if ( regs [0x8F] & (1 << index) )
39 | 		{
40 | 			blip_time_t inaudible_period = (blargg_ulong) (output->clock_rate() +
41 | 					inaudible_freq * 32) / (inaudible_freq * 16);
42 | 			if ( period > inaudible_period )
43 | 				volume = (regs [0x8A + index] & 0x0F) * (amp_range / 256 / 15);
44 | 		}
45 | 		
46 | 		int8_t const* wave = (int8_t*) regs + index * wave_size;
47 | 		if ( index == osc_count - 1 )
48 | 			wave -= wave_size; // last two oscs share wave
49 | 		{
50 | 			int amp = wave [osc.phase] * volume;
51 | 			int delta = amp - osc.last_amp;
52 | 			if ( delta )
53 | 			{
54 | 				osc.last_amp = amp;
55 | 				synth.offset( last_time, delta, output );
56 | 			}
57 | 		}
58 | 		
59 | 		blip_time_t time = last_time + osc.delay;
60 | 		if ( time < end_time )
61 | 		{
62 | 			if ( !volume )
63 | 			{
64 | 				// maintain phase
65 | 				blargg_long count = (end_time - time + period - 1) / period;
66 | 				osc.phase = (osc.phase + count) & (wave_size - 1);
67 | 				time += count * period;
68 | 			}
69 | 			else
70 | 			{
71 | 				
72 | 				int phase = osc.phase;
73 | 				int last_wave = wave [phase];
74 | 				phase = (phase + 1) & (wave_size - 1); // pre-advance for optimal inner loop
75 | 				
76 | 				do
77 | 				{
78 | 					int amp = wave [phase];
79 | 					phase = (phase + 1) & (wave_size - 1);
80 | 					int delta = amp - last_wave;
81 | 					if ( delta )
82 | 					{
83 | 						last_wave = amp;
84 | 						synth.offset( time, delta * volume, output );
85 | 					}
86 | 					time += period;
87 | 				}
88 | 				while ( time < end_time );
89 | 				
90 | 				osc.phase = phase = (phase - 1) & (wave_size - 1); // undo pre-advance
91 | 				osc.last_amp = wave [phase] * volume;
92 | 			}
93 | 		}
94 | 		osc.delay = time - end_time;
95 | 	}
96 | 	last_time = end_time;
97 | }
98 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Kss_Scc_Apu.h:
--------------------------------------------------------------------------------
  1 | // Konami SCC sound chip emulator
  2 | 
  3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
  4 | #ifndef KSS_SCC_APU_H
  5 | #define KSS_SCC_APU_H
  6 | 
  7 | #include "blargg_common.h"
  8 | #include "Blip_Buffer.h"
  9 | #include 
 10 | 
 11 | class Scc_Apu {
 12 | public:
 13 | 	// Set buffer to generate all sound into, or disable sound if NULL
 14 | 	void output( Blip_Buffer* );
 15 | 	
 16 | 	// Reset sound chip
 17 | 	void reset();
 18 | 	
 19 | 	// Write to register at specified time
 20 | 	enum { reg_count = 0x90 };
 21 | 	void write( blip_time_t time, int reg, int data );
 22 | 	
 23 | 	// Run sound to specified time, end current time frame, then start a new
 24 | 	// time frame at time 0. Time frames have no effect on emulation and each
 25 | 	// can be whatever length is convenient.
 26 | 	void end_frame( blip_time_t length );
 27 | 
 28 | // Additional features
 29 | 	
 30 | 	// Set sound output of specific oscillator to buffer, where index is
 31 | 	// 0 to 4. If buffer is NULL, the specified oscillator is muted.
 32 | 	enum { osc_count = 5 };
 33 | 	void osc_output( int index, Blip_Buffer* );
 34 | 	
 35 | 	// Set overall volume (default is 1.0)
 36 | 	void volume( double );
 37 | 	
 38 | 	// Set treble equalization (see documentation)
 39 | 	void treble_eq( blip_eq_t const& );
 40 | 	
 41 | public:
 42 | 	Scc_Apu();
 43 | private:
 44 | 	enum { amp_range = 0x8000 };
 45 | 	struct osc_t
 46 | 	{
 47 | 		int delay;
 48 | 		int phase;
 49 | 		int last_amp;
 50 | 		Blip_Buffer* output;
 51 | 	};
 52 | 	osc_t oscs [osc_count];
 53 | 	blip_time_t last_time;
 54 | 	unsigned char regs [reg_count];
 55 | 	Blip_Synth synth;
 56 | 	
 57 | 	void run_until( blip_time_t );
 58 | };
 59 | 
 60 | inline void Scc_Apu::volume( double v ) { synth.volume( 0.43 / osc_count / amp_range * v ); }
 61 | 
 62 | inline void Scc_Apu::treble_eq( blip_eq_t const& eq ) { synth.treble_eq( eq ); }
 63 | 
 64 | inline void Scc_Apu::osc_output( int index, Blip_Buffer* b )
 65 | {
 66 | 	assert( (unsigned) index < osc_count );
 67 | 	oscs [index].output = b;
 68 | }
 69 | 
 70 | inline void Scc_Apu::write( blip_time_t time, int addr, int data )
 71 | {
 72 | 	assert( (unsigned) addr < reg_count );
 73 | 	run_until( time );
 74 | 	regs [addr] = data;
 75 | }
 76 | 
 77 | inline void Scc_Apu::end_frame( blip_time_t end_time )
 78 | {
 79 | 	if ( end_time > last_time )
 80 | 		run_until( end_time );
 81 | 	last_time -= end_time;
 82 | 	assert( last_time >= 0 );
 83 | }
 84 | 
 85 | inline void Scc_Apu::output( Blip_Buffer* buf )
 86 | {
 87 | 	for ( int i = 0; i < osc_count; i++ )
 88 | 		oscs [i].output = buf;
 89 | }
 90 | 
 91 | inline Scc_Apu::Scc_Apu()
 92 | {
 93 | 	output( 0 );
 94 | }
 95 | 
 96 | inline void Scc_Apu::reset()
 97 | {
 98 | 	last_time = 0;
 99 | 	
100 | 	for ( int i = 0; i < osc_count; i++ )
101 | 		memset( &oscs [i], 0, offsetof (osc_t,output) );
102 | 	
103 | 	memset( regs, 0, sizeof regs );
104 | }
105 | 
106 | #endif
107 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/M3u_Playlist.h:
--------------------------------------------------------------------------------
 1 | // M3U playlist file parser, with support for subtrack information
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef M3U_PLAYLIST_H
 5 | #define M3U_PLAYLIST_H
 6 | 
 7 | #include "blargg_common.h"
 8 | #include "Data_Reader.h"
 9 | 
10 | class M3u_Playlist {
11 | public:
12 | 	// Load playlist data
13 | 	blargg_err_t load( const char* path );
14 | 	blargg_err_t load( Data_Reader& in );
15 | 	blargg_err_t load( void const* data, long size );
16 | 	
17 | 	// Line number of first parse error, 0 if no error. Any lines with parse
18 | 	// errors are ignored.
19 | 	int first_error() const { return first_error_; }
20 | 	
21 | 	struct info_t
22 | 	{
23 | 		const char* title;
24 | 		const char* composer;
25 | 		const char* engineer;
26 | 		const char* ripping;
27 | 		const char* tagging;
28 | 	};
29 | 	info_t const& info() const { return info_; }
30 | 	
31 | 	struct entry_t
32 | 	{
33 | 		const char* file; // filename without stupid ::TYPE suffix
34 | 		const char* type; // if filename has ::TYPE suffix, this will be "TYPE". "" if none.
35 | 		const char* name;
36 | 		bool decimal_track; // true if track was specified in hex
37 | 		// integers are -1 if not present
38 | 		int track;  // 1-based
39 | 		int length; // milliseconds
40 | 		int intro;
41 | 		int loop;
42 | 		int fade;
43 | 		int repeat; // count
44 | 	};
45 | 	entry_t const& operator [] ( int i ) const { return entries [i]; }
46 | 	int size() const { return entries.size(); }
47 | 	
48 | 	void clear();
49 | 	
50 | private:
51 | 	blargg_vector entries;
52 | 	blargg_vector data;
53 | 	int first_error_;
54 | 	info_t info_;
55 | 	
56 | 	blargg_err_t parse();
57 | 	blargg_err_t parse_();
58 | };
59 | 
60 | inline void M3u_Playlist::clear()
61 | {
62 | 	first_error_ = 0;
63 | 	entries.clear();
64 | 	data.clear();
65 | }
66 | 
67 | #endif
68 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Nes_Cpu.h:
--------------------------------------------------------------------------------
  1 | // NES 6502 CPU emulator
  2 | 
  3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
  4 | #ifndef NES_CPU_H
  5 | #define NES_CPU_H
  6 | 
  7 | #include "blargg_common.h"
  8 | 
  9 | typedef blargg_long nes_time_t; // clock cycle count
 10 | typedef unsigned nes_addr_t; // 16-bit address
 11 | enum { future_nes_time = INT_MAX / 2 + 1 };
 12 | 
 13 | class Nes_Cpu {
 14 | public:
 15 | 	// Clear registers, map low memory and its three mirrors to address 0,
 16 | 	// and mirror unmapped_page in remaining memory
 17 | 	void reset( void const* unmapped_page = 0 );
 18 | 	
 19 | 	// Map code memory (memory accessed via the program counter). Start and size
 20 | 	// must be multiple of page_size. If mirror is true, repeats code page
 21 | 	// throughout address range.
 22 | 	enum { page_size = 0x800 };
 23 | 	void map_code( nes_addr_t start, unsigned size, void const* code, bool mirror = false );
 24 | 	
 25 | 	// Access emulated memory as CPU does
 26 | 	uint8_t const* get_code( nes_addr_t );
 27 | 	
 28 | 	// 2KB of RAM at address 0
 29 | 	uint8_t low_mem [0x800];
 30 | 	
 31 | 	// NES 6502 registers. Not kept updated during a call to run().
 32 | 	struct registers_t {
 33 | 		uint16_t pc;
 34 | 		uint8_t a;
 35 | 		uint8_t x;
 36 | 		uint8_t y;
 37 | 		uint8_t status;
 38 | 		uint8_t sp;
 39 | 	};
 40 | 	registers_t r;
 41 | 	
 42 | 	// Set end_time and run CPU from current time. Returns true if execution
 43 | 	// stopped due to encountering bad_opcode.
 44 | 	bool run( nes_time_t end_time );
 45 | 	
 46 | 	// Time of beginning of next instruction to be executed
 47 | 	nes_time_t time() const             { return state->time + state->base; }
 48 | 	void set_time( nes_time_t t )       { state->time = t - state->base; }
 49 | 	void adjust_time( int delta )       { state->time += delta; }
 50 | 	
 51 | 	nes_time_t irq_time() const         { return irq_time_; }
 52 | 	void set_irq_time( nes_time_t );
 53 | 	
 54 | 	nes_time_t end_time() const         { return end_time_; }
 55 | 	void set_end_time( nes_time_t );
 56 | 	
 57 | 	// Number of undefined instructions encountered and skipped
 58 | 	void clear_error_count()            { error_count_ = 0; }
 59 | 	unsigned long error_count() const   { return error_count_; }
 60 | 	
 61 | 	// CPU invokes bad opcode handler if it encounters this
 62 | 	enum { bad_opcode = 0xF2 };
 63 | 	
 64 | public:
 65 | 	Nes_Cpu() { state = &state_; }
 66 | 	enum { page_bits = 11 };
 67 | 	enum { page_count = 0x10000 >> page_bits };
 68 | 	enum { irq_inhibit = 0x04 };
 69 | private:
 70 | 	struct state_t {
 71 | 		uint8_t const* code_map [page_count + 1];
 72 | 		nes_time_t base;
 73 | 		int time;
 74 | 	};
 75 | 	state_t* state; // points to state_ or a local copy within run()
 76 | 	state_t state_;
 77 | 	nes_time_t irq_time_;
 78 | 	nes_time_t end_time_;
 79 | 	unsigned long error_count_;
 80 | 	
 81 | 	void set_code_page( int, void const* );
 82 | 	inline int update_end_time( nes_time_t end, nes_time_t irq );
 83 | };
 84 | 
 85 | inline uint8_t const* Nes_Cpu::get_code( nes_addr_t addr )
 86 | {
 87 | 	return state->code_map [addr >> page_bits] + addr
 88 | 	#if !BLARGG_NONPORTABLE
 89 | 		% (unsigned) page_size
 90 | 	#endif
 91 | 	;
 92 | }
 93 | 
 94 | inline int Nes_Cpu::update_end_time( nes_time_t t, nes_time_t irq )
 95 | {
 96 | 	if ( irq < t && !(r.status & irq_inhibit) ) t = irq;
 97 | 	int delta = state->base - t;
 98 | 	state->base = t;
 99 | 	return delta;
100 | }
101 | 
102 | inline void Nes_Cpu::set_irq_time( nes_time_t t )
103 | {
104 | 	state->time += update_end_time( end_time_, (irq_time_ = t) );
105 | }
106 | 
107 | inline void Nes_Cpu::set_end_time( nes_time_t t )
108 | {
109 | 	state->time += update_end_time( (end_time_ = t), irq_time_ );
110 | }
111 | 
112 | #endif
113 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Nes_Fme7_Apu.cpp:
--------------------------------------------------------------------------------
  1 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
  2 | 
  3 | #include "Nes_Fme7_Apu.h"
  4 | 
  5 | #include 
  6 | 
  7 | /* Copyright (C) 2003-2006 Shay Green. This module is free software; you
  8 | can redistribute it and/or modify it under the terms of the GNU Lesser
  9 | General Public License as published by the Free Software Foundation; either
 10 | version 2.1 of the License, or (at your option) any later version. This
 11 | module is distributed in the hope that it will be useful, but WITHOUT ANY
 12 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 13 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 14 | details. You should have received a copy of the GNU Lesser General Public
 15 | License along with this module; if not, write to the Free Software Foundation,
 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
 17 | 
 18 | #include "blargg_source.h"
 19 | 
 20 | void Nes_Fme7_Apu::reset()
 21 | {
 22 | 	last_time = 0;
 23 | 	
 24 | 	for ( int i = 0; i < osc_count; i++ )
 25 | 		oscs [i].last_amp = 0;
 26 | 	
 27 | 	fme7_apu_state_t* state = this;
 28 | 	memset( state, 0, sizeof *state );
 29 | }
 30 | 
 31 | unsigned char const Nes_Fme7_Apu::amp_table [16] =
 32 | {
 33 | 	#define ENTRY( n ) (unsigned char) (n * amp_range + 0.5)
 34 | 	ENTRY(0.0000), ENTRY(0.0078), ENTRY(0.0110), ENTRY(0.0156),
 35 | 	ENTRY(0.0221), ENTRY(0.0312), ENTRY(0.0441), ENTRY(0.0624),
 36 | 	ENTRY(0.0883), ENTRY(0.1249), ENTRY(0.1766), ENTRY(0.2498),
 37 | 	ENTRY(0.3534), ENTRY(0.4998), ENTRY(0.7070), ENTRY(1.0000)
 38 | 	#undef ENTRY
 39 | };
 40 | 
 41 | void Nes_Fme7_Apu::run_until( blip_time_t end_time )
 42 | {
 43 | 	require( end_time >= last_time );
 44 | 	
 45 | 	for ( int index = 0; index < osc_count; index++ )
 46 | 	{
 47 | 		int mode = regs [7] >> index;
 48 | 		int vol_mode = regs [010 + index];
 49 | 		int volume = amp_table [vol_mode & 0x0F];
 50 | 		
 51 | 		Blip_Buffer* const osc_output = oscs [index].output;
 52 | 		if ( !osc_output )
 53 | 			continue;
 54 | 		osc_output->set_modified();
 55 | 		
 56 | 		// check for unsupported mode
 57 | 		#ifndef NDEBUG
 58 | 			if ( (mode & 011) <= 001 && vol_mode & 0x1F )
 59 | 				debug_printf( "FME7 used unimplemented sound mode: %02X, vol_mode: %02X\n",
 60 | 						mode, vol_mode & 0x1F );
 61 | 		#endif
 62 | 		
 63 | 		if ( (mode & 001) | (vol_mode & 0x10) )
 64 | 			volume = 0; // noise and envelope aren't supported
 65 | 		
 66 | 		// period
 67 | 		int const period_factor = 16;
 68 | 		unsigned period = (regs [index * 2 + 1] & 0x0F) * 0x100 * period_factor +
 69 | 				regs [index * 2] * period_factor;
 70 | 		if ( period < 50 ) // around 22 kHz
 71 | 		{
 72 | 			volume = 0;
 73 | 			if ( !period ) // on my AY-3-8910A, period doesn't have extra one added
 74 | 				period = period_factor;
 75 | 		}
 76 | 		
 77 | 		// current amplitude
 78 | 		int amp = volume;
 79 | 		if ( !phases [index] )
 80 | 			amp = 0;
 81 | 		{
 82 | 			int delta = amp - oscs [index].last_amp;
 83 | 			if ( delta )
 84 | 			{
 85 | 				oscs [index].last_amp = amp;
 86 | 				synth.offset( last_time, delta, osc_output );
 87 | 			}
 88 | 		}
 89 | 		
 90 | 		blip_time_t time = last_time + delays [index];
 91 | 		if ( time < end_time )
 92 | 		{
 93 | 			int delta = amp * 2 - volume;
 94 | 			if ( volume )
 95 | 			{
 96 | 				do
 97 | 				{
 98 | 					delta = -delta;
 99 | 					synth.offset_inline( time, delta, osc_output );
100 | 					time += period;
101 | 				}
102 | 				while ( time < end_time );
103 | 				
104 | 				oscs [index].last_amp = (delta + volume) >> 1;
105 | 				phases [index] = (delta > 0);
106 | 			}
107 | 			else
108 | 			{
109 | 				// maintain phase when silent
110 | 				int count = (end_time - time + period - 1) / period;
111 | 				phases [index] ^= count & 1;
112 | 				time += (blargg_long) count * period;
113 | 			}
114 | 		}
115 | 		
116 | 		delays [index] = time - end_time;
117 | 	}
118 | 	
119 | 	last_time = end_time;
120 | }
121 | 
122 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Nes_Fme7_Apu.h:
--------------------------------------------------------------------------------
  1 | // Sunsoft FME-7 sound emulator
  2 | 
  3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
  4 | #ifndef NES_FME7_APU_H
  5 | #define NES_FME7_APU_H
  6 | 
  7 | #include "blargg_common.h"
  8 | #include "Blip_Buffer.h"
  9 | 
 10 | struct fme7_apu_state_t
 11 | {
 12 | 	enum { reg_count = 14 };
 13 | 	uint8_t regs [reg_count];
 14 | 	uint8_t phases [3]; // 0 or 1
 15 | 	uint8_t latch;
 16 | 	uint16_t delays [3]; // a, b, c
 17 | };
 18 | 
 19 | class Nes_Fme7_Apu : private fme7_apu_state_t {
 20 | public:
 21 | 	// See Nes_Apu.h for reference
 22 | 	void reset();
 23 | 	void volume( double );
 24 | 	void treble_eq( blip_eq_t const& );
 25 | 	void output( Blip_Buffer* );
 26 | 	enum { osc_count = 3 };
 27 | 	void osc_output( int index, Blip_Buffer* );
 28 | 	void end_frame( blip_time_t );
 29 | 	void save_state( fme7_apu_state_t* ) const;
 30 | 	void load_state( fme7_apu_state_t const& );
 31 | 	
 32 | 	// Mask and addresses of registers
 33 | 	enum { addr_mask = 0xE000 };
 34 | 	enum { data_addr = 0xE000 };
 35 | 	enum { latch_addr = 0xC000 };
 36 | 	
 37 | 	// (addr & addr_mask) == latch_addr
 38 | 	void write_latch( int );
 39 | 	
 40 | 	// (addr & addr_mask) == data_addr
 41 | 	void write_data( blip_time_t, int data );
 42 | 	
 43 | public:
 44 | 	Nes_Fme7_Apu();
 45 | 	BLARGG_DISABLE_NOTHROW
 46 | private:
 47 | 	// noncopyable
 48 | 	Nes_Fme7_Apu( const Nes_Fme7_Apu& );
 49 | 	Nes_Fme7_Apu& operator = ( const Nes_Fme7_Apu& );
 50 | 	
 51 | 	static unsigned char const amp_table [16];
 52 | 	
 53 | 	struct {
 54 | 		Blip_Buffer* output;
 55 | 		int last_amp;
 56 | 	} oscs [osc_count];
 57 | 	blip_time_t last_time;
 58 | 	
 59 | 	enum { amp_range = 192 }; // can be any value; this gives best error/quality tradeoff
 60 | 	Blip_Synth synth;
 61 | 	
 62 | 	void run_until( blip_time_t );
 63 | };
 64 | 
 65 | inline void Nes_Fme7_Apu::volume( double v )
 66 | {
 67 | 	synth.volume( 0.38 / amp_range * v ); // to do: fine-tune
 68 | }
 69 | 
 70 | inline void Nes_Fme7_Apu::treble_eq( blip_eq_t const& eq )
 71 | {
 72 | 	synth.treble_eq( eq );
 73 | }
 74 | 
 75 | inline void Nes_Fme7_Apu::osc_output( int i, Blip_Buffer* buf )
 76 | {
 77 | 	assert( (unsigned) i < osc_count );
 78 | 	oscs [i].output = buf;
 79 | }
 80 | 
 81 | inline void Nes_Fme7_Apu::output( Blip_Buffer* buf )
 82 | {
 83 | 	for ( int i = 0; i < osc_count; i++ )
 84 | 		osc_output( i, buf );
 85 | }
 86 | 
 87 | inline Nes_Fme7_Apu::Nes_Fme7_Apu()
 88 | {
 89 | 	output( NULL );
 90 | 	volume( 1.0 );
 91 | 	reset();
 92 | }
 93 | 
 94 | inline void Nes_Fme7_Apu::write_latch( int data ) { latch = data; }
 95 | 
 96 | inline void Nes_Fme7_Apu::write_data( blip_time_t time, int data )
 97 | {
 98 | 	if ( (unsigned) latch >= reg_count )
 99 | 	{
100 | 		#ifdef debug_printf
101 | 			debug_printf( "FME7 write to %02X (past end of sound registers)\n", (int) latch );
102 | 		#endif
103 | 		return;
104 | 	}
105 | 	
106 | 	run_until( time );
107 | 	regs [latch] = data;
108 | }
109 | 
110 | inline void Nes_Fme7_Apu::end_frame( blip_time_t time )
111 | {
112 | 	if ( time > last_time )
113 | 		run_until( time );
114 | 	
115 | 	assert( last_time >= time );
116 | 	last_time -= time;
117 | }
118 | 
119 | inline void Nes_Fme7_Apu::save_state( fme7_apu_state_t* out ) const
120 | {
121 | 	*out = *this;
122 | }
123 | 
124 | inline void Nes_Fme7_Apu::load_state( fme7_apu_state_t const& in )
125 | {
126 | 	reset();
127 | 	fme7_apu_state_t* state = this;
128 | 	*state = in;
129 | }
130 | 
131 | #endif
132 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Nes_Namco_Apu.cpp:
--------------------------------------------------------------------------------
  1 | // Nes_Snd_Emu 0.1.8. http://www.slack.net/~ant/
  2 | 
  3 | #include "Nes_Namco_Apu.h"
  4 | 
  5 | /* Copyright (C) 2003-2006 Shay Green. This module is free software; you
  6 | can redistribute it and/or modify it under the terms of the GNU Lesser
  7 | General Public License as published by the Free Software Foundation; either
  8 | version 2.1 of the License, or (at your option) any later version. This
  9 | module is distributed in the hope that it will be useful, but WITHOUT ANY
 10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 11 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 12 | details. You should have received a copy of the GNU Lesser General Public
 13 | License along with this module; if not, write to the Free Software Foundation,
 14 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
 15 | 
 16 | #include "blargg_source.h"
 17 | 
 18 | Nes_Namco_Apu::Nes_Namco_Apu()
 19 | {
 20 | 	output( NULL );
 21 | 	volume( 1.0 );
 22 | 	reset();
 23 | }
 24 | 
 25 | void Nes_Namco_Apu::reset()
 26 | {
 27 | 	last_time = 0;
 28 | 	addr_reg = 0;
 29 | 	
 30 | 	int i;
 31 | 	for ( i = 0; i < reg_count; i++ )
 32 | 		reg [i] = 0;
 33 | 	
 34 | 	for ( i = 0; i < osc_count; i++ )
 35 | 	{
 36 | 		Namco_Osc& osc = oscs [i];
 37 | 		osc.delay = 0;
 38 | 		osc.last_amp = 0;
 39 | 		osc.wave_pos = 0;
 40 | 	}
 41 | }
 42 | 
 43 | void Nes_Namco_Apu::output( Blip_Buffer* buf )
 44 | {
 45 | 	for ( int i = 0; i < osc_count; i++ )
 46 | 		osc_output( i, buf );
 47 | }
 48 | 
 49 | /*
 50 | void Nes_Namco_Apu::reflect_state( Tagged_Data& data )
 51 | {
 52 | 	reflect_int16( data, BLARGG_4CHAR('A','D','D','R'), &addr_reg );
 53 | 	
 54 | 	static const char hex [17] = "0123456789ABCDEF";
 55 | 	int i;
 56 | 	for ( i = 0; i < reg_count; i++ )
 57 | 		reflect_int16( data, 'RG\0\0' + hex [i >> 4] * 0x100 + hex [i & 15], ® [i] );
 58 | 	
 59 | 	for ( i = 0; i < osc_count; i++ )
 60 | 	{
 61 | 		reflect_int32( data, BLARGG_4CHAR('D','L','Y','0') + i, &oscs [i].delay );
 62 | 		reflect_int16( data, BLARGG_4CHAR('P','O','S','0') + i, &oscs [i].wave_pos );
 63 | 	}
 64 | }
 65 | */
 66 | 
 67 | void Nes_Namco_Apu::end_frame( blip_time_t time )
 68 | {
 69 | 	if ( time > last_time )
 70 | 		run_until( time );
 71 | 	
 72 | 	assert( last_time >= time );
 73 | 	last_time -= time;
 74 | }
 75 | 
 76 | void Nes_Namco_Apu::run_until( blip_time_t nes_end_time )
 77 | {
 78 | 	int active_oscs = (reg [0x7F] >> 4 & 7) + 1;
 79 | 	for ( int i = osc_count - active_oscs; i < osc_count; i++ )
 80 | 	{
 81 | 		Namco_Osc& osc = oscs [i];
 82 | 		Blip_Buffer* output = osc.output;
 83 | 		if ( !output )
 84 | 			continue;
 85 | 		output->set_modified();
 86 | 		
 87 | 		blip_resampled_time_t time =
 88 | 				output->resampled_time( last_time ) + osc.delay;
 89 | 		blip_resampled_time_t end_time = output->resampled_time( nes_end_time );
 90 | 		osc.delay = 0;
 91 | 		if ( time < end_time )
 92 | 		{
 93 | 			const uint8_t* osc_reg = ® [i * 8 + 0x40];
 94 | 			if ( !(osc_reg [4] & 0xE0) )
 95 | 				continue;
 96 | 			
 97 | 			int volume = osc_reg [7] & 15;
 98 | 			if ( !volume )
 99 | 				continue;
100 | 			
101 | 			blargg_long freq = (osc_reg [4] & 3) * 0x10000 + osc_reg [2] * 0x100L + osc_reg [0];
102 | 			if ( freq < 64 * active_oscs )
103 | 				continue; // prevent low frequencies from excessively delaying freq changes
104 | 			blip_resampled_time_t period =
105 | 					output->resampled_duration( 983040 ) / freq * active_oscs;
106 | 			
107 | 			int wave_size = 32 - (osc_reg [4] >> 2 & 7) * 4;
108 | 			if ( !wave_size )
109 | 				continue;
110 | 			
111 | 			int last_amp = osc.last_amp;
112 | 			int wave_pos = osc.wave_pos;
113 | 			
114 | 			do
115 | 			{
116 | 				// read wave sample
117 | 				int addr = wave_pos + osc_reg [6];
118 | 				int sample = reg [addr >> 1] >> (addr << 2 & 4);
119 | 				wave_pos++;
120 | 				sample = (sample & 15) * volume;
121 | 				
122 | 				// output impulse if amplitude changed
123 | 				int delta = sample - last_amp;
124 | 				if ( delta )
125 | 				{
126 | 					last_amp = sample;
127 | 					synth.offset_resampled( time, delta, output );
128 | 				}
129 | 				
130 | 				// next sample
131 | 				time += period;
132 | 				if ( wave_pos >= wave_size )
133 | 					wave_pos = 0;
134 | 			}
135 | 			while ( time < end_time );
136 | 			
137 | 			osc.wave_pos = wave_pos;
138 | 			osc.last_amp = last_amp;
139 | 		}
140 | 		osc.delay = time - end_time;
141 | 	}
142 | 	
143 | 	last_time = nes_end_time;
144 | }
145 | 
146 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Nes_Namco_Apu.h:
--------------------------------------------------------------------------------
  1 | // Namco 106 sound chip emulator
  2 | 
  3 | // Nes_Snd_Emu 0.1.8
  4 | #ifndef NES_NAMCO_APU_H
  5 | #define NES_NAMCO_APU_H
  6 | 
  7 | #include "blargg_common.h"
  8 | #include "Blip_Buffer.h"
  9 | 
 10 | struct namco_state_t;
 11 | 
 12 | class Nes_Namco_Apu {
 13 | public:
 14 | 	// See Nes_Apu.h for reference.
 15 | 	void volume( double );
 16 | 	void treble_eq( const blip_eq_t& );
 17 | 	void output( Blip_Buffer* );
 18 | 	enum { osc_count = 8 };
 19 | 	void osc_output( int index, Blip_Buffer* );
 20 | 	void reset();
 21 | 	void end_frame( blip_time_t );
 22 | 	
 23 | 	// Read/write data register is at 0x4800
 24 | 	enum { data_reg_addr = 0x4800 };
 25 | 	void write_data( blip_time_t, int );
 26 | 	int read_data();
 27 | 	
 28 | 	// Write-only address register is at 0xF800
 29 | 	enum { addr_reg_addr = 0xF800 };
 30 | 	void write_addr( int );
 31 | 	
 32 | 	// to do: implement save/restore
 33 | 	void save_state( namco_state_t* out ) const;
 34 | 	void load_state( namco_state_t const& );
 35 | 	
 36 | public:
 37 | 	Nes_Namco_Apu();
 38 | 	BLARGG_DISABLE_NOTHROW
 39 | private:
 40 | 	// noncopyable
 41 | 	Nes_Namco_Apu( const Nes_Namco_Apu& );
 42 | 	Nes_Namco_Apu& operator = ( const Nes_Namco_Apu& );
 43 | 	
 44 | 	struct Namco_Osc {
 45 | 		blargg_long delay;
 46 | 		Blip_Buffer* output;
 47 | 		short last_amp;
 48 | 		short wave_pos;
 49 | 	};
 50 | 	
 51 | 	Namco_Osc oscs [osc_count];
 52 | 	
 53 | 	blip_time_t last_time;
 54 | 	int addr_reg;
 55 | 	
 56 | 	enum { reg_count = 0x80 };
 57 | 	uint8_t reg [reg_count];
 58 | 	Blip_Synth synth;
 59 | 	
 60 | 	uint8_t& access();
 61 | 	void run_until( blip_time_t );
 62 | };
 63 | /*
 64 | struct namco_state_t
 65 | {
 66 | 	uint8_t regs [0x80];
 67 | 	uint8_t addr;
 68 | 	uint8_t unused;
 69 | 	uint8_t positions [8];
 70 | 	uint32_t delays [8];
 71 | };
 72 | */
 73 | 
 74 | inline uint8_t& Nes_Namco_Apu::access()
 75 | {
 76 | 	int addr = addr_reg & 0x7F;
 77 | 	if ( addr_reg & 0x80 )
 78 | 		addr_reg = (addr + 1) | 0x80;
 79 | 	return reg [addr];
 80 | }
 81 | 
 82 | inline void Nes_Namco_Apu::volume( double v ) { synth.volume( 0.10 / osc_count * v ); }
 83 | 
 84 | inline void Nes_Namco_Apu::treble_eq( const blip_eq_t& eq ) { synth.treble_eq( eq ); }
 85 | 
 86 | inline void Nes_Namco_Apu::write_addr( int v ) { addr_reg = v; }
 87 | 
 88 | inline int Nes_Namco_Apu::read_data() { return access(); }
 89 | 
 90 | inline void Nes_Namco_Apu::osc_output( int i, Blip_Buffer* buf )
 91 | {
 92 | 	assert( (unsigned) i < osc_count );
 93 | 	oscs [i].output = buf;
 94 | }
 95 | 
 96 | inline void Nes_Namco_Apu::write_data( blip_time_t time, int data )
 97 | {
 98 | 	run_until( time );
 99 | 	access() = data;
100 | }
101 | 
102 | #endif
103 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Nes_Oscs.h:
--------------------------------------------------------------------------------
  1 | // Private oscillators used by Nes_Apu
  2 | 
  3 | // Nes_Snd_Emu 0.1.8
  4 | #ifndef NES_OSCS_H
  5 | #define NES_OSCS_H
  6 | 
  7 | #include "blargg_common.h"
  8 | #include "Blip_Buffer.h"
  9 | 
 10 | class Nes_Apu;
 11 | 
 12 | struct Nes_Osc
 13 | {
 14 | 	unsigned char regs [4];
 15 | 	bool reg_written [4];
 16 | 	Blip_Buffer* output;
 17 | 	int length_counter;// length counter (0 if unused by oscillator)
 18 | 	int delay;      // delay until next (potential) transition
 19 | 	int last_amp;   // last amplitude oscillator was outputting
 20 | 	
 21 | 	void clock_length( int halt_mask );
 22 | 	int period() const {
 23 | 		return (regs [3] & 7) * 0x100 + (regs [2] & 0xFF);
 24 | 	}
 25 | 	void reset() {
 26 | 		delay = 0;
 27 | 		last_amp = 0;
 28 | 	}
 29 | 	int update_amp( int amp ) {
 30 | 		int delta = amp - last_amp;
 31 | 		last_amp = amp;
 32 | 		return delta;
 33 | 	}
 34 | };
 35 | 
 36 | struct Nes_Envelope : Nes_Osc
 37 | {
 38 | 	int envelope;
 39 | 	int env_delay;
 40 | 	
 41 | 	void clock_envelope();
 42 | 	int volume() const;
 43 | 	void reset() {
 44 | 		envelope = 0;
 45 | 		env_delay = 0;
 46 | 		Nes_Osc::reset();
 47 | 	}
 48 | };
 49 | 
 50 | // Nes_Square
 51 | struct Nes_Square : Nes_Envelope
 52 | {
 53 | 	enum { negate_flag = 0x08 };
 54 | 	enum { shift_mask = 0x07 };
 55 | 	enum { phase_range = 8 };
 56 | 	int phase;
 57 | 	int sweep_delay;
 58 | 	
 59 | 	typedef Blip_Synth Synth;
 60 | 	Synth const& synth; // shared between squares
 61 | 	
 62 | 	Nes_Square( Synth const* s ) : synth( *s ) { }
 63 | 	
 64 | 	void clock_sweep( int adjust );
 65 | 	void run( nes_time_t, nes_time_t );
 66 | 	void reset() {
 67 | 		sweep_delay = 0;
 68 | 		Nes_Envelope::reset();
 69 | 	}
 70 | 	nes_time_t maintain_phase( nes_time_t time, nes_time_t end_time,
 71 | 			nes_time_t timer_period );
 72 | };
 73 | 
 74 | // Nes_Triangle
 75 | struct Nes_Triangle : Nes_Osc
 76 | {
 77 | 	enum { phase_range = 16 };
 78 | 	int phase;
 79 | 	int linear_counter;
 80 | 	Blip_Synth synth;
 81 | 	
 82 | 	int calc_amp() const;
 83 | 	void run( nes_time_t, nes_time_t );
 84 | 	void clock_linear_counter();
 85 | 	void reset() {
 86 | 		linear_counter = 0;
 87 | 		phase = 1;
 88 | 		Nes_Osc::reset();
 89 | 	}
 90 | 	nes_time_t maintain_phase( nes_time_t time, nes_time_t end_time,
 91 | 			nes_time_t timer_period );
 92 | };
 93 | 
 94 | // Nes_Noise
 95 | struct Nes_Noise : Nes_Envelope
 96 | {
 97 | 	int noise;
 98 | 	Blip_Synth synth;
 99 | 	
100 | 	void run( nes_time_t, nes_time_t );
101 | 	void reset() {
102 | 		noise = 1 << 14;
103 | 		Nes_Envelope::reset();
104 | 	}
105 | };
106 | 
107 | // Nes_Dmc
108 | struct Nes_Dmc : Nes_Osc
109 | {
110 | 	int address;    // address of next byte to read
111 | 	int period;
112 | 	//int length_counter; // bytes remaining to play (already defined in Nes_Osc)
113 | 	int buf;
114 | 	int bits_remain;
115 | 	int bits;
116 | 	bool buf_full;
117 | 	bool silence;
118 | 	
119 | 	enum { loop_flag = 0x40 };
120 | 	
121 | 	int dac;
122 | 	
123 | 	nes_time_t next_irq;
124 | 	bool irq_enabled;
125 | 	bool irq_flag;
126 | 	bool pal_mode;
127 | 	bool nonlinear;
128 | 	
129 | 	int (*prg_reader)( void*, nes_addr_t ); // needs to be initialized to prg read function
130 | 	void* prg_reader_data;
131 | 	
132 | 	Nes_Apu* apu;
133 | 	
134 | 	Blip_Synth synth;
135 | 	
136 | 	void start();
137 | 	void write_register( int, int );
138 | 	void run( nes_time_t, nes_time_t );
139 | 	void recalc_irq();
140 | 	void fill_buffer();
141 | 	void reload_sample();
142 | 	void reset();
143 | 	int count_reads( nes_time_t, nes_time_t* ) const;
144 | 	nes_time_t next_read_time() const;
145 | };
146 | 
147 | #endif
148 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Nes_Vrc6_Apu.h:
--------------------------------------------------------------------------------
 1 | // Konami VRC6 sound chip emulator
 2 | 
 3 | // Nes_Snd_Emu 0.1.8
 4 | #ifndef NES_VRC6_APU_H
 5 | #define NES_VRC6_APU_H
 6 | 
 7 | #include "blargg_common.h"
 8 | #include "Blip_Buffer.h"
 9 | 
10 | struct vrc6_apu_state_t;
11 | 
12 | class Nes_Vrc6_Apu {
13 | public:
14 | 	// See Nes_Apu.h for reference
15 | 	void reset();
16 | 	void volume( double );
17 | 	void treble_eq( blip_eq_t const& );
18 | 	void output( Blip_Buffer* );
19 | 	enum { osc_count = 3 };
20 | 	void osc_output( int index, Blip_Buffer* );
21 | 	void end_frame( blip_time_t );
22 | 	void save_state( vrc6_apu_state_t* ) const;
23 | 	void load_state( vrc6_apu_state_t const& );
24 | 	
25 | 	// Oscillator 0 write-only registers are at $9000-$9002
26 | 	// Oscillator 1 write-only registers are at $A000-$A002
27 | 	// Oscillator 2 write-only registers are at $B000-$B002
28 | 	enum { reg_count = 3 };
29 | 	enum { base_addr = 0x9000 };
30 | 	enum { addr_step = 0x1000 };
31 | 	void write_osc( blip_time_t, int osc, int reg, int data );
32 | 	
33 | public:
34 | 	Nes_Vrc6_Apu();
35 | 	BLARGG_DISABLE_NOTHROW
36 | private:
37 | 	// noncopyable
38 | 	Nes_Vrc6_Apu( const Nes_Vrc6_Apu& );
39 | 	Nes_Vrc6_Apu& operator = ( const Nes_Vrc6_Apu& );
40 | 	
41 | 	struct Vrc6_Osc
42 | 	{
43 | 		uint8_t regs [3];
44 | 		Blip_Buffer* output;
45 | 		int delay;
46 | 		int last_amp;
47 | 		int phase;
48 | 		int amp; // only used by saw
49 | 		
50 | 		int period() const
51 | 		{
52 | 			return (regs [2] & 0x0F) * 0x100L + regs [1] + 1;
53 | 		}
54 | 	};
55 | 	
56 | 	Vrc6_Osc oscs [osc_count];
57 | 	blip_time_t last_time;
58 | 	
59 | 	Blip_Synth saw_synth;
60 | 	Blip_Synth square_synth;
61 | 	
62 | 	void run_until( blip_time_t );
63 | 	void run_square( Vrc6_Osc& osc, blip_time_t );
64 | 	void run_saw( blip_time_t );
65 | };
66 | 
67 | struct vrc6_apu_state_t
68 | {
69 | 	uint8_t regs [3] [3];
70 | 	uint8_t saw_amp;
71 | 	uint16_t delays [3];
72 | 	uint8_t phases [3];
73 | 	uint8_t unused;
74 | };
75 | 
76 | inline void Nes_Vrc6_Apu::osc_output( int i, Blip_Buffer* buf )
77 | {
78 | 	assert( (unsigned) i < osc_count );
79 | 	oscs [i].output = buf;
80 | }
81 | 
82 | inline void Nes_Vrc6_Apu::volume( double v )
83 | {
84 | 	double const factor = 0.0967 * 2;
85 | 	saw_synth.volume( factor / 31 * v );
86 | 	square_synth.volume( factor * 0.5 / 15 * v );
87 | }
88 | 
89 | inline void Nes_Vrc6_Apu::treble_eq( blip_eq_t const& eq )
90 | {
91 | 	saw_synth.treble_eq( eq );
92 | 	square_synth.treble_eq( eq );
93 | }
94 | 
95 | #endif
96 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Nsf_Emu.h:
--------------------------------------------------------------------------------
  1 | // Nintendo NES/Famicom NSF music file emulator
  2 | 
  3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
  4 | #ifndef NSF_EMU_H
  5 | #define NSF_EMU_H
  6 | 
  7 | #include "Classic_Emu.h"
  8 | #include "Nes_Apu.h"
  9 | #include "Nes_Cpu.h"
 10 | 
 11 | class Nsf_Emu : private Nes_Cpu, public Classic_Emu {
 12 | 	typedef Nes_Cpu cpu;
 13 | public:
 14 | 	// Equalizer profiles for US NES and Japanese Famicom
 15 | 	static equalizer_t const nes_eq;
 16 | 	static equalizer_t const famicom_eq;
 17 | 	
 18 | 	// NSF file header
 19 | 	enum { header_size = 0x80 };
 20 | 	struct header_t
 21 | 	{
 22 | 		char tag [5];
 23 | 		byte vers;
 24 | 		byte track_count;
 25 | 		byte first_track;
 26 | 		byte load_addr [2];
 27 | 		byte init_addr [2];
 28 | 		byte play_addr [2];
 29 | 		char game [32];
 30 | 		char author [32];
 31 | 		char copyright [32];
 32 | 		byte ntsc_speed [2];
 33 | 		byte banks [8];
 34 | 		byte pal_speed [2];
 35 | 		byte speed_flags;
 36 | 		byte chip_flags;
 37 | 		byte unused [4];
 38 | 	};
 39 | 	
 40 | 	// Header for currently loaded file
 41 | 	header_t const& header() const { return header_; }
 42 | 	
 43 | 	static gme_type_t static_type() { return gme_nsf_type; }
 44 | 	
 45 | public:
 46 | 	// deprecated
 47 | 	using Music_Emu::load;
 48 | 	blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
 49 | 			{ return load_remaining_( &h, sizeof h, in ); }
 50 | 
 51 | public:
 52 | 	Nsf_Emu();
 53 | 	~Nsf_Emu();
 54 | 	Nes_Apu* apu_() { return &apu; }
 55 | protected:
 56 | 	blargg_err_t track_info_( track_info_t*, int track ) const;
 57 | 	blargg_err_t load_( Data_Reader& );
 58 | 	blargg_err_t start_track_( int );
 59 | 	blargg_err_t run_clocks( blip_time_t&, int );
 60 | 	void set_tempo_( double );
 61 | 	void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
 62 | 	void update_eq( blip_eq_t const& );
 63 | 	void unload();
 64 | protected:
 65 | 	enum { bank_count = 8 };
 66 | 	byte initial_banks [bank_count];
 67 | 	nes_addr_t init_addr;
 68 | 	nes_addr_t play_addr;
 69 | 	double clock_rate_;
 70 | 	bool pal_only;
 71 | 	
 72 | 	// timing
 73 | 	Nes_Cpu::registers_t saved_state;
 74 | 	nes_time_t next_play;
 75 | 	nes_time_t play_period;
 76 | 	int play_extra;
 77 | 	int play_ready;
 78 | 	
 79 | 	enum { rom_begin = 0x8000 };
 80 | 	enum { bank_select_addr = 0x5FF8 };
 81 | 	enum { bank_size = 0x1000 };
 82 | 	Rom_Data rom;
 83 | 	
 84 | public: private: friend class Nes_Cpu;
 85 | 	void cpu_jsr( nes_addr_t );
 86 | 	int cpu_read( nes_addr_t );
 87 | 	void cpu_write( nes_addr_t, int );
 88 | 	void cpu_write_misc( nes_addr_t, int );
 89 | 	enum { badop_addr = bank_select_addr };
 90 | 	
 91 | private:
 92 | 	class Nes_Namco_Apu* namco;
 93 | 	class Nes_Vrc6_Apu*  vrc6;
 94 | 	class Nes_Fme7_Apu*  fme7;
 95 | 	Nes_Apu apu;
 96 | 	static int pcm_read( void*, nes_addr_t );
 97 | 	blargg_err_t init_sound();
 98 | 	
 99 | 	header_t header_;
100 | 	
101 | 	enum { sram_addr = 0x6000 };
102 | 	byte sram [0x2000];
103 | 	byte unmapped_code [Nes_Cpu::page_size + 8];
104 | };
105 | 
106 | #endif
107 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Nsfe_Emu.h:
--------------------------------------------------------------------------------
 1 | // Nintendo NES/Famicom NSFE music file emulator
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef NSFE_EMU_H
 5 | #define NSFE_EMU_H
 6 | 
 7 | #include "blargg_common.h"
 8 | #include "Nsf_Emu.h"
 9 | 
10 | // Allows reading info from NSFE file without creating emulator
11 | class Nsfe_Info {
12 | public:
13 | 	blargg_err_t load( Data_Reader&, Nsf_Emu* );
14 | 	
15 | 	struct info_t : Nsf_Emu::header_t
16 | 	{
17 | 		char game      [256];
18 | 		char author    [256];
19 | 		char copyright [256];
20 | 		char dumper    [256];
21 | 	} info;
22 | 	
23 | 	void disable_playlist( bool = true );
24 | 	
25 | 	blargg_err_t track_info_( track_info_t* out, int track ) const;
26 | 	
27 | 	int remap_track( int i ) const;
28 | 	
29 | 	void unload();
30 | 	
31 | 	Nsfe_Info();
32 | 	~Nsfe_Info();
33 | private:
34 | 	blargg_vector track_name_data;
35 | 	blargg_vector track_names;
36 | 	blargg_vector playlist;
37 | 	blargg_vector track_times;
38 | 	int actual_track_count_;
39 | 	bool playlist_disabled;
40 | };
41 | 
42 | class Nsfe_Emu : public Nsf_Emu {
43 | public:
44 | 	static gme_type_t static_type() { return gme_nsfe_type; }
45 | 	
46 | public:
47 | 	// deprecated
48 | 	struct header_t { char tag [4]; };
49 | 	using Music_Emu::load;
50 | 	blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
51 | 			{ return load_remaining_( &h, sizeof h, in ); }
52 | 	void disable_playlist( bool = true ); // use clear_playlist()
53 | 
54 | public:
55 | 	Nsfe_Emu();
56 | 	~Nsfe_Emu();
57 | protected:
58 | 	blargg_err_t load_( Data_Reader& );
59 | 	blargg_err_t track_info_( track_info_t*, int track ) const;
60 | 	blargg_err_t start_track_( int );
61 | 	void unload();
62 | 	void clear_playlist_();
63 | private:
64 | 	Nsfe_Info info;
65 | 	bool loading;
66 | };
67 | 
68 | #endif
69 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Sap_Apu.h:
--------------------------------------------------------------------------------
 1 | // Atari POKEY sound chip emulator
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef SAP_APU_H
 5 | #define SAP_APU_H
 6 | 
 7 | #include "blargg_common.h"
 8 | #include "Blip_Buffer.h"
 9 | 
10 | class Sap_Apu_Impl;
11 | 
12 | class Sap_Apu {
13 | public:
14 | 	enum { osc_count = 4 };
15 | 	void osc_output( int index, Blip_Buffer* );
16 | 	
17 | 	void reset( Sap_Apu_Impl* );
18 | 	
19 | 	enum { start_addr = 0xD200 };
20 | 	enum { end_addr   = 0xD209 };
21 | 	void write_data( blip_time_t, unsigned addr, int data );
22 | 	
23 | 	void end_frame( blip_time_t );
24 | 	
25 | public:
26 | 	Sap_Apu();
27 | private:
28 | 	struct osc_t
29 | 	{
30 | 		unsigned char regs [2];
31 | 		unsigned char phase;
32 | 		unsigned char invert;
33 | 		int last_amp;
34 | 		blip_time_t delay;
35 | 		blip_time_t period; // always recalculated before use; here for convenience
36 | 		Blip_Buffer* output;
37 | 	};
38 | 	osc_t oscs [osc_count];
39 | 	Sap_Apu_Impl* impl;
40 | 	blip_time_t last_time;
41 | 	int poly5_pos;
42 | 	int poly4_pos;
43 | 	int polym_pos;
44 | 	int control;
45 | 	
46 | 	void calc_periods();
47 | 	void run_until( blip_time_t );
48 | 	
49 | 	enum { poly4_len  = (1L <<  4) - 1 };
50 | 	enum { poly9_len  = (1L <<  9) - 1 };
51 | 	enum { poly17_len = (1L << 17) - 1 };
52 | 	friend class Sap_Apu_Impl;
53 | };
54 | 
55 | // Common tables and Blip_Synth that can be shared among multiple Sap_Apu objects
56 | class Sap_Apu_Impl {
57 | public:
58 | 	Blip_Synth synth;
59 | 	
60 | 	Sap_Apu_Impl();
61 | 	void volume( double d ) { synth.volume( 1.0 / Sap_Apu::osc_count / 30 * d ); }
62 | 	
63 | private:
64 | 	typedef unsigned char byte;
65 | 	byte poly4  [Sap_Apu::poly4_len  / 8 + 1];
66 | 	byte poly9  [Sap_Apu::poly9_len  / 8 + 1];
67 | 	byte poly17 [Sap_Apu::poly17_len / 8 + 1];
68 | 	friend class Sap_Apu;
69 | };
70 | 
71 | inline void Sap_Apu::osc_output( int i, Blip_Buffer* b )
72 | {
73 | 	assert( (unsigned) i < osc_count );
74 | 	oscs [i].output = b;
75 | }
76 | 
77 | #endif
78 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Sap_Cpu.h:
--------------------------------------------------------------------------------
 1 | // Atari 6502 CPU emulator
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef SAP_CPU_H
 5 | #define SAP_CPU_H
 6 | 
 7 | #include "blargg_common.h"
 8 | 
 9 | typedef blargg_long sap_time_t; // clock cycle count
10 | typedef unsigned sap_addr_t; // 16-bit address
11 | enum { future_sap_time = INT_MAX / 2 + 1 };
12 | 
13 | class Sap_Cpu {
14 | public:
15 | 	// Clear all registers and keep pointer to 64K memory passed in
16 | 	void reset( void* mem_64k );
17 | 	
18 | 	// Run until specified time is reached. Returns true if suspicious/unsupported
19 | 	// instruction was encountered at any point during run.
20 | 	bool run( sap_time_t end_time );
21 | 	
22 | 	// Registers are not updated until run() returns (except I flag in status)
23 | 	struct registers_t {
24 | 		uint16_t pc;
25 | 		uint8_t a;
26 | 		uint8_t x;
27 | 		uint8_t y;
28 | 		uint8_t status;
29 | 		uint8_t sp;
30 | 	};
31 | 	registers_t r;
32 | 	
33 | 	enum { idle_addr = 0xFEFF };
34 | 	
35 | 	// Time of beginning of next instruction to be executed
36 | 	sap_time_t time() const             { return state->time + state->base; }
37 | 	void set_time( sap_time_t t )       { state->time = t - state->base; }
38 | 	void adjust_time( int delta )       { state->time += delta; }
39 | 	
40 | 	sap_time_t irq_time() const         { return irq_time_; }
41 | 	void set_irq_time( sap_time_t );
42 | 	
43 | 	sap_time_t end_time() const         { return end_time_; }
44 | 	void set_end_time( sap_time_t );
45 | 	
46 | public:
47 | 	Sap_Cpu() { state = &state_; }
48 | 	enum { irq_inhibit = 0x04 };
49 | private:
50 | 	struct state_t {
51 | 		sap_time_t base;
52 | 		sap_time_t time;
53 | 	};
54 | 	state_t* state; // points to state_ or a local copy within run()
55 | 	state_t state_;
56 | 	sap_time_t irq_time_;
57 | 	sap_time_t end_time_;
58 | 	uint8_t* mem;
59 | 	
60 | 	inline sap_time_t update_end_time( sap_time_t end, sap_time_t irq );
61 | };
62 | 
63 | inline sap_time_t Sap_Cpu::update_end_time( sap_time_t t, sap_time_t irq )
64 | {
65 | 	if ( irq < t && !(r.status & irq_inhibit) ) t = irq;
66 | 	sap_time_t delta = state->base - t;
67 | 	state->base = t;
68 | 	return delta;
69 | }
70 | 
71 | inline void Sap_Cpu::set_irq_time( sap_time_t t )
72 | {
73 | 	state->time += update_end_time( end_time_, (irq_time_ = t) );
74 | }
75 | 
76 | inline void Sap_Cpu::set_end_time( sap_time_t t )
77 | {
78 | 	state->time += update_end_time( (end_time_ = t), irq_time_ );
79 | }
80 | 
81 | #endif
82 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Sap_Emu.h:
--------------------------------------------------------------------------------
 1 | // Atari XL/XE SAP music file emulator
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef SAP_EMU_H
 5 | #define SAP_EMU_H
 6 | 
 7 | #include "Classic_Emu.h"
 8 | #include "Sap_Apu.h"
 9 | #include "Sap_Cpu.h"
10 | 
11 | class Sap_Emu : private Sap_Cpu, public Classic_Emu {
12 | 	typedef Sap_Cpu cpu;
13 | public:
14 | 	static gme_type_t static_type() { return gme_sap_type; }
15 | public:
16 | 	Sap_Emu();
17 | 	~Sap_Emu();
18 | 	struct info_t {
19 | 		byte const* rom_data;
20 | 		const char* warning;
21 | 		long init_addr;
22 | 		long play_addr;
23 | 		long music_addr;
24 | 		int  type;
25 | 		int  track_count;
26 | 		int  fastplay;
27 | 		bool stereo;
28 | 		char author    [256];
29 | 		char name      [256];
30 | 		char copyright [ 32];
31 | 	};
32 | protected:
33 | 	blargg_err_t track_info_( track_info_t*, int track ) const;
34 | 	blargg_err_t load_mem_( byte const*, long );
35 | 	blargg_err_t start_track_( int );
36 | 	blargg_err_t run_clocks( blip_time_t&, int );
37 | 	void set_tempo_( double );
38 | 	void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
39 | 	void update_eq( blip_eq_t const& );
40 | public: private: friend class Sap_Cpu;
41 | 	int cpu_read( sap_addr_t );
42 | 	void cpu_write( sap_addr_t, int );
43 | 	void cpu_write_( sap_addr_t, int );
44 | private:
45 | 	info_t info;
46 | 	
47 | 	byte const* file_end;
48 | 	sap_time_t scanline_period;
49 | 	sap_time_t next_play;
50 | 	sap_time_t time_mask;
51 | 	Sap_Apu apu;
52 | 	Sap_Apu apu2;
53 | 	
54 | 	// large items
55 | 	struct {
56 | 		byte padding1 [0x100];
57 | 		byte ram [0x10000 + 0x100];
58 | 	} mem;
59 | 	Sap_Apu_Impl apu_impl;
60 | 	
61 | 	sap_time_t play_period() const;
62 | 	void call_play();
63 | 	void cpu_jsr( sap_addr_t );
64 | 	void call_init( int track );
65 | 	void run_routine( sap_addr_t );
66 | };
67 | 
68 | #endif
69 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Sms_Apu.h:
--------------------------------------------------------------------------------
 1 | // Sega Master System SN76489 PSG sound chip emulator
 2 | 
 3 | // Sms_Snd_Emu 0.1.4
 4 | #ifndef SMS_APU_H
 5 | #define SMS_APU_H
 6 | 
 7 | #include "Sms_Oscs.h"
 8 | 
 9 | class Sms_Apu {
10 | public:
11 | 	// Set overall volume of all oscillators, where 1.0 is full volume
12 | 	void volume( double );
13 | 	
14 | 	// Set treble equalization
15 | 	void treble_eq( const blip_eq_t& );
16 | 	
17 | 	// Outputs can be assigned to a single buffer for mono output, or to three
18 | 	// buffers for stereo output (using Stereo_Buffer to do the mixing).
19 | 	
20 | 	// Assign all oscillator outputs to specified buffer(s). If buffer
21 | 	// is NULL, silences all oscillators.
22 | 	void output( Blip_Buffer* mono );
23 | 	void output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
24 | 	
25 | 	// Assign single oscillator output to buffer(s). Valid indicies are 0 to 3,
26 | 	// which refer to Square 1, Square 2, Square 3, and Noise. If buffer is NULL,
27 | 	// silences oscillator.
28 | 	enum { osc_count = 4 };
29 | 	void osc_output( int index, Blip_Buffer* mono );
30 | 	void osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
31 | 	
32 | 	// Reset oscillators and internal state
33 | 	void reset( unsigned noise_feedback = 0, int noise_width = 0 );
34 | 	
35 | 	// Write GameGear left/right assignment byte
36 | 	void write_ggstereo( blip_time_t, int );
37 | 	
38 | 	// Write to data port
39 | 	void write_data( blip_time_t, int );
40 | 	
41 | 	// Run all oscillators up to specified time, end current frame, then
42 | 	// start a new frame at time 0.
43 | 	void end_frame( blip_time_t );
44 | 
45 | public:
46 | 	Sms_Apu();
47 | 	~Sms_Apu();
48 | private:
49 | 	// noncopyable
50 | 	Sms_Apu( const Sms_Apu& );
51 | 	Sms_Apu& operator = ( const Sms_Apu& );
52 | 	
53 | 	Sms_Osc*    oscs [osc_count];
54 | 	Sms_Square  squares [3];
55 | 	Sms_Square::Synth square_synth; // used by squares
56 | 	blip_time_t last_time;
57 | 	int         latch;
58 | 	Sms_Noise   noise;
59 | 	unsigned    noise_feedback;
60 | 	unsigned    looped_feedback;
61 | 	
62 | 	void run_until( blip_time_t );
63 | };
64 | 
65 | struct sms_apu_state_t
66 | {
67 | 	unsigned char regs [8] [2];
68 | 	unsigned char latch;
69 | };
70 | 
71 | inline void Sms_Apu::output( Blip_Buffer* b ) { output( b, b, b ); }
72 | 
73 | inline void Sms_Apu::osc_output( int i, Blip_Buffer* b ) { osc_output( i, b, b, b ); }
74 | 
75 | #endif
76 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Sms_Oscs.h:
--------------------------------------------------------------------------------
 1 | // Private oscillators used by Sms_Apu
 2 | 
 3 | // Sms_Snd_Emu 0.1.4
 4 | #ifndef SMS_OSCS_H
 5 | #define SMS_OSCS_H
 6 | 
 7 | #include "blargg_common.h"
 8 | #include "Blip_Buffer.h"
 9 | 
10 | struct Sms_Osc
11 | {
12 | 	Blip_Buffer* outputs [4]; // NULL, right, left, center
13 | 	Blip_Buffer* output;
14 | 	int output_select;
15 | 	
16 | 	int delay;
17 | 	int last_amp;
18 | 	int volume;
19 | 	
20 | 	Sms_Osc();
21 | 	void reset();
22 | };
23 | 
24 | struct Sms_Square : Sms_Osc
25 | {
26 | 	int period;
27 | 	int phase;
28 | 	
29 | 	typedef Blip_Synth Synth;
30 | 	const Synth* synth;
31 | 	
32 | 	void reset();
33 | 	void run( blip_time_t, blip_time_t );
34 | };
35 | 
36 | struct Sms_Noise : Sms_Osc
37 | {
38 | 	const int* period;
39 | 	unsigned shifter;
40 | 	unsigned feedback;
41 | 	
42 | 	typedef Blip_Synth Synth;
43 | 	Synth synth;
44 | 	
45 | 	void reset();
46 | 	void run( blip_time_t, blip_time_t );
47 | };
48 | 
49 | #endif
50 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Spc_Emu.h:
--------------------------------------------------------------------------------
 1 | // Super Nintendo SPC music file emulator
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef SPC_EMU_H
 5 | #define SPC_EMU_H
 6 | 
 7 | #include "Fir_Resampler.h"
 8 | #include "Music_Emu.h"
 9 | #include "Snes_Spc.h"
10 | #include "Spc_Filter.h"
11 | 
12 | class Spc_Emu : public Music_Emu {
13 | public:
14 | 	// The Super Nintendo hardware samples at 32kHz. Other sample rates are
15 | 	// handled by resampling the 32kHz output; emulation accuracy is not affected.
16 | 	enum { native_sample_rate = 32000 };
17 | 	
18 | 	// SPC file header
19 | 	enum { header_size = 0x100 };
20 | 	struct header_t
21 | 	{
22 | 		char tag [35];
23 | 		byte format;
24 | 		byte version;
25 | 		byte pc [2];
26 | 		byte a, x, y, psw, sp;
27 | 		byte unused [2];
28 | 		char song [32];
29 | 		char game [32];
30 | 		char dumper [16];
31 | 		char comment [32];
32 | 		byte date [11];
33 | 		byte len_secs [3];
34 | 		byte fade_msec [4];
35 | 		char author [32]; // sometimes first char should be skipped (see official SPC spec)
36 | 		byte mute_mask;
37 | 		byte emulator;
38 | 		byte unused2 [46];
39 | 	};
40 | 	
41 | 	// Header for currently loaded file
42 | 	header_t const& header() const { return *(header_t const*) file_data; }
43 | 	
44 | 	// Prevents channels and global volumes from being phase-negated
45 | 	void disable_surround( bool disable = true );
46 | 	
47 | 	static gme_type_t static_type() { return gme_spc_type; }
48 | 	
49 | public:
50 | 	// deprecated
51 | 	using Music_Emu::load;
52 | 	blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
53 | 			{ return load_remaining_( &h, sizeof h, in ); }
54 | 	byte const* trailer() const; // use track_info()
55 | 	long trailer_size() const;
56 | 
57 | public:
58 | 	Spc_Emu();
59 | 	~Spc_Emu();
60 | protected:
61 | 	blargg_err_t load_mem_( byte const*, long );
62 | 	blargg_err_t track_info_( track_info_t*, int track ) const;
63 | 	blargg_err_t set_sample_rate_( long );
64 | 	blargg_err_t start_track_( int );
65 | 	blargg_err_t play_( long, sample_t* );
66 | 	blargg_err_t skip_( long );
67 | 	void mute_voices_( int );
68 | 	void set_tempo_( double );
69 | 	void enable_accuracy_( bool );
70 | private:
71 | 	byte const* file_data;
72 | 	long        file_size;
73 | 	Fir_Resampler<24> resampler;
74 | 	SPC_Filter filter;
75 | 	Snes_Spc apu;
76 | 	
77 | 	blargg_err_t play_and_filter( long count, sample_t out [] );
78 | };
79 | 
80 | inline void Spc_Emu::disable_surround( bool b ) { apu.disable_surround( b ); }
81 | 
82 | #endif
83 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Spc_Filter.cpp:
--------------------------------------------------------------------------------
 1 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 2 | 
 3 | #include "Spc_Filter.h"
 4 | 
 5 | #include 
 6 | 
 7 | /* Copyright (C) 2007 Shay Green. This module is free software; you
 8 | can redistribute it and/or modify it under the terms of the GNU Lesser
 9 | General Public License as published by the Free Software Foundation; either
10 | version 2.1 of the License, or (at your option) any later version. This
11 | module is distributed in the hope that it will be useful, but WITHOUT ANY
12 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 | details. You should have received a copy of the GNU Lesser General Public
15 | License along with this module; if not, write to the Free Software Foundation,
16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
17 | 
18 | #include "blargg_source.h"
19 | 
20 | void SPC_Filter::clear() { memset( ch, 0, sizeof ch ); }
21 | 
22 | SPC_Filter::SPC_Filter()
23 | {
24 | 	enabled = true;
25 | 	gain    = gain_unit;
26 | 	bass    = bass_norm;
27 | 	clear();
28 | }
29 | 
30 | void SPC_Filter::run( short* io, int count )
31 | {
32 | 	require( (count & 1) == 0 ); // must be even
33 | 	
34 | 	int const gain = this->gain;
35 | 	if ( enabled )
36 | 	{
37 | 		int const bass = this->bass;
38 | 		chan_t* c = &ch [2];
39 | 		do
40 | 		{
41 | 			// cache in registers
42 | 			int sum = (--c)->sum;
43 | 			int pp1 = c->pp1;
44 | 			int p1  = c->p1;
45 | 			
46 | 			for ( int i = 0; i < count; i += 2 )
47 | 			{
48 | 				// Low-pass filter (two point FIR with coeffs 0.25, 0.75)
49 | 				int f = io [i] + p1;
50 | 				p1 = io [i] * 3;
51 | 				
52 | 				// High-pass filter ("leaky integrator")
53 | 				int delta = f - pp1;
54 | 				pp1 = f;
55 | 				int s = sum >> (gain_bits + 2);
56 | 				sum += (delta * gain) - (sum >> bass);
57 | 				
58 | 				// Clamp to 16 bits
59 | 				if ( (short) s != s )
60 | 					s = (s >> 31) ^ 0x7FFF;
61 | 				
62 | 				io [i] = (short) s;
63 | 			}
64 | 			
65 | 			c->p1  = p1;
66 | 			c->pp1 = pp1;
67 | 			c->sum = sum;
68 | 			++io;
69 | 		}
70 | 		while ( c != ch );
71 | 	}
72 | 	else if ( gain != gain_unit )
73 | 	{
74 | 		short* const end = io + count;
75 | 		while ( io < end )
76 | 		{
77 | 			int s = (*io * gain) >> gain_bits;
78 | 			if ( (short) s != s )
79 | 				s = (s >> 31) ^ 0x7FFF;
80 | 			*io++ = (short) s;
81 | 		}
82 | 	}
83 | }
84 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Spc_Filter.h:
--------------------------------------------------------------------------------
 1 | // Simple low-pass and high-pass filter to better match sound output of a SNES
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef SPC_FILTER_H
 5 | #define SPC_FILTER_H
 6 | 
 7 | #include "blargg_common.h"
 8 | 
 9 | struct SPC_Filter {
10 | public:
11 | 	
12 | 	// Filters count samples of stereo sound in place. Count must be a multiple of 2.
13 | 	typedef short sample_t;
14 | 	void run( sample_t* io, int count );
15 | 	
16 | // Optional features
17 | 
18 | 	// Clears filter to silence
19 | 	void clear();
20 | 	
21 | 	// Sets gain (volume), where gain_unit is normal. Gains greater than gain_unit
22 | 	// are fine, since output is clamped to 16-bit sample range.
23 | 	enum { gain_unit = 0x100 };
24 | 	void set_gain( int gain );
25 | 	
26 | 	// Enables/disables filtering (when disabled, gain is still applied)
27 | 	void enable( bool b );
28 | 	
29 | 	// Sets amount of bass (logarithmic scale)
30 | 	enum { bass_none =  0 };
31 | 	enum { bass_norm =  8 }; // normal amount
32 | 	enum { bass_max  = 31 };
33 | 	void set_bass( int bass );
34 | 	
35 | public:
36 | 	SPC_Filter();
37 | 	BLARGG_DISABLE_NOTHROW
38 | private:
39 | 	enum { gain_bits = 8 };
40 | 	int gain;
41 | 	int bass;
42 | 	bool enabled;
43 | 	struct chan_t { int p1, pp1, sum; };
44 | 	chan_t ch [2];
45 | };
46 | 
47 | inline void SPC_Filter::enable( bool b )  { enabled = b; }
48 | 
49 | inline void SPC_Filter::set_gain( int g ) { gain = g; }
50 | 
51 | inline void SPC_Filter::set_bass( int b ) { bass = b; }
52 | 
53 | #endif
54 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Vgm_Emu.h:
--------------------------------------------------------------------------------
 1 | // Sega Master System/Mark III, Sega Genesis/Mega Drive, BBC Micro VGM music file emulator
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef VGM_EMU_H
 5 | #define VGM_EMU_H
 6 | 
 7 | #include "Vgm_Emu_Impl.h"
 8 | 
 9 | // Emulates VGM music using SN76489/SN76496 PSG, YM2612, and YM2413 FM sound chips.
10 | // Supports custom sound buffer and frequency equalization when VGM uses just the PSG.
11 | // FM sound chips can be run at their proper rates, or slightly higher to reduce
12 | // aliasing on high notes. Currently YM2413 support requires that you supply a
13 | // YM2413 sound chip emulator. I can provide one I've modified to work with the library.
14 | class Vgm_Emu : public Vgm_Emu_Impl {
15 | public:
16 | 	// True if custom buffer and custom equalization are supported
17 | 	// TODO: move into Music_Emu and rename to something like supports_custom_buffer()
18 | 	bool is_classic_emu() const { return !uses_fm; }
19 | 	
20 | 	blargg_err_t set_multi_channel ( bool is_enabled ) override;
21 | 	
22 | 	// Disable running FM chips at higher than normal rate. Will result in slightly
23 | 	// more aliasing of high notes.
24 | 	void disable_oversampling( bool disable = true ) { disable_oversampling_ = disable; }
25 | 	
26 | 	// VGM header format
27 | 	enum { header_size = 0x40 };
28 | 	struct header_t
29 | 	{
30 | 		char tag [4];
31 | 		byte data_size [4];
32 | 		byte version [4];
33 | 		byte psg_rate [4];
34 | 		byte ym2413_rate [4];
35 | 		byte gd3_offset [4];
36 | 		byte track_duration [4];
37 | 		byte loop_offset [4];
38 | 		byte loop_duration [4];
39 | 		byte frame_rate [4];
40 | 		byte noise_feedback [2];
41 | 		byte noise_width;
42 | 		byte unused1;
43 | 		byte ym2612_rate [4];
44 | 		byte ym2151_rate [4];
45 | 		byte data_offset [4];
46 | 		byte unused2 [8];
47 | 	};
48 | 	
49 | 	// Header for currently loaded file
50 | 	header_t const& header() const { return *(header_t const*) data; }
51 | 	
52 | 	static gme_type_t static_type() { return gme_vgm_type; }
53 | 	
54 | public:
55 | 	// deprecated
56 | 	using Music_Emu::load;
57 | 	blargg_err_t load( header_t const& h, Data_Reader& in ) // use Remaining_Reader
58 | 			{ return load_remaining_( &h, sizeof h, in ); }
59 | 	byte const* gd3_data( int* size_out = 0 ) const; // use track_info()
60 | 
61 | public:
62 | 	Vgm_Emu();
63 | 	~Vgm_Emu();
64 | protected:
65 | 	blargg_err_t track_info_( track_info_t*, int track ) const;
66 | 	blargg_err_t load_mem_( byte const*, long );
67 | 	blargg_err_t set_sample_rate_( long sample_rate );
68 | 	blargg_err_t start_track_( int );
69 | 	blargg_err_t play_( long count, sample_t* );
70 | 	blargg_err_t run_clocks( blip_time_t&, int );
71 | 	void set_tempo_( double );
72 | 	void mute_voices_( int mask );
73 | 	void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
74 | 	void update_eq( blip_eq_t const& );
75 | private:
76 | 	// removed; use disable_oversampling() and set_tempo() instead
77 | 	Vgm_Emu( bool oversample, double tempo = 1.0 );
78 | 	double fm_rate;
79 | 	long psg_rate;
80 | 	long vgm_rate;
81 | 	bool disable_oversampling_;
82 | 	bool uses_fm;
83 | 	blargg_err_t setup_fm();
84 | };
85 | 
86 | #endif
87 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Vgm_Emu_Impl.h:
--------------------------------------------------------------------------------
 1 | // Low-level parts of Vgm_Emu
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef VGM_EMU_IMPL_H
 5 | #define VGM_EMU_IMPL_H
 6 | 
 7 | #include "Dual_Resampler.h"
 8 | #include "Classic_Emu.h"
 9 | #include "Ym2413_Emu.h"
10 | #include "Ym2612_Emu.h"
11 | #include "Sms_Apu.h"
12 | 
13 | template
14 | class Ym_Emu : public Emu {
15 | protected:
16 | 	int last_time;
17 | 	short* out;
18 | 	enum { disabled_time = -1 };
19 | public:
20 | 	Ym_Emu()                        : last_time( disabled_time ), out( NULL ) { }
21 | 	void enable( bool b )           { last_time = b ? 0 : disabled_time; }
22 | 	bool enabled() const            { return last_time != disabled_time; }
23 | 	void begin_frame( short* p );
24 | 	int run_until( int time );
25 | };
26 | 
27 | class Vgm_Emu_Impl : public Classic_Emu, private Dual_Resampler {
28 | public:
29 | 	typedef Classic_Emu::sample_t sample_t;
30 | protected:
31 | 	enum { stereo = 2 };
32 | 	
33 | 	typedef int vgm_time_t;
34 | 	
35 | 	enum { fm_time_bits = 12 };
36 | 	typedef int fm_time_t;
37 | 	long fm_time_offset;
38 | 	int fm_time_factor;
39 | 	fm_time_t to_fm_time( vgm_time_t ) const;
40 | 	
41 | 	enum { blip_time_bits = 12 };
42 | 	int blip_time_factor;
43 | 	blip_time_t to_blip_time( vgm_time_t ) const;
44 | 	
45 | 	byte const* data;
46 | 	byte const* loop_begin;
47 | 	byte const* data_end;
48 | 	void update_fm_rates( long* ym2413_rate, long* ym2612_rate ) const;
49 | 	
50 | 	vgm_time_t vgm_time;
51 | 	byte const* pos;
52 | 	blip_time_t run_commands( vgm_time_t );
53 | 	int play_frame( blip_time_t blip_time, int sample_count, sample_t* buf );
54 | 	
55 | 	byte const* pcm_data;
56 | 	byte const* pcm_pos;
57 | 	int dac_amp;
58 | 	int dac_disabled; // -1 if disabled
59 | 	void write_pcm( vgm_time_t, int amp );
60 | 	
61 | 	Ym_Emu ym2612[2];
62 | 	Ym_Emu ym2413[2];
63 | 	
64 | 	Blip_Buffer blip_buf;
65 | 	Sms_Apu psg[2];
66 | 	bool psg_dual;
67 | 	bool psg_t6w28;
68 | 	Blip_Synth dac_synth;
69 | 	
70 | 	friend class Vgm_Emu;
71 | };
72 | 
73 | #endif
74 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Ym2413_Emu.cpp:
--------------------------------------------------------------------------------
 1 | 
 2 | // Use in place of Ym2413_Emu.cpp and ym2413.c to disable support for this chip
 3 | 
 4 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 5 | 
 6 | #include "Ym2413_Emu.h"
 7 | 
 8 | Ym2413_Emu::Ym2413_Emu() { }
 9 | 
10 | Ym2413_Emu::~Ym2413_Emu() { }
11 | 
12 | int Ym2413_Emu::set_rate( double, double ) { return 2; }
13 | 
14 | void Ym2413_Emu::reset() { }
15 | 
16 | void Ym2413_Emu::write( int, int ) { }
17 | 
18 | void Ym2413_Emu::mute_voices( int ) { }
19 | 
20 | void Ym2413_Emu::run( int, sample_t* ) { }
21 | 
22 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Ym2413_Emu.h:
--------------------------------------------------------------------------------
 1 | // YM2413 FM sound chip emulator interface
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef YM2413_EMU_H
 5 | #define YM2413_EMU_H
 6 | 
 7 | class Ym2413_Emu  {
 8 | 	struct OPLL* opll;
 9 | public:
10 | 	Ym2413_Emu();
11 | 	~Ym2413_Emu();
12 | 	
13 | 	// Set output sample rate and chip clock rates, in Hz. Returns non-zero
14 | 	// if error.
15 | 	int set_rate( double sample_rate, double clock_rate );
16 | 	
17 | 	// Reset to power-up state
18 | 	void reset();
19 | 	
20 | 	// Mute voice n if bit n (1 << n) of mask is set
21 | 	enum { channel_count = 14 };
22 | 	void mute_voices( int mask );
23 | 	
24 | 	// Write 'data' to 'addr'
25 | 	void write( int addr, int data );
26 | 	
27 | 	// Run and write pair_count samples to output
28 | 	typedef short sample_t;
29 | 	enum { out_chan_count = 2 }; // stereo
30 | 	void run( int pair_count, sample_t* out );
31 | };
32 | 
33 | #endif
34 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Ym2612_Emu.h:
--------------------------------------------------------------------------------
 1 | // YM2612 FM sound chip emulator interface
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | 
 5 | #include "gme_types.h"
 6 | 
 7 | #ifdef VGM_YM2612_GENS // LGPL v2.1+ license
 8 | #include "Ym2612_GENS.h"
 9 | typedef Ym2612_GENS_Emu Ym2612_Emu;
10 | #endif
11 | 
12 | #ifdef VGM_YM2612_NUKED // LGPL v2.1+ license
13 | #include "Ym2612_Nuked.h"
14 | typedef Ym2612_Nuked_Emu Ym2612_Emu;
15 | #endif
16 | 
17 | #ifdef VGM_YM2612_MAME // GPL v2+ license
18 | #include "Ym2612_MAME.h"
19 | typedef Ym2612_MAME_Emu Ym2612_Emu;
20 | #endif
21 | 
22 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Ym2612_GENS.h:
--------------------------------------------------------------------------------
 1 | // YM2612 FM sound chip emulator interface
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef YM2612_EMU_H
 5 | #define YM2612_EMU_H
 6 | 
 7 | struct Ym2612_GENS_Impl;
 8 | 
 9 | class Ym2612_GENS_Emu  {
10 | 	Ym2612_GENS_Impl* impl;
11 | public:
12 | 	Ym2612_GENS_Emu() { impl = 0; }
13 | 	~Ym2612_GENS_Emu();
14 | 
15 | 	// Set output sample rate and chip clock rates, in Hz. Returns non-zero
16 | 	// if error.
17 | 	const char* set_rate( double sample_rate, double clock_rate );
18 | 
19 | 	// Reset to power-up state
20 | 	void reset();
21 | 
22 | 	// Mute voice n if bit n (1 << n) of mask is set
23 | 	enum { channel_count = 6 };
24 | 	void mute_voices( int mask );
25 | 
26 | 	// Write addr to register 0 then data to register 1
27 | 	void write0( int addr, int data );
28 | 
29 | 	// Write addr to register 2 then data to register 3
30 | 	void write1( int addr, int data );
31 | 
32 | 	// Run and add pair_count samples into current output buffer contents
33 | 	typedef short sample_t;
34 | 	enum { out_chan_count = 2 }; // stereo
35 | 	void run( int pair_count, sample_t* out );
36 | };
37 | 
38 | #endif
39 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Ym2612_MAME.h:
--------------------------------------------------------------------------------
 1 | // YM2612 FM sound chip emulator interface
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef YM2612_EMU_H
 5 | #define YM2612_EMU_H
 6 | 
 7 | typedef void Ym2612_MAME_Impl;
 8 | 
 9 | class Ym2612_MAME_Emu  {
10 | 	Ym2612_MAME_Impl* impl;
11 | public:
12 | 	Ym2612_MAME_Emu();
13 | 	~Ym2612_MAME_Emu();
14 | 
15 | 	// Set output sample rate and chip clock rates, in Hz. Returns non-zero
16 | 	// if error.
17 | 	const char* set_rate( double sample_rate, double clock_rate );
18 | 
19 | 	// Reset to power-up state
20 | 	void reset();
21 | 
22 | 	// Mute voice n if bit n (1 << n) of mask is set
23 | 	enum { channel_count = 6 };
24 | 	void mute_voices( int mask );
25 | 
26 | 	// Write addr to register 0 then data to register 1
27 | 	void write0( int addr, int data );
28 | 
29 | 	// Write addr to register 2 then data to register 3
30 | 	void write1( int addr, int data );
31 | 
32 | 	// Run and add pair_count samples into current output buffer contents
33 | 	typedef short sample_t;
34 | 	enum { out_chan_count = 2 }; // stereo
35 | 	void run( int pair_count, sample_t* out );
36 | };
37 | 
38 | #endif
39 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/Ym2612_Nuked.h:
--------------------------------------------------------------------------------
 1 | // YM2612 FM sound chip emulator interface
 2 | 
 3 | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
 4 | #ifndef YM2612_EMU_H
 5 | #define YM2612_EMU_H
 6 | 
 7 | typedef void Ym2612_Nuked_Impl;
 8 | 
 9 | class Ym2612_Nuked_Emu  {
10 | 	Ym2612_Nuked_Impl* impl;
11 | 	double prev_sample_rate;
12 | 	double prev_clock_rate;
13 | public:
14 | 	Ym2612_Nuked_Emu();
15 | 	~Ym2612_Nuked_Emu();
16 | 
17 | 	// Set output sample rate and chip clock rates, in Hz. Returns non-zero
18 | 	// if error.
19 | 	const char* set_rate( double sample_rate, double clock_rate );
20 | 
21 | 	// Reset to power-up state
22 | 	void reset();
23 | 
24 | 	// Mute voice n if bit n (1 << n) of mask is set
25 | 	enum { channel_count = 6 };
26 | 	void mute_voices( int mask );
27 | 
28 | 	// Write addr to register 0 then data to register 1
29 | 	void write0( int addr, int data );
30 | 
31 | 	// Write addr to register 2 then data to register 3
32 | 	void write1( int addr, int data );
33 | 
34 | 	// Run and add pair_count samples into current output buffer contents
35 | 	typedef short sample_t;
36 | 	enum { out_chan_count = 2 }; // stereo
37 | 	void run( int pair_count, sample_t* out );
38 | };
39 | 
40 | #endif
41 | 
42 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/blargg_config.h:
--------------------------------------------------------------------------------
 1 | // Library configuration. Modify this file as necessary.
 2 | 
 3 | #ifndef BLARGG_CONFIG_H
 4 | #define BLARGG_CONFIG_H
 5 | 
 6 | // Uncomment to use zlib for transparent decompression of gzipped files
 7 | //#define HAVE_ZLIB_H
 8 | 
 9 | // Uncomment and edit list to support only the listed game music types,
10 | // so that the others don't get linked in at all.
11 | /*
12 | #define GME_TYPE_LIST \
13 | 	gme_ay_type,\
14 | 	gme_gbs_type,\
15 | 	gme_gym_type,\
16 | 	gme_hes_type,\
17 | 	gme_kss_type,\
18 | 	gme_nsf_type,\
19 | 	gme_nsfe_type,\
20 | 	gme_sap_type,\
21 | 	gme_spc_type,\
22 | 	gme_vgm_type,\
23 | 	gme_vgz_type
24 | */
25 | 
26 | // Uncomment to enable platform-specific optimizations
27 | //#define BLARGG_NONPORTABLE 1
28 | 
29 | // Uncomment to use faster, lower quality sound synthesis
30 | //#define BLIP_BUFFER_FAST 1
31 | 
32 | // Uncomment if automatic byte-order determination doesn't work
33 | //#define BLARGG_BIG_ENDIAN 1
34 | 
35 | // Uncomment if you get errors in the bool section of blargg_common.h
36 | //#define BLARGG_COMPILER_HAS_BOOL 1
37 | 
38 | // Use standard config.h if present
39 | #ifdef HAVE_CONFIG_H
40 | 	#include "config.h"
41 | #endif
42 | 
43 | #endif
44 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/blargg_source.h:
--------------------------------------------------------------------------------
 1 | /* Included at the beginning of library source files, after all other #include lines.
 2 |  * Sets up helpful macros and services used in my source code. They don't need
 3 |  * module an annoying module prefix on their names since they are defined after
 4 |  * all other #include lines. */
 5 | 
 6 | #ifndef BLARGG_SOURCE_H
 7 | #define BLARGG_SOURCE_H
 8 | 
 9 | /* If debugging is enabled, abort program if expr is false. Meant for checking
10 |  * internal state and consistency. A failed assertion indicates a bug in the module.
11 |  * void assert( bool expr ); */
12 | #include 
13 | 
14 | /* If debugging is enabled and expr is false, abort program. Meant for checking
15 |  * caller-supplied parameters and operations that are outside the control of the
16 |  * module. A failed requirement indicates a bug outside the module.
17 |  * void require( bool expr ); */
18 | #undef require
19 | 
20 | #if DEBUG_BLARGG
21 | #define require( expr ) assert( expr )
22 | #else
23 | #define require( expr ) ( expr )
24 | #undef assert
25 | #define assert( expr ) ( expr )
26 | #endif
27 | 
28 | /* Use to provide hints to compiler for optimized code layout in situations where we
29 |  * can almost always expect a conditional to go one way or the other.  Should only be
30 |  * used in situations where an unexpected branch is truly exceptional though! */
31 | #undef likely
32 | #undef unlikely
33 | #ifdef __GNUC__
34 |     #define likely( x ) __builtin_expect(x, 1)
35 |     #define unlikely( x ) __builtin_expect(x, 0)
36 | #else
37 |     #define likely( x ) (x)
38 |     #define unlikely( x ) (x)
39 | #endif
40 | 
41 | /* Like printf() except output goes to debug log file. Might be defined to do
42 |  * nothing (not even evaluate its arguments).
43 |  * void debug_printf( const char* format, ... ); */
44 | #if defined(__cplusplus) && defined(BLARGG_BUILD_DLL)
45 |     static inline void blargg_dprintf_( const char* fmt_str, ... ) { (void) fmt_str; }
46 |     #undef debug_printf
47 |     #define debug_printf (1) ? (void) 0 : blargg_dprintf_
48 | #else
49 | #define NDEBUG
50 | #endif
51 | 
52 | /* If enabled, evaluate expr and if false, make debug log entry with source file
53 |  * and line. Meant for finding situations that should be examined further, but that
54 |  * don't indicate a problem. In all cases, execution continues normally. */
55 | #undef check
56 | #define check( expr ) ((void) 0)
57 | 
58 | /* If expr yields error string, return it from current function, otherwise continue. */
59 | #undef RETURN_ERR
60 | #define RETURN_ERR( expr ) do {                         \
61 | 		blargg_err_t blargg_return_err_ = (expr);               \
62 | 		if ( blargg_return_err_ ) return blargg_return_err_;    \
63 | 	} while ( 0 )
64 | 
65 | /* If ptr is 0, return out of memory error string. */
66 | #undef CHECK_ALLOC
67 | #define CHECK_ALLOC( ptr ) do { if ( (ptr) == 0 ) return "Out of memory"; } while ( 0 )
68 | 
69 | /* TODO: good idea? bad idea? */
70 | #undef byte
71 | #define byte byte_
72 | typedef unsigned char byte;
73 | 
74 | /* Setup compiler defines useful for exporting required public API symbols in gme.cpp */
75 | #ifndef BLARGG_EXPORT
76 |     #if defined (_WIN32)
77 |         #if defined(BLARGG_BUILD_DLL)
78 |             #define BLARGG_EXPORT __declspec(dllexport)
79 |         #else
80 |             #define BLARGG_EXPORT /* Leave blank: friendly with both static and shared linking */
81 |         #endif
82 |     #elif defined (LIBGME_VISIBILITY) && defined(__cplusplus)
83 |         #define BLARGG_EXPORT __attribute__((visibility ("default")))
84 |     #else
85 |         #define BLARGG_EXPORT
86 |     #endif
87 | #endif
88 | 
89 | /* deprecated */
90 | #define BLARGG_CHECK_ALLOC CHECK_ALLOC
91 | #define BLARGG_RETURN_ERR RETURN_ERR
92 | 
93 | /* BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of debug_printf and check */
94 | #ifdef BLARGG_SOURCE_BEGIN
95 | 	#include BLARGG_SOURCE_BEGIN
96 | #endif
97 | 
98 | #endif
99 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/gb_cpu_io.h:
--------------------------------------------------------------------------------
 1 | 
 2 | #include "Gbs_Emu.h"
 3 | 
 4 | #include "blargg_source.h"
 5 | 
 6 | int Gbs_Emu::cpu_read( gb_addr_t addr )
 7 | {
 8 | 	int result = *cpu::get_code( addr );
 9 | 	if ( unsigned (addr - Gb_Apu::start_addr) < Gb_Apu::register_count )
10 | 		result = apu.read_register( clock(), addr );
11 | #ifndef NDEBUG
12 | 	else if ( unsigned (addr - 0x8000) < 0x2000 || unsigned (addr - 0xE000) < 0x1F00 )
13 | 		debug_printf( "Read from unmapped memory $%.4x\n", (unsigned) addr );
14 | 	else if ( unsigned (addr - 0xFF01) < 0xFF80 - 0xFF01 )
15 | 		debug_printf( "Unhandled I/O read 0x%4X\n", (unsigned) addr );
16 | #endif
17 | 	return result;
18 | }
19 | 
20 | void Gbs_Emu::cpu_write( gb_addr_t addr, int data )
21 | {
22 | 	unsigned offset = addr - ram_addr;
23 | 	if ( offset <= 0xFFFF - ram_addr )
24 | 	{
25 | 		ram [offset] = data;
26 | 		if ( (addr ^ 0xE000) <= 0x1F80 - 1 )
27 | 		{
28 | 			if ( unsigned (addr - Gb_Apu::start_addr) < Gb_Apu::register_count )
29 | 			{
30 | 				GME_APU_HOOK( this, addr - Gb_Apu::start_addr, data );
31 | 				apu.write_register( clock(), addr, data );
32 | 			}
33 | 			else if ( (addr ^ 0xFF06) < 2 )
34 | 				update_timer();
35 | 			else if ( addr == joypad_addr )
36 | 				ram [offset] = 0; // keep joypad return value 0
37 | 			else
38 | 				ram [offset] = 0xFF;
39 | 
40 | 			//if ( addr == 0xFFFF )
41 | 			//  debug_printf( "Wrote interrupt mask\n" );
42 | 		}
43 | 	}
44 | 	else if ( (addr ^ 0x2000) <= 0x2000 - 1 )
45 | 	{
46 | 		set_bank( data );
47 | 	}
48 | #ifndef NDEBUG
49 | 	else if ( unsigned (addr - 0x8000) < 0x2000 || unsigned (addr - 0xE000) < 0x1F00 )
50 | 	{
51 | 		debug_printf( "Wrote to unmapped memory $%.4x\n", (unsigned) addr );
52 | 	}
53 | #endif
54 | }
55 | 
56 | #define CPU_READ_FAST( cpu, addr, time, out ) \
57 | 	CPU_READ_FAST_( STATIC_CAST(Gbs_Emu*,cpu), addr, time, out )
58 | 
59 | #define CPU_READ_FAST_( emu, addr, time, out ) \
60 | {\
61 | 	out = READ_PROG( addr );\
62 | 	if ( unsigned (addr - Gb_Apu::start_addr) < Gb_Apu::register_count )\
63 | 		out = emu->apu.read_register( emu->cpu_time - time * clocks_per_instr, addr );\
64 | 	else\
65 | 		check( out == emu->cpu_read( addr ) );\
66 | }
67 | 
68 | #define CPU_READ( cpu, addr, time ) \
69 | 	STATIC_CAST(Gbs_Emu*,cpu)->cpu_read( addr )
70 | 
71 | #define CPU_WRITE( cpu, addr, data, time ) \
72 | 	STATIC_CAST(Gbs_Emu*,cpu)->cpu_write( addr, data )
73 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/gme_types.h:
--------------------------------------------------------------------------------
 1 | #ifndef GME_TYPES_H
 2 | #define GME_TYPES_H
 3 | 
 4 | /*
 5 |  * This is a default gme_types.h for use when *not* using
 6 |  * CMake.  If CMake is in use gme_types.h.in will be
 7 |  * processed instead.
 8 |  */
 9 | #define USE_GME_AY
10 | #define USE_GME_GBS
11 | #define USE_GME_GYM
12 | #define USE_GME_HES
13 | #define USE_GME_KSS
14 | #define USE_GME_NSF
15 | #define USE_GME_NSFE
16 | #define USE_GME_SAP
17 | #define USE_GME_SPC
18 | /* VGM and VGZ are a package deal */
19 | #define USE_GME_VGM
20 | #define VGM_YM2612_GENS
21 | 
22 | #endif /* GME_TYPES_H */
23 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/hes_cpu_io.h:
--------------------------------------------------------------------------------
  1 | 
  2 | #include "Hes_Emu.h"
  3 | 
  4 | #include "blargg_source.h"
  5 | 
  6 | int Hes_Emu::cpu_read( hes_addr_t addr )
  7 | {
  8 | 	check( addr <= 0xFFFF );
  9 | 	int result = *cpu::get_code( addr );
 10 | 	if ( mmr [addr >> page_shift] == 0xFF )
 11 | 		result = cpu_read_( addr );
 12 | 	return result;
 13 | }
 14 | 
 15 | void Hes_Emu::cpu_write( hes_addr_t addr, int data )
 16 | {
 17 | 	check( addr <= 0xFFFF );
 18 | 	byte* out = write_pages [addr >> page_shift];
 19 | 	addr &= page_size - 1;
 20 | 	if ( out )
 21 | 		out [addr] = data;
 22 | 	else if ( mmr [addr >> page_shift] == 0xFF )
 23 | 		cpu_write_( addr, data );
 24 | }
 25 | 
 26 | inline byte const* Hes_Emu::cpu_set_mmr( int page, int bank )
 27 | {
 28 | 	write_pages [page] = 0;
 29 | 	if ( bank < 0x80 )
 30 | 		return rom.at_addr( bank * (blargg_long) page_size );
 31 | 	
 32 | 	byte* data = 0;
 33 | 	switch ( bank )
 34 | 	{
 35 | 		case 0xF8:
 36 | 			data = cpu::ram;
 37 | 			break;
 38 | 		
 39 | 		case 0xF9:
 40 | 		case 0xFA:
 41 | 		case 0xFB:
 42 | 			data = &sgx [(bank - 0xF9) * page_size];
 43 | 			break;
 44 | 		
 45 | 		default:
 46 | #ifndef NDEBUG
 47 | 			if ( bank != 0xFF )
 48 | 				debug_printf( "Unmapped bank $%02X\n", bank );
 49 | #endif
 50 | 			return rom.unmapped();
 51 | 	}
 52 | 	
 53 | 	write_pages [page] = data;
 54 | 	return data;
 55 | }
 56 | 
 57 | #define CPU_READ_FAST( cpu, addr, time, out ) \
 58 | 	CPU_READ_FAST_( STATIC_CAST(Hes_Emu*,cpu), addr, time, out )
 59 | 
 60 | #define CPU_READ_FAST_( cpu, addr, time, out ) \
 61 | {\
 62 | 	out = READ_PROG( addr );\
 63 | 	if ( mmr [addr >> page_shift] == 0xFF )\
 64 | 	{\
 65 | 		FLUSH_TIME();\
 66 | 		out = cpu->cpu_read_( addr );\
 67 | 		CACHE_TIME();\
 68 | 	}\
 69 | }
 70 | 
 71 | #define CPU_WRITE_FAST( cpu, addr, data, time ) \
 72 | 	CPU_WRITE_FAST_( STATIC_CAST(Hes_Emu*,cpu), addr, data, time )
 73 | 
 74 | #define CPU_WRITE_FAST_( cpu, addr, data, time ) \
 75 | {\
 76 | 	byte* out = cpu->write_pages [addr >> page_shift];\
 77 | 	addr &= page_size - 1;\
 78 | 	if ( out )\
 79 | 	{\
 80 | 		out [addr] = data;\
 81 | 	}\
 82 | 	else if ( mmr [addr >> page_shift] == 0xFF )\
 83 | 	{\
 84 | 		FLUSH_TIME();\
 85 | 		cpu->cpu_write_( addr, data );\
 86 | 		CACHE_TIME();\
 87 | 	}\
 88 | }
 89 | 
 90 | #define CPU_READ( cpu, addr, time ) \
 91 | 	STATIC_CAST(Hes_Emu*,cpu)->cpu_read( addr )
 92 | 
 93 | #define CPU_WRITE( cpu, addr, data, time ) \
 94 | 	STATIC_CAST(Hes_Emu*,cpu)->cpu_write( addr, data )
 95 | 
 96 | #define CPU_WRITE_VDP( cpu, addr, data, time ) \
 97 | 	STATIC_CAST(Hes_Emu*,cpu)->cpu_write_vdp( addr, data )
 98 | 
 99 | #define CPU_SET_MMR( cpu, page, bank ) \
100 | 	STATIC_CAST(Hes_Emu*,cpu)->cpu_set_mmr( page, bank )
101 | 
102 | #define CPU_DONE( cpu, time, result_out ) \
103 | 	result_out = STATIC_CAST(Hes_Emu*,cpu)->cpu_done()
104 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/nes_cpu_io.h:
--------------------------------------------------------------------------------
 1 | 
 2 | #include "Nsf_Emu.h"
 3 | 
 4 | #if !NSF_EMU_APU_ONLY
 5 | 	#include "Nes_Namco_Apu.h"
 6 | #endif
 7 | 
 8 | #include "blargg_source.h"
 9 | 
10 | int Nsf_Emu::cpu_read( nes_addr_t addr )
11 | {
12 | 	int result;
13 | 	
14 | 	result = cpu::low_mem [addr & 0x7FF];
15 | 	if ( !(addr & 0xE000) )
16 | 		goto exit;
17 | 	
18 | 	result = *cpu::get_code( addr );
19 | 	if ( addr > 0x7FFF )
20 | 		goto exit;
21 | 	
22 | 	result = sram [addr & (sizeof sram - 1)];
23 | 	if ( addr > 0x5FFF )
24 | 		goto exit;
25 | 	
26 | 	if ( addr == Nes_Apu::status_addr )
27 | 		return apu.read_status( cpu::time() );
28 | 	
29 | 	#if !NSF_EMU_APU_ONLY
30 | 		if ( addr == Nes_Namco_Apu::data_reg_addr && namco )
31 | 			return namco->read_data();
32 | 	#endif
33 | 	
34 | 	result = addr >> 8; // simulate open bus
35 | 	
36 | #ifndef NDEBUG
37 | 	if ( addr != 0x2002 )
38 | 		debug_printf( "Read unmapped $%.4X\n", (unsigned) addr );
39 | #endif
40 | 	
41 | exit:
42 | 	return result;
43 | }
44 | 
45 | void Nsf_Emu::cpu_write( nes_addr_t addr, int data )
46 | {
47 | 	{
48 | 		nes_addr_t offset = addr ^ sram_addr;
49 | 		if ( offset < sizeof sram )
50 | 		{
51 | 			sram [offset] = data;
52 | 			return;
53 | 		}
54 | 	}
55 | 	{
56 | 		int temp = addr & 0x7FF;
57 | 		if ( !(addr & 0xE000) )
58 | 		{
59 | 			cpu::low_mem [temp] = data;
60 | 			return;
61 | 		}
62 | 	}
63 | 	
64 | 	if ( unsigned (addr - Nes_Apu::start_addr) <= Nes_Apu::end_addr - Nes_Apu::start_addr )
65 | 	{
66 | 		GME_APU_HOOK( this, addr - Nes_Apu::start_addr, data );
67 | 		apu.write_register( cpu::time(), addr, data );
68 | 		return;
69 | 	}
70 | 	
71 | 	unsigned bank = addr - bank_select_addr;
72 | 	if ( bank < bank_count )
73 | 	{
74 | 		blargg_long offset = rom.mask_addr( data * (blargg_long) bank_size );
75 | 		if ( offset >= rom.size() )
76 | 			set_warning( "Invalid bank" );
77 | 		cpu::map_code( (bank + 8) * bank_size, bank_size, rom.at_addr( offset ) );
78 | 		return;
79 | 	}
80 | 	
81 | 	cpu_write_misc( addr, data );
82 | }
83 | 
84 | #define CPU_READ( cpu, addr, time )         STATIC_CAST(Nsf_Emu&,*cpu).cpu_read( addr )
85 | #define CPU_WRITE( cpu, addr, data, time )  STATIC_CAST(Nsf_Emu&,*cpu).cpu_write( addr, data )
86 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Engine/gme/sap_cpu_io.h:
--------------------------------------------------------------------------------
 1 | 
 2 | #include "Sap_Emu.h"
 3 | 
 4 | #include "blargg_source.h"
 5 | 
 6 | #define CPU_WRITE( cpu, addr, data, time )  STATIC_CAST(Sap_Emu&,*cpu).cpu_write( addr, data )
 7 | 
 8 | void Sap_Emu::cpu_write( sap_addr_t addr, int data )
 9 | {
10 | 	mem.ram [addr] = data;
11 | 	if ( (addr >> 8) == 0xD2 )
12 | 		cpu_write_( addr, data );
13 | }
14 | 
15 | #ifdef NDEBUG
16 | 	#define CPU_READ( cpu, addr, time )     READ_LOW( addr )
17 | #else
18 | 	#define CPU_READ( cpu, addr, time )     STATIC_CAST(Sap_Emu&,*cpu).cpu_read( addr )
19 | 	
20 | 	int Sap_Emu::cpu_read( sap_addr_t addr )
21 | 	{
22 | 		if ( (addr & 0xF900) == 0xD000 )
23 | 			debug_printf( "Unmapped read $%04X\n", addr );
24 | 		return mem.ram [addr];
25 | 	}
26 | #endif
27 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/FilePicker.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  FilePicker.swift
 3 | //  Square Wave
 4 | //
 5 | //  Created by Alex Busman on 2/13/20.
 6 | //  Copyright © 2020 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | import SwiftUI
10 | import MobileCoreServices
11 | 
12 | struct FilePicker: UIViewControllerRepresentable {
13 |     @Environment(\.presentationMode) var presentationMode
14 |     
15 |     func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIDocumentPickerViewController {
16 |         let sevenZipUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, "7z" as CFString, nil)?.takeRetainedValue() as String? ?? ""
17 |         let rarUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, "rar" as CFString, nil)?.takeRetainedValue() as String? ?? ""
18 |         let documentTypes: [String] = [kUTTypeZipArchive as String, "com.abusman.nsf", "com.abusman.ay", "com.abusman.gbs", "com.abusman.gym", "com.abusman.hes", "com.abusman.kss", "com.abusman.sap", "com.abusman.spc", "com.abusman.vgm", sevenZipUTI, rarUTI]
19 | 
20 |         let picker = UIDocumentPickerViewController(documentTypes: documentTypes, in: .import)
21 |         picker.allowsMultipleSelection = true
22 |         picker.delegate = context.coordinator
23 |         return picker
24 |     }
25 |     
26 |     func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext) {
27 |         
28 |     }
29 |     
30 |     func makeCoordinator() -> Coordinator {
31 |         Coordinator(self)
32 |     }
33 |     
34 |     class Coordinator: NSObject, UINavigationControllerDelegate, UIDocumentPickerDelegate {
35 |         var parent: FilePicker
36 |         
37 |         init(_ parent: FilePicker) {
38 |             self.parent = parent
39 |         }
40 |         
41 |         func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
42 |             for file in urls {
43 |                 if FileManager.default.fileExists(atPath: file.path) {
44 |                     FileEngine.addFile(file, removeOriginal: true)
45 |                 }
46 |             }
47 |         }
48 |     }
49 | }
50 | 
51 | 
52 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/GamesView.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  GamesView.swift
 3 | //  Square Wave
 4 | //
 5 | //  Created by Alex Busman on 2/13/20.
 6 | //  Copyright © 2020 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | import SwiftUI
10 | import CoreData
11 | 
12 | struct GamesView: View {
13 |     @FetchRequest(entity: Game.entity(), sortDescriptors: []) var games: FetchedResults
14 | 
15 |     var body: some View {
16 |         UIListView(rows: Binding(get: {
17 |             Array(self.games)
18 |         }, set: { _ in
19 |             
20 |         }),
21 |         sortType: Binding(get: {
22 |             SortType.title.rawValue
23 |         }, set: { _ in
24 |             
25 |         }), isEditing: .constant(false), rowType: Game.self, keypaths: UIListViewCellKeypaths(art: \Game.system?.name, title: \Game.name, desc: \Game.system?.name), showSearch: false, showsHeader: false)
26 |             .navigationBarTitle(Text(NSLocalizedString("Games", comment: "Games")), displayMode: .inline)
27 |         .edgesIgnoringSafeArea(.vertical)
28 |     }
29 | }
30 | 
31 | struct GamesView_Previews: PreviewProvider {
32 |     static var previews: some View {
33 |         GamesView()
34 |     }
35 | }
36 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/GoogleService-Info.plist:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 | 
 5 | 	CLIENT_ID
 6 | 	568783072531-eha6nct4vmihcu8o0jq666ckgje1ffsd.apps.googleusercontent.com
 7 | 	REVERSED_CLIENT_ID
 8 | 	com.googleusercontent.apps.568783072531-eha6nct4vmihcu8o0jq666ckgje1ffsd
 9 | 	API_KEY
10 | 	AIzaSyDdNArgKF6i354aaIm64wU_cH7GGAKeU_k
11 | 	GCM_SENDER_ID
12 | 	568783072531
13 | 	PLIST_VERSION
14 | 	1
15 | 	BUNDLE_ID
16 | 	com.abusman.Square-Wave
17 | 	PROJECT_ID
18 | 	square-wave-e799a
19 | 	STORAGE_BUCKET
20 | 	square-wave-e799a.appspot.com
21 | 	IS_ADS_ENABLED
22 | 	
23 | 	IS_ANALYTICS_ENABLED
24 | 	
25 | 	IS_APPINVITE_ENABLED
26 | 	
27 | 	IS_GCM_ENABLED
28 | 	
29 | 	IS_SIGNIN_ENABLED
30 | 	
31 | 	GOOGLE_APP_ID
32 | 	1:568783072531:ios:b8f47bf6684a1d0a2bbee6
33 | 	DATABASE_URL
34 | 	https://square-wave-e799a.firebaseio.com
35 | 
36 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/IAP_ProductIDs.plist:
--------------------------------------------------------------------------------
1 | 
2 | 
3 | 
4 | 
5 | 	com.abusman.square_waves.premium
6 | 
7 | 
8 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/LibraryView.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LibraryView.swift
 3 | //  Square Wave
 4 | //
 5 | //  Created by Alex Busman on 2/13/20.
 6 | //  Copyright © 2020 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | import SwiftUI
10 | 
11 | struct LibraryView: View {
12 |     @Environment(\.managedObjectContext) var context
13 |     @EnvironmentObject var playbackState: PlaybackState
14 |     @State var hasTracks: Bool = false
15 |     @State var isShowingPicker: Bool = false
16 |     static var miniViewPosition: CGFloat = 75.0
17 | 
18 |     var body: some View {
19 |         Group {
20 |             if self.hasTracks {
21 |                 List {
22 |                     NavigationLink(destination: PlaylistsView().environment(\.managedObjectContext, context).environmentObject(playbackState)) {
23 |                         Text(NSLocalizedString("Playlists", comment: "Playlists"))
24 |                     }
25 |                     NavigationLink(destination: PlatformsView().environment(\.managedObjectContext, context)) {
26 |                         Text(NSLocalizedString("Platforms", comment: "Platforms"))
27 |                     }
28 |                     NavigationLink(destination: ArtistsView().environment(\.managedObjectContext, context)) {
29 |                         Text(NSLocalizedString("Artists", comment: "Artists"))
30 |                     }
31 |                     NavigationLink(destination: GamesView().environment(\.managedObjectContext, context)) {
32 |                         Text(NSLocalizedString("Games", comment: "Games"))
33 |                     }
34 |                     NavigationLink(destination: SongsView(predicate: nil).environment(\.managedObjectContext, context).environmentObject(playbackState)) {
35 |                         Text(NSLocalizedString("Songs", comment: "Songs"))
36 |                     }
37 |                 }
38 |                 .navigationBarTitle(Text(NSLocalizedString("Library", comment: "Library")))
39 |             } else {
40 |                 VStack {
41 |                     Spacer()
42 |                     Button(action: {
43 |                         self.isShowingPicker.toggle()
44 |                     }) {
45 |                     Image(systemName: "plus")
46 |                         .resizable()
47 |                         .aspectRatio(contentMode: .fit)
48 |                         .padding(Edge.Set(arrayLiteral: [.horizontal, .top]), 100)
49 |                     }
50 |                     Text(NSLocalizedString("Add Files", comment: "Add Files")).multilineTextAlignment(.center)
51 |                     .lineLimit(6)
52 |                     .padding()
53 |                         .padding(.bottom, 50)
54 |                     Spacer()
55 |                 }
56 |                 .foregroundColor(Color(.tertiaryLabel))
57 |                 .navigationBarTitle(Text(NSLocalizedString("Library", comment: "Library")))
58 |                 .sheet(isPresented: self.$isShowingPicker) {
59 |                     FilePicker()
60 |                 }
61 |             }
62 |         }.onAppear {
63 |             self.hasTracks = self.playbackState.hasTracks
64 |         }
65 |         .onReceive(self.playbackState.$hasTracks) { value in
66 |             self.hasTracks = value
67 |         }
68 |     }
69 | }
70 | 
71 | /*
72 | struct LibraryView_Previews: PreviewProvider {
73 |     static let playbackState = PlaybackState()
74 |     static var previews: some View {
75 |         LibraryView().environmentObject(playbackState)
76 |     }
77 | }
78 | */
79 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/ListSectionIndexView.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  ListSectionIndexView.swift
 3 | //  
 4 | //
 5 | //  Created by Alex Busman on 2/26/20.
 6 | //
 7 | 
 8 | import SwiftUI
 9 | 
10 | struct ListSectionIndexView: View {
11 |     @Binding var index: Int
12 |     
13 |     var indices: [Character]
14 |     
15 |     var body: some View {
16 |         VStack {
17 |             ForEach(indicies, id: \.self) { index in
18 |                 Text(index)
19 |             }
20 |         }.background(Rectangle())
21 |     }
22 | }
23 | 
24 | struct ListSectionIndexView_Previews: PreviewProvider {
25 |     static var previews: some View {
26 |         ListSectionIndexView(index: .constant(0))
27 |     }
28 | }
29 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Main.storyboard:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 |     
 4 |     
 5 |         
 6 |         
 7 |         
 8 |         
 9 |     
10 |     
11 |         
12 |         
13 |             
14 |                 
15 |                     
16 |                         
17 |                         
18 |                         
19 |                         
20 |                     
21 |                 
22 |                 
23 |             
24 |             
25 |         
26 |     
27 |     
28 |         
29 |             
30 |         
31 |     
32 | 
33 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/NewPlaylistView.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  NewPlaylistView.swift
 3 | //  Square Wave
 4 | //
 5 | //  Created by Alex Busman on 3/1/20.
 6 | //  Copyright © 2020 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | import SwiftUI
10 | 
11 | struct NewPlaylistView: View {
12 |     @Environment(\.presentationMode) var presentationMode: Binding
13 |     @State var playlist: Playlist?
14 |     @ObservedObject var playlistModel = PlaylistModel()
15 |     var body: some View {
16 |         NavigationView {
17 |             PlaylistView(isNewPlaylist: true, playlistModel: self.playlistModel)
18 |                 .navigationBarTitle(Text(NSLocalizedString("New Playlist", comment: "New Playlist")), displayMode: .inline)
19 |                 .navigationBarItems(leading: Button(action: {
20 |                     self.presentationMode.wrappedValue.dismiss()
21 |                 }) {
22 |                     Text(NSLocalizedString("Cancel", comment: "Cancel"))
23 |                 }, trailing: Button(action: {
24 |                     let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
25 |                     let playlist = Playlist(entity: Playlist.entity(), insertInto: context)
26 |                     
27 |                     playlist.id = UUID()
28 |                     playlist.name = self.playlistModel.titleText
29 |                     playlist.tracks = NSOrderedSet(array: self.playlistModel.tracks)
30 |                     playlist.dateAdded = Date()
31 |                     let image = self.playlistModel.image
32 |                     self.savePlaylistImage(playlist, image: image)
33 |                     
34 |                     self.presentationMode.wrappedValue.dismiss()
35 |                 }) {
36 |                     Text(NSLocalizedString("Done", comment: "Done"))
37 |                     .bold()
38 |                 })
39 |         }
40 |     }
41 |     
42 |     func savePlaylistImage(_ playlist: Playlist, image: UIImage?) {
43 |         if let filename = Util.getPlaylistImagesDirectory()?.appendingPathComponent("\(playlist.id!).png") {
44 |             let url = URL(fileURLWithPath: "\(playlist.id!).png")
45 |             let delegate = UIApplication.shared.delegate as! AppDelegate
46 |             if image != nil {
47 |                 let data = image!.pngData()
48 |                 do {
49 |                     try data?.write(to: filename)
50 |                     playlist.art = url
51 |                     delegate.saveContext()
52 |                 } catch {
53 |                     NSLog("Failed to write image data to \(filename.path)")
54 |                 }
55 |             } else {
56 |                 do {
57 |                     try FileManager.default.removeItem(at: filename)
58 |                     playlist.art = nil
59 |                     delegate.saveContext()
60 |                 } catch {
61 |                     NSLog("Failed to remove \(filename.path)")
62 |                 }
63 |             }
64 |         }
65 |     }
66 | }
67 | 
68 | /*
69 | struct NewPlaylistView_Previews: PreviewProvider {
70 |     static var previews: some View {
71 |         NewPlaylistView()
72 |     }
73 | }
74 | */
75 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/NowPlayingMiniView.swift:
--------------------------------------------------------------------------------
  1 | //
  2 | //  NowPlayingMiniView.swift
  3 | //  Square Wave
  4 | //
  5 | //  Created by Alex Busman on 2/14/20.
  6 | //  Copyright © 2020 Alex Busman. All rights reserved.
  7 | //
  8 | 
  9 | import SwiftUI
 10 | import Combine
 11 | 
 12 | class NowPlayingMiniViewDelegate: ObservableObject {
 13 |     var willChange = PassthroughSubject()
 14 |     var didChange  = PassthroughSubject()
 15 |     
 16 |     var didTap: Bool = false {
 17 |         willSet {
 18 |             willChange.send(self)
 19 |         }
 20 |         
 21 |         didSet {
 22 |             didChange.send(self)
 23 |         }
 24 |     }
 25 | }
 26 | 
 27 | struct NowPlayingMiniView: View {
 28 |     @State var playButtonImage = "play.fill"
 29 |     @EnvironmentObject var playbackState: PlaybackState
 30 |     
 31 |     @ObservedObject var delegate: NowPlayingMiniViewDelegate
 32 |     let impactGenerator = UIImpactFeedbackGenerator()
 33 |     var swipe: some Gesture {
 34 |         DragGesture()
 35 |             .onChanged({ value in
 36 |                 if value.predictedEndLocation.y < -20.0 {
 37 |                     self.delegate.didTap = true
 38 |                 }
 39 |             })
 40 |     }
 41 | 
 42 |     var body: some View {
 43 |         VStack {
 44 |             Divider()
 45 |                 .offset(y: 12)
 46 |             HStack {
 47 |                 Image(uiImage: ListArtView.getImage(for: self.playbackState.nowPlayingTrack?.system?.name ?? "") ?? UIImage(named: "placeholder-art")!)
 48 |                     .resizable()
 49 |                     .aspectRatio(contentMode: .fit)
 50 |                     .frame(height: 50.0)
 51 |                     .cornerRadius(6.0)
 52 |                     .overlay(RoundedRectangle(cornerRadius: 6.0).stroke(Color(.systemGray4), lineWidth: 0.5))
 53 |                     .shadow(radius: 5.0)
 54 |                     .padding()
 55 |                 VStack(alignment: .leading) {
 56 |                     Text(self.playbackState.nowPlayingTrack?.name ?? NSLocalizedString("Not Playing", comment: "Not Playing"))
 57 |                         .foregroundColor(Color(.label))
 58 |                         .lineLimit(1)
 59 |                     if (self.playbackState.nowPlayingTrack?.game?.name?.count ?? 0) > 0 {
 60 |                         Text(self.playbackState.nowPlayingTrack?.game?.name ?? "")
 61 |                             .foregroundColor(Color(.secondaryLabel))
 62 |                         .lineLimit(1)
 63 |                     }
 64 |                 }
 65 |                 Spacer()
 66 |                 Button(action: {
 67 |                     self.impactGenerator.impactOccurred(intensity: 1.0)
 68 |                     if !self.playbackState.isNowPlaying {
 69 |                         self.playbackState.play()
 70 |                     } else {
 71 |                         self.playbackState.pause()
 72 |                     }
 73 |                 }) {
 74 |                     Image(systemName: self.playbackState.isNowPlaying ? "pause.fill" : "play.fill")
 75 |                     .resizable()
 76 |                         .aspectRatio(contentMode: .fit)
 77 |                         .frame(height: 25.0)
 78 |                 }.foregroundColor(Color(.label))
 79 |                 Button(action: {
 80 |                     self.impactGenerator.impactOccurred(intensity: 0.5)
 81 |                     self.playbackState.nextTrack()
 82 |                 }) {
 83 |                     Image(systemName: "forward.end.fill")
 84 |                     .resizable()
 85 |                         .aspectRatio(contentMode: .fit)
 86 |                         .frame(height: 20.0)
 87 |                     .padding()
 88 |                 }.foregroundColor(Color(.label))
 89 |             }
 90 |             Spacer()
 91 |             }.contentShape(Rectangle())
 92 |         .onTapGesture {
 93 |             self.delegate.didTap = true
 94 |         }.gesture(self.swipe)
 95 |         .onAppear {
 96 |             self.impactGenerator.prepare()
 97 |         }
 98 |     }
 99 | }
100 | 
101 | struct NowPlayingMiniView_Previews: PreviewProvider {
102 |     static var previews: some View {
103 |         NowPlayingMiniView(delegate: NowPlayingMiniViewDelegate())
104 |             .frame(width: UIScreen.main.bounds.width, height: 75.0)
105 |     }
106 | }
107 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/PlatformsView.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  PlatformsView.swift
 3 | //  Square Wave
 4 | //
 5 | //  Created by Alex Busman on 2/13/20.
 6 | //  Copyright © 2020 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | import SwiftUI
10 | import CoreData
11 | 
12 | struct PlatformsView: View {
13 |     @FetchRequest(entity: System.entity(), sortDescriptors: []) var platforms: FetchedResults
14 |     var body: some View {
15 |         UIListView(rows: Binding(get: {
16 |             Array(self.platforms)
17 |         }, set: { _ in
18 |             
19 |         }),
20 |         sortType: Binding(get: {
21 |             SortType.title.rawValue
22 |         }, set: { _ in
23 |             
24 |         }), isEditing: .constant(false), rowType: System.self, keypaths: UIListViewCellKeypaths(art: \System.name, title: \System.name, desc: nil), showSections: false)
25 |             .navigationBarTitle(Text(NSLocalizedString("Platforms", comment: "Platforms")))
26 |             .edgesIgnoringSafeArea(.vertical)
27 |     }
28 | }
29 | 
30 | struct PlatformsView_Previews: PreviewProvider {
31 |     static var previews: some View {
32 |         PlatformsView()
33 |     }
34 | }
35 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 |   "info" : {
3 |     "version" : 1,
4 |     "author" : "xcode"
5 |   }
6 | }
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Receipts/AppleIncRootCertificate.cer:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/Receipts/AppleIncRootCertificate.cer
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Receipts/ReceiptFetcher.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  ReceiptFetcher.swift
 3 | //  Square Waves
 4 | //
 5 | //  Created by Alex Busman on 3/20/20.
 6 | //  Copyright © 2020 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | import StoreKit
10 | 
11 | class ReceiptFetcher: NSObject, SKRequestDelegate {
12 |     let receiptRefreshRequest = SKReceiptRefreshRequest()
13 |     
14 |     override init() {
15 |         super.init()
16 |         
17 |         self.receiptRefreshRequest.delegate = self
18 |     }
19 |     
20 |     func fetchReceipt() {
21 |         guard let receiptUrl = Bundle.main.appStoreReceiptURL else {
22 |             NSLog("Unable to retrieve receipt URL")
23 |             return
24 |         }
25 |         
26 |         do {
27 |             let reachable = try receiptUrl.checkResourceIsReachable()
28 |             
29 |             if !reachable {
30 |                 self.receiptRefreshRequest.start()
31 |             }
32 |         } catch {
33 |             NSLog("Could not check if resource was reachable: \(error.localizedDescription)")
34 |             self.receiptRefreshRequest.start()
35 |         }
36 |     }
37 |     
38 |     func requestDidFinish(_ request: SKRequest) {
39 |         NSLog("Request finished successfully")
40 |     }
41 |     
42 |     func request(_ request: SKRequest, didFailWithError error: Error) {
43 |         NSLog("Request failed with error \(error.localizedDescription)")
44 |     }
45 | }
46 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Receipts/pkcs7_union_accessors.c:
--------------------------------------------------------------------------------
 1 | //
 2 | //  pkcs7_union_accessors.c
 3 | //  SwiftyReceiptValidatorDemo
 4 | //
 5 | //  Created by Andrew Bancroft on 10/26/17.
 6 | //  Copyright © 2017 Andrew Bancroft. All rights reserved.
 7 | //
 8 | 
 9 | #include "pkcs7_union_accessors.h"
10 | 
11 | inline char *pkcs7_d_char(PKCS7 *ptr) {
12 |     return ptr->d.ptr;
13 | }
14 | 
15 | inline ASN1_OCTET_STRING *pkcs7_d_data(PKCS7 *ptr) {
16 |     return ptr->d.data;
17 | }
18 | 
19 | inline PKCS7_SIGNED *pkcs7_d_sign(PKCS7 *ptr) {
20 |     return ptr->d.sign;
21 | }
22 | 
23 | inline PKCS7_ENVELOPE *pkcs7_d_enveloped(PKCS7 *ptr) {
24 |     return ptr->d.enveloped;
25 | }
26 | 
27 | inline PKCS7_SIGN_ENVELOPE *pkcs7_d_signed_and_enveloped(PKCS7 *ptr) {
28 |     return ptr->d.signed_and_enveloped;
29 | }
30 | 
31 | inline PKCS7_DIGEST *pkcs7_d_digest(PKCS7 *ptr) {
32 |     return ptr->d.digest;
33 | }
34 | 
35 | inline PKCS7_ENCRYPT *pkcs7_d_encrypted(PKCS7 *ptr) {
36 |     return ptr->d.encrypted;
37 | }
38 | 
39 | inline ASN1_TYPE *pkcs7_d_other(PKCS7 *ptr) {
40 |     return ptr->d.other;
41 | }
42 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Receipts/pkcs7_union_accessors.h:
--------------------------------------------------------------------------------
 1 | #ifndef pkcs7_union_accessors_h
 2 | #define pkcs7_union_accessors_h
 3 | 
 4 | #include 
 5 | 
 6 | char *pkcs7_d_char(PKCS7 *ptr);
 7 | ASN1_OCTET_STRING *pkcs7_d_data(PKCS7 *ptr);
 8 | PKCS7_SIGNED *pkcs7_d_sign(PKCS7 *ptr);
 9 | PKCS7_ENVELOPE *pkcs7_d_enveloped(PKCS7 *ptr);
10 | PKCS7_SIGN_ENVELOPE *pkcs7_d_signed_and_enveloped(PKCS7 *ptr);
11 | PKCS7_DIGEST *pkcs7_d_digest(PKCS7 *ptr);
12 | PKCS7_ENCRYPT *pkcs7_d_encrypted(PKCS7 *ptr);
13 | ASN1_TYPE *pkcs7_d_other(PKCS7 *ptr);
14 | 
15 | #endif /* pkcs7_union_accessors_h */
16 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/SceneDelegate.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  SceneDelegate.swift
 3 | //  Square Wave
 4 | //
 5 | //  Created by Alex Busman on 2/10/20.
 6 | //  Copyright © 2020 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | import SwiftUI
11 | import AVKit
12 | 
13 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
14 | 
15 |     var window: UIWindow?
16 | 
17 |     func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
18 |         // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 |         // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 |         // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 |         guard let _ = (scene as? UIWindowScene) else { return }
22 |     }
23 |     
24 |     func scene(_ scene: UIScene, openURLContexts URLContexts: Set) {
25 |         for urlContext in URLContexts {
26 |             FileEngine.addFile(urlContext.url, removeOriginal: true)
27 |         }
28 |     }
29 | 
30 |     func sceneDidDisconnect(_ scene: UIScene) {
31 |         // Called as the scene is being released by the system.
32 |         // This occurs shortly after the scene enters the background, or when its session is discarded.
33 |         // Release any resources associated with this scene that can be re-created the next time the scene connects.
34 |         // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
35 |     }
36 | 
37 |     func sceneDidBecomeActive(_ scene: UIScene) {
38 |         // Called when the scene has moved from an inactive state to an active state.
39 |         // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
40 |         do {
41 |             try AVAudioSession.sharedInstance().setCategory(.playback)
42 |         } catch {
43 |             NSLog("\(error.localizedDescription)")
44 |         }
45 |     }
46 | 
47 |     func sceneWillResignActive(_ scene: UIScene) {
48 |         // Called when the scene will move from an active state to an inactive state.
49 |         // This may occur due to temporary interruptions (ex. an incoming phone call).
50 |     }
51 | 
52 |     func sceneWillEnterForeground(_ scene: UIScene) {
53 |         // Called as the scene transitions from the background to the foreground.
54 |         // Use this method to undo the changes made on entering the background.
55 |     }
56 | 
57 |     func sceneDidEnterBackground(_ scene: UIScene) {
58 |         // Called as the scene transitions from the foreground to the background.
59 |         // Use this method to save data, release shared resources, and store enough scene-specific state information
60 |         // to restore the scene back to its current state.
61 | 
62 |         // Save changes in the application's managed object context when the application transitions to the background.
63 |         (UIApplication.shared.delegate as? AppDelegate)?.saveContext()
64 |     }
65 | 
66 | 
67 | }
68 | 
69 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Square Wave.entitlements:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 | 
 5 | 	com.apple.developer.icloud-container-identifiers
 6 | 	
 7 | 		iCloud.com.abusman.square-wave
 8 | 	
 9 | 	com.apple.developer.icloud-services
10 | 	
11 | 		CloudDocuments
12 | 	
13 | 	com.apple.developer.ubiquity-container-identifiers
14 | 	
15 | 		iCloud.com.abusman.square-wave
16 | 	
17 | 	com.apple.developer.ubiquity-kvstore-identifier
18 | 	$(TeamIdentifierPrefix)$(CFBundleIdentifier)
19 | 	keychain-access-groups
20 | 	
21 | 
22 | 
23 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/TextView.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  TextView.swift
 3 | //  Square Wave
 4 | //
 5 | //  Created by Alex Busman on 3/1/20.
 6 | //  Copyright © 2020 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | import SwiftUI
10 | 
11 | struct TextView: UIViewRepresentable {
12 |     var title: String
13 |     @Binding var text: String
14 |     var placeholder = UILabel()
15 | 
16 |     func makeCoordinator() -> Coordinator {
17 |         Coordinator(self)
18 |     }
19 | 
20 |     func makeUIView(context: Context) -> UITextView {
21 | 
22 |         let myTextView = UITextView()
23 |         myTextView.delegate = context.coordinator
24 |         myTextView.isScrollEnabled = true
25 |         myTextView.isEditable = true
26 |         myTextView.isUserInteractionEnabled = true
27 |         myTextView.backgroundColor = .clear
28 |         myTextView.font = UIFont.preferredFont(forTextStyle: .headline)
29 |         myTextView.returnKeyType = .done
30 |         myTextView.text = self.text
31 | 
32 |         self.placeholder.text = self.title
33 |         self.placeholder.textColor = .placeholderText
34 |         self.placeholder.font = UIFont.preferredFont(forTextStyle: .headline)
35 |         myTextView.addSubview(self.placeholder)
36 |         
37 |         self.placeholder.translatesAutoresizingMaskIntoConstraints = false
38 |         self.placeholder.isUserInteractionEnabled = false
39 | 
40 |         self.placeholder.leadingAnchor.constraint(equalTo: myTextView.leadingAnchor, constant: 6).isActive = true
41 |         self.placeholder.topAnchor.constraint(equalTo: myTextView.topAnchor, constant: 7.5).isActive = true
42 |         
43 |         if !self.text.isEmpty {
44 |             self.placeholder.isHidden = true
45 |         }
46 |         return myTextView
47 |     }
48 | 
49 |     func updateUIView(_ uiView: UITextView, context: Context) {
50 | 
51 |     }
52 | 
53 |     class Coordinator : NSObject, UITextViewDelegate {
54 | 
55 |         var parent: TextView
56 | 
57 |         init(_ uiTextView: TextView) {
58 |             self.parent = uiTextView
59 |         }
60 | 
61 |         func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
62 |             if text == "\n" {
63 |                 textView.resignFirstResponder()
64 |                 return false
65 |             }
66 |             return true
67 |         }
68 | 
69 |         func textViewDidChange(_ textView: UITextView) {
70 |             self.parent.text = textView.text
71 | 
72 |             if self.parent.text.isEmpty {
73 |                 self.parent.placeholder.isHidden = false
74 |             } else {
75 |                 self.parent.placeholder.isHidden = true
76 |             }
77 |         }
78 |     }
79 | }
80 | 
81 | struct TextView_Previews: PreviewProvider {
82 |     static var previews: some View {
83 |         TextView(title: "Preview", text: .constant(""))
84 |     }
85 | }
86 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/Util.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Util.swift
 3 | //  Square Wave
 4 | //
 5 | //  Created by Alex Busman on 3/8/20.
 6 | //  Copyright © 2020 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | import Foundation
10 | 
11 | class Util {
12 |     class func getPlaylistImagesDirectory() -> URL? {
13 |         var ret: URL?
14 |         do {
15 |             let docsDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
16 |             ret = docsDir.appendingPathComponent("images/playlists")
17 |         } catch {
18 |             NSLog("Could not get docs dir")
19 |         }
20 |         return ret
21 |     }
22 |     
23 |     class func getPurchased() -> Bool {
24 |         return PlaybackStateProperty.purchased.getProperty() ?? false
25 |     }
26 | }
27 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/VisualEffectView.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 | 
3 | struct VisualEffectView: UIViewRepresentable {
4 |     var effect: UIVisualEffect?
5 |     func makeUIView(context: UIViewRepresentableContext) -> UIVisualEffectView { UIVisualEffectView() }
6 |     func updateUIView(_ uiView: UIVisualEffectView, context: UIViewRepresentableContext) { uiView.effect = effect }
7 | }
8 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
 1 | /* 
 2 |   Localizable.strings
 3 |   Square Waves
 4 | 
 5 |   Created by Alex Busman on 4/4/20.
 6 |   Copyright © 2020 Alex Busman. All rights reserved.
 7 | */
 8 | 
 9 | "Library" = "Library";
10 | "Settings" = "Settings";
11 | "Playlists" = "Playlists";
12 | "Platforms" = "Platforms";
13 | "Games" = "Games";
14 | "Songs" = "Songs";
15 | "Track Length" = "Track Length";
16 | "Add Files" = "Add files by pressing the \"+\" button in the top right, or by adding them to the\nSquare Wave folder on your iCloud Drive";
17 | "Track Length Description" = "For tracks without loop information, you can choose how long you want the track to play for before moving on to the next track.";
18 | "Loop Count" = "Loop Count";
19 | "Loop Count Description" = "For tracks with loop information, you can choose how many times you want the track to loop before moving on to the next track.";
20 | "Upgrade" = "Upgrade";
21 | "Upgrade Description %@" = "With the free version, you are limited to %@ tracks per day. Upgrade, and get unlimited playback, playlist support, voice toggling, and more!";
22 | "Restore Purchases" = "Restore Purchases";
23 | "Upgrade Purchased" = "Upgrade Purchased. Thanks!";
24 | "Delete All" = "Delete All";
25 | "Done" = "Done";
26 | "Edit" = "Edit";
27 | "Cancel" = "Cancel";
28 | "Playback Rate" = "Playback Rate";
29 | "Voices" = "Voices";
30 | "Play Count Exceeded" = "Play Count Exceeded";
31 | "Exceeded Error" = "You have exceeded the maximum amount of tracks per day. Would you like to purchase premium?";
32 | "Yes" = "Yes";
33 | "No" = "No";
34 | "Playlists Premium" = "Playlists are a premium feature. Upgrade to get this and more!";
35 | "Confirm Playlists" = "Sounds like fun!";
36 | "Sort" = "Sort";
37 | "Sort By" = "Sort by...";
38 | "Title" = "Title";
39 | "Game" = "Game";
40 | "Playlist Title" = "Playlist Title";
41 | "Add Songs" = "Add Songs";
42 | "Error" = "Error";
43 | "Okay" = "Okay";
44 | "Delete All Question" = "Delete All?";
45 | "Delete All Description" = "This will delete all your music and playlists. This will NOT delete anything stored in your cloud drive.\nAre you sure?";
46 | "Delete All Confirm" = "Yes, Delete";
47 | "Purchase Error Description %@" = "Could not complete purchase. %@";
48 | "Add To Playlist" = "Add to Playlist";
49 | "Search" = "Search";
50 | "New Playlist" = "New Playlist";
51 | "tracks" = "tracks";
52 | "Remove" = "Remove";
53 | "Delete" = "Delete";
54 | "Rename" = "Rename";
55 | "Save" = "Save";
56 | "No Name" = "No Name";
57 | "Shuffle" = "Shuffle";
58 | "Play" = "Play";
59 | "Not Playing" = "Not Playing";
60 | "Artists" = "Artists";
61 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/fr-CA.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 |     
 4 |     
 5 |         
 6 |         
 7 |     
 8 |     
 9 |         
10 |         
11 |             
12 |                 
13 |                     
14 |                         
15 |                         
16 |                         
17 |                         
18 |                         
19 |                             
20 |                             
21 |                         
22 |                     
23 |                     
24 |                         
25 |                         
26 |                             
27 |                             
28 |                         
29 |                     
30 |                 
31 |                 
32 |             
33 |             
34 |         
35 |         
36 |         
37 |             
38 |                 
39 |                     
40 |                         
41 |                         
42 |                     
43 |                     
44 |                         
45 |                     
46 |                 
47 |                 
48 |             
49 |             
50 |         
51 |     
52 | 
53 | 
--------------------------------------------------------------------------------
/Square Wave/Square Wave/fr-CA.lproj/Localizable.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-busman/SquareWaveSwift/cd194d8dcc6bafa8f64d6156b1f6af0dde744005/Square Wave/Square Wave/fr-CA.lproj/Localizable.strings
--------------------------------------------------------------------------------
/Square Wave/Square WaveTests/Info.plist:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 | 
 5 | 	CFBundleDevelopmentRegion
 6 | 	$(DEVELOPMENT_LANGUAGE)
 7 | 	CFBundleExecutable
 8 | 	$(EXECUTABLE_NAME)
 9 | 	CFBundleIdentifier
10 | 	$(PRODUCT_BUNDLE_IDENTIFIER)
11 | 	CFBundleInfoDictionaryVersion
12 | 	6.0
13 | 	CFBundleName
14 | 	$(PRODUCT_NAME)
15 | 	CFBundlePackageType
16 | 	$(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | 	CFBundleShortVersionString
18 | 	1.0
19 | 	CFBundleVersion
20 | 	1
21 | 
22 | 
23 | 
--------------------------------------------------------------------------------
/Square Wave/Square WaveTests/Square_WaveTests.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Square_WaveTests.swift
 3 | //  Square WaveTests
 4 | //
 5 | //  Created by Alex Busman on 2/10/20.
 6 | //  Copyright © 2020 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | import XCTest
10 | @testable import Square_Wave
11 | 
12 | class Square_WaveTests: XCTestCase {
13 | 
14 |     override func setUp() {
15 |         // Put setup code here. This method is called before the invocation of each test method in the class.
16 |     }
17 | 
18 |     override func tearDown() {
19 |         // Put teardown code here. This method is called after the invocation of each test method in the class.
20 |     }
21 | 
22 |     func testExample() {
23 |         // This is an example of a functional test case.
24 |         // Use XCTAssert and related functions to verify your tests produce the correct results.
25 |     }
26 | 
27 |     func testPerformanceExample() {
28 |         // This is an example of a performance test case.
29 |         self.measure {
30 |             // Put the code you want to measure the time of here.
31 |         }
32 |     }
33 | 
34 | }
35 | 
--------------------------------------------------------------------------------
/Square Wave/Square WaveUITests/Info.plist:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 | 
 5 | 	CFBundleDevelopmentRegion
 6 | 	$(DEVELOPMENT_LANGUAGE)
 7 | 	CFBundleExecutable
 8 | 	$(EXECUTABLE_NAME)
 9 | 	CFBundleIdentifier
10 | 	$(PRODUCT_BUNDLE_IDENTIFIER)
11 | 	CFBundleInfoDictionaryVersion
12 | 	6.0
13 | 	CFBundleName
14 | 	$(PRODUCT_NAME)
15 | 	CFBundlePackageType
16 | 	$(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | 	CFBundleShortVersionString
18 | 	1.0
19 | 	CFBundleVersion
20 | 	1
21 | 
22 | 
23 | 
--------------------------------------------------------------------------------
/Square Wave/Square WaveUITests/Square_WaveUITests.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Square_WaveUITests.swift
 3 | //  Square WaveUITests
 4 | //
 5 | //  Created by Alex Busman on 2/10/20.
 6 | //  Copyright © 2020 Alex Busman. All rights reserved.
 7 | //
 8 | 
 9 | import XCTest
10 | 
11 | class Square_WaveUITests: XCTestCase {
12 | 
13 |     override func setUp() {
14 |         // Put setup code here. This method is called before the invocation of each test method in the class.
15 | 
16 |         // In UI tests it is usually best to stop immediately when a failure occurs.
17 |         continueAfterFailure = false
18 | 
19 |         // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
20 |     }
21 | 
22 |     override func tearDown() {
23 |         // Put teardown code here. This method is called after the invocation of each test method in the class.
24 |     }
25 | 
26 |     func testExample() {
27 |         // UI tests must launch the application that they test.
28 |         let app = XCUIApplication()
29 |         app.launch()
30 | 
31 |         // Use recording to get started writing UI tests.
32 |         // Use XCTAssert and related functions to verify your tests produce the correct results.
33 |     }
34 | 
35 |     func testLaunchPerformance() {
36 |         if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) {
37 |             // This measures how long it takes to launch your application.
38 |             measure(metrics: [XCTOSSignpostMetric.applicationLaunch]) {
39 |                 XCUIApplication().launch()
40 |             }
41 |         }
42 |     }
43 | }
44 | 
--------------------------------------------------------------------------------
/Square Wave/Square Waves.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 | 
2 | 
4 |    
6 |    
7 | 
8 | 
--------------------------------------------------------------------------------
/Square Wave/Square Waves.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 | 
2 | 
3 | 
4 | 
5 | 	IDEDidComputeMac32BitWarning
6 | 	
7 | 
8 | 
9 | 
--------------------------------------------------------------------------------
/Square Wave/Square Waves.xcodeproj/xcshareddata/xcschemes/Square Wave.xcscheme:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 5 |    
 8 |       
 9 |          
15 |             
21 |             
22 |          
23 |       
24 |    
25 |    
30 |       
31 |          
33 |             
39 |             
40 |          
41 |          
43 |             
49 |             
50 |          
51 |       
52 |    
53 |    
63 |       
65 |          
71 |          
72 |       
73 |    
74 |    
80 |       
82 |          
88 |          
89 |       
90 |    
91 |    
93 |    
94 |    
97 |    
98 | 
99 | 
--------------------------------------------------------------------------------
/Square Wave/Square Waves.xcodeproj/xcuserdata/abusman.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 | 
 5 | 	SchemeUserState
 6 | 	
 7 | 		Square Wave.xcscheme_^#shared#^_
 8 | 		
 9 | 			orderHint
10 | 			0
11 | 		
12 | 	
13 | 	SuppressBuildableAutocreation
14 | 	
15 | 		FA822D3123F1F81C005FCFB3
16 | 		
17 | 			primary
18 | 			
19 | 		
20 | 		FA822D4A23F1F81E005FCFB3
21 | 		
22 | 			primary
23 | 			
24 | 		
25 | 		FA822D5523F1F81E005FCFB3
26 | 		
27 | 			primary
28 | 			
29 | 		
30 | 	
31 | 
32 | 
33 | 
--------------------------------------------------------------------------------
/Square Wave/Square Waves.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 4 |    
 6 |    
 7 |    
 9 |    
10 | 
11 | 
--------------------------------------------------------------------------------