世嘉MD游戏开发【四】:输入控制(下)

上一节讲了世嘉MD两种输入控制当中的一种,也是比较容易理解的一种,这一节讲一下剩下的这种控制方式:回调函数式。

建好文件夹,用vscode打开,新建main.c,依然是直觉一般的写下如下代码:

#include <genesis.h>
#include <joy.h>    //这一句不加也能编译通过,只是方便F12跳转过去看文档

int main()
{

    while (1)
    {
        VDP_waitVSync();
    }

    return 0;
}

我其实也没有背过怎么写那个回调函数,有哪些参数啊什么的我都没记住,不过不要紧,只要你记住输入相关的内容都在joy.h这个头文件中就行了,然后include一下就可以直接按F12跳转到文档了。

跳转到文档,我们会发现有一个很明显属于回调函数的代码,详情如下:

/**
 *  \brief
 *      Joypad event callback.
 *
 *  \param joy
 *      Joypad which generated the event.<br>
 *      <b>JOY_1</b>    = joypad 1<br>
 *      <b>JOY_2</b>    = joypad 2<br>
 *      <b>...  </b>    = ...<br>
 *      <b>JOY_8</b>    = joypad 8 (only possible with 2 teamplayers connected)<br>
 *      <b>JOY_ALL</b>  = joypad 1 | joypad 2 | ... | joypad 8<br>
 *  \param change
 *      Changed state (button for which state changed).<br>
 *      <b>BUTTON_UP</b>    = UP button<br>
 *      <b>BUTTON_DOWN</b>  = DOWN button<br>
 *      <b>BUTTON_LEFT</b>  = LEFT button<br>
 *      <b>BUTTON_RIGHT</b> = RIGHT button<br>
 *      <b>BUTTON_A</b>     = A button<br>
 *      <b>BUTTON_B</b>     = B button<br>
 *      <b>BUTTON_C</b>     = C button<br>
 *      <b>BUTTON_START</b> = START button<br>
 *      <b>BUTTON_X</b>     = X button<br>
 *      <b>BUTTON_Y</b>     = Y button<br>
 *      <b>BUTTON_Z</b>     = Z button<br>
 *      <b>BUTTON_MODE</b>  = MODE button<br>
 *      <b>BUTTON_LMB</b>   = Alias for A button for mouse<br>
 *      <b>BUTTON_MMB</b>   = Alias for B button for mouse<br>
 *      <b>BUTTON_RMC</b>   = Alias for C button for mouse<br>
 *  \param state
 *      Current joypad state.<br>
 *<br>
 *      Ex: Test if button START on joypad 1 just get pressed:<br>
 *      joy = JOY_1; changed = BUTTON_START; state = BUTTON_START | (previous state)
 */
typedef void _joyEventCallback(u16 joy, u16 changed, u16 state);

就是typedef void _joyEventCallback(u16 joy, u16 changed, u16 state);这一行了,很容易联想到这肯定是另一个函数的参数,继续往下拉就能看到调用这个参数的函数了,看代码:

/**
 *  \brief
 *      Set the callback function for controller state changed.<br>
 *<br>
 *      SGDK provides facilities to detect state change on controller.<br>
 *      It update controllers state at each V Blank period and fire event if a state change is detected.<br>
 *
 *  \param CB
 *      Callback to call when controller(s) state changed.<br>
 *      The function prototype should reply to _joyEventCallback type :<br>
 *      void function(u16 joy, u16 changed, u16 state);<br>

 *      意思就是控制器状态更改的时候会调用这个函数。回调函数的形式应该是下面这样的:
 *      void function(u16 joy, u16 changed, u16 state);
 *<br>
 *      <b>Ex 1</b> : if player 1 just pressed START button you receive :<br>
 *      joy = JOY_1, changed = BUTTON_START, state = BUTTON_START<br>
 *      <b>Ex 2</b> : if player 2 just released the A button you receive :<br>
 *      joy = JOY_2, changed = BUTTON_A, state = 0<br>
 */
void JOY_setEventHandler(_joyEventCallback *CB);

单看这个注释还是感觉一头雾水,那么咱们就来做个小实验吧,看看这个joychangedstate都是什么东西。

main函数上面声明一下回调函数,函数名随便写,我就叫handleInputCallback好了,然后在main函数下面实现回调函数,再回到main函数,在while循环里去调用回调函数(错误更正:其实不用在while循环里调用,直接在while循环上面调用就可以了,这是我写完文章才发现的),代码如下:

#include <genesis.h>
#include <joy.h> //这一句不加也能编译通过,只是方便F12跳转过去看文档

void handleInputCallback(u16 joy, u16 changed, u16 state);

int main()
{

    while (1)
    {
        JOY_setEventHandler(handleInputCallback);
        VDP_waitVSync();
    }

    return 0;
}

void handleInputCallback(u16 joy, u16 changed, u16 state)
{
    //输入
}

然后我们就在handleInputCallback函数里打印一下这几个参数,代码如下:

//省略上面的代码,只给出回调函数部分

void handleInputCallback(u16 joy, u16 changed, u16 state)
{
    //输入

    char strJoy[20];        //存储joy数值的字符串
    char strChanged[20];
    char strState[20];

    //用sprintf函数把这几个参数存储到数组中

    sprintf(strJoy, "%4d", joy);
    sprintf(strChanged, "%4d", changed);
    sprintf(strState, "%4d", state);

    //在屏幕上打印字符串

    VDP_drawText("joy = ",0,1);     VDP_drawText(strJoy,5,1);
    VDP_drawText("changed = ",0,2); VDP_drawText(strChanged,5,2);
    VDP_drawText("state = ",0,3);     VDP_drawText(strState,5,3);
}

再看结果之前先给出几个键值和手柄端口值:

#define JOY_1           0x0000        //1P
#define JOY_2           0x0001        //2P
#define JOY_3           0x0002
#define JOY_4           0x0003
#define JOY_5           0x0004
#define JOY_6           0x0005
#define JOY_7           0x0006
#define JOY_8           0x0007
#define JOY_NUM         0x0008
#define JOY_ALL         0xFFFF


#define BUTTON_UP       0x0001      //十进制    1
#define BUTTON_DOWN     0x0002      //十进制    2
#define BUTTON_LEFT     0x0004      //十进制    4
#define BUTTON_RIGHT    0x0008      //十进制    8
#define BUTTON_A        0x0040      //十进制    64
#define BUTTON_B        0x0010      //十进制    16
#define BUTTON_C        0x0020      //十进制    32
#define BUTTON_START    0x0080      //十进制    128
#define BUTTON_X        0x0400      //十进制    1024
#define BUTTON_Y        0x0200      //十进制    512
#define BUTTON_Z        0x0100      //十进制    256
#define BUTTON_MODE     0x0800      //十进制    2048

回到main.cCtrl+Shift+B编译一下,运行rom,尝试一下按键,对照一下键值表很直观的就能得出joychangedstate是什么东西了。

joy就是手柄端口号了,1P的端口号是0,所以屏幕上得到的joy也是0.

changed是当前按键的值,如果先按住A键再按住B键,那么changed显示的是B键的值。

state是所有按键的和,如果先按住A键再按住B键,那么changed显示的就是A+B两个键的和。

配合 世嘉MD游戏开发【三】:输入控制(上)效果更好

未完待续。。。

复古游戏开发群:879063892

发布了17 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq272508839/article/details/103214069