Playstation厄运多边形

图片

索尼PlayStation



PlayStation的故事始于1988年,当时任天堂和索尼开始在SNES控制台的可选CD-ROM阅读器上进行合作。根据协议条款,索尼能够独立开发该平台的游戏,并保留对超级光盘格式的控制权-任天堂的两项不寻常的让步。

该项目是在CES '91展览会之前开发的,索尼在该展览会上宣布了与Play Station的合作。第二天,在同一个展览会上,任天堂让索尼感到惊讶,它宣布它已与飞利浦签订了合作协议(条件更为优惠)。忠诚而公开的索尼试图向世嘉董事会提出上诉,后者立即拒绝了这一提议。 SEGA首席执行官Tom Kalinske在2013年的一次采访中回顾了理事会的决定。

“这是一个愚蠢的想法,索尼不知道如何开发设备。他们不知道如何编写软件。我们为什么要惹他们?” -SEGA董事会

他们没有弄错,索尼在游戏方面确实没有什么经验。除了一个人-Ken Kutaragi的主动行动,她几乎对他们没有兴趣。从看到女儿在任天堂Famicom玩游戏的那一刻起,Ken就一直说服索尼,他需要进入这个市场。尽管有索尼副总裁的建议,他甚至为任天堂开发了SNES中使用的音频芯片(SPC700)。

索尼的大多数高管都认为这是一个冒险的赌注,但库塔拉吉(Kutaragi)获得了索尼首席执行​​官Norio Oga的支持。 1992年6月,肯被允许从头开始创建游戏系统。为了使董事会平静,后来被他们称为“ PlayStation之父”的他被调任到财务上独立的母公司Sony Music,他开始着手开发最终成为“ PlayStation”的名称(已经没有名称了)。

最初,开发人员无法决定体系结构应集中在精灵2D图形还是多边形3D图形上。但是,世嘉公司于1993年10月在日本街机上发布的“ Virtua Fighter”游戏取得了成功,这消除了所有怀疑:PSX将遵循3D道路。

该项目的高潮发生在两年后,1994年12月3日创建了Sony Computer Entertainment,并在日本发布了该游戏机。它获得了立竿见影的成功,并在上市的第一天就售出了10万台设备,六个月后销售了200万台设备,一生中售出了1.02亿台设备。


索尼PSX(PS1,PlayStation)。图片:维基百科

建筑



机器的核心是频率为33.8688 MHz [3]的MIPS 32位RISC R3000A处理器,结合2 MB DRAM。值得注意的是,该芯片还具有运动解码器(MDEC),可在30 fps的频率下以320x240的分辨率提供视频播放。在MDEC旁边,我们看到了几何变换引擎(GTE)协处理器,用于对向量和矩阵执行快速的定点数学运算。整个系统无法使用浮点数。

GPU是由中央处理器使用“命令”控制的“黑匣子”。它具有1 MB的VRAM,CPU无法使用。在许多方面,他的作品都类似于出色的即时模式OpenGL:他绘制了可以使用顶点颜色“着色”的带纹理的多边形。图形管道是固定的,不能进行编程。没有Z缓冲区(深度缓冲区)。

像GPU一样,声音处理单元(SPU)也是一个黑匣子。它可以处理24个通道,具有512 KB的SRAM用于存储音频(采用ADPCM格式),并且能够将CD-ROM音频轨道与其音频通道混合。缩写SRAM的含义不是“静态RAM”,而是“声音RAM”。

索尼工程师最大胆的决定是选择数据载体。他们选择的不是盒式磁带,而是双速CD-ROM模块,这降低了游戏成本,并显着增加了可用容量(最大约为650 MB)。缺点是传输速率低(300 KB / s),磁头安装时间过长(300 ms)。

控制台中没有任何响声。该机器的编程模型是开发人员没有触摸“裸”铁。但是,有一个DMA控制器用于将数据从CD / DRAM传输到VRAM / SRAM。

影像系统


尽管视频系统支持24位彩色,但很少有游戏使用它(“黑心之心”背景除外[4])。在实践中,可以良心地说,大多数游戏使用带有1位掩码的16位颜色。



像素深度为15位的PSX色彩空间

