3D界面 可选择音调 上上周学校课程写的 我用的是masm for windows集成编译环境 写的比较粗糙 代码中提供了A-G调的频率值,但程序只用了C和F,有兴趣可以自己扩展 放上来就算抛砖引玉吧
;-----------------------------------------
;画横线
;-------------------------------------------
DRAWLINE0 MACRO START_X,START_Y,END_X,COLOR
LOCAL PAINT
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,0CH
MOV AL,COLOR
MOV BX,0
MOV CX,START_X
MOV DX,START_Y
PAINT:
INT 10H
INC CX
CMP CX,END_X
JC PAINT
POP DX
POP CX
POP BX
POP AX
ENDM
;------------------------------------------------
;画竖线
;-----------------------------------------------
DRAWLINE1 MACRO START_X,START_Y,END_Y,COLOR
LOCAL PAINT
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,0CH
MOV AL,COLOR
MOV BX,0
MOV CX,START_X
MOV DX,START_Y
PAINT:
INT 10H
INC DX
CMP DX,END_Y
JC PAINT
POP DX
POP CX
POP BX
POP AX
ENDM
;----------------------------------------------
;画斜线 向右倾斜
;----------------------------------------------
DRAWOBILQUE MACRO START_X,START_Y,END_X,COLOR
LOCAL PAINT2
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,0CH
MOV AL,COLOR
MOV BX,0
MOV DX,START_Y
MOV CX,START_X
PAINT2:
INT 10H
DEC CX
INC DX
CMP CX,END_X
JA PAINT2
POP DX
POP CX
POP BX
POP AX
ENDM
;-------------------------------------------
;画填充矩形
;-------------------------------------------
DRAW MACRO START_X,START_Y,END_X,END_Y,COLOR
LOCAL DRAW_NEXT
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,0CH ;写像素点
MOV AL,COLOR ;设置颜色
MOV BH,0 ;选用页号0
MOV CX,START_X ;列起始点
MOV DX,START_Y ;行起始点
DRAW_NEXT:
INT 10H ;画点
INC CX ;画横线
CMP CX,END_X ;比较行是否画完
JNE DRAW_NEXT ;画另一行
MOV CX, START_X ;另一行的起始点
INC DX
CMP DX,END_Y ;比较列是否画完
JNE DRAW_NEXT ;未完继续画
POP DX
POP CX
POP BX
POP AX
ENDM
;--------------------------------------------
DATAS SEGMENT
WHITE DB 0FFH
BLACK DB 0
YELLOW DB 0EEH
GRAY DB 8
CHOSE DB 'Chose the tone:C,F',0AH,0DH,'$'
ANSWER DB 0AH,0DH,'You have chosed the tone,Now enjoy the game!$'
;TABFA DW 441,495,556,589,661,742,833
;TABFB DW 495,556,624,661,742,833,935
TABFC DW 192,294,330,350,393,441,495
;TABFD DW 294,330,371,393,441,495,556
;TABFE DW 330,371,416,441,495,556,624
TABFF DW 350,393,441,467,525,589,661
;TABFG DW 393,441,495,525,589,661,742
;ZERO DW -1
BUFFER DW 0
DTIME DW 10
TONEF DW 0
TABOLINE DW 240,290,340,390,440,490
BLACKL DW 225,275,375,425,475
BLACKR DW 255,305,405,455,505
BBL DW 180,230,330,380,430
BBR DW 211,261,361,411,461
WL DW 101,151,201,251,301,351,401
WR DW 150,200,250,300,350,400,451
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
START:
MOV AX,DATAS
MOV DS,AX
CALL INIT
CALL OPEN
;---------------------------------------
;主界面
;----------------------------------------
;画白键盘,平行四边形
;----------------------------------------
MOV SI,190 ;SI=START_X
MOV DI,140 ;DI=START_Y
MOV BP,540 ;BP=END_X
DRAWW:
DRAWLINE0 SI,DI,BP,WHITE
DEC SI
DEC BP
INC DI
CMP DI,230
JC DRAWW
;------------------------------------------
;DRAW 190,120,540,140,YELLOW
;-------------------------------------
;画阴影
;-------------------------------------
DRAW 100,230,450,250,GRAY
;--------------------------------------
;侧面阴影
;-------------------------------------
MOV SI,140
PAINTSIDE:
DRAWOBILQUE 540,SI,450,GRAY
INC SI
CMP SI,160
JC PAINTSIDE
;----------------------------------------
;黑键阴影
;--------------------------------------
MOV SI,140
PAINTSIDE0:
DRAWOBILQUE 255,SI,210,WHITE
INC SI
CMP SI,150
JC PAINTSIDE0
MOV SI,140
PAINTSIDE1:
DRAWOBILQUE 305,SI,260,WHITE
INC SI
CMP SI,150
JC PAINTSIDE1
MOV SI,140
PAINTSIDE2:
DRAWOBILQUE 405,SI,360,WHITE
INC SI
CMP SI,150
JC PAINTSIDE2
MOV SI,140
PAINTSIDE3:
DRAWOBILQUE 455,SI,410,WHITE
INC SI
CMP SI,150
JC PAINTSIDE3
MOV SI,140
PAINTSIDE4:
DRAWOBILQUE 505,SI,460,WHITE
INC SI
CMP SI,150
JC PAINTSIDE4
;---------------------------------------
;画分割线
;---------------------------------------
MOV SI,240
REDRAW0:
MOV DI,SI
SUB DI,90
DRAWOBILQUE SI,140,DI,BLACK
ADD SI,50
CMP SI,540
JC REDRAW0
MOV SI,150
REDRAW1:
DRAWLINE1 SI,230,250,BLACK
ADD SI,50
CMP SI,440
JC REDRAW1
;------------------------------------------
;画黑键盘
;------------------------------------------
MOV BX,0
PAINTB:
MOV SI,OFFSET BLACKL
MOV DI,OFFSET BLACKR
MOV SI,[SI+BX]
MOV BP,[DI+BX]
;DRAW SI,185,BP,195,BLACK
MOV DI,140 ;DI=START_Y
DRAWB:
DRAWLINE0 SI,DI,BP,BLACK
DEC SI
DEC BP
INC DI
CMP DI,185
JC DRAWB
ADD BX,2
CMP BX,9
JC PAINTB
;-----------------------------------------
;黑键底下阴影
;-----------------------------------------
MOV BX,0
PAINTBB:
MOV SI,OFFSET BBL
MOV DI,OFFSET BBR
MOV SI,[SI+BX]
MOV BP,[DI+BX]
DRAW SI,185,BP,195,BLACK
ADD BX,2
;MOV DI,140 ;DI=START_Y
;DRAWB:
; DRAWLINE0 SI,DI,BP,BLACK
; DEC SI
; DEC BP
; INC DI
; CMP DI,185
; JC DRAWB
; ADD BX,2
CMP BX,9
JC PAINTBB
;-----------------------------------------
;提示选择信息
;-------------------------------
MOV AH,09H
MOV DX,OFFSET CHOSE
INT 21H
;---------------------------------
INPUT:
MOV AH,01H
INT 21H
CMP AL,'C'
JZ CTONE
CMP AL,'c'
JZ CTONE
CMP AL,'F'
JZ FTONE
CMP AL,'f'
JZ FTONE
JMP INPUT
;-------------------------------
;C调,F调
;--------------------------------
CTONE:
MOV DI,OFFSET TABFC
JMP ANS
FTONE:
MOV DI,OFFSET TABFF
;------------------------
ANS:
MOV TONEF,DI ;把选择的音调标号存储在TONEF中
MOV DX,OFFSET ANSWER ;显示提示信息
MOV AH,09H
INT 21H
;-------------------------------------
;获取弹奏的音符
;-------------------------------------
SCAN:
MOV AH,00H
INT 16H
CMP AL,37H ;ASCII>37H,退出
JA ERROR
CMP AL,31H ;ASCII<31H,退出
JC ERROR
AND AX,000FH ;将ASCII码转换成数字
MOV BUFFER,AX ;将数字存储在内存空间BUFFER中
JMP PLAY
ERROR:
CMP AL,1BH
JZ EXIT
JMP SCAN
PLAY:
MOV DI,TONEF
DEC AX
ADD AX,AX ;TABFx为双字表,需要将获得的ASCII符*2
ADD DI,AX
MOV BX,[DI] ;根据按键获取的ASCII码得到相应的频率值
;--------------------------------------------------------
MOV DX,12H
MOV AX,34DEH ;1.193182MHZ/BX
DIV BX
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
;---------------------------------------------------
;画阴影抖动 模拟动态效果
PAINTKEY:
MOV AX,BUFFER
MOV SI,OFFSET WL
MOV DI,OFFSET WR
DEC AX
ADD AX,AX
ADD SI,AX
ADD DI,AX
MOV SI,WORD PTR[SI]
MOV DI,WORD PTR[DI]
;-------------------------------------
DRAW SI,230,DI,250,WHITE
DRAW SI,230,DI,250,WHITE
;------------------------------------
CALL DELAY ;扬声器延时
MOV AX,12H ;往扬声器送高频,模拟关闭
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
JMP SCAN
EXIT:
CALL CLOSE
MOV AH,1
INT 21H
MOV AH,4CH
INT 21H
;--------------------------------------------------------
DELAY PROC
MOV AH,2DH
MOV CX,0
MOV DX,0
INT 21H ;设置系统时间
READ:
MOV AH,2CH
INT 21H
MOV AL,100
MUL DH
MOV DH,0
ADD AX,DX
CMP AX,DTIME
JC READ
RET
DELAY ENDP
;---------------------------------------
OPEN PROC
PUSH AX
IN AL,61H
OR AL,03H
OUT 61H,AL
POP AX
RET
OPEN ENDP
;-----------------------------------------
CLOSE PROC
PUSH AX
IN AL,61H
AND AL,0FCH
OUT 61H,AL
POP AX
RET
CLOSE ENDP
;------------------------------------------
INIT PROC
MOV AH,00H
MOV AL,12H ;640*480 彩色图形
INT 10H
MOV AL,80H ;对8255进行初始化工作,A口、B口均为输出状态工作与方式0
OUT 63H,AL
MOV AL,0B7H ;对计数器8254进行初始化工作,选2号计数器,且先读写低8位后高8位,工作与模式3
OUT 43H,AL
RET
INIT ENDP
CODES ENDS
END START