peasant: add electric duet music if no mockingboard

This commit is contained in:
Vince Weaver 2021-10-01 01:26:09 -04:00
parent 74ed7d7e9d
commit 1e06b6f9d8
14 changed files with 3967 additions and 97 deletions

View File

@ -154,7 +154,7 @@ title.o: title.s qload.inc music.inc \
graphics_title/title_graphics.inc \
graphics_title/altfire.inc \
directions.s \
pt3_lib_mockingboard_patch.s
pt3_lib_mockingboard_patch.s duet.s
ca65 -o title.o title.s -l title.lst
###

View File

@ -1,5 +1,20 @@
TODO:
before 0.75 release
+ update version file
+ merge electric duet
+ complete waterfall, including animation
+ have init routine set starting score, etc
after 0.75
+ move copy to disk2
+ re-do how off edge-of-screen works (have destination for all 4 co-ords?)
+ move drawing to PAGE1 and use PAGE2 for RAM?
This would remove backing store when drawing text boxes?
+ add dictionary lookup for text
+ add standard set of text box sizes
General:
- More frames in peasant sprites
- Hook up text parser

213
games/peasant/duet.s Normal file
View File

@ -0,0 +1,213 @@
; ***************************************************************************
; * Copyright (C) 1979-2015 by Paul Lutus *
; * http://arachnoid.com/administration *
; * *
; * This program is free software; you can redistribute it and/or modify *
; * it under the terms of the GNU General Public License as published by *
; * the Free Software Foundation; either version 2 of the License, or *
; * (at your option) any later version. *
; * *
; * This program is distributed in the hope that it will be useful, *
; * but WITHOUT ANY WARRANTY; without even the implied warranty of *
; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
; * GNU General Public License for more details. *
; * *
; * You should have received a copy of the GNU General Public License *
; * along with this program; if not, write to the *
; * Free Software Foundation, Inc., *
; * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
; ***************************************************************************
; 645d roughly trogdor music
; Electric Duet Player Routine circa 1980
; Formatting / comments added by Vince Weaver
; These are all "Free" zero page locations
;FREQ1 = $10
;FREQ2 = $11
;DURATION = $12
;INSTRUMENT1 = $13
;INSTRUMENT2 = $14
;MADDRL = $15
;MADDRH = $16
;LOC4E = $4E
;COUNT256 = $4F
play_ed:
lda #$01 ; 900: A9 01 ; 2 *!*
sta INSTRUMENT1 ; 902: 85 09 ; 3 set default
sta INSTRUMENT2 ; 904: 85 1D ; 3 instruments
pha ; 906: 48 ; 3 1 on stack
pha ; 907: 48 ; 3 1 on stack
pha ; 908: 48 ; 3 1 on stack
bne load_triplet ; 909: D0 15 ; 4 *!* start decoding
change_instrmnt:
iny ; 90B: C8 ; 2
lda (MADDRL),Y ; 90C: B1 1E ; 5 *!* load next byte
sta INSTRUMENT1 ; 90E: 85 09 ; 3 save instrument
iny ; 910: C8 ; 2
lda (MADDRL),Y ; 911: B1 1E ; 5 *!* load next byte
sta INSTRUMENT2 ; 913: 85 1D ; 3 save instrument
triplet_loop:
; flash different if trogdor music
ldy #2
lda (MADDRL),Y
cmp #24 ; D4
beq no_trogdor
bit PAGE2
jmp done_duet_trog
no_trogdor:
bit PAGE1
done_duet_trog:
lda MADDRL ; 915: A5 1E ; 3 *!* increment pointer
clc ; 917: 18 ; 2 by three
adc #$03 ; 918: 69 03 ; 2 *!*
sta MADDRL ; 91A: 85 1E ; 3
bcc load_triplet ; 91C: 90 02 ; 4 *!* if overflow
inc MADDRH ; 91E: E6 1F ; 5 update high byte
load_triplet:
ldy #$00 ; 920: A0 00 ; 2 *!* Set Y to zero
lda (MADDRL),Y ; 922: B1 1E ; 5 *!* Load first byte
cmp #$01 ; 924: C9 01 ; 2 Compare to 1
beq change_instrmnt ; 926: F0 E3 ; 4 *!* If one change inst
bcs play_note ; 928: B0 0D ; 4 *!* If >1, then duration
pla ; 92A: 68 ; 4 pop off stack
pla ; 92B: 68 ; 4 pop off stack
pla ; 92C: 68 ; 4 pop off stack
; fallthrough if first byte was zero
; Load byte from music stream
; Set X=EOR if note zero, set X=CMP if it is
load_freq:
ldx #$49 ; 92D: A2 49 ; 2 *!* X=0x49 (EOR opcode)
iny ; 92F: C8 ; 2 increment to next byte
lda (MADDRL),Y ; 930: B1 1E ; 5 *!* load next byte
bne exit_player ; 932: D0 02 ; 4 *!* if not zero
ldx #$C9 ; 934: A2 C9 ; 2 *!* X=0xC9 (CMP opcode)
exit_player:
; if byte0==0 and byte1==0 then end (I have no idea how)
rts ; 936: 60 ; 6 return
; We've got a duration/note/note triplet here
play_note:
sta DURATION ; 937: 85 08 ; 3 store out duration
jsr load_freq ; 939: 20 2D09 ; 6 get freq#1
stx selfmodify1 ; 93C: 8E 8309 ; 4 if 0 self-modify EOR/CMP
sta FREQ1 ; 93F: 85 06 ; 3
ldx INSTRUMENT1 ; 941: A6 09 ; 3 *!*
instr1_adjust:
lsr A ; 943: 4A ; 2 rshift freq by inst#
dex ; 944: CA ; 2
bne instr1_adjust ; 945: D0 FC ; 4 *!*
sta selfmodify2+1 ; 947: 8D 7C09 ; 4 self-modify a CPY
jsr load_freq ; 94A: 20 2D09 ; 6 get freq#2
stx selfmodify3 ; 94D: 8E BB09 ; 4 if 0 self-modify EOR/CMP
sta FREQ2 ; 950: 85 07 ; 3
ldx INSTRUMENT2 ; 952: A6 1D ; 3 *!*
instr2_adjust:
lsr A ; 954: 4A ; 2 rshift freq by inst#
dex ; 955: CA ; 2
bne instr2_adjust ; 956: D0 FC ; 4 *!*
sta selfmodify4+1 ; 958: 8D B409 ; 4 self modify a CPX
pla ; 95B: 68 ; 4
tay ; 95C: A8 ; 2
pla ; 95D: 68 ; 4
tax ; 95E: AA ; 2
pla ; 95F: 68 ; 4
bne label8 ; 960: D0 03 ; 4 *!*
label99:
bit $C030 ; 962: 2C 30C0 ; 4 SPEAKER
label8:
cmp #$00 ; 965: C9 00 ; 2
bmi label7 ; 967: 30 03 ; 4 *!*
nop ; 969: EA ; 2
bpl label9 ; 96A: 10 03 ; 4 *!*
label7:
bit $C030 ; 96C: 2C 30C0 ; 4 SPEAKER
label9:
sta LOC4E ; 96F: 85 4E ; 3
bit $C000 ; 971: 2C 00C0 ; 4 KEYBOARD DATA
bmi exit_keypress ; 974: 30 C0 ; 4 *!* if keypress, exit
dey ; 976: 88 ; 2
bne selfmodify2 ; 977: D0 02 ; 4 *!*
beq label11 ; 979: F0 06 ; 4 *!*
selfmodify2:
cpy #$00 ; 97B: C0 00 ; 2
beq selfmodify1 ; 97D: F0 04 ; 4 *!* !!!
bne label13 ; 97F: D0 04 ; 4 *!*
label11:
ldy FREQ1 ; 981: A4 06 ; 3 *!*
selfmodify1:
eor #$40 ; 983: 49 40 ; 2 *!* !!!
label13:
bit LOC4E ; 985: 24 4E ; 3
bvc label14 ; 987: 50 07 ; 4 *!*
bvs label15 ; 989: 70 00 ; 4 *!*
label15:
bpl label16 ; 98B: 10 09 ; 4 *!*
nop ; 98D: EA ; 2
bmi label17 ; 98E: 30 09 ; 4 *!*
label14:
nop ; 990: EA ; 2
bmi label16 ; 991: 30 03 ; 4 *!*
nop ; 993: EA ; 2
bpl label17 ; 994: 10 03 ; 4 *!*
label16:
cmp $C030 ; 996: CD 30C0 ; 4 SPEAKER
label17:
dec COUNT256 ; 999: C6 4F ; 5 div by 256 counter
bne label18 ; 99B: D0 11 ; 4 *!*
dec DURATION ; 99D: C6 08 ; 5
bne label18 ; 99F: D0 0D ; 4 *!*
bvc label19 ; 9A1: 50 03 ; 4 *!*
bit $C030 ; 9A3: 2C 30C0 ; 4 SPEAKER
label19:
pha ; 9A6: 48 ; 3
txa ; 9A7: 8A ; 2
pha ; 9A8: 48 ; 3
tya ; 9A9: 98 ; 2
pha ; 9AA: 48 ; 3
jmp triplet_loop ; 9AB: 4C 1509 ; 3
label18:
dex ; 9AE: CA ; 2
bne selfmodify4 ; 9AF: D0 02 ; 4 *!*
beq label21 ; 9B1: F0 06 ; 4 *!*
selfmodify4:
cpx #$00 ; 9B3: E0 00 ; 2
beq selfmodify3 ; 9B5: F0 04 ; 4 *!* !!!
bne label23 ; 9B7: D0 04 ; 4 *!*
label21:
ldx FREQ2 ; 9B9: A6 07 ; 3 *!*
selfmodify3:
eor #$80 ; 9BB: 49 80 ; 2 *!* !!!
label23:
bvs label99 ; 9BD: 70 A3 ; 4 *!*
nop ; 9BF: EA ; 2
bvc label8 ; 9C0: 50 A3 ; 4 *!*
exit_keypress:
inc duet_done
rts
duet_done:
.byte $00

