HaaS100复古街机来了!

HaaS100除了在物联网领域可以大显身手外,还有哪些可能的玩法呢?今天就带大家一起寻找童年的记忆,打造一台复古街机。最终完工图如下图:

 

接下来我们分三个步骤来进行打造:

  1. LCD及游戏手柄硬件接线
  2. 驱动开发
  3. 游戏开发

1、接线配置

1.1、LCD模块

我们采用了2.4寸彩色LCD屏幕,分辨率320*240,该屏幕使用SPI串口总线,因此使用较小的引脚数量就可以实现驱动。

HaaS100复古街机来了!_第1张图片

具体的接线配置如下,大家可以参考LCD模块上的丝印以及HaaS100开发板的引脚配置来完成接线。如果想要修改该引脚配置,请记得在代码中也进行更改嗷。

更多HaaS100的硬件规格请参考 https://help.aliyun.com/document_detail/184186.html?spm=a2c4g.11186623.6.642.7fd815815Xe5iP

HaaS100复古街机来了!_第2张图片              HaaS100复古街机来了!_第3张图片

1.2、模块

游戏拓展模块采用的是Arduino的硬件生态,该游戏模块具备了一个摇杆以及4颗按键,足够适配大量街机游戏(街机经典配置)。由于该模块没有具体的丝印,所以请开发者们参考下图的接线方式,使用标注的引脚进行连接。这么有意思的一款模块在以下地址购买:https://item.taobao.com/item.htm?spm=a1z09.2.0.0.3e082e8ddu5BB8&id=35422379433&_u=f1tg6s600889

  HaaS100复古街机来了!_第4张图片

 

2、驱动开发

2.1、 LCD模块

LCD模块与HaaS100的通讯方式为SPI,因此这里采用SPI0进行通讯。对于SPI0及相关GPIO的配置如下:

    // 硬件SPI0 最高通讯速度26MHz
	spi_ili9341.port = 0;
    spi_ili9341.config.mode = SPI_WORK_MODE_3; // CPOL = 1; CPHA = 1
    spi_ili9341.config.freq = 26000000;
    spi_ili9341.config.role = SPI_ROLE_MASTER;
    spi_ili9341.config.firstbit = SPI_FIRSTBIT_MSB;
    spi_ili9341.config.t_mode = SPI_TRANSFER_NORMAL;
    spi_ili9341.config.serial_len = 8;
    spi_ili9341.config.data_size = SPI_DATA_SIZE_8BIT;
    spi_ili9341.config.cs = SPI_CS_EN;

	// Data/Cmd引脚 用于切换发送指令或是数据
	gpio_ili9341_dc.port = ILI9341_DC_PIN;
    gpio_ili9341_dc.config = OUTPUT_PUSH_PULL;
    gpio_ili9341_dc.priv = NULL;

	// 复位引脚
    gpio_ili9341_reset.port = ILI9341_RESET_PIN;
    gpio_ili9341_reset.config = OUTPUT_PUSH_PULL;
    gpio_ili9341_reset.priv = NULL;

我们在驱动文件中已经实现了多种绘图函数,开发者可以直接使用这些绘图函数来进行更多有意思的开发。

    void (*lcd_frame_draw)(uint32_t *frame);
    void (*lcd_area_draw)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t *frame, uint32_t areaSize);
    void (*lcd_line_draw)(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t color);
    void (*lcd_rect_draw)(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t borderWidth, uint32_t color);
    void (*lcd_fill_rect_draw)(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t color);
    void (*lcd_circle_draw)(uint16_t x, uint16_t y, uint16_t r, uint16_t borderWidth, uint32_t color);
    void (*lcd_fill_circle_draw)(uint16_t x, uint16_t y, uint16_t r, uint32_t color);

2.2、模块

该模块包含 摇杆 及 按键 两部分。

摇杆的结构是两个相互垂直的弹性电位器。当用户操作摇杆时,即引发电位器的阻值变动,进而改变观测点输出的电压。因此只需要使用ADC采集观测点的电压值,便能够得到摇杆的位置信息。

HaaS100复古街机来了!_第5张图片

ADC的读取方法如下,需要注意的是,在每次 hal_adc_value_get 之前, 都需要进行 hal_adc_init ,才能进行有效地数据读取。

hal_adc_init(&roll_X);
hal_adc_init(&roll_Y);

hal_adc_value_get(&roll_X, &roll_X_value, 5);
hal_adc_value_get(&roll_Y, &roll_Y_value, 5);

按键采用中断检测的方式,对于每个按键设置上升沿触发中断,并在中断函数中完成键值的变换。

int game_key_init()
{
    int ret = 0;
    int key_num = straight; // 在这里填键值
    key_Y.port = 33;
    key_Y.config = IRQ_MODE;
    ret |= hal_gpio_init(&key_Y);
    // 上升沿触发中断函数 game_key_irq_fun, 同时传入键值
    ret |= hal_gpio_enable_irq(&key_Y, IRQ_TRIGGER_RISING_EDGE, game_key_irq_fun, key_num);

    return ret;
}

void game_key_irq_fun(int key_num)
{
    // do your things here
    printf("key %d down\n", key_num);
}

3、游戏开发

3.1、SDL多媒体库移植

单独写一个游戏很麻烦,怎么样可以玩更多的游戏呢?这里就给大家介绍一个多媒体库SDL。Why use SDL?用官方的话来讲——“因为它是一个跨平台的多媒体库,提供了多种控制图像、声音、和输入设备的函数,可以让游戏开发者专注于游戏本身”。这里为了帮你找回童年记忆,AliOS Things已经将SDL移植进来。

 

HaaS100复古街机来了!_第6张图片

HaaS100复古街机来了!_第7张图片HaaS100复古街机来了!_第8张图片

SDL移植后的代码在:

./components/utility/SDL。

 

将底层LCD驱动和遥杆驱动适配到SDL,驱动适配的逻辑参考:

./components/utility/SDL2/src/video/alios/SDL_AliOS_framebuffer.c

./components/utility/SDL2/src/video/alios/SDL_AliOS_video.c

AOS_APP_GAME_DEMO宏定义相关代码。

 

3.2、俄罗斯方块游戏移植

基于SDL的开源游戏在市面上已经非常多,在github上搜一搜一大把。当然我们先来一个经典俄罗斯方块试试水https://github.com/andwn/sdl2-tetris。代码已经移植好,你可以在AliOS Things的github仓库中找到游戏demo。

HaaS100复古街机来了!_第9张图片

4、游戏烧录

游戏中涉及到字体,在编译代码前先将字体文件拷贝到预编译目录:

 $cp application/example/game_demo/sdl2-tetris/data/DejaVuSerif.ttf ./platform/mcu/haas1000/prebuild/data/

编译game demo:

$aos make game_demo@haas100 -c config
$aos make

烧录以下两个文件:

参考烧录方法链接

./out/wificamera_demo@haas100/binary/[email protected]
./platform/mcu/haas1000/release/write_flash_gui/ota_bin/littlefs.bin

5、小结

到此为止,俄罗斯方块玩起来了,如果觉得还不过瘾,一起来尝试移植其他的SDL游戏,找找童年的感觉,是不是很有意义呀,期待您的杰作。

如需更多技术支持,可加入钉钉开发者群

更多技术与解决方案介绍,请访问阿里云AIoT首页https://iot.aliyun.com/

你可能感兴趣的:(HaaS解决方案,嵌入式,物联网,实时操作系统,游戏,HaaS)