视频系统的一个惊人功能是VRAM的组织,它完全取决于开发人员。 1 MB VRAM被视为可以免费使用的1024 x 512 x 16位数组。双倍或三倍缓冲的应用以简单的方式执行,因为该区域足以保留,提取和传输到输出系统。纹理也位于帧缓冲区旁边的VRAM中。要写入帧缓冲区,将启动用于渲染纹理三角形/四边形的GPU命令。

纹理可以具有各种格式。有两种直接的16位和24位颜色源,以及基于称为“颜色查找表(CLUT)”的调色板的源。支持8位和4位CLUT。

在分辨率方面,该控制台仅限于NTSC和PAL电视标准。对于美国和日本市场,开发人员可以选择256、320、384、512或640像素的水平分辨率。垂直分辨率为240像素(每隔第二条光栅线跳过时),或交替时为480像素。两种垂直模式均以60 Hz的频率运行。NTSC和PAL之间的唯一区别是垂直分辨率提高了(256/512,而不是240/480),刷新率降低了(50 Hz)。

NTSC模式(60Hz)PAL(50Hz)注意
=================================================== ========

0256 x 240256 x 256非隔行
1320 x 240320 x 256非隔行
2 512 x 240512 x 256非隔行
3640 x 240640 x 256非隔行
4256 x 480256 x 512交错
5320 x 480320 x 512交错
6512 x 480512 x 512交错
7640 x 480640x 512交错
8384 x 240384 x 256非隔行
9384 x 480384 x 512交错


请注意水平分辨率为384像素(8和9)的模式,根据其id判断,这些模式稍后会添加。

PSX上的《毁灭战士》


在id Software的支持下,Williams Entertainment将DOOM移植到PSX。由五个人组成的团队用了不到一年的时间[5] [6]来移植引擎,更改资源和修改游戏,以便所有内容仅在3.5 MB的RAM上起作用。

“图形已经降级:纹理的大小,精灵,怪物和武器也减少了。[...]有时我们会剪切动画帧。” -哈里·提斯利

最终结果于1995年11月16日发布。它被认为是游戏的最佳控制台端口,并且由于其色面和CD品质的音乐,某些方面甚至超过了PC版本。

“到目前为止,这是最好的DOOM!” 约翰·罗梅罗

学习计划



由于开发的性质,DOOM结构基于一个内核,该内核使用六个子系统进行I / O。大多数时候,我研究我发现最有趣的三个部分,即基于CD-ROM的文件系统,基于SPU的音频和基于GPU的视频,因为它们是PSX体系结构所独有的。

PSX的DOOM源代码从未发布过,但事实证明完全没有问题。可用的信息就足够了。

第一个来源是很棒的PSY-Q SDK,它是当时PSX开发人员使用的“官方”工具。它上有很多文档,以一组PDF文件的形式提供。如此丰富的信息仅证实了我所听到的关于PSX对开发人员友好的所有好处。由Psygnosis开发的库(即libcd,libds)也有据可查。很高兴看到清晰的解释,尤其是与几乎完全缺乏有关其他控制台的信息相比(是的,我在谈论SNES)。

信息的另一个来源是当今可用的许多外部工具。 ISOBuster使我可以打开CD的内容。 PSound帮助扫描LCD文件。没有$ PSX模拟器的强大功能就可以跟踪GPU和SPU命令,这已成为真正的黄金。

但是,也许DOOM对PSX粉丝的热爱使我印象最深刻。进行了完整的游戏反向工程。PSXDOOM-RE尤其引人注目,因为它是一个C代码库,可以使用PSY-Q SDK编译成完整的PSX游戏。该代码高度可靠,因为它是通过用C重写机器代码的每个功能获得的。

CD的神奇世界


在开始研究文件系统的实现之前,我进行了短暂的游览,以更好地了解CD的奇妙世界。

从1980年到2000年的20年间,已经发布了几卷规格说明了这一主题。它们一起被称为“彩虹书”。该系列的第一本书“ Red Book”包含音频光盘(CD)的规范。 “黄皮书”是对“红皮书”的补充,它增加了CD-ROM和ISO-9600的数据规范。橙皮书增加了CD-DA,CD-R(可记录)和CR-WR(可重写)的规范。白皮书专门用于Video-CD(VCD)。绿皮书讨论了CD交互(CD-I)。蓝皮书介绍了用于多媒体支持的增强型CD(ECD)数据。 《猩红色的书》致力于超级音频(SACD),可添加高清音频。紫皮书列出了双密度CD(DDCD)规范,该规范将磁盘容量从650 MB增加到了1.3 GB。最后,青色书详细信息9660文件系统规格[7]