Binary file not shown.

View File

@ -0,0 +1,654 @@
'
' TITLE: Peasant's Quest Theme
' AUTHOR: (tracked by) Vince Weaver <vince@deater.net>
' COMMENTS: based on MIDI found online
'
' LOOP: 640
'
' BPM: 250
' TEMPO: 6
' FREQ: 1000000
' IRQ: 50
'
' LYRICS: 0
'
' ENDHEADER
-------
' 0
0 C 2 3 ----- -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- ----- -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- ----- -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C C 2 3 ----- -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 C 2 3 ----- -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 C 2 3 ----- -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
18 C 2 3 ----- -----
19 ----- ----- -----
1A ----- ----- -----
1B ----- ----- -----
1C ----- ----- -----
1D ----- ----- -----
1E ----- ----- -----
1F ----- ----- -----
20 ----- ----- -----
21 ----- ----- -----
22 ----- ----- -----
23 ----- ----- -----
24 C 2 3 ----- -----
25 ----- ----- -----
26 ----- ----- -----
27 ----- ----- -----
28 C 2 3 ----- -----
29 ----- ----- -----
2A ----- ----- -----
2B ----- ----- -----
2C C 2 3 ----- -----
2D ----- ----- -----
2E ----- ----- -----
2F ----- ----- -----
' 0 again
0 C 2 3 ----- -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- ----- -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- ----- -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C C 2 3 ----- -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 C 2 3 ----- -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 C 2 3 ----- -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
18 C 2 3 ----- -----
19 ----- ----- -----
1A ----- ----- -----
1B ----- ----- -----
1C ----- ----- -----
1D ----- ----- -----
1E ----- ----- -----
1F ----- ----- -----
20 ----- ----- -----
21 ----- ----- -----
22 ----- ----- -----
23 ----- ----- -----
24 C 2 3 ----- -----
25 ----- ----- -----
26 ----- ----- -----
27 ----- ----- -----
28 C 2 3 ----- -----
29 ----- ----- -----
2A ----- ----- -----
2B ----- ----- -----
2C C 2 3 ----- -----
2D ----- ----- -----
2E ----- ----- -----
2F ----- ----- -----
' 1
0 F 2 3 ----- -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- ----- -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- ----- -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C F 2 3 ----- -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 F 2 3 ----- -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 F 2 3 ----- -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
18 F 2 3 ----- -----
19 ----- ----- -----
1A ----- ----- -----
1B ----- ----- -----
1C ----- ----- -----
1D ----- ----- -----
1E ----- ----- -----
1F ----- ----- -----
20 ----- ----- -----
21 ----- ----- -----
22 ----- ----- -----
23 ----- ----- -----
24 F 2 3 ----- -----
25 ----- ----- -----
26 ----- ----- -----
27 ----- ----- -----
28 F 2 3 ----- -----
29 ----- ----- -----
2A ----- ----- -----
2B ----- ----- -----
2C F 2 3 ----- -----
2D ----- ----- -----
2E ----- ----- -----
2F ----- ----- -----
' 2
0 G 2 3 ----- -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- ----- -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- ----- -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C G 2 3 ----- -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 G 2 3 ----- -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 G 2 3 ----- -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
18 G 2 3 ----- -----
19 ----- ----- -----
1A ----- ----- -----
1B ----- ----- -----
1C ----- ----- -----
1D ----- ----- -----
1E ----- ----- -----
1F ----- ----- -----
20 ----- ----- -----
21 ----- ----- -----
22 ----- ----- -----
23 ----- ----- -----
24 G 2 3 ----- -----
25 ----- ----- -----
26 ----- ----- -----
27 ----- ----- -----
28 G 2 3 ----- -----
29 ----- ----- -----
2A ----- ----- -----
2B ----- ----- -----
2C G 2 3 ----- -----
2D ----- ----- -----
2E ----- ----- -----
2F ----- ----- -----
' 3
0 C 2 3 C 4 4 -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- C 4 4 -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- C 4 4 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C C 2 3 C 4 4 -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 C 2 3 C 4 4 -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 C 2 3 C 4 4 -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
18 C 2 3 ----- -----
19 ----- ----- -----
1A ----- ----- -----
1B ----- ----- -----
1C ----- ----- -----
1D ----- ----- -----
1E ----- ----- -----
1F ----- ----- -----
20 ----- ----- -----
21 ----- ----- -----
22 ----- ----- -----
23 ----- ----- -----
24 C 2 3 ----- -----
25 ----- ----- -----
26 ----- ----- -----
27 ----- ----- -----
28 C 2 3 ----- -----
29 ----- ----- -----
2A ----- ----- -----
2B ----- ----- -----
2C C 2 3 ----- -----
2D ----- ----- -----
2E ----- ----- -----
2F ----- ----- -----
' 4
0 C 2 3 ----- -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- ----- -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- G 4 3 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C C 2 3 G 4 4 -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 C 2 3 G 4 3 -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 C 2 3 F 4 3 -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
18 C 2 3 F 4 4 -----
19 ----- ----- -----
1A ----- ----- -----
1B ----- ----- -----
1C ----- F 4 3 -----
1D ----- ----- -----
1E ----- ----- -----
1F ----- ----- -----
20 ----- E 4 3 -----
21 ----- ----- -----
22 ----- ----- -----
23 ----- ----- -----
24 C 2 3 E 4 4 -----
25 ----- ----- -----
26 ----- ----- -----
27 ----- ----- -----
28 C 2 3 E 4 3 -----
29 ----- ----- -----
2A ----- ----- -----
2B ----- ----- -----
2C C 2 3 F 4 3 -----
2D ----- ----- -----
2E ----- ----- -----
2F ----- ----- -----
' 5
0 F 2 3 C 4 4 -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- C 4 4 -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- C 4 4 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C F 2 3 C 4 4 -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 F 2 3 C 4 4 -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 F 2 3 C 4 4 -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
18 F 2 3 ----- -----
19 ----- ----- -----
1A ----- ----- -----
1B ----- ----- -----
1C ----- ----- -----
1D ----- ----- -----
1E ----- ----- -----
1F ----- ----- -----
20 ----- ----- -----
21 ----- ----- -----
22 ----- ----- -----
23 ----- ----- -----
24 F 2 3 ----- -----
25 ----- ----- -----
26 ----- ----- -----
27 ----- ----- -----
28 F 2 3 ----- -----
29 ----- ----- -----
2A ----- ----- -----
2B ----- ----- -----
2C F 2 3 ----- -----
2D ----- ----- -----
2E ----- ----- -----
2F ----- ----- -----
' 6
0 G 2 3 ----- -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- ----- -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- G 4 3 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C G 2 3 G 4 4 -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 G 2 3 G 4 3 -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 G 2 3 F 4 3 -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
18 G 2 3 F 4 4 -----
19 ----- ----- -----
1A ----- ----- -----
1B ----- ----- -----
1C ----- F 4 3 -----
1D ----- ----- -----
1E ----- ----- -----
1F ----- ----- -----
20 ----- E 4 3 -----
21 ----- ----- -----
22 ----- ----- -----
23 ----- ----- -----
24 G 2 3 E 4 4 -----
25 ----- ----- -----
26 ----- ----- -----
27 ----- ----- -----
28 G 2 3 E 4 3 -----
29 ----- ----- -----
2A ----- ----- -----
2B ----- ----- -----
2C G 2 3 F 4 3 -----
2D ----- ----- -----
2E ----- ----- -----
2F ----- ----- -----
' 7
0 C 2 3 D 4 3 -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- D 4 6 -----
4 ----- D 4 8 -----
5 ----- ----- -----
6 ----- D 4 3 -----
7 ----- ----- -----
8 ----- ----- -----
9 ----- D 4 3 -----
A ----- ----- -----
B ----- ----- -----
C C 2 3 A#4 4 -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 C 2 3 A#4 4 -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 C 2 3 A#4 3 -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
18 C 2 3 D 4 3 -----
19 ----- ----- -----
1A ----- ----- -----
1B ----- D 4 6 -----
1C ----- D 4 8 -----
1D ----- ----- -----
1E ----- D 4 4 -----
1F ----- ----- -----
20 ----- ----- -----
21 ----- ----- -----
22 ----- D 4 8 -----
23 ----- ----- -----
24 C 2 3 G 4 4 -----
25 ----- ----- -----
26 ----- ----- -----
27 ----- ----- -----
28 C 2 3 G 4 4 -----
29 ----- ----- -----
2A ----- ----- -----
2B ----- ----- -----
2C C 2 3 G 4 3 -----
2D ----- ----- -----
2E ----- ----- -----
2F ----- ----- -----
' 8
0 C 2 3 D 4 3 -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- D 4 6 -----
4 ----- D 4 8 -----
5 ----- ----- -----
6 ----- D 4 8 -----
7 ----- ----- -----
8 ----- D 4 4 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C C 2 3 A#4 4 -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 C 2 3 A#4 8 -----
11 ----- ----- -----
12 ----- D 4 4 -----
13 ----- ----- -----
14 C 2 3 ----- -----
15 ----- ----- -----
16 ----- D 4 8 -----
17 ----- ----- -----
18 C 2 3 G 4 4 -----
19 ----- ----- -----
1A ----- ----- -----
1B ----- ----- -----
1C ----- G 4 8 -----
1D ----- ----- -----
1E ----- D 4 4 -----
1F ----- ----- -----
20 ----- ----- -----
21 ----- ----- -----
22 ----- D 4 8 -----
23 ----- ----- -----
24 C 2 3 F 4 4 -----
25 ----- ----- -----
26 ----- ----- -----
27 ----- ----- -----
28 C 2 3 F 4 8 -----
29 ----- ----- -----
2A ----- G 4 4 -----
2B ----- ----- -----
2C C 2 3 ----- -----
2D ----- ----- -----
2E ----- G 4 8 -----
2F ----- ----- -----
' 5
0 F 2 3 C 4 4 -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- C 4 4 -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- C 4 4 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C F 2 3 C 4 4 -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 F 2 3 C 4 4 -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 F 2 3 C 4 4 -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
18 F 2 3 ----- -----
19 ----- ----- -----
1A ----- ----- -----
1B ----- ----- -----
1C ----- ----- -----
1D ----- ----- -----
1E ----- ----- -----
1F ----- ----- -----
20 ----- ----- -----
21 ----- ----- -----
22 ----- ----- -----
23 ----- ----- -----
24 F 2 3 ----- -----
25 ----- ----- -----
26 ----- ----- -----
27 ----- ----- -----
28 F 2 3 ----- -----
29 ----- ----- -----
2A ----- ----- -----
2B ----- ----- -----
2C F 2 3 ----- -----
2D ----- ----- -----
2E ----- ----- -----
2F ----- ----- -----
' 6
0 G 2 3 ----- -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- ----- -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- G 4 3 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C G 2 3 G 4 4 -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 G 2 3 G 4 3 -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 G 2 3 F 4 3 -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
18 G 2 3 F 4 4 -----
19 ----- ----- -----
1A ----- ----- -----
1B ----- ----- -----
1C ----- F 4 3 -----
1D ----- ----- -----
1E ----- ----- -----
1F ----- ----- -----
20 ----- E 4 3 -----
21 ----- ----- -----
22 ----- ----- -----
23 ----- ----- -----
24 G 2 3 E 4 4 -----
25 ----- ----- -----
26 ----- ----- -----
27 ----- ----- -----
28 G 2 3 E 4 3 -----
29 ----- ----- -----
2A ----- ----- -----
2B ----- ----- -----
2C G 2 3 F 4 3 -----
2D ----- ----- -----
2E ----- ----- -----
2F ----- ----- -----
' 9
0 C 2 3 G 4 4 -----
1 ----- ----- -----
2 ----- ----- -----
3 ----- ----- -----
4 ----- G 4 4 -----
5 ----- ----- -----
6 ----- ----- -----
7 ----- ----- -----
8 ----- G 4 3 -----
9 ----- ----- -----
A ----- ----- -----
B ----- ----- -----
C C 2 3 ----- -----
D ----- ----- -----
E ----- ----- -----
F ----- ----- -----
10 C 2 3 ----- -----
11 ----- ----- -----
12 ----- ----- -----
13 ----- ----- -----
14 C 2 3 ----- -----
15 ----- ----- -----
16 ----- ----- -----
17 ----- ----- -----
18 C 2 3 ----- -----
19 ----- ----- -----
1A ----- ----- -----
1B ----- ----- -----
1C ----- ----- -----
1D ----- ----- -----
1E ----- ----- -----
1F ----- ----- -----
20 ----- ----- -----
21 ----- ----- -----
22 ----- ----- -----
23 ----- ----- -----
24 C 2 3 ----- -----
25 ----- ----- -----
26 ----- ----- -----
27 ----- ----- -----
28 C 2 3 ----- -----
29 ----- ----- -----
2A ----- ----- -----
2B ----- ----- -----
2C C 2 3 ----- -----
2D ----- ----- -----
2E ----- ----- -----
2F ----- ----- -----
' LOOP TO FRAME 8

