rlm@440: (ns com.aurellem.exp.music rlm@440: "scratchpad namespace" rlm@440: (:use (com.aurellem.gb gb-driver util constants rlm@440: assembly saves rlm@440: items pokemon status types rlm@440: characters species moves rlm@440: pokedex money rival-name rlm@440: text-speed badges rlm@440: pokemon-presets rlm@440: )) rlm@440: rlm@440: (:import java.io.File) rlm@440: (:import [com.aurellem.gb.gb_driver SaveState])) rlm@440: rlm@440: rlm@440: rlm@440: rlm@440: (defn analyze-music [] rlm@440: (clojure.pprint/pprint rlm@440: (map (fn [[addr nums]] rlm@440: [(hex addr) nums]) rlm@440: (apply harmonic-compare rlm@440: (map read-state rlm@440: ["song-1" "no-song-1" rlm@440: "song-2" "no-song-2" rlm@440: "song-3" "no-song-3" rlm@440: "song-4"]))))) rlm@440: ;; there are only two addresses that alternate between only rlm@440: ;; two unique values: rlm@440: rlm@440: 0xC0DE ;; lol code :) rlm@440: 0xC0DF rlm@440: rlm@440: ;; perhaps they are the address of the current playing sound? rlm@440: rlm@440: ;; after watching them for a while in different environments, rlm@440: ;; I can tell that they're definately music related, but they rlm@440: ;; _don't_ seem to be the address to the current track. rlm@440: ;; they generally change whenever a substantually different rlm@440: ;; sequence is played. maybe they control some high level rlm@440: ;; setting in the synthesizer? They are only affected by the rlm@440: ;; background music and not by pokemon cries, etc. rlm@440: rlm@440: 0xC001 ;; seems to change along with the music, but is much rlm@440: ;; more stable than 0xC0DE and 0xC0DF. It _is_ rlm@440: ;; affected by sound effects. When a sound effect happens, rlm@440: ;; is sometimes does not return to its previous value when the sound rlm@440: ;; effect is done. rlm@440: rlm@440: 0xC000 ;; does not seem to be affected by music rlm@440: rlm@440: ;; maybe 0xC001 - something is loaded with the actual sounds? rlm@440: rlm@440: rlm@440: ;; replacing just the first 0xFF bytes starting at 0xC001 with those rlm@440: ;; found in celadon changes the music to celadon city. rlm@440: rlm@440: ;; this can't be the actual music because it doesn't have enough rlm@440: ;; information. rlm@440: rlm@440: ;; let's try to narrow down the bytes from the first 0xFF of celadon rlm@440: ;; starting at 0xC001 rlm@440: rlm@440: (def celadon-song rlm@440: [202 0 0 255 0 178 117 40 118 158 118 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@441: 0 0 0 0 0 0 0 0 0 0 0 202 202 202 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 rlm@441: 0 0 0 0 128 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@441: 0 0 0 0 0 0 0 0 0 0 0 0 115 88 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@441: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@441: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 1 1 1 1 1 rlm@441: 1 1 1 1 1 1 1 1 12 12 12 1 1 1 1 1 128 128 128 0 0 0 0 0 5 4 4 0 4 3 rlm@441: 4 0 178 194 32 0 180 196 32 0 3 0 0 144 1 0 66 31 0 2 2 32 48 0 0 0 rlm@440: 0 0 0 0 0 0 0 0 0 0]) rlm@440: rlm@441: (def jiggly-song rlm@441: [208 0 0 255 0 240 113 7 114 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@441: 0 0 0 0 0 0 0 0 208 208 0 0 0 0 0 0 65 72 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@441: 0 128 0 0 0 0 0 0 0 105 130 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 16 0 0 0 rlm@441: 0 0 0 65 81 0 0 0 0 0 0 58 57 0 0 0 0 0 0 8 5 0 0 0 0 0 0 0 0 0 0 0 rlm@441: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@441: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 3 1 1 1 1 1 1 1 rlm@441: 1 1 1 1 1 1 1 13 12 1 1 1 1 1 1 128 0 0 0 88 152 0 0 4 4 4 0 4 4 3 0 rlm@441: 103 167 32 0 180 196 32 0 0 0 0 144 1 0 66 28 0 31 31 224 255 0 0 0 rlm@441: 0 0 0 0 0 0 0 0 0 0]) rlm@441: rlm@441: (def fight-gym-leader-song rlm@441: [234 0 0 255 0 0 92 43 94 112 95 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@441: 0 0 0 0 0 0 0 0 234 234 234 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@441: 0 192 192 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 7 0 0 0 0 0 0 33 17 17 0 0 0 rlm@441: 0 0 68 82 0 0 0 0 0 0 89 90 57 0 0 0 0 0 8 8 0 0 0 0 0 0 0 0 0 0 0 0 rlm@441: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@441: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 1 1 1 1 1 1 1 rlm@441: 1 1 1 1 1 1 12 12 12 1 1 1 1 1 192 192 192 0 88 152 0 0 7 5 4 0 4 4 rlm@441: 3 0 179 195 32 0 180 196 32 0 3 0 0 104 1 0 65 176 0 8 8 224 255 0 0 rlm@441: 0 0 0 0 0 0 0 0 0 0 0]) rlm@441: rlm@441: rlm@441: (def fight-gym-leader-song-simp rlm@442: [ rlm@442: rlm@445: (Integer/parseInt "00000001" 2) ;; channel-on/off rlm@442: rlm@442: 0 ;; no-effect rlm@442: rlm@442: ;; channel 0 rlm@443: 0 ;; note-counter low 0xC006 rlm@443: 92 ;; note-counter high 0xC007 rlm@442: rlm@442: ;; channel 1 rlm@443: 43 ;; note-counter low 0xC008 rlm@443: 94 ;; note-counter high 0xC009 rlm@442: rlm@442: ;; channel 2 rlm@443: 112 ;; note-counter low 0xC00A rlm@443: 95 ;; note-counter high 0xC00B rlm@442: rlm@443: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@442: rlm@443: 1 ;; if zero, mute channel 0xC026 rlm@443: 1 ;; rlm@443: 1 ;; rlm@443: rlm@443: rlm@443: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@443: rlm@443: ;; square wave duty (only first two bits matter.) rlm@443: ;; channel 0 rlm@445: (Integer/parseInt "10000000" 2) ;; 0xC03E rlm@443: ;; channel 1 rlm@443: (Integer/parseInt "11000000" 2) ;; 0xC03F rlm@443: rlm@441: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@443: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@443: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@443: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@443: rlm@443: rlm@443: 4 4 4;; these change very quickly! 0xC0B6 rlm@443: rlm@443: 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@443: rlm@443: ;; Tempo rlm@443: rlm@443: ;; channel 0 tempo (higher is slower) rlm@443: 12 ;; 0xC0C6 rlm@443: rlm@443: ;; channel 1 tempo rlm@443: 12 ;; 0xC0C7 rlm@443: rlm@443: ;; channel 2 tempo rlm@443: 12 ;; 0xC0C8 rlm@443: rlm@443: 0 0 0 0 0 0 0 0 0 0 0 0 0 rlm@443: rlm@444: 7 ;; 0xC0D6 (transient pitch channel 0) rlm@443: rlm@444: 5 4 0 4 4 3 0 rlm@443: rlm@444: ;; volume rlm@444: ;; channel 0 volume (first 4 bits) rlm@444: (Integer/parseInt "11110000" 2) ;; 0xC0DE rlm@444: ;; channel 1 volume (first 4 bits) rlm@444: (Integer/parseInt "11000000" 2) ;; 0xC0DF rlm@444: ;; channel 2 volume (unknown syntax) rlm@444: (Integer/parseInt "00100000" 2) ;; 0xC0E0 rlm@443: rlm@444: 0 0 0 0 0 0 0 0 rlm@442: rlm@444: 104 ;; MASTER TEMPO 0xC0E9 rlm@444: rlm@444: 0 0 0 0 0 rlm@444: rlm@444: rlm@444: 8 ;; checksum? address? rlm@442: ]) rlm@441: rlm@441: (defn change-music rlm@441: ([#^SaveState state start length song] rlm@440: rlm@442: (set-memory-range state (+ 0xC004 start) rlm@441: (take length (drop start song)))) rlm@441: ([start length song] rlm@441: (continue! (change-music (read-state "rlm-viridian-forest") rlm@441: start length song)))) rlm@440: rlm@440: rlm@440: rlm@440: ;;0 0x90) blend between both, with end theme as well rlm@440: rlm@440: ;; 0x05 0xEA is the limit to completely change song to celadon from rlm@440: ;; viridian forest rlm@440: rlm@440: ;; 0x05 0xEA is also sufficient to change music to celadon from rlm@441: ;; a battle in viridian forest rlm@441: rlm@441: (def minimal-celadon-song rlm@441: (subvec celadon-song 0x05 0xEA)) rlm@441: rlm@441: ;; 0xC006 -- appears to be the song note counter. rlm@441: ;; 0cC007 --