【问题标题】:Assembly playing audio file TASM 16 bit汇编播放音频文件 TASM 16 位
【发布时间】:2018-01-29 17:41:22
【问题描述】:

您好,我正在为学校项目编写游戏,但播放音频文件时遇到问题。 我能够播放该文件,但问题是程序冻结并停止响应用户

音乐文件代码

proc read Near ; Read next sample
    push bx
    push cx
    push dx
    mov ah, 3Fh
    mov bx, [filehandle]
    mov cx, 1
    lea dx, [Buffer]
    int 21h
    jc errorcode
    mov al, [Buffer]
    xor ah, ah
    mov bx, 54
    mul bx
    ; mov ax, dx ; Result is in DX because we need to div by 65536 which is all of AX
    shr ax, 8
    pop dx
    pop cx
    pop bx
    ret
endp
proc br Near; Print line break
    push dx
    push ax
    mov dl, 10
    mov ah, 2
    int 21h
    mov dl, 13
    mov ah, 2
    int 21h
    pop ax
    pop dx
    ret
endp
proc PlayMusic Near
    mov ah, 3Dh
    xor al, al
    lea dx, [filename]
    int 21h
    mov [filehandle], ax
    call br
    mov al, 90h
    out 43h, al
in al, 61h
    or al, 3
    out 61h, al
    cli
    mov ax, 0
totalloop:
    call read ; Read file
    out 42h, al ; Send data
    mov bx, ax
    mov cx, [delay]
portloop:
    loop portloop
    mov ax, bx
    out 42h, ax ; Send data
    mov cx, [delay]
rloop:
    loop rloop
    call read
    jmp totalloop
    ret
errorcode:
    ; Close
    sti
    mov al, 86h
    out 43h, al
    mov ah, 3Eh
    mov bx, [filehandle]
    int 21h
    pop dx
    pop cx
    pop bx
    ret
endp PlayMusic

在我调用这个 proc 之后,我调用 int 16h 从用户那里读取一个密钥,但是音乐文件阻止了 IO 有人知道我需要做什么吗? 顺便说一句对不起我的英语不好 而且我是组装新手,所以我不太好

【问题讨论】:

  • 那段代码很乱。比如你为什么要从函数read跳转到errorcode
  • 只有在进位标志打开时才会跳转到错误码,也就是说有错误时
  • 但它做错了事。它与read 的序言不匹配,甚至没有向调用者发出错误信号。
  • 我不认为有很多 86 位处理器(如标题)。我假设您的意思是 16 位或 x86,对吧?
  • @שחרדגן 见PCGPE 1.0 有您需要的所有东西,例如 VGA/VESA、TSR、ISR、PIT、SB、DOOM、Plasma 和 Fire 等等......但是最好的组装新手的所有时代的书是:Assembler a ZX Spectrum 1,但它是捷克语的 Z80 CPU,我不知道有任何翻译....

标签: audio assembly x86 dos tasm


【解决方案1】:

您要做的是“并行化”您的游戏代码(不使用线程)。关于如何执行此操作的选项很少:

  1. 交错代码

    这是最简单的实现方式。所以你的游戏架构应该是这样的:

    loop:handle input
         handle game logic
         render frame
         play sound (20-40ms)
         jmp loop
    

    这种架构将允许游戏“并行”运行其所有任务。如果你的任务比较慢,你可以多交错音乐

    loop:handle input
         play sound (~10ms)
         handle game logic
         play sound (~10ms)
         render frame
         play sound (~10ms)
         jmp loop
    

    如果任何任务真的很慢,那么您需要将声音直接插入其中,否则您会听到断断续续的声音。这是一个例子(没有声音):

    这是有声音的(但不是游戏):

    您需要使您的键盘测试非阻塞。取自我的无信号演示,它是这样完成的:

        mov ah,1    ; non blocking key test
        int 16h
        jz keyr0
        sub ax,ax   ; blocking key test
        int 16h
        ; here handle the key press...
    keyr0:          ; here continues your code
    
  2. 使用 PIT 作为发生器播放声音

    我没有使用这个,但 IIRC PIT 可以配置为使用扬声器播放恒定频率。因此,无需设置扬声器开/关,您只需设置其每帧的频率左右...这将在后台播放,在此期间 CPU 可以做其他事情...

  3. 使用 PIT 作为计时器在后台播放声音

    为了更好地计时并在后台播放与您的游戏代码平行的声音,您可以将播放的声音完全移动到 PIT ISR,它可以在 1193180.0/16bit_divider Hz 上运行,因此将 PIT 设置为目标声音采样频率。为其设置 ISR 并在其中获取/播放单个位......

    如果您使用 PWM 和多个采样频率,您可以将 Speaker 变成 DAC 播放甚至 PCM *.wav 文件。

    在这种情况下,您根本没有在游戏循环中交错的声音代码。

不要忘记在退出前将 PIT 频率设置回 18.2 Hz,因为 MS-DOS 和游戏使用它来计时。许多游戏可以通过单独更改 PIT 频率来加速。此外,当您更改 PIT 频率和 ISR 时,最好从新 ISR 中调用具有 18.2Hz 频率的原始 ISR。

有关 PC MS-DOS 和游戏的更多信息,请参阅:

  • PCGPE 1.0
  • WPCGPE 1.0 这应该是*.hlp 格式(你需要Windows6.1-KB917607 Win7+ 补丁,因为他们不再支持它)

这是我所知道的从组装开始的最佳选择:

Z80 CPU 是捷克语,我不知道有任何翻译......

【讨论】:

  • 嗨,如果你能帮助我,我还有另一个问题我目前正在阅读你给我的 PCGPE 1.0 是我见过的最好的教程,我在教程 Asphixia 的 VGA Primer - Virtual Screens 文件中,但是我找不到如何在汇编中使用虚拟屏幕,而不是在 Pascal 中,您有一些关于如何在汇编中使用虚拟屏幕的示例我可以学习吗?
  • @שחרדגן 花了我一段时间在 Windows 帮助中找到正确的页面格式化 PCGPE(只是单个文件而不是很多)所有的东西都在汇编中你只需忽略帕斯卡标题和标签并使用你自己的反而。我没有使用过这种 VGA 访问,我总是使用直接访问 VRAM 段并仅重新映射页面而不是整个屏幕。当时我什至没有使用 backbuffering 或 LFB,因为 asm 渲染速度足够快,而且对我来说没有闪烁......我什至在 asm 中做过 3D 引擎作为学校项目游戏(它是 ~4 Kbyte *.com)。
  • @שחרדגן 添加了指向 Windows 版本的链接(我在我下载的存档附近的一个文本文件中找到了 :))
  • 好的,所以我可以使用汇编中编写的移动 (mem[...])?还有一个问题,如果有可能我正在构建一款马里奥游戏,并且我需要当玩家移动到屏幕的尽头时,关卡会随着他移动你知道我该如何实现吗? @Spektre
  • @שחרדגן 取决于您游戏的架构...如果您在 QA 中查看我的游戏(在屏幕上移动对象的最佳方法是什么?)我链接它确实汽车居中,地图随着移动而滚动……这只是用 x 和 y 偏移渲染背景的问题。使用图块意味着您不是从(0,0) 角图块进行渲染,而是从某个 (x,y) 开始,而不是通常固定到玩家位置。我在 PCGPE 页面中没有看到任何 mem[]asmend; 之间的任何内容都是 TASM 的汇编代码。
猜你喜欢
  • 2014-08-08
  • 2018-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多