Rainbow Books包含了我们对CD的了解。

绝对最低限度,我们需要了解PSX CD通常由扇区组成,每个扇区包含2048字节的数据。扇区分为轨道(可以是数据或声音)。曲目在会话中分组。可以使用标准的ISO-9660文件系统来安排数据磁道的信息,但是,游戏也可以具有硬编码的扇区地址。

在DOOM游戏CD中



如果使用ISOBuster查看CD-ROM的内部内容,则可以看到DOOM包含一个包含八个磁道的会话[8]其中有七个是在任务之间和最终场景中播放的CD品质的音轨。最终音轨(#7)甚至使用数字化的恶魔声音。音轨编号6特别值得注意,因为它似乎是直接从狂欢派对上摘下来的。事实证明,这是在超级秘密卡59“ Club DOOM”(只能从秘密卡访问的秘密卡)[9]上播放的音乐让我让你欣赏她的疯狂。开始之前,请检查音量。


其余曲目(编号1)为ISO-9660,其中包含游戏引擎和大多数资源。探索了许多DOOM端口之后,我天真地希望使用一个名为DOOM.EXE的引擎,一个PSXDOOM.WAD资源文件以及一个清单。我很误会。在赛道上发现287个文件[10] [11],包括60 .WAD,120 .IMG和不计其数的.LCD。

数据按级别排序(每张卡五个文件)。

文件名说明
=================================================== =====

MAPDIR0 / MAP01.WAD标准几何(BSP /拒绝/ ...)
MAPDIR0 / MAPTEX01.IMG平面/墙壁的纹理
MAPDIR0 / MAPSPR01.IMG由THINGS创建的所有子画面
MUSIC / MUSLEV1.LCD可播放的音乐
SNDMAPS1 / MAP01.LCD THINGS发出的所有声音

当被问及为什么一切都以新的方式安排时,Crash Bandicoot开发人员Andy Gavin在接受Ars Technica采访时部分回答了。[ 哈布雷翻译 ]

“将磁头移动到CD上的任何点大约需要1/3秒。”

由于磁头定位速度接近300毫秒(这已由PSY-Q文档[12]确认),因此Williams Entertainment的开发人员无法保存DOOM引擎的清晰架构,该架构将所有资源存储在一个文件中(例如, DOOM.WAD),并根据要求下载它们。在PSX上,这将导致可怕的帧速率。

开发人员通过在CD上抛出看似无穷无尽的字节来解决了这个问题。关卡所需的所有资源都存储在五个文件中,其中包含地图的几何形状,纹理。精灵,音效和音乐。这非常昂贵,但是消除了在游戏过程中访问CD的需要。

趣味事实:在数据轨道上的文件列表中,有一个名为PSXDOOM.WAD的文件(4 806 088字节),但它仅用于加载调色板和多个菜单图像。在开发过程中可能会更积极地使用。

以第一个地图为例:下载的数据总量已从4 MB减少到900 KB。

文件名大小(以字节为单位)  
====================================  	
MAPDIR0 / MAP01.WAD 28196
MAPDIR0 / MAPTEX01.IMG 90744
MAPDIR0 / MAPSPR01.IMG 590344
音乐/MUSLEV1.LCD 61232
SNDMAPS1 / MAP01.LCD 143632
====================================
总计:914,148

知道资源占用914 KB,您可能会认为还有很多未使用的DRAM。但是,您需要记住,它还必须适合428 KB的可执行文件以及在运行时会更改的堆栈。实际上,运行时只有大约1 MB的DRAM可用。

一个有趣的事实:在检查PSXDOOM-RE的源代码时,我发现了P_LoadBlocks函数,该函数尝试从CD读取多达四次[13],然后将其放弃。这是使用容易刮擦的介质的乐趣之一。

我没想到CD-ROM头的安装时间会如此大地影响游戏架构。某些游戏(例如Crash Bandicoot)是使用页面系统从头开始创建的,用于在运行时从CD传输数据。对于DOOM,引擎无法做到这一点。除了一首特定的歌曲(是,来自俱乐部DOOM级别)外,游戏期间不使用CD。

id Software的家伙从来都不喜欢CD-ROM提供的容量和速度之间的权衡。

« - . , CD. - , Crash 'n Burn — ? . , CD , 3DO . - CD- DOOM, „ DOOM“. , . .

, CD. ». — (ATARI EXPLORER ONLINE, 22 1994 )

一个有趣的事实: DOOM游戏中的事件是使用“拉伸标记”触发的。越过具有特殊属性的线时,将调用特殊功能。在引擎的“旧版”版本中,没有允许您播放歌曲的属性。为了玩Club DOOM,创建了一个特殊的linedef动作(编号142) [14]令人惊讶的是,创建此关卡花费了额外的精力。开发人员可能真的很喜欢在狂欢中玩得开心。

失踪档案室的情况



在研究《 Game Engine Black Book》时,我无法完全弄清设计师Harry Teesley所说的这句话:

“ Archvile的动画帧数是任何其他怪物的两倍,我们无法将其塞入PSX。他的攻击和复活效果都不会丢失。他太大了。” -Harry Tisley(设计师)在doomworld.com的一次采访中

显然问题不在于CD的650兆字节容量,而是我不明白什么是限制因素-DRAM或VRAM。

了解了CD-ROM的局限性之后,我意识到问题不在于将子画面存储在CD上,甚至不将其从DRAM传输到VRAM。问题是将所有内容都装入DRAM。

有趣的事实: ArchVile已从PSXDOOM-RE的源代码中完全删除。甚至他的#DEFINE也被注释掉了[15]

#define CC_ZOMBIE  "Zombieman"
#define CC_SHOTGUN  "Shotgun Guy"
#define CC_HEAVY  "Heavy Weapon Dude"
...
#define CC_HELL   "Hell Knight"
//#define CC_ARCH "Arch-Vile"
#define CC_SPIDER "The Spider Mastermind"
#define CC_CYBER  "The Cyberdemon"
#define CC_HERO   "Our Hero"

SPU编程


SPU芯片仅了解一种格式,即ADPCM。它能够混合多达24个通道(包括CD音频轨道),并具有强大的音频处理功能。

为了驯服这只野兽,DOOM PSX使用了由音响工程师Scott Patterson编写的libWESS库(威廉姆斯娱乐音响系统)。该库功能非常强大,它能够重新创建MiDI系统,在该系统中,一大堆音符(称为声音字体)由占用很少空间的乐谱控制。它还可以实时处理声音属性,例如音量,音调,音符速度和ADSR功能(打击,衰减,延音和释放)。游戏中播放的所有音乐都是使用libWESS生成的。您猜到了一个例外,那就是Club DOOM,它从CD音轨6播放。

WESS使用两种专有文件格式。这些是包含乐谱和声音效果的.WMD文件,以及是PSX VAG格式(无标题)并包含ADPCM样本的.LCD文件。当DOOM启动时,libWESS库将加载存储在一个名为DOOMSND.WMD的小文件(55 KB)中的所有声音效果(SFX,89个)和乐谱(19个)。她还将角色,门等发布的“始终使用的”样本加载到SRAM中。

音乐/DOOMSFX.LCD-> SRAM
音乐/ DOOMSND.WMD-> DRAM

加载地图后,libWESS将打开MUSIC / MUSLEV%.LCD,其中包含此卡音乐中使用的ADPCM样本;以及SNDMAPS%/ MAP %%。LCD,其中包含该级别敌人所需的ADPCM样本。所有ADPCM样本都直接加载到SRAM中,并且不占用DRAM中的空间。

PSX上的DOOM:GPU


在视频生成领域,Williams Entertainment需要解决两个问题:少量的VRAM(我们稍后会再讨论)和缺乏正确的纹理映射(考虑到视角)。

“我和亚伦·席勒(Aaron Siler)分别为Nintendo 64(该游戏完全不同)和Playstation开发了版本。这些是第一个不是用裸机编写的版本,因为Sony和Nintendo都迫使开发人员(至少是第三方的)编写API,并且没有在硬件寄存器上提供文档。最初,SGI文化特别限制了开发人员,但后来任天堂逐渐放松了控制。

关于为Playstation开发版本的一个有趣故事:Aaron和我从不同的引擎架构入手,该引擎架构渲染了世界三角,因为该控制台为它们提供了完整的硬件加速。在N64的情况下,这是完美的,因为它具有亚像素精度的透视校正渲染(SGI影响的结果),但在Playstation仿射纹理贴图上使用整数坐标执行,因此大的墙和地板三角形看起来很棒。” -John Carmack(游戏引擎黑皮书:DOOM)

为了理解它的外观多么“糟糕”,我在下面显示了三幅仿射并可能正确构造纹理的墙。


透视纹理


仿射(PSX)

请注意,直壁没有问题,并且随着视角的增加,失真会变得更加明显。

在将DOOM移植到SEGA Saturn时,Rage Software开发人员也面临相同的感知问题。

« , id Software. , WAD Saturn, , 3D-. , , 3D- . , PC. , , : SH2 , PC, 68000 .

, » — ( DOOM Saturn) RetroGamer №134.

也许,由于PSX开发人员有更多时间,他们可以通过将GPU多边形渲染器转换为线渲染器来解决前瞻性正确的纹理映射问题。

“我说:备份所有内容(那时还没有版本控制系统!),我们将使游戏完全不同。” 我们使用了渲染三角形的设备,这些三角形代表一像素宽的列或行,就像在PC上的汇编代码中一样,并且效果很好。事实证明,在Playstation上更常见的解决方案是沿两个轴细分曲面,但是我真的很喜欢Doom看上去不如那个时期的Playstation上的大多数游戏那样“抽搐”。”-John Carmack(游戏引擎黑皮书:DOOM)

感谢PSXDOOM-RE项目[16],我们可以找到它是如何实现的。渲染管道已被完全重写,分为两个阶段。这将在下面进行更详细的讨论,但实际上我们可以看到R_Render_Wall渲染函数发送了宽度为1像素的定义明确的绘图命令。

void R_Render_Wall(...) {
  .
  int x1 = ... ; // Left end of wall.
  int x2 = ... ; // Right end of wall.
  .
  while(x1 < x2) {
    .
    setRGB0(wallpoly);

    setXY3(wallpoly,
      x1    , ypos1 - 1,
      x1 + 1, ypos2 + 1,
      x1    , ypos2 + 1);		

    setUV3(wallpoly,
         upos, v0,
         upos, v1,
         upos, v1);  
    .
    x1 += 1;
  }
}

墙以一像素宽的列进行渲染。签出类似于OpenGL中即时模式的API。

有趣的事实:索尼的硬件设计师保留了MIPS处理器的i-cache,但禁用了其d-cache,将其转变为1K高速暂存器。墙/平面渲染程序广泛使用此暂存器。

VRAM GPU管理


为了了解如何执行VRAM控制,我选择了一种奇怪的方法:我使用了查看实时VRAM仿真器$ PSX的功能。此函数显示1024 x 512 x 16位的整个像素阵列(尽管格式失真)。查看功能还显示了中央处理器在每一帧中传输的GPU指令的完整列表。


否$ PSX-上帝送给我们一个模拟器,让您可以查看GPU的内部。

仔细研究VRAM第一帧可以使您学习很多。


游戏的第一帧显示为No $ PSX。

最明显的是左上角的两个256 x 240 x 16位区域,它们是帧缓冲区(因此,游戏使用双缓冲)。值得注意的是,256x240是PSX上可能的最低分辨率。

在帧缓冲区下方是一组彩色像素-CLUT调色板。注意红色阴影,它们表示当玩家受到伤害时屏幕变成红色时,将使用预先计算的调色板。

在右上角,我们看到纹理在水平方向上被奇怪地压缩并且具有“错误”的颜色。发生这种情况是因为纹理使用了上述CLUT的8位索引。

让我们再来谈谈PS1中《毁灭战士》中的射击


在2018年,我研究了如何实现火的效果[17] [ Habré的翻译 ]。在研究GPU命令时再次回到他身边真是太好了。请注意,没有$ PSX用红色标记每个命令的目标区域。

阶段1:火焰在RAM中更新,并加载到VRAM中(CpuToVram命令)。


阶段2:沿着屏幕绘制四次火焰纹理(QuadTex命令)。火焰纹理的宽度为32像素,但GPU用于绘制宽度为64像素的像素。这里不可能进行双线性滤波,而是采样最近的纹理像素。


阶段3:将最终的DOOM板(QuadTex命令)绘制在所有内容的顶部。


全画幅,逐个团队


对框架中传输的命令的研究表明,该引擎与PC版本完全不同。在其中,世界从短距离盘旋到了远方。首先,渲染所有墙。在第二遍中,它们(平面)(包括天空)之间填充了垂直间隙。在第三(最后)段落中,从最远的地方开始渲染精灵。所有这些都是通过零重绘像素完成的。

在PSX上,渲染有点不礼貌。从远处开始,所有内容都经过一次渲染。 PC用来填充墙壁之间的空隙的visplane系统不在这里。由于有了一个称为“叶子”的新概念,平面和墙壁按子部门的顺序进行渲染。由于积极使用GPE矩阵投影功能,因此可以在“真正的3D”中进行此类操作。 Sprites还可以与墙/平面同时渲染,而没有重叠和截断检查,这导致少量的重画。

void R_RenderPlayerView(void) {
  R_BSP();         // Phase 1
  R_RenderSKY();   // Phase 2
  for (all subsectors from phase 1) {
    R_RenderAll(subsector)
  }
  R_Render_Hud_Weapons();
}

让我们详细看一下从天空开始的每个步骤,首先使用CopyRectRaw渲染天空。没有$ PSX在帧完成时显示VRAM,但允许您回顾命令的历史记录。天空像素是可见的,因为没有$ PSX可以用一个像素宽度的列来感知这种入侵(其他仿真器,例如ePSXe,无法更好地应对[18]),但是所有这些像素都将被重写。请注意,在天空的纹理下,所有门钥匙的标记都收集在地图集中。


然后从远到近依次遍历BSP。对于每个子部门,将渲染所有墙/平面/子图形。如果您熟悉DOOM BSP,则可能还记得doombsp编译器仅保留了可靠的子扇区。为了确保渲染平面,在PSX版本中增加了“叶子”的新概念,其中存储了BPS分隔段(不可见)。这些段被投影到屏幕空间中以生成平面边界。这是一种更加“干净”的方法,因为它使您摆脱了具有屏幕空间和错误的hack,例如,从著名的“ slug”中摆脱了。


在下一个VRAM镜头中,来自与我们在上面的墙相同的子扇区的平面被渲染为1像素高的三角形。也要注意墙壁/平面的纹理,它们都具有相同的大小。此功能简化了VRAM纹理的选择并避免了碎片。


我们仍然在同一个子部门中。现在,精灵将渲染为四边形(Quad)。这些精灵包括敌人,炮弹,部分透明的墙壁。


为了娱乐,我们将展示等离子外壳。


我们即将结束渲染命令。在这里,通过混合矩形来渲染武器。


最后一步:接口渲染(HUD)。


VRAM溢出!



使用GPU是在VRAM中分配空间的一种练习。对于帧缓冲区,CLUT,静态内容(接口),甚至墙/平面,该任务是基本任务,因为它们的大小均相同。但是,使用精灵,事情会更加复杂。

由于精灵的大小不同,因此会导致碎片化。而且,纹理可以覆盖屏幕的大面积并重复,并且子画面通常是唯一的,并且在每帧中可能需要大量的画面。在最坏的情况下,一帧需要一定数量的子画面,这些子画面不能放置在VRAM中。这称为纹理缓存溢出,并且无法解决此问题。发生这种情况时,游戏会崩溃并显示一条错误的错误消息[19]让我们中的一些人想起了不祥的“不再有平面”。


您同时看到的精灵越多,使用的VRAM就越多。

PAL和NTSC之间的区别


在视频章节的结尾,我决定看看NTSC如何转换为PAL。不幸的是,与其他许多游戏一样,DOOM PSX也没有考虑垂直分辨率的提高。在欧洲的PS1上播放DOOM时,您看到了带有明显黑色边框的垂直压缩图像。

了解了VRAM的原理后,我很难责怪开发人员。如果仔细查看NTSC中的VRAM方案,您会注意到增加帧缓冲区的垂直分辨率会违反整个数据分配结构。在其下存储纹理将是不可能的。否则,您将不得不将CLUT移到另一个位置。成本太高,收益却相对较少,即使黑色边框干扰了游戏,我也认为这样做不值得。

致谢


感谢Eric Vazquez(PSXDOOM-RE的作者),Samuel Villarreal(PSXDOOM-RE的开发商之一)和Dan Leslie(PlayStation 1游戏的专业开发商)慷慨地与我分享了他们的知识。


All Articles