38
games/peasant/talk/notes Normal file
View File

@ -0,0 +1,38 @@
Demakes
HGr-MIST
HGR
(horrible hgr)
Backgrounds
AGI-like? They abandoned it. Would save space
Sprites
easier in blocks 0f 7
still have to rotate 1 pixel for odd columns
transparency a pain with color clash
Animations
too big?
Mini-games?
Text
HGR drawing lib (no built in on 2)
How to fit? Lookup for common word distribution?
Ram-map
Music
Mockingboard, pt3 player
no mockingboard, electric duet, but can't do more than
page flip (missing flame). Worth it?
Speech
Can we do SAM? 9k?
SSI-263 but unobtanium
Disks:
Fitting on disk.
swappign fun for nostalgia, not so much when actually playing

View File

@ -18,83 +18,8 @@ title:
jsr hgr_make_tables
;========================
; Music
;========================
;===================================
; Setup Mockingboard
;===================================
PT3_ENABLE_APPLE_IIC = 1
lda SOUND_STATUS
and #SOUND_MOCKINGBOARD
beq mockingboard_notfound
;==================================
; load music into the language card
; into $D000 set 2
;==================================
; switch in language card
; read/write RAM, $d000 bank 2
lda $C083
lda $C083
; lda $C081 ; enable ROM
; lda $C081 ; enable write
; actually load it
lda #LOAD_MUSIC
sta WHICH_LOAD
jsr load_file
lda #0
sta DONE_PLAYING
lda #1
sta LOOP
jsr mockingboard_patch ; patch to work in slots other than 4?
;=======================
; Set up 50Hz interrupt
;========================
jsr mockingboard_init
jsr mockingboard_setup_interrupt
zurg:
;============================
; Init the Mockingboard
;============================
jsr reset_ay_both
jsr clear_ay_both
;==================
; init song
;==================
jsr pt3_init_song
;=======================
; start music
;=======================
cli
mockingboard_notfound:
;=========================
;=========================
@ -135,8 +60,112 @@ do_title:
bit KEYRESET
lda SOUND_STATUS
and #SOUND_MOCKINGBOARD
beq mockingboard_notfound
jsr mockingboard_loop
jmp title_loop_done
mockingboard_notfound:
jsr duet_loop
title_loop_done:
;************************
; Tips
;************************
jsr directions
lda #LOAD_INTRO
sta WHICH_LOAD
rts
;=====================
; main loop
;=====================
; mockingboard loop
;=====================
;=====================
mockingboard_loop:
;===================================
; Setup Mockingboard
;===================================
PT3_ENABLE_APPLE_IIC = 1
;==================================
; load music into the language card
; into $D000 set 2
;==================================
; switch in language card
; read/write RAM, $d000 bank 2
lda $C083
lda $C083
; lda $C081 ; enable ROM
; lda $C081 ; enable write
; actually load it
lda #LOAD_MUSIC
sta WHICH_LOAD
jsr load_file
lda #0
sta DONE_PLAYING
lda #1
sta LOOP
jsr mockingboard_patch ; patch to work in slots other than 4?
;=======================
; Set up 50Hz interrupt
;========================
jsr mockingboard_init
jsr mockingboard_setup_interrupt
zurg:
;============================
; Init the Mockingboard
;============================
jsr reset_ay_both
jsr clear_ay_both
;==================
; init song
;==================
jsr pt3_init_song
;=======================
; start music
;=======================
cli
; we're supposed to animate flame, flash the "CLICK ANYWHERE" sign
; and show trogdor when his music plays
@ -221,34 +250,57 @@ altfire_good:
bit PAGE2 ; return to viewing PAGE2
;==============================
; disable music, if applicable
lda SOUND_STATUS
and #SOUND_MOCKINGBOARD
beq mockingboard_notfound2
;==============
; disable music
sei ; disable music
jsr clear_ay_both
mockingboard_notfound2:
;************************
; Tips
;************************
jsr directions
lda #LOAD_INTRO
sta WHICH_LOAD
rts
;=====================
;=====================
; Electric Duet Loop
;=====================
;=====================
duet_loop:
lda #<peasant_ed
sta MADDRL
lda #>peasant_ed
sta MADDRH
duet_loop_again:
jsr play_ed
lda #1
sta peasant_ed+24
lda #0
sta peasant_ed+25
sta peasant_ed+26
lda #<(peasant_ed+24)
sta MADDRL
lda #>(peasant_ed+24)
sta MADDRH
lda duet_done
beq duet_loop_again
duet_finished:
bit KEYRESET
rts
;.include "decompress_fast_v2.s"
.include "wait_keypress.s"
@ -256,9 +308,13 @@ mockingboard_notfound2:
;.include "hgr_font.s"
;.include "hgr_tables.s"
;.include "hgr_hgr2.s"
.include "duet.s"
peasant_ed:
.incbin "music/peasant.ed"
.include "pt3_lib_mockingboard_patch.s"
.include "graphics_title/title_graphics.inc"

