【发布时间】:2015-07-25 10:54:52
【问题描述】:
我最近写了一个小诅咒游戏,因为它所需要的只是一些计时器机制和一个诅咒实现,所以尝试为 DOS 构建它的想法很自然。诅咒是由pdcurses 为 DOS 提供的。
POSIX和Win32的时序已经不同了,所以我定义了这个接口:
#ifndef CSNAKE_TICKER_H
#define CSNAKE_TICKER_H
void ticker_init(void);
void ticker_done(void);
void ticker_start(int msec);
void ticker_stop(void);
void ticker_wait(void);
#endif
游戏调用ticker_init() 和ticker_done() 一次,ticker_start() 在需要滴答时以毫秒为间隔,在其主循环中调用ticker_wait() 以等待下一个滴答。
在 DOS 上使用与 POSIX 平台相同的实现,使用setitimer(),但不起作用。一个原因是 djgpp 附带的 C lib 没有实现waitsig()。所以我为我的 DOS 接口创建了一个新实现:
#undef __STRICT_ANSI__
#include <time.h>
uclock_t tick;
uclock_t nextTick;
uclock_t tickTime;
void
ticker_init(void)
{
}
void
ticker_done(void)
{
}
void
ticker_start(int msec)
{
tickTime = msec * UCLOCKS_PER_SEC / 1000;
tick = uclock();
nextTick = tick + tickTime;
}
void
ticker_stop()
{
}
void
ticker_wait(void)
{
while ((tick = uclock()) < nextTick);
nextTick = tick + tickTime;
}
这就像dosbox 中的魅力一样(我现在没有真正的 DOS 系统)。但我担心的是:忙着等待真的是我在这个平台上能做的最好的事情吗?我想要一个解决方案,让 CPU 至少可以节省一些能量。
【问题讨论】:
-
我怀疑 DOS 提供了这个。 Wikipedia page on the HLT instruction 表示“在 1994 年英特尔 DX4 处理器发布之前,它没有被 MS-DOS 使用,也不是专门为降低功耗而设计的”,当时 DOS 正被 Windows 取代。 AFAIK,当时的忙碌等待是非常典型的。
-
您是否考虑过基于中断的键盘例程?当你在 DOS 中按下一个键时,会产生一个中断,然后你会找出哪个键被按下并将其存储在一个键数组中。然后,当您的游戏逻辑需要处理输入时,它只需检查数组以查看是否按下了按钮,这会导致您的玩家移动、开火等。您还可以使用 Allegro 之类的库在 DJGPP 中执行与游戏相关的任务更容易做到。
-
大多数时候,我只需要这个游戏以恒定的速度运行(它是蛇的变种),因此是滴答声。输入通过 curses 处理以保持可移植性。如果我只为 DOS 端口执行自己的输入中断例程,那么问题(我 认为 已解决,请参阅我自己的答案,但欢迎使用 cmets)是否会持续存在做某事(例如
hlt)等待中断?