上一节讲了世嘉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);
单看这个注释还是感觉一头雾水,那么咱们就来做个小实验吧,看看这个joy,changed,state都是什么东西。
在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.c按Ctrl+Shift+B编译一下,运行rom,尝试一下按键,对照一下键值表很直观的就能得出joy,changed,state是什么东西了。
joy就是手柄端口号了,1P的端口号是0,所以屏幕上得到的joy也是0.
changed是当前按键的值,如果先按住A键再按住B键,那么changed显示的是B键的值。
state是所有按键的和,如果先按住A键再按住B键,那么changed显示的就是A+B两个键的和。
配合 世嘉MD游戏开发【三】:输入控制(上)效果更好
未完待续。。。
复古游戏开发群:879063892