View File

@ -33,7 +33,7 @@ intro_text:
lda #>boot_message
sta OUTH
ldx #7
ldx #8
text_loop:
jsr move_and_print
@ -442,6 +442,7 @@ boot_message:
.byte 0,5,"APPLE II PORT: VINCE WEAVER",0
.byte 0,6,"DISK CODE : QKUMBA",0
.byte 0,7,"LZSA CODE : EMMANUEL MARTY",0
.byte 0,8,"ELECTRIC DUET: PAUL LUTUS",0
.byte 7,19,"______",0
.byte 5,20,"A \/\/\/ SOFTWARE PRODUCTION",0

View File

@ -18,6 +18,18 @@ TEMP3 = $13
TEMP4 = $14
TEMP5 = $15
; electric duet
FREQ1 = $10
FREQ2 = $11
DURATION = $12
INSTRUMENT1 = $13
INSTRUMENT2 = $14
MADDRL = $15
MADDRH = $16
LOC4E = $4E
COUNT256 = $4F
HGR_BITS = $1C
CH = $24

File diff suppressed because it is too large Load Diff

313
music/electric_duet/notes.c Normal file
View File

@ -0,0 +1,313 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#define TWELTH_TWO 1.059463094359
// http://www.phy.mtu.edu/~suits/NoteFreqCalcs.html
double note_to_freq(char note, int flat, int sharp, int octave, double sub) {
double freq=0.0;
double step=0;
switch(note) {
case 'B': step= 2; break;
case 'A': step= 0; break;
case 'G': step=-2; break;
case 'F': step=-4; break;
case 'E': step=-5; break;
case 'D': step=-7; break;
case 'C': step=-9; break;
default:
fprintf(stderr,"Unknown note %c\n",note);
}
if (flat) step+=flat;
if (sharp) step-=sharp;
step-=(4-octave)*12;
step+=sub/16.0;
freq=440.0*pow(TWELTH_TWO,step);
return freq;
}
/* https://sourceforge.net/p/ed2midi/code/ */
/* From a spreadsheet from ed2midi */
/* Ugh, ym5 changes octave on C, but looks like ED does at A */
/* Octave 1 2 3 4 5
A 255 128 64 32 16
A#/B- 240 120 60 30 15
B 228 114 57 28 14
C 216 108 54 27 13
C#/D- 204 102 51 25 12
D 192 96 48 24 12
D#/E- 180 90 45 22 11
E 172 86 43 21 10
F 160 80 40 20 10
F#/G- 152 76 38 19 9
G 144 72 36 18 9
G#/A- 136 68 34 17 8 */
/* Octave 1 2 3 4 5 6
C 216 108 54 27 13
C#/D- 204 102 51 25 12
D 192 96 48 24 12
D#/E- 180 90 45 22 11
E 172 86 43 21 10
F 160 80 40 20 10
F#/G- 152 76 38 19 9
G 144 72 36 18 9
G#/A- 136 68 34 17 8
A 255 128 64 32 16
A#/B- 240 120 60 30 15
B 228 114 57 28 14
*/
/* Octave 1 2 3 4 5 6
C 216 108 54 27 13
C#/D- 204 102 51 25 12
D 192 96 48 24 12
D#/E- 180 90 45 22 11
E 172 86 43 21 10
F 160 80 40 20 10
F#/G- 152 76 38 19 9
G 144 72 36 18 9
G#/A- 136 68 34 17 8
A 255 128 64 32 16 8
A#/B- 240 120 60 30 15 8
B 228 114 57 28 14 7
*/
static unsigned char ed_freqs[]={
/* A A# B C C# D D# E F F# G G# */
255,240,228,216,204,192,180,172,160,152,144,136,
128,120,114,108,102,96, 90, 86, 80, 76, 72, 68,
64, 60, 57, 54, 51, 48, 45, 43, 40, 38, 36, 34,
32, 30, 28, 27, 25, 24, 22, 21, 20, 19, 18, 17,
16, 15, 14, 13, 12, 12, 11, 10, 10, 9, 9, 8,
8, 8, 7};
/* c1 c1
d1 d1
e1 e1
f1 f1
g1 g1
a1 a2
b1 b2
c2 c2
*/
int note_to_ed(char note, int flat, int sharp, int octave) {
int offset;
switch(note) {
case 'A': offset=12; break;
case 'B': offset=14; break;
case 'C': offset=3; break;
case 'D': offset=5; break;
case 'E': offset=7; break;
case 'F': offset=8; break;
case 'G': offset=10; break;
default:
fprintf(stderr,"Unknown note %c\n",note);
return -1;
}
if (flat==1) offset--;
if (sharp==1) offset++;
if (sharp==2) offset+=2;
offset+=((octave-1)*12);
if (offset>63) {
fprintf(stderr,"Out of range offset %d\n",offset);
return 7;
}
if (offset<0) {
fprintf(stderr,"Out of range offset %d\n",offset);
return 255;
}
return ed_freqs[offset];
}
static struct note_mapping_type {
int actual;
int low;
int high;
} note_mapping[10][12]={
{ /* Octave 0 */
{ 16, 16, 16, }, // "C 0"
{ 17, 17, 17, }, // "C#0"
{ 18, 18, 18, }, // "D 0"
{ 19, 19, 19, }, // "D#0"
{ 20, 20, 21, }, // "E 0"
{ 21, 21, 22, }, // "F 0"
{ 23, 22, 23, }, // "F#0"
{ 24, 24, 25, }, // "G 0"
{ 26, 25, 26, }, // "G#0"
{ 27, 27, 28, }, // "A 0"
{ 29, 28, 29, }, // "A#0"
{ 30, 30, 31, }, // "B 0"
},
{ /* Octave 1 */
{ 32, 32, 33, }, // "C 1"
{ 34, 34, 35, }, // "C#1"
{ 36, 36, 37, }, // "D 1"
{ 38, 38, 39, }, // "D#1"
{ 41, 40, 41, }, // "E 1"
{ 43, 43, 44, }, // "F 1"
{ 46, 45, 46, }, // "F#1"
{ 49, 48, 49, }, // "G 1"
{ 51, 51, 52, }, // "G#1"
{ 55, 54, 55, }, // "A 1"
{ 58, 57, 58, }, // "A#1"
{ 61, 61, 62, }, // "B 1"
},
{ /* Octave 2 */
{ 65, 64, 65, }, // "C 2"
{ 69, 68, 69, }, // "C#2"
{ 73, 72, 73, }, // "D 2"
{ 77, 77, 78, }, // "D#2"
{ 82, 81, 82, }, // "E 2"
{ 87, 86, 87, }, // "F 2"
{ 92, 92, 93, }, // "F#2"
{ 98, 97, 98, }, // "G 2"
{ 103, 103, 104, }, // "G#2"
{ 110, 109, 110, }, // "A 2"
{ 116, 116, 117, }, // "A#2"
{ 123, 123, 124, }, // "B 2"
},
{ /* Octave 3 */
{ 130, 129, 131, }, // "C 3"
{ 138, 137, 139, }, // "C#3"
{ 146, 145, 147, }, // "D 3"
{ 155, 154, 156, }, // "D#3"
{ 164, 163, 165, }, // "E 3"
{ 174, 173, 175, }, // "F 3"
{ 185, 184, 186, }, // "F#3"
{ 196, 195, 198, }, // "G 3"
{ 207, 206, 209, }, // "G#3"
{ 220, 119, 222, }, // "A 3"
{ 233, 232, 235, }, // "A#3"
{ 246, 245, 248, }, // "B 3"
},
{ /* Octave 4 */
{ 261, 256, 266, }, // "C 4"
{ 277, 272, 282, }, // "C#4"
{ 293, 288, 298, }, // "D 4"
{ 311, 306, 316, }, // "D#4"
{ 329, 324, 334, }, // "E 4"
{ 349, 344, 354, }, // "F 4"
{ 370, 365, 375, }, // "F#4"
{ 392, 387, 397, }, // "G 4"
{ 415, 410, 420, }, // "G#4"
{ 440, 435, 445, }, // "A 4"
{ 466, 461, 471, }, // "A#4"
{ 493, 488, 498, }, // "B 4"
},
{ /* Octave 5 */
{ 523, 513, 533, }, // "C 5"
{ 554, 544, 564, }, // "C#5"
{ 587, 577, 597, }, // "D 5"
{ 622, 612, 632, }, // "D#5"
{ 659, 649, 669, }, // "E 5"
{ 698, 688, 708, }, // "F 5"
{ 740, 730, 750, }, // "F#5"
{ 784, 774, 794, }, // "G 5"
{ 830, 820, 840, }, // "G#5"
{ 880, 870, 890, }, // "A 5"
{ 932, 922, 942, }, // "A#5"
{ 987, 977, 997, }, // "B 5"
},
{ /* Octave 6 */
{ 1046, 1026, 1066, }, // "C 6"
{ 1108, 1088, 1128, }, // "C#6"
{ 1174, 1154, 1194, }, // "D 6"
{ 1244, 1224, 1264, }, // "D#6"
{ 1318, 1298, 1338, }, // "E 6"
{ 1396, 1376, 1416, }, // "F 6"
{ 1480, 1460, 1500, }, // "F#6"
{ 1568, 1548, 1588, }, // "G 6"
{ 1661, 1641, 1681, }, // "G#6"
{ 1760, 1740, 1780, }, // "A 6"
{ 1864, 1844, 1884, }, // "A#6"
{ 1975, 1955, 1995, }, // "B 6"
},
{ /* Octave 7 */
{ 2093, 2063, 2123, }, // "C 7"
{ 2217, 2187, 2247, }, // "C#7"
{ 2349, 2319, 2379, }, // "D 7"
{ 2489, 2459, 2519, }, // "D#7"
{ 2637, 2607, 2667, }, // "E 7"
{ 2793, 2763, 2823, }, // "F 7"
{ 2960, 2930, 2990, }, // "F#7"
{ 3136, 3106, 3166, }, // "G 7"
{ 3322, 3292, 3352, }, // "G#7"
{ 3520, 3490, 3550, }, // "A 7"
{ 3729, 3699, 3759, }, // "A#7"
{ 3951, 3921, 3981, }, // "B 7"
},
{ /* Octave 8 */
{ 4186, 4146, 4226, }, // "C 8
{ 4434, 4394, 4474, }, // "C#8
{ 4698, 4658, 5738, }, // "D 8
{ 4978, 4938, 5018, }, // "D#8
{ 5274, 5234, 5314, }, // "E 8
{ 5587, 5547, 5627, }, // "F 8
{ 5919, 5879, 5959, }, // "F#8
{ 6271, 6231, 6311, }, // "G 8
{ 6644, 6604, 6684, }, // "G#8
{ 7040, 7000, 7080, }, // "A 8
{ 7458, 7418, 7498, }, // "A#8
{ 7902, 7862, 7942, }, // "B 8
},
{ /* Octave 9 */
{ 8372, 8322, 8422, }, // "C 9
{ 8869, 8819, 8919, }, // "C#9
{ 9397, 9347, 9447, }, // "D 9
{ 9956, 9906, 10006, }, // "D#9
{ 10548, 10498, 10598, }, // "E 9
{ 11175, 11125, 11225, }, // "F 9
{ 11839, 11789, 11889, }, // "F#9
{ 12543, 12493, 12593, }, // "G 9
{ 13289, 13239, 13339, }, // "G#9
{ 14080, 14030, 14130, }, // "A 9
{ 14917, 14867, 14967, }, // "A#9
{ 15804, 15754, 15854, }, // "B 9
},
};
int freq_to_note(int f) {
int octave=0,note=0;
int i,j;
for(i=0;i<10;i++) {
if ((f>=note_mapping[i][0].low)&&(f<=note_mapping[i][11].high)) {
octave=i;
for(j=0;j<12;j++) {
if ((f>=note_mapping[i][j].low)&&(f<=note_mapping[i][j].high)) {
note=j;
}
}
break;
}
}
// printf("Found Octave %d note %d\n",octave,note);
return (octave*12)+note;
}

