1

所以我是 C 的新手,并被分配了制作游戏的任务。我将使用 Gameboy 模拟器,并且不鼓励导入任何超出基础的库。

我想想出一种方法来运行第二个计数器(将显示在屏幕上),但无法使用该time.h库,我觉得有点卡住了。

无论如何我可以这样做吗?有人告诉我,Gameboy 的运行速度相当慢,如果我可以让它陷入“忙碌循环”,我可以“大约一秒钟”并以这种方式计数。

我已经考虑过sleep执行此操作的功能,但那是在unistd.h库中。我还考虑过可能设置一个循环并数到 10000(或任何数字可能需要一秒钟来计算),但所有这些都将同时发生在手头的游戏中,我担心这样的事情会延迟游戏玩法和其他事情的发生。

有什么建议吗?

编辑:我认为任何超出的stdlib.h东西stdio.h都是不允许的。

4

2 回答 2

6

gameboy一个硬件计时器。

有时,对于需要定期或精确更新的例程,有一个定期中断的计时器很有用。GameBoy 中的计时器可选择频率为 4096、16384、65536 或 262144 赫兹。此频率增加定时器计数器 (TIMA)。当它溢出时,它会产生一个中断。然后加载定时器模数 (TMA) 的内容。以下是示例:

;This interval timer interrupts 4096 times per second
ld a,-1
ld ($FF06),a ;Set TMA to divide clock by 1
ld a,4
ld ($FF07),a ;Set clock to 4096 Hertz

因此,编写您的中断处理程序以跟踪中断的数量并每 4096 (=0x1000) 个中断更新显示的时钟。

于 2014-04-04T23:23:50.000 回答
2

一些(不是全部)延迟函数的实现是阻塞的,(在延迟函数返回之前,代码中没有其他内容运行。也容易受到运行时选项的影响,例如是否处于调试或发布执行模式等(即将以不一致的方式运行)时间取决于这些模式)

非阻塞的实现,即在延迟期间,系统事件被给予时间片以继续可能需要使用多线程。但由于 C 本质上不是多线程语言,因此您必须使用不允许使用的其他非标准 C 库。

假设您了解这一点,并且使用简单的技术(即阻塞,对执行模式敏感)就可以了,那么只需使用简单的时间循环。按着这些次序:

1)创建一个开发(测试)函数,它只是一个带有硬编码索引值的for循环:

void sec_delay(void)
{
    //loop incrementer value
    int i = 334000000;//change value here during testing to adjust duration of calling
                      //test program.  eg: for 60 calls, should elapse 60 seconds.
                      //this value run on PC shown below provided 1 second duration.
    while(i-- > 0);
}  

在此处输入图像描述

2) 描述 sec_delay
运行一个调用 sec_delay 60 次的程序,并根据时钟或秒表计时其执行时间。

void sec_delay(void);
int main(void)
{
    int i;
    for(i=0;i<60;i++)//target 60 seconds, change to 600 for 10 min. or 10 for 10 sec.
    {
        sec_delay();
    }
    printf("Done");//uses stdio.h
    getchar();     //uses stdio.h
    return 0;
}

3) 使用此可执行文件的执行时间来调整循环增量值,以便尽可能接近 1 分钟。为了获得更高的精度,将主程序循环 600 次并将增量器映射到 sec_l​​oop 中,使经过的时间为 10 分钟。

一旦你描述了 sec_delay() 函数的特征,你基本上就有了可以用于 1 秒计时器的东西。

4) 现在你有一个 1 秒过去时间的值,创建一个新原型:

无效延迟(浮动);并创建一个#define:

#define SEC 334000000.0 //enter your value here in float 

最后,定义 delay() 函数:

void delay(float secs)//note, fractions of seconds can be called
{
    if(secs < 0) break;//leave for negative values;
    int i = (int)secs*SEC ;
    while(i-- > 0);
}
于 2014-04-04T22:58:27.627 回答