NES是Nintendo Entertainment System的缩写,记录了NES小游戏的所有代码和数据。像超级玛丽、忍者龙剑传、热血格斗、007等游戏都有精彩纷呈的背景图片和形象生动的人物造型,我们是否能提取出这些素材,经过加工,用于其他UI设计呢?今天我们用MATLAB研究下具体内容。
NES文件结构分为3大部分:文件头、CPU代码区、PPU数据区。通过文件头可以获得代码区、数据区的大小。这里只需要数据区。
数据区组织为4KB大小的数据块,填充在PPU地址区间0x0000~0x1000(或者0x1000~0x2000),称为Pattern Table,其实就是一个个8x8的点阵数据,用户程序写入Name Table、SPR-RAM中相应的索引就能实现在屏幕指定位置上描绘相应的点阵信息,组合多个点阵可以实现复杂背景和人物造型的显示。这里只将原始点阵描出。代码如下:
clear;
clc;
close all;
path = './rom/';
[nes_file_name, path, filterindex] = uigetfile('*.nes', 'Pick an NES file',path);%选择NES文件
fid = fopen(fullfile(path,nes_file_name),'rb');
rawdata = fread(fid,'uint8');
fclose(fid);
len_header = 16;<span style="white-space:pre"> </span>%文件头,16Bytes
len_pgm = 1024*16; %16KB
len_ppu = 1024*8; %8KB
header = rawdata(1:len_header);
if and(and(and((header(1) == uint8('N')),header(2) == uint8('E')),header(3) == uint8('S')),header(4) == 26)
fprintf('NES File Loaded...\n');
else
fprintf('Not an NES File!\n');
return;
end
num_pgm = header(5);
num_ppu = header(6);
pgm = rawdata(len_header + (1:len_pgm));
for ppu_idx = 1:num_ppu
ppu = rawdata(len_header + len_pgm * num_pgm + (ppu_idx - 1) * len_ppu + (1:len_ppu));
ppu1 = ppu(0 + (1:len_ppu/2)); % 4KB
ppu2 = ppu(len_ppu/2 + (1:len_ppu/2)); % 4KB
ppu1 = reshape(ppu1,16,[]);
ppu2 = reshape(ppu2,16,[]);
showimag1 = zeros(128,128);
showimag2 = zeros(128,128);
and_matrix = ones(8,1)*2.^(7:-1:0);
zz1 = zeros(8,8);
zz2 = zeros(8,8);
for k = 1:size(ppu1,2)
x = mod(k-1,16);
y = floor((k-1)/16);
rdata1l = logical(bitand(ppu1(1:8,k)*ones(1,8),and_matrix));
rdata1h = logical(bitand(ppu1(9:16,k)*ones(1,8),and_matrix));
rdata2l = logical(bitand(ppu2(1:8,k)*ones(1,8),and_matrix));
rdata2h = logical(bitand(ppu2(9:16,k)*ones(1,8),and_matrix));
zz1 = rdata1l + rdata1h * 2;
zz2 = rdata2l + rdata2h * 2;
showimag1((y)*8 + (1:8), (x)*8 + (1:8)) = zz1 * 64;
showimag2((y)*8 + (1:8), (x)*8 + (1:8)) = zz2 * 64;
end
figure;subplot(121);imshow(uint8(showimag1));title('Pattern Table #1');
subplot(122);imshow(uint8(showimag2));title('Pattern Table #2');
end
下面欣赏几幅游戏中提取出来的Pattern Table