View File

@ -0,0 +1,3 @@
double note_to_freq(char note, int flat, int sharp, int octave, double sub);
int note_to_ed(char note, int flat, int sharp, int octave);
int freq_to_note(int f);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,559 @@
/* This is a two-track format to play on the simple 1-bit speaker */
/* Interface available on the Apple II */
/* https://sourceforge.net/p/ed2midi/code/ */
/* From a spreadsheet from ed2midi */
/* Octave 1 2 3 4 5
A 255 128 64 32 16
A# 240 120 60 30 15
B 228 114 57 28 14
C 216 108 54 27 13
C# 204 102 51 25 12
D 192 96 48 24 12
D# 180 90 45 22 11
E 172 86 43 21 10
F 160 80 40 20 10
F# 152 76 38 19 9
G 144 72 36 18 9
G# 136 68 34 17 8
*/
/* ed file format */
/* First byte 0: ??? (0,0,0 = exit) */
/* First byte 1: Voice */
/* byte1 = voice1 instrument */
/* byte2 = voice2 instrument */
/* Varies, bigger than 8 seem to make no difference */
/* Otherwise, byte0 = duration (20=quarter, 40=half) */
/* byte1 = voice1 note */
/* byte2 = voice2 note */
#define VERSION "1.0"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "notes.h"
static int debug=0;
static int bpm=120;
static int baselen=80;
static int frames_per_line;
static int octave_adjust=0;
static int line=0;
static int header_version=0;
static int note_to_length(int length) {
int len=1;
switch(length) {
case 0: len=(baselen*5)/2; break; // 0 = 2.5
case 1: len=baselen; break; // 1 = 1 whole
case 2: len=baselen/2; break; // 2 = 1/2 half
case 3: len=(baselen*3)/8; break; // 3 = 3/8 dotted quarter
case 4: len=baselen/4; break; // 4 = 1/4 quarter
case 5: len=(baselen*5)/8; break; // 5 = 5/8 ?
case 8: len=baselen/8; break; // 8 = 1/8 eighth
case 9: len=(baselen*3)/16; break; // 9 = 3/16 dotted eighth
case 6: len=baselen/16; break; // 6 = 1/16 sixteenth
case 10: len=(baselen*3)/4; break; // : = 3/4 dotted half
case 11: len=(baselen*9)/8; break; // ; = 9/8 dotted half + dotted quarter
case 12: len=(baselen*3)/2; break; // < = 3/2 dotted whole
case 13: len=(baselen*2); break; // = = 2 double whole
default:
fprintf(stderr,"Unknown length %d, line %d\n",
length,line);
}
return len;
}
struct note_type {
unsigned char which;
unsigned char note;
int sharp,flat;
int octave;
int len;
int enabled;
int freq;
int length;
int left;
int ed_freq;
};
static int get_note(char *string, int sp, struct note_type *n, int line) {
int freq;
int ch;
// fprintf(stderr,"VMW: Entering, sp=%d\n",sp);
/* Skip white space */
while((string[sp]==' ' || string[sp]=='\t')) sp++;
if (string[sp]=='\n') return -1;
/* return early if no change */
ch=string[sp];
// fprintf(stderr,"VMW: %d %d\n",ch,sp);
if (ch=='-') {
if (header_version==0) return sp+6;
else {
return sp+11;
}
}
/* get note info */
n->sharp=0;
n->flat=0;
n->ed_freq=0;
n->note=ch;
sp++;
if (string[sp]==' ') ;
else if (string[sp]=='#') n->sharp=1;
else if (string[sp]=='-') n->flat=1;
else if (string[sp]=='=') n->flat=2;
else {
fprintf(stderr,"Unknown note modifier %c, line %d:%d\n",
string[sp],line,sp);
fprintf(stderr,"String: %s\n",string);
}
// printf("Sharp=%d Flat=%d\n",n->sharp,n->flat);
sp++;
n->octave=string[sp]-'0';
sp++;
sp++;
n->len=string[sp]-'0';
sp++;
if (n->note!='-') {
freq=note_to_ed(n->note,n->flat,n->sharp,
n->octave+octave_adjust);
if (debug) printf("(%c) %c%c L=%d O=%d f=%d\n",
n->which,
n->note,
n->sharp?'#':' ',
n->len,
n->octave,
freq);
n->ed_freq=freq;
n->enabled=1;
n->length=note_to_length(n->len);
n->left=n->length-1;
if (n->length<=0) {
printf("Error line %d\n",line);
exit(-1);
}
}
else {
n->ed_freq=0;
}
if (header_version==2) sp+=6;
return sp;
}
static int get_string(char *string, char *key, char *output, int strip_linefeed) {
char *found;
found=strstr(string,key);
found=found+strlen(key);
/* get rid of leading whitespace */
while(1) {
if ((*found==' ') || (*found=='\t')) found++;
else break;
}
strcpy(output,found);
/* remove trailing linefeed */
if (strip_linefeed) output[strlen(output)-1]=0;
return 0;
}
static void print_help(int just_version, char *exec_name) {
printf("\ntext_to_ed version %s by Vince Weaver <vince@deater.net>\n\n",VERSION);
if (just_version) exit(0);
printf("This created Electric Duet files\n\n");
printf("Usage:\n");
printf("\t%s [-h] [-v] [-d] [-o X] [-i X] textfile outbase\n\n",
exec_name);
printf("\t-h: this help message\n");
printf("\t-v: version info\n");
printf("\t-d: print debug messages\n");
printf("\t-o: Offset octave by X\n");
printf("\t-i: set second instrument to X\n");
exit(0);
}
int main(int argc, char **argv) {
char string[BUFSIZ];
char *result;
char ed_filename[BUFSIZ],lyrics_filename[BUFSIZ],*in_filename;
char temp[BUFSIZ];
FILE *ed_file,*lyrics_file,*in_file=NULL;
//int attributes=0;
int loop=0,i;
int sp,external_frequency,irq;
struct note_type a,b,c;
int copt;
// Instruments 0=square
int voice1=0,voice2=0;
char song_name[BUFSIZ];
char author_name[BUFSIZ];
char comments[BUFSIZ];
char *comments_ptr=comments;
unsigned char sharp_char[]=" #-=";
/* Parse command line arguments */
while ((copt = getopt(argc, argv, "dhvo:i:"))!=-1) {
switch (copt) {
case 'd':
/* Debug messages */
printf("Debug enabled\n");
debug=1;
break;
case 'h':
/* help */
print_help(0,argv[0]);
break;
case 'v':
/* version */
print_help(1,argv[0]);
break;
case 'o':
/* octave offset */
octave_adjust=atoi(optarg);
break;
case 'i':
/* instrument to use */
voice1=atoi(optarg);
break;
default:
print_help(0,argv[0]);
break;
}
}
if (argv[optind]!=NULL) {
/* Open the input file */
if (argv[optind][0]=='-') {
in_file=stdin;
}
else {
in_filename=strdup(argv[optind]);
in_file=fopen(in_filename,"r");
if (in_file==NULL) {
fprintf(stderr,"Couldn't open %s\n",in_filename);
return -1;
}
}
}
if (optind+1>=argc) {
fprintf(stderr,"Error, need outfile\n");
exit(0);
}
/* Open the output/lyrics files */
sprintf(ed_filename,"%s.ed",argv[optind+1]);
sprintf(lyrics_filename,"%s.edlyrics",argv[optind+1]);
ed_file=fopen(ed_filename,"w");
if (ed_file==NULL) {
fprintf(stderr,"Couldn't open %s\n",ed_filename);
return -1;
}
lyrics_file=fopen(lyrics_filename,"w");
if (lyrics_file==NULL) {
fprintf(stderr,"Couldn't open %s\n",lyrics_filename);
return -1;
}
/* Get the info for the header */
while(1) {
result=fgets(string,BUFSIZ,in_file);
if (result==NULL) break;
line++;
if (strstr(string,"ENDHEADER")) break;
if (strstr(string,"HEADER:")) {
get_string(string,"HEADER:",temp,1);
header_version=atoi(temp);
printf("Found header version %d\n",header_version);
}
if (strstr(string,"TITLE:")) {
get_string(string,"TITLE:",song_name,1);
}
if (strstr(string,"AUTHOR:")) {
get_string(string,"AUTHOR:",author_name,1);
}
if (strstr(string,"COMMENTS:")) {
get_string(string,"COMMENTS:",comments_ptr,0);
comments_ptr=&comments[strlen(comments)];
}
if (strstr(string,"BPM:")) {
get_string(string,"BPM:",temp,1);
bpm=atoi(temp);
}
if (strstr(string,"FREQ:")) {
get_string(string,"FREQ:",temp,1);
external_frequency=atoi(temp);
}
if (strstr(string,"IRQ:")) {
get_string(string,"IRQ:",temp,1);
irq=atoi(temp);
}
if (strstr(string,"LOOP:")) {
get_string(string,"LOOP:",temp,1);
loop=atoi(temp);
}
}
if (bpm==115) {
baselen=80;
}
else if (bpm==120) { // 2Hz, 500ms, 80x=500, x=6.25, should be 80
baselen=120;
}
else if (bpm==136) { // 2.3Hz, 440ms, should be 70
baselen=70;
}
else if (bpm==160) {// 2.66Hz, 375ms, should be 60
baselen=60;
}
else if (bpm==250) {
baselen=50; // eyeballed
}
else {
fprintf(stderr,"Warning! Unusual BPM of %d\n",bpm);
baselen=80;
}
frames_per_line=baselen/16;
a.which='A'; b.which='B'; c.which='C';
int first=1;
int a_last=0,b_last=0,same_count=0;
int a_len=0,b_len=0,a_freq=0,b_freq=0;
int frame=0,lyric=0;
int lyric_line=1;
fprintf(ed_file,"%c%c%c",1,voice1,voice2);
while(1) {
result=fgets(string,BUFSIZ,in_file);
if (result==NULL) break;
line++;
a.ed_freq=0;
b.ed_freq=0;
a.length=0;
b.length=0;
/* skip comments */
if (string[0]=='\'') continue;
if (string[0]=='-') continue;
if (string[0]=='*') continue;
sp=0;
/* Skip line number */
while((string[sp]!=' ' && string[sp]!='\t')) sp++;
sp=get_note(string,sp,&a,line);
if (sp!=-1) sp=get_note(string,sp,&b,line);
if (sp!=-1) sp=get_note(string,sp,&c,line);
/* handle lyrics */
if ((sp!=-1) && (string[sp]!='\n') && (string[sp]!=0)) {
fprintf(lyrics_file,"; %d: %s",frame,&string[sp]);
while((string[sp]==' ' || string[sp]=='\t')) sp++;
if (string[sp]!='\n') {
fprintf(lyrics_file,".byte\t$%02X",lyric_line&0xff);
/* get to first quote */
while(string[sp]!='\"') sp++;
sp++;
/* stop at second quote */
while(string[sp]!='\"') {
if (string[sp]=='\\') {
sp++;
/* Ignore if we have LED panel */
if (string[sp]=='i') {
//printf(",$%02X",10);
}
/* form feed */
else if (string[sp]=='f') {
fprintf(lyrics_file,",$%02X",12);
}
/* Vertical tab */
else if (string[sp]=='v') {
fprintf(lyrics_file,",$%02X",11);
}
else if (string[sp]=='n') {
fprintf(lyrics_file,",$%02X",13|0x80);
}
else if ((string[sp]>='0') &&
(string[sp]<=':')) {
fprintf(lyrics_file,",$%02X",string[sp]-'0');
}
else {
printf("UNKNOWN ESCAPE %d\n",string[sp]);
}
sp++;
continue;
}
fprintf(lyrics_file,",$%02X",string[sp]|0x80);
sp++;
}
fprintf(lyrics_file,",$00\n");
// fprintf(lyrics_file," %s",&string[sp]);
// printf("%s",&string[sp]);
}
lyric=1;
}
if ((a.ed_freq!=0)||(b.ed_freq!=0)) {
if (debug) {
printf("%d: ",frame);
printf("%c%c%d %d (%d,%d) |%d %d %d %c|\t",
a.note,sharp_char[a.sharp+2*a.flat],a.octave,
a.len,a.ed_freq,a.length,
a.sharp,a.flat,a.sharp+2*a.flat,
sharp_char[2]);
printf("%c%c%d %d (%d,%d)\n",
b.note,sharp_char[b.sharp+2*b.flat],b.octave,
b.len,b.ed_freq,b.length);
}
}
if (a.length) a_len=a.length;
if (b.length) b_len=b.length;
if (a.ed_freq) {
a_freq=a.ed_freq;
}
if (b.ed_freq) {
b_freq=b.ed_freq;
}
if (first) {
a_last=a_freq;
b_last=b_freq;
first=0;
}
for(i=0;i<frames_per_line;i++) {
if ( (a_len==0) || (b_len==0) ) {
// fprintf(ed_file,"%c%c%c",same_count*(baselen/16),a_last,b_last);
// printf("*** %x %x %x\n",same_count*(baselen/16),a_last,b_last);
if (a_len==0) {
a_freq=0;
// printf("A hit zero\n");
}
if (b_len==0) {
b_freq=0;
// printf("B hit zero\n");
}
// same_count=0;
}
else {
// printf("%d\n",a_len);
}
if ((a_freq!=a_last) ||
(b_freq!=b_last) ||
(lyric) ||
(same_count>250)) {
/* Avoid changing instrument by accident */
/* Also keep lyrics in sync */
if (same_count<2) {
same_count=2;
}
lyric_line++;
fprintf(ed_file,"%c%c%c",same_count,a_last,b_last);
if (debug) {
printf("*** %x %x %x\n",same_count,a_last,b_last);
}
same_count=0;
}
same_count++;
if (a_len) a_len--;
if (b_len) b_len--;
a_last=a_freq;
b_last=b_freq;
lyric=0;
}
frame++;
}
if (same_count==1) same_count++;
fprintf(ed_file,"%c%c%c",same_count,a_last,b_last);
fprintf(ed_file,"%c%c%c",0,0,0); // EOF?
fclose(ed_file);
fclose(lyrics_file);
(void) irq;
(void) loop;
(void) external_frequency;
return 0;
}