1、任天堂FC(红白机)

先上图——

这就是任天堂FC(北美版叫做NES,外形也不同),电子游戏历史上影响力最大的一台游戏主机。

在中国玩家里,恐怕只有极少数人玩过它的原版机型,大部分人记忆中的都是“小霸王学习机”,以及小天才、胜天等等外形迥异的兼容机。


在那个信息闭塞、娱乐方式有限的年代,FC是不止一代人的童年回忆。一篇2009年的旧帖,打开了满是灰尘的记忆——

沉默的人–中国电视游戏业往事(《家用电脑与游戏》2009年3期) – 游戏业界综合讨论区 – TGFC Lifestyle
连接:https://bbs.tgfcer.com/thread-6059014-1-665.html

2、非主流开发者

FC代表的不仅仅是一台游戏机,生活中也围绕它展开了一系列或是鸡飞狗跳、或是可歌可泣的故事。

上面TGFC的旧帖中提到了多位与FC开发结缘的人,有《烟山坦克》的作者,有“小天才”的开发者,还有英年早逝的天才、Dream系列模拟器开发者李可文。

除了早年间的传奇人物,其实还有一批默默无闻的FC业余开发者,他们或是怀着热情,或是抱着学习的目的来学习FC开发。

2021年年初,我忽然在B站上看到一个“教学”视频——从0开始实现一个FC模拟器。链接:【科普】编程实现简单的FC模拟器,揭秘红白机内部的运行原理!

这个模拟器效果出色,视频讲解逻辑清楚,令我十分惊讶——在互联网高度发达的今天,像FC模拟器这种以前只有大神黑客才能掌握的东西,现在竟然可以做成教学视频。

对于有一点编程能力的人来说,理解FC的原理不会太难。但比较麻烦的是搭建开发环境并逐步实践。

这时我已经有了一点开发FC游戏的想法,但不知从何入手。

经过一番搜索,我找到了一个神奇的网站(网盘),在那里几乎有我需要的所有FC资料—— 链接:http://fogota.ysepan.com/

这时我才发现,原来一直有一群人,一直凭着热情研究FC游戏开发。沿着他们的脚印,让我也能快速学会开发FC的方法。

3、开始FC开发——FC游戏大师

我翻了一遍网盘资料,经过实验发现一款比较容易上手的软件——FC游戏大师。看信息它是“维京猎人”制作的一个FC开发IDE,整合了多款必要的小工具。

推荐FC游戏大师的原因有很多:

一键编译。只要写好Build.cmd批处理文件,一键编译,一键运行。
有示例工程,有注释。

示例工程似乎是作者 维京 自己写的C语言源代码,有注释可参考。
整合了chr工具、map工具。
★ 主要开发语言是C语言,极大降低了入门门槛。

4、创建和运行第一个游戏项目

下载FC游戏大师

位于“维京的梦”网盘中“FC-工具集[2]”文件夹中。下载后解压即可使用。
文件夹中包含入门PDF文档“FC_NES_maker使用说明_小白档”,需要略读前半部分。
打开FC_maker.exe,左上角按钮 -> 打开工程 -> 例子,发现里面没有工程。打开文件夹查看,发现示例工程被压缩了,原地解压它们即可。
示例工程有两个,《迷宫不迷》和《移动》。我们先从简单的《移动》开始。
打开“移动.vk5”工程,点击“工程编译”按钮。

软件会自动打开cmd窗口运行Build.cmd,Build.cmd里面是批处理指令。

编译成功后关闭cmd窗口。点击绿色小三角,会自动打开FCEUX模拟器运行编译好的rom。

5、代码与字符文件简介

第一个工程比较简单,稍微看一下。

主程序是“移动.c”,打开它就可以编辑代码。FC大师集成了Notepad++可以直接编辑,由于编译器是独立的,只要能写文字的编辑器都可以编辑代码。

Notepad++功能太少,我推荐用Visual Studio,可以识别C语言语法并跳转函数。做Unity开发的同学应该都已经安装过了,用VS直接打开C文件即可,不要创建工程。

用VS写C语言代码

代码解释:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <conio.h>

void main()
{
    // C语言变量定义必须在最前面
    int var1 = 1;
    int t = 1;
    // 一直循环20次
    while (var1 < 20)
    {
        // 指定打印坐标到第var1行,第10列,每行每列是8个像素
        gotoxy(var1, 10);
        cprintf("0123456789:;");      // 打印chr文件中指定的tile到背景
        gotoxy(var1, 11);
        cprintf("@ABCDEFGHIJK");

        var1 = var1 + 1;        // 横坐标+1
        t = 1;
        // 空循环体,等待一段时间
        while (t++ < 800);
    }
    // 死循环,卡住CPU不动
    while (1);
}

不熟悉单片机开发的人可能觉得这个代码很奇怪,到处是空循环、死循环。但事实就是这样,我们大部分人都会觉得很奇怪【狗头】

问题是,代码里写的是打印“0123456789:”,为什么打印出来是“维京猎人来了”呢?

请打开FC大师窗口中的ASCII.chr

打开以后发现一个字符表。作者将字符表中的“0123456”和“ABCDEF”那段替换成了汉字,就自然会打印“维京XXXX”的汉字了。

FC根本就没有电脑那样的字符系统,字符都是以tile的形式画出来的。这里可以用工具编辑chr文件,然后编译运行,发现文字图案变了。(chr工具使用方法略)

由于这个例子并不是很具有代表性,实际开发中cprintf的办法并不常用。我们简单略过,之后找更合适的例子来介绍。

6、开始?

我最近研究FC,做了一个像这样的打飞机游戏:

敌机素材借用了FC游戏《1943》里面的飞机素材。

整个游戏做的非常简单,主要是为了配合文章介绍用。

工程可以在“维京的梦”网盘中的“访客上传03”文件夹中找到,文件名“goodorc作品_FC大师工程_spitfire.zip”

FC开发涉及到的细节非常多,需要实践才能理解。

我打算围绕着FC开发中的重点逐步展开,用最简单的方式把FC核心技术介绍清楚。计划会有4~5个短篇文章,每期介绍一个小问题。

相信大部分读者都是对FC开发的原理有兴趣,相信本系列会起到抛砖引用的作用:)