ref: 3626ddebd1dd7363c98b403ba1fe3c2d7dc598ee
parent: bfbb9b77e8b55fa2acdaf2c4267b5221fabb410b
author: padz <[email protected]>
date: Fri Nov 30 00:58:00 EST 2012
implement music macros; INCLUDE injection in pre
--- a/extras/crystal.py
+++ b/extras/crystal.py
@@ -2934,6 +2934,87 @@
return klasses
command_classes = create_command_classes()
+
+
+music_commands_new = {
+ 0xD0: ["octave8"],
+ 0xD1: ["octave7"],
+ 0xD2: ["octave6"],
+ 0xD3: ["octave5"],
+ 0xD4: ["octave4"],
+ 0xD5: ["octave3"],
+ 0xD6: ["octave2"],
+ 0xD7: ["octave1"],
+ 0xD8: ["notetype", ["note_length", SingleByteParam], ["intensity", SingleByteParam]], # only 1 param on ch3
+ 0xD9: ["forceoctave", ["octave", SingleByteParam]],
+ 0xDA: ["tempo", ["tempo", MultiByteParam]],
+ 0xDB: ["dutycycle", ["duty_cycle", SingleByteParam]],
+ 0xDC: ["intensity", ["intensity", SingleByteParam]],
+ 0xDD: ["soundinput", ["input", SingleByteParam]],
+ 0xDE: ["unknownmusic0xde", ["unknown", SingleByteParam]], # also updates duty cycle
+ 0xDF: ["unknownmusic0xdf"],
+ 0xE0: ["unknownmusic0xe0", ["unknown", SingleByteParam], ["unknown", SingleByteParam]],
+ 0xE1: ["vibrato", ["delay", SingleByteParam], ["extent", SingleByteParam]],
+ 0xE2: ["unknownmusic0xe2", ["unknown", SingleByteParam]],
+ 0xE3: ["togglenoise", ["id", SingleByteParam]], # this can have 0-1 params!
+ 0xE4: ["panning", ["tracks", SingleByteParam]],
+ 0xE5: ["volume", ["volume", SingleByteParam]],
+ 0xE6: ["tone", ["tone", MultiByteParam]], # big endian
+ 0xE7: ["unknownmusic0xe7", ["unknown", SingleByteParam]],
+ 0xE8: ["unknownmusic0xe8", ["unknown", SingleByteParam]],
+ 0xE9: ["globaltempo", ["value", MultiByteParam]],
+ 0xEA: ["restartchannel", ["address", PointerLabelParam]],
+ 0xEB: ["newsong", ["id", MultiByteParam]],
+ 0xEC: ["sfxpriorityon"],
+ 0xED: ["sfxpriorityoff"],
+ 0xEE: ["unknownmusic0xee", ["address", PointerLabelParam]],
+ 0xEF: ["stereopanning", ["tracks", SingleByteParam]],
+ 0xF0: ["sfxtogglenoise", ["id", SingleByteParam]], # 0-1 params
+ 0xF1: ["music0xf1"], # nothing
+ 0xF2: ["music0xf2"], # nothing
+ 0xF3: ["music0xf3"], # nothing
+ 0xF4: ["music0xf4"], # nothing
+ 0xF5: ["music0xf5"], # nothing
+ 0xF6: ["music0xf6"], # nothing
+ 0xF7: ["music0xf7"], # nothing
+ 0xF8: ["music0xf8"], # nothing
+ 0xF9: ["unknownmusic0xf9"],
+ 0xFA: ["setcondition", ["condition", SingleByteParam]],
+ 0xFB: ["jumpif", ["condition", SingleByteParam], ["address", PointerLabelParam]],
+ 0xFC: ["jumpchannel", ["address", PointerLabelParam]],
+ 0xFD: ["loopchannel", ["count", SingleByteParam], ["address", PointerLabelParam]],
+ 0xFE: ["callchannel", ["address", PointerLabelParam]],
+ 0xFF: ["endchannel"],
+}
+
+music_command_enders = [0xEA, 0xEB, 0xEE, 0xFC, 0xFF,]
+# special case for 0xFD (if loopchannel.count = 0, break)
+
+
+
+def create_music_command_classes(debug=False):
+ klasses = [GivePoke]
+ for (byte, cmd) in music_commands_new.items():
+ cmd_name = cmd[0].replace(" ", "_")
+ params = {"id": byte, "size": 1, "end": byte in music_command_enders, "macro_name": cmd_name}
+ params["param_types"] = {}
+ if len(cmd) > 1:
+ param_types = cmd[1:]
+ for (i, each) in enumerate(param_types):
+ thing = {"name": each[0], "class": each[1]}
+ params["param_types"][i] = thing
+ if debug:
+ print "each is: " + str(each)
+ print "thing[class] is: " + str(thing["class"])
+ params["size"] += thing["class"].size
+ klass_name = cmd_name+"Command"
+ klass = classobj(klass_name, (Command,), params)
+ globals()[klass_name] = klass
+ klasses.append(klass)
+ # later an individual klass will be instantiated to handle something
+ return klasses
+music_classes = create_music_command_classes()
+
def generate_macros(filename="../script_macros.asm"):
"""generates all macros based on commands
this is dumped into script_macros.asm"""
--- a/preprocessor.py
+++ b/preprocessor.py
@@ -15,7 +15,8 @@
ItemFragment, \
TextEndingCommand, \
text_command_classes, \
- movement_command_classes
+ movement_command_classes, \
+ music_classes
macros = command_classes + \
[
@@ -25,8 +26,9 @@
PeopleEvent,
DataByteWordMacro,
ItemFragment,
- ] + [x[1] for x in text_command_classes] \
- + movement_command_classes
+ ] + [x[1] for x in text_command_classes] + \
+ movement_command_classes + \
+ music_classes
chars = {
"ガ": 0x05,
@@ -329,8 +331,8 @@
# skip asm that actually does use ASCII in quotes
lowasm = asms[0].lower()
+
if "section" in lowasm \
- or "include" in lowasm \
or "incbin" in lowasm:
sys.stdout.write(asm)
return
@@ -488,6 +490,12 @@
else:
allowed_lengths = [allowed_length]
+ if macro.macro_name == "notetype":
+ allowed_lengths = [1,2]
+ elif macro.macro_name == "togglenoise" \
+ or macro.macro_name == "sfxtogglenoise":
+ allowed_lengths = [0,1]
+
assert len(params) in allowed_lengths, \
"mismatched number of parameters on this line: " + \
original_line
@@ -543,27 +551,42 @@
index += 1
-for l in sys.stdin:
- # strip and store any comment on this line
- if ";" in l:
- asm, comment = separate_comment(l)
- else:
- asm = l
- comment = None
- # convert text to bytes when a quote appears (not in a comment)
- if "\"" in asm:
- quote_translator(asm)
+def include_file(asm):
+ filename = asm.split("\"")
+ filename = filename[1].replace("\"","").replace("\n","")
+ lines = open(filename, 'r').readlines()
+ for line in lines:
+ read_line(line)
- # check against other preprocessor features
- else:
- macro, token = macro_test(asm)
-
- if macro:
- macro_translator(macro, token, asm)
+def read_line(l):
+ # strip and store any comment on this line
+ if ";" in l:
+ asm, comment = separate_comment(l)
else:
- sys.stdout.write(asm)
+ asm = l
+ comment = None
+
+ if "INCLUDE \"" in asm:
+ include_file(asm)
+
+ elif "\"" in asm:
+ # convert text to bytes when a quote appears (not in a comment)
+ quote_translator(asm)
+
+
+ # check against other preprocessor features
+ else:
+ macro, token = macro_test(asm)
+
+ if macro:
+ macro_translator(macro, token, asm)
+ else:
+ sys.stdout.write(asm)
+
+ # show line comment
+ if comment != None:
+ sys.stdout.write(comment)
- # show line comment
- if comment != None:
- sys.stdout.write(comment)
+for l in sys.stdin:
+ read_line(l)
\ No newline at end of file