在Gameboy中为C创建一个二级计数器

时间:2014-04-04 21:17:08

标签: c gameboy

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

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

无论如何我可以这样做吗? 有人告诉我,Gameboy运行速度相当慢,如果我能把它抓到一个忙碌的循环中,那么我可以接近第二个'并按此计算。

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

有什么建议吗?

修改:我认为不允许stdlib.hstdio.h以外的任何内容。

2 个答案:

答案 0 :(得分:5)

gameboy有一个硬件计时器。

  

有时候让计时器中断是很有用的    定期进行需要的例行程序    定期或percise更新。 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)次中断时更新显示的时钟。

答案 1 :(得分: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);
}  

enter image description here

2)表征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秒钟的值,创建一个新的原型:

void delay(float); 并创建一个#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);
}