Allegro学习笔记十一

http://wiki.allegro.cc/AllegroExamples 以上是英文例子站点。

by Shawn Hargreaves,allegro的作者

目录: 1 Allegro 例子

1.1 exhello
1.2 exmem
1.3 expat
1.4 expal
1.5 exflame
1.6 exbuf
1.7 exflip
1.8 exfixed
1.9 exfont
1.10exmouse
1.11extimer

这个例子展示了如何使用时钟中断
可能会有一点小痛(麻烦),因为你必须锁住所有在你的中断中使用的内存。
在例子的第1个部分展示了基本的计时函数rest()的用法(相当于delay();)
在例子的第2个部分展示了如何使用3个频率不同的用户时钟
 *    This program demonstrates how to use the timer routines.
 *    These can be a bit of a pain, because you have to be sure
 *    you lock all the memory that is used inside your interrupt
 *    handlers.  The first part of the example shows a basic use of
 *    timing using the blocking function rest(). The second part
 *    shows how to use three timers with different frequencies in
 *    a non blocking way.
 */


#include <allegro.h>

 

/* 这些变量应当用volatile声明,这样优化器就不会搞错了 */
volatile int x = 0;
volatile int y = 0;
volatile int z = 0;

 

/* 时钟中断句柄 */
void inc_x(void)
{
   x++;
}

END_OF_FUNCTION(inc_x)

 

/* 时钟中断句柄 */
void inc_y(void)
{
   y++;
}

END_OF_FUNCTION(inc_y)

 

/* 时钟中断句柄 */
void inc_z(void)
{
   z++;
}

END_OF_FUNCTION(inc_z)

 

int main(void)
{
   int c;

   if (allegro_init() != 0)
      return 1;
   install_keyboard();
   install_timer();

   if (set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0) != 0) {
      if (set_gfx_mode(GFX_SAFE, 320, 200, 0, 0) != 0) {
  set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
  allegro_message("Unable to set any graphic mode/n%s/n", allegro_error);
  return 1;
      }
   }

   set_palette(desktop_palette);
   clear_to_color(screen, makecol(255, 255, 255));

   textprintf_centre_ex(screen, font, SCREEN_W/2, 8, makecol(0, 0, 0),
   makecol(255, 255, 255), "Driver: %s",
   timer_driver->name);

   /* 使用rest()来延迟给定的时间(毫秒级) */
   textprintf_centre_ex(screen, font, SCREEN_W/2, 48, makecol(0, 0, 0),
   makecol(255, 255, 255), "Timing five seconds:");

   for (c=1; c<=5; c++) {
      textprintf_centre_ex(screen, font, SCREEN_W/2, 62+c*10,
      makecol(0, 0, 0), makecol(255, 255, 255), "%d", c);
      rest(1000);
   }

   textprintf_centre_ex(screen, font, SCREEN_W/2, 142, makecol(0, 0, 0),
   makecol(255, 255, 255),
   "Press a key to set up interrupts");
   readkey();

   /* 所有在时钟中断中使用的变量和函数都应该锁起来 */
   LOCK_VARIABLE(x);
   LOCK_VARIABLE(y);
   LOCK_VARIABLE(z);
   LOCK_FUNCTION(inc_x);
   LOCK_FUNCTION(inc_y);
   LOCK_FUNCTION(inc_z);

   /* 速度可以由毫秒级的数字给定(在这里是1秒一次中断)*/
   install_int(inc_x, 1000);

   /* 或者使用每秒的节拍率(BPS) (在这里是每秒10拍) */
   install_int_ex(inc_y, BPS_TO_TIMER(10));

   /* 或者使用秒 (这里是10秒一个周期) */
   install_int_ex(inc_z, SECS_TO_TIMER(10));

   /* 这些中断在这里被激活... */
   while (!keypressed())
      textprintf_centre_ex(screen, font, SCREEN_W/2, 176, makecol(0, 0, 0),
      makecol(255, 255, 255), "x=%d, y=%d, z=%d", x, y, z);

   return 0;
}

END_OF_MAIN()
---------------------------------------------------------------------
1、volatile声明
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值(From Memory),而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1) 并行设备的硬件寄存器(如:状态寄存器)
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3) 多线程应用中被几个任务共享的变量
详细的可以访问http://blog.csdn.net/gaoteng1984/archive/2007/07/27/1711924.aspx
2、Allegro中的时钟中断
你的函数将被 Allegro 中断处理程序调用而不是被处理器直接调用, 所以它能够 按正常的 C 函数来写而不需要特别的包装. 然而, 你必须知道,它将在一个中断中 被调用,而这给你希望在函数中做的事增加了许多约束.它不能使用大数量的堆栈, 不能调用任何 DOS 例程和使用调用了 DOS 例程的 C 库函数, 而且它必须被很快 的执行.不要在时钟处理程序里写太多的复杂代码: 一个基本的规则是你应该设置 一些标志然后在你的主控制循环里来回应它们.

在象 djgpp 这样的保护模式环境里, 内存被虚拟化并可以向磁盘交换. 由于 DOS 的不可重入, 如果磁盘交换发生在中断处理程序内部,系统将痛苦的死机, 所以你 需要确认你锁住了所有时钟例程中触及的所有内存 (包括代码和数据). Allegro 将锁住它用的所有东西,但是你有责任锁住你自己处理程序的. 宏 LOCK_VARIABLE (变量), END_OF_FUNCTION(函数名), 和 LOCK_FUNCTION(函数名) 可以被用来简化 这项任务.例如, 你想用一个中断处理程序来增加一个记数变量, 就应该这样写:
      volatile int counter;
      void my_timer_handler()
      {
         counter++;
      }
      END_OF_FUNCTION(my_timer_handler);
在你的初始化代码里,应该锁住内存:
      LOCK_VARIABLE(counter);
      LOCK_FUNCTION(my_timer_handler);
很明显,如果你使用了复杂的数据结构并且在这个处理程序中调用了其它的 函数,这就显得很笨拙,所以你应该使你的中断处理程序尽量简洁.

3、设置时钟中断的频率
SECS_TO_TIMER(secs)  - 给出两次触发间的秒数
MSEC_TO_TIMER(msec)  - 给出两次触发间的万分之一秒数
BPS_TO_TIMER(bps)    - 给出每秒触发多少次
BPM_TO_TIMER(bpm)    - 给出每分钟触发多少次

4、/* 这些中断在这里被激活... */
Allegro的用户时钟中断貌似都在whlie(true)循环里起作用。如果你有写过“XX引擎”的话,应该对此有更深的